Module Name:    src
Committed By:   rillig
Date:           Sun Mar 30 01:09:41 UTC 2025

Modified Files:
        src/usr.bin/make: var.c
        src/usr.bin/make/unit-tests: varmod-assign.exp varmod-assign.mk

Log Message:
make: add details to error message for the "::=" modifier

The previous error message about a bad modifier ":" was not helpful, as
the strcspn call stopped immediately due to the modifier starting with
the separater character ":".  The previous error message also didn't
reveal that the "parse error" was due to the expression name being
empty.


To generate a diff of this commit:
cvs rdiff -u -r1.1155 -r1.1156 src/usr.bin/make/var.c
cvs rdiff -u -r1.33 -r1.34 src/usr.bin/make/unit-tests/varmod-assign.exp
cvs rdiff -u -r1.27 -r1.28 src/usr.bin/make/unit-tests/varmod-assign.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.1155 src/usr.bin/make/var.c:1.1156
--- src/usr.bin/make/var.c:1.1155	Sun Mar 30 00:50:33 2025
+++ src/usr.bin/make/var.c	Sun Mar 30 01:09:41 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.1155 2025/03/30 00:50:33 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.1156 2025/03/30 01:09:41 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.1155 2025/03/30 00:50:33 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1156 2025/03/30 01:09:41 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -3555,10 +3555,14 @@ ApplyModifier_Assign(const char **pp, Mo
 
 found_op:
 	if (expr->name[0] == '\0') {
+		const char *value = op[0] == '=' ? op + 1 : op + 2;
 		*pp = mod + 1;
 		/* Take a guess at where the modifier ends. */
-		Parse_Error(PARSE_FATAL, "Bad modifier \":%.*s\"",
-		    (int)strcspn(mod, ":)}"), mod);
+		Parse_Error(PARSE_FATAL,
+		    "Invalid attempt to assign \"%.*s\" to variable \"\" "
+		    "via modifier \"::%.*s\"",
+		    (int)strcspn(value, ":)}"), value,
+		    (int)(value - op), op);
 		return AMR_CLEANUP;
 	}
 

Index: src/usr.bin/make/unit-tests/varmod-assign.exp
diff -u src/usr.bin/make/unit-tests/varmod-assign.exp:1.33 src/usr.bin/make/unit-tests/varmod-assign.exp:1.34
--- src/usr.bin/make/unit-tests/varmod-assign.exp:1.33	Sat Mar 29 19:08:52 2025
+++ src/usr.bin/make/unit-tests/varmod-assign.exp	Sun Mar 30 01:09:41 2025
@@ -37,15 +37,19 @@ Global: .MAKEOVERRIDES =  FIRST LAST LAS
 Result of ${CMD_NEW_VAR::=new-value} is "" (eval, undefined)
 Global: .MAKEFLAGS =  -r -k -d v -d 0 -d v -d
 Global: .MAKEFLAGS =  -r -k -d v -d 0 -d v -d 0
-make: Bad modifier ":"
+make: Invalid attempt to assign "value" to variable "" via modifier "::="
 	while evaluating "${::=value}" with value ""
 	in command "@echo $@: ${::=value}"
 	in target "mod-assign-empty-1"
-make: Bad modifier ":"
+make: Invalid attempt to assign "overwritten" to variable "" via modifier "::="
 	while evaluating "${:Uvalue::=overwritten}" with value "value"
 	in command "@echo $@: ${:Uvalue::=overwritten}"
 	in target "mod-assign-empty-2"
-mod-assign-empty-3: VAR=overwritten
+make: Invalid attempt to assign "appended" to variable "" via modifier "::+="
+	while evaluating "${:Uvalue::+=appended}" with value "value"
+	in command "@echo $@: ${:Uvalue::+=appended}"
+	in target "mod-assign-empty-3"
+mod-assign-empty-4: VAR=overwritten
 make: Unknown modifier "::x"
 	while evaluating variable "ASSIGN" with value ""
 	in command "@echo ${ASSIGN::x}"

Index: src/usr.bin/make/unit-tests/varmod-assign.mk
diff -u src/usr.bin/make/unit-tests/varmod-assign.mk:1.27 src/usr.bin/make/unit-tests/varmod-assign.mk:1.28
--- src/usr.bin/make/unit-tests/varmod-assign.mk:1.27	Sat Mar 29 19:08:52 2025
+++ src/usr.bin/make/unit-tests/varmod-assign.mk	Sun Mar 30 01:09:41 2025
@@ -1,11 +1,11 @@
-# $NetBSD: varmod-assign.mk,v 1.27 2025/03/29 19:08:52 rillig Exp $
+# $NetBSD: varmod-assign.mk,v 1.28 2025/03/30 01:09:41 rillig Exp $
 #
 # Tests for the obscure ::= variable modifiers, which perform variable
 # assignments during evaluation, just like the = operator in C.
 
 .if !make(target)
 
-all:	mod-assign-empty-{1,2,3}
+all:	mod-assign-empty-{1,2,3,4}
 all:	mod-assign-parse-{1,2,3}
 all:	mod-assign-shell-error
 
@@ -74,20 +74,26 @@ SINK4:=	${0:?${THEN4::=then4${IT4::=t4}}
 mod-assign-empty-1:
 	# Assigning to the empty variable would obviously not work since that
 	# variable is write-protected.
-# expect: make: Bad modifier ":"
+# expect: make: Invalid attempt to assign "value" to variable "" via modifier "::="
 	@echo $@: ${::=value}
 
 mod-assign-empty-2:
 	# In this variant, it is not as obvious that the name of the
 	# expression is empty.
-# expect: make: Bad modifier ":"
+# expect: make: Invalid attempt to assign "overwritten" to variable "" via modifier "::="
 	@echo $@: ${:Uvalue::=overwritten}
 
 mod-assign-empty-3:
+	# In this variant, it is not as obvious that the name of the
+	# expression is empty.
+# expect: make: Invalid attempt to assign "appended" to variable "" via modifier "::+="
+	@echo $@: ${:Uvalue::+=appended}
+
+mod-assign-empty-4:
 	# The :L modifier sets the value of the expression to its variable
 	# name.  The name of the expression is "VAR", therefore assigning to
 	# that variable works.
-# expect: mod-assign-empty-3: VAR=overwritten
+# expect: mod-assign-empty-4: VAR=overwritten
 	@echo $@: ${VAR:L::=overwritten} VAR=${VAR}
 
 mod-assign-parse-1:

Reply via email to