Subject: Re: make: Dir_FindFile still broken
To: Simon J. Gerraty <sjg@crufty.net>
From: Christos Zoulas <christos@zoulas.com>
List: tech-toolchain
Date: 11/25/2002 07:38:20
On Nov 24, 10:10pm, sjg@crufty.net ("Simon J. Gerraty") wrote:
-- Subject: Re: make: Dir_FindFile still broken
If you tried a make build with it, commit it...
christos
| Ok, here is the patch I've finished up with.
|
| If .CURDIR is reset, then we re-initialize dirSearchPath as well as
| dot and cur. The only time it makes sense to do this is early in
| sys.mk (which is when I do it ;-).
|
| Rather than append to ${.PATH} as dirs are added to .PATH, I rebuild
| ${.PATH} after any .PATH: line - so as to ensure that the effect of
| .DOTLAST is accurately reflected. The idea is that ${.PATH} should
| actually show the dirs in the order they will be searched.
|
| The logic used by Dir_SetPATH() follows that of Dir_FindFile()
| which is now also consitent in its calls to DirLoopupSubdir().
| Ie. if no .DOTLAST, we look in 'dot' and 'cur' first (which is what
| DirFindDot() does), and if we do have .DOTLAST we look in 'dot' and
| 'cur' last. Also we avoid looking in 'dot' more than once.
|
| --sjg
|
| Index: dir.c
| ===================================================================
| RCS file: /cvsroot/basesrc/usr.bin/make/dir.c,v
| retrieving revision 1.34
| diff -u -p -r1.34 dir.c
| --- dir.c 2002/06/15 18:24:56 1.34
| +++ dir.c 2002/11/25 06:08:40
| @@ -62,6 +62,8 @@ __RCSID("$NetBSD: dir.c,v 1.34 2002/06/1
| *
| * Dir_End Cleanup the module.
| *
| + * Dir_SetPATH Set ${.PATH} to reflect state of dirSearchPath.
| + *
| * Dir_HasWildcards Returns TRUE if the name given it needs to
| * be wildcard-expanded.
| *
| @@ -284,6 +286,7 @@ Dir_InitDot(void)
| * to make sure it's not destroyed.
| */
| dot->refCount += 1;
| + Dir_SetPATH(); /* initialize */
| }
|
| /*-
| @@ -318,6 +321,55 @@ Dir_End(void)
| #endif
| }
|
| +/*
| + * We want ${.PATH} to indicate the order in which we will actually
| + * search, so we rebuild it after any .PATH: target.
| + * This is the simplest way to deal with the effect of .DOTLAST.
| + */
| +void
| +Dir_SetPATH (void)
| +{
| + LstNode ln; /* a list element */
| + Path *p;
| + Boolean hasLastDot = FALSE; /* true we should search dot last */
| +
| + Var_Delete(".PATH", VAR_GLOBAL);
| +
| + if (Lst_Open (dirSearchPath) == SUCCESS) {
| + if ((ln = Lst_First (dirSearchPath)) != NILLNODE) {
| + p = (Path *) Lst_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);
| + }
| +
| + while ((ln = Lst_Next (dirSearchPath)) != NILLNODE) {
| + p = (Path *) Lst_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);
| + }
| +}
| +
| /*-
| *-----------------------------------------------------------------------
| * DirFindName --
| @@ -1065,19 +1117,27 @@ Dir_FindFile(char *name, Lst path)
| if (DEBUG(DIR)) {
| printf("failed. Trying subdirectories...");
| }
| -
| - /* XXX - should we look in `dot' subdirs here? */
|
| - if (!hasLastDot && cur && (file = DirLookupSubdir(cur, name)) != NULL)
| - return file;
| + if (!hasLastDot) {
| + 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);
| while ((ln = Lst_Next (path)) != NILLNODE) {
| p = (Path *) Lst_Datum (ln);
| if (p == dotLast)
| continue;
| - if (p == dot)
| + if (p == dot) {
| + if (checkedDot)
| + continue;
| checkedDot = TRUE;
| + }
| if ((file = DirLookupSubdir(p, name)) != NULL) {
| Lst_Close (path);
| return file;
| @@ -1085,8 +1145,15 @@ Dir_FindFile(char *name, Lst path)
| }
| Lst_Close (path);
|
| - if (hasLastDot && cur && (file = DirLookupSubdir(cur, name)) != NULL)
| - return file;
| + 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 (DEBUG(DIR)) {
| printf("failed. ");
| @@ -1301,7 +1368,7 @@ Dir_MTime(GNode *gn)
| Path *
| Dir_AddDir(Lst path, const char *name)
| {
| - LstNode ln; /* node in case Path structure is found */
| + LstNode ln = NILLNODE; /* 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 */
| @@ -1316,7 +1383,8 @@ Dir_AddDir(Lst path, const char *name)
| }
| }
|
| - ln = Lst_Find (openDirectories, (ClientData)name, DirFindName);
| + if (path)
| + ln = Lst_Find (openDirectories, (ClientData)name, DirFindName);
| if (ln != NILLNODE) {
| p = (Path *)Lst_Datum (ln);
| if (Lst_Member(path, (ClientData)p) == NILLNODE) {
| Index: dir.h
| ===================================================================
| RCS file: /cvsroot/basesrc/usr.bin/make/dir.h,v
| retrieving revision 1.7
| diff -u -p -r1.7 dir.h
| --- dir.h 2002/06/15 18:24:56 1.7
| +++ dir.h 2002/11/25 06:08:40
| @@ -57,6 +57,7 @@ typedef struct Path {
| void Dir_Init(const char *);
| void Dir_InitDot(void);
| void Dir_End(void);
| +void Dir_SetPATH(void);
| Boolean Dir_HasWildcards(char *);
| void Dir_Expand(char *, Lst, Lst);
| char *Dir_FindFile(char *, Lst);
| Index: parse.c
| ===================================================================
| RCS file: /cvsroot/basesrc/usr.bin/make/parse.c,v
| retrieving revision 1.84
| diff -u -p -r1.84 parse.c
| --- parse.c 2002/06/15 18:24:57 1.84
| +++ parse.c 2002/11/25 06:08:42
| @@ -1154,6 +1154,7 @@ ParseDoDependency(char *line)
| break;
| case ExPath:
| Lst_ForEach(paths, ParseClearPath, (ClientData)NULL);
| + Dir_SetPATH();
| break;
| #ifdef POSIX
| case Posix:
| @@ -1255,6 +1256,8 @@ ParseDoDependency(char *line)
| if (paths) {
| Lst_Destroy(paths, NOFREE);
| }
| + if (specType == ExPath)
| + Dir_SetPATH();
| } else {
| while (*line) {
| /*
| @@ -1594,6 +1597,15 @@ Parse_DoVar(char *line, GNode *ctxt)
| }
| if (strcmp(line, MAKEOVERRIDES) == 0)
| Main_ExportMAKEFLAGS(FALSE); /* re-export MAKEFLAGS */
| + else if (strcmp(line, ".CURDIR") == 0) {
| + /*
| + * Somone is trying to be way too clever.
| + * Let's just pretend they know what they are doing...
| + * and re-initialize dirSearchPath
| + */
| + Dir_Init(cp);
| + Dir_InitDot();
| + }
| }
|
|
-- End of excerpt from "Simon J. Gerraty"