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 make(1): add test for error handling...
details: https://anonhg.NetBSD.org/src/rev/50b3a8f11d2f
branches: trunk
changeset: 958287:50b3a8f11d2f
user: rillig <rillig%NetBSD.org@localhost>
date: Thu Dec 31 03:05:12 2020 +0000
description:
make(1): add test for error handling and expansion in .for loops
diffstat:
distrib/sets/lists/tests/mi | 6 +-
usr.bin/make/unit-tests/Makefile | 4 +-
usr.bin/make/unit-tests/directive-for-errors.exp | 22 +++++++
usr.bin/make/unit-tests/directive-for-errors.mk | 75 ++++++++++++++++++++++++
usr.bin/make/unit-tests/directive-for-escape.exp | 44 ++++++++++++++
usr.bin/make/unit-tests/directive-for-escape.mk | 61 +++++++++++++++++++
6 files changed, 210 insertions(+), 2 deletions(-)
diffs (256 lines):
diff -r a0b640ec3dc8 -r 50b3a8f11d2f distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi Thu Dec 31 02:16:14 2020 +0000
+++ b/distrib/sets/lists/tests/mi Thu Dec 31 03:05:12 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1002 2020/12/30 14:50:08 rillig Exp $
+# $NetBSD: mi,v 1.1003 2020/12/31 03:05:12 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -5058,6 +5058,10 @@
./usr/tests/usr.bin/make/unit-tests/directive-export-literal.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-export.mk tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-for-errors.exp tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-for-errors.mk tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-for-escape.exp tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/directive-for-escape.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-generating-endif.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-generating-endif.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/directive-for-lines.exp tests-usr.bin-tests compattestfile,atf
diff -r a0b640ec3dc8 -r 50b3a8f11d2f usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile Thu Dec 31 02:16:14 2020 +0000
+++ b/usr.bin/make/unit-tests/Makefile Thu Dec 31 03:05:12 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.259 2020/12/30 14:50:08 rillig Exp $
+# $NetBSD: Makefile,v 1.260 2020/12/31 03:05:12 rillig Exp $
#
# Unit tests for make(1)
#
@@ -162,6 +162,8 @@
TESTS+= directive-export-gmake
TESTS+= directive-export-literal
TESTS+= directive-for
+TESTS+= directive-for-errors
+TESTS+= directive-for-escape
TESTS+= directive-for-generating-endif
TESTS+= directive-for-lines
TESTS+= directive-for-null
diff -r a0b640ec3dc8 -r 50b3a8f11d2f usr.bin/make/unit-tests/directive-for-errors.exp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-errors.exp Thu Dec 31 03:05:12 2020 +0000
@@ -0,0 +1,22 @@
+make: "directive-for-errors.mk" line 7: Unknown directive "fori"
+make: "directive-for-errors.mk" line 8: warning:
+make: "directive-for-errors.mk" line 9: for-less endfor
+make: "directive-for-errors.mk" line 19: Unknown directive "for"
+make: "directive-for-errors.mk" line 20: warning:
+make: "directive-for-errors.mk" line 21: for-less endfor
+make: "directive-for-errors.mk" line 37: Dollar $ 1 1 and backslash 2 2 2.
+make: "directive-for-errors.mk" line 37: Dollar $ 3 3 and backslash 4 4 4.
+make: "directive-for-errors.mk" line 43: no iteration variables in for
+make: "directive-for-errors.mk" line 47: warning: Should not be reached.
+make: "directive-for-errors.mk" line 48: for-less endfor
+make: "directive-for-errors.mk" line 53: Wrong number of words (5) in .for substitution list with 3 variables
+make: "directive-for-errors.mk" line 64: missing `in' in for
+make: "directive-for-errors.mk" line 66: warning: Should not be reached.
+make: "directive-for-errors.mk" line 67: for-less endfor
+make: "directive-for-errors.mk" line 73: Unknown modifier 'Z'
+make: "directive-for-errors.mk" line 74: warning: Should not be reached.
+make: "directive-for-errors.mk" line 74: warning: Should not be reached.
+make: "directive-for-errors.mk" line 74: warning: Should not be reached.
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
diff -r a0b640ec3dc8 -r 50b3a8f11d2f usr.bin/make/unit-tests/directive-for-errors.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-errors.mk Thu Dec 31 03:05:12 2020 +0000
@@ -0,0 +1,75 @@
+# $NetBSD: directive-for-errors.mk,v 1.1 2020/12/31 03:05:12 rillig Exp $
+#
+# Tests for error handling in .for loops.
+
+# A .for directive must be followed by whitespace, everything else results
+# in a parse error.
+.fori in 1 2 3
+. warning ${i}
+.endfor
+
+# A slash is not whitespace, therefore this is not parsed as a .for loop.
+#
+# XXX: The error message is misleading though. As of 2020-12-31, it says
+# "Unknown directive "for"", but that directive is actually known. This is
+# because ForEval does not detect the .for loop as such, so parsing
+# continues in ParseLine > ParseDependency > ParseDoDependency >
+# ParseDoDependencyTargets > ParseErrorNoDependency, and there the directive
+# name is parsed a bit differently.
+.for/i in 1 2 3
+. warning ${i}
+.endfor
+
+# As of 2020-12-31, the variable name can be an arbitrary word, it just needs
+# to be separated by whitespace. Even '$' and '\' are valid variable names,
+# which is not useful in practice.
+#
+# The '$$' is not replaced with the values '1' or '3' from the .for loop,
+# instead it is kept as-is, and when the .info directive expands its argument,
+# each '$$' gets replaced with a single '$'. The "long variable expression"
+# ${$} gets replaced though, even though this would be a parse error everywhere
+# outside a .for loop.
+#
+# The '\' on the other hand is treated as a normal variable name.
+${:U\$}= dollar # see whether the "variable" '$' is local
+${:U\\}= backslash # see whether the "variable" '\' is local
+.for $ \ in 1 2 3 4
+. info Dollar $$ ${$} $($) and backslash $\ ${\} $(\).
+.endfor
+
+# If there are no variables, there is no point in expanding the .for loop
+# since this would end up in an endless loop, each time consuming 0 of the
+# 3 values.
+.for in 1 2 3
+# XXX: This should not be reached. It should be skipped, as already done
+# when the number of values is not a multiple of the number of variables,
+# see below.
+. warning Should not be reached.
+.endfor
+
+# There are 3 variables and 5 values. These 5 values cannot be split evenly
+# among the variables, therefore the loop is not expanded at all, it is
+# rather skipped.
+.for a b c in 1 2 3 4 5
+. warning Should not be reached.
+.endfor
+
+# The list of values after the 'in' may be empty, no matter if this emptiness
+# comes from an empty expansion or even from a syntactically empty line.
+.for i in
+. info Would be reached if there were items to loop over.
+.endfor
+
+# A missing 'in' should parse the .for loop but skip the body.
+.for i : k
+# XXX: As of 2020-12-31, this line is reached once.
+. warning Should not be reached.
+.endfor
+
+# A malformed modifier should be detected and skip the body of the loop.
+#
+# XXX: As of 2020-12-31, Var_Subst doesn't report any errors, therefore
+# the loop body is expanded as if no error had happened.
+.for i in 1 2 ${:U3:Z} 4
+. warning Should not be reached.
+.endfor
diff -r a0b640ec3dc8 -r 50b3a8f11d2f usr.bin/make/unit-tests/directive-for-escape.exp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.exp Thu Dec 31 03:05:12 2020 +0000
@@ -0,0 +1,44 @@
+For: end for 1
+For: loop body:
+. info ${:U!"#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
+make: Unclosed variable specification (expecting '}') for "" (value "!"") modifier U
+make: "directive-for-escape.mk" line 19: !"
+For: end for 1
+For: loop body:
+. info ${:U!"\\\\#$%&'()*+,-./0-9\:;<=>?@A-Z[\\]_^a-z{|\}~}
+make: Unclosed variable specification (expecting '}') for "" (value "!"\\") modifier U
+make: "directive-for-escape.mk" line 29: !"\\
+For: end for 1
+For: loop body:
+. info ${:U\$}
+make: "directive-for-escape.mk" line 41: $
+For: loop body:
+. info ${:U${V}}
+make: "directive-for-escape.mk" line 41: value
+For: loop body:
+. info ${:U${V:=-with-modifier}}
+make: "directive-for-escape.mk" line 41: value-with-modifier
+For: loop body:
+. info ${:U$(V)}
+make: "directive-for-escape.mk" line 41: value
+For: loop body:
+. info ${:U$(V:=-with-modifier)}
+make: "directive-for-escape.mk" line 41: value-with-modifier
+For: end for 1
+For: loop body:
+. info ${:U\${UNDEF\:U\\$\\$}
+make: "directive-for-escape.mk" line 52: ${UNDEF:U\$
+For: loop body:
+. info ${:U{{\}\}}
+make: "directive-for-escape.mk" line 52: {{}}
+For: loop body:
+. info ${:Uend\}}
+make: "directive-for-escape.mk" line 52: end}
+For: end for 1
+For: loop body:
+. info ${:U\$}
+make: "directive-for-escape.mk" line 60: $
+make: no target to make.
+
+make: stopped in unit-tests
+exit status 2
diff -r a0b640ec3dc8 -r 50b3a8f11d2f usr.bin/make/unit-tests/directive-for-escape.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/directive-for-escape.mk Thu Dec 31 03:05:12 2020 +0000
@@ -0,0 +1,61 @@
+# $NetBSD: directive-for-escape.mk,v 1.1 2020/12/31 03:05:12 rillig Exp $
+#
+# Test escaping of special characters in the iteration values of a .for loop.
+# These values get expanded later using the :U variable modifier, and this
+# escaping and unescaping must pass all characters and strings effectively
+# unmodified.
+
+.MAKEFLAGS: -df
+
+# Even though the .for loops takes quotes into account when splitting the
+# string into words, the quotes don't need to be balances, as of 2020-12-31.
+# This could be considered a bug.
+ASCII= !"\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
+
+# XXX: As of 2020-12-31, the '#' is not preserved in the expanded body of
+# the loop since it would not need only the escaping for the :U variable
+# modifier but also the escaping for the line-end comment.
+.for chars in ${ASCII}
+. info ${chars}
+.endfor
+
+# As of 2020-12-31, using 2 backslashes before be '#' would treat the '#'
+# as comment character. Using 3 backslashes doesn't help either since
+# then the situation is essentially the same as with 1 backslash.
+# This means that a '#' sign cannot be passed in the value of a .for loop
+# at all.
+ASCII.2020-12-31= !"\\\#$$%&'()*+,-./0-9:;<=>?@A-Z[\]_^a-z{|}~
+.for chars in ${ASCII.2020-12-31}
+. info ${chars}
+.endfor
+
+# Cover the code in for_var_len.
+#
+# XXX: It is unexpected that the variable V gets expanded in the loop body.
+# The double '$$' should prevent exactly this. Probably nobody was
+# adventurous enough to use literal dollar signs in the values for a .for
+# loop.
+V= value
+VALUES= $$ $${V} $${V:=-with-modifier} $$(V) $$(V:=-with-modifier)
+.for i in ${VALUES}
+. info $i
+.endfor
+
+# Cover the code for nested '{}' in for_var_len.
+#
+# The value of VALUES is not a variable expression. Instead, it is meant to
+# represent dollar, lbrace, "UNDEF:U", backslash, dollar, backslash, dollar,
+# space, nested braces, space, "end}".
+VALUES= $${UNDEF:U\$$\$$ {{}} end}
+# XXX: Where does the '\$$\$$' get converted into a single '\$'?
+.for i in ${VALUES}
+. info $i
+.endfor
+
+# A single trailing dollar doesn't happen in practice.
+# The dollar sign is correctly passed through to the body of the .for loop.
+# There, it is expanded by the .info directive, but even there a trailing
+# dollar sign is kept as-is.
+.for i in ${:U\$}
+. info ${i}
+.endfor
Home |
Main Index |
Thread Index |
Old Index