Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make(1): fix .INCLUDEDFROMDIR/.INCLUDEDFROMFILE
details: https://anonhg.NetBSD.org/src/rev/1661f8537c71
branches: trunk
changeset: 938287:1661f8537c71
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Sep 05 18:18:05 2020 +0000
description:
make(1): fix .INCLUDEDFROMDIR/.INCLUDEDFROMFILE
diffstat:
usr.bin/make/parse.c | 128 ++++++++++++++----------------
usr.bin/make/unit-tests/include-main.exp | 12 +-
usr.bin/make/unit-tests/include-main.mk | 10 +-
3 files changed, 73 insertions(+), 77 deletions(-)
diffs (259 lines):
diff -r 4f5dbd85d6ae -r 1661f8537c71 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c Sat Sep 05 18:13:47 2020 +0000
+++ b/usr.bin/make/parse.c Sat Sep 05 18:18:05 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.280 2020/09/05 15:12:03 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.281 2020/09/05 18:18:05 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.280 2020/09/05 15:12:03 rillig Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.281 2020/09/05 18:18:05 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.280 2020/09/05 15:12:03 rillig Exp $");
+__RCSID("$NetBSD: parse.c,v 1.281 2020/09/05 18:18:05 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -150,6 +150,7 @@
*/
typedef struct IFile {
char *fname; /* name of file */
+ Boolean fromForLoop; /* simulated .include by the .for loop */
int lineno; /* current line number in file */
int first_lineno; /* line number of start of text */
int cond_depth; /* 'if' nesting when file opened */
@@ -269,7 +270,7 @@
/* The current file from the command line (at the bottom of the stack) and
* further up all the files that are currently being read due to nested
- * .include directives. */
+ * .include or .for directives. */
static Stack /* of *IFile */ includes;
/* include paths (lists of directories) */
@@ -337,10 +338,6 @@
{ ".WAIT", Wait, 0 },
};
-/* local functions */
-
-static void ParseSetIncludedFile(void);
-
/* file loader */
struct loadedfile {
@@ -2254,7 +2251,6 @@
/* load it */
lf = loadfile(fullname, fd);
- ParseSetIncludedFile();
/* Start reading from this file next */
Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf);
curFile->lf = lf;
@@ -2313,74 +2309,70 @@
free(file);
}
+/* Split filename into dirname + basename, then assign these to the
+ * given variables. */
+static void
+SetFilenameVars(const char *filename, const char *dirvar, const char *filevar)
+{
+ const char *slash, *dirname, *basename;
+ void *freeIt;
-/*-
- *---------------------------------------------------------------------
- * ParseSetIncludedFile --
- * Set the .INCLUDEDFROMFILE variable to the contents of .PARSEFILE
- * and the .INCLUDEDFROMDIR variable to the contents of .PARSEDIR
- *
- * Results:
- * None
- *
- * Side Effects:
- * The .INCLUDEDFROMFILE variable is overwritten by the contents
- * of .PARSEFILE and the .INCLUDEDFROMDIR variable is overwriten
- * by the contents of .PARSEDIR
- *---------------------------------------------------------------------
- */
-static void
-ParseSetIncludedFile(void)
-{
- const char *pf, *pd;
- char *pf_freeIt, *pd_freeIt;
+ slash = strrchr(filename, '/');
+ if (slash == NULL) {
+ dirname = curdir;
+ basename = filename;
+ freeIt = NULL;
+ } else {
+ dirname = freeIt = bmake_strsedup(filename, slash);
+ basename = slash + 1;
+ }
- pf = Var_Value(".PARSEFILE", VAR_GLOBAL, &pf_freeIt);
- Var_Set(".INCLUDEDFROMFILE", pf, VAR_GLOBAL);
- pd = Var_Value(".PARSEDIR", VAR_GLOBAL, &pd_freeIt);
- Var_Set(".INCLUDEDFROMDIR", pd, VAR_GLOBAL);
+ Var_Set(dirvar, dirname, VAR_GLOBAL);
+ Var_Set(filevar, basename, VAR_GLOBAL);
if (DEBUG(PARSE))
- fprintf(debug_file, "%s: ${.INCLUDEDFROMDIR} = `%s' "
- "${.INCLUDEDFROMFILE} = `%s'\n", __func__, pd, pf);
-
- bmake_free(pf_freeIt);
- bmake_free(pd_freeIt);
+ fprintf(debug_file, "%s: ${%s} = `%s' ${%s} = `%s'\n",
+ __func__, dirvar, dirname, filevar, basename);
+ free(freeIt);
}
-/*-
- *---------------------------------------------------------------------
- * ParseSetParseFile --
- * Set the .PARSEDIR and .PARSEFILE variables to the dirname and
- * basename of the given filename
+
+/* Return the immediately including file.
*
- * Results:
- * None
- *
- * Side Effects:
- * The .PARSEDIR and .PARSEFILE variables are overwritten by the
- * dirname and basename of the given filename.
- *---------------------------------------------------------------------
- */
+ * This is made complicated since the .for loop is implemented as a special
+ * kind of .include; see For_Run. */
+static const char *
+GetActuallyIncludingFile(void)
+{
+ const char *filename = NULL;
+ size_t i;
+
+ /* XXX: Stack was supposed to be an opaque data structure. */
+ for (i = 0; i < includes.len; i++) {
+ IFile *parent = includes.items[i];
+ IFile *child = (i + 1 < includes.len) ? includes.items[i + 1] : curFile;
+ if (!child->fromForLoop)
+ filename = parent->fname;
+ }
+ return filename;
+}
+
+/* Set .PARSEDIR/.PARSEFILE to the given filename, as well as
+ * .INCLUDEDFROMDIR/.INCLUDEDFROMFILE. */
static void
ParseSetParseFile(const char *filename)
{
- char *slash, *dirname;
- const char *pd, *pf;
+ const char *including;
+
+ SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE");
- slash = strrchr(filename, '/');
- if (slash == NULL) {
- Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL);
- Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL);
- dirname = NULL;
+ including = GetActuallyIncludingFile();
+ if (including != NULL) {
+ SetFilenameVars(including,
+ ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE");
} else {
- dirname = bmake_strsedup(filename, slash);
- Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL);
- Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL);
+ Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL);
+ Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL);
}
- if (DEBUG(PARSE))
- fprintf(debug_file, "%s: ${.PARSEDIR} = `%s' ${.PARSEFILE} = `%s'\n",
- __func__, pd, pf);
- free(dirname);
}
/*
@@ -2424,8 +2416,9 @@
{
char *buf;
size_t len;
+ Boolean fromForLoop = name == NULL;
- if (name == NULL)
+ if (fromForLoop)
name = curFile->fname;
else
ParseTrackInput(name);
@@ -2439,7 +2432,7 @@
return;
if (curFile != NULL)
- /* Save exiting file info */
+ /* Save existing file info */
Stack_Push(&includes, curFile);
/* Allocate and fill in new structure */
@@ -2452,6 +2445,7 @@
* place.
*/
curFile->fname = bmake_strdup(name);
+ curFile->fromForLoop = fromForLoop;
curFile->lineno = line;
curFile->first_lineno = line;
curFile->nextbuf = nextbuf;
diff -r 4f5dbd85d6ae -r 1661f8537c71 usr.bin/make/unit-tests/include-main.exp
--- a/usr.bin/make/unit-tests/include-main.exp Sat Sep 05 18:13:47 2020 +0000
+++ b/usr.bin/make/unit-tests/include-main.exp Sat Sep 05 18:18:05 2020 +0000
@@ -1,10 +1,10 @@
-make: "include-main.mk" line 12: main-before-ok
-make: "include-main.mk" line 19: main-before-for-ok
+make: "include-main.mk" line 14: main-before-ok
+make: "include-main.mk" line 21: main-before-for-ok
make: "include-sub.mk" line 4: sub-before-ok
make: "include-sub.mk" line 14: sub-before-for-ok
make: "include-subsub.mk" line 4: subsub-ok
-make: "include-sub.mk" line 25: warning: sub-after-fail(include-sub.mk)
-make: "include-sub.mk" line 32: warning: sub-after-for-fail(include-sub.mk)
-make: "include-main.mk" line 30: warning: main-after-fail(include-sub.mk)
-make: "include-main.mk" line 35: main-after-for-ok
+make: "include-sub.mk" line 23: sub-after-ok
+make: "include-sub.mk" line 30: sub-after-for-ok
+make: "include-main.mk" line 30: main-after-ok
+make: "include-main.mk" line 37: main-after-for-ok
exit status 0
diff -r 4f5dbd85d6ae -r 1661f8537c71 usr.bin/make/unit-tests/include-main.mk
--- a/usr.bin/make/unit-tests/include-main.mk Sat Sep 05 18:13:47 2020 +0000
+++ b/usr.bin/make/unit-tests/include-main.mk Sat Sep 05 18:18:05 2020 +0000
@@ -1,12 +1,14 @@
-# $NetBSD: include-main.mk,v 1.4 2020/09/05 18:13:47 rillig Exp $
+# $NetBSD: include-main.mk,v 1.5 2020/09/05 18:18:05 rillig Exp $
#
-# Demonstrates that the .INCLUDEDFROMFILE magic variable does not behave
+# Until 2020-09-05, the .INCLUDEDFROMFILE magic variable did not behave
# as described in the manual page.
#
# The manual page says that it is the "filename of the file this Makefile
-# was included from", while in reality it is the "filename in which the
-# latest .include happened". See parse.c, function ParseSetIncludeFile.
+# was included from", while before 2020-09-05 it was the "filename in which
+# the latest .include happened". See parse.c, function ParseSetIncludeFile.
#
+# Since 2020-09-05, the .INCLUDEDFROMDIR and .INCLUDEDFROMFILE variables
+# properly handle nested includes and even .for loops.
.if !defined(.INCLUDEDFROMFILE)
. info main-before-ok
Home |
Main Index |
Thread Index |
Old Index