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