[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.24 and 1.25

version 1.24, 2000/09/14 13:32:06 version 1.25, 2000/09/14 13:43:30
Line 82 
Line 82 
  *      Dir_PrintDirectories    Print stats about the directory cache.   *      Dir_PrintDirectories    Print stats about the directory cache.
  */   */
   
   #include <stddef.h>
 #include <stdio.h>  #include <stdio.h>
 #include <sys/types.h>  #include <sys/types.h>
 #include <dirent.h>  #include <dirent.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include "make.h"  #include "make.h"
 #include "hash.h"  #include "hash.h"
   #include "ohash.h"
 #include "dir.h"  #include "dir.h"
   
 #ifndef lint  #ifndef lint
Line 109 
Line 111 
  *      hampers the style of some makefiles, they must be changed.   *      hampers the style of some makefiles, they must be changed.
  *   *
  *      A list of all previously-read directories is kept in the   *      A list of all previously-read directories is kept in the
  *      openDirectories Lst. This list is checked first before a directory   *      openDirectories cache.
  *      is opened.  
  *   *
  *      The need for the caching of whole directories is brought about by   *      The need for the caching of whole directories is brought about by
  *      the multi-level transformation code in suff.c, which tends to search   *      the multi-level transformation code in suff.c, which tends to search
Line 171 
Line 172 
   
 LIST          dirSearchPath;    /* main search path */  LIST          dirSearchPath;    /* main search path */
   
 static LIST   openDirectories;  /* the list of all open directories */  static struct hash   openDirectories;   /* cache all open directories */
   
 /*  /*
  * Variables for gathering statistics on the efficiency of the hashing   * Variables for gathering statistics on the efficiency of the hashing
Line 193 
Line 194 
                              * 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... */
   
   static struct hash_info dir_info = { offsetof(Path, name),
       NULL, hash_alloc, hash_free, element_alloc };
   
 static int DirFindName __P((void *, void *));  static Path *DirReaddir __P((const char *, const char *));
 static int DirMatchFiles __P((char *, Path *, Lst));  static int DirMatchFiles __P((char *, Path *, Lst));
 static void DirExpandCurly __P((char *, char *, Lst, Lst));  static void DirExpandCurly __P((char *, char *, Lst, Lst));
 static void DirExpandInt __P((char *, Lst, Lst));  static void DirExpandInt __P((char *, Lst, Lst));
Line 217 
Line 220 
 Dir_Init()  Dir_Init()
 {  {
     Lst_Init(&dirSearchPath);      Lst_Init(&dirSearchPath);
     Lst_Init(&openDirectories);      hash_init(&openDirectories, 4, &dir_info);
     Hash_InitTable(&mtimes, 0);      Hash_InitTable(&mtimes, 0);
   
     /*      dot = DirReaddir(".", NULL);
      * Since the Path structure is placed on both openDirectories and  
      * the path we give Dir_AddDir (which in this case is openDirectories),  
      * we need to remove "." from openDirectories and what better time to  
      * do it than when we have to fetch the thing anyway?  
      */  
     Dir_AddDir(&openDirectories, ".");  
     dot = (Path *)Lst_DeQueue(&openDirectories);  
   
     /*      /* We always need to have dot around, so we increment its reference count
      * We always need to have dot around, so we increment its reference count       * to make sure it's not destroyed.  */
      * to make sure it's not destroyed.      dot->refCount++;
      */  
     dot->refCount += 1;  
 }  }
   
 /*-  /*-
Line 252 
Line 246 
 Dir_End()  Dir_End()
 {  {
 #ifdef CLEANUP  #ifdef CLEANUP
     dot->refCount -= 1;      struct Path *p;
       unsigned int i;
   
       dot->refCount--;
     Dir_Destroy(dot);      Dir_Destroy(dot);
     Dir_ClearPath(&dirSearchPath);      Lst_Destroy(&dirSearchPath, Dir_Destroy);
     Lst_Destroy(&dirSearchPath, NOFREE);      for (p = hash_first(&openDirectories, &i); p != NULL;
     Dir_ClearPath(&openDirectories);          p = hash_next(&openDirectories, &i))
     Lst_Destroy(&openDirectories, NOFREE);              Dir_Destroy(p);
       hash_delete(&openDirectories);
     Hash_DeleteTable(&mtimes);      Hash_DeleteTable(&mtimes);
 #endif  #endif
 }  }
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * DirFindName --  
  *      See if the Path structure describes the same directory as the  
  *      given one by comparing their names. Called from Dir_AddDir via  
  *      Lst_Find when searching the list of open directories.  
  *  
  * Results:  
  *      0 if it is the same. Non-zero otherwise  
  *  
  * Side Effects:  
  *      None  
  *-----------------------------------------------------------------------  
  */  
 static int  
 DirFindName (p, dname)  
     void *p;          /* Current name */  
     void *dname;      /* Desired name */  
 {  
     return strcmp(((Path *)p)->name, (char *)dname);  
 }  
   
 /*-  
  *-----------------------------------------------------------------------  
  * Dir_HasWildcards  --   * Dir_HasWildcards  --
  *      see if the given name has any wildcard characters in it   *      see if the given name has any wildcard characters in it
  *      be careful not to expand unmatching brackets or braces.   *      be careful not to expand unmatching brackets or braces.
Line 620 
Line 596 
                         if (*dp == '/')                          if (*dp == '/')
                             *dp = '\0';                              *dp = '\0';
                         Lst_Init(&temp);                          Lst_Init(&temp);
                         Dir_AddDir(&temp, dirpath);                          Dir_AddDir(&temp, dirpath, NULL);
                         DirExpandInt(cp+1, &temp, expansions);                          DirExpandInt(cp+1, &temp, expansions);
                         Lst_Destroy(&temp, NOFREE);                          Lst_Destroy(&temp, NOFREE);
                     }                      }
Line 836 
Line 812 
                  * again in such a manner, we will find it without having to do                   * again in such a manner, we will find it without having to do
                  * numerous numbers of access calls. Hurrah!                   * numerous numbers of access calls. Hurrah!
                  */                   */
                 cp = strrchr (file, '/');                  cp = strrchr(file, '/');
                 *cp = '\0';                  Dir_AddDir(path, file, cp);
                 Dir_AddDir (path, file);  
                 *cp = '/';  
   
                 /*                  /*
                  * Save the modification time so if it's needed, we don't have                   * Save the modification time so if it's needed, we don't have
Line 895 
Line 869 
      * b/c we added it here. This is not good...       * b/c we added it here. This is not good...
      */       */
 #ifdef notdef  #ifdef notdef
     cp[-1] = '\0';      Dir_AddDir(path, name, cp-1);
     Dir_AddDir (path, name);  
     cp[-1] = '/';  
   
     bigmisses += 1;      bigmisses += 1;
     ln = Lst_Last(path);      ln = Lst_Last(path);
Line 1015 
Line 987 
     return exists;      return exists;
 }  }
   
   /* Read a directory, either from the disk, or from the cache.  */
   static Path *
   DirReaddir(name, end)
       const char          *name;
       const char          *end;
   {
       Path                *p;     /* pointer to new Path structure */
       DIR                 *d;     /* for reading directory */
       struct dirent       *dp;    /* entry in directory */
       unsigned int        slot;
   
       slot = hash_qlookupi(&openDirectories, name, &end);
       p = hash_find(&openDirectories, slot);
   
       if (p != NULL)
           return p;
   
       p = hash_create_entry(&dir_info, name, &end);
       p->hits = 0;
       p->refCount = 0;
       Hash_InitTable(&p->files, -1);
   
       if (DEBUG(DIR)) {
           printf("Caching %s...", p->name);
           fflush(stdout);
       }
   
       if ((d = opendir(p->name)) == NULL)
           return NULL;
       /* Skip the first two entries -- these will *always* be . and ..  */
       (void)readdir(d);
       (void)readdir(d);
   
       while ((dp = readdir(d)) != NULL) {
   #if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */
           /* The sun directory library doesn't check for a 0 inode
            * (0-inode slots just take up space), so we have to do
            * it ourselves.  */
           if (dp->d_fileno == 0)
               continue;
   #endif /* sun && d_ino */
           (void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);
       }
       (void)closedir(d);
       if (DEBUG(DIR))
           printf("done\n");
   
       hash_insert(&openDirectories, slot, p);
       return p;
   }
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  * Dir_AddDir --   * Dir_AddDir --
Line 1022 
Line 1045 
  *      the arguments is backwards so ParseDoDependency can do a   *      the arguments is backwards so ParseDoDependency can do a
  *      Lst_ForEach of its list of paths...   *      Lst_ForEach of its list of paths...
  *   *
  * Results:  
  *      none  
  *  
  * Side Effects:   * Side Effects:
  *      A structure is added to the list and the directory is   *      A structure is added to the list and the directory is
  *      read and hashed.   *      read and hashed.
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 void  void
 Dir_AddDir (path, name)  Dir_AddDir(path, name, end)
     Lst           path;       /* the path to which the directory should be      Lst         path;   /* the path to which the directory should be
                                * added */                           * added */
     char          *name;      /* the name of the directory to add */      const char  *name;  /* the name of the directory to add */
       const char  *end;
 {  {
     LstNode       ln;         /* node in case Path structure is found */      Path        *p;     /* pointer to new Path structure */
     register Path *p;         /* pointer to new Path structure */  
     DIR           *d;         /* for reading directory */  
     register struct dirent *dp; /* entry in directory */  
   
     ln = Lst_Find(&openDirectories, DirFindName, name);      p = DirReaddir(name, end);
     if (ln != NULL) {      if (p == NULL)
         p = (Path *)Lst_Datum(ln);          return;
         if (Lst_Member(path, p) == NULL) {      if (p->refCount == 0)
             p->refCount += 1;          Lst_AtEnd(path, p);
             Lst_AtEnd(path, p);      else if (Lst_Member(path, p) != NULL)
         }          return;
     } else {      else
         if (DEBUG(DIR)) {          Lst_AtEnd(path, p);
             printf("Caching %s...", name);      p->refCount++;
             fflush(stdout);  
         }  
   
         if ((d = opendir (name)) != (DIR *) NULL) {  
             p = (Path *) emalloc (sizeof (Path));  
             p->name = estrdup (name);  
             p->hits = 0;  
             p->refCount = 1;  
             Hash_InitTable (&p->files, -1);  
   
             /*  
              * Skip the first two entries -- these will *always* be . and ..  
              */  
             (void)readdir(d);  
             (void)readdir(d);  
   
             while ((dp = readdir (d)) != (struct dirent *) NULL) {  
 #if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */  
                 /*  
                  * The sun directory library doesn't check for a 0 inode  
                  * (0-inode slots just take up space), so we have to do  
                  * it ourselves.  
                  */  
                 if (dp->d_fileno == 0) {  
                     continue;  
                 }  
 #endif /* sun && d_ino */  
                 (void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);  
             }  
             (void) closedir (d);  
             Lst_AtEnd(&openDirectories, p);  
             Lst_AtEnd(path, p);  
         }  
         if (DEBUG(DIR)) {  
             printf("done\n");  
         }  
     }  
 }  }
   
 /*-  /*-
Line 1169 
Line 1150 
     void *pp;       /* The directory descriptor to nuke */      void *pp;       /* The directory descriptor to nuke */
 {  {
     Path          *p = (Path *) pp;      Path          *p = (Path *) pp;
     p->refCount -= 1;  
   
     if (p->refCount == 0) {      if (--p->refCount == 0) {
         LstNode ln;          hash_remove(&openDirectories, hash_qlookup(&openDirectories, p->name));
   
         ln = Lst_Member(&openDirectories, p);  
         Lst_Remove(&openDirectories, ln);  
   
         Hash_DeleteTable (&p->files);          Hash_DeleteTable (&p->files);
         free(p->name);  
         free(p);          free(p);
     }      }
 }  }
Line 1242 
Line 1217 
 void  void
 Dir_PrintDirectories()  Dir_PrintDirectories()
 {  {
     LstNode     ln;  
     Path        *p;      Path        *p;
       unsigned int i;
   
     printf ("#*** Directory Cache:\n");      printf ("#*** Directory Cache:\n");
     printf ("# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",      printf ("# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
Line 1251 
Line 1226 
               (hits+bigmisses+nearmisses ?                (hits+bigmisses+nearmisses ?
                hits * 100 / (hits + bigmisses + nearmisses) : 0));                 hits * 100 / (hits + bigmisses + nearmisses) : 0));
     printf ("# %-20s referenced\thits\n", "directory");      printf ("# %-20s referenced\thits\n", "directory");
     Lst_Open(&openDirectories);      for (p = hash_first(&openDirectories, &i); p != NULL;
     while ((ln = Lst_Next(&openDirectories)) != NULL) {          p = hash_next(&openDirectories, &i))
         p = (Path *)Lst_Datum(ln);              printf("# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits);
         printf("# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits);  
     }  
     Lst_Close(&openDirectories);  
 }  }
   
 static void  static void

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25