xref: /netbsd-src/usr.bin/make/unit-tests/varmod-subst.mk (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1# $NetBSD: varmod-subst.mk,v 1.2 2020/08/16 12:30:45 rillig Exp $
2#
3# Tests for the :S,from,to, variable modifier.
4
5all: mod-subst
6all: mod-subst-delimiter
7all: mod-subst-chain
8all: mod-subst-dollar
9
10WORDS=		sequences of letters
11.if ${WORDS:S,,,} != ${WORDS}
12.warning The empty pattern matches something.
13.endif
14.if ${WORDS:S,e,*,1} != "s*quences of letters"
15.warning The :S modifier flag '1' is not applied exactly once.
16.endif
17.if ${WORDS:S,e,*,} != "s*quences of l*tters"
18.warning The :S modifier does not replace every first match per word.
19.endif
20.if ${WORDS:S,e,*,g} != "s*qu*nc*s of l*tt*rs"
21.warning The :S modifier flag 'g' does not replace every occurrence.
22.endif
23.if ${WORDS:S,^sequ,occurr,} != "occurrences of letters"
24.warning The :S modifier fails for a short match anchored at the start.
25.endif
26.if ${WORDS:S,^of,with,} != "sequences with letters"
27.warning The :S modifier fails for an exact match anchored at the start.
28.endif
29.if ${WORDS:S,^office,does not match,} != ${WORDS}
30.warning The :S modifier matches a too long pattern anchored at the start.
31.endif
32.if ${WORDS:S,f$,r,} != "sequences or letters"
33.warning The :S modifier fails for a short match anchored at the end.
34.endif
35.if ${WORDS:S,s$,,} != "sequence of letter"
36.warning The :S modifier fails to replace one occurrence per word.
37.endif
38.if ${WORDS:S,of$,,} != "sequences letters"
39.warning The :S modifier fails for an exact match anchored at the end.
40.endif
41.if ${WORDS:S,eof$,,} != ${WORDS}
42.warning The :S modifier matches a too long pattern anchored at the end.
43.endif
44.if ${WORDS:S,^of$,,} != "sequences letters"
45.warning The :S modifier does not match a word anchored at both ends.
46.endif
47.if ${WORDS:S,^o$,,} != ${WORDS}
48.warning The :S modifier matches a prefix anchored at both ends.
49.endif
50.if ${WORDS:S,^f$,,} != ${WORDS}
51.warning The :S modifier matches a suffix anchored at both ends.
52.endif
53.if ${WORDS:S,^eof$,,} != ${WORDS}
54.warning The :S modifier matches a too long prefix anchored at both ends.
55.endif
56.if ${WORDS:S,^office$,,} != ${WORDS}
57.warning The :S modifier matches a too long suffix anchored at both ends.
58.endif
59
60mod-subst:
61	@echo $@:
62	@echo :${:Ua b b c:S,a b,,:Q}:
63	@echo :${:Ua b b c:S,a b,,1:Q}:
64	@echo :${:Ua b b c:S,a b,,W:Q}:
65	@echo :${:Ua b b c:S,b,,g:Q}:
66	@echo :${:U1 2 3 1 2 3:S,1 2,___,Wg:S,_,x,:Q}:
67	@echo ${:U12345:S,,sep,g:Q}
68
69# The :S and :C modifiers accept an arbitrary character as the delimiter,
70# including characters that are otherwise used as escape characters or
71# interpreted in a special way.  This can be used to confuse humans.
72mod-subst-delimiter:
73	@echo $@:
74	@echo ${:U1 2 3:S	2	two	:Q} horizontal tabulator
75	@echo ${:U1 2 3:S 2 two :Q} space
76	@echo ${:U1 2 3:S!2!two!:Q} exclamation mark
77	@echo ${:U1 2 3:S"2"two":Q} double quotes
78	# In shell command lines, the hash does not need to be escaped.
79	# It needs to be escaped in variable assignment lines though.
80	@echo ${:U1 2 3:S#2#two#:Q} hash
81	@echo ${:U1 2 3:S$2$two$:Q} dollar
82	@echo ${:U1 2 3:S%2%two%:Q} percent
83	@echo ${:U1 2 3:S'2'two':Q} apostrophe
84	@echo ${:U1 2 3:S(2(two(:Q} opening parenthesis
85	@echo ${:U1 2 3:S)2)two):Q} closing parenthesis
86	@echo ${:U1 2 3:S121two1:Q} digit
87	@echo ${:U1 2 3:S:2:two::Q} colon
88	@echo ${:U1 2 3:S<2<two<:Q} less than sign
89	@echo ${:U1 2 3:S=2=two=:Q} equal sign
90	@echo ${:U1 2 3:S>2>two>:Q} greater than sign
91	@echo ${:U1 2 3:S?2?two?:Q} question mark
92	@echo ${:U1 2 3:S@2@two@:Q} at
93	@echo ${:U1 2 3:Sa2atwoa:Q} letter
94	@echo ${:U1 2 3:S[2[two[:Q} opening bracket
95	@echo ${:U1 2 3:S\2\two\:Q} backslash
96	@echo ${:U1 2 3:S]2]two]:Q} closing bracket
97	@echo ${:U1 2 3:S^2^two^:Q} caret
98	@echo ${:U1 2 3:S{2{two{:Q} opening brace
99	@echo ${:U1 2 3:S|2|two|:Q} vertical line
100	@echo ${:U1 2 3:S}2}two}:Q} closing brace
101	@echo ${:U1 2 3:S~2~two~:Q} tilde
102
103# The :S and :C modifiers can be chained without a separating ':'.
104# This is not documented in the manual page.
105# It works because ApplyModifier_Subst scans for the known modifiers g1W
106# and then just returns to ApplyModifiers.  There, the colon is optionally
107# skipped (see the *st.next == ':' at the end of the loop).
108#
109# Most other modifiers cannot be chained since their parsers skip until
110# the next ':' or '}' or ')'.
111mod-subst-chain:
112	@echo $@:
113	@echo ${:Ua b c:S,a,A,S,b,B,}.
114	# There is no 'i' modifier for the :S or :C modifiers.
115	# The error message is "make: Unknown modifier 'i'", which is
116	# kind of correct, although it is mixing the terms for variable
117	# modifiers with the matching modifiers.
118	@echo ${:Uvalue:S,a,x,i}.
119
120# No matter how many dollar characters there are, they all get merged
121# into a single dollar by the :S modifier.
122#
123# As of 2020-08-09, this is because ParseModifierPart sees a '$' and
124# calls Var_Parse to expand the variable.  In all other places, the "$$"
125# is handled outside of Var_Parse.  Var_Parse therefore considers "$$"
126# one of the "really stupid names", skips the first dollar, and parsing
127# continues with the next character.  This repeats for the other dollar
128# signs, except the one before the delimiter.  That one is handled by
129# the code that optionally interprets the '$' as the end-anchor in the
130# first part of the :S modifier.  That code doesn't call Var_Parse but
131# simply copies the dollar to the result.
132mod-subst-dollar:
133	@echo $@:${:U1:S,^,$,:Q}:
134	@echo $@:${:U2:S,^,$$,:Q}:
135	@echo $@:${:U3:S,^,$$$,:Q}:
136	@echo $@:${:U4:S,^,$$$$,:Q}:
137	@echo $@:${:U5:S,^,$$$$$,:Q}:
138	@echo $@:${:U6:S,^,$$$$$$,:Q}:
139	@echo $@:${:U7:S,^,$$$$$$$,:Q}:
140	@echo $@:${:U8:S,^,$$$$$$$$,:Q}:
141	@echo $@:${:U40:S,^,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$,:Q}:
142# This generates no dollar at all:
143	@echo $@:${:UU8:S,^,${:U$$$$$$$$},:Q}:
144# Here is an alternative way to generate dollar characters.
145# It's unexpectedly complicated though.
146	@echo $@:${:U:range=5:ts\x24:C,[0-9],,g:Q}:
147# In modifiers, dollars are escaped using the backslash, not using another
148# dollar sign.  Therefore, creating a dollar sign is pretty simple:
149	@echo $@:${:Ugood3:S,^,\$\$\$,:Q}
150