Module Name:    src
Committed By:   rillig
Date:           Thu Sep  3 18:52:37 UTC 2020

Modified Files:
        src/usr.bin/make/unit-tests: varmod-defined.mk varmod-undefined.mk

Log Message:
make(1): add tests for the :D and :U modifiers

This prepares a refactoring for ApplyModifier_Defined.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/varmod-defined.mk \
    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/varmod-defined.mk
diff -u src/usr.bin/make/unit-tests/varmod-defined.mk:1.3 src/usr.bin/make/unit-tests/varmod-defined.mk:1.4
--- src/usr.bin/make/unit-tests/varmod-defined.mk:1.3	Tue Aug 25 21:58:08 2020
+++ src/usr.bin/make/unit-tests/varmod-defined.mk	Thu Sep  3 18:52:36 2020
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-defined.mk,v 1.3 2020/08/25 21:58:08 rillig Exp $
+# $NetBSD: varmod-defined.mk,v 1.4 2020/09/03 18:52:36 rillig Exp $
 #
 # Tests for the :D variable modifier, which returns the given string
 # if the variable is defined.  It is closely related to the :U modifier.
@@ -24,5 +24,44 @@ DEF=	defined
 .error
 .endif
 
+# The modifier text may contain plain text as well as expressions.
+#
+.if ${DEF:D<${DEF}>} != "<defined>"
+.  error
+.endif
+
+# Special characters that would be interpreted differently can be escaped.
+# These are '}' (the closing character of the expression), ':', '$' and '\'.
+# Any other backslash sequences are preserved.
+#
+# The escaping rules for string literals in conditions are completely
+# different though. There, any character may be escaped using a backslash.
+#
+.if ${DEF:D \} \: \$ \\ \) \n } != " } : \$ \\ \\) \\n "
+.  error
+.endif
+
+# Like in several other places in variable expressions, when
+# ApplyModifier_Defined calls Var_Parse, double dollars lead to a parse
+# error that is silently ignored.  This makes all dollar signs disappear,
+# except for the last, which is a well-formed variable expression.
+#
+.if ${DEF:D$$$$$${DEF}} != "defined"
+.  error
+.endif
+
+# Any other text is written without any further escaping.  In contrast
+# to the :M modifier, parentheses and braces do not need to be nested.
+# Instead, the :D modifier is implemented sanely by parsing nested
+# expressions as such, without trying any shortcuts. See ApplyModifier_Match
+# for an inferior variant.
+#
+.if ${DEF:D!&((((} != "!&(((("
+.  error
+.endif
+
+# TODO: Add more tests for parsing the plain text part, to cover each branch
+# of ApplyModifier_Defined.
+
 all:
 	@:;
Index: src/usr.bin/make/unit-tests/varmod-undefined.mk
diff -u src/usr.bin/make/unit-tests/varmod-undefined.mk:1.3 src/usr.bin/make/unit-tests/varmod-undefined.mk:1.4
--- src/usr.bin/make/unit-tests/varmod-undefined.mk:1.3	Sun Aug 23 20:49:33 2020
+++ src/usr.bin/make/unit-tests/varmod-undefined.mk	Thu Sep  3 18:52:36 2020
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-undefined.mk,v 1.3 2020/08/23 20:49:33 rillig Exp $
+# $NetBSD: varmod-undefined.mk,v 1.4 2020/09/03 18:52:36 rillig Exp $
 #
 # Tests for the :U variable modifier, which returns the given string
 # if the variable is undefined.
@@ -46,10 +46,20 @@
 # the .newline variable is for.
 #
 # Whitespace at the edges is preserved, on both sides of the comparison.
-
+#
 .if ${:U \: \} \$ \\ \a \b \n } != " : } \$ \\ \\a \\b \\n "
 .error
 .endif
 
+# Even after the :U modifier has been applied, the expression still remembers
+# that it originated from an undefined variable, and the :U modifier can
+# be used to overwrite the value of the expression.
+#
+.if ${UNDEF:Uvalue:S,a,X,} != "vXlue"
+.  error
+.elif ${UNDEF:Uvalue:S,a,X,:Uwas undefined} != "was undefined"
+.  error
+.endif
+
 all:
 	@:;

Reply via email to