LTP GCOV extension - code coverage report
Current view: directory - src/libstore - references.cc
Test: app.info
Date: 2004-12-21 Instrumented lines: 45
Code covered: 95.6 % Executed lines: 43

       1                 : #include <cerrno>
       2                 : #include <map>
       3                 : 
       4                 : #include <sys/types.h>
       5                 : #include <sys/stat.h>
       6                 : #include <unistd.h>
       7                 : #include <dirent.h>
       8                 : #include <fcntl.h>
       9                 : 
      10                 : #include "references.hh"
      11                 : #include "hash.hh"
      12                 : 
      13                 : 
      14                 : static void search(const string & s,
      15                 :     Strings & ids, Strings & seen)
      16              34 : {
      17              36 :     for (Strings::iterator i = ids.begin();
      18                 :          i != ids.end(); )
      19                 :     {
      20              96 :         checkInterrupt();
      21              96 :         if (s.find(*i) == string::npos)
      22              94 :             i++;
      23                 :         else {
      24               2 :             debug(format("found reference to `%1%'") % *i);
      25               2 :             seen.push_back(*i);
      26               2 :             i = ids.erase(i);
      27                 :         }
      28                 :     }
      29                 : }
      30                 : 
      31                 : 
      32                 : void checkPath(const string & path,
      33                 :     Strings & ids, Strings & seen)
      34              32 : {
      35              32 :     checkInterrupt();
      36                 :     
      37              32 :     struct stat st;
      38              32 :     if (lstat(path.c_str(), &st))
      39               0 :         throw SysError(format("getting attributes of path `%1%'") % path);
      40                 : 
      41              32 :     if (S_ISDIR(st.st_mode)) {
      42              10 :         Strings names = readDirectory(path);
      43              22 :         for (Strings::iterator i = names.begin(); i != names.end(); i++) {
      44              12 :             search(*i, ids, seen);
      45              12 :             checkPath(path + "/" + *i, ids, seen);
      46                 :         }
      47                 :     }
      48                 : 
      49              22 :     else if (S_ISREG(st.st_mode)) {
      50                 :         
      51              20 :         debug(format("checking `%1%'") % path);
      52                 : 
      53              20 :         AutoCloseFD fd = open(path.c_str(), O_RDONLY);
      54              20 :         if (fd == -1) throw SysError(format("opening file `%1%'") % path);
      55                 : 
      56              20 :         unsigned char * buf = new unsigned char[st.st_size];
      57                 : 
      58              20 :         readFull(fd, buf, st.st_size);
      59                 : 
      60              20 :         search(string((char *) buf, st.st_size), ids, seen);
      61                 :         
      62              20 :         delete buf; /* !!! autodelete */
      63                 :     }
      64                 :     
      65               2 :     else if (S_ISLNK(st.st_mode))
      66               2 :         search(readLink(path), ids, seen);
      67                 :     
      68               0 :     else throw Error(format("unknown file type: %1%") % path);
      69                 : }
      70                 : 
      71                 : 
      72                 : Strings filterReferences(const string & path, const Strings & paths)
      73              20 : {
      74              20 :     map<string, string> backMap;
      75              20 :     Strings ids;
      76              20 :     Strings seen;
      77                 : 
      78                 :     /* For efficiency (and a higher hit rate), just search for the
      79                 :        hash part of the file name.  (This assumes that all references
      80                 :        have the form `HASH-bla'). */
      81              76 :     for (Strings::const_iterator i = paths.begin();
      82                 :          i != paths.end(); i++)
      83                 :     {
      84              56 :         string s = string(baseNameOf(*i), 0, 32);
      85              56 :         parseHash(s);
      86              56 :         ids.push_back(s);
      87              56 :         backMap[s] = *i;
      88                 :     }
      89                 : 
      90              20 :     checkPath(path, ids, seen);
      91                 : 
      92              20 :     Strings found;
      93              22 :     for (Strings::iterator i = seen.begin(); i != seen.end(); i++)
      94                 :     {
      95               2 :         map<string, string>::iterator j;
      96               2 :         if ((j = backMap.find(*i)) == backMap.end()) abort();
      97               2 :         found.push_back(j->second);
      98                 :     }
      99                 : 
     100              20 :     return found;
     101                 : }

Generated by: LTP GCOV extension version 1.1