summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c1160
1 files changed, 536 insertions, 624 deletions
diff --git a/dir.c b/dir.c
index 5c5e7e5c14f28..4a561deca6fc8 100644
--- a/dir.c
+++ b/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: dir.c,v 1.135 2020/09/02 04:32:13 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -143,10 +143,20 @@ __RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
#include <stdio.h>
#include "make.h"
-#include "hash.h"
#include "dir.h"
#include "job.h"
+
+#define DIR_DEBUG0(fmt) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt)
+
+#define DIR_DEBUG1(fmt, arg1) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt, arg1)
+
+#define DIR_DEBUG2(fmt, arg1, arg2) \
+ if (!DEBUG(DIR)) (void) 0; else fprintf(debug_file, fmt, arg1, arg2)
+
+
/*
* A search path consists of a Lst of Path structures. A Path structure
* has in it the name of the directory and a hash table of all the files
@@ -217,37 +227,35 @@ __RCSID("$NetBSD: dir.c,v 1.76 2020/07/03 08:13:23 rillig Exp $");
* in a cache for when Dir_MTime was actually called.
*/
-Lst dirSearchPath; /* main search path */
+Lst dirSearchPath; /* main search path */
-static Lst openDirectories; /* the list of all open directories */
+static Lst openDirectories; /* the list of all open directories */
/*
* Variables for gathering statistics on the efficiency of the hashing
* mechanism.
*/
-static int hits, /* Found in directory cache */
- misses, /* Sad, but not evil misses */
- nearmisses, /* Found under search path */
- bigmisses; /* Sought by itself */
-
-static Path *dot; /* contents of current directory */
-static Path *cur; /* contents of current directory, if not dot */
-static Path *dotLast; /* a fake path entry indicating we need to
- * look for . last */
-static Hash_Table mtimes; /* Results of doing a last-resort stat in
- * Dir_FindFile -- if we have to go to the
- * system to find the file, we might as well
- * have its mtime on record. 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... */
-
-static Hash_Table lmtimes; /* same as mtimes but for lstat */
-
-static int DirFindName(const void *, const void *);
-static int DirMatchFiles(const char *, Path *, Lst);
+static int hits; /* Found in directory cache */
+static int misses; /* Sad, but not evil misses */
+static int nearmisses; /* Found under search path */
+static int bigmisses; /* Sought by itself */
+
+static Path *dot; /* contents of current directory */
+static Path *cur; /* contents of current directory, if not dot */
+static Path *dotLast; /* a fake path entry indicating we need to
+ * look for . last */
+
+/* Results of doing a last-resort stat in Dir_FindFile -- if we have to go to
+ * the system to find the file, we might as well have its mtime on record.
+ *
+ * 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... */
+static Hash_Table mtimes;
+
+static Hash_Table lmtimes; /* same as mtimes but for lstat */
+
static void DirExpandCurly(const char *, const char *, Lst, Lst);
static void DirExpandInt(const char *, Lst, Lst);
static int DirPrintWord(void *, void *);
@@ -259,23 +267,28 @@ static char *DirLookupAbs(Path *, const char *, const char *);
/*
- * We use stat(2) a lot, cache the results
+ * We use stat(2) a lot, cache the results.
* mtime and mode are all we care about.
*/
struct cache_st {
- time_t lmtime; /* lstat */
- time_t mtime; /* stat */
- mode_t mode;
+ time_t lmtime; /* lstat */
+ time_t mtime; /* stat */
+ mode_t mode;
};
/* minimize changes below */
-#define CST_LSTAT 1
-#define CST_UPDATE 2
+typedef enum {
+ CST_LSTAT = 0x01, /* call lstat(2) instead of stat(2) */
+ CST_UPDATE = 0x02 /* ignore existing cached entry */
+} CachedStatsFlags;
+/* Returns 0 and the result of stat(2) or lstat(2) in *mst, or -1 on error. */
static int
-cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
+cached_stats(Hash_Table *htp, const char *pathname, struct make_stat *mst,
+ CachedStatsFlags flags)
{
Hash_Entry *entry;
+ struct stat sys_st;
struct cache_st *cst;
int rc;
@@ -284,83 +297,74 @@ cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
entry = Hash_FindEntry(htp, pathname);
- if (entry && (flags & CST_UPDATE) == 0) {
- cst = entry->clientPtr;
+ if (entry && !(flags & CST_UPDATE)) {
+ cst = Hash_GetValue(entry);
- memset(st, 0, sizeof(*st));
- st->st_mode = cst->mode;
- st->st_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
- if (st->st_mtime) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Using cached time %s for %s\n",
- Targ_FmtTime(st->st_mtime), pathname);
- }
+ mst->mst_mode = cst->mode;
+ mst->mst_mtime = (flags & CST_LSTAT) ? cst->lmtime : cst->mtime;
+ if (mst->mst_mtime) {
+ DIR_DEBUG2("Using cached time %s for %s\n",
+ Targ_FmtTime(mst->mst_mtime), pathname);
return 0;
}
}
- rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
+ rc = (flags & CST_LSTAT)
+ ? lstat(pathname, &sys_st)
+ : stat(pathname, &sys_st);
if (rc == -1)
return -1;
- if (st->st_mtime == 0)
- st->st_mtime = 1; /* avoid confusion with missing file */
+ if (sys_st.st_mtime == 0)
+ sys_st.st_mtime = 1; /* avoid confusion with missing file */
+
+ mst->mst_mode = sys_st.st_mode;
+ mst->mst_mtime = sys_st.st_mtime;
- if (!entry)
+ if (entry == NULL)
entry = Hash_CreateEntry(htp, pathname, NULL);
- if (!entry->clientPtr) {
- entry->clientPtr = bmake_malloc(sizeof(*cst));
- memset(entry->clientPtr, 0, sizeof(*cst));
+ if (Hash_GetValue(entry) == NULL) {
+ Hash_SetValue(entry, bmake_malloc(sizeof(*cst)));
+ memset(Hash_GetValue(entry), 0, sizeof(*cst));
}
- cst = entry->clientPtr;
- if ((flags & CST_LSTAT)) {
- cst->lmtime = st->st_mtime;
+ cst = Hash_GetValue(entry);
+ if (flags & CST_LSTAT) {
+ cst->lmtime = sys_st.st_mtime;
} else {
- cst->mtime = st->st_mtime;
- }
- cst->mode = st->st_mode;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Caching %s for %s\n",
- Targ_FmtTime(st->st_mtime), pathname);
+ cst->mtime = sys_st.st_mtime;
}
+ cst->mode = sys_st.st_mode;
+ DIR_DEBUG2(" Caching %s for %s\n",
+ Targ_FmtTime(sys_st.st_mtime), pathname);
return 0;
}
int
-cached_stat(const char *pathname, void *st)
+cached_stat(const char *pathname, struct make_stat *st)
{
return cached_stats(&mtimes, pathname, st, 0);
}
int
-cached_lstat(const char *pathname, void *st)
+cached_lstat(const char *pathname, struct make_stat *st)
{
return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_Init --
- * initialize things for this module
- *
- * Results:
- * none
- *
- * Side Effects:
- * some directories may be opened.
- *-----------------------------------------------------------------------
- */
+/* Initialize things for this module. */
void
-Dir_Init(const char *cdname)
+Dir_Init(void)
+{
+ dirSearchPath = Lst_Init();
+ openDirectories = Lst_Init();
+ Hash_InitTable(&mtimes, 0);
+ Hash_InitTable(&lmtimes, 0);
+}
+
+void
+Dir_InitDir(const char *cdname)
{
- if (!cdname) {
- dirSearchPath = Lst_Init(FALSE);
- openDirectories = Lst_Init(FALSE);
- Hash_InitTable(&mtimes, 0);
- Hash_InitTable(&lmtimes, 0);
- return;
- }
Dir_InitCur(cdname);
dotLast = bmake_malloc(sizeof(Path));
@@ -371,7 +375,7 @@ Dir_Init(const char *cdname)
}
/*
- * Called by Dir_Init() and whenever .CURDIR is assigned to.
+ * Called by Dir_InitDir and whenever .CURDIR is assigned to.
*/
void
Dir_InitCur(const char *cdname)
@@ -397,18 +401,8 @@ Dir_InitCur(const char *cdname)
}
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_InitDot --
- * (re)initialize "dot" (current/object directory) path hash
- *
- * Results:
- * none
- *
- * Side Effects:
- * some directories may be opened.
- *-----------------------------------------------------------------------
- */
+/* (Re)initialize "dot" (current/object directory) path hash.
+ * Some directories may be opened. */
void
Dir_InitDot(void)
{
@@ -416,8 +410,8 @@ Dir_InitDot(void)
LstNode ln;
/* Remove old entry from openDirectories, but do not destroy. */
- ln = Lst_Member(openDirectories, dot);
- (void)Lst_Remove(openDirectories, ln);
+ ln = Lst_FindDatum(openDirectories, dot);
+ Lst_Remove(openDirectories, ln);
}
dot = Dir_AddDir(NULL, ".");
@@ -432,21 +426,10 @@ Dir_InitDot(void)
* to make sure it's not destroyed.
*/
dot->refCount += 1;
- Dir_SetPATH(); /* initialize */
+ Dir_SetPATH(); /* initialize */
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_End --
- * cleanup things for this module
- *
- * Results:
- * none
- *
- * Side Effects:
- * none
- *-----------------------------------------------------------------------
- */
+/* Clean up things for this module. */
void
Dir_End(void)
{
@@ -460,9 +443,9 @@ Dir_End(void)
Dir_Destroy(dotLast);
Dir_Destroy(dot);
Dir_ClearPath(dirSearchPath);
- Lst_Destroy(dirSearchPath, NULL);
+ Lst_Free(dirSearchPath);
Dir_ClearPath(openDirectories);
- Lst_Destroy(openDirectories, NULL);
+ Lst_Free(openDirectories);
Hash_DeleteTable(&mtimes);
#endif
}
@@ -475,122 +458,100 @@ Dir_End(void)
void
Dir_SetPATH(void)
{
- LstNode ln; /* a list element */
+ LstNode ln; /* a list element */
Path *p;
- Boolean hasLastDot = FALSE; /* true we should search dot last */
+ Boolean hasLastDot = FALSE; /* true if we should search dot last */
Var_Delete(".PATH", VAR_GLOBAL);
- if (Lst_Open(dirSearchPath) == SUCCESS) {
- if ((ln = Lst_First(dirSearchPath)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast) {
- hasLastDot = TRUE;
- Var_Append(".PATH", dotLast->name, VAR_GLOBAL);
- }
+ Lst_Open(dirSearchPath);
+ if ((ln = Lst_First(dirSearchPath)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast) {
+ hasLastDot = TRUE;
+ Var_Append(".PATH", dotLast->name, VAR_GLOBAL);
}
+ }
- if (!hasLastDot) {
- if (dot)
- Var_Append(".PATH", dot->name, VAR_GLOBAL);
- if (cur)
- Var_Append(".PATH", cur->name, VAR_GLOBAL);
- }
+ if (!hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
+ }
- while ((ln = Lst_Next(dirSearchPath)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast)
- continue;
- if (p == dot && hasLastDot)
- continue;
- Var_Append(".PATH", p->name, VAR_GLOBAL);
- }
+ while ((ln = Lst_Next(dirSearchPath)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if (p == dot && hasLastDot)
+ continue;
+ Var_Append(".PATH", p->name, VAR_GLOBAL);
+ }
- if (hasLastDot) {
- if (dot)
- Var_Append(".PATH", dot->name, VAR_GLOBAL);
- if (cur)
- Var_Append(".PATH", cur->name, VAR_GLOBAL);
- }
- Lst_Close(dirSearchPath);
+ if (hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
}
+ Lst_Close(dirSearchPath);
}
-/*-
- *-----------------------------------------------------------------------
- * 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.
- *
- * Input:
- * p Current name
- * dname Desired name
- *
- * Results:
- * 0 if it is the same. Non-zero otherwise
- *
- * Side Effects:
- * None
- *-----------------------------------------------------------------------
- */
-static int
-DirFindName(const void *p, const void *dname)
+/* 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. */
+static Boolean
+DirFindName(const void *p, const void *desiredName)
{
- return strcmp(((const Path *)p)->name, dname);
+ return strcmp(((const Path *)p)->name, desiredName) == 0;
}
-/*-
- *-----------------------------------------------------------------------
- * Dir_HasWildcards --
- * see if the given name has any wildcard characters in it
- * be careful not to expand unmatching brackets or braces.
- * 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!
+/* See if the given name has any wildcard characters in it. Be careful not to
+ * expand unmatching brackets or braces.
+ *
+ * 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!
*
* Input:
* name name to check
*
* Results:
* returns TRUE if the word should be expanded, FALSE otherwise
- *
- * Side Effects:
- * none
- *-----------------------------------------------------------------------
*/
Boolean
-Dir_HasWildcards(char *name)
+Dir_HasWildcards(const char *name)
{
- char *cp;
- int wild = 0, brace = 0, bracket = 0;
+ const char *cp;
+ Boolean wild = FALSE;
+ int braces = 0, brackets = 0;
for (cp = name; *cp; cp++) {
- switch(*cp) {
+ switch (*cp) {
case '{':
- brace++;
- wild = 1;
- break;
+ braces++;
+ wild = TRUE;
+ break;
case '}':
- brace--;
- break;
+ braces--;
+ break;
case '[':
- bracket++;
- wild = 1;
- break;
+ brackets++;
+ wild = TRUE;
+ break;
case ']':
- bracket--;
- break;
+ brackets--;
+ break;
case '?':
case '*':
- wild = 1;
- break;
+ wild = TRUE;
+ break;
default:
- break;
+ break;
}
}
- return wild && bracket == 0 && brace == 0;
+ return wild && brackets == 0 && braces == 0;
}
/*-
@@ -607,20 +568,17 @@ Dir_HasWildcards(char *name)
* p Directory to search
* expansion Place to store the results
*
- * Results:
- * Always returns 0
- *
* Side Effects:
* File names are added to the expansions lst. The directory will be
* fully hashed when this is done.
*-----------------------------------------------------------------------
*/
-static int
+static void
DirMatchFiles(const char *pattern, Path *p, Lst expansions)
{
- Hash_Search search; /* Index into the directory's table */
- Hash_Entry *entry; /* Current entry in the table */
- Boolean isDot; /* TRUE if the directory being searched is . */
+ Hash_Search search; /* Index into the directory's table */
+ Hash_Entry *entry; /* Current entry in the table */
+ Boolean isDot; /* TRUE if the directory being searched is . */
isDot = (*p->name == '.' && p->name[1] == '\0');
@@ -638,13 +596,75 @@ DirMatchFiles(const char *pattern, Path *p, Lst expansions)
((entry->name[0] != '.') ||
(pattern[0] == '.')))
{
- (void)Lst_AtEnd(expansions,
- (isDot ? bmake_strdup(entry->name) :
- str_concat(p->name, entry->name,
- STR_ADDSLASH)));
+ Lst_Append(expansions,
+ (isDot ? bmake_strdup(entry->name) :
+ str_concat3(p->name, "/", entry->name)));
}
}
- return 0;
+}
+
+/* Find the next closing brace in the string, taking nested braces into
+ * account. */
+static const char *
+closing_brace(const char *p)
+{
+ int nest = 0;
+ while (*p != '\0') {
+ if (*p == '}' && nest == 0)
+ break;
+ if (*p == '{')
+ nest++;
+ if (*p == '}')
+ nest--;
+ p++;
+ }
+ return p;
+}
+
+/* Find the next closing brace or comma in the string, taking nested braces
+ * into account. */
+static const char *
+separator_comma(const char *p)
+{
+ int nest = 0;
+ while (*p != '\0') {
+ if ((*p == '}' || *p == ',') && nest == 0)
+ break;
+ if (*p == '{')
+ nest++;
+ if (*p == '}')
+ nest--;
+ p++;
+ }
+ return p;
+}
+
+static Boolean
+contains_wildcard(const char *p)
+{
+ for (; *p != '\0'; p++) {
+ switch (*p) {
+ case '*':
+ case '?':
+ case '{':
+ case '[':
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static char *
+concat3(const char *a, size_t a_len, const char *b, size_t b_len,
+ const char *c, size_t c_len)
+{
+ size_t s_len = a_len + b_len + c_len;
+ char *s = bmake_malloc(s_len + 1);
+ memcpy(s, a, a_len);
+ memcpy(s + a_len, b, b_len);
+ memcpy(s + a_len + b_len, c, c_len);
+ s[s_len] = '\0';
+ return s;
}
/*-
@@ -672,91 +692,41 @@ DirMatchFiles(const char *pattern, Path *p, Lst expansions)
static void
DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions)
{
- const char *end; /* Character after the closing brace */
- const char *cp; /* Current position in brace clause */
- const char *start; /* Start of current piece of brace clause */
- int bracelevel; /* Number of braces we've seen. If we see a
- * right brace when this is 0, we've hit the
- * end of the clause. */
- char *file; /* Current expansion */
- int otherLen; /* The length of the other pieces of the
- * expansion (chars before and after the
- * clause in 'word') */
- char *cp2; /* Pointer for checking for wildcards in
- * expansion before calling Dir_Expand */
-
- start = brace+1;
+ const char *prefix, *middle, *piece, *middle_end, *suffix;
+ size_t prefix_len, suffix_len;
- /*
- * Find the end of the brace clause first, being wary of nested brace
- * clauses.
- */
- for (end = start, bracelevel = 0; *end != '\0'; end++) {
- if (*end == '{') {
- bracelevel++;
- } else if ((*end == '}') && (bracelevel-- == 0)) {
- break;
- }
- }
- if (*end == '\0') {
- Error("Unterminated {} clause \"%s\"", start);
+ /* Split the word into prefix '{' middle '}' suffix. */
+
+ middle = brace + 1;
+ middle_end = closing_brace(middle);
+ if (*middle_end == '\0') {
+ Error("Unterminated {} clause \"%s\"", middle);
return;
- } else {
- end++;
}
- otherLen = brace - word + strlen(end);
- for (cp = start; cp < end; cp++) {
- /*
- * Find the end of this piece of the clause.
- */
- bracelevel = 0;
- while (*cp != ',') {
- if (*cp == '{') {
- bracelevel++;
- } else if ((*cp == '}') && (bracelevel-- <= 0)) {
- break;
- }
- cp++;
- }
- /*
- * Allocate room for the combination and install the three pieces.
- */
- file = bmake_malloc(otherLen + cp - start + 1);
- if (brace != word) {
- strncpy(file, word, brace-word);
- }
- if (cp != start) {
- strncpy(&file[brace-word], start, cp-start);
- }
- strcpy(&file[(brace-word)+(cp-start)], end);
+ prefix = word;
+ prefix_len = (size_t)(brace - prefix);
+ suffix = middle_end + 1;
+ suffix_len = strlen(suffix);
- /*
- * See if the result has any wildcards in it. If we find one, call
- * Dir_Expand right away, telling it to place the result on our list
- * of expansions.
- */
- for (cp2 = file; *cp2 != '\0'; cp2++) {
- switch(*cp2) {
- case '*':
- case '?':
- case '{':
- case '[':
- Dir_Expand(file, path, expansions);
- goto next;
- }
- }
- if (*cp2 == '\0') {
- /*
- * Hit the end w/o finding any wildcards, so stick the expansion
- * on the end of the list.
- */
- (void)Lst_AtEnd(expansions, file);
- } else {
- next:
+ /* Split the middle into pieces, separated by commas. */
+
+ piece = middle;
+ while (piece < middle_end + 1) {
+ const char *piece_end = separator_comma(piece);
+ size_t piece_len = (size_t)(piece_end - piece);
+
+ char *file = concat3(prefix, prefix_len, piece, piece_len,
+ suffix, suffix_len);
+
+ if (contains_wildcard(file)) {
+ Dir_Expand(file, path, expansions);
free(file);
+ } else {
+ Lst_Append(expansions, file);
}
- start = cp+1;
+
+ piece = piece_end + 1; /* skip over the comma or closing brace */
}
}
@@ -784,32 +754,18 @@ DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions)
static void
DirExpandInt(const char *word, Lst path, Lst expansions)
{
- LstNode ln; /* Current node */
- Path *p; /* Directory in the node */
+ LstNode ln; /* Current node */
- if (Lst_Open(path) == SUCCESS) {
- while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- DirMatchFiles(word, p, expansions);
- }
- Lst_Close(path);
+ Lst_Open(path);
+ while ((ln = Lst_Next(path)) != NULL) {
+ Path *p = LstNode_Datum(ln);
+ DirMatchFiles(word, p, expansions);
}
+ Lst_Close(path);
}
-/*-
- *-----------------------------------------------------------------------
- * DirPrintWord --
- * Print a word in the list of expansions. Callback for Dir_Expand
- * when DEBUG(DIR), via Lst_ForEach.
- *
- * Results:
- * === 0
- *
- * Side Effects:
- * The passed word is printed, followed by a space.
- *
- *-----------------------------------------------------------------------
- */
+/* Print a word in the list of expansions.
+ * Callback for Dir_Expand when DEBUG(DIR), via Lst_ForEach. */
static int
DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED)
{
@@ -836,16 +792,18 @@ DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED)
*
* Side Effects:
* Directories may be opened. Who knows?
+ * Undefined behavior if the word is really in read-only memory.
*-----------------------------------------------------------------------
*/
void
Dir_Expand(const char *word, Lst path, Lst expansions)
{
- const char *cp;
+ const char *cp;
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Expanding \"%s\"... ", word);
- }
+ assert(path != NULL);
+ assert(expansions != NULL);
+
+ DIR_DEBUG1("Expanding \"%s\"... ", word);
cp = strchr(word, '{');
if (cp) {
@@ -872,13 +830,12 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
/*
* Back up to the start of the component
*/
- char *dirpath;
-
while (cp > word && *cp != '/') {
cp--;
}
if (cp != word) {
char sc;
+ char *dirpath;
/*
* If the glob isn't in the first component, try and find
* all the components up to the one with a wildcard.
@@ -898,10 +855,10 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
char *dp = &dirpath[strlen(dirpath) - 1];
if (*dp == '/')
*dp = '\0';
- path = Lst_Init(FALSE);
+ path = Lst_Init();
(void)Dir_AddDir(path, dirpath);
- DirExpandInt(cp+1, path, expansions);
- Lst_Destroy(path, NULL);
+ DirExpandInt(cp + 1, path, expansions);
+ Lst_Free(path);
}
} else {
/*
@@ -948,21 +905,17 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
*/
static char *
DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
- Boolean hasSlash MAKE_ATTR_UNUSED)
+ Boolean hasSlash MAKE_ATTR_UNUSED)
{
- char *file; /* the current filename to check */
+ char *file; /* the current filename to check */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " %s ...\n", p->name);
- }
+ DIR_DEBUG1(" %s ...\n", p->name);
if (Hash_FindEntry(&p->files, cp) == NULL)
return NULL;
- file = str_concat(p->name, cp, STR_ADDSLASH);
- if (DEBUG(DIR)) {
- fprintf(debug_file, " returning %s\n", file);
- }
+ file = str_concat3(p->name, "/", cp);
+ DIR_DEBUG1(" returning %s\n", file);
p->hits += 1;
hits += 1;
return file;
@@ -986,11 +939,11 @@ DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
static char *
DirLookupSubdir(Path *p, const char *name)
{
- struct stat stb; /* Buffer for stat, if necessary */
- char *file; /* the current filename to check */
+ struct make_stat mst;
+ char *file; /* the current filename to check */
if (p != dot) {
- file = str_concat(p->name, name, STR_ADDSLASH);
+ file = str_concat3(p->name, "/", name);
} else {
/*
* Checking in dot -- DON'T put a leading ./ on the thing.
@@ -998,11 +951,9 @@ DirLookupSubdir(Path *p, const char *name)
file = bmake_strdup(name);
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "checking %s ...\n", file);
- }
+ DIR_DEBUG1("checking %s ...\n", file);
- if (cached_stat(file, &stb) == 0) {
+ if (cached_stat(file, &mst) == 0) {
nearmisses += 1;
return file;
}
@@ -1028,40 +979,34 @@ DirLookupSubdir(Path *p, const char *name)
static char *
DirLookupAbs(Path *p, const char *name, const char *cp)
{
- char *p1; /* pointer into p->name */
- const char *p2; /* pointer into name */
+ char *p1; /* pointer into p->name */
+ const char *p2; /* pointer into name */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " %s ...\n", p->name);
- }
+ DIR_DEBUG1(" %s ...\n", p->name);
- /*
- * If the file has a leading path component and that component
- * exactly matches the entire name of the current search
- * directory, we can attempt another cache lookup. And if we don't
- * have a hit, we can safely assume the file does not exist at all.
- */
- for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {
- continue;
- }
- if (*p1 != '\0' || p2 != cp - 1) {
- return NULL;
- }
+ /*
+ * If the file has a leading path component and that component
+ * exactly matches the entire name of the current search
+ * directory, we can attempt another cache lookup. And if we don't
+ * have a hit, we can safely assume the file does not exist at all.
+ */
+ for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {
+ continue;
+ }
+ if (*p1 != '\0' || p2 != cp - 1) {
+ return NULL;
+ }
- if (Hash_FindEntry(&p->files, cp) == NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " must be here but isn't -- returning\n");
- }
- /* Return empty string: terminates search */
- return bmake_strdup("");
- }
+ if (Hash_FindEntry(&p->files, cp) == NULL) {
+ DIR_DEBUG0(" must be here but isn't -- returning\n");
+ /* Return empty string: terminates search */
+ return bmake_strdup("");
+ }
- p->hits += 1;
- hits += 1;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " returning %s\n", name);
- }
- return bmake_strdup(name);
+ p->hits += 1;
+ hits += 1;
+ DIR_DEBUG1(" returning %s\n", name);
+ return bmake_strdup(name);
}
/*-
@@ -1081,25 +1026,20 @@ static char *
DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
{
- if (Hash_FindEntry(&dot->files, cp) != NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " in '.'\n");
- }
- hits += 1;
- dot->hits += 1;
- return bmake_strdup(name);
- }
- if (cur &&
- Hash_FindEntry(&cur->files, cp) != NULL) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " in ${.CURDIR} = %s\n", cur->name);
- }
- hits += 1;
- cur->hits += 1;
- return str_concat(cur->name, cp, STR_ADDSLASH);
- }
+ if (Hash_FindEntry(&dot->files, cp) != NULL) {
+ DIR_DEBUG0(" in '.'\n");
+ hits += 1;
+ dot->hits += 1;
+ return bmake_strdup(name);
+ }
+ if (cur && Hash_FindEntry(&cur->files, cp) != NULL) {
+ DIR_DEBUG1(" in ${.CURDIR} = %s\n", cur->name);
+ hits += 1;
+ cur->hits += 1;
+ return str_concat3(cur->name, "/", cp);
+ }
- return NULL;
+ return NULL;
}
/*-
@@ -1127,14 +1067,14 @@ DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
char *
Dir_FindFile(const char *name, Lst path)
{
- LstNode ln; /* a list element */
- char *file; /* the current filename to check */
- Path *p; /* current path member */
- const char *cp; /* Terminal name of file */
- Boolean hasLastDot = FALSE; /* true we should search dot last */
- Boolean hasSlash; /* true if 'name' contains a / */
- struct stat stb; /* Buffer for stat, if necessary */
- const char *trailing_dot = ".";
+ LstNode ln; /* a list element */
+ char *file; /* the current filename to check */
+ Path *p; /* current path member */
+ const char *cp; /* Terminal name of file */
+ Boolean hasLastDot = FALSE; /* true we should search dot last */
+ Boolean hasSlash; /* true if 'name' contains a / */
+ struct make_stat mst; /* Buffer for stat, if necessary */
+ const char *trailing_dot = ".";
/*
* Find the final component of the name and note whether it has a
@@ -1149,29 +1089,23 @@ Dir_FindFile(const char *name, Lst path)
cp = name;
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Searching for %s ...", name);
- }
+ DIR_DEBUG1("Searching for %s ...", name);
- if (Lst_Open(path) == FAILURE) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "couldn't open path, file not found\n");
- }
+ if (path == NULL) {
+ DIR_DEBUG0("couldn't open path, file not found\n");
misses += 1;
return NULL;
}
+ Lst_Open(path);
if ((ln = Lst_First(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast) {
hasLastDot = TRUE;
- if (DEBUG(DIR))
- fprintf(debug_file, "[dot last]...");
+ DIR_DEBUG0("[dot last]...");
}
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, "\n");
- }
+ DIR_DEBUG0("\n");
/*
* If there's no leading directory components or if the leading
@@ -1179,41 +1113,39 @@ Dir_FindFile(const char *name, Lst path)
* of each of the directories on the search path.
*/
if (!hasSlash || (cp - name == 2 && *name == '.')) {
- /*
- * We look through all the directories on the path seeking one which
- * contains the final component of the given name. If such a beast
- * 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...
- *
- * 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.
- * This is so there are no conflicts between what the user
- * specifies (fish.c) and what pmake finds (./fish.c).
- */
- if (!hasLastDot &&
- (file = DirFindDot(hasSlash, name, cp)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ /*
+ * We look through all the directories on the path seeking one which
+ * contains the final component of the given name. If such a beast
+ * 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...
+ *
+ * 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.
+ * This is so there are no conflicts between what the user
+ * specifies (fish.c) and what pmake finds (./fish.c).
+ */
+ if (!hasLastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
- while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (p == dotLast)
- continue;
- if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = LstNode_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) {
+ Lst_Close(path);
+ return file;
}
+ }
- if (hasLastDot &&
- (file = DirFindDot(hasSlash, name, cp)) != NULL) {
- Lst_Close(path);
- return file;
- }
+ if (hasLastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
}
Lst_Close(path);
@@ -1232,9 +1164,7 @@ Dir_FindFile(const char *name, Lst path)
* This phase is only performed if the file is *not* absolute.
*/
if (!hasSlash) {
- if (DEBUG(DIR)) {
- fprintf(debug_file, " failed.\n");
- }
+ DIR_DEBUG0(" failed.\n");
misses += 1;
return NULL;
}
@@ -1245,30 +1175,28 @@ Dir_FindFile(const char *name, Lst path)
}
if (name[0] != '/') {
- Boolean checkedDot = FALSE;
+ Boolean checkedDot = FALSE;
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Trying subdirectories...\n");
- }
+ DIR_DEBUG0(" Trying subdirectories...\n");
if (!hasLastDot) {
- if (dot) {
- checkedDot = TRUE;
- if ((file = DirLookupSubdir(dot, name)) != NULL)
- return file;
- }
- if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
- return file;
+ if (dot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
}
- (void)Lst_Open(path);
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast)
continue;
if (p == dot) {
- if (checkedDot)
- continue;
+ if (checkedDot)
+ continue;
checkedDot = TRUE;
}
if ((file = DirLookupSubdir(p, name)) != NULL) {
@@ -1279,13 +1207,13 @@ Dir_FindFile(const char *name, Lst path)
Lst_Close(path);
if (hasLastDot) {
- if (dot && !checkedDot) {
- checkedDot = TRUE;
- if ((file = DirLookupSubdir(dot, name)) != NULL)
- return file;
- }
- if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
- return file;
+ if (dot && !checkedDot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
}
if (checkedDot) {
@@ -1293,9 +1221,7 @@ Dir_FindFile(const char *name, Lst path)
* Already checked by the given name, since . was in the path,
* so no point in proceeding...
*/
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Checked . already, returning NULL\n");
- }
+ DIR_DEBUG0(" Checked . already, returning NULL\n");
return NULL;
}
@@ -1310,12 +1236,10 @@ Dir_FindFile(const char *name, Lst path)
* file does not exist at all. This is signified by DirLookupAbs()
* returning an empty string.
*/
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Trying exact path matches...\n");
- }
+ DIR_DEBUG0(" Trying exact path matches...\n");
- if (!hasLastDot && cur && ((file = DirLookupAbs(cur, name, cp))
- != NULL)) {
+ if (!hasLastDot && cur &&
+ ((file = DirLookupAbs(cur, name, cp)) != NULL)) {
if (file[0] == '\0') {
free(file);
return NULL;
@@ -1323,9 +1247,9 @@ Dir_FindFile(const char *name, Lst path)
return file;
}
- (void)Lst_Open(path);
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
if (p == dotLast)
continue;
if ((file = DirLookupAbs(p, name, cp)) != NULL) {
@@ -1339,8 +1263,8 @@ Dir_FindFile(const char *name, Lst path)
}
Lst_Close(path);
- if (hasLastDot && cur && ((file = DirLookupAbs(cur, name, cp))
- != NULL)) {
+ if (hasLastDot && cur &&
+ ((file = DirLookupAbs(cur, name, cp)) != NULL)) {
if (file[0] == '\0') {
free(file);
return NULL;
@@ -1380,7 +1304,7 @@ Dir_FindFile(const char *name, Lst path)
if (ln == NULL) {
return NULL;
} else {
- p = (Path *)Lst_Datum(ln);
+ p = LstNode_Datum(ln);
}
if (Hash_FindEntry(&p->files, cp) != NULL) {
@@ -1389,18 +1313,14 @@ Dir_FindFile(const char *name, Lst path)
return NULL;
}
#else /* !notdef */
- if (DEBUG(DIR)) {
- fprintf(debug_file, " Looking for \"%s\" ...\n", name);
- }
+ DIR_DEBUG1(" Looking for \"%s\" ...\n", name);
bigmisses += 1;
- if (cached_stat(name, &stb) == 0) {
+ if (cached_stat(name, &mst) == 0) {
return bmake_strdup(name);
}
- if (DEBUG(DIR)) {
- fprintf(debug_file, " failed. Returning NULL\n");
- }
+ DIR_DEBUG0(" failed. Returning NULL\n");
return NULL;
#endif /* notdef */
}
@@ -1416,7 +1336,7 @@ Dir_FindFile(const char *name, Lst path)
* here starting directory
* search_path the path we are looking for
* result the result of a successful search is placed here
- * rlen the length of the result buffer
+ * result_len the length of the result buffer
* (typically MAXPATHLEN + 1)
*
* Results:
@@ -1426,62 +1346,57 @@ Dir_FindFile(const char *name, Lst path)
* Side Effects:
*-----------------------------------------------------------------------
*/
-int
-Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
-
- struct stat st;
- char dirbase[MAXPATHLEN + 1], *db_end;
- char try[MAXPATHLEN + 1], *try_end;
-
- /* copy out our starting point */
- snprintf(dirbase, sizeof(dirbase), "%s", here);
- db_end = dirbase + strlen(dirbase);
-
- /* loop until we determine a result */
- while (1) {
+Boolean
+Dir_FindHereOrAbove(const char *here, const char *search_path,
+ char *result, int result_len)
+{
+ struct make_stat mst;
+ char dirbase[MAXPATHLEN + 1], *dirbase_end;
+ char try[MAXPATHLEN + 1], *try_end;
- /* try and stat(2) it ... */
- snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
- if (cached_stat(try, &st) != -1) {
- /*
- * success! if we found a file, chop off
- * the filename so we return a directory.
- */
- if ((st.st_mode & S_IFMT) != S_IFDIR) {
- try_end = try + strlen(try);
- while (try_end > try && *try_end != '/')
- try_end--;
- if (try_end > try)
- *try_end = 0; /* chop! */
- }
+ /* copy out our starting point */
+ snprintf(dirbase, sizeof(dirbase), "%s", here);
+ dirbase_end = dirbase + strlen(dirbase);
- /*
- * done!
- */
- snprintf(result, rlen, "%s", try);
- return 1;
- }
+ /* loop until we determine a result */
+ while (TRUE) {
- /*
- * nope, we didn't find it. if we used up dirbase we've
- * reached the root and failed.
- */
- if (db_end == dirbase)
- break; /* failed! */
+ /* try and stat(2) it ... */
+ snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
+ if (cached_stat(try, &mst) != -1) {
+ /*
+ * success! if we found a file, chop off
+ * the filename so we return a directory.
+ */
+ if ((mst.mst_mode & S_IFMT) != S_IFDIR) {
+ try_end = try + strlen(try);
+ while (try_end > try && *try_end != '/')
+ try_end--;
+ if (try_end > try)
+ *try_end = '\0'; /* chop! */
+ }
- /*
- * truncate dirbase from the end to move up a dir
- */
- while (db_end > dirbase && *db_end != '/')
- db_end--;
- *db_end = 0; /* chop! */
+ snprintf(result, result_len, "%s", try);
+ return TRUE;
+ }
- } /* while (1) */
+ /*
+ * nope, we didn't find it. if we used up dirbase we've
+ * reached the root and failed.
+ */
+ if (dirbase_end == dirbase)
+ break; /* failed! */
/*
- * we failed...
+ * truncate dirbase from the end to move up a dir
*/
- return 0;
+ while (dirbase_end > dirbase && *dirbase_end != '/')
+ dirbase_end--;
+ *dirbase_end = '\0'; /* chop! */
+
+ } /* while (TRUE) */
+
+ return FALSE;
}
/*-
@@ -1505,8 +1420,8 @@ Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
int
Dir_MTime(GNode *gn, Boolean recheck)
{
- char *fullName; /* the full pathname of name */
- struct stat stb; /* buffer for finding the mod time */
+ char *fullName; /* the full pathname of name */
+ struct make_stat mst; /* buffer for finding the mod time */
if (gn->type & OP_ARCHV) {
return Arch_MTime(gn);
@@ -1519,7 +1434,7 @@ Dir_MTime(GNode *gn, Boolean recheck)
else {
fullName = Dir_FindFile(gn->name, Suff_FindPath(gn));
if (fullName == NULL && gn->flags & FROM_DEPEND &&
- !Lst_IsEmpty(gn->iParents)) {
+ !Lst_IsEmpty(gn->implicitParents)) {
char *cp;
cp = strrchr(gn->name, '/');
@@ -1539,15 +1454,15 @@ Dir_MTime(GNode *gn, Boolean recheck)
gn->path = bmake_strdup(fullName);
if (!Job_RunTarget(".STALE", gn->fname))
fprintf(stdout,
- "%s: %s, %d: ignoring stale %s for %s, "
- "found %s\n", progname, gn->fname, gn->lineno,
- makeDependfile, gn->name, fullName);
+ "%s: %s, %d: ignoring stale %s for %s, "
+ "found %s\n", progname, gn->fname,
+ gn->lineno,
+ makeDependfile, gn->name, fullName);
}
}
}
- if (DEBUG(DIR))
- fprintf(debug_file, "Found '%s' as '%s'\n",
- gn->name, fullName ? fullName : "(not found)" );
+ DIR_DEBUG2("Found '%s' as '%s'\n",
+ gn->name, fullName ? fullName : "(not found)");
}
} else {
fullName = gn->path;
@@ -1557,13 +1472,13 @@ Dir_MTime(GNode *gn, Boolean recheck)
fullName = bmake_strdup(gn->name);
}
- if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
+ if (cached_stats(&mtimes, fullName, &mst, recheck ? CST_UPDATE : 0) < 0) {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
free(fullName);
return Arch_MemMTime(gn);
} else {
- stb.st_mtime = 0;
+ mst.mst_mtime = 0;
}
}
@@ -1571,7 +1486,7 @@ Dir_MTime(GNode *gn, Boolean recheck)
gn->path = fullName;
}
- gn->mtime = stb.st_mtime;
+ gn->mtime = mst.mst_mtime;
return gn->mtime;
}
@@ -1585,6 +1500,8 @@ Dir_MTime(GNode *gn, Boolean recheck)
* Input:
* path the path to which the directory should be
* added
+ * XXX: Why would this ever be NULL, and what does
+ * that mean?
* name the name of the directory to add
*
* Results:
@@ -1598,78 +1515,70 @@ Dir_MTime(GNode *gn, Boolean recheck)
Path *
Dir_AddDir(Lst path, const char *name)
{
- LstNode ln = NULL; /* node in case Path structure is found */
- Path *p = NULL; /* pointer to new Path structure */
- DIR *d; /* for reading directory */
- struct dirent *dp; /* entry in directory */
+ LstNode ln = NULL; /* node in case Path structure is found */
+ Path *p = NULL; /* pointer to new Path structure */
+ DIR *d; /* for reading directory */
+ struct dirent *dp; /* entry in directory */
- if (strcmp(name, ".DOTLAST") == 0) {
- ln = Lst_Find(path, name, DirFindName);
+ if (path != NULL && strcmp(name, ".DOTLAST") == 0) {
+ ln = Lst_Find(path, DirFindName, name);
if (ln != NULL)
- return (Path *)Lst_Datum(ln);
- else {
- dotLast->refCount += 1;
- (void)Lst_AtFront(path, dotLast);
- }
+ return LstNode_Datum(ln);
+
+ dotLast->refCount++;
+ Lst_Prepend(path, dotLast);
}
- if (path)
- ln = Lst_Find(openDirectories, name, DirFindName);
+ if (path != NULL)
+ ln = Lst_Find(openDirectories, DirFindName, name);
if (ln != NULL) {
- p = (Path *)Lst_Datum(ln);
- if (path && Lst_Member(path, p) == NULL) {
+ p = LstNode_Datum(ln);
+ if (Lst_FindDatum(path, p) == NULL) {
p->refCount += 1;
- (void)Lst_AtEnd(path, p);
- }
- } else {
- if (DEBUG(DIR)) {
- fprintf(debug_file, "Caching %s ...", name);
+ Lst_Append(path, p);
}
+ return p;
+ }
+
+ DIR_DEBUG1("Caching %s ...", name);
- if ((d = opendir(name)) != NULL) {
- p = bmake_malloc(sizeof(Path));
- p->name = bmake_strdup(name);
- p->hits = 0;
- p->refCount = 1;
- Hash_InitTable(&p->files, -1);
+ if ((d = opendir(name)) != NULL) {
+ p = bmake_malloc(sizeof(Path));
+ p->name = bmake_strdup(name);
+ p->hits = 0;
+ p->refCount = 1;
+ Hash_InitTable(&p->files, -1);
- while ((dp = readdir(d)) != NULL) {
+ 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, NULL);
+ /*
+ * 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;
}
- (void)closedir(d);
- (void)Lst_AtEnd(openDirectories, p);
- if (path != NULL)
- (void)Lst_AtEnd(path, p);
- }
- if (DEBUG(DIR)) {
- fprintf(debug_file, "done\n");
+#endif /* sun && d_ino */
+ (void)Hash_CreateEntry(&p->files, dp->d_name, NULL);
}
+ (void)closedir(d);
+ Lst_Append(openDirectories, p);
+ if (path != NULL)
+ Lst_Append(path, p);
}
+ DIR_DEBUG0("done\n");
return p;
}
/*-
*-----------------------------------------------------------------------
* Dir_CopyDir --
- * Callback function for duplicating a search path via Lst_Duplicate.
+ * Callback function for duplicating a search path via Lst_Copy.
* Ups the reference count for the directory.
*
* Results:
* Returns the Path it was given.
- *
- * Side Effects:
- * The refCount of the path is incremented.
- *
*-----------------------------------------------------------------------
*/
void *
@@ -1704,25 +1613,23 @@ Dir_CopyDir(void *p)
char *
Dir_MakeFlags(const char *flag, Lst path)
{
- char *str; /* the string which will be returned */
- char *s1, *s2;/* the current directory preceded by 'flag' */
- LstNode ln; /* the node of the current directory */
- Path *p; /* the structure describing the current directory */
+ Buffer buf;
+ LstNode ln; /* the node of the current directory */
- str = bmake_strdup("");
+ Buf_Init(&buf, 0);
- if (Lst_Open(path) == SUCCESS) {
+ if (path != NULL) {
+ Lst_Open(path);
while ((ln = Lst_Next(path)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- s2 = str_concat(flag, p->name, 0);
- str = str_concat(s1 = str, s2, STR_ADDSPACE);
- free(s1);
- free(s2);
+ Path *p = LstNode_Datum(ln);
+ Buf_AddStr(&buf, " ");
+ Buf_AddStr(&buf, flag);
+ Buf_AddStr(&buf, p->name);
}
Lst_Close(path);
}
- return str;
+ return Buf_Destroy(&buf, FALSE);
}
/*-
@@ -1746,14 +1653,14 @@ Dir_MakeFlags(const char *flag, Lst path)
void
Dir_Destroy(void *pp)
{
- Path *p = (Path *)pp;
+ Path *p = (Path *)pp;
p->refCount -= 1;
if (p->refCount == 0) {
- LstNode ln;
+ LstNode ln;
- ln = Lst_Member(openDirectories, p);
- (void)Lst_Remove(openDirectories, ln);
+ ln = Lst_FindDatum(openDirectories, p);
+ Lst_Remove(openDirectories, ln);
Hash_DeleteTable(&p->files);
free(p->name);
@@ -1781,9 +1688,8 @@ Dir_Destroy(void *pp)
void
Dir_ClearPath(Lst path)
{
- Path *p;
while (!Lst_IsEmpty(path)) {
- p = (Path *)Lst_DeQueue(path);
+ Path *p = Lst_Dequeue(path);
Dir_Destroy(p);
}
}
@@ -1811,37 +1717,43 @@ void
Dir_Concat(Lst path1, Lst path2)
{
LstNode ln;
- Path *p;
+ Path *p;
- for (ln = Lst_First(path2); ln != NULL; ln = Lst_Succ(ln)) {
- p = (Path *)Lst_Datum(ln);
- if (Lst_Member(path1, p) == NULL) {
+ for (ln = Lst_First(path2); ln != NULL; ln = LstNode_Next(ln)) {
+ p = LstNode_Datum(ln);
+ if (Lst_FindDatum(path1, p) == NULL) {
p->refCount += 1;
- (void)Lst_AtEnd(path1, p);
+ Lst_Append(path1, p);
}
}
}
+static int
+percentage(int num, int den)
+{
+ return den != 0 ? num * 100 / den : 0;
+}
+
/********** DEBUG INFO **********/
void
Dir_PrintDirectories(void)
{
- LstNode ln;
- Path *p;
+ LstNode ln;
fprintf(debug_file, "#*** Directory Cache:\n");
- fprintf(debug_file, "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
- hits, misses, nearmisses, bigmisses,
- (hits+bigmisses+nearmisses ?
- hits * 100 / (hits + bigmisses + nearmisses) : 0));
+ fprintf(debug_file,
+ "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
+ hits, misses, nearmisses, bigmisses,
+ percentage(hits, hits + bigmisses + nearmisses));
fprintf(debug_file, "# %-20s referenced\thits\n", "directory");
- if (Lst_Open(openDirectories) == SUCCESS) {
- while ((ln = Lst_Next(openDirectories)) != NULL) {
- p = (Path *)Lst_Datum(ln);
- fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits);
- }
- Lst_Close(openDirectories);
+
+ Lst_Open(openDirectories);
+ while ((ln = Lst_Next(openDirectories)) != NULL) {
+ Path *p = LstNode_Datum(ln);
+ fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount,
+ p->hits);
}
+ Lst_Close(openDirectories);
}
static int