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