Module Name:    src
Committed By:   rillig
Date:           Fri Aug  5 20:59:54 UTC 2022

Modified Files:
        src/usr.bin/make: var.c

Log Message:
make: when parsing ':D' or ':U', only copy text if necessary

When parsing the expression ${:D any ${uninterpreted} text}, parsing of
the ':D' modifier only needs to skip to the next delimiter, there is no
need to keep record of the text that has been skipped.  In this
particular example, there had been an unnecessary memory allocation
since the nested expression was not copied to the result buffer.  Due to
that, the resulting buffer contained " any  text", which was not a
substring of the text passed to the parser, thereby forcing the memory
allocation.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.1026 -r1.1027 src/usr.bin/make/var.c

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.1026 src/usr.bin/make/var.c:1.1027
--- src/usr.bin/make/var.c:1.1026	Fri Aug  5 20:35:55 2022
+++ src/usr.bin/make/var.c	Fri Aug  5 20:59:54 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.1026 2022/08/05 20:35:55 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.1027 2022/08/05 20:59:54 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -139,7 +139,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1026 2022/08/05 20:35:55 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1027 2022/08/05 20:59:54 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -2440,7 +2440,7 @@ done:
 }
 
 static void
-ParseModifier_Defined(const char **pp, ModChain *ch, VarEvalMode emode,
+ParseModifier_Defined(const char **pp, ModChain *ch, bool shouldEval,
 		      LazyBuf *buf)
 {
 	const char *p;
@@ -2460,7 +2460,8 @@ ParseModifier_Defined(const char **pp, M
 		if (*p == '\\') {
 			char c = p[1];
 			if (IsDelimiter(c, ch) || c == '$' || c == '\\') {
-				LazyBuf_Add(buf, c);
+				if (shouldEval)
+					LazyBuf_Add(buf, c);
 				p += 2;
 				continue;
 			}
@@ -2468,18 +2469,21 @@ ParseModifier_Defined(const char **pp, M
 
 		/* Nested variable expression */
 		if (*p == '$') {
-			FStr nested_val;
+			FStr val;
 
-			(void)Var_Parse(&p, ch->expr->scope, emode, &nested_val);
+			(void)Var_Parse(&p, ch->expr->scope,
+			    shouldEval ? ch->expr->emode : VARE_PARSE_ONLY,
+			    &val);
 			/* TODO: handle errors */
-			if (ModChain_ShouldEval(ch))
-				LazyBuf_AddStr(buf, nested_val.str);
-			FStr_Done(&nested_val);
+			if (shouldEval)
+				LazyBuf_AddStr(buf, val.str);
+			FStr_Done(&val);
 			continue;
 		}
 
 		/* Ordinary text */
-		LazyBuf_Add(buf, *p);
+		if (shouldEval)
+			LazyBuf_Add(buf, *p);
 		p++;
 	}
 	*pp = p;
@@ -2491,20 +2495,15 @@ ApplyModifier_Defined(const char **pp, M
 {
 	Expr *expr = ch->expr;
 	LazyBuf buf;
+	bool shouldEval =
+	    Expr_ShouldEval(expr) &&
+	    (**pp == 'D') == (expr->defined == DEF_REGULAR);
 
-	VarEvalMode emode = VARE_PARSE_ONLY;
-	if (Expr_ShouldEval(expr))
-		if ((**pp == 'D') == (expr->defined == DEF_REGULAR))
-			emode = expr->emode;
-
-	ParseModifier_Defined(pp, ch, emode, &buf);
+	ParseModifier_Defined(pp, ch, shouldEval, &buf);
 
 	Expr_Define(expr);
-
-	if (VarEvalMode_ShouldEval(emode))
+	if (shouldEval)
 		Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf)));
-	else
-		LazyBuf_Done(&buf);
 
 	return AMR_OK;
 }

Reply via email to