xref: /freebsd/contrib/bmake/unit-tests/varmod-match.mk (revision 1d3f2ddc32fc37e4835aa5a51eabc8696c1e8114)
1*1d3f2ddcSSimon J. Gerraty# $NetBSD: varmod-match.mk,v 1.8 2022/03/27 18:39:01 rillig Exp $
22c3632d1SSimon J. Gerraty#
32c3632d1SSimon J. Gerraty# Tests for the :M variable modifier, which filters words that match the
42c3632d1SSimon J. Gerraty# given pattern.
5956e45f6SSimon J. Gerraty#
6956e45f6SSimon J. Gerraty# See ApplyModifier_Match and ModifyWord_Match for the implementation.
72c3632d1SSimon J. Gerraty
8956e45f6SSimon J. Gerraty.MAKEFLAGS: -dc
92c3632d1SSimon J. Gerraty
102c3632d1SSimon J. GerratyNUMBERS=	One Two Three Four five six seven
112c3632d1SSimon J. Gerraty
12956e45f6SSimon J. Gerraty# Only keep words that start with an uppercase letter.
13956e45f6SSimon J. Gerraty.if ${NUMBERS:M[A-Z]*} != "One Two Three Four"
14956e45f6SSimon J. Gerraty.  error
15956e45f6SSimon J. Gerraty.endif
162c3632d1SSimon J. Gerraty
17956e45f6SSimon J. Gerraty# Only keep words that start with a character other than an uppercase letter.
18956e45f6SSimon J. Gerraty.if ${NUMBERS:M[^A-Z]*} != "five six seven"
19956e45f6SSimon J. Gerraty.  error
20956e45f6SSimon J. Gerraty.endif
21956e45f6SSimon J. Gerraty
22956e45f6SSimon J. Gerraty# Only keep words that don't start with s and at the same time end with
23956e45f6SSimon J. Gerraty# either of [ex].
24956e45f6SSimon J. Gerraty#
25956e45f6SSimon J. Gerraty# This test case ensures that the negation from the first character class
26956e45f6SSimon J. Gerraty# does not propagate to the second character class.
27956e45f6SSimon J. Gerraty.if ${NUMBERS:M[^s]*[ex]} != "One Three five"
28956e45f6SSimon J. Gerraty.  error
29956e45f6SSimon J. Gerraty.endif
302c3632d1SSimon J. Gerraty
312c3632d1SSimon J. Gerraty# Before 2020-06-13, this expression took quite a long time in Str_Match,
322c3632d1SSimon J. Gerraty# calling itself 601080390 times for 16 asterisks.
33956e45f6SSimon J. Gerraty.if ${:U****************:M****************b}
34956e45f6SSimon J. Gerraty.endif
35956e45f6SSimon J. Gerraty
36956e45f6SSimon J. Gerraty# To match a dollar sign in a word, double it.
37956e45f6SSimon J. Gerraty#
38956e45f6SSimon J. Gerraty# This is different from the :S and :C variable modifiers, where a '$'
39956e45f6SSimon J. Gerraty# has to be escaped as '\$'.
40956e45f6SSimon J. Gerraty.if ${:Ua \$ sign:M*$$*} != "\$"
41956e45f6SSimon J. Gerraty.  error
42956e45f6SSimon J. Gerraty.endif
43956e45f6SSimon J. Gerraty
44956e45f6SSimon J. Gerraty# In the :M modifier, '\$' does not escape a dollar.  Instead it is
45956e45f6SSimon J. Gerraty# interpreted as a backslash followed by whatever expression the
46956e45f6SSimon J. Gerraty# '$' starts.
47956e45f6SSimon J. Gerraty#
48956e45f6SSimon J. Gerraty# This differs from the :S, :C and several other variable modifiers.
49956e45f6SSimon J. Gerraty${:U*}=		asterisk
50956e45f6SSimon J. Gerraty.if ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk"
51956e45f6SSimon J. Gerraty.  error
52956e45f6SSimon J. Gerraty.endif
53956e45f6SSimon J. Gerraty
54e2eeea75SSimon J. Gerraty# TODO: ${VAR:M(((}}}}
55e2eeea75SSimon J. Gerraty# TODO: ${VAR:M{{{)))}
56e2eeea75SSimon J. Gerraty# TODO: ${VAR:M${UNBALANCED}}
57e2eeea75SSimon J. Gerraty# TODO: ${VAR:M${:U(((\}\}\}}}
58e2eeea75SSimon J. Gerraty
59*1d3f2ddcSSimon J. Gerraty.MAKEFLAGS: -d0
60*1d3f2ddcSSimon J. Gerraty
61*1d3f2ddcSSimon J. Gerraty# Special characters:
62*1d3f2ddcSSimon J. Gerraty#	*	matches 0 or more arbitrary characters
63*1d3f2ddcSSimon J. Gerraty#	?	matches a single arbitrary character
64*1d3f2ddcSSimon J. Gerraty#	\	starts an escape sequence, only outside ranges
65*1d3f2ddcSSimon J. Gerraty#	[	starts a set for matching a single character
66*1d3f2ddcSSimon J. Gerraty#	]	ends a set for matching a single character
67*1d3f2ddcSSimon J. Gerraty#	-	in a set, forms a range of characters
68*1d3f2ddcSSimon J. Gerraty#	^	as the first character in a set, negates the set
69*1d3f2ddcSSimon J. Gerraty#	(	during parsing of the pattern, starts a nesting level
70*1d3f2ddcSSimon J. Gerraty#	)	during parsing of the pattern, ends a nesting level
71*1d3f2ddcSSimon J. Gerraty#	{	during parsing of the pattern, starts a nesting level
72*1d3f2ddcSSimon J. Gerraty#	}	during parsing of the pattern, ends a nesting level
73*1d3f2ddcSSimon J. Gerraty#	:	during parsing of the pattern, finishes the pattern
74*1d3f2ddcSSimon J. Gerraty#	$	during parsing of the pattern, starts a nested expression
75*1d3f2ddcSSimon J. Gerraty#	#	in a line except a shell command, starts a comment
76*1d3f2ddcSSimon J. Gerraty#
77*1d3f2ddcSSimon J. Gerraty# Pattern parts:
78*1d3f2ddcSSimon J. Gerraty#	*	matches 0 or more arbitrary characters
79*1d3f2ddcSSimon J. Gerraty#	?	matches exactly 1 arbitrary character
80*1d3f2ddcSSimon J. Gerraty#	\x	matches exactly the character 'x'
81*1d3f2ddcSSimon J. Gerraty#	[...]	matches exactly 1 character from the set
82*1d3f2ddcSSimon J. Gerraty#	[^...]	matches exactly 1 character outside the set
83*1d3f2ddcSSimon J. Gerraty#	[a-z]	matches exactly 1 character from the range 'a' to 'z'
84*1d3f2ddcSSimon J. Gerraty#
85*1d3f2ddcSSimon J. Gerraty
86*1d3f2ddcSSimon J. Gerraty#	[]	matches never
87*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b :L:M[]} != ""
88*1d3f2ddcSSimon J. Gerraty.  error
89*1d3f2ddcSSimon J. Gerraty.endif
90*1d3f2ddcSSimon J. Gerraty
91*1d3f2ddcSSimon J. Gerraty#	a[]b	matches never
92*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b [ ] :L:Ma[]b} != ""
93*1d3f2ddcSSimon J. Gerraty.  error
94*1d3f2ddcSSimon J. Gerraty.endif
95*1d3f2ddcSSimon J. Gerraty
96*1d3f2ddcSSimon J. Gerraty#	[^]	matches exactly 1 arbitrary character
97*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b [ ] :L:M[^]} != "a b [ ]"
98*1d3f2ddcSSimon J. Gerraty.  error
99*1d3f2ddcSSimon J. Gerraty.endif
100*1d3f2ddcSSimon J. Gerraty
101*1d3f2ddcSSimon J. Gerraty#	a[^]b	matches 'a', then exactly 1 arbitrary character, then 'b'
102*1d3f2ddcSSimon J. Gerraty.if ${ ab a[]b a[b a b :L:Ma[^]b} != "a[b"
103*1d3f2ddcSSimon J. Gerraty.  error
104*1d3f2ddcSSimon J. Gerraty.endif
105*1d3f2ddcSSimon J. Gerraty
106*1d3f2ddcSSimon J. Gerraty#	[Nn0]	matches exactly 1 character from the set 'N', 'n', '0'
107*1d3f2ddcSSimon J. Gerraty.if ${ a b N n 0 Nn0 [ ] :L:M[Nn0]} != "N n 0"
108*1d3f2ddcSSimon J. Gerraty.  error
109*1d3f2ddcSSimon J. Gerraty.endif
110*1d3f2ddcSSimon J. Gerraty
111*1d3f2ddcSSimon J. Gerraty#	[a-c]	matches exactly 1 character from the range 'a' to 'c'
112*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d [a-c] [a] :L:M[a-c]} != "a b c"
113*1d3f2ddcSSimon J. Gerraty.  error
114*1d3f2ddcSSimon J. Gerraty.endif
115*1d3f2ddcSSimon J. Gerraty
116*1d3f2ddcSSimon J. Gerraty#	[c-a]	matches the same as [a-c]
117*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d [a-c] [a] :L:M[c-a]} != "a b c"
118*1d3f2ddcSSimon J. Gerraty.  error
119*1d3f2ddcSSimon J. Gerraty.endif
120*1d3f2ddcSSimon J. Gerraty
121*1d3f2ddcSSimon J. Gerraty#	[^a-c67]
122*1d3f2ddcSSimon J. Gerraty#		matches a single character, except for 'a', 'b', 'c', '6' or
123*1d3f2ddcSSimon J. Gerraty#		'7'
124*1d3f2ddcSSimon J. Gerraty.if ${ A B C a b c d 5 6 7 8 [a-c] [a] :L:M[^a-c67]} != "A B C d 5 8"
125*1d3f2ddcSSimon J. Gerraty.  error
126*1d3f2ddcSSimon J. Gerraty.endif
127*1d3f2ddcSSimon J. Gerraty
128*1d3f2ddcSSimon J. Gerraty#	:	terminates the pattern
129*1d3f2ddcSSimon J. Gerraty.if ${ A * :L:M:} != ""
130*1d3f2ddcSSimon J. Gerraty.  error
131*1d3f2ddcSSimon J. Gerraty.endif
132*1d3f2ddcSSimon J. Gerraty
133*1d3f2ddcSSimon J. Gerraty#	\:	matches a colon
134*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\: \:\:} :L:M\:} != ":"
135*1d3f2ddcSSimon J. Gerraty.  error
136*1d3f2ddcSSimon J. Gerraty.endif
137*1d3f2ddcSSimon J. Gerraty
138*1d3f2ddcSSimon J. Gerraty#	${:U\:}	matches a colon
139*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\:} ${:U\:\:} :L:M${:U\:}} != ":"
140*1d3f2ddcSSimon J. Gerraty.  error
141*1d3f2ddcSSimon J. Gerraty.endif
142*1d3f2ddcSSimon J. Gerraty
143*1d3f2ddcSSimon J. Gerraty#	[:]	matches never since the ':' starts the next modifier
144*1d3f2ddcSSimon J. Gerraty# expect+2: Unknown modifier "]"
145*1d3f2ddcSSimon J. Gerraty# expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
146*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":"
147*1d3f2ddcSSimon J. Gerraty.  error
148*1d3f2ddcSSimon J. Gerraty.else
149*1d3f2ddcSSimon J. Gerraty.  error
150*1d3f2ddcSSimon J. Gerraty.endif
151*1d3f2ddcSSimon J. Gerraty
152*1d3f2ddcSSimon J. Gerraty#	[\]	matches exactly a backslash; no escaping takes place in
153*1d3f2ddcSSimon J. Gerraty#		character ranges
154*1d3f2ddcSSimon J. Gerraty# Without the 'a' in the below expressions, the backslash would end a word and
155*1d3f2ddcSSimon J. Gerraty# thus influence how the string is split into words.
156*1d3f2ddcSSimon J. Gerraty.if ${ ${:U\\a} ${:U\\\\a} :L:M[\]a} != "\\a"
157*1d3f2ddcSSimon J. Gerraty.  error
158*1d3f2ddcSSimon J. Gerraty.endif
159*1d3f2ddcSSimon J. Gerraty
160*1d3f2ddcSSimon J. Gerraty#.MAKEFLAGS: -dcv
161*1d3f2ddcSSimon J. Gerraty#
162*1d3f2ddcSSimon J. Gerraty# Incomplete patterns:
163*1d3f2ddcSSimon J. Gerraty#	[	matches TODO
164*1d3f2ddcSSimon J. Gerraty#	[x	matches TODO
165*1d3f2ddcSSimon J. Gerraty#	[^	matches TODO
166*1d3f2ddcSSimon J. Gerraty#	[-	matches TODO
167*1d3f2ddcSSimon J. Gerraty#	[xy	matches TODO
168*1d3f2ddcSSimon J. Gerraty#	[^x	matches TODO
169*1d3f2ddcSSimon J. Gerraty#	[\	matches TODO
170*1d3f2ddcSSimon J. Gerraty#
171*1d3f2ddcSSimon J. Gerraty#	[x-	matches exactly 'x', doesn't match 'x-'
172*1d3f2ddcSSimon J. Gerraty#	[^x-	matches TODO
173*1d3f2ddcSSimon J. Gerraty#	\	matches never
174*1d3f2ddcSSimon J. Gerraty
175*1d3f2ddcSSimon J. Gerraty
176*1d3f2ddcSSimon J. Gerraty# The modifier ':tW' prevents splitting at whitespace.  Even leading and
177*1d3f2ddcSSimon J. Gerraty# trailing whitespace is preserved.
178*1d3f2ddcSSimon J. Gerraty.if ${   plain   string   :L:tW:M*} != "   plain   string   "
179*1d3f2ddcSSimon J. Gerraty.  error
180*1d3f2ddcSSimon J. Gerraty.endif
181*1d3f2ddcSSimon J. Gerraty
182*1d3f2ddcSSimon J. Gerraty# Without the modifier ':tW', the string is split into words.  All whitespace
183*1d3f2ddcSSimon J. Gerraty# around and between the words is normalized to a single space.
184*1d3f2ddcSSimon J. Gerraty.if ${   plain    string   :L:M*} != "plain string"
185*1d3f2ddcSSimon J. Gerraty.  error
186*1d3f2ddcSSimon J. Gerraty.endif
187