Module Name:    src
Committed By:   rillig
Date:           Sat Aug  6 21:26:06 UTC 2022

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

Log Message:
tests/make: demonstrate bug in parsing of modifier parts

In the modifier ':S,from,to,', parsing the two parts 'from' and 'to' of
the modifier differs depending on whether the expression is actually
evaluated or merely parsed.  This not only applies to the ':S' modifier,
but also to ':C', ':@var@body@', ':!cmd!', ':[...]', ':?:', '::=' and
':from=to'.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/usr.bin/make/unit-tests/parse-var.exp \
    src/usr.bin/make/unit-tests/parse-var.mk
cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/varmod-undefined.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/unit-tests/parse-var.exp
diff -u src/usr.bin/make/unit-tests/parse-var.exp:1.1 src/usr.bin/make/unit-tests/parse-var.exp:1.2
--- src/usr.bin/make/unit-tests/parse-var.exp:1.1	Sun Oct  4 06:53:15 2020
+++ src/usr.bin/make/unit-tests/parse-var.exp	Sat Aug  6 21:26:05 2022
@@ -1 +1,5 @@
-exit status 0
+make: Unfinished modifier for "BRACE_GROUP" (',' missing)
+make: "parse-var.mk" line 47: Malformed conditional (0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,})
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
Index: src/usr.bin/make/unit-tests/parse-var.mk
diff -u src/usr.bin/make/unit-tests/parse-var.mk:1.1 src/usr.bin/make/unit-tests/parse-var.mk:1.2
--- src/usr.bin/make/unit-tests/parse-var.mk:1.1	Sun Oct  4 06:53:15 2020
+++ src/usr.bin/make/unit-tests/parse-var.mk	Sat Aug  6 21:26:05 2022
@@ -1,13 +1,52 @@
-# $NetBSD: parse-var.mk,v 1.1 2020/10/04 06:53:15 rillig Exp $
+# $NetBSD: parse-var.mk,v 1.2 2022/08/06 21:26:05 rillig Exp $
+#
+# Tests for parsing variable expressions.
 
 .MAKEFLAGS: -dL
 
-# In variable assignments, there may be spaces on the left-hand side of the
-# assignment, but only if they occur inside variable expressions.
+# In variable assignments, there may be spaces in the middle of the left-hand
+# side of the assignment, but only if they occur inside variable expressions.
+# Leading spaces (but not tabs) are possible but unusual.
+# Trailing spaces are common in some coding styles, others omit them.
 VAR.${:U param }=	value
 .if ${VAR.${:U param }} != "value"
 .  error
 .endif
 
-all:
-	@:;
+
+# As of var.c 1.1027 from 2022-08-05, the exact way of parsing an expression
+# depends on whether the expression is actually evaluated or merely parsed.
+#
+# If it is evaluated, nested expressions are parsed correctly, parsing each
+# modifier according to its exact definition.  If the expression is merely
+# parsed but not evaluated (because its value would not influence the outcome
+# of the condition), and the expression contains a modifier, and that modifier
+# contains a nested expression, the nested expression is not parsed
+# correctly.  Instead, make only counts the opening and closing delimiters,
+# which fails for nested modifiers with unbalanced braces.
+#
+# See ParseModifierPartDollar.
+
+#.MAKEFLAGS: -dcpv
+# Keep these braces outside the conditions below, to keep them simple to
+# understand.  If the BRACE_PAIR had been replaced with ':U{}', the '}' would
+# have to be escaped, but not the '{'.  This asymmetry would have made the
+# example even more complicated to understand.
+BRACE_PAIR=	{}
+# In this test word, the '{{}' in the middle will be replaced.
+BRACE_GROUP=	{{{{}}}}
+
+# The inner ':S' modifier turns the word '{}' into '{{}'.
+# The outer ':S' modifier then replaces '{{}' with '<lbraces>'.
+# In the first case, the outer expression is relevant and is parsed correctly.
+.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
+.endif
+# In the second case, the outer expression is irrelevant.  In this case, in
+# the parts of the outer ':S' modifier, make only counts the braces, and since
+# the inner expression '${:U...}' contains more '{' than '}', parsing fails.
+.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
+.endif
+#.MAKEFLAGS: -d0
+
+
+all: .PHONY

Index: src/usr.bin/make/unit-tests/varmod-undefined.mk
diff -u src/usr.bin/make/unit-tests/varmod-undefined.mk:1.7 src/usr.bin/make/unit-tests/varmod-undefined.mk:1.8
--- src/usr.bin/make/unit-tests/varmod-undefined.mk:1.7	Sun Nov 15 20:20:58 2020
+++ src/usr.bin/make/unit-tests/varmod-undefined.mk	Sat Aug  6 21:26:05 2022
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-undefined.mk,v 1.7 2020/11/15 20:20:58 rillig Exp $
+# $NetBSD: varmod-undefined.mk,v 1.8 2022/08/06 21:26:05 rillig Exp $
 #
 # Tests for the :U variable modifier, which returns the given string
 # if the variable is undefined.
@@ -29,7 +29,7 @@
 # The nested variable expressions may contain braces, and these braces don't
 # need to match pairwise.  In the following example, the :S modifier uses '{'
 # as delimiter, which confuses both editors and humans because the opening
-# and # closing braces don't match anymore.  It's syntactically valid though.
+# and closing braces don't match anymore.  It's syntactically valid though.
 # For more similar examples, see varmod-subst.mk, mod-subst-delimiter.
 
 .if ${:U${:Uvalue:S{a{X{}} != vXlue

Reply via email to