Module Name: src
Committed By: rillig
Date: Sun Mar 14 11:49:37 UTC 2021
Modified Files:
src/distrib/sets/lists/tests: mi
src/usr.bin/make/unit-tests: Makefile cond-short.mk
Added Files:
src/usr.bin/make/unit-tests: var-eval-short.exp var-eval-short.mk
Log Message:
tests/make: add test for short-circuit evaluation of modifiers
To generate a diff of this commit:
cvs rdiff -u -r1.1031 -r1.1032 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.272 -r1.273 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/make/unit-tests/cond-short.mk
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/var-eval-short.exp \
src/usr.bin/make/unit-tests/var-eval-short.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1031 src/distrib/sets/lists/tests/mi:1.1032
--- src/distrib/sets/lists/tests/mi:1.1031 Fri Mar 12 00:13:06 2021
+++ src/distrib/sets/lists/tests/mi Sun Mar 14 11:49:37 2021
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1031 2021/03/12 00:13:06 rillig Exp $
+# $NetBSD: mi,v 1.1032 2021/03/14 11:49:37 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -5727,6 +5727,8 @@
./usr/tests/usr.bin/make/unit-tests/var-class-local.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-class.mk tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/var-eval-short.exp tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/var-eval-short.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-append.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-append.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/var-op-assign.exp tests-usr.bin-tests compattestfile,atf
Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.272 src/usr.bin/make/unit-tests/Makefile:1.273
--- src/usr.bin/make/unit-tests/Makefile:1.272 Sun Mar 14 10:45:51 2021
+++ src/usr.bin/make/unit-tests/Makefile Sun Mar 14 11:49:37 2021
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.272 2021/03/14 10:45:51 rillig Exp $
+# $NetBSD: Makefile,v 1.273 2021/03/14 11:49:37 rillig Exp $
#
# Unit tests for make(1)
#
@@ -320,6 +320,7 @@ TESTS+= var-class-env
TESTS+= var-class-global
TESTS+= var-class-local
TESTS+= var-class-local-legacy
+TESTS+= var-eval-short
TESTS+= var-op
TESTS+= var-op-append
TESTS+= var-op-assign
Index: src/usr.bin/make/unit-tests/cond-short.mk
diff -u src/usr.bin/make/unit-tests/cond-short.mk:1.15 src/usr.bin/make/unit-tests/cond-short.mk:1.16
--- src/usr.bin/make/unit-tests/cond-short.mk:1.15 Tue Dec 1 19:37:23 2020
+++ src/usr.bin/make/unit-tests/cond-short.mk Sun Mar 14 11:49:37 2021
@@ -1,4 +1,4 @@
-# $NetBSD: cond-short.mk,v 1.15 2020/12/01 19:37:23 rillig Exp $
+# $NetBSD: cond-short.mk,v 1.16 2021/03/14 11:49:37 rillig Exp $
#
# Demonstrates that in conditions, the right-hand side of an && or ||
# is only evaluated if it can actually influence the result.
@@ -13,8 +13,11 @@
# parse them. They were still evaluated though, the only difference to
# relevant variable expressions was that in the irrelevant variable
# expressions, undefined variables were allowed.
+#
+# See also:
+# var-eval-short.mk, for short-circuited variable modifiers
-# The && operator.
+# The && operator:
.if 0 && ${echo "unexpected and" 1>&2 :L:sh}
.endif
@@ -86,7 +89,7 @@ VAR= # empty again, for the following te
. warning first=${FIRST} last=${LAST} appended=${APPENDED} ran=${RAN}
.endif
-# The || operator.
+# The || operator:
.if 1 || ${echo "unexpected or" 1>&2 :L:sh}
.endif
@@ -208,9 +211,4 @@ x!= echo '0 || $${iV2:U2} < $${V42}: $x'
. error
.endif
-# TODO: Test each modifier to make sure it is skipped when it is irrelevant
-# for the result. Since this test is already quite long, do that in another
-# test.
-
all:
- @:;:
Added files:
Index: src/usr.bin/make/unit-tests/var-eval-short.exp
diff -u /dev/null src/usr.bin/make/unit-tests/var-eval-short.exp:1.1
--- /dev/null Sun Mar 14 11:49:38 2021
+++ src/usr.bin/make/unit-tests/var-eval-short.exp Sun Mar 14 11:49:37 2021
@@ -0,0 +1,11 @@
+unexpected
+make: Bad modifier ":[${FAIL" for variable ""
+make: "var-eval-short.mk" line 43: Malformed conditional (0 && ${:Uword:[${FAIL}]})
+make: "var-eval-short.mk" line 48: Missing argument for ".error"
+make: "var-eval-short.mk" line 63: Invalid time value: ${FAIL}}
+make: "var-eval-short.mk" line 63: Malformed conditional (0 && ${:Uword:gmtime=${FAIL}})
+make: "var-eval-short.mk" line 77: Invalid time value: ${FAIL}}
+make: "var-eval-short.mk" line 77: Malformed conditional (0 && ${:Uword:localtime=${FAIL}})
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
Index: src/usr.bin/make/unit-tests/var-eval-short.mk
diff -u /dev/null src/usr.bin/make/unit-tests/var-eval-short.mk:1.1
--- /dev/null Sun Mar 14 11:49:38 2021
+++ src/usr.bin/make/unit-tests/var-eval-short.mk Sun Mar 14 11:49:37 2021
@@ -0,0 +1,128 @@
+# $NetBSD: var-eval-short.mk,v 1.1 2021/03/14 11:49:37 rillig Exp $
+#
+# Tests for each variable modifier to ensure that they only do the minimum
+# necessary computations. If the result of the expression is not needed, they
+# should only parse the modifier but not actually evaluate it.
+#
+# See also:
+# var.c, the comment starting with 'The ApplyModifier functions'
+# ApplyModifier, for the order of the modifiers
+# ParseModifierPart, for evaluating nested expressions
+# cond-short.mk
+
+FAIL= ${:!echo unexpected 1>&2!}
+
+# The following tests only ensure that nested expressions are not evaluated.
+# They cannot ensure that any unexpanded text returned from ParseModifierPart
+# is ignored as well. To do that, it is necessary to step through the code of
+# each modifier.
+
+.if 0 && ${FAIL}
+.endif
+
+.if 0 && ${VAR::=${FAIL}}
+.elif defined(VAR)
+. error
+.endif
+
+.if 0 && ${${FAIL}:?then:else}
+.endif
+
+.if 0 && ${1:?${FAIL}:${FAIL}}
+.endif
+
+.if 0 && ${0:?${FAIL}:${FAIL}}
+.endif
+
+.if 0 && ${:Uword:@${FAIL}@expr@}
+.endif
+
+.if 0 && ${:Uword:@var@${FAIL}@}
+.endif
+
+.if 0 && ${:Uword:[${FAIL}]}
+.endif
+
+.if 0 && ${:Uword:_=VAR}
+.elif defined(VAR)
+. error
+.endif
+
+.if 0 && ${:Uword:C,${FAIL}****,,}
+.endif
+
+DEFINED= # defined
+.if 0 && ${DEFINED:D${FAIL}}
+.endif
+
+.if 0 && ${:Uword:E}
+.endif
+
+# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since
+# ':gmtime' does not expand its argument.
+.if 0 && ${:Uword:gmtime=${FAIL}}
+.endif
+
+.if 0 && ${:Uword:H}
+.endif
+
+.if 0 && ${:Uword:hash}
+.endif
+
+.if 0 && ${value:L}
+.endif
+
+# As of 2021-03-14, the error 'Invalid time value: ${FAIL}}' is ok since
+# ':localtime' does not expand its argument.
+.if 0 && ${:Uword:localtime=${FAIL}}
+.endif
+
+.if 0 && ${:Uword:M${FAIL}}
+.endif
+
+.if 0 && ${:Uword:N${FAIL}}
+.endif
+
+.if 0 && ${:Uword:O}
+.endif
+
+.if 0 && ${:Uword:Ox}
+.endif
+
+.if 0 && ${:Uword:P}
+.endif
+
+.if 0 && ${:Uword:Q}
+.endif
+
+.if 0 && ${:Uword:q}
+.endif
+
+.if 0 && ${:Uword:R}
+.endif
+
+.if 0 && ${:Uword:range}
+.endif
+
+.if 0 && ${:Uword:S,${FAIL},${FAIL},}
+.endif
+
+.if 0 && ${:Uword:sh}
+.endif
+
+.if 0 && ${:Uword:T}
+.endif
+
+.if 0 && ${:Uword:ts/}
+.endif
+
+.if 0 && ${:U${FAIL}}
+.endif
+
+.if 0 && ${:Uword:u}
+.endif
+
+.if 0 && ${:Uword:word=replacement}
+.endif
+
+all: