add parent directory search for make as discussed on tech-toolchain.

- new dir.c function: 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 ("/").
 - add hooks to use it in main.c for -m and syspath (compiled in
      _PATH_DEFSYSPATH and $MAKESYSPATH).
 - updated man page
This commit is contained in:
chuck 2004-02-03 19:25:29 +00:00
parent b267be2d28
commit 51659857a7
4 changed files with 139 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.39 2004/01/11 12:22:40 dsl Exp $ */
/* $NetBSD: dir.c,v 1.40 2004/02/03 19:25:29 chuck Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -70,14 +70,14 @@
*/
#ifdef MAKE_BOOTSTRAP
static char rcsid[] = "$NetBSD: dir.c,v 1.39 2004/01/11 12:22:40 dsl Exp $";
static char rcsid[] = "$NetBSD: dir.c,v 1.40 2004/02/03 19:25:29 chuck 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.39 2004/01/11 12:22:40 dsl Exp $");
__RCSID("$NetBSD: dir.c,v 1.40 2004/02/03 19:25:29 chuck Exp $");
#endif
#endif /* not lint */
#endif
@ -109,6 +109,10 @@ __RCSID("$NetBSD: dir.c,v 1.39 2004/01/11 12:22:40 dsl Exp $");
* If it exists, the entire path is returned.
* Otherwise NULL is returned.
*
* 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 ("/").
*
* Dir_MTime Return the modification time of a node. The file
* is searched for along the default search path.
* The path and mtime fields of the node are filled
@ -1312,6 +1316,85 @@ Dir_FindFile(const char *name, Lst path)
#endif /* notdef */
}
/*-
*-----------------------------------------------------------------------
* Dir_FindHereOrAbove --
* 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 path we are looking for
* result the result of a successful search is placed here
* rlen the length of the result buffer
* (typically MAXPATHLEN + 1)
*
* Results:
* 0 on failure, 1 on success [in which case the found path is put
* in the result buffer].
*
* 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) {
/* try and stat(2) it ... */
snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
if (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! */
}
/*
* done!
*/
snprintf(result, rlen, "%s", try);
return(1);
}
/*
* nope, we didn't find it. if we used up dirbase we've
* reached the root and failed.
*/
if (db_end == dirbase)
break; /* failed! */
/*
* truncate dirbase from the end to move up a dir
*/
while (db_end > dirbase && *db_end != '/')
db_end--;
*db_end = 0; /* chop! */
} /* while (1) */
/*
* we failed...
*/
return(0);
}
/*-
*-----------------------------------------------------------------------
* Dir_MTime --

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.h,v 1.10 2003/08/07 11:14:50 agc Exp $ */
/* $NetBSD: dir.h,v 1.11 2004/02/03 19:25:29 chuck Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@ -94,6 +94,7 @@ void Dir_SetPATH(void);
Boolean Dir_HasWildcards(char *);
void Dir_Expand(const char *, Lst, Lst);
char *Dir_FindFile(const char *, Lst);
int Dir_FindHereOrAbove(char *, char *, char *, int);
int Dir_MTime(GNode *);
Path *Dir_AddDir(Lst, const char *);
char *Dir_MakeFlags(const char *, Lst);

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.96 2004/01/05 23:23:35 jmmv Exp $ */
/* $NetBSD: main.c,v 1.97 2004/02/03 19:25:29 chuck Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,7 +69,7 @@
*/
#ifdef MAKE_BOOTSTRAP
static char rcsid[] = "$NetBSD: main.c,v 1.96 2004/01/05 23:23:35 jmmv Exp $";
static char rcsid[] = "$NetBSD: main.c,v 1.97 2004/02/03 19:25:29 chuck Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: main.c,v 1.96 2004/01/05 23:23:35 jmmv Exp $");
__RCSID("$NetBSD: main.c,v 1.97 2004/02/03 19:25:29 chuck Exp $");
#endif
#endif /* not lint */
#endif
@ -206,6 +206,7 @@ MainParseArgs(int argc, char **argv)
{
char *p;
int c;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
optind = 1; /* since we're called more than once */
#ifdef REMOTE
@ -391,7 +392,16 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
break;
case 'm':
(void) Dir_AddDir(sysIncPath, optarg);
/* look for magic parent directory search string */
if (strncmp(".../", optarg, 4) == 0) {
if (!Dir_FindHereOrAbove(curdir, optarg+4,
found_path, sizeof(found_path)))
break; /* nothing doing */
(void) Dir_AddDir(sysIncPath, found_path);
} else {
(void) Dir_AddDir(sysIncPath, optarg);
}
Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
break;
@ -565,6 +575,7 @@ main(int argc, char **argv)
char *cp = NULL, *start;
/* avoid faults on read-only strings */
static char defsyspath[] = _PATH_DEFSYSPATH;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
if ((progname = strrchr(argv[0], '/')) != NULL)
progname++;
@ -808,11 +819,17 @@ main(int argc, char **argv)
for (start = syspath; *start != '\0'; start = cp) {
for (cp = start; *cp != '\0' && *cp != ':'; cp++)
continue;
if (*cp == '\0') {
if (*cp == ':') {
*cp++ = '\0';
}
/* look for magic parent directory search string */
if (strncmp(".../", start, 4) != 0) {
(void) Dir_AddDir(defIncPath, start);
} else {
*cp++ = '\0';
(void) Dir_AddDir(defIncPath, start);
if (Dir_FindHereOrAbove(curdir, start+4,
found_path, sizeof(found_path))) {
(void) Dir_AddDir(defIncPath, found_path);
}
}
}
if (syspath != defsyspath)

View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.97 2004/01/27 01:38:01 lukem Exp $
.\" $NetBSD: make.1,v 1.98 2004/02/03 19:25:29 chuck Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -188,13 +188,36 @@ Continue processing after errors are encountered, but only on those targets
that do not depend on the target whose creation caused the error.
.It Fl m Ar directory
Specify a directory in which to search for sys.mk and makefiles included
via the \*[Lt]...\*[Gt] style.
Multiple directories can be added to form a search path.
via the
.Aq Ar file
style include statement.
The
.Fl m
option can be used multiple times to form a search path.
This path will override the default system include path: /usr/share/mk.
Furthermore the system include path will be appended to the search path used
for "..."-style inclusions (see the
for
.Pf \*q Ar file Ns \*q
style include statements (see the
.Fl I
option).
.Pp
If a file or directory name in the
.Fl m
argument (or the
.Ev MAKESYSPATH
environment variable) starts with the string ".../" then
.Nm
will search for the specified file or directory named in the remaining part
of the argument string. The search starts with the current directory of
the Makefile and then works upward towards the root of the filesystem.
If the search is successful, then the resulting directory replaces the
".../" specification in the
.Fl m
argument. If used, this feature allows
.Nm
to easily search in the current source tree for customized sys.mk files
(e.g. by using ".../mk/sys.mk" as an argument).
.It Fl n
Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE special