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