Module Name:    src
Committed By:   rillig
Date:           Sat Mar 29 16:44:14 UTC 2025

Modified Files:
        src/usr.bin/make: var.c
        src/usr.bin/make/unit-tests: moderrs.exp moderrs.mk vardebug.exp
            vardebug.mk varmod-edge.exp varmod-edge.mk varmod-indirect.exp
            varmod-indirect.mk

Log Message:
make: stop parsing after seeing an unknown modifier in an expression

Previously, after an expression such as ${VAR:Z::::}, make detected the
unknown modifier ":Z" and then continued parsing, which produced
unnecessary follow-up error messages. It was also necessary to
distinguish the error cases when logging the result of an applied
modifier in -dv mode.

Unify the error handling cases of a syntax error, an evaluation error
and an unknown modifier, to avoid the unnecessary follow-up error
messages.

The test in varmod-edge.mk now produces ":}" from the erroneous
expression, which may be misleading and thus will be looked at in a
follow-up commit.

The general idea of this patch was reviewed by sjg, I made a few
nonsubstantial changes after the review.


To generate a diff of this commit:
cvs rdiff -u -r1.1149 -r1.1150 src/usr.bin/make/var.c
cvs rdiff -u -r1.49 -r1.50 src/usr.bin/make/unit-tests/moderrs.exp
cvs rdiff -u -r1.43 -r1.44 src/usr.bin/make/unit-tests/moderrs.mk
cvs rdiff -u -r1.40 -r1.41 src/usr.bin/make/unit-tests/vardebug.exp
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/make/unit-tests/vardebug.mk
cvs rdiff -u -r1.30 -r1.31 src/usr.bin/make/unit-tests/varmod-edge.exp
cvs rdiff -u -r1.34 -r1.35 src/usr.bin/make/unit-tests/varmod-edge.mk
cvs rdiff -u -r1.32 -r1.33 src/usr.bin/make/unit-tests/varmod-indirect.exp
cvs rdiff -u -r1.21 -r1.22 src/usr.bin/make/unit-tests/varmod-indirect.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/var.c
diff -u src/usr.bin/make/var.c:1.1149 src/usr.bin/make/var.c:1.1150
--- src/usr.bin/make/var.c:1.1149	Sat Mar 29 12:02:40 2025
+++ src/usr.bin/make/var.c	Sat Mar 29 16:44:14 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.1149 2025/03/29 12:02:40 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.1150 2025/03/29 16:44:14 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -128,7 +128,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1149 2025/03/29 12:02:40 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1150 2025/03/29 16:44:14 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -3843,18 +3843,15 @@ LogAfterApply(const ModChain *ch, const 
 {
 	const Expr *expr = ch->expr;
 	const char *value = Expr_Str(expr);
-	const char *quot = value == var_Error ? "" : "\"";
 
 	if (ShouldLogInSimpleFormat(expr)) {
-		debug_printf("Result of ${%s:%.*s} is %s%s%s\n",
-		    expr->name, (int)(p - mod), mod,
-		    quot, value == var_Error ? "error" : value, quot);
+		debug_printf("Result of ${%s:%.*s} is \"%s\"\n",
+		    expr->name, (int)(p - mod), mod, value);
 		return;
 	}
 
-	debug_printf("Result of ${%s:%.*s} is %s%s%s (%s, %s)\n",
-	    expr->name, (int)(p - mod), mod,
-	    quot, value == var_Error ? "error" : value, quot,
+	debug_printf("Result of ${%s:%.*s} is \"%s\" (%s, %s)\n",
+	    expr->name, (int)(p - mod), mod, value,
 	    VarEvalMode_Name[expr->emode],
 	    ExprDefined_Name[expr->defined]);
 }
@@ -4019,8 +4016,9 @@ ApplySingleModifier(const char **pp, Mod
 		Parse_Error(PARSE_FATAL, "Unknown modifier \"%.*s\"",
 		    (int)(p - mod), mod);
 		Expr_SetValueRefer(ch->expr, var_Error);
+		res = AMR_CLEANUP;
 	}
-	if (res == AMR_CLEANUP || res == AMR_BAD) {
+	if (res != AMR_OK) {
 		*pp = p;
 		return res;
 	}

Index: src/usr.bin/make/unit-tests/moderrs.exp
diff -u src/usr.bin/make/unit-tests/moderrs.exp:1.49 src/usr.bin/make/unit-tests/moderrs.exp:1.50
--- src/usr.bin/make/unit-tests/moderrs.exp:1.49	Sat Mar 29 12:02:41 2025
+++ src/usr.bin/make/unit-tests/moderrs.exp	Sat Mar 29 16:44:14 2025
@@ -161,10 +161,6 @@ make: Unknown modifier "3"
 	while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
 	in command "@echo ${FIB:3"
 	in target "mod-sysv-parse-1"
-make: Unclosed expression, expecting '}' for modifier "3"
-	while evaluating variable "FIB" with value ""
-	in command "@echo ${FIB:3"
-	in target "mod-sysv-parse-1"
 make: Unfinished modifier after "", expecting "}"
 	while evaluating variable "FIB" with value "1 1 2 3 5 8 13 21 34"
 	in command "@echo ${FIB:3="

Index: src/usr.bin/make/unit-tests/moderrs.mk
diff -u src/usr.bin/make/unit-tests/moderrs.mk:1.43 src/usr.bin/make/unit-tests/moderrs.mk:1.44
--- src/usr.bin/make/unit-tests/moderrs.mk:1.43	Sat Mar 29 12:02:41 2025
+++ src/usr.bin/make/unit-tests/moderrs.mk	Sat Mar 29 16:44:14 2025
@@ -1,4 +1,4 @@
-# $NetBSD: moderrs.mk,v 1.43 2025/03/29 12:02:41 rillig Exp $
+# $NetBSD: moderrs.mk,v 1.44 2025/03/29 16:44:14 rillig Exp $
 #
 # various modifier error tests
 
@@ -197,7 +197,6 @@ mod-remember-parse:
 
 mod-sysv-parse-1:
 # expect: make: Unknown modifier "3"
-# expect: make: Unclosed expression, expecting '}' for modifier "3"
 	@echo ${FIB:3
 mod-sysv-parse-2:
 # expect: make: Unfinished modifier after "", expecting "}"

Index: src/usr.bin/make/unit-tests/vardebug.exp
diff -u src/usr.bin/make/unit-tests/vardebug.exp:1.40 src/usr.bin/make/unit-tests/vardebug.exp:1.41
--- src/usr.bin/make/unit-tests/vardebug.exp:1.40	Sat Jan 11 21:21:33 2025
+++ src/usr.bin/make/unit-tests/vardebug.exp	Sat Mar 29 16:44:14 2025
@@ -54,11 +54,10 @@ Var_Parse: ${:Uvariable:unknown} (eval-d
 Evaluating modifier ${:U...} on value "" (eval, undefined)
 Result of ${:Uvariable} is "variable" (eval, defined)
 Evaluating modifier ${:u...} on value "variable" (eval, defined)
-make: "vardebug.mk" line 62: Unknown modifier "unknown"
+make: "vardebug.mk" line 59: Unknown modifier "unknown"
 	while evaluating "${:Uvariable:unknown}" with value "variable"
-Result of ${:unknown} is error (eval, defined)
 Var_Parse: ${UNDEFINED} (eval-defined-loud)
-make: "vardebug.mk" line 66: Variable "UNDEFINED" is undefined
+make: "vardebug.mk" line 63: Variable "UNDEFINED" is undefined
 Global: ignoring delete '.SHELL' as it is not found
 Command: .SHELL = </path/to/shell>
 Command: ignoring '.SHELL = overwritten' as it is read-only

Index: src/usr.bin/make/unit-tests/vardebug.mk
diff -u src/usr.bin/make/unit-tests/vardebug.mk:1.16 src/usr.bin/make/unit-tests/vardebug.mk:1.17
--- src/usr.bin/make/unit-tests/vardebug.mk:1.16	Sat Jan 11 21:21:33 2025
+++ src/usr.bin/make/unit-tests/vardebug.mk	Sat Mar 29 16:44:14 2025
@@ -1,4 +1,4 @@
-# $NetBSD: vardebug.mk,v 1.16 2025/01/11 21:21:33 rillig Exp $
+# $NetBSD: vardebug.mk,v 1.17 2025/03/29 16:44:14 rillig Exp $
 #
 # Demonstrates the debugging output for var.c.
 
@@ -55,9 +55,6 @@ VAR+=		3
 # expect: Global: delete VAR
 .undef ${:UVAR}			# Var_Delete
 
-# When ApplyModifiers results in an error, this appears in the debug log
-# as "is error", without surrounding quotes.
-# expect: Result of ${:unknown} is error (eval, defined)
 # expect+1: Unknown modifier "unknown"
 .if ${:Uvariable:unknown}
 .endif

Index: src/usr.bin/make/unit-tests/varmod-edge.exp
diff -u src/usr.bin/make/unit-tests/varmod-edge.exp:1.30 src/usr.bin/make/unit-tests/varmod-edge.exp:1.31
--- src/usr.bin/make/unit-tests/varmod-edge.exp:1.30	Sat Mar 29 11:51:54 2025
+++ src/usr.bin/make/unit-tests/varmod-edge.exp	Sat Mar 29 16:44:14 2025
@@ -8,15 +8,12 @@ make: "varmod-edge.mk" line 88: Unfinish
 make: "varmod-edge.mk" line 178: Unfinished modifier after "a\=b}", expecting "="
 	while evaluating variable "INP" with value "file.c file..."
 	while evaluating variable "MOD" with value "${INP:a\=b}"
-make: "varmod-edge.mk" line 194: Unknown modifier ":"
+make: "varmod-edge.mk" line 193: Unknown modifier ":"
 	while evaluating variable "INP" with value "value"
 	while evaluating variable "MOD" with value "${INP::::}"
-make: "varmod-edge.mk" line 194: Unknown modifier ":"
-	while evaluating variable "INP" with value ""
-	while evaluating variable "MOD" with value "${INP::::}"
-make: "varmod-edge.mk" line 200: Unknown modifier "Z"
+make: "varmod-edge.mk" line 199: Unknown modifier "Z"
 	while evaluating "${:Z}" with value ""
-make: "varmod-edge.mk" line 213: Unfinished modifier after "}", expecting ","
+make: "varmod-edge.mk" line 212: Unfinished modifier after "}", expecting ","
 	while evaluating "${:S,}" with value ""
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests

Index: src/usr.bin/make/unit-tests/varmod-edge.mk
diff -u src/usr.bin/make/unit-tests/varmod-edge.mk:1.34 src/usr.bin/make/unit-tests/varmod-edge.mk:1.35
--- src/usr.bin/make/unit-tests/varmod-edge.mk:1.34	Sat Mar 29 11:51:54 2025
+++ src/usr.bin/make/unit-tests/varmod-edge.mk	Sat Mar 29 16:44:14 2025
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-edge.mk,v 1.34 2025/03/29 11:51:54 rillig Exp $
+# $NetBSD: varmod-edge.mk,v 1.35 2025/03/29 16:44:14 rillig Exp $
 #
 # Tests for edge cases in variable modifiers.
 #
@@ -188,8 +188,7 @@ EXP=	value
 
 INP=	value
 MOD=	${INP::::}
-EXP=	# empty
-# expect+2: Unknown modifier ":"
+EXP=	:}
 # expect+1: Unknown modifier ":"
 .if ${MOD} != ${EXP}
 .  warning expected "${EXP}", got "${MOD}"

Index: src/usr.bin/make/unit-tests/varmod-indirect.exp
diff -u src/usr.bin/make/unit-tests/varmod-indirect.exp:1.32 src/usr.bin/make/unit-tests/varmod-indirect.exp:1.33
--- src/usr.bin/make/unit-tests/varmod-indirect.exp:1.32	Sat Mar 29 11:24:34 2025
+++ src/usr.bin/make/unit-tests/varmod-indirect.exp	Sat Mar 29 16:44:14 2025
@@ -2,23 +2,22 @@ make: "varmod-indirect.mk" line 19: Unkn
 	while evaluating variable "value" with value "value"
 make: "varmod-indirect.mk" line 52: Unknown modifier "${"
 	while evaluating variable "value" with value "value"
-make: "varmod-indirect.mk" line 54: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
-make: "varmod-indirect.mk" line 143: before
-make: "varmod-indirect.mk" line 143: after
-make: "varmod-indirect.mk" line 151: before
-make: "varmod-indirect.mk" line 151: after
-make: "varmod-indirect.mk" line 159: before
-make: "varmod-indirect.mk" line 159: after
-make: "varmod-indirect.mk" line 164: Unknown modifier "Z"
+make: "varmod-indirect.mk" line 140: before
+make: "varmod-indirect.mk" line 140: after
+make: "varmod-indirect.mk" line 148: before
+make: "varmod-indirect.mk" line 148: after
+make: "varmod-indirect.mk" line 156: before
+make: "varmod-indirect.mk" line 156: after
+make: "varmod-indirect.mk" line 161: Unknown modifier "Z"
 	while evaluating indirect modifiers "Z"
 	while evaluating variable "UNDEF" with value ""
-make: "varmod-indirect.mk" line 167: before
-make: "varmod-indirect.mk" line 167: after
-Parsing varmod-indirect.mk:176: _:=	before ${UNDEF} after
+make: "varmod-indirect.mk" line 164: before
+make: "varmod-indirect.mk" line 164: after
+Parsing varmod-indirect.mk:173: _:=	before ${UNDEF} after
 Global: _ = # (empty)
 Var_Parse: ${UNDEF} after (eval-keep-dollar-and-undefined)
 Global: _ = before ${UNDEF} after
-Parsing varmod-indirect.mk:179: _:=	before ${UNDEF:${:US,a,a,}} after
+Parsing varmod-indirect.mk:176: _:=	before ${UNDEF:${:US,a,a,}} after
 Var_Parse: ${UNDEF:${:US,a,a,}} after (eval-keep-dollar-and-undefined)
 Indirect modifier "S,a,a," from "${:US,a,a,}"
 Evaluating modifier ${UNDEF:S...} on value "" (eval-keep-dollar-and-undefined, undefined)
@@ -27,20 +26,19 @@ Modifier part: "a"
 ModifyWords: split "" into 1 word
 Result of ${UNDEF:S,a,a,} is "" (eval-keep-dollar-and-undefined, undefined)
 Global: _ = before ${UNDEF:S,a,a,} after
-Parsing varmod-indirect.mk:189: _:=	before ${UNDEF:${:U}} after
+Parsing varmod-indirect.mk:186: _:=	before ${UNDEF:${:U}} after
 Var_Parse: ${UNDEF:${:U}} after (eval-keep-dollar-and-undefined)
 Indirect modifier "" from "${:U}"
 Global: _ = before ${UNDEF:} after
-Parsing varmod-indirect.mk:195: _:=	before ${UNDEF:${:UZ}} after
+Parsing varmod-indirect.mk:192: _:=	before ${UNDEF:${:UZ}} after
 Var_Parse: ${UNDEF:${:UZ}} after (eval-keep-dollar-and-undefined)
 Indirect modifier "Z" from "${:UZ}"
 Evaluating modifier ${UNDEF:Z} on value "" (eval-keep-dollar-and-undefined, undefined)
-make: "varmod-indirect.mk" line 195: Unknown modifier "Z"
+make: "varmod-indirect.mk" line 192: Unknown modifier "Z"
 	while evaluating indirect modifiers "Z"
 	while evaluating variable "UNDEF" with value ""
-Result of ${UNDEF:Z} is error (eval-keep-dollar-and-undefined, undefined)
 Global: _ = before ${UNDEF:Z} after
-Parsing varmod-indirect.mk:197: .MAKEFLAGS: -d0
+Parsing varmod-indirect.mk:194: .MAKEFLAGS: -d0
 ParseDependency(.MAKEFLAGS: -d0)
 Global: .MAKEFLAGS =  -r -k -d 0 -d pv -d
 Global: .MAKEFLAGS =  -r -k -d 0 -d pv -d 0

Index: src/usr.bin/make/unit-tests/varmod-indirect.mk
diff -u src/usr.bin/make/unit-tests/varmod-indirect.mk:1.21 src/usr.bin/make/unit-tests/varmod-indirect.mk:1.22
--- src/usr.bin/make/unit-tests/varmod-indirect.mk:1.21	Thu Aug 29 20:20:36 2024
+++ src/usr.bin/make/unit-tests/varmod-indirect.mk	Sat Mar 29 16:44:14 2025
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-indirect.mk,v 1.21 2024/08/29 20:20:36 rillig Exp $
+# $NetBSD: varmod-indirect.mk,v 1.22 2025/03/29 16:44:14 rillig Exp $
 #
 # Tests for indirect variable modifiers, such as in ${VAR:${M_modifiers}}.
 # These can be used for very basic purposes like converting a string to either
@@ -44,16 +44,13 @@
 
 # If an expression for an indirect modifier evaluates to anything else than an
 # empty string and is neither followed by a ':' nor '}', this produces a parse
-# error.  Because of this parse error, this feature cannot be used reasonably
+# error.  Due to this parse error, this construct cannot be used reasonably
 # in practice.
 #
 # expect+2: Unknown modifier "${"
 #.MAKEFLAGS: -dvc
-.if ${value:L:${:UM*}S,value,replaced,} == "M*S,value,replaced,}"
-# expect+1: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression.
-.  warning	FIXME: this expression should have resulted in a parse $\
- 		error rather than returning the unparsed portion of the $\
- 		expression.
+.if ${value:L:${:UM*}S,value,replaced,} == "anything"
+.  error
 .else
 .  error
 .endif

Reply via email to