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