Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make/unit-tests tests/make: test double indirection ...



details:   https://anonhg.NetBSD.org/src/rev/1a3e1c084f8e
branches:  trunk
changeset: 1025913:1a3e1c084f8e
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sat Nov 13 18:37:42 2021 +0000

description:
tests/make: test double indirection in ':=' with undefined variable

Reported by Simon J Gerraty via private mail.

This edge case has been handled in essentially the same way since at
least 2000-05-30, probably several years earlier as well.  The test file
is:

---- snip ----
.undef LATER
.undef later
INDIRECT:=      ${LATER:S,value,replaced,}
indirect:=      ${INDIRECT:C,S,s,}
# expect+1: Unknown modifier "s,value,replaced,"
.if ${indirect} != ""
.  error
.else
.  warning      XXX Neither branch should be taken.
.endif
LATER=  uppercase-value
later=  lowercase-value
# expect+1: Unknown modifier "s,value,replaced,"
.if ${indirect} != "uppercase-replaced"
.  warning      XXX Neither branch should be taken.
.else
.  error
.endif

all:
        @:;
---- snap ----

The output from 'make -r -f later.mk' is:

make-2000.05.30.02.32.21
| make: Unknown modifier 's'
|
| "later.mk", line 9: Need an operator
| make: Unknown modifier 's'
|
| "later.mk", line 15: Need an operator
| Fatal errors encountered -- cannot continue
| exit status 1
make-2000.12.30.16.38.22

The pathnames in the error message gets absolute:

make-2001.01.23.02.48.05
| make: Unknown modifier 's'
|
| ".../later.mk", line 9: Need an operator
| make: Unknown modifier 's'
|
| ".../later.mk", line 15: Need an operator
| Fatal errors encountered -- cannot continue
| exit status 1
make-2001.01.23.02.48.05

All error messages get 'make:' as a common prefix:

make-2001.02.23.21.11.38
| make: Unknown modifier 's'
|
| make: ".../later.mk" line 9: Need an operator
| make: Unknown modifier 's'
|
| make: ".../later.mk" line 15: Need an operator
| make: Fatal errors encountered -- cannot continue
| exit status 1
make-2001.05.29.17.37.52

The 'stopped in' gets added:

make-2001.06.12.23.36.18
| make: Unknown modifier 's'
|
| make: ".../later.mk" line 9: Need an operator
| make: Unknown modifier 's'
|
| make: ".../later.mk" line 15: Need an operator
| make: Fatal errors encountered -- cannot continue
|
| make: stopped in ...
| exit status 1
make-2002.02.21.22.21.34

The empty lines between the error messages get removed.

make-2002.03.21.11.42.21
| make: Unknown modifier 's'
| make: ".../later.mk" line 9: Need an operator
| make: Unknown modifier 's'
| make: ".../later.mk" line 15: Need an operator
| make: Fatal errors encountered -- cannot continue
|
| make: stopped in ...
| exit status 1
make-2009.10.15.02.27.44

The error message for unknown directives gets more helpful:

make-2009.11.19.06.48.37
| make: Unknown modifier 's'
| make: ".../later.mk" line 9: Unknown directive
| make: Unknown modifier 's'
| make: ".../later.mk" line 15: Unknown directive
| make: Fatal errors encountered -- cannot continue
|
| make: stopped in ...
| exit status 1
make-2010.02.22.19.20.33

The directives '.error', '.warning' and '.info' get added:

make-2010.04.29.23.12.21
| make: Unknown modifier 's'
| make: ".../later.mk" line 9: warning: XXX Neither branch should be taken.
| make: Unknown modifier 's'
| make: ".../later.mk" line 15: warning: XXX Neither branch should be taken.
| exit status 0
make-2020.12.20.19.37.23

The error message about an unknown variable modifier gets line number
information:

make-2020.12.20.19.47.34
| make: ".../later.mk" line 6: Unknown modifier 's'
| make: ".../later.mk" line 9: warning: XXX Neither branch should be taken.
| make: ".../later.mk" line 14: Unknown modifier 's'
| make: ".../later.mk" line 15: warning: XXX Neither branch should be taken.
| make: Fatal errors encountered -- cannot continue
| make: stopped in ...
| exit status 1
make-2021.02.23.15.07.58

The error message about an unknown variable modifier gets more context
than only a single letter:

