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"