[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.52 and 1.53

version 1.52, 2007/09/16 14:29:33 version 1.53, 2007/09/17 09:28:36
Line 175 
Line 175 
  * possibility a caller might update the file and invalidate the cache   * possibility a caller might update the file and invalidate the cache
  * entry, and we don't look up in this cache except as a last resort.   * entry, and we don't look up in this cache except as a last resort.
  */   */
 static struct ohash mtimes;  static struct ohash mtimes;
   
   
 /* There are three distinct hash structures:  /* There are three distinct hash structures:
  * - to collate files's last modification times (global mtimes)   * - to collate files's last modification times (global mtimes)
  * - to collate file names (in each PathEntry structure)   * - to collate file names (in each PathEntry structure)
  * - to collate known directories (global knownDirectories).  */   * - to collate known directories (global knownDirectories).  */
 static struct ohash_info stamp_info = {  static struct ohash_info stamp_info = {
         offsetof(struct file_stamp, name), NULL, hash_alloc, hash_free,          offsetof(struct file_stamp, name), NULL, hash_alloc, hash_free,
         element_alloc };          element_alloc };
   
 static struct ohash_info file_info = {  static struct ohash_info file_info = {
         0, NULL, hash_alloc, hash_free, element_alloc };          0, NULL, hash_alloc, hash_free, element_alloc };
   
 static struct ohash_info dir_info = {  static struct ohash_info dir_info = {
         offsetof(struct PathEntry, name), NULL,          offsetof(struct PathEntry, name), NULL,
         hash_alloc, hash_free, element_alloc };          hash_alloc, hash_free, element_alloc };
   
 /* add_file(path, name): add a file name to a path hash structure. */  /* add_file(path, name): add a file name to a path hash structure. */
 static void add_file(struct PathEntry *, const char *);  static void add_file(struct PathEntry *, const char *);
 /* n = find_file_hashi(p, name, end, hv): retrieve name in a path hash  /* n = find_file_hashi(p, name, end, hv): retrieve name in a path hash
  *      structure. */   *      structure. */
 static char *find_file_hashi(struct PathEntry *, const char *, const char *,  static char *find_file_hashi(struct PathEntry *, const char *, const char *,
     uint32_t);      uint32_t);
   
 /* stamp = find_stampi(name, end): look for (name, end) in the global  /* stamp = find_stampi(name, end): look for (name, end) in the global
Line 254 
Line 254 
 }  }
   
 static char *  static char *
 find_file_hashi(struct PathEntry *p, const char *file, const char *efile,  find_file_hashi(struct PathEntry *p, const char *file, const char *efile,
     uint32_t hv)      uint32_t hv)
 {  {
         struct ohash    *h = &p->files;          struct ohash    *h = &p->files;
Line 279 
Line 279 
         if (!dot)          if (!dot)
                 Fatal("Can't access current directory");                  Fatal("Can't access current directory");
   
         /* We always need to have dot around, so we increment its reference          /* We always need to have dot around, so we increment its reference
          * count to make sure it won't be destroyed.  */           * count to make sure it won't be destroyed.  */
         dot->refCount++;          dot->refCount++;
 }  }
Line 313 
Line 313 
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
  */   */
 void  void
 Dir_MatchFilesi(const char *word, const char *eword, struct PathEntry *p,  Dir_MatchFilesi(const char *word, const char *eword, struct PathEntry *p,
     Lst expansions)      Lst expansions)
 {  {
         unsigned int search;    /* Index into the directory's table */          unsigned int search;    /* Index into the directory's table */
Line 331 
Line 331 
                 if (*word != '.' && *entry == '.')                  if (*word != '.' && *entry == '.')
                         continue;                          continue;
                 if (Str_Matchi(entry, strchr(entry, '\0'), word, eword))                  if (Str_Matchi(entry, strchr(entry, '\0'), word, eword))
                         Lst_AtEnd(expansions,                          Lst_AtEnd(expansions,
                             isDot ? estrdup(entry) :                              isDot ? estrdup(entry) :
                             Str_concat(p->name, entry, '/'));                              Str_concat(p->name, entry, '/'));
         }          }
 }  }
