[BACK]Return to dir.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/dir.c between version 1.26 and 1.27

version 1.26, 2000/09/14 13:46:44 version 1.27, 2000/09/14 13:52:41
Line 88 
Line 88 
 #include <dirent.h>  #include <dirent.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include "make.h"  #include "make.h"
 #include "hash.h"  
 #include "ohash.h"  #include "ohash.h"
 #include "dir.h"  #include "dir.h"
   
Line 184 
Line 183 
               bigmisses;      /* Sought by itself */                bigmisses;      /* Sought by itself */
   
 static Path       *dot;     /* contents of current directory */  static Path       *dot;     /* contents of current directory */
 static Hash_Table mtimes;   /* Results of doing a last-resort stat in  
   struct file_stamp {
           TIMESTAMP mtime;                /* time stamp... */
           char name[1];                   /* ...for that file.  */
   };
   
   static struct hash mtimes;  /* Results of doing a last-resort stat in
                              * Dir_FindFile -- if we have to go to the                               * Dir_FindFile -- if we have to go to the
                              * system to find the file, we might as well                               * system to find the file, we might as well
                              * have its mtime on record. XXX: If this is done                               * have its mtime on record. XXX: If this is done
Line 194 
Line 199 
                              * be two rules to update a single file, so this                               * be two rules to update a single file, so this
                              * should be ok, but... */                               * should be ok, but... */
   
   /* There are three distinct hash structures:
    * - to collate files's last modification times (global mtimes)
    * - to collate file names (in each Path structure)
    * - to collate known directories (global openDirectories).  */
   static struct hash_info stamp_info = { offsetof(struct file_stamp, name),
       NULL, hash_alloc, hash_free, element_alloc };
   
 static struct hash_info file_info = { 0,  static struct hash_info file_info = { 0,
     NULL, hash_alloc, hash_free, element_alloc };      NULL, hash_alloc, hash_free, element_alloc };
   
 static struct hash_info dir_info = { offsetof(Path, name),  static struct hash_info dir_info = { offsetof(Path, name),
     NULL, hash_alloc, hash_free, element_alloc };      NULL, hash_alloc, hash_free, element_alloc };
   
   static void record_stamp __P((const char *, TIMESTAMP));
 static void add_file __P((Path *, const char *));  static void add_file __P((Path *, const char *));
 static char *find_file_hash __P((Path *, const char *, const char *, u_int32_t));  static char *find_file_hash __P((Path *, const char *, const char *, u_int32_t));
   static struct file_stamp *find_stamp __P((const char *));
 static void free_hash __P((struct hash *));  static void free_hash __P((struct hash *));
   
 static Path *DirReaddir __P((const char *, const char *));  static Path *DirReaddir __P((const char *, const char *));
Line 212 
Line 226 
 static void DirPrintDir __P((void *));  static void DirPrintDir __P((void *));
   
 static void  static void
   record_stamp(file, t)
       const char          *file;
       TIMESTAMP           t;
   {
       unsigned            slot;
       const char          *end = NULL;
       struct file_stamp   *n;
   
       slot = hash_qlookupi(&mtimes, file, &end);
       n = hash_find(&mtimes, slot);
       if (n)
           n->mtime = t;
       else {
           n = hash_create_entry(&stamp_info, file, &end);
           n->mtime = t;
           hash_insert(&mtimes, slot, n);
       }
   }
   
   static struct file_stamp *
   find_stamp(file)
       const char          *file;
   {
       return hash_find(&mtimes, hash_qlookup(&mtimes, file));
   }
   
   static void
 add_file(p, file)  add_file(p, file)
     Path                *p;      Path                *p;
     const char          *file;      const char          *file;
Line 270 
Line 311 
 {  {
     Lst_Init(&dirSearchPath);      Lst_Init(&dirSearchPath);
     hash_init(&openDirectories, 4, &dir_info);      hash_init(&openDirectories, 4, &dir_info);
     Hash_InitTable(&mtimes, 0);      hash_init(&mtimes, 4, &stamp_info);
   
     dot = DirReaddir(".", NULL);      dot = DirReaddir(".", NULL);
   
Line 687 
Line 728 
     register char *cp;      /* index of first slash, if any */      register char *cp;      /* index of first slash, if any */
     Boolean       hasSlash; /* true if 'name' contains a / */      Boolean       hasSlash; /* true if 'name' contains a / */
     struct stat   stb;      /* Buffer for stat, if necessary */      struct stat   stb;      /* Buffer for stat, if necessary */
       struct file_stamp
                     *entry;   /* Entry for mtimes table */
     const char    *e;      const char    *e;
     u_int32_t     hv;      u_int32_t     hv;
     Hash_Entry    *entry;  
   
     /*      /*
      * Find the final component of the name and note whether it has a       * Find the final component of the name and note whether it has a
Line 817 
Line 859 
                 printf("checking %s...", file);                  printf("checking %s...", file);
   
             if (stat(file, &stb) == 0) {              if (stat(file, &stb) == 0) {
                   TIMESTAMP mtime;
   
                   grab_stat(stb, mtime);
                 if (DEBUG(DIR))                  if (DEBUG(DIR))
                     printf("got it.\n");                      printf("got it.\n");
   
Line 835 
Line 880 
                 if (DEBUG(DIR))                  if (DEBUG(DIR))
                     printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),                      printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                             file);                              file);
                 entry = Hash_CreateEntry(&mtimes, (char *) file,                  record_stamp(file, mtime);
                                          (Boolean *)NULL);  
                 /* XXX */  
                 Hash_SetValue(entry, (void *)((long)stb.st_mtime));  
                 nearmisses += 1;                  nearmisses += 1;
                 return file;                  return file;
             } else              } else
