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