diff options
Diffstat (limited to 'contrib/bmake/dir.c')
-rw-r--r-- | contrib/bmake/dir.c | 401 |
1 files changed, 140 insertions, 261 deletions
diff --git a/contrib/bmake/dir.c b/contrib/bmake/dir.c index 627e654387f8..5c11d6c794d7 100644 --- a/contrib/bmake/dir.c +++ b/contrib/bmake/dir.c @@ -1,4 +1,4 @@ -/* $NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $ */ +/* $NetBSD: dir.c,v 1.286 2023/12/29 18:53:24 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -83,7 +83,7 @@ * * Dir_End Clean up the module. * - * Dir_SetPATH Set ${.PATH} to reflect state of dirSearchPath. + * Dir_SetPATH Set ${.PATH} to reflect the state of dirSearchPath. * * Dir_HasWildcards * Returns true if the name given it needs to @@ -94,13 +94,12 @@ * from the search path. * * Dir_FindFile Searches for a file on a given search path. - * If it exists, the entire path is returned. - * Otherwise NULL is returned. + * If it exists, returns the entire path, otherwise NULL. * * Dir_FindHereOrAbove - * Search for a path in the current directory and - * then all the directories above it in turn until - * the path is found or we reach the root ("/"). + * Search for a path in the current directory and then + * all the directories above it in turn, until the path + * is found or the root directory ("/") is reached. * * Dir_UpdateMTime * Update the modification time and path of a node with @@ -114,11 +113,6 @@ * preceded by the command flag and all of them * separated by a space. * - * Dir_Destroy Destroy an element of a search path. Frees up all - * things that can be freed for the element as long - * as the element is no longer referenced by any other - * search path. - * * SearchPath_Clear * Resets a search path to the empty list. * @@ -138,7 +132,7 @@ #include "job.h" /* "@(#)dir.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $"); +MAKE_RCSID("$NetBSD: dir.c,v 1.286 2023/12/29 18:53:24 rillig Exp $"); /* * A search path is a list of CachedDir structures. A CachedDir has in it the @@ -152,26 +146,21 @@ MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $"); * All previously-read directories are kept in openDirs, which is checked * first before a directory is opened. * - * The need for the caching of whole directories is brought about by the - * multi-level transformation code in suff.c, which tends to search for far - * more files than regular make does. In the initial implementation, the - * amount of time spent performing "stat" calls was truly astronomical. - * The problem with caching at the start is, of course, that pmake doesn't - * then detect changes to these directories during the course of the make. - * Three possibilities suggest themselves: + * This cache is used by the multi-level transformation code in suff.c, which + * tends to search for far more files than in regular explicit targets. After + * a directory has been cached, any later changes to that directory are not + * reflected in the cache. To keep the cache up to date, there are several + * ideas: * * 1) just use stat to test for a file's existence. As mentioned above, - * this is very inefficient due to the number of checks engendered by + * this is very inefficient due to the number of checks performed by * the multi-level transformation code. * - * 2) use readdir() and company to search the directories, keeping them - * open between checks. I have tried this and while it didn't slow down - * the process too much, it could severely affect the amount of - * parallelism available as each directory open would take another file - * descriptor out of play for handling I/O for another job. Given that - * it is only recently (as of 1993 or earlier) that UNIX OS's have taken - * to allowing more than 20 or 32 file descriptors for a process, this - * doesn't seem acceptable to me. + * 2) use readdir() to search the directories, keeping them open between + * checks. Around 1993 or earlier, this didn't slow down the process too + * much, but it consumed one file descriptor per open directory, which + * was critical on the then-current operating systems, as many limited + * the number of open file descriptors to 20 or 32. * * 3) record the mtime of the directory in the CachedDir structure and * verify the directory hasn't changed since the contents were cached. @@ -184,9 +173,9 @@ MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $"); * number of reloadings and if the number goes over a (small) limit, * resort to using stat in its place. * - * An additional thing to consider is that pmake is used primarily to create - * C programs and until recently (as of 1993 or earlier) pcc-based compilers - * refused to allow you to specify where the resulting object file should be + * An additional thing to consider is that make is used primarily to create + * C programs and until recently (as of 1993 or earlier), pcc-based compilers + * didn't have an option to specify where the resulting object file should be * placed. This forced all objects to be created in the current directory. * This isn't meant as a full excuse, just an explanation of some of the * reasons for the caching used here. @@ -212,7 +201,7 @@ MAKE_RCSID("$NetBSD: dir.c,v 1.272 2021/04/04 10:13:09 rillig Exp $"); /* A cache for the filenames in a directory. */ struct CachedDir { /* - * Name of directory, either absolute or relative to the current + * Name of the directory, either absolute or relative to the current * directory. The name is not normalized in any way, that is, "." * and "./." are different. * @@ -238,20 +227,12 @@ struct CachedDir { typedef List CachedDirList; typedef ListNode CachedDirListNode; -typedef ListNode SearchPathNode; - /* A list of cached directories, with fast lookup by directory name. */ typedef struct OpenDirs { CachedDirList list; HashTable /* of CachedDirListNode */ table; } OpenDirs; -typedef enum CachedStatsFlags { - CST_NONE = 0, - CST_LSTAT = 1 << 0, /* call lstat(2) instead of stat(2) */ - CST_UPDATE = 1 << 1 /* ignore existing cached entry */ -} CachedStatsFlags; - SearchPath dirSearchPath = { LST_INIT }; /* main search path */ @@ -279,8 +260,7 @@ static CachedDir *dotLast = NULL; * * XXX: If this is done way early, there's a chance other rules will have * already updated the file, in which case we'll update it again. Generally, - * there won't be two rules to update a single file, so this should be ok, - * but... + * there won't be two rules to update a single file, so this should be ok. */ static HashTable mtimes; @@ -344,7 +324,7 @@ CachedDir_Unref(CachedDir *dir) free(dir); } -/* Update the value of the CachedDir variable, updating the reference counts. */ +/* Update the value of 'var', updating the reference counts. */ static void CachedDir_Assign(CachedDir **var, CachedDir *dir) { @@ -419,9 +399,9 @@ OpenDirs_Remove(OpenDirs *odirs, const char *name) */ static int cached_stats(const char *pathname, struct cached_stat *out_cst, - CachedStatsFlags flags) + bool useLstat, bool forceRefresh) { - HashTable *tbl = flags & CST_LSTAT ? &lmtimes : &mtimes; + HashTable *tbl = useLstat ? &lmtimes : &mtimes; struct stat sys_st; struct cached_stat *cst; int rc; @@ -430,14 +410,14 @@ cached_stats(const char *pathname, struct cached_stat *out_cst, return -1; /* This can happen in meta mode. */ cst = HashTable_FindValue(tbl, pathname); - if (cst != NULL && !(flags & CST_UPDATE)) { + if (cst != NULL && !forceRefresh) { *out_cst = *cst; DEBUG2(DIR, "Using cached time %s for %s\n", Targ_FmtTime(cst->cst_mtime), pathname); return 0; } - rc = (flags & CST_LSTAT ? lstat : stat)(pathname, &sys_st); + rc = (useLstat ? lstat : stat)(pathname, &sys_st); if (rc == -1) return -1; /* don't cache negative lookups */ @@ -462,13 +442,13 @@ cached_stats(const char *pathname, struct cached_stat *out_cst, int cached_stat(const char *pathname, struct cached_stat *cst) { - return cached_stats(pathname, cst, CST_NONE); + return cached_stats(pathname, cst, false, false); } int cached_lstat(const char *pathname, struct cached_stat *cst) { - return cached_stats(pathname, cst, CST_LSTAT); + return cached_stats(pathname, cst, true, false); } /* Initialize the directories module. */ @@ -481,9 +461,7 @@ Dir_Init(void) CachedDir_Assign(&dotLast, CachedDir_New(".DOTLAST")); } -/* - * Called by Dir_InitDir and whenever .CURDIR is assigned to. - */ +/* Called by Dir_InitDir and whenever .CURDIR is assigned to. */ void Dir_InitCur(const char *newCurdir) { @@ -493,7 +471,7 @@ Dir_InitCur(const char *newCurdir) return; /* - * Our build directory is not the same as our source directory. + * The build directory is not the same as the source directory. * Keep this one around too. */ dir = SearchPath_Add(NULL, newCurdir); @@ -504,7 +482,7 @@ Dir_InitCur(const char *newCurdir) } /* - * (Re)initialize "dot" (current/object directory) path hash. + * (Re)initialize "dot" (the current/object directory). * Some directories may be cached. */ void @@ -583,6 +561,21 @@ Dir_SetPATH(void) } } + +void +Dir_SetSYSPATH(void) +{ + CachedDirListNode *ln; + + Var_ReadOnly(".SYSPATH", false); + Global_Delete(".SYSPATH"); + for (ln = sysIncPath->dirs.first; ln != NULL; ln = ln->next) { + CachedDir *dir = ln->datum; + Global_Append(".SYSPATH", dir->name); + } + Var_ReadOnly(".SYSPATH", true); +} + /* * See if the given name has any wildcard characters in it and all braces and * brackets are properly balanced. @@ -590,8 +583,6 @@ Dir_SetPATH(void) * XXX: This code is not 100% correct ([^]] fails etc.). I really don't think * that make(1) should be expanding patterns, because then you have to set a * mechanism for escaping the expansion! - * - * Return true if the word should be expanded, false otherwise. */ bool Dir_HasWildcards(const char *name) @@ -628,20 +619,14 @@ Dir_HasWildcards(const char *name) } /* - * See if any files match the pattern and add their names to the 'expansions' - * list if they do. + * See if any files as seen from 'dir' match 'pattern', and add their names + * to 'expansions' if they do. * - * This is incomplete -- wildcards are only expanded in the final path - * component, but not in directories like src/lib*c/file*.c, but it - * will do for now (now being 1993 until at least 2020). To expand these, + * Wildcards are only expanded in the final path component, but not in + * directories like src/lib*c/file*.c. To expand these wildcards, * delegate the work to the shell, using the '!=' variable assignment * operator, the ':sh' variable modifier or the ':!...!' variable modifier, * such as in ${:!echo src/lib*c/file*.c!}. - * - * Input: - * pattern Pattern to look for - * dir Directory to search - * expansion Place to store the results */ static void DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions) @@ -659,8 +644,10 @@ DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions) HashIter_InitSet(&hi, &dir->files); while (HashIter_Next(&hi) != NULL) { const char *base = hi.entry->key; + StrMatchResult res = Str_Match(base, pattern); + /* TODO: handle errors from res.error */ - if (!Str_Match(base, pattern)) + if (!res.matched) continue; /* @@ -678,28 +665,25 @@ DirMatchFiles(const char *pattern, CachedDir *dir, StringList *expansions) { char *fullName = isDot - ? bmake_strdup(base) - : str_concat3(dirName, "/", base); + ? bmake_strdup(base) + : str_concat3(dirName, "/", base); Lst_Append(expansions, fullName); } } } -/* - * Find the next closing brace in the string, taking nested braces into - * account. - */ +/* Find the next closing brace in 'p', taking nested braces into account. */ static const char * closing_brace(const char *p) { - int nest = 0; + int depth = 0; while (*p != '\0') { - if (*p == '}' && nest == 0) + if (*p == '}' && depth == 0) break; if (*p == '{') - nest++; + depth++; if (*p == '}') - nest--; + depth--; p++; } return p; @@ -712,14 +696,14 @@ closing_brace(const char *p) static const char * separator_comma(const char *p) { - int nest = 0; + int depth = 0; while (*p != '\0') { - if ((*p == '}' || *p == ',') && nest == 0) + if ((*p == '}' || *p == ',') && depth == 0) break; if (*p == '{') - nest++; + depth++; if (*p == '}') - nest--; + depth--; p++; } return p; @@ -776,7 +760,7 @@ DirExpandCurly(const char *word, const char *brace, SearchPath *path, const char *prefix, *middle, *piece, *middle_end, *suffix; size_t prefix_len, suffix_len; - /* Split the word into prefix '{' middle '}' suffix. */ + /* Split the word into prefix, '{', middle, '}' and suffix. */ middle = brace + 1; middle_end = closing_brace(middle); @@ -798,7 +782,7 @@ DirExpandCurly(const char *word, const char *brace, SearchPath *path, size_t piece_len = (size_t)(piece_end - piece); char *file = concat3(prefix, prefix_len, piece, piece_len, - suffix, suffix_len); + suffix, suffix_len); if (contains_wildcard(file)) { SearchPath_Expand(path, file, expansions); @@ -813,14 +797,14 @@ DirExpandCurly(const char *word, const char *brace, SearchPath *path, } -/* Expand the word in each of the directories from the path. */ +/* Expand 'pattern' in each of the directories from 'path'. */ static void -DirExpandPath(const char *word, SearchPath *path, StringList *expansions) +DirExpandPath(const char *pattern, SearchPath *path, StringList *expansions) { - SearchPathNode *ln; + CachedDirListNode *ln; for (ln = path->dirs.first; ln != NULL; ln = ln->next) { CachedDir *dir = ln->datum; - DirMatchFiles(word, dir, expansions); + DirMatchFiles(pattern, dir, expansions); } } @@ -850,11 +834,6 @@ SearchPath_ExpandMiddle(SearchPath *path, const char *pattern, prefix = bmake_strsedup(pattern, wildcardComponent + 1); /* - * XXX: Check the "the directory is added to the path" part. - * It is probably surprising that the directory before a - * wildcard gets added to the path. - */ - /* * XXX: Only the first match of the prefix in the path is * taken, any others are ignored. The expectation may be * that the pattern is expanded in the whole path. @@ -869,7 +848,7 @@ SearchPath_ExpandMiddle(SearchPath *path, const char *pattern, * path contains ../Etc/Object and we're looking for Etc, it won't * be found. Ah well. Probably not important. * - * XXX: Check whether the above comment is still true. + * TODO: Check whether the above comment is still true. */ if (dirpath == NULL) return; @@ -910,15 +889,9 @@ SearchPath_Expand(SearchPath *path, const char *pattern, StringList *expansions) goto done; } - /* At this point, the pattern does not contain '{'. */ - slash = strchr(pattern, '/'); if (slash == NULL) { - /* The pattern has no directory component. */ - - /* First the files in dot. */ DirMatchFiles(pattern, dot, expansions); - /* Then the files in every other directory on the path. */ DirExpandPath(pattern, path, expansions); goto done; } @@ -961,13 +934,13 @@ done: } /* - * Find if the file with the given name exists in the given path. + * Find if 'base' exists in 'dir'. * Return the freshly allocated path to the file, or NULL. */ static char * DirLookup(CachedDir *dir, const char *base) { - char *file; /* the current filename to check */ + char *file; DEBUG1(DIR, " %s ...\n", dir->name); @@ -983,15 +956,16 @@ DirLookup(CachedDir *dir, const char *base) /* - * Find if the file with the given name exists in the given directory. + * Find if 'name' exists in 'dir'. * Return the freshly allocated path to the file, or NULL. */ static char * DirLookupSubdir(CachedDir *dir, const char *name) { struct cached_stat cst; - char *file = dir == dot ? bmake_strdup(name) - : str_concat3(dir->name, "/", name); + char *file = dir == dot + ? bmake_strdup(name) + : str_concat3(dir->name, "/", name); DEBUG1(DIR, "checking %s ...\n", file); @@ -1004,12 +978,12 @@ DirLookupSubdir(CachedDir *dir, const char *name) } /* - * Find if the file with the given name exists in the given path. - * Return the freshly allocated path to the file, the empty string, or NULL. - * Returning the empty string means that the search should be terminated. + * Find if 'name' (which has basename 'base') exists in 'dir'. + * Return the freshly allocated path to the file, an empty string, or NULL. + * Returning an empty string means that the search should be terminated. */ static char * -DirLookupAbs(CachedDir *dir, const char *name, const char *cp) +DirLookupAbs(CachedDir *dir, const char *name, const char *base) { const char *dnp; /* pointer into dir->name */ const char *np; /* pointer into name */ @@ -1025,10 +999,10 @@ DirLookupAbs(CachedDir *dir, const char *name, const char *cp) for (dnp = dir->name, np = name; *dnp != '\0' && *dnp == *np; dnp++, np++) continue; - if (*dnp != '\0' || np != cp - 1) + if (*dnp != '\0' || np != base - 1) return NULL; - if (!HashSet_Contains(&dir->files, cp)) { + if (!HashSet_Contains(&dir->files, base)) { DEBUG0(DIR, " must be here but isn't -- returning\n"); return bmake_strdup(""); /* to terminate the search */ } @@ -1040,7 +1014,7 @@ DirLookupAbs(CachedDir *dir, const char *name, const char *cp) } /* - * Find the file given on "." or curdir. + * Find the given file in "." or curdir. * Return the freshly allocated path to the file, or NULL. */ static char * @@ -1068,7 +1042,7 @@ static bool FindFileRelative(SearchPath *path, bool seenDotLast, const char *name, char **out_file) { - SearchPathNode *ln; + CachedDirListNode *ln; bool checkedDot = false; char *file; @@ -1078,11 +1052,11 @@ FindFileRelative(SearchPath *path, bool seenDotLast, if (dot != NULL) { checkedDot = true; if ((file = DirLookupSubdir(dot, name)) != NULL) - goto found; + goto done; } if (cur != NULL && (file = DirLookupSubdir(cur, name)) != NULL) - goto found; + goto done; } for (ln = path->dirs.first; ln != NULL; ln = ln->next) { @@ -1095,18 +1069,18 @@ FindFileRelative(SearchPath *path, bool seenDotLast, checkedDot = true; } if ((file = DirLookupSubdir(dir, name)) != NULL) - goto found; + goto done; } if (seenDotLast) { if (dot != NULL && !checkedDot) { checkedDot = true; if ((file = DirLookupSubdir(dot, name)) != NULL) - goto found; + goto done; } if (cur != NULL && (file = DirLookupSubdir(cur, name)) != NULL) - goto found; + goto done; } if (checkedDot) { @@ -1116,34 +1090,23 @@ FindFileRelative(SearchPath *path, bool seenDotLast, */ DEBUG0(DIR, " Checked . already, returning NULL\n"); file = NULL; - goto found; + goto done; } return false; -found: +done: *out_file = file; return true; } static bool -FindFileAbsolute(SearchPath *path, bool const seenDotLast, - const char *const name, const char *const base, - char **out_file) +FindFileAbsolute(SearchPath *path, bool seenDotLast, + const char *name, const char *base, char **out_file) { char *file; - SearchPathNode *ln; + CachedDirListNode *ln; - /* - * For absolute names, compare directory path prefix against - * the the directory path of each member on the search path - * for an exact match. If we have an exact match on any member - * of the search path, use the cached contents of that member - * to lookup the final file component. If that lookup fails we - * can safely assume that the file does not exist at all. - * This is signified by DirLookupAbs() returning an empty - * string. - */ DEBUG0(DIR, " Trying exact path matches...\n"); if (!seenDotLast && cur != NULL && @@ -1176,13 +1139,6 @@ found: /* * Find the file with the given name along the given search path. * - * If the file is found in a directory that is not on the path - * already (either 'name' is absolute or it is a relative path - * [ dir1/.../dirn/file ] which exists below one of the directories - * 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 - * that directory later on. Sometimes this is true. Sometimes not. - * * Input: * name the file to find * path the directories to search, or NULL @@ -1195,7 +1151,7 @@ Dir_FindFile(const char *name, SearchPath *path) { char *file; /* the current filename to check */ bool seenDotLast = false; /* true if we should search dot last */ - struct cached_stat cst; /* Buffer for stat, if necessary */ + struct cached_stat cst; const char *trailing_dot = "."; const char *base = str_basename(name); @@ -1222,21 +1178,19 @@ Dir_FindFile(const char *name, SearchPath *path) * of each of the directories on the search path. */ if (base == name || (base - name == 2 && *name == '.')) { - SearchPathNode *ln; + CachedDirListNode *ln; /* - * We look through all the directories on the path seeking one + * Look through all the directories on the path seeking one * which contains the final component of the given name. If - * such a file is found, we concatenate the directory name - * and the final component and return the resulting string. - * If we don't find any such thing, we go on to phase two. + * such a file is found, return its pathname. + * If there is no such file, go on to phase two. * - * No matter what, we always look for the file in the current - * directory before anywhere else (unless we found the magic - * DOTLAST path, in which case we search it last) and we *do - * not* add the ./ to it if it exists. + * No matter what, always look for the file in the current + * directory before anywhere else (unless the path contains + * the magic '.DOTLAST', in which case search it last). * This is so there are no conflicts between what the user - * specifies (fish.c) and what pmake finds (./fish.c). + * specifies (fish.c) and what make finds (./fish.c). */ if (!seenDotLast && (file = DirFindDot(name, base)) != NULL) return file; @@ -1253,30 +1207,14 @@ Dir_FindFile(const char *name, SearchPath *path) return file; } - /* - * We didn't find the file on any directory in the search path. - * If the name doesn't contain a slash, that means it doesn't exist. - * If it *does* contain a slash, however, there is still hope: it - * could be in a subdirectory of one of the members of the search - * path. (eg. /usr/include and sys/types.h. The above search would - * fail to turn up types.h in /usr/include, but it *is* in - * /usr/include/sys/types.h). - * [ This no longer applies: If we find such a file, we assume there - * will be more (what else can we assume?) and add all but the last - * component of the resulting name onto the search path (at the - * end).] - * This phase is only performed if the file is *not* absolute. - */ if (base == name) { DEBUG0(DIR, " failed.\n"); misses++; return NULL; } - if (*base == '\0') { - /* we were given a trailing "/" */ - base = trailing_dot; - } + if (*base == '\0') + base = trailing_dot; /* we were given a trailing "/" */ if (name[0] != '/') { if (FindFileRelative(path, seenDotLast, name, &file)) @@ -1287,16 +1225,7 @@ Dir_FindFile(const char *name, SearchPath *path) } /* - * Didn't find it that way, either. Sigh. Phase 3. Add its directory - * onto the search path in any case, just in case, then look for the - * thing in the hash table. If we find it, grand. We return a new - * copy of the name. Otherwise we sadly return a NULL pointer. Sigh. - * Note that if the directory holding the file doesn't exist, this - * will do an extra search of the final directory on the path. Unless - * something weird happens, this search won't succeed and life will - * be groovy. - * - * Sigh. We cannot add the directory onto the search path because + * We cannot add the directory onto the search path because * of this amusing case: * $(INSTALLDIR)/$(FILE): $(FILE) * @@ -1304,75 +1233,40 @@ Dir_FindFile(const char *name, SearchPath *path) * When searching for $(FILE), we will find it in $(INSTALLDIR) * b/c we added it here. This is not good... */ -#if 0 - { - CachedDir *dir; - char *prefix; - - if (base == trailing_dot) { - base = strrchr(name, '/'); - base++; - } - prefix = bmake_strsedup(name, base - 1); - (void)SearchPath_Add(path, prefix); - free(prefix); - - bigmisses++; - if (path->last == NULL) - return NULL; - dir = path->last->datum; - if (HashSet_Contains(&dir->files, base)) - return bmake_strdup(name); - return NULL; - } -#else DEBUG1(DIR, " Looking for \"%s\" ...\n", name); bigmisses++; - if (cached_stat(name, &cst) == 0) { + if (cached_stat(name, &cst) == 0) return bmake_strdup(name); - } DEBUG0(DIR, " failed. Returning NULL\n"); return NULL; -#endif } /* - * Search for a path starting at a given directory and then working our way - * up towards the root. - * - * Input: - * here starting directory - * search_path the relative path we are looking for - * - * Results: - * The found path, or NULL. + * Search for 'needle' starting at the directory 'here' and then working our + * way up towards the root directory. Return the allocated path, or NULL. */ char * -Dir_FindHereOrAbove(const char *here, const char *search_path) +Dir_FindHereOrAbove(const char *here, const char *needle) { struct cached_stat cst; char *dirbase, *dirbase_end; char *try, *try_end; - /* copy out our starting point */ dirbase = bmake_strdup(here); dirbase_end = dirbase + strlen(dirbase); - /* loop until we determine a result */ for (;;) { - - /* try and stat(2) it ... */ - try = str_concat3(dirbase, "/", search_path); + try = str_concat3(dirbase, "/", needle); if (cached_stat(try, &cst) != -1) { - /* - * success! if we found a file, chop off - * the filename so we return a directory. - */ if ((cst.cst_mode & S_IFMT) != S_IFDIR) { + /* + * Chop off the filename, to return a + * directory. + */ try_end = try + strlen(try); while (try_end > try && *try_end != '/') try_end--; @@ -1385,16 +1279,10 @@ Dir_FindHereOrAbove(const char *here, const char *search_path) } free(try); - /* - * nope, we didn't find it. if we used up dirbase we've - * reached the root and failed. - */ if (dirbase_end == dirbase) break; /* failed! */ - /* - * truncate dirbase from the end to move up a dir - */ + /* Truncate dirbase from the end to move up a dir. */ while (dirbase_end > dirbase && *dirbase_end != '/') dirbase_end--; *dirbase_end = '\0'; /* chop! */ @@ -1431,9 +1319,9 @@ ResolveMovedDepends(GNode *gn) gn->path = bmake_strdup(fullName); if (!Job_RunTarget(".STALE", gn->fname)) fprintf(stdout, /* XXX: Why stdout? */ - "%s: %s, %d: ignoring stale %s for %s, found %s\n", - progname, gn->fname, gn->lineno, - makeDependfile, gn->name, fullName); + "%s: %s, %u: ignoring stale %s for %s, found %s\n", + progname, gn->fname, gn->lineno, + makeDependfile, gn->name, fullName); return fullName; } @@ -1448,7 +1336,7 @@ ResolveFullName(GNode *gn) fullName = Dir_FindFile(gn->name, Suff_FindPath(gn)); - if (fullName == NULL && gn->flags & FROM_DEPEND && + if (fullName == NULL && gn->flags.fromDepend && !Lst_IsEmpty(&gn->implicitParents)) fullName = ResolveMovedDepends(gn); @@ -1465,13 +1353,13 @@ ResolveFullName(GNode *gn) } /* - * Search gn along dirSearchPath and store its modification time in gn->mtime. - * If no file is found, store 0 instead. + * Search 'gn' along 'dirSearchPath' and store its modification time in + * 'gn->mtime'. If no file is found, store 0 instead. * - * The found file is stored in gn->path, unless the node already had a path. + * The found file is stored in 'gn->path', unless the node already had a path. */ void -Dir_UpdateMTime(GNode *gn, bool recheck) +Dir_UpdateMTime(GNode *gn, bool forceRefresh) { char *fullName; struct cached_stat cst; @@ -1488,7 +1376,7 @@ Dir_UpdateMTime(GNode *gn, bool recheck) fullName = ResolveFullName(gn); - if (cached_stats(fullName, &cst, recheck ? CST_UPDATE : CST_NONE) < 0) { + if (cached_stats(fullName, &cst, false, forceRefresh) < 0) { if (gn->type & OP_MEMBER) { if (fullName != gn->path) free(fullName); @@ -1551,14 +1439,14 @@ CacheNewDir(const char *name, SearchPath *path) } /* - * Read the list of filenames in the directory and store the result - * in openDirs. + * Read the list of filenames in the directory 'name' and store the result + * in 'openDirs'. * - * If a path is given, append the directory to that path. + * If a search path is given, append the directory to that path. * * Input: * path The path to which the directory should be - * added, or NULL to only add the directory to openDirs + * added, or NULL to only add the directory to openDirs. * name The name of the directory to add. * The name is not normalized in any way. * Output: @@ -1573,7 +1461,7 @@ SearchPath_Add(SearchPath *path, const char *name) { if (path != NULL && strcmp(name, ".DOTLAST") == 0) { - SearchPathNode *ln; + CachedDirListNode *ln; /* XXX: Linear search gets slow with thousands of entries. */ for (ln = path->dirs.first; ln != NULL; ln = ln->next) { @@ -1606,7 +1494,7 @@ SearchPath * Dir_CopyDirSearchPath(void) { SearchPath *path = SearchPath_New(); - SearchPathNode *ln; + CachedDirListNode *ln; for (ln = dirSearchPath.dirs.first; ln != NULL; ln = ln->next) { CachedDir *dir = ln->datum; Lst_Append(&path->dirs, CachedDir_Ref(dir)); @@ -1617,22 +1505,14 @@ Dir_CopyDirSearchPath(void) /* * Make a string by taking all the directories in the given search path and * preceding them by the given flag. Used by the suffix module to create - * variables for compilers based on suffix search paths. - * - * Input: - * flag flag which should precede each directory - * path list of directories - * - * Results: - * The string mentioned above. Note that there is no space between the - * given flag and each directory. The empty string is returned if things - * don't go well. + * variables for compilers based on suffix search paths. Note that there is no + * space between the given flag and each directory. */ char * SearchPath_ToFlags(SearchPath *path, const char *flag) { Buffer buf; - SearchPathNode *ln; + CachedDirListNode *ln; Buf_Init(&buf); @@ -1652,7 +1532,7 @@ SearchPath_ToFlags(SearchPath *path, const char *flag) void SearchPath_Free(SearchPath *path) { - SearchPathNode *ln; + CachedDirListNode *ln; for (ln = path->dirs.first; ln != NULL; ln = ln->next) { CachedDir *dir = ln->datum; @@ -1683,7 +1563,7 @@ SearchPath_Clear(SearchPath *path) void SearchPath_AddAll(SearchPath *dst, SearchPath *src) { - SearchPathNode *ln; + CachedDirListNode *ln; for (ln = src->dirs.first; ln != NULL; ln = ln->next) { CachedDir *dir = ln->datum; @@ -1698,7 +1578,6 @@ percentage(int num, int den) return den != 0 ? num * 100 / den : 0; } -/********** DEBUG INFO **********/ void Dir_PrintDirectories(void) { @@ -1721,7 +1600,7 @@ Dir_PrintDirectories(void) void SearchPath_Print(const SearchPath *path) { - SearchPathNode *ln; + CachedDirListNode *ln; for (ln = path->dirs.first; ln != NULL; ln = ln->next) { const CachedDir *dir = ln->datum; |