idep_AliasDep Class Reference

#include <idep_aliasdep.h>

List of all members.

Public Member Functions

 idep_AliasDep ()
 ~idep_AliasDep ()
void addIgnoreName (const char *name)
int readIgnoreNames (const char *file)
const char * addAlias (const char *aliasName, const char *componentName)
int readAliases (std::ostream &err, const char *file)
void addFileName (const char *fileName)
int readFileNames (const char *file)
void inputFileNames ()
int unpaired (std::ostream &out, std::ostream &err, int suffixFlag=1) const
int verify (std::ostream &err) const
int extract (std::ostream &out, std::ostream &err) const

Private Member Functions

 idep_AliasDep (const idep_AliasDep &)
idep_AliasDepoperator= (const idep_AliasDep &)

Private Attributes

idep_AliasDep_id_this

Detailed Description

Definition at line 11 of file idep_aliasdep.h.


Constructor & Destructor Documentation

idep_AliasDep::idep_AliasDep ( const idep_AliasDep  )  [private]
idep_AliasDep::idep_AliasDep (  ) 

Definition at line 158 of file idep_adep.cxx.

00159 : d_this(new idep_AliasDep_i)
00160 {
00161 }

idep_AliasDep::~idep_AliasDep (  ) 

Definition at line 163 of file idep_adep.cxx.

References d_this.

00164 {
00165     delete d_this;
00166 }


Member Function Documentation

const char * idep_AliasDep::addAlias ( const char *  aliasName,
const char *  componentName 
)

Definition at line 178 of file idep_adep.cxx.

References idep_AliasTable::add(), idep_AliasDep_i::d_aliases, d_this, and idep_AliasTable::lookup().

00179 {
00180     return d_this->d_aliases.add(alias, component) < 0 ?
00181                                         d_this->d_aliases.lookup(alias) : 0;
00182 }

void idep_AliasDep::addFileName ( const char *  fileName  ) 

Definition at line 189 of file idep_adep.cxx.

References idep_NameIndexMap::add(), idep_AliasDep_i::d_fileNames, and d_this.

Referenced by inputFileNames(), main(), and readFileNames().

00190 {
00191     d_this->d_fileNames.add(fileName);          
00192 }

void idep_AliasDep::addIgnoreName ( const char *  name  ) 

Definition at line 168 of file idep_adep.cxx.

References idep_NameIndexMap::add(), idep_AliasDep_i::d_ignoreNames, and d_this.

Referenced by main(), and readIgnoreNames().

00169 {
00170     d_this->d_ignoreNames.add(fileName);                
00171 }

int idep_AliasDep::extract ( std::ostream &  out,
std::ostream &  err 
) const

Definition at line 374 of file idep_adep.cxx.

References idep_AliasDep_i::d_aliases, idep_AliasDep_i::d_fileNames, idep_AliasDep_i::d_ignoreNames, d_this, idep_NameIndexMap::entry(), err(), GOOD, header, IOERROR, idep_FileDepIter::isValidFile(), it, idep_NameIndexMap::length(), idep_AliasTable::lookup(), idep_NameIndexMap::lookup(), removeSuffix(), stripDir(), warn(), and zero().

Referenced by main().