Line 344 
Line 344 
  *      [ dir1/.../dirn/file ] which exists below one of the directories   *      [ dir1/.../dirn/file ] which exists below one of the directories
  *      already on the search path), its directory is added to the end   *      already on the search path), its directory is added to the end
  *      of the path on the assumption that there will be more files in   *      of the path on the assumption that there will be more files in
  *      that directory later on.   *      that directory later on.
  */   */
 char *  char *
 Dir_FindFileComplexi(const char *name, const char *ename, Lst path,  Dir_FindFileComplexi(const char *name, const char *ename, Lst path,
     bool checkCurdirFirst)      bool checkCurdirFirst)
 {  {
         struct PathEntry *p;    /* current path member */          struct PathEntry *p;    /* current path member */
Line 359 
Line 359 
         const char *cp; /* index of first slash, if any */          const char *cp; /* index of first slash, if any */
         bool hasSlash;          bool hasSlash;
         struct stat stb;/* Buffer for stat, if necessary */          struct stat stb;/* Buffer for stat, if necessary */
         struct file_stamp *entry;          struct file_stamp *entry;
                         /* Entry for mtimes table */                          /* Entry for mtimes table */
         uint32_t hv;    /* hash value for last component in file name */          uint32_t hv;    /* hash value for last component in file name */
         char *q;        /* Str_dupi(name, ename) */          char *q;        /* Str_dupi(name, ename) */
Line 379 
Line 379 
   
         if (DEBUG(DIR))          if (DEBUG(DIR))
                 printf("Searching for %s...", name);                  printf("Searching for %s...", name);
         /* Unless checkCurDirFirst is false, we always look for          /* Unless checkCurDirFirst is false, we always look for
          * the file in the current directory before anywhere else           * the file in the current directory before anywhere else
          * and we always return exactly what the caller specified. */           * and we always return exactly what the caller specified. */
         if (checkCurdirFirst &&          if (checkCurdirFirst &&
             (!hasSlash || (cp - name == 2 && *name == '.')) &&              (!hasSlash || (cp - name == 2 && *name == '.')) &&
             find_file_hashi(dot, cp, ename, hv) != NULL) {              find_file_hashi(dot, cp, ename, hv) != NULL) {
                 if (DEBUG(DIR))                  if (DEBUG(DIR))
Line 390 
Line 390 
                 return Str_dupi(name, ename);                  return Str_dupi(name, ename);
         }          }
   
         /* Then, we look through all the directories on path, seeking one          /* Then, we look through all the directories on path, seeking one
          * containing the final component of name and whose final           * containing the final component of name and whose final
          * component(s) match name's initial component(s).           * component(s) match name's initial component(s).
          * If found, we concatenate the directory name and the           * If found, we concatenate the directory name and the
          * final component and return the resulting string.  */           * final component and return the resulting string.  */
         for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) {          for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) {
                 p = (struct PathEntry *)Lst_Datum(ln);                  p = (struct PathEntry *)Lst_Datum(ln);
Line 403 
Line 403 
                         if (DEBUG(DIR))                          if (DEBUG(DIR))
                                 printf("here...");                                  printf("here...");
                         if (hasSlash) {                          if (hasSlash) {
                                 /* If the name had a slash, its initial                                  /* If the name had a slash, its initial
                                  * components and p's final components must                                   * components and p's final components must
                                  * match. This is false if a mismatch is                                   * match. This is false if a mismatch is
                                  * encountered before all of the initial                                   * encountered before all of the initial
                                  * components have been checked (p2 > name at                                   * components have been checked (p2 > name at
                                  * the end of the loop), or we matched only                                   * the end of the loop), or we matched only
                                  * part of one of the components of p along                                   * part of one of the components of p along
                                  * with all the rest of them (*p1 != '/').  */                                   * with all the rest of them (*p1 != '/').  */
                                 p1 = p->name + strlen(p->name) - 1;                                  p1 = p->name + strlen(p->name) - 1;
                                 p2 = cp - 2;                                  p2 = cp - 2;
                                 while (p2 >= name && p1 >= p->name &&                                  while (p2 >= name && p1 >= p->name &&
                                     *p1 == *p2) {                                      *p1 == *p2) {
                                         p1--;                                          p1--;
                                         p2--;                                          p2--;
                                 }                                  }
                                 if (p2 >= name ||                                  if (p2 >= name ||
                                     (p1 >= p->name && *p1 != '/')) {                                      (p1 >= p->name && *p1 != '/')) {
                                         if (DEBUG(DIR))                                          if (DEBUG(DIR))
                                                 printf("component mismatch -- continuing...");                                                  printf("component mismatch -- continuing...");
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
                         file = Str_concati(p->name, strchr(p->name, '\0'), cp,                          file = Str_concati(p->name, strchr(p->name, '\0'), cp,
                             ename, '/');                              ename, '/');
                         if (DEBUG(DIR))                          if (DEBUG(DIR))
                                 printf("returning %s\n", file);                                  printf("returning %s\n", file);
                         return file;                          return file;
                 } else if (hasSlash) {                  } else if (hasSlash) {
                         /* If the file has a leading path component and that                          /* If the file has a leading path component and that
                          * component exactly matches the entire name of the                           * component exactly matches the entire name of the
                          * current search directory, we assume the file                           * current search directory, we assume the file
                          * doesn't exist and return NULL.  */                           * doesn't exist and return NULL.  */
                         for (p1 = p->name, p2 = name; *p1 && *p1 == *p2;                          for (p1 = p->name, p2 = name; *p1 && *p1 == *p2;
                             p1++, p2++)                              p1++, p2++)
                                 continue;                                  continue;
                         if (*p1 == '\0' && p2 == cp - 1) {                          if (*p1 == '\0' && p2 == cp - 1) {
Line 448 
Line 448 
   
         /* We didn't find the file on any existing member of the path.          /* We didn't find the file on any existing member of the path.
          * If the name doesn't contain a slash, end of story.           * If the name doesn't contain a slash, end of story.
          * If it does contain a slash, however, it could be in a subdirectory           * If it does contain a slash, however, it could be in a subdirectory
          * of one of the members of the search path. (eg., for path=/usr/include           * of one of the members of the search path. (eg., for path=/usr/include
          * and name=sys/types.h, the above search fails to turn up types.h           * and name=sys/types.h, the above search fails to turn up types.h
          * in /usr/include, even though /usr/include/sys/types.h exists).           * in /usr/include, even though /usr/include/sys/types.h exists).
          *           *
          * We only perform this look-up for non-absolute file names.           * We only perform this look-up for non-absolute file names.
          *           *
          * Whenever we score a hit, we assume there will be more matches from           * Whenever we score a hit, we assume there will be more matches from
          * that directory, and append all but the last component of the           * that directory, and append all but the last component of the
          * resulting name onto the search path. */           * resulting name onto the search path. */
         if (!hasSlash) {          if (!hasSlash) {
                 if (DEBUG(DIR))                  if (DEBUG(DIR))
Line 472 
Line 472 
                 for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) {                  for (ln = Lst_First(path); ln != NULL; ln = Lst_Adv(ln)) {
                         p = (struct PathEntry *)Lst_Datum(ln);                          p = (struct PathEntry *)Lst_Datum(ln);
                         if (p != dot)                          if (p != dot)
                                 file = Str_concati(p->name,                                  file = Str_concati(p->name,
                                     strchr(p->name, '\0'), name, ename, '/');                                      strchr(p->name, '\0'), name, ename, '/');
                         else {                          else {
                                 /* Checking in dot -- DON'T put a leading                                  /* Checking in dot -- DON'T put a leading
                                 * ./ on the thing.  */                                  * ./ on the thing.  */
                                 file = Str_dupi(name, ename);                                  file = Str_dupi(name, ename);
                                 checkedDot = true;                                  checkedDot = true;
Line 490 
Line 490 
                                 if (DEBUG(DIR))                                  if (DEBUG(DIR))
                                         printf("got it.\n");                                          printf("got it.\n");
   
                                 /* We've found another directory to search.                                  /* We've found another directory to search.
                                  * We know there is a slash in 'file'. We                                   * We know there is a slash in 'file'. We
                                  * call Dir_AddDiri to add the new directory                                   * call Dir_AddDiri to add the new directory
                                  * onto the existing search path. Once that's                                   * onto the existing search path. Once that's
                                  * done, we return the file name, knowing that                                   * done, we return the file name, knowing that
                                  * should a file in this directory ever be                                   * should a file in this directory ever be
                                  * referenced again in such a manner, we will                                   * referenced again in such a manner, we will
                                  * find it without having to do numerous                                   * find it without having to do numerous
                                  * access calls.  */                                   * access calls.  */
                                 temp = strrchr(file, '/');                                  temp = strrchr(file, '/');
                                 Dir_AddDiri(path, file, temp);                                  Dir_AddDiri(path, file, temp);
   
                                 /* Save the modification time so if it's                                  /* Save the modification time so if it's
                                 * needed, we don't have to fetch it again.  */                                  * needed, we don't have to fetch it again.  */
                                 if (DEBUG(DIR))                                  if (DEBUG(DIR))
                                         printf("Caching %s for %s\n",                                          printf("Caching %s for %s\n",
                                             time_to_string(mtime), file);                                              time_to_string(mtime), file);
                                 record_stamp(file, mtime);                                  record_stamp(file, mtime);
                                 return file;                                  return file;
Line 517 
Line 517 
                         printf("failed. ");                          printf("failed. ");
   
                 if (checkedDot) {                  if (checkedDot) {
                         /* Already checked by the given name, since . was in                          /* Already checked by the given name, since . was in
                          * the path, so no point in proceeding...  */                           * the path, so no point in proceeding...  */
                         if (DEBUG(DIR))                          if (DEBUG(DIR))
                                 printf("Checked . already, returning NULL\n");                                  printf("Checked . already, returning NULL\n");
Line 589 
Line 589 
                 return NULL;                  return NULL;
   
         while ((dp = readdir(d)) != NULL) {          while ((dp = readdir(d)) != NULL) {
                 if (dp->d_name[0] == '.' &&                  if (dp->d_name[0] == '.' &&
                     (dp->d_name[1] == '\0' ||                      (dp->d_name[1] == '\0' ||
                         (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))                          (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
                         continue;                          continue;
                 add_file(p, dp->d_name);                  add_file(p, dp->d_name);
Line 699 
Line 699 
         struct PathEntry *p = (struct PathEntry *)pp;          struct PathEntry *p = (struct PathEntry *)pp;
   
         if (--p->refCount == 0) {          if (--p->refCount == 0) {
                 ohash_remove(&knownDirectories,                  ohash_remove(&knownDirectories,
                     ohash_qlookup(&knownDirectories, p->name));                      ohash_qlookup(&knownDirectories, p->name));
                 free_hash(&p->files);                  free_hash(&p->files);
                 free(p);                  free(p);
Line 764 
Line 764 
         entry = ohash_find(&mtimes, slot);          entry = ohash_find(&mtimes, slot);
         if (entry != NULL) {          if (entry != NULL) {
                 /* Only do this once -- the second time folks are checking to                  /* Only do this once -- the second time folks are checking to
                  * see if the file was actually updated, so we need to                   * see if the file was actually updated, so we need to
                  * actually go to the file system.      */                   * actually go 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",

Legend:
Removed from v.1.52  
changed lines
  Added in v.1.53