Line 890 
Line 932 
         printf("Looking for \"%s\"...", name);          printf("Looking for \"%s\"...", name);
   
     bigmisses += 1;      bigmisses += 1;
     entry = Hash_FindEntry(&mtimes, name);      entry = find_stamp(name);
     if (entry != (Hash_Entry *)NULL) {      if (entry != NULL) {
         if (DEBUG(DIR))          if (DEBUG(DIR))
             printf("got it (in mtime cache)\n");              printf("got it (in mtime cache)\n");
         return estrdup(name);          return estrdup(name);
     } else if (stat(name, &stb) == 0) {      } else if (stat(name, &stb) == 0) {
         entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);          TIMESTAMP mtime;
   
           grab_stat(stb, mtime);
         if (DEBUG(DIR))          if (DEBUG(DIR))
             printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),              printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                     name);                      name);
         /* XXX */          record_stamp(name, mtime);
         Hash_SetValue(entry, (void *)(long)stb.st_mtime);  
         return estrdup(name);          return estrdup(name);
     } else {      } else {
         if (DEBUG(DIR))          if (DEBUG(DIR))
Line 918 
Line 961 
  *      search path dirSearchPath.   *      search path dirSearchPath.
  *   *
  * Results:   * Results:
  *      TRUE if file exists.   *      The modification time or OUT_OF_DATE if it doesn't exist
  *   *
  * Side Effects:   * Side Effects:
  *      The modification time is placed in the node's mtime slot.   *      The modification time is placed in the node's mtime slot.
Line 926 
Line 969 
  *      found one for it, the full name is placed in the path slot.   *      found one for it, the full name is placed in the path slot.
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 Boolean  TIMESTAMP
 Dir_MTime(gn)  Dir_MTime(gn)
     GNode         *gn;        /* the file whose modification time is      GNode         *gn;        /* the file whose modification time is
                                * desired */                                 * desired */
 {  {
     char          *fullName;  /* the full pathname of name */      char          *fullName;  /* the full pathname of name */
     struct stat   stb;        /* buffer for finding the mod time */      struct stat   stb;        /* buffer for finding the mod time */
     Hash_Entry    *entry;      struct file_stamp
     Boolean       exists;                    *entry;
       unsigned int  slot;
       TIMESTAMP     mtime;
   
     if (gn->type & OP_ARCHV)      if (gn->type & OP_ARCHV)
         return Arch_MTime(gn);          return Arch_MTime(gn);
     else if (gn->path == NULL)      if (gn->path == NULL) {
         fullName = Dir_FindFile(gn->name, &dirSearchPath);          fullName = Dir_FindFile(gn->name, &dirSearchPath);
     else          if (fullName == NULL)
               fullName = estrdup(gn->name);
       } else
         fullName = gn->path;          fullName = gn->path;
   
     if (fullName == (char *)NULL) {      slot = hash_qlookup(&mtimes, fullName);
         fullName = estrdup(gn->name);      entry = hash_find(&mtimes, slot);
     }      if (entry != NULL) {
           /* Only do this once -- the second time folks are checking to
     entry = Hash_FindEntry(&mtimes, fullName);  
     if (entry != (Hash_Entry *)NULL) {  
         /*  
          * Only do this once -- the second time folks are checking to  
          * see if the file was actually updated, so we need to actually go           * see if the file was actually updated, so we need to actually go
          * to the file system.           * to the file system.  */
          */          if (DEBUG(DIR))
         if (DEBUG(DIR)) {  
             printf("Using cached time %s for %s\n",              printf("Using cached time %s for %s\n",
                     Targ_FmtTime((time_t)(long)Hash_GetValue(entry)), fullName);                      Targ_FmtTime(entry->mtime), fullName);
         }          mtime = entry->mtime;
         stb.st_mtime = (time_t)(long)Hash_GetValue(entry);          free(entry);
         Hash_DeleteEntry(&mtimes, entry);          hash_remove(&mtimes, slot);
         exists = TRUE;      } else if (stat(fullName, &stb) == 0)
     } else if (stat (fullName, &stb) == 0) {          grab_stat(stb, mtime);
         /* XXX forces make to differentiate between the epoch and      else {
          * non-existent files by kludging the timestamp slightly. */  
         if (stb.st_mtime == OUT_OF_DATE)  
                 stb.st_mtime++;  
         exists = TRUE;  
     } else {  
         if (gn->type & OP_MEMBER) {          if (gn->type & OP_MEMBER) {
             if (fullName != gn->path)              if (fullName != gn->path)
                 free(fullName);                  free(fullName);
             return Arch_MemMTime (gn);              return Arch_MemMTime (gn);
         } else {          } else
             stb.st_mtime = OUT_OF_DATE;              set_out_of_date(mtime);
             exists = FALSE;  
         }  
     }      }
     if (fullName && gn->path == (char *)NULL) {      if (fullName && gn->path == NULL)
         gn->path = fullName;          gn->path = fullName;
     }  
   
     gn->mtime = stb.st_mtime;      gn->mtime = mtime;
     return exists;      return gn->mtime;
 }  }
   
 /* Read a directory, either from the disk, or from the cache.  */  /* Read a directory, either from the disk, or from the cache.  */

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27