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