make-2021.02.23.15.19.41
| make: ".../later.mk" line 6: Unknown modifier "s,value,replaced,"
| make: ".../later.mk" line 9: warning: XXX Neither branch should be taken.
| make: ".../later.mk" line 14: Unknown modifier "s,value,replaced,"
| make: ".../later.mk" line 15: warning: XXX Neither branch should be taken.
| make: Fatal errors encountered -- cannot continue
| make: stopped in ...
| exit status 1

diffstat:

 usr.bin/make/unit-tests/var-op-expand.exp |   8 +++-
 usr.bin/make/unit-tests/var-op-expand.mk  |  69 ++++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 2 deletions(-)

diffs (94 lines):

diff -r 62c8d2add92d -r 1a3e1c084f8e usr.bin/make/unit-tests/var-op-expand.exp
--- a/usr.bin/make/unit-tests/var-op-expand.exp Sat Nov 13 18:30:27 2021 +0000
+++ b/usr.bin/make/unit-tests/var-op-expand.exp Sat Nov 13 18:37:42 2021 +0000
@@ -1,1 +1,7 @@
-exit status 0
+make: "var-op-expand.mk" line 229: Unknown modifier "s,value,replaced,"
+make: "var-op-expand.mk" line 232: warning: XXX Neither branch should be taken.
+make: "var-op-expand.mk" line 237: Unknown modifier "s,value,replaced,"
+make: "var-op-expand.mk" line 238: warning: XXX Neither branch should be taken.
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
diff -r 62c8d2add92d -r 1a3e1c084f8e usr.bin/make/unit-tests/var-op-expand.mk
--- a/usr.bin/make/unit-tests/var-op-expand.mk  Sat Nov 13 18:30:27 2021 +0000
+++ b/usr.bin/make/unit-tests/var-op-expand.mk  Sat Nov 13 18:37:42 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-expand.mk,v 1.11 2021/01/01 23:07:48 sjg Exp $
+# $NetBSD: var-op-expand.mk,v 1.12 2021/11/13 18:37:42 rillig Exp $
 #
 # Tests for the := variable assignment operator, which expands its
 # right-hand side.
@@ -174,5 +174,72 @@
 .  error
 .endif
 
+
+# The following test case demonstrates that the variable 'LATER' is preserved
+# in the ':=' assignment since the variable 'LATER' is not yet defined.
+# After the assignment to 'LATER', evaluating the variable 'INDIRECT'
+# evaluates 'LATER' as well.
+#
+.undef LATER
+INDIRECT:=     ${LATER:S,value,replaced,}
+.if ${INDIRECT} != ""
+.  error
+.endif
+LATER= late-value
+.if ${INDIRECT} != "late-replaced"
+.  error
+.endif
+
+
+# Same as the test case above, except for the additional modifier ':tl' when
+# evaluating the variable 'INDIRECT'.  Nothing surprising here.
+.undef LATER
+.undef later
+INDIRECT:=     ${LATER:S,value,replaced,}
+.if ${INDIRECT:tl} != ""
+.  error
+.endif
+LATER= uppercase-value
+later= lowercase-value
+.if ${INDIRECT:tl} != "uppercase-replaced"
+.  error
+.endif
+
+
+# Similar to the two test cases above, the situation gets a bit more involved
+# here, due to the double indirection.  The variable 'indirect' is supposed to
+# be the lowercase version of the variable 'INDIRECT'.
+#
+# The assignment operator ':=' for the variable 'INDIRECT' could be a '=' as
+# well, it wouldn't make a difference in this case.  The crucial detail is the
+# assignment operator ':=' for the variable 'indirect', though.  During this
+# assignment, the variable modifier ':S,value,replaced,' is converted to
+# lowercase, which turns 'S' into 's', thus producing an unknown modifier.
+# In this case, make issues a warning, but in cases where the modifier
+# includes a '=', the modifier would be interpreted as a SysV-style
+# substitution like '.c=.o', and make would not issue a warning, leading to
+# silent unexpected behavior.
+#
+# As of 2021-11-13, the actual behavior is unexpected though since
+.undef LATER
+.undef later
+INDIRECT:=     ${LATER:S,value,replaced,}
+indirect:=     ${INDIRECT:tl}
+# expect+1: Unknown modifier "s,value,replaced,"
+.if ${indirect} != ""
+.  error
+.else
+.  warning     XXX Neither branch should be taken.
+.endif
+LATER= uppercase-value
+later= lowercase-value
+# expect+1: Unknown modifier "s,value,replaced,"
+.if ${indirect} != "uppercase-replaced"
+.  warning     XXX Neither branch should be taken.
+.else
+.  error
+.endif
+
+
 all:
        @:;



Home | Main Index | Thread Index | Old Index