Home | History | Annotate | Line # | Download | only in unit-tests
varmod-to-separator.mk revision 1.15
      1 # $NetBSD: varmod-to-separator.mk,v 1.15 2024/06/01 18:44:05 rillig Exp $
      2 #
      3 # Tests for the :ts variable modifier, which joins the words of the variable
      4 # using an arbitrary character as word separator.
      5 
      6 WORDS=	one two three four five six
      7 
      8 # The words are separated by a single space, just as usual.
      9 .if ${WORDS:ts } != "one two three four five six"
     10 .  warning Space as separator does not work.
     11 .endif
     12 
     13 # The separator can be an arbitrary character, for example a comma.
     14 .if ${WORDS:ts,} != "one,two,three,four,five,six"
     15 .  warning Comma as separator does not work.
     16 .endif
     17 
     18 # After the :ts modifier, other modifiers can follow.
     19 .if ${WORDS:ts/:tu} != "ONE/TWO/THREE/FOUR/FIVE/SIX"
     20 .  warning Chaining modifiers does not work.
     21 .endif
     22 
     23 # To use the ':' as the separator, just write it normally.
     24 # The first colon is the separator, the second ends the modifier.
     25 .if ${WORDS:ts::tu} != "ONE:TWO:THREE:FOUR:FIVE:SIX"
     26 .  warning Colon as separator does not work.
     27 .endif
     28 
     29 # When there is just a colon but no other character, the words are
     30 # "separated" by an empty string, that is, they are all squashed
     31 # together.
     32 .if ${WORDS:ts:tu} != "ONETWOTHREEFOURFIVESIX"
     33 .  warning Colon as separator does not work.
     34 .endif
     35 
     36 # Applying the :tu modifier first and then the :ts modifier does not change
     37 # anything since neither of these modifiers is related to how the string is
     38 # split into words.  Beware of separating the words using a single or double
     39 # quote though, or other special characters like dollar or backslash.
     40 #
     41 # This example also demonstrates that the closing brace is not interpreted
     42 # as a separator, but as the closing delimiter of the whole
     43 # expression.
     44 .if ${WORDS:tu:ts} != "ONETWOTHREEFOURFIVESIX"
     45 .  warning Colon as separator does not work.
     46 .endif
     47 
     48 # The '}' plays the same role as the ':' in the preceding examples.
     49 # Since there is a single character before it, that character is taken as
     50 # the separator.
     51 .if ${WORDS:tu:ts/} != "ONE/TWO/THREE/FOUR/FIVE/SIX"
     52 .  warning Colon as separator does not work.
     53 .endif
     54 
     55 # Now it gets interesting and ambiguous:  The separator could either be empty
     56 # since it is followed by a colon.  Or it could be the colon since that
     57 # colon is followed by the closing brace.  It's the latter case.
     58 .if ${WORDS:ts:} != "one:two:three:four:five:six"
     59 .  warning Colon followed by closing brace does not work.
     60 .endif
     61 
     62 # As in the ${WORDS:tu:ts} example above, the separator is empty.
     63 .if ${WORDS:ts} != "onetwothreefourfivesix"
     64 .  warning Empty separator before closing brace does not work.
     65 .endif
     66 
     67 # The :ts modifier can be followed by other modifiers.
     68 .if ${WORDS:ts:S/two/2/} != "one2threefourfivesix"
     69 .  warning Separator followed by :S modifier does not work.
     70 .endif
     71 
     72 # The :ts modifier can follow other modifiers.
     73 .if ${WORDS:S/two/2/:ts} != "one2threefourfivesix"
     74 .  warning :S modifier followed by :ts modifier does not work.
     75 .endif
     76 
     77 # The :ts modifier with an actual separator can be followed by other
     78 # modifiers.
     79 .if ${WORDS:ts/:S/two/2/} != "one/2/three/four/five/six"
     80 .  warning The :ts modifier followed by an :S modifier does not work.
     81 .endif
     82 
     83 # After the modifier ':ts/', the expression value is a single word since all
     84 # spaces have been replaced with '/'.  This single word does not start with
     85 # 'two', which makes the modifier ':S' a no-op.
     86 .if ${WORDS:ts/:S/^two/2/} != "one/two/three/four/five/six"
     87 .  error
     88 .endif
     89 
     90 # After the :ts modifier, the whole string is interpreted as a single
     91 # word since all spaces have been replaced with x.  Because of this single
     92 # word, only the first 'b' is replaced with 'B'.
     93 .if ${aa bb aa bb aa bb:L:tsx:S,b,B,} != "aaxBbxaaxbbxaaxbb"
     94 .  error
     95 .endif
     96 
     97 # The :ts modifier also applies to word separators that are added
     98 # afterwards.  First, the modifier ':tsx' joins the 3 words, then the modifier
     99 # ':S' replaces the 2 'b's with spaces.  These spaces are part of the word,
    100 # so when the words are joined at the end of the modifier ':S', there is only
    101 # a single word, and the custom separator from the modifier ':tsx' has no
    102 # effect.
    103 .if ${a ababa c:L:tsx:S,b, ,g} != "axa a axc"
    104 .  error
    105 .endif
    106 
    107 # Adding the modifier ':M*' at the end of the above chain splits the
    108 # expression value and then joins it again.  At this point of splitting, the
    109 # newly added spaces are treated as word separators, resulting in 3 words.
    110 # When these 3 words are joined, the separator from the modifier ':tsx' is
    111 # used.
    112 .if ${a ababa c:L:tsx:S,b, ,g:M*} != "axaxaxaxc"
    113 .  error
    114 .endif
    115 
    116 # Not all modifiers use the separator from the previous modifier ':ts' though.
    117 # The modifier ':@' always uses a space as word separator instead.  This has
    118 # probably been an oversight during implementation.  For consistency, the
    119 # result should rather be "axaxaxaxc", as in the previous example.
    120 .if ${a ababa c:L:tsx:S,b, ,g:@v@$v@} != "axa a axc"
    121 .  error
    122 .endif
    123 
    124 # Adding a final :M* modifier applies the :ts separator again, though.
    125 .if ${a ababa c:L:tsx:S,b, ,g:@v@${v}@:M*} != "axaxaxaxc"
    126 .  error
    127 .endif
    128 
    129 # The separator can be \n, which is a newline.
    130 .if ${WORDS:[1..3]:ts\n} != "one${.newline}two${.newline}three"
    131 .  warning The separator \n does not produce a newline.
    132 .endif
    133 
    134 # The separator can be \t, which is a tab.
    135 .if ${WORDS:[1..3]:ts\t} != "one	two	three"
    136 .  warning The separator \t does not produce a tab.
    137 .endif
    138 
    139 # The separator can be given as octal number.
    140 .if ${WORDS:[1..3]:ts\012:tu} != "ONE${.newline}TWO${.newline}THREE"
    141 .  warning The separator \012 is not interpreted in octal ASCII.
    142 .endif
    143 
    144 # The octal number can have as many digits as it wants.
    145 .if ${WORDS:[1..2]:ts\000000000000000000000000012:tu} != "ONE${.newline}TWO"
    146 .  warning The separator \012 cannot have many leading zeroes.
    147 .endif
    148 
    149 # The value of the separator character must not be outside the value space
    150 # for an unsigned character though.
    151 #
    152 # Since 2020-11-01, these out-of-bounds values are rejected.
    153 # expect+2: while evaluating variable "WORDS": Invalid character number at "400:tu}"
    154 # expect+1: Malformed conditional (${WORDS:[1..3]:ts\400:tu})
    155 .if ${WORDS:[1..3]:ts\400:tu}
    156 .  warning The separator \400 is accepted even though it is out of bounds.
    157 .else
    158 .  warning The separator \400 is accepted even though it is out of bounds.
    159 .endif
    160 
    161 # The separator can be given as hexadecimal number.
    162 .if ${WORDS:[1..3]:ts\xa:tu} != "ONE${.newline}TWO${.newline}THREE"
    163 .  warning The separator \xa is not interpreted in hexadecimal ASCII.
    164 .endif
    165 
    166 # The hexadecimal number must be in the range of an unsigned char.
    167 #
    168 # Since 2020-11-01, these out-of-bounds values are rejected.
    169 # expect+2: while evaluating variable "WORDS": Invalid character number at "100:tu}"
    170 # expect+1: Malformed conditional (${WORDS:[1..3]:ts\x100:tu})
    171 .if ${WORDS:[1..3]:ts\x100:tu}
    172 .  warning The separator \x100 is accepted even though it is out of bounds.
    173 .else
    174 .  warning The separator \x100 is accepted even though it is out of bounds.
    175 .endif
    176 
    177 # The number after ':ts\x' must be hexadecimal.
    178 # expect+2: while evaluating variable "word": Invalid character number at ",}"
    179 # expect+1: Malformed conditional (${word:L:ts\x,})
    180 .if ${word:L:ts\x,}
    181 .endif
    182 
    183 # The hexadecimal number must be in the range of 'unsigned long' on all
    184 # supported platforms.
    185 # expect+2: while evaluating variable "word": Invalid character number at "112233445566778899}"
    186 # expect+1: Malformed conditional (${word:L:ts\x112233445566778899})
    187 .if ${word:L:ts\x112233445566778899}
    188 .endif
    189 
    190 # Negative numbers are not allowed for the separator character.
    191 # expect+1: Malformed conditional (${WORDS:[1..3]:ts\-300:tu})
    192 .if ${WORDS:[1..3]:ts\-300:tu}
    193 .  warning The separator \-300 is accepted even though it is negative.
    194 .else
    195 .  warning The separator \-300 is accepted even though it is negative.
    196 .endif
    197 
    198 # The character number is interpreted as octal number by default.
    199 # The digit '8' is not an octal digit though.
    200 # expect+1: Malformed conditional (${1 2 3:L:ts\8:tu})
    201 .if ${1 2 3:L:ts\8:tu}
    202 .  warning The separator \8 is accepted even though it is not octal.
    203 .else
    204 .  warning The separator \8 is accepted even though it is not octal.
    205 .endif
    206 
    207 # Trailing characters after the octal character number are rejected.
    208 # expect+1: Malformed conditional (${1 2 3:L:ts\100L})
    209 .if ${1 2 3:L:ts\100L}
    210 .  warning The separator \100L is accepted even though it contains an 'L'.
    211 .else
    212 .  warning The separator \100L is accepted even though it contains an 'L'.
    213 .endif
    214 
    215 # Trailing characters after the hexadecimal character number are rejected.
    216 # expect+1: Malformed conditional (${1 2 3:L:ts\x40g})
    217 .if ${1 2 3:L:ts\x40g}
    218 .  warning The separator \x40g is accepted even though it contains a 'g'.
    219 .else
    220 .  warning The separator \x40g is accepted even though it contains a 'g'.
    221 .endif
    222 
    223 
    224 # In the :t modifier, the :t must be followed by any of A, l, s, u.
    225 # expect: make: Bad modifier ":tx" for variable "WORDS"
    226 # expect+1: Malformed conditional (${WORDS:tx})
    227 .if ${WORDS:tx}
    228 .  error
    229 .else
    230 .  error
    231 .endif
    232 
    233 # The word separator can only be a single character.
    234 # expect: make: Bad modifier ":ts\X" for variable "WORDS"
    235 # expect+1: Malformed conditional (${WORDS:ts\X})
    236 .if ${WORDS:ts\X}
    237 .  error
    238 .else
    239 .  error
    240 .endif
    241 
    242 # After the backslash, only n, t, an octal number, or x and a hexadecimal
    243 # number are allowed.
    244 # expect+1: Malformed conditional (${WORDS:t\X} != "anything")
    245 .if ${WORDS:t\X} != "anything"
    246 .  info This line is not reached.
    247 .endif
    248 
    249 
    250 # Since 2003.07.23.18.06.46 and before 2016.03.07.20.20.35, the modifier ':ts'
    251 # interpreted an "octal escape" as decimal if the first digit was not '0'.
    252 .if ${:Ua b:ts\61} != "a1b"	# decimal would have been "a=b"
    253 .  error
    254 .endif
    255 
    256 # Since the character escape is always interpreted as octal, let's see what
    257 # happens for non-octal digits.  From 2003.07.23.18.06.46 to
    258 # 2016.02.27.16.20.06, the result was '1E2', since 2016.03.07.20.20.35 make no
    259 # longer accepts this escape and complains.
    260 # expect: make: Bad modifier ":ts\69" for variable ""
    261 # expect+1: Malformed conditional (${:Ua b:ts\69})
    262 .if ${:Ua b:ts\69}
    263 .  error
    264 .else
    265 .  error
    266 .endif
    267 
    268 # Try whether bmake is Unicode-ready.
    269 # expect+2: while evaluating "${:Ua b:ts\x1F60E}": Invalid character number at "1F60E}"
    270 # expect+1: Malformed conditional (${:Ua b:ts\x1F60E})
    271 .if ${:Ua b:ts\x1F60E}		# U+1F60E "smiling face with sunglasses"
    272 .  error
    273 .else
    274 .  error
    275 .endif
    276