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