Module Name: src
Committed By: rillig
Date: Sat Jun 11 09:15:49 UTC 2022
Modified Files:
src/usr.bin/make/unit-tests: varmod-match.exp varmod-match.mk
Log Message:
tests/make: test edge cases in pattern matching
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/varmod-match.exp
cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/unit-tests/varmod-match.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-match.exp
diff -u src/usr.bin/make/unit-tests/varmod-match.exp:1.6 src/usr.bin/make/unit-tests/varmod-match.exp:1.7
--- src/usr.bin/make/unit-tests/varmod-match.exp:1.6 Sat Jun 11 07:54:25 2022
+++ src/usr.bin/make/unit-tests/varmod-match.exp Sat Jun 11 09:15:49 2022
@@ -10,8 +10,8 @@ CondParser_Eval: ${:Ua \$ sign:M*$$*} !=
Comparing "$" != "$"
CondParser_Eval: ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk"
Comparing "any-asterisk" != "any-asterisk"
-make: "varmod-match.mk" line 151: Unknown modifier "]"
-make: "varmod-match.mk" line 151: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 157: Unknown modifier "]"
+make: "varmod-match.mk" line 157: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1
Index: src/usr.bin/make/unit-tests/varmod-match.mk
diff -u src/usr.bin/make/unit-tests/varmod-match.mk:1.10 src/usr.bin/make/unit-tests/varmod-match.mk:1.11
--- src/usr.bin/make/unit-tests/varmod-match.mk:1.10 Sat Jun 11 07:54:25 2022
+++ src/usr.bin/make/unit-tests/varmod-match.mk Sat Jun 11 09:15:49 2022
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match.mk,v 1.10 2022/06/11 07:54:25 rillig Exp $
+# $NetBSD: varmod-match.mk,v 1.11 2022/06/11 09:15:49 rillig Exp $
#
# Tests for the :M variable modifier, which filters words that match the
# given pattern.
@@ -130,6 +130,12 @@ ${:U*}= asterisk
. error
.endif
+# [\] matches a single backslash
+WORDS= a\b a[\]b ab
+.if ${WORDS:Ma[\]b} != "a\\b"
+. error
+.endif
+
# : terminates the pattern
.if ${ A * :L:M:} != ""
. error
@@ -156,26 +162,95 @@ ${:U*}= asterisk
# [\] matches exactly a backslash; no escaping takes place in
# character ranges
-# Without the 'a' in the below expressions, the backslash would end a word and
-# thus influence how the string is split into words.
-.if ${ ${:U\\a} ${:U\\\\a} :L:M[\]a} != "\\a"
+# Without the 'a' in the below words, the backslash would end a word and thus
+# influence how the string is split into words.
+WORDS= 1\a 2\\a
+.if ${WORDS:M?[\]a} != "1\\a"
+. error
+.endif
+
+# [[-]] May look like it would match a single '[', '\' or ']', but
+# the inner ']' has two roles: it is the upper bound of the
+# character range as well as the closing character of the
+# character list. The outer ']' is just a regular character.
+WORDS= [ ] [] \] ]]
+.if ${WORDS:M[[-]]} != "[] \\] ]]"
+. error
+.endif
+
+# [b[-]a]
+# Same as for '[[-]]': the character list stops at the first
+# ']', and the 'a]' is treated as a literal string.
+WORDS= [a \a ]a []a \]a ]]a [a] \a] ]a] ba]
+.if ${WORDS:M[b[-]a]} != "[a] \\a] ]a] ba]"
+. error
+.endif
+
+# [-] Matches a single '-' since the '-' only becomes part of a
+# character range if it is preceded and followed by another
+# character.
+WORDS= - -]
+.if ${WORDS:M[-]} != "-"
+. error
+.endif
+
+# [ Incomplete empty character list, never matches.
+WORDS= a a[
+.if ${WORDS:Ma[} != ""
+. error
+.endif
+
+# [^ Incomplete negated empty character list, matches any single
+# character.
+WORDS= a a[ aX
+.if ${WORDS:Ma[^} != "a[ aX"
. error
.endif
-#.MAKEFLAGS: -dcv
-#
-# Incomplete patterns:
-# [ matches TODO
-# [x matches TODO
-# [^ matches TODO
-# [- matches TODO
-# [xy matches TODO
-# [^x matches TODO
-# [\ matches TODO
-#
-# [x- matches exactly 'x', doesn't match 'x-'
-# [^x- matches TODO
-# \ matches never
+# [-x1-3 Incomplete character list, matches those elements that can be
+# parsed without lookahead.
+WORDS= - + x xx 0 1 2 3 4 [x1-3
+.if ${WORDS:M[-x1-3} != "- x 1 2 3"
+. error
+.endif
+
+# [^-x1-3
+# Incomplete negated character list, matches any character
+# except those elements that can be parsed without lookahead.
+WORDS= - + x xx 0 1 2 3 4 [x1-3
+.if ${WORDS:M[^-x1-3} != "+ 0 4"
+. error
+.endif
+
+# [\ Incomplete character list containing a single '\'.
+#
+# A word can only end with a backslash if the preceding
+# character is a backslash as well; in all other cases the final
+# backslash would escape the following space, making the space
+# part of the word. Only the very last word of a string can be
+# '\', as there is no following space that could be escaped.
+WORDS= \\ \a ${:Ux\\}
+.if ${WORDS:M?[\]} != "\\\\ x\\"
+. error
+.endif
+
+# [x- Incomplete character list containing an incomplete character
+# range, matches only the 'x'.
+WORDS= [x- x x- y
+.if ${WORDS:M[x-} != "x"
+. error
+.endif
+
+# [^x- Incomplete negated character list containing an incomplete
+# character range; matches each word that does not have an 'x'
+# at the position of the character list.
+#
+# XXX: Even matches strings that are longer than a single
+# character.
+WORDS= [x- x x- y yyyyy
+.if ${WORDS:M[^x-} != "[x- y yyyyy"
+. error
+.endif
# The modifier ':tW' prevents splitting at whitespace. Even leading and