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"

Reply via email to