Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

file.h

Go to the documentation of this file.
00001 /************ file.h **************
00002 $Revision: 1.2 $
00003 $Author: pbergen $
00004 $Date: 2001/05/13 21:56:03 $
00005 ***********************************/
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <sys/stat.h>
00011 #include <unistd.h>
00012 
00013 #ifndef _FILE_H_
00014 #define _FILE_H_
00015 
00018 #define MAXLINES 256
00019 
00021 #define MAXDEPEND 512
00022 
00024 #define MAXINCLUDEPATHS 2048
00025 
00026 #define EXCLUDELISTS 3
00027 
00028 
00030 #define EXTUNKNOWN 0
00031 
00032 #define EXTH       1
00033 
00034 #define EXTCPP     2
00035 
00036 #define EXTOBJ     3
00037 
00038 #include "makeutilities.h"
00039 
00041 static class File *fileRoot=NULL;
00042 
00053 class File
00054 {
00055  public:
00061   File(const char *fname)
00062     {
00063       ageChecked=false;
00064       rebuild=false;
00065       scanned=false;
00066       compiled=false;
00067       dotted=false;
00068       subDotted=false;
00069       objected=false;
00070       included=false;
00071       tagged=false;
00072       hasClass=true;
00073       hFileCount=0;
00074       cppFileCount=0;
00075 
00076       for(int i=0;i<EXCLUDELISTS;i++)
00077         {
00078           excluded[i]=false;
00079         }
00080        
00081       objFile=NULL;
00082       fullName=NULL;
00083       fileName=NULL;
00084       dotName=NULL;
00085       path=NULL;
00086       next=NULL;
00087 
00088       fullName=MakeUtilities::getStrCopy(fname);
00089 
00090       if (!getStats())
00091         {
00092           extension=EXTUNKNOWN;
00093           disectFilename();
00094           if (extension==EXTUNKNOWN)
00095             {
00096               delete [] path;
00097               path=NULL;
00098               delete [] fileName;
00099               fileName=NULL;
00100             }
00101           else
00102             {
00103               objFile=NULL;
00104               for(int i=0;i<MAXDEPEND;i++)
00105                 {
00106                   hFile[i]=NULL;
00107                   cppFile[i]=NULL;
00108                 }
00109               guess();
00110             }
00111         }
00112     }
00113 
00117   ~File()
00118     {
00119       delete [] fullName;
00120       /* No need since it is part of path! */
00121       // delete [] fileName; 
00122       delete [] path;
00123       delete next;
00124     }
00125 
00132    void setGraphExcluded(int n, bool state)
00133      {
00134         if (n<EXCLUDELISTS)
00135           {
00136              excluded[n]=state;
00137           }
00138      }
00139    
00144   const char *getFileName(void)
00145     {
00146       return fileName;
00147     }
00148 
00153   const char *getPath(void)
00154     {
00155       return path;
00156     }
00157 
00161   const char *getFullName(void)
00162     {
00163       return fullName;
00164     }
00165 
00169   File *getNext()
00170     {
00171       return next;
00172     }
00173 
00178   int getExtension(void)
00179     {
00180       return extension;
00181     }
00182 
00189   File *addNextFile(File *file)
00190     {
00191       if (file)
00192         {
00193           if (next)
00194             {
00195               file->next=next;
00196             }
00197           next=file;
00198         }
00199       return file;
00200     }
00201 
00215   void resolveDependencies(void)
00216     {
00217       bool classDef=false;
00218       if (!scanned)
00219         {
00220           if (extension==EXTH || extension==EXTCPP)
00221             {
00222               char buf[MAXLINES],*p,*q;
00223               int line=0;
00224               FILE *fin=fopen(fullName,"r");
00225               if (fin)
00226                 {
00227                   while (fgets(buf,MAXLINES,fin))
00228                     {
00229                       line++;
00230                       if (!strncmp(buf,"#include",8))
00231                         {
00232                           p=strchr(buf+9,'\"');
00233                           if (p)
00234                             {
00235                               q=strchr(p+1,'\"');
00236                               if (q)
00237                                 {
00238                                   *q=0;
00239                                   addDependency(getFileNoPath(p+1));
00240                                 }
00241                             }
00242                           else
00243                             {
00244                               p=strchr(buf+9,'<');
00245                               if (p)
00246                                 {
00247                                   q=strchr(p+1,'>');
00248                                   if (q)
00249                                     {                       
00250                                       *q=0;
00251                                       addDependency(getFileNoPath(p+1));
00252                                     }
00253                                 }
00254                             }
00255                         }
00256                       else if (!strncmp(buf,"MAKER_ADD_DEPENDENCY=",21))
00257                         {
00258                           p=strchr(buf+21,'\"');
00259                           if (p)
00260                             {
00261                               q=strchr(p+1,'\"');
00262                               if (q)
00263                                 {
00264                                   *q=0;
00265                                   char *tmpPath=warpPath(p+1);
00266                                   bool aCopy=false;
00267                                   File *tmp=addDependency(findFile(tmpPath,
00268                                                                    NULL,
00269                                                                    aCopy));
00270                                   if (!tmp)
00271                                     {
00272                                       printf("Dependency not found: %s\n",
00273                                              tmpPath);
00274                                     }
00275                                   if (!aCopy)
00276                                     {
00277                                       addFile(tmp);
00278                                     }
00279                                 }
00280                             }
00281                         }
00282                       else
00283                         {
00284                           if (!strncmp(buf,"class",5))
00285                             {
00286                               classDef=true;
00287                               break;
00288                             }
00289                         }
00290                       if (line>128)
00291                         {
00292                           break;
00293                         }
00294                     }
00295                   fclose(fin);
00296                 }
00297             }
00298           scanned=true;
00299           for(int i=0;i<cppFileCount;i++)
00300             {
00301               cppFile[i]->resolveDependencies();
00302             }
00303           for(int i=0;i<hFileCount;i++)
00304             {
00305               hFile[i]->resolveDependencies();
00306             }
00307         }
00308       hasClass&=classDef;
00309     }
00310 
00315   void print(bool recursive=false)
00316     {
00317       printf("Fullname: %s %s\n",fullName,hasClass?"(has class)":"");
00318       printf("This: 0x%X            %s\n",(int)this,rebuild?"REBUILD":"");
00319       printf("Path and name: %s + %s\n",path,fileName);    
00320       printf("ObjFile: 0x%X\n",(int)objFile);
00321       printf("CppFiles:\t0x%X\n",(int)cppFile[0]);
00322       for(int i=1;i<cppFileCount;i++)
00323         {
00324           printf("\t\t0x%X (%s)\n",(int)cppFile[i],cppFile[i]->fileName);
00325         }
00326       printf("Next: 0x%X\n",(int)next);
00327       printf("Dependecies: %d\n",hFileCount);
00328       for(int i=0;i<hFileCount;i++)
00329         {
00330           printf("%.7d: 0x%X (%s)\n",i,(int)hFile[i],hFile[i]->fileName);
00331         }
00332       if (recursive && next)
00333         {
00334           next->print(recursive);
00335         }
00336     }
00337 
00342   void tagRebuild(void)
00343     {
00344       if (tagged)
00345         {
00346           return;
00347         }
00348       tagged=true;
00349       if (extension==EXTCPP)
00350         {
00351           rebuild=false;
00352           if (!objFile)
00353             {
00354               rebuild=true;
00355             }
00356           else
00357             {
00358               clearAgeChecked();
00359               if (isObjFileOld(objFile->stats.st_mtime) /*st_ctime?*/)
00360                 {
00361                   rebuild=true;
00362                 }
00363             }
00364         }
00365       else if (extension==EXTH)
00366         {
00367           for(int i=0;i<cppFileCount;i++)
00368             {
00369               cppFile[i]->tagRebuild();
00370             }
00371         }
00372       for(int i=0;i<hFileCount;i++)
00373         {
00374           hFile[i]->tagRebuild();
00375         }
00376     }
00377 
00385   void writeCompilation(FILE *stream,const char *compiler)
00386     {
00387       if (compiled)
00388         {
00389           return;
00390         }
00391       compiled=true;
00392       for(int i=0;i<cppFileCount;i++)
00393         {
00394           cppFile[i]->writeCompilation(stream,compiler);
00395         }
00396       for(int i=0;i<hFileCount;i++)
00397         {
00398           hFile[i]->writeCompilation(stream,compiler);
00399         }
00400       if (extension==EXTCPP && rebuild)
00401         {
00402           char *output=MakeUtilities::changeExtension(fullName,"o");
00403           fprintf(stream,"echo COMPILING: %s\n",fullName);
00404           fprintf(stream,"%s -c -o %s",compiler,output);
00405           delete [] output;
00406 
00407           int count=0;
00408           char *paths[MAXINCLUDEPATHS];
00409           File::clearIncluded();
00410           getIncludePath(paths,count);
00411           for(int i=0;i<count;i++)
00412             {
00413               fprintf(stream," -I%s",paths[i]);
00414             }
00415           fprintf(stream," %s\n",fullName);
00416           fprintf(stream,"if [ $? -ne 0 ]; then\nexit 1\nfi\n");
00417         }
00418     }
00419 
00431   void writeLink(FILE* stream, const char *executable,
00432                  const char *linker, const char *linkerTail)
00433     {
00434       fprintf(stream,"echo LINKING: %s\n",executable);
00435       fprintf(stream,"%s -o %s",linker,executable);
00436       writeObjects(stream);
00437       fprintf(stream," %s\n",linkerTail);
00438     }
00439 
00446   bool writeDot(const char *dotFile)
00447   {
00448     /* Build big messy graph. */
00449     char *fname=MakeUtilities::changeExtension(dotFile,
00450                                                "all.dot");
00451     FILE *fout=fopen(fname,"w+");
00452     if (fout)
00453       {
00454         fprintf(fout,"digraph \"All files\" {\n");
00455         fprintf(fout,"size=\"7.5,11\";ratio=fill;rankdir=LR;\n");
00456         fprintf(fout,"node [fontsize=11];\n");
00457 
00458         clearDotted();
00459         writeDotNodes(fout,true);
00460         fprintf(fout,"}\n");
00461         fclose(fout);
00462         noDuplicates(fname);
00463       }
00464     else
00465       {
00466         delete [] fname;
00467         return false;
00468       }
00469     delete [] fname;
00470 
00471     /* Build organized graph of CPPs and Hs with no CPP and a class. */
00472     fname=MakeUtilities::changeExtension(dotFile,
00473                                      "class.dot");
00474     fout=fopen(fname,"w+");
00475     if (fout)
00476       {
00477         fprintf(fout,"digraph \"All source files\" {\n");
00478         fprintf(fout,"size=\"7.5,11\";ratio=fill;rankdir=LR;\n");
00479         fprintf(fout,"node [fontsize=11];\n");
00480 
00481         clearDotted();  
00482         clearSubDotted();
00483         writeDotCPPs2(fout);
00484 
00485         fprintf(fout,"}\n");
00486         fclose(fout);
00487         noDuplicates(fname);
00488       }
00489     else
00490       {
00491         return false;
00492       }
00493     delete [] fname;
00494 
00495     /* Build organized graph of CPPs only. */
00496     fout=fopen(dotFile,"w+");
00497     if (fout)
00498       {
00499         fprintf(fout,"digraph \"All source files\" {\n");
00500         fprintf(fout,"size=\"7.5,11\";ratio=fill;rankdir=LR;\n");
00501         fprintf(fout,"node [fontsize=11];\n");
00502 
00503         clearDotted();  
00504         clearSubDotted();
00505         writeDotCPPs(fout,NULL);
00506 
00507         fprintf(fout,"}\n");
00508         fclose(fout);
00509         noDuplicates(dotFile);
00510       }
00511     else
00512       {
00513         return false;
00514       }
00515     return true;
00516   }
00517 
00518 private:
00519 
00528   void noDuplicates(const char *fname)
00529   {
00530     FILE *fin=fopen(fname,"r");
00531     if (fin)
00532       {
00533         char **lines,buf[5000];
00534         int linesC=0,i,newLine,c=0;
00535         lines=new char*[100000];
00536         while(fgets(buf,5000,fin))
00537           {
00538             c++;
00539             newLine=true;
00540             for(i=0;i<linesC;i++)
00541               {
00542                 if (!strcmp(lines[i],buf))
00543                   {
00544                     newLine=false;
00545                     break;
00546                   }
00547               }
00548             if (newLine)
00549               {
00550                 lines[linesC]=new char[1+strlen(buf)];
00551                 strcpy(lines[i],buf);
00552                 linesC++;
00553                 if (linesC>100000)
00554                   {
00555                     printf("noDuplicates 100000 lines capacity exceeded. "
00556                            "Duplicates were not removed.\n");
00557                     fclose(fin);
00558                     return;
00559                   }
00560               }
00561           }
00562         fclose(fin);
00563         FILE *fout=fopen(fname,"w+");
00564         for(i=0;i<linesC;i++)
00565           {
00566             if (fout)
00567               {
00568                 fputs(lines[i],fout);
00569               }
00570             delete [] lines[i];
00571           }
00572         delete lines;
00573         if (fout)
00574           {
00575             fclose(fout);
00576           }
00577       }
00578   }
00579 
00584   char *warpPath(char *incPath)
00585   {
00586     static char tmp[8000],*p;
00587     tmp[0]=0;
00588     
00589     if (!incPath || !path)
00590       {
00591         return incPath;
00592       }
00593 
00594     strcpy(tmp,path);
00595     char *addPath=incPath;
00596     while (!strncmp(addPath,"../",3))
00597       { 
00598         p=MakeUtilities::strchrReverse(tmp,'/');
00599         if (p)
00600           {
00601             *p=0;
00602           }
00603         else 
00604           {
00605             if (!*tmp)
00606               {
00607                 printf("Cannot resolve relative path. Goes below /.\n");
00608                 return incPath;
00609               }
00610             else
00611               {
00612                 *tmp=0;
00613               }
00614           }
00615         addPath=strchr(addPath,'/')+1;
00616       }
00617     if (tmp[strlen(tmp)]!='/')
00618       {
00619         strcat(tmp,"/");
00620       }
00621     strcat(tmp,addPath);
00622     return tmp;    
00623   }
00624 
00630   static const char *stripPath(const char *incPath)
00631   {
00632     if (!incPath)
00633       {
00634         return incPath;
00635       }
00636 
00637     char *p=MakeUtilities::strchrReverse(incPath,'/');
00638     if (p)
00639       {
00640         return p+1;
00641       }
00642     return incPath;
00643   }
00644 
00651   void writeDotNodes(FILE *stream, bool followCPP=false)
00652   {
00653     if (dotted)
00654       {
00655         return;
00656       }
00657     dotted=true;
00658 
00659     if (extension==EXTCPP)
00660       {
00661         if (rebuild)
00662           {
00663             fprintf(stream,"\"%s\" [label=\"%s\\n(rebuild)\", style=filled, "
00664                     "color=lightgray, shape=box];",fileName,fileName);
00665           }
00666         else
00667           {
00668             fprintf(stream,"\"%s\" [shape=box];\n",fileName);
00669           }
00670       }
00671     if (cppFileCount)
00672       {
00673         if (followCPP)
00674           {
00675             for(int i=0;i<cppFileCount;i++)
00676               {
00677                 cppFile[i]->writeDotNodes(stream,followCPP);
00678               }
00679           }
00680         for(int i=0;i<cppFileCount;i++)
00681           {
00682             fprintf(stream,"\"%s\" -> \"%s\";\n",
00683                     fileName,cppFile[i]->fileName);
00684           }
00685       }
00686     if (hFileCount)
00687       {
00688         fprintf(stream,"\"%s\" -> { ",fileName);
00689         for (int i=0;i<hFileCount;i++)
00690           {
00691             fprintf(stream,"\"%s\"%c",hFile[i]->fileName,
00692                     (i+1)==hFileCount?' ':';');
00693           }
00694         fprintf(stream,"}\n");
00695         for(int i=0;i<hFileCount;i++)
00696           {
00697             hFile[i]->writeDotNodes(stream,followCPP);
00698           }
00699       }
00700   }
00701 
00709   void writeDotCPPs(FILE *stream, File *from)
00710   {
00711     if (extension==EXTCPP && from)
00712       {
00713         fprintf(stream,"\"%s\" -> \"%s\";\n",from->fileName,fileName);
00714       }
00715     if (dotted)
00716       {
00717         return;
00718       }
00719     dotted=true;
00720     if (extension==EXTCPP)
00721       {
00722         if (rebuild)
00723           {
00724             fprintf(stream,"\"%s\" [label=\"%s\\n(rebuild)\", style=filled, "
00725                     "color=lightgray, shape=box];",fileName,fileName);
00726           }
00727         else
00728           {
00729             fprintf(stream,"\"%s\" [shape=box];\n",fileName);
00730           }
00731         from=this;
00732       }
00733     for(int i=0;i<cppFileCount;i++)
00734       {
00735         cppFile[i]->writeDotCPPs(stream,from);
00736       }
00737     for(int i=0;i<hFileCount;i++)
00738       {
00739         hFile[i]->writeDotCPPs(stream,from);
00740       }
00741   }
00742 
00751   void writeDotCPPs2(FILE *stream)
00752   {
00753     if (dotted)
00754       {
00755         return;
00756       }
00757     dotted=true;
00758     if (extension==EXTCPP || hasClass)
00759       {
00760         if (rebuild)
00761           {
00762             fprintf(stream,"\"%s\" [label=\"%s\\n(rebuild%s)\", "
00763                     "style=filled, color=lightgray, shape=box];",
00764                     fileName,fileName,excluded[1]?", excluded":"");
00765           }
00766         else
00767           {
00768              if (excluded[1])
00769                {
00770                   fprintf(stream,"\"%s\" [label=\"%s\\n(excluded)\", "
00771                           "shape=box];",
00772                           fileName,fileName);
00773                }
00774              else
00775                {
00776                   fprintf(stream,"\"%s\" [shape=box];\n",fileName);
00777                }
00778           }
00779         for(int i=0;i<cppFileCount;i++)
00780           {
00781             clearSubDotted();
00782             cppFile[i]->writeDotCPPsubs(stream,this);
00783           }
00784         for(int i=0;i<hFileCount;i++)
00785           {
00786             clearSubDotted();
00787              bool isMine=false;
00788              for (int k=0;k<hFile[i]->cppFileCount;k++)
00789                {
00790                   if (this==hFile[i]->cppFile[k])
00791                     {
00792                        isMine=true;
00793                        break;
00794                     }
00795                }
00796             hFile[i]->writeDotCPPsubs(stream,this,!isMine);
00797           }
00798       }
00799 
00800     for(int i=0;i<cppFileCount;i++)
00801       {
00802         cppFile[i]->writeDotCPPs2(stream);
00803       }
00804     for(int i=0;i<hFileCount;i++)
00805       {
00806         hFile[i]->writeDotCPPs2(stream);
00807       }
00808   }
00809 
00817   void writeDotCPPsubs(FILE *stream, File *from,bool CPPOnly=false)
00818   {
00819     if (hasClass || extension==EXTCPP)
00820       {
00821         if (from!=this && !from->excluded[1] && !excluded[1])
00822           {
00823             fprintf(stream,"\"%s\" -> \"%s\";\n",from->fileName,fileName);
00824           }
00825         return;
00826       }
00827     for(int i=0;i<cppFileCount;i++)
00828       {
00829         if (from!=cppFile[i] && !from->excluded[1] && !cppFile[i]->excluded[1])
00830           {
00831             fprintf(stream,"\"%s\" -> \"%s\";\n",
00832                     from->fileName,cppFile[i]->fileName);
00833           }
00834       }
00835     if (!CPPOnly)
00836       {
00837         for(int i=0;i<hFileCount;i++)
00838           {
00839             hFile[i]->writeDotCPPsubs(stream,from,true);
00840           }
00841       }
00842   }
00843 
00852   void getIncludePath(char **paths, int &count)
00853     {
00854       if (included)
00855         {
00856           return;
00857         }
00858       included=true;
00859       bool insert=true;
00860       for(int i=0;i<count;i++)
00861         {
00862           if (!strcmp(path,paths[i]))
00863             {
00864               insert=false;
00865               break;
00866             }
00867         }
00868       if (insert)
00869         {
00870           if (path && strlen(path))
00871             {
00872               paths[count]=MakeUtilities::getStrCopy(path);
00873               count++;
00874               if (count==MAXINCLUDEPATHS)
00875                 {
00876                   printf("The include paths have overflown the buffer.\n");
00877                   _exit(-1);
00878                 }
00879             }
00880         }
00881       for(int i=0;i<hFileCount;i++)
00882         {
00883           hFile[i]->getIncludePath(paths,count);
00884         }
00885     }
00886 
00892   void writeObjects(FILE *stream)
00893     {
00894       if (objected)
00895         {
00896           return;
00897         }
00898       objected=true;
00899       if (extension==EXTCPP)
00900         {
00901           char *object=MakeUtilities::changeExtension(fullName,"o");
00902           fprintf(stream," %s",object);
00903           delete [] object;
00904         }
00905       for(int i=0;i<cppFileCount;i++)
00906         {
00907           cppFile[i]->writeObjects(stream);
00908         }
00909       for(int i=0;i<hFileCount;i++)
00910         {
00911           hFile[i]->writeObjects(stream);
00912         }
00913     }
00914 
00921   bool isObjFileOld(time_t t)
00922     {
00923       if (isNewer(t))
00924         {
00925           return true;
00926         }
00927       if (ageChecked)
00928         {
00929           return false;
00930         }
00931       ageChecked=true;
00932       for (int i=0;i<hFileCount;i++)
00933         {
00934           if (hFile[i]->isObjFileOld(t))
00935             {
00936               return true;
00937             }
00938         }
00939       return false;
00940     }
00941 
00946   bool isNewer(time_t t)
00947     {
00948       return (t<stats.st_mtime);
00949     }
00950 
00958   File *addDependency(File *file)
00959     {
00960       if (file)
00961         {
00962           if (file->extension==EXTH)
00963             {
00964               for (int i=0;i<hFileCount;i++)
00965                 {
00966                   if (hFile[i]==file)
00967                     {
00968                       /* No need to add the same file twice. */
00969                       return file;
00970                     }
00971                 }
00972               hFile[hFileCount]=file;
00973               hFileCount++;
00974               if (hFileCount==MAXDEPEND)
00975                 {
00976                   printf("Cannot insert dependency. Buffer overflow. "
00977                          "Probably files are including each other "
00978                          "recursively.\n");
00979                   _exit(-1);
00980                 }
00981             }
00982           else if (file->extension==EXTCPP)
00983             {
00984               for (int i=0;i<cppFileCount;i++)
00985                 {
00986                   if (cppFile[i]==file)
00987                     {
00988                       /* No need to add the same file twice. */
00989                       return file;
00990                     }
00991                 }
00992               cppFile[cppFileCount]=file;
00993               cppFileCount++;
00994               if (cppFileCount==MAXDEPEND)
00995                 {
00996                   printf("Cannot insert dependency. Buffer overflow. "
00997                          "Probably files are including each other "
00998                          "recursively.\n");
00999                   _exit(-1);
01000                 }
01001             }
01002           else if (file->extension==EXTOBJ)
01003             {
01004               if (objFile)
01005                 {
01006                   printf("Cannot add more than one object file to a "
01007                          "source file.\n");
01008                   _exit(-1);
01009                 }
01010               objFile=file;
01011             }
01012         }
01013       return file;
01014     }
01015 
01020   int getStats(void)
01021     {
01022       return stat(fullName,&stats);
01023     }
01024 
01028   void disectFilename(void)
01029     {
01030       delete [] path;
01031       /* No need since it is part of path! */
01032       // delete [] fileName;
01033       path=MakeUtilities::getStrCopy(fullName);
01034       fileName=MakeUtilities::strchrReverse(path,'/');
01035       if (!fileName)
01036         {
01037           fileName=path;
01038           path=NULL;
01039         }
01040       else
01041         {
01042           *fileName=0;
01043           fileName++;
01044         }
01045       char *p=MakeUtilities::strchrReverse(fullName,'.');
01046       if (p)
01047         {
01048           p++;
01049           if (!strcmp(p,"h") || !strcmp(p,"hpp") || !strcmp(p,"hh"))
01050             {
01051               extension=EXTH;
01052             }
01053           else if (!strcmp(p,"c") || !strcmp(p,"cpp") || !strcmp(p,"cc"))
01054             {
01055               extension=EXTCPP;
01056             }
01057           else if (!strcmp(p,"o") || !strcmp(p,"obj"))
01058             {
01059               extension=EXTOBJ;
01060             }
01061 
01062           p=MakeUtilities::strchrReverse(fileName,'.');
01063           if (p);
01064             {
01065               *p=0;
01066               dotName=MakeUtilities::getStrCopy(fileName,4);
01067               *p='.';
01068               strcat(dotName,"_");
01069               strcat(dotName,p+1);
01070             }
01071         }
01072     }
01073 
01078   void guess(void)
01079     {
01080       bool aCopy=false;
01081       File *tmp;
01082       if (extension==EXTH)
01083         {
01084           tmp=addDependency(findFile(fullName,"cpp",aCopy));
01085           if (!aCopy)
01086             {
01087               addFile(tmp);
01088             }
01089           if (tmp)
01090             {
01091               hasClass=false;
01092             }
01093 
01094           tmp=addDependency(findFile(fullName,"cc",aCopy));
01095           if (!aCopy)
01096             {
01097               addFile(tmp);
01098             }
01099           if (tmp)
01100             {
01101               hasClass=false;
01102             }
01103 
01104           tmp=addDependency(findFile(fullName,"c",aCopy));
01105           if (!aCopy)
01106             {
01107               addFile(tmp);
01108             }
01109           if (tmp)
01110             {
01111               hasClass=false;
01112             }
01113         }
01114       if (extension==EXTCPP)
01115         {
01116           tmp=addDependency(findFile(fullName,"o",aCopy));
01117           if (!aCopy)
01118             {
01119               addFile(tmp);
01120             }
01121 
01122           tmp=addDependency(findFile(fullName,"obj",aCopy));
01123           if (!aCopy)
01124             {
01125               addFile(tmp);
01126             }
01127         }
01128     }
01129 
01135   static void clearIncluded(void)
01136     {
01137       File *f=fileRoot;
01138       while (f)
01139         {
01140           f->included=false;
01141           f=f->next;
01142         }
01143     }
01144 
01150   static void clearAgeChecked(void)
01151     {
01152       File *f=fileRoot;
01153       while (f)
01154         {
01155           f->ageChecked=false;
01156           f=f->next;
01157         }
01158     }
01159 
01165   static void clearDotted(void)
01166     {
01167       File *f=fileRoot;
01168       while (f)
01169         {
01170           f->dotted=false;
01171           f=f->next;
01172         }
01173     }
01174 
01180   static void clearSubDotted(void)
01181     {
01182       File *f=fileRoot;
01183       while (f)
01184         {
01185           f->subDotted=false;
01186           f=f->next;
01187         }
01188     }
01189 
01198   static File *findFile(const char *fname, const char *ext, bool &aCopy)
01199     {
01200       char *newName=MakeUtilities::getStrCopy(fname,ext?strlen(ext)+1:0);
01201       if (ext)
01202         {
01203           char *p=MakeUtilities::strchrReverse(newName,'.');
01204           if (!p)
01205             {
01206               p=newName+strlen(newName)+1;
01207               *p='.';
01208             }
01209           p[1]=0;
01210           strcat(newName,ext);
01211         }
01212       File *res=getFileNoPath(newName);
01213       if (res)
01214         {
01215           delete [] newName;
01216           aCopy=true;
01217           return res;
01218         }
01219       aCopy=false;
01220       res=new File(newName);
01221       delete [] newName;
01222       if (!res->fileName)
01223         {
01224           delete res;
01225           res=NULL;
01226         }
01227       return res;
01228     }
01229 
01239   static File *getFileNoPath(const char *fname)
01240     {
01241       File *f=fileRoot;
01242       while (f)
01243         {
01244           if (!strcmp(f->fileName,stripPath(fname)))
01245             {
01246               return f;
01247             }
01248           f=f->next;
01249         }
01250       return NULL;
01251     }
01252 
01253 public:
01259   static void addFile(File *file)
01260     {
01261       if (file)
01262         {
01263           if (fileRoot)
01264             {
01265               fileRoot->addNextFile(file);
01266             }
01267           else
01268             {
01269               fileRoot=file;
01270             }
01271         }
01272     }
01273 
01278   static void printRegistered(void)
01279     {
01280       File *f=fileRoot;
01281       while (f)
01282         {
01283           f->print(false);
01284           f=f->next;
01285         }
01286     }
01287 
01288 private:
01289   char *fullName, *path, *fileName, *dotName;
01290   int extension;
01291   struct stat stats;
01292   File *objFile;
01293   File *cppFile[MAXDEPEND];
01294   File *hFile[MAXDEPEND];
01295   File *next;
01296   bool rebuild,scanned,tagged,compiled,objected,
01297     included,dotted,subDotted,ageChecked;
01300   bool excluded[EXCLUDELISTS];
01303   bool hasClass;
01304   int hFileCount,cppFileCount;
01305 };
01306 
01307 #endif
01308 
01309 /*************** LOG *****************
01310  $Log: file.h,v $
01311  Revision 1.2  2001/05/13 21:56:03  pbergen
01312  Improved dot output.
01313 
01314  Revision 1.16  2001/05/09 14:00:36  pb
01315  Removed recusion bug in tagRebuild (isObjFileOld).
01316 
01317  Revision 1.15  2001/05/09 13:25:54  pb
01318  Fixed the bug caused in warpPath by the prior bugfix.
01319 
01320  Revision 1.14  2001/05/09 13:15:07  pb
01321  Fixed a bug in warpPath.
01322 
01323  Revision 1.13  2001/05/09 12:22:49  pb
01324  Reversed the compilation.
01325 
01326  Revision 1.12  2001/05/09 12:10:56  pb
01327  Cleaned up the source. Added new directive MAKER_ADD_DEPENDENCY.
01328  Added documentation.
01329 
01330  Revision 1.11  2001/05/08 18:10:18  pb
01331  Fixed a couple of bugs.
01332 
01333  Revision 1.10  2001/05/08 14:21:28  pb
01334  Works 100% and lots of new features.
01335 
01336  Revision 1.9  2001/05/07 17:42:00  pb
01337  Added conditional break if compile errors occur.
01338 
01339  Revision 1.8  2001/05/07 17:17:15  pb
01340  It really works!
01341 
01342  Revision 1.7  2001/05/01 07:33:25  pb
01343  Nothing really.
01344 
01345  Revision 1.6  2001/04/30 13:20:42  arnum
01346  Misc. small changes to unitests and xatof handles errors and matches strings
01347         
01348  Revision 1.5  2001/04/28 14:35:10  pb
01349  Added dot-output.
01350                 
01351  Revision 1.4  2001/04/28 10:11:19  pb
01352  A -perhaps- working version.
01353                 
01354  Revision 1.3  2001/04/27 14:23:36  pb
01355  It seems to start working. But there is a bug in building dependencies.
01356 
01357  Revision 1.2  2001/04/27 13:49:28  pb
01358  Added headers and footers.
01359 *************************************/

Generated at Mon May 14 00:45:43 2001 for Maker by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001