Module Name: src
Committed By: rillig
Date: Sat Apr 10 22:09:54 UTC 2021
Modified Files:
src/usr.bin/make: var.c
src/usr.bin/make/unit-tests: vardebug.exp varmod-indirect.exp
varmod-match-escape.exp varname-empty.exp varname.exp
Log Message:
make: reduce debug logging and memory allocation for ${:U...}
Expressions of the form ${:U...} are often generated by .for loops.
Since these expressions are not generated knowingly by the make user, do
not fill the debug log with them since that would interrupt the normal
reading flow of the -dv log for nested expressions.
To generate a diff of this commit:
cvs rdiff -u -r1.912 -r1.913 src/usr.bin/make/var.c
cvs rdiff -u -r1.24 -r1.25 src/usr.bin/make/unit-tests/vardebug.exp
cvs rdiff -u -r1.17 -r1.18 src/usr.bin/make/unit-tests/varmod-indirect.exp
cvs rdiff -u -r1.14 -r1.15 \
src/usr.bin/make/unit-tests/varmod-match-escape.exp
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/make/unit-tests/varname-empty.exp
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/make/unit-tests/varname.exp
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/var.c
diff -u src/usr.bin/make/var.c:1.912 src/usr.bin/make/var.c:1.913
--- src/usr.bin/make/var.c:1.912 Tue Apr 6 01:38:39 2021
+++ src/usr.bin/make/var.c Sat Apr 10 22:09:53 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.912 2021/04/06 01:38:39 rillig Exp $ */
+/* $NetBSD: var.c,v 1.913 2021/04/10 22:09:53 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
#include "metachar.h"
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.912 2021/04/06 01:38:39 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.913 2021/04/10 22:09:53 rillig Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@@ -437,6 +437,11 @@ VarFind(const char *name, GNode *scope,
if (var == NULL) {
char *env;
+ /*
+ * TODO: try setting an environment variable with the empty
+ * name, which should be technically possible, just to see
+ * how make reacts. All .for loops should be broken then.
+ */
if ((env = getenv(name)) != NULL) {
char *varname = bmake_strdup(name);
return VarNew(FStr_InitOwn(varname), env, true, false);
@@ -4381,6 +4386,34 @@ Expr_Literal(const char *name, FStr valu
#endif
/*
+ * Expressions of the form ${:U...} with a trivial value are often generated
+ * by .for loops and are boring, therefore parse and evaluate them in a fast
+ * lane without debug logging.
+ */
+static bool
+Var_Parse_FastLane(const char **pp, VarEvalMode emode, FStr *out_value)
+{
+ const char *p;
+
+ p = *pp;
+ if (!(p[0] == '$' && p[1] == '{' && p[2] == ':' && p[3] == 'U'))
+ return false;
+
+ p += 4;
+ while (*p != '$' && *p != '{' && *p != ':' && *p != '\\' && *p != '}')
+ p++;
+ if (*p != '}')
+ return false;
+
+ if (emode == VARE_PARSE_ONLY)
+ *out_value = FStr_InitRefer("");
+ else
+ *out_value = FStr_InitOwn(bmake_strsedup(*pp + 4, p));
+ *pp = p + 1;
+ return true;
+}
+
+/*
* Given the start of a variable expression (such as $v, $(VAR),
* ${VAR:Mpattern}), extract the variable name and value, and the modifiers,
* if any. While doing that, apply the modifiers to the value of the
@@ -4439,6 +4472,9 @@ Var_Parse(const char **pp, GNode *scope,
Expr expr = Expr_Literal(NULL, FStr_InitRefer(NULL), emode,
scope, DEF_REGULAR);
+ if (Var_Parse_FastLane(pp, emode, out_val))
+ return VPR_OK;
+
DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]);
*out_val = FStr_InitRefer(NULL);
Index: src/usr.bin/make/unit-tests/vardebug.exp
diff -u src/usr.bin/make/unit-tests/vardebug.exp:1.24 src/usr.bin/make/unit-tests/vardebug.exp:1.25
--- src/usr.bin/make/unit-tests/vardebug.exp:1.24 Tue Apr 6 01:38:39 2021
+++ src/usr.bin/make/unit-tests/vardebug.exp Sat Apr 10 22:09:54 2021
@@ -5,13 +5,7 @@ Global: VAR = added
Global: VAR = overwritten
Global:delete VAR
Global:delete VAR (not found)
-Var_Parse: ${:U} (eval)
-Evaluating modifier ${:U} on value "" (eval, undefined)
-Result of ${:U} is "" (eval, defined)
Var_Set("${:U}", "empty name", ...) name expands to empty string - ignored
-Var_Parse: ${:U} (eval)
-Evaluating modifier ${:U} on value "" (eval, undefined)
-Result of ${:U} is "" (eval, defined)
Var_Append("${:U}", "empty name", ...) name expands to empty string - ignored
Global: FROM_CMDLINE = overwritten ignored!
Global: VAR = 1
@@ -46,9 +40,6 @@ Result of ${VAR:Q} is "1\ 2\ 3"
Var_Parse: ${:Uvalue:${:UM*e}:Mvalu[e]} (eval-defined)
Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
Result of ${:Uvalue} is "value" (eval-defined, defined)
-Var_Parse: ${:UM*e}:Mvalu[e]} (eval-defined)
-Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
-Result of ${:UM*e} is "M*e" (eval-defined, defined)
Indirect modifier "M*e" from "${:UM*e}"
Evaluating modifier ${:M...} on value "value" (eval-defined, defined)
Pattern for ':M' is "*e"
@@ -58,9 +49,6 @@ Evaluating modifier ${:M...} on value "v
Pattern for ':M' is "valu[e]"
ModifyWords: split "value" into 1 words
Result of ${:Mvalu[e]} is "value" (eval-defined, defined)
-Var_Parse: ${:UVAR} (eval)
-Evaluating modifier ${:U...} on value "" (eval, undefined)
-Result of ${:UVAR} is "VAR" (eval, defined)
Global:delete VAR
Var_Parse: ${:Uvariable:unknown} (eval-defined)
Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
Index: src/usr.bin/make/unit-tests/varmod-indirect.exp
diff -u src/usr.bin/make/unit-tests/varmod-indirect.exp:1.17 src/usr.bin/make/unit-tests/varmod-indirect.exp:1.18
--- src/usr.bin/make/unit-tests/varmod-indirect.exp:1.17 Mon Apr 5 13:35:41 2021
+++ src/usr.bin/make/unit-tests/varmod-indirect.exp Sat Apr 10 22:09:54 2021
@@ -16,41 +16,23 @@ Var_Parse: ${UNDEF} after (eval-keep-dol
Global: _ = before ${UNDEF} after
ParseReadLine (169): '_:= before ${UNDEF:${:US,a,a,}} after'
Var_Parse: ${UNDEF:${:US,a,a,}} after (eval-keep-dollar-and-undefined)
-Var_Parse: ${:US,a,a,}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U...} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:US,a,a,} is "S,a,a," (eval-keep-dollar-and-undefined, defined)
Indirect modifier "S,a,a," from "${:US,a,a,}"
Evaluating modifier ${UNDEF:S...} on value "" (eval-keep-dollar-and-undefined, undefined)
Modifier part: "a"
Modifier part: "a"
ModifyWords: split "" into 1 words
Result of ${UNDEF:S,a,a,} is "" (eval-keep-dollar-and-undefined, undefined)
-Var_Parse: ${:US,a,a,}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U...} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:US,a,a,} is "S,a,a," (eval-keep-dollar-and-undefined, defined)
Global: _ = before ${UNDEF:S,a,a,} after
ParseReadLine (179): '_:= before ${UNDEF:${:U}} after'
Var_Parse: ${UNDEF:${:U}} after (eval-keep-dollar-and-undefined)
-Var_Parse: ${:U}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:U} is "" (eval-keep-dollar-and-undefined, defined)
Indirect modifier "" from "${:U}"
-Var_Parse: ${:U}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:U} is "" (eval-keep-dollar-and-undefined, defined)
Global: _ = before ${UNDEF:} after
ParseReadLine (184): '_:= before ${UNDEF:${:UZ}} after'
Var_Parse: ${UNDEF:${:UZ}} after (eval-keep-dollar-and-undefined)
-Var_Parse: ${:UZ}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U...} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:UZ} is "Z" (eval-keep-dollar-and-undefined, defined)
Indirect modifier "Z" from "${:UZ}"
Evaluating modifier ${UNDEF:Z} on value "" (eval-keep-dollar-and-undefined, undefined)
make: "varmod-indirect.mk" line 184: Unknown modifier "Z"
Result of ${UNDEF:Z} is error (eval-keep-dollar-and-undefined, undefined)
-Var_Parse: ${:UZ}} after (eval-keep-dollar-and-undefined)
-Evaluating modifier ${:U...} on value "" (eval-keep-dollar-and-undefined, undefined)
-Result of ${:UZ} is "Z" (eval-keep-dollar-and-undefined, defined)
Global: _ = before ${UNDEF:Z} after
ParseReadLine (186): '.MAKEFLAGS: -d0'
ParseDependency(.MAKEFLAGS: -d0)
Index: src/usr.bin/make/unit-tests/varmod-match-escape.exp
diff -u src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.14 src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.15
--- src/usr.bin/make/unit-tests/varmod-match-escape.exp:1.14 Tue Apr 6 01:38:39 2021
+++ src/usr.bin/make/unit-tests/varmod-match-escape.exp Sat Apr 10 22:09:54 2021
@@ -2,17 +2,11 @@ Global: SPECIALS = \: : \\ * \*
CondParser_Eval: ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}}
Var_Parse: ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}} (eval-defined)
Evaluating modifier ${SPECIALS:M...} on value "\: : \\ * \*"
-Var_Parse: ${:U}\: (eval-defined)
-Evaluating modifier ${:U} on value "" (eval-defined, undefined)
-Result of ${:U} is "" (eval-defined, defined)
Pattern for ':M' is "\:"
ModifyWords: split "\: : \\ * \*" into 5 words
Result of ${SPECIALS:M${:U}\:} is ":"
Var_Parse: ${SPECIALS:M\:${:U}} (eval-defined)
Evaluating modifier ${SPECIALS:M...} on value "\: : \\ * \*"
-Var_Parse: ${:U} (eval-defined)
-Evaluating modifier ${:U} on value "" (eval-defined, undefined)
-Result of ${:U} is "" (eval-defined, defined)
Pattern for ':M' is ":"
ModifyWords: split "\: : \\ * \*" into 5 words
Result of ${SPECIALS:M\:${:U}} is ":"
Index: src/usr.bin/make/unit-tests/varname-empty.exp
diff -u src/usr.bin/make/unit-tests/varname-empty.exp:1.13 src/usr.bin/make/unit-tests/varname-empty.exp:1.14
--- src/usr.bin/make/unit-tests/varname-empty.exp:1.13 Mon Apr 5 13:35:41 2021
+++ src/usr.bin/make/unit-tests/varname-empty.exp Sat Apr 10 22:09:54 2021
@@ -1,6 +1,3 @@
-Var_Parse: ${:U} (eval)
-Evaluating modifier ${:U} on value "" (eval, undefined)
-Result of ${:U} is "" (eval, defined)
Var_Set("${:U}", "cmdline-u", ...) name expands to empty string - ignored
Var_Set("", "cmdline-plain", ...) name expands to empty string - ignored
Global: .CURDIR = <curdir>
@@ -23,23 +20,8 @@ SetVar: variable name is empty - ignored
Var_Set("", "", ...) name expands to empty string - ignored
Var_Set("", "subst", ...) name expands to empty string - ignored
Var_Set("", "shell-output", ...) name expands to empty string - ignored
-Var_Parse: ${:Ufallback} != "fallback" (eval-defined)
-Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
-Result of ${:Ufallback} is "fallback" (eval-defined, defined)
-Var_Parse: ${:U} (eval)
-Evaluating modifier ${:U} on value "" (eval, undefined)
-Result of ${:U} is "" (eval, defined)
Var_Set("${:U}", "assigned indirectly", ...) name expands to empty string - ignored
-Var_Parse: ${:Ufallback} != "fallback" (eval-defined)
-Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
-Result of ${:Ufallback} is "fallback" (eval-defined, defined)
-Var_Parse: ${:U} (eval)
-Evaluating modifier ${:U} on value "" (eval, undefined)
-Result of ${:U} is "" (eval, defined)
Var_Append("${:U}", "appended indirectly", ...) name expands to empty string - ignored
-Var_Parse: ${:Ufallback} != "fallback" (eval-defined)
-Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
-Result of ${:Ufallback} is "fallback" (eval-defined, defined)
Global: .MAKEFLAGS = -r -d v -d
Global: .MAKEFLAGS = -r -d v -d 0
out: fallback
Index: src/usr.bin/make/unit-tests/varname.exp
diff -u src/usr.bin/make/unit-tests/varname.exp:1.16 src/usr.bin/make/unit-tests/varname.exp:1.17
--- src/usr.bin/make/unit-tests/varname.exp:1.16 Mon Apr 5 13:35:41 2021
+++ src/usr.bin/make/unit-tests/varname.exp Sat Apr 10 22:09:54 2021
@@ -4,9 +4,6 @@ Global: VARNAME = VAR(((
Var_Parse: ${VARNAME} (eval)
Global: VAR((( = 3 open parentheses
Var_Parse: ${VAR(((}}}}" != "3 open parentheses}}}" (eval)
-Var_Parse: ${:UVAR(((}= try1 (eval-defined)
-Evaluating modifier ${:U...} on value "" (eval-defined, undefined)
-Result of ${:UVAR(((} is "VAR(((" (eval-defined, defined)
Global: .ALLTARGETS = VAR(((=)
make: "varname.mk" line 30: No closing parenthesis in archive specification
make: "varname.mk" line 30: Error in archive specification: "VAR"