1# $NetBSD: varmod-subst.mk,v 1.8 2021/05/14 19:37:16 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 89mod-subst: 90 @echo $@: 91 @echo :${:Ua b b c:S,a b,,:Q}: 92 @echo :${:Ua b b c:S,a b,,1:Q}: 93 @echo :${:Ua b b c:S,a b,,W:Q}: 94 @echo :${:Ua b b c:S,b,,g:Q}: 95 @echo :${:U1 2 3 1 2 3:S,1 2,___,Wg:S,_,x,:Q}: 96 @echo ${:U12345:S,,sep,g:Q} 97 98# The :S and :C modifiers accept an arbitrary character as the delimiter, 99# including characters that are otherwise used as escape characters or 100# interpreted in a special way. This can be used to confuse humans. 101mod-subst-delimiter: 102 @echo $@: 103 @echo ${:U1 2 3:S 2 two :Q} horizontal tabulator 104 @echo ${:U1 2 3:S 2 two :Q} space 105 @echo ${:U1 2 3:S!2!two!:Q} exclamation mark 106 @echo ${:U1 2 3:S"2"two":Q} quotation mark 107 # In shell command lines, the hash does not need to be escaped. 108 # It needs to be escaped in variable assignment lines though. 109 @echo ${:U1 2 3:S#2#two#:Q} number sign 110 @echo ${:U1 2 3:S$2$two$:Q} dollar sign 111 @echo ${:U1 2 3:S%2%two%:Q} percent sign 112 @echo ${:U1 2 3:S&2&two&:Q} ampersand 113 @echo ${:U1 2 3:S'2'two':Q} apostrophe 114 @echo ${:U1 2 3:S(2(two(:Q} left parenthesis 115 @echo ${:U1 2 3:S)2)two):Q} right parenthesis 116 @echo ${:U1 2 3:S*2*two*:Q} asterisk 117 @echo ${:U1 2 3:S+2+two+:Q} plus sign 118 @echo ${:U1 2 3:S,2,two,:Q} comma 119 @echo ${:U1 2 3:S-2-two-:Q} hyphen-minus 120 @echo ${:U1 2 3:S.2.two.:Q} full stop 121 @echo ${:U1 2 3:S/2/two/:Q} solidus 122 @echo ${:U1 2 3:S121two1:Q} digit 123 @echo ${:U1 2 3:S:2:two::Q} colon 124 @echo ${:U1 2 3:S;2;two;:Q} semicolon 125 @echo ${:U1 2 3:S<2<two<:Q} less-than sign 126 @echo ${:U1 2 3:S=2=two=:Q} equals sign 127 @echo ${:U1 2 3:S>2>two>:Q} greater-than sign 128 @echo ${:U1 2 3:S?2?two?:Q} question mark 129 @echo ${:U1 2 3:S@2@two@:Q} commercial at 130 @echo ${:U1 2 3:SA2AtwoA:Q} capital letter 131 @echo ${:U1 2 3:S[2[two[:Q} left square bracket 132 @echo ${:U1 2 3:S\2\two\:Q} reverse solidus 133 @echo ${:U1 2 3:S]2]two]:Q} right square bracket 134 @echo ${:U1 2 3:S^2^two^:Q} circumflex accent 135 @echo ${:U1 2 3:S_2_two_:Q} low line 136 @echo ${:U1 2 3:S`2`two`:Q} grave accent 137 @echo ${:U1 2 3:Sa2atwoa:Q} small letter 138 @echo ${:U1 2 3:S{2{two{:Q} left curly bracket 139 @echo ${:U1 2 3:S|2|two|:Q} vertical line 140 @echo ${:U1 2 3:S}2}two}:Q} right curly bracket 141 @echo ${:U1 2 3:S~2~two~:Q} tilde 142 143# The :S and :C modifiers can be chained without a separating ':'. 144# This is not documented in the manual page. 145# It works because ApplyModifier_Subst scans for the known modifiers g1W 146# and then just returns to ApplyModifiers. There, the colon is optionally 147# skipped (see the *st.next == ':' at the end of the loop). 148# 149# Most other modifiers cannot be chained since their parsers skip until 150# the next ':' or '}' or ')'. 151mod-subst-chain: 152 @echo $@: 153 @echo ${:Ua b c:S,a,A,S,b,B,}. 154 # There is no 'i' modifier for the :S or :C modifiers. 155 # The error message is "make: Unknown modifier 'i'", which is 156 # kind of correct, although it is mixing the terms for variable 157 # modifiers with the matching modifiers. 158 @echo ${:Uvalue:S,a,x,i}. 159 160# No matter how many dollar signs there are, they all get merged 161# into a single dollar by the :S modifier. 162# 163# As of 2020-08-09, this is because ParseModifierPart sees a '$' and 164# calls Var_Parse to expand the variable. In all other places, the "$$" 165# is handled outside of Var_Parse. Var_Parse therefore considers "$$" 166# one of the "really stupid names", skips the first dollar, and parsing 167# continues with the next character. This repeats for the other dollar 168# signs, except the one before the delimiter. That one is handled by 169# the code that optionally interprets the '$' as the end-anchor in the 170# first part of the :S modifier. That code doesn't call Var_Parse but 171# simply copies the dollar to the result. 172mod-subst-dollar: 173 @echo $@:${:U1:S,^,$,:Q}: 174 @echo $@:${:U2:S,^,$$,:Q}: 175 @echo $@:${:U3:S,^,$$$,:Q}: 176 @echo $@:${:U4:S,^,$$$$,:Q}: 177 @echo $@:${:U5:S,^,$$$$$,:Q}: 178 @echo $@:${:U6:S,^,$$$$$$,:Q}: 179 @echo $@:${:U7:S,^,$$$$$$$,:Q}: 180 @echo $@:${:U8:S,^,$$$$$$$$,:Q}: 181 @echo $@:${:U40:S,^,$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$,:Q}: 182# This generates no dollar at all: 183 @echo $@:${:UU8:S,^,${:U$$$$$$$$},:Q}: 184# Here is an alternative way to generate dollar signs. 185# It's unexpectedly complicated though. 186 @echo $@:${:U:range=5:ts\x24:C,[0-9],,g:Q}: 187# In modifiers, dollars are escaped using the backslash, not using another 188# dollar sign. Therefore, creating a dollar sign is pretty simple: 189 @echo $@:${:Ugood3:S,^,\$\$\$,:Q} 190