Module Name: src
Committed By: rillig
Date: Tue Aug 27 04:52:14 UTC 2024
Modified Files:
src/usr.bin/make: main.c make.h var.c
src/usr.bin/make/unit-tests: var-recursive.exp var-recursive.mk
Log Message:
make: treat recursive variables non-fatally
A recursive variable is no worse than an unknown modifier, so treat them
in the same way by continuing parsing until the end of the makefile.
To generate a diff of this commit:
cvs rdiff -u -r1.633 -r1.634 src/usr.bin/make/main.c
cvs rdiff -u -r1.345 -r1.346 src/usr.bin/make/make.h
cvs rdiff -u -r1.1137 -r1.1138 src/usr.bin/make/var.c
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/unit-tests/var-recursive.exp
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/var-recursive.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.633 src/usr.bin/make/main.c:1.634
--- src/usr.bin/make/main.c:1.633 Sun Aug 25 20:44:31 2024
+++ src/usr.bin/make/main.c Tue Aug 27 04:52:14 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.633 2024/08/25 20:44:31 rillig Exp $ */
+/* $NetBSD: main.c,v 1.634 2024/08/27 04:52:14 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -111,7 +111,7 @@
#include "trace.h"
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: main.c,v 1.633 2024/08/25 20:44:31 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.634 2024/08/27 04:52:14 rillig Exp $");
#if defined(MAKE_NATIVE)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. "
@@ -1859,13 +1859,6 @@ Error(const char *fmt, ...)
main_errors++;
}
-void
-WaitForJobs(void)
-{
- if (jobsRunning)
- Job_Wait();
-}
-
/*
* Wait for any running jobs to finish, then produce an error message,
* finally exit immediately.
@@ -1878,7 +1871,8 @@ Fatal(const char *fmt, ...)
{
va_list ap;
- WaitForJobs();
+ if (jobsRunning)
+ Job_Wait();
(void)fflush(stdout);
fprintf(stderr, "%s: ", progname);
Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.345 src/usr.bin/make/make.h:1.346
--- src/usr.bin/make/make.h:1.345 Sun Aug 25 20:44:31 2024
+++ src/usr.bin/make/make.h Tue Aug 27 04:52:14 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.345 2024/08/25 20:44:31 rillig Exp $ */
+/* $NetBSD: make.h,v 1.346 2024/08/27 04:52:14 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -864,7 +864,6 @@ char *getTmpdir(void) MAKE_ATTR_USE;
bool ParseBoolean(const char *, bool) MAKE_ATTR_USE;
const char *cached_realpath(const char *, char *);
bool GetBooleanExpr(const char *, bool);
-void WaitForJobs(void);
/* parse.c */
extern int parseErrors;
Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.1137 src/usr.bin/make/var.c:1.1138
--- src/usr.bin/make/var.c:1.1137 Sun Aug 25 20:44:31 2024
+++ src/usr.bin/make/var.c Tue Aug 27 04:52:14 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1137 2024/08/25 20:44:31 rillig Exp $ */
+/* $NetBSD: var.c,v 1.1138 2024/08/27 04:52:14 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -129,7 +129,7 @@
#include "trace.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1137 2024/08/25 20:44:31 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1138 2024/08/27 04:52:14 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@@ -4573,16 +4573,13 @@ Var_Parse(const char **pp, GNode *scope,
expr.name = v->name.str;
if (v->inUse && VarEvalMode_ShouldEval(emode)) {
- if (scope->fname != NULL) {
- fprintf(stderr, "In a command near ");
- PrintLocation(stderr, false, scope);
- }
- WaitForJobs();
Parse_Error(PARSE_FATAL, "Variable %s is recursive.",
v->name.str);
- PrintOnError(NULL, "\n");
- Trace_Log(MAKEERROR, NULL);
- exit(2); /* Not 1 so -q can distinguish error */
+ FStr_Done(&val);
+ if (*p != '\0')
+ p++;
+ *pp = p;
+ return FStr_InitRefer(var_Error);
}
/*
Index: src/usr.bin/make/unit-tests/var-recursive.exp
diff -u src/usr.bin/make/unit-tests/var-recursive.exp:1.10 src/usr.bin/make/unit-tests/var-recursive.exp:1.11
--- src/usr.bin/make/unit-tests/var-recursive.exp:1.10 Sun Aug 25 20:44:31 2024
+++ src/usr.bin/make/unit-tests/var-recursive.exp Tue Aug 27 04:52:14 2024
@@ -1,23 +1,20 @@
-make: "var-recursive.mk" line 21: still there
-make: "var-recursive.mk" line 23: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive.
+make: "var-recursive.mk" line 11: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive.
in directory <curdir>
-
-make: stopped in unit-tests
-sub-exit status 2
-make: "var-recursive.mk" line 31: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive.
+make: "var-recursive.mk" line 11: <>
+make: "var-recursive.mk" line 19: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive.
in directory <curdir>
-
-make: stopped in unit-tests
-sub-exit status 2
-make: "var-recursive.mk" line 39: ok
-make: "var-recursive.mk" line 48: while evaluating variable "V" with value "$V": Variable V is recursive.
+make: "var-recursive.mk" line 19: <>
+make: "var-recursive.mk" line 26: <ok>
+make: "var-recursive.mk" line 34: while evaluating variable "MODIFIERS" with value "${MODIFIERS:Mpattern}": Variable MODIFIERS is recursive.
in directory <curdir>
-
-make: stopped in unit-tests
-sub-exit status 2
+make: "var-recursive.mk" line 34: <Mpattern}>
+make: "var-recursive.mk" line 43: while evaluating variable "V" with value "$V": Variable V is recursive.
+ in directory <curdir>
+make: "var-recursive.mk" line 43: <>
+make: Fatal errors encountered -- cannot continue
+make: stopped making "loadtime" in unit-tests
+sub-exit status 1
: OK
-In a command near "var-recursive.mk" line 60: make[1]: in target "target": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive.
-
-make: stopped making "target" in unit-tests
+make: in target "runtime": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive.
sub-exit status 2
exit status 0
Index: src/usr.bin/make/unit-tests/var-recursive.mk
diff -u src/usr.bin/make/unit-tests/var-recursive.mk:1.7 src/usr.bin/make/unit-tests/var-recursive.mk:1.8
--- src/usr.bin/make/unit-tests/var-recursive.mk:1.7 Sun Aug 25 20:44:31 2024
+++ src/usr.bin/make/unit-tests/var-recursive.mk Tue Aug 27 04:52:14 2024
@@ -1,66 +1,64 @@
-# $NetBSD: var-recursive.mk,v 1.7 2024/08/25 20:44:31 rillig Exp $
+# $NetBSD: var-recursive.mk,v 1.8 2024/08/27 04:52:14 rillig Exp $
#
-# Tests for expressions that refer to themselves and thus
-# cannot be evaluated.
+# Tests for expressions that refer to themselves and thus cannot be
+# evaluated, as that would lead to an endless loop.
-TESTS= direct indirect conditional short target
+.if make(loadtime)
-# Since make exits immediately when it detects a recursive expression,
-# the actual tests are run in sub-makes.
-TEST?= # none
-.if ${TEST} == ""
-all:
-.for test in ${TESTS}
- @${.MAKE} -f ${MAKEFILE} TEST=${test} || echo "sub-exit status $$?"
-.endfor
-
-.elif ${TEST} == direct
-
-DIRECT= ${DIRECT} # Defining a recursive variable is not yet an error.
-# expect+1: still there
-. info still there # Therefore this line is printed.
-# expect+1: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive.
-. info ${DIRECT} # But expanding the variable is an error.
+DIRECT= ${DIRECT} # Defining a recursive variable is not an error.
+# expect+2: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive.
+# expect+1: <>
+. info <${DIRECT}> # But expanding such a variable is an error.
-.elif ${TEST} == indirect
# The chain of variables that refer to each other may be long.
INDIRECT1= ${INDIRECT2}
INDIRECT2= ${INDIRECT1}
-# expect+1: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive.
-. info ${INDIRECT1}
+# expect+2: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive.
+# expect+1: <>
+. info <${INDIRECT1}>
-.elif ${TEST} == conditional
# The variable refers to itself, but only in the branch of a condition that
-# is never satisfied and is thus not evaluated.
+# is not satisfied and is thus not evaluated.
CONDITIONAL= ${1:?ok:${CONDITIONAL}}
-# expect+1: ok
-. info ${CONDITIONAL}
+# expect+1: <ok>
+. info <${CONDITIONAL}>
+
+
+# An expression with modifiers is skipped halfway. This can lead to wrong
+# follow-up error messages, but recursive variables occur seldom.
+MODIFIERS= ${MODIFIERS:Mpattern}
+# expect+2: while evaluating variable "MODIFIERS" with value "${MODIFIERS:Mpattern}": Variable MODIFIERS is recursive.
+# expect+1: <Mpattern}>
+. info <${MODIFIERS}>
-.elif ${TEST} == short
# Short variable names can be expanded using the short-hand $V notation,
# which takes a different code path in Var_Parse for parsing the variable
# name. Ensure that these are checked as well.
V= $V
-# expect+1: while evaluating variable "V" with value "$V": Variable V is recursive.
-. info $V
+# expect+2: while evaluating variable "V" with value "$V": Variable V is recursive.
+# expect+1: <>
+. info <$V>
-.elif ${TEST} == target
+.elif make(runtime)
# If a recursive variable is accessed in a command of a target, the makefiles
-# are not parsed anymore, so there is no location information from the
-# .includes and .for directives. In such a case, use the location of the last
+# have already been fully parsed, so there is no location information from the
+# .include and .for directives. In such a case, use the location of the last
# command of the target to provide at least a hint to the location.
VAR= ${VAR}
-target:
+runtime:
: OK
- : ${VAR}
+# expect: make: in target "runtime": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive.
+ : <${VAR}>
: OK
.else
-. error Unknown test "${TEST}"
-.endif
all:
+ @${MAKE} -f ${MAKEFILE} loadtime || echo "sub-exit status $$?"
+ @${MAKE} -f ${MAKEFILE} runtime || echo "sub-exit status $$?"
+
+.endif