Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

idep_linkdep.h

Go to the documentation of this file.
00001 // idep_linkdep.h
00002 #ifndef INCLUDED_IDEP_LINKDEP
00003 #define INCLUDED_IDEP_LINKDEP
00004 
00005 // This wrapper component defines 8 fully insulated classes:
00006 //          idep_LinkDep: environment for analyzing link dependencies
00007 //        idep_AliasIter: iterate over specified alias pairs
00008 //      idep_UnaliasIter: iterate over specified unaliased directories
00009 //        idep_CycleIter: iterate over cycles in the system
00010 //       idep_MemberIter: iterate over members within a given cycle
00011 //        idep_LevelIter: iterate over levels in the system
00012 //    idep_ComponentIter: iterate over components on a given level
00013 //   idep_DependencyIter: iterate over dependencies for a given component
00014 
00015 #include <iosfwd>
00016 class idep_AliasIter;
00017 class idep_UnaliasIter;
00018 class idep_CycleIter;
00019 class idep_MemberIter;
00020 class idep_LevelIter;
00021 class idep_ComponentIter;
00022 class idep_DependencyIter;
00023 
00024 class idep_LinkDep_i;
00025 class idep_LinkDep {
00026     idep_LinkDep_i *d_this;
00027 
00028     friend class idep_AliasIter;
00029     friend class idep_UnaliasIter;
00030     friend class idep_CycleIter;
00031     friend class idep_MemberIter;
00032     friend class idep_LevelIter;
00033     friend class idep_ComponentIter;
00034     friend class idep_DependencyIter;
00035 
00036   private:
00037     idep_LinkDep(const idep_LinkDep&);                  // not implemented
00038     idep_LinkDep& operator=(const idep_LinkDep&);       // not implemented
00039 
00040   public:
00041     // CREATORS
00042     idep_LinkDep();
00043     ~idep_LinkDep();
00044 
00045     // MANIPULATORS
00046     void addDependencyFile(const char *fileName);  
00047         // Add a file containing dependencies to be parsed.  Parsing errors 
00048         // will be reported during the calculation phase.  Note that the
00049         // empty string ("") is interpreted to mean <stdin>. 
00050 
00051     const char *addAlias(const char *aliasName, const char *componentName);
00052         // Add an alias/component name pair to the set of aliases.  This
00053         // function returns 0 on success or a character string containing
00054         // a previously corresponding component name for this alias that is
00055         // not identical to the once specified here.
00056  
00057     int readAliases(std::ostream& err, const char *file);
00058         // Read a list of component aliases from the specified file.  Each
00059         // contiguous sequence of non-whitespace characters represents a name.
00060         // Names are also arranged into sequences.  The first name in a name
00061         // sequence represents the actual component name.  Names that follow
00062         // on the same line (horizontal sequence) or subsequent lines
00063         // (vertical sequence) are interpreted as aliases for that component
00064         // name.  A horizontal sequence is terminated by a newline ('\n')
00065         // unless preceded by a backslash ('\\').  A vertical sequence is
00066         // terminated by a blank line.  This function quietly returns 0 on
00067         // success.  If the specified file is not readable, this function
00068         // quietly returns -1.  If an alias that is inconsistent with a
00069         // previously specified alias is encountered, the conflicting aliases
00070         // are identified to the err stream.  After parsing is complete, the
00071         // number of offending aliases is returned as the value of this 
00072         // function.
00073 
00074     void addUnaliasDirectory(const char *dirName);
00075         // Add a directory _not_ to be treated as a single unit by default.
00076         // This function has no effect if the directory has already been 
00077         // specified.
00078 
00079     int readUnaliasDirectories(const char *file);
00080         // Add a list of unalias directories read from the specified file.
00081         // This function assumes that each contiguous sequence of
00082         // non-whitespace characters represents a directory to be added.  
00083         // This function returns 0 unless the specified file is unreadable 
00084         // or contains non-ascii characters.
00085 
00086     int calculate(std::ostream& err,int canonicalFlag=1,int suffixFlag=0);
00087         // Calculate link-time component dependencies.  This function returns 
00088         // 0 on success, non-zero on error.  If an io-error occurs, the result 
00089         // will be negative, and this object will be left in an invalid state.
00090         // Otherwise the number of components involved in cyclic dependencies
00091         // will be returned.  Specific errors will be reported to the indicated
00092         // output stream stream (err).  A non-zero canocialFlag argument 
00093         // request a canonical representation of the dependencies -- i.e., 
00094         // containing no redundant, transitive edges.  Overriding this default 
00095         // behavior causes the complete (transitive) graph to remain.  Also by 
00096         // default, all file suffixes are removed.  Passing a non-zero value
00097         // for the optional suffixFlag argument causes individual component 
00098         // files to be treated as separate physical entities.
00099 
00100     // ACCESSORS
00101     int numComponents() const;
00102         // Return the total number of components in the system.  Note: This 
00103         // number is the sum of the number of local components and the 
00104         // number of external packages, and is NOT used to calculate ACD 
00105         // and NCCD.
00106 
00107     int numLocalComponents() const;
00108         // Return the number of (local) components -- i.e., with level > 0.
00109         // Note: it is this value that is used to calculate ACD and NCCD.
00110 
00111     int numPackages() const;
00112         // Return the number of entities with a level of 0.  Note a local
00113         // component that has no external dependencies at all (i.e., not even 
00114         // a standard compiler library include directive) will be incorrectly 
00115         // treated as a package.  Adding a fictitious dependency on the 
00116         // language ("C++") or the local directory (".") corrects this problem.
00117 
00118     int numLevels() const;
00119         // Return the number of (local) component levels in this subsystem.  
00120         // This value represent the "depth" of the (local) component 
00121         // dependency graph.
00122         
00123     int numCycles() const;
00124         // Return the number of local cycles in this subsystem
00125 
00126     int numMembers() const;
00127         // Return the number of cyclically dependent components in this 
00128         // subsystem.
00129 
00130     int ccd() const;
00131         // Return the Cumulative Component Dependency (CCD) for this subsystem
00132         // assuming level 0 entities have 0 weight.
00133 
00134     double acd() const;
00135         // Return the Average Component Dependency (ACD) for this subsystem
00136         // ignoring level 0 entities.
00137 
00138     double nccd() const;
00139         // Return the Normalized Cumulative Component Dependency (NCCD) for 
00140         // this subsystem ignoring level 0 entities.
00141 
00142     void printAliases(std::ostream& out) const;
00143         // Format all aliases in this environment to the specified output
00144         // stream.
00145 
00146     void printUnaliases(std::ostream& out) const;
00147         // Format all unaliases in this environment to the specified output 
00148         // stream.
00149 
00150     void printCycles(std::ostream& out) const;
00151         // Format all cyclically-dependent components to the specified 
00152         // output stream.
00153 
00154     void printLevels(std::ostream& out, int longFlag = 0, 
00155                                         int supressFlag = 0) const;
00156         // Format all components in levelized order to the specified output 
00157         // stream.  If the optional longFlag argument is specified with a
00158         // value other than 0, the dependencies of each component will be
00159         // explicitly delineated.  Otherwise, only the components and their
00160         // corresponding levels will be included.  By default, component
00161         // levels and identifying cycle suffixes will be included in the
00162         // output.  If the value of the optional supressFlag argument is 
00163         // not 0, only the component names will be supplied with levels 
00164         // delimited only by the extra blank line.
00165 
00166     void printSummary(std::ostream& out) const;
00167         // Format statistics characterizing dependencies within this package
00168         // to the specified output stream.  These statistics include
00169         // the following:
00170         // 
00171         //   Components  The number of (local) components with a level above
00172         //               0 (i.e., the number of components with at least one
00173         //               dependency).
00174         //
00175         //   Levels      The height of the component dependency graph.
00176         //
00177         //   Packages    The number of level 0 entities (i.e., the number of
00178         //               entities with no dependencies).
00179         //
00180         //   CCD         The sum over all (local) components C(i) of the
00181         //               number of (local) components required to link and 
00182         //               test C(i).
00183         //
00184         //   ACD         The ratio of the CCD to the number of (local)
00185         //               components.
00186         //
00187         //   NCCD        The ratio of CCD to the CCD of a (theoretical)
00188         //               balanced binary dependency tree with an equal
00189         //               number of local components.  (Note: For most
00190         //               high-quality package architectures, this number
00191         //               will not be much greater than 1.00).
00192         // 
00193         // In the presence of cyclic component dependencies, the members of 
00194         // each distinct maximal cycle are identified with a unique cycle 
00195         // index enclosed in angle brackets ('<' and '>').  An additional 
00196         // summary line preceding the others is formatted to the specified
00197         // output stream:
00198         // 
00199         //   Cycles      The number of distinct maximal cycles in the 
00200         //               component dependency graph.
00201         // 
00202         //   Members     The total number of components participating in
00203         //               cycles.
00204 };
00205 
00206 std::ostream& operator<<(std::ostream& out, const idep_LinkDep& dep);
00207         // Format all available information in the specified environment (dep)
00208         // to the specified output stream (out) including the following:
00209         //   unaliases: directories not to group 
00210         //     aliases: component file name mappings
00211         //      cycles: maximial interdependent subgraphs
00212         //      levels: components in levelized order along with dependencies 
00213         //     summary: statistics characterizing local component dependencies
00214 
00215 class idep_AliasIter_i;
00216 class idep_AliasIter {
00217     idep_AliasIter_i *d_this;
00218 
00219   private:
00220     idep_AliasIter(const idep_AliasIter&);              // not implemented
00221     idep_AliasIter& operator=(const idep_AliasIter&);   // not implemented
00222 
00223   public:
00224     // CREATORS
00225     idep_AliasIter(const idep_LinkDep& linkDep);
00226     ~idep_AliasIter();
00227 
00228     // MANIPULATORS
00229     void operator++(); 
00230 
00231     // ACCESSORS
00232     operator const void *() const; 
00233     const char *fromName() const; 
00234         // Return current alias Name.
00235 
00236     const char *toName() const; 
00237         // Return corresponding actual Name.
00238 };
00239 
00240 class idep_UnaliasIter_i;
00241 class idep_UnaliasIter {
00242     idep_UnaliasIter_i *d_this;
00243 
00244   private:
00245     idep_UnaliasIter(const idep_UnaliasIter&);              // not implemented
00246     idep_UnaliasIter& operator=(const idep_UnaliasIter&);   // not implemented
00247 
00248   public:
00249     // CREATORS
00250     idep_UnaliasIter(const idep_LinkDep& linkDep);
00251     ~idep_UnaliasIter();
00252 
00253     // MANIPULATORS
00254     void operator++(); 
00255 
00256     // ACCESSORS
00257     operator const void *() const; 
00258     const char *operator()() const; 
00259         // Return current unalias (directory) name.
00260 };
00261 
00262 class idep_CycleIter_i;
00263 class idep_CycleIter {
00264     idep_CycleIter_i *d_this;
00265 
00266     friend class idep_MemberIter;
00267 
00268   private:
00269     idep_CycleIter(const idep_CycleIter&);              // not implemented
00270     idep_CycleIter& operator=(const idep_CycleIter&);   // not implemented
00271 
00272   public:
00273     // CREATORS
00274     idep_CycleIter(const idep_LinkDep& linkDep);
00275     ~idep_CycleIter();
00276 
00277     // MANIPULATORS
00278     void operator++(); 
00279 
00280     // ACCESSORS
00281     operator const void *() const; 
00282     int weight() const;
00283         // Return the number of members in the current (maximal) cycle.
00284 
00285     int cycle() const;
00286         // Return the positive index of the current cycle.
00287 };
00288 
00289 class idep_MemberIter_i;
00290 class idep_MemberIter {
00291     idep_MemberIter_i *d_this;
00292 
00293   private:
00294     idep_MemberIter(const idep_MemberIter&);            // not implemented
00295     idep_MemberIter& operator=(const idep_MemberIter&); // not implemented
00296 
00297   public:
00298     // CREATORS
00299     idep_MemberIter(const idep_CycleIter& cycleIter);
00300     ~idep_MemberIter();
00301 
00302     // MANIPULATORS
00303     void operator++(); 
00304 
00305     // ACCESSORS
00306     operator const void *() const; 
00307     const char *operator()() const; 
00308         // Return the name of the current member of the current cycle.
00309 };
00310 
00311 class idep_LevelIter_i;
00312 class idep_LevelIter {
00313     idep_LevelIter_i *d_this;
00314 
00315     friend class idep_ComponentIter;
00316 
00317   private:
00318     idep_LevelIter(const idep_LevelIter&);              // not implemented
00319     idep_LevelIter& operator=(const idep_LevelIter&);   // not implemented
00320 
00321   public:
00322     // CREATORS
00323     idep_LevelIter(const idep_LinkDep& linkDep);
00324     ~idep_LevelIter();
00325 
00326     // MANIPULATORS
00327     void operator++(); 
00328 
00329     // ACCESSORS
00330     operator const void *() const; 
00331     int operator()() const; 
00332         // Return the index of the current level.
00333 };
00334 
00335 class idep_ComponentIter_i;
00336 class idep_ComponentIter {
00337     idep_ComponentIter_i *d_this;
00338 
00339     friend class idep_DependencyIter;
00340 
00341   private:
00342     idep_ComponentIter(const idep_ComponentIter&);              // not impl.
00343     idep_ComponentIter& operator=(const idep_ComponentIter&);   // not impl.
00344 
00345   public:
00346     // CREATORS
00347     idep_ComponentIter(const idep_LevelIter& levelIter);
00348     ~idep_ComponentIter();
00349 
00350     // MANIPULATORS
00351     void operator++(); 
00352 
00353     // ACCESSORS
00354     operator const void *() const; 
00355     const char *operator()() const; 
00356         // Return the name of the current component on the current level.
00357 
00358     int cycle() const; 
00359         // return the positive index of the current cycle or 0 if acyclic.
00360 };
00361 
00362 class idep_DependencyIter_i;
00363 class idep_DependencyIter {
00364     idep_DependencyIter_i *d_this;
00365 
00366   private:
00367     idep_DependencyIter(const idep_DependencyIter&);            // not impl.
00368     idep_DependencyIter& operator=(const idep_DependencyIter&); // not impl.
00369 
00370   public:
00371     // CREATORS
00372     idep_DependencyIter(const idep_ComponentIter& componentIter);
00373     ~idep_DependencyIter();
00374 
00375     // MANIPULATORS
00376     void operator++(); 
00377 
00378     // ACCESSORS
00379     operator const void *() const; 
00380     const char *operator()() const; 
00381         // Return the name of the current component on which the initial 
00382         // component depends.
00383 
00384     int level() const; 
00385         // Return the level of the current component.
00386 
00387     int cycle() const; 
00388         // return the positive index of the current cycle or 0 if acyclic.
00389 };
00390 
00391 #endif
00392 
00393 
00394 

Generated on Mon Feb 15 11:06:48 2010 for loon by  doxygen 1.3.9.1