00375 {
00376     enum { IOERROR = -1, GOOD = 0 } status = GOOD;
00377     enum { INVALID_INDEX = -1 };
00378     int errorCount = 0; // keep track of number of readable faulty files
00379 
00380     idep_NameIndexMap uniqueHeaders;       // used to detect multiple .c files
00381     int length = d_this->d_fileNames.length();
00382     idep_AliasDepIntArray hits(length);    // records frequency of headers
00383     zero(&hits); 
00384     idep_AliasDepIntArray hmap(length);    // index header file index in table
00385     idep_AliasDepIntArray verified(length);// verifies that guess was correct
00386     zero(&verified); 
00387     
00388     int i;
00389     for (i = 0; i < length; ++i) {
00390         hmap[i] = INVALID_INDEX;   // set valid when a suitable header is found
00391 
00392         const char *path = d_this->d_fileNames[i];
00393         idep_AliasDepString c(path);
00394 
00395         if (d_this->d_ignoreNames.lookup(c) >= 0) {
00396             continue; // ignore this file
00397         }
00398 
00399         // strip off suffix and path from component file name and check aliases
00400         removeSuffix(c);
00401         const char *actualComponent = stripDir(c);
00402         const char *compAlias = d_this->d_aliases.lookup(actualComponent);
00403         const char *component = compAlias ? compAlias : actualComponent;
00404 
00405         idep_FileDepIter it(path);      // hook up with first dependency.
00406 
00407         if (!it.isValidFile()) {        // unable to read file
00408             err(orr) << "unable to open file \""
00409                     << path << "\" for read access." << std::endl;
00410             status = IOERROR;
00411             continue;                   // nothing more we can do here
00412         }
00413 
00414         if (!it) {                      // no include directives
00415             err(orr) << '"' << path 
00416                     << "\" contains no include directives." << std::endl;
00417             ++errorCount;
00418             continue;                   // nothing more we can do here
00419         }
00420 
00421         // strip off suffix and path from header name and check aliases
00422         idep_AliasDepString h(it());
00423         removeSuffix(h);
00424         const char *actualHeader = stripDir(h);
00425         const char *headerAlias = d_this->d_aliases.lookup(actualHeader);
00426         const char *header = headerAlias ? headerAlias : actualHeader;
00427 
00428         if (0 == strcmp(component, header)) { 
00429 
00430             // At this point, we have the component name and header name
00431             // that match either because the root names were matching or 
00432             // because we found an alias that made it work.  Record this 
00433             // fact in the verified array.
00434 
00435             verified[i] = 1;
00436         }
00437         else {
00438 
00439             // We suspect this may be an alias pair, but we are not sure.
00440             // We will check to see if an alias involving this .c file
00441             // already exists.  If so, that will override and we will
00442             // not regenerate the alias.
00443 
00444             if (compAlias) {
00445                 continue;               // nothing more we can do here
00446             }
00447         }
00448 
00449         // We have no reason *not* to think this is a valid match (yet).
00450         // Record this header as being associated with the this .c file.
00451 
00452         int hIndex = uniqueHeaders.entry(header); // obtaine index of header
00453         ++hits[hIndex];                           // record frequency
00454         hmap[i] = hIndex;                         // set .c -> header index
00455     }
00456 
00457     const int FW = 25;
00458     const char *const ARROW = ">- probably correct -> ";
00459 
00460     // For each unique header, if more than one .c file names this header
00461     // int its first include directive, output a warning to the error stream.
00462 
00463     for (i = 0; i < uniqueHeaders.length(); ++i) {
00464         if (hits[i] > 1) {
00465             warn(orr) << hits[i] << " files specify \"" << uniqueHeaders[i]
00466                  << "\" as their first include directive:" << std::endl;
00467             for (int j = 0; j < length; ++j) {
00468                 if (i ==  hmap[j]) {
00469                     orr.width(FW);
00470                     orr << (verified[j] ? ARROW : "");
00471                     orr << '"' << stripDir(d_this->d_fileNames[j])
00472                        << '"' << std::endl;
00473                 }
00474             }
00475             orr << std::endl;
00476         }
00477     }
00478 
00479     // Print the non-redundant header / implementation file aliases to
00480     // the specified output stream.
00481 
00482     for (i = 0; i < length; ++i) {
00483         if (hmap[i] >= 0 && !verified[i]) {
00484            // strip off suffix and path from component file name
00485            idep_AliasDepString c(d_this->d_fileNames[i]);
00486            removeSuffix(c);
00487            out << uniqueHeaders[hmap[i]] << ' ' << c << std::endl;
00488         }
00489     }
00490 
00491     return status == GOOD ? errorCount : status;        
00492 }

void idep_AliasDep::inputFileNames (  ) 

Definition at line 199 of file idep_adep.cxx.

References addFileName(), and loadFromStream().

Referenced by main().

00200 {
00201     if (std::cin) {
00202         loadFromStream(std::cin, this, &idep_AliasDep::addFileName); 
00203         std::cin.clear(std::ios::iostate(0)); // reset eof for standard input
00204     }
00205 }

idep_AliasDep& idep_AliasDep::operator= ( const idep_AliasDep  )  [private]
int idep_AliasDep::readAliases ( std::ostream &  err,
const char *  file 
)

Definition at line 184 of file idep_adep.cxx.

References idep_AliasDep_i::d_aliases, and d_this.

Referenced by main().

00185 {
00186     return idep_AliasUtil::readAliases(&d_this->d_aliases, orr, file);
00187 }

int idep_AliasDep::readFileNames ( const char *  file  ) 

Definition at line 194 of file idep_adep.cxx.

References addFileName(), and loadFromFile().

Referenced by main().

00195 {
00196     return loadFromFile(file, this, &idep_AliasDep::addFileName); 
00197 }

int idep_AliasDep::readIgnoreNames ( const char *  file  ) 

Definition at line 173 of file idep_adep.cxx.

References addIgnoreName(), and loadFromFile().

Referenced by main().

00174 {
00175     return loadFromFile(file, this, &idep_AliasDep::addIgnoreName); 
00176 }

int idep_AliasDep::unpaired ( std::ostream &  out,
std::ostream &  err,
int  suffixFlag = 1 
) const

Definition at line 207 of file idep_adep.cxx.

References idep_NameIndexMap::add(), idep_AliasDep_i::d_aliases, idep_AliasDep_i::d_fileNames, idep_AliasDep_i::d_ignoreNames, d_this, idep_NameIndexMap::entry(), len, idep_NameIndexMap::length(), idep_AliasTable::lookup(), idep_NameIndexMap::lookup(), removeSuffix(), s(), warn(), and zero().

Referenced by main().

00210 {
00211     int maxLength = d_this->d_fileNames.length();
00212     idep_AliasDepIntArray hits(maxLength);  // records num files per component
00213     idep_AliasDepIntArray cmap(maxLength);  // map component to (last) file
00214     zero(&hits); 
00215     idep_NameIndexMap components;
00216     int numComponents = 0;
00217 
00218     idep_NameIndexMap printNames;   // Used to sort names for ease of use
00219                                     // during cut and past in the editor.
00220 
00221     int i;
00222     for (i = 0; i < maxLength; ++i) {
00223         idep_AliasDepString s(d_this->d_fileNames[i]);
00224 
00225         if (d_this->d_ignoreNames.lookup(s) >= 0) {
00226             continue; // ignore this file
00227         }
00228         removeSuffix(s);
00229 
00230         const char *componentName = d_this->d_aliases.lookup(s);
00231         if (!componentName) {
00232             componentName = s;
00233         }
00234 
00235         int componentIndex = components.entry(componentName);
00236         if (components.length() > numComponents) {      // new component
00237             ++numComponents;
00238             
00239         }
00240 
00241         assert(components.length() == numComponents);
00242 
00243         ++hits[componentIndex];
00244         cmap[componentIndex] = i; // overwrite with most recent index
00245     }
00246 
00247     for (i = 0; i < numComponents; ++i) {
00248         assert(hits[i] > 0);
00249         if (1 == hits[i]) {
00250             printNames.add(suffixFlag ? d_this->d_fileNames[cmap[i]] 
00251                                       : components[i]); 
00252         }
00253         if (hits[i] > 2) { 
00254             warn(ing) << "component \"" << components[i] 
00255                       << "\" consists of " << hits[i] << " files." 
00256                       << std::endl;
00257         }
00258     }
00259 
00260     // Because of library .o file name-length limitations it is often the
00261     // header which has the longer name representing the true name of the
00262     // component.  If the suffixFlag is 0, we will sort into almost
00263     // lexicographic order except that the shorter of two initially identical
00264     // names will *follow* rather than precede longer.  This ordering will 
00265     // facilitate cut and past when creating an alias file by hand in a
00266     // text editor. 
00267 
00268     int numUnpaired = printNames.length();
00269     idep_AliasDepIntArray smap(numUnpaired); 
00270     for (i = 0; i < numUnpaired; ++i) {
00271         smap[i] = i;                            // identity mapping to start
00272     }
00273 
00274     for (i = 1; i < numUnpaired; ++i) {
00275         for (int j = 0; j < numUnpaired; ++j) {
00276             int swap;
00277             if (suffixFlag) {
00278                 swap = strcmp(printNames[smap[i]], printNames[smap[j]]) < 0;
00279             }
00280             else {
00281                 int li = strlen(printNames[smap[i]]);
00282                 int lj = strlen(printNames[smap[j]]);
00283                 int len = li < lj ? li : lj;    // min length
00284                 int cmp = strncmp(printNames[smap[i]], 
00285                                   printNames[smap[j]], len); 
00286                 swap = cmp < 0 || 0 == cmp && li > lj;  // longer first if tie
00287             }
00288             if (swap) {                                 // swap if necessary
00289                 int tmp = smap[i];                
00290                 smap[i] = smap[j];
00291                 smap[j] = tmp;
00292             }
00293         }
00294     }
00295 
00296     // print out names in (almost) lexicographic order (if suffixFlag set to 0)
00297 
00298     for (i = 0; i < numUnpaired; ++i) {
00299         out << printNames[smap[i]] << std::endl;
00300     }
00301 
00302     return printNames.length();
00303 }

int idep_AliasDep::verify ( std::ostream &  err  )  const

Definition at line 310 of file idep_adep.cxx.

References idep_AliasDep_i::d_aliases, idep_AliasDep_i::d_fileNames, idep_AliasDep_i::d_ignoreNames, d_this, err(), GOOD, header, IOERROR, idep_FileDepIter::isValidFile(), it, idep_NameIndexMap::length(), idep_AliasTable::lookup(), idep_NameIndexMap::lookup(), removeSuffix(), stripDir(), and th().

Referenced by main().

00311 {
00312     enum { IOERROR = -1, GOOD = 0 } status = GOOD;
00313     int errorCount = 0; // keep track of the number of readable faulty files
00314 
00315     int length = d_this->d_fileNames.length();
00316     for (int i = 0; i < length; ++i) {
00317         const char *path = d_this->d_fileNames[i];
00318         idep_AliasDepString c(path);
00319 
00320         if (d_this->d_ignoreNames.lookup(c) >= 0) {
00321             continue; // ignore this file
00322         }
00323 
00324         // strip off suffix and path from component file name and check aliases
00325         removeSuffix(c);
00326         const char *actualComponent = stripDir(c);
00327         const char *compAlias = d_this->d_aliases.lookup(actualComponent);
00328         const char *component = compAlias ? compAlias : actualComponent;
00329 
00330         int directiveIndex = 0;
00331         idep_FileDepIter it(path);
00332         for (; it; ++it) {
00333 
00334             ++directiveIndex;
00335 
00336             // strip off suffix and path from header name and check aliases
00337             idep_AliasDepString h(it());
00338             removeSuffix(h);
00339             const char *actualHeader = stripDir(h);
00340             const char *headerAlias = d_this->d_aliases.lookup(actualHeader);
00341             const char *header = headerAlias ? headerAlias : actualHeader;
00342 
00343             if (0 == strcmp(component, header)) { // if the same, we found it
00344                 break;
00345             }
00346         }
00347 
00348         if (!it.isValidFile()) { // if the file was never valid to begin with
00349             err(orr) << "unable to open file \""
00350                     << path << "\" for read access." << std::endl;
00351             status = IOERROR;
00352         }
00353         else if (!it) {                         // header not found
00354             err(orr) << "corresponding include directive for \"" << path 
00355                     << "\" not found."
00356                     << std::endl;
00357             ++errorCount;
00358         }
00359         else if (1 != directiveIndex) {         // header found but not first
00360             err(orr) << '"' << path 
00361                     << "\" contains corresponding include as " 
00362                     << directiveIndex << th(directiveIndex)
00363                     << " directive." << std::endl;
00364             ++errorCount;
00365         }
00366 
00367         // else there is nothing wrong here
00368     }
00369 
00370     return status == GOOD ? errorCount : status;        
00371 }


Member Data Documentation


The documentation for this class was generated from the following files:

Generated on 3 Dec 2018 for loon by  doxygen 1.6.1