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