1# $NetBSD: varmod-to-separator.mk,v 1.12 2023/06/01 20:56:35 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 6WORDS= 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 variable 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: 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: 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# Negative numbers are not allowed for the separator character. 178# expect+1: Malformed conditional (${WORDS:[1..3]:ts\-300:tu}) 179.if ${WORDS:[1..3]:ts\-300:tu} 180. warning The separator \-300 is accepted even though it is negative. 181.else 182. warning The separator \-300 is accepted even though it is negative. 183.endif 184 185# The character number is interpreted as octal number by default. 186# The digit '8' is not an octal digit though. 187# expect+1: Malformed conditional (${1 2 3:L:ts\8:tu}) 188.if ${1 2 3:L:ts\8:tu} 189. warning The separator \8 is accepted even though it is not octal. 190.else 191. warning The separator \8 is accepted even though it is not octal. 192.endif 193 194# Trailing characters after the octal character number are rejected. 195# expect+1: Malformed conditional (${1 2 3:L:ts\100L}) 196.if ${1 2 3:L:ts\100L} 197. warning The separator \100L is accepted even though it contains an 'L'. 198.else 199. warning The separator \100L is accepted even though it contains an 'L'. 200.endif 201 202# Trailing characters after the hexadecimal character number are rejected. 203# expect+1: Malformed conditional (${1 2 3:L:ts\x40g}) 204.if ${1 2 3:L:ts\x40g} 205. warning The separator \x40g is accepted even though it contains a 'g'. 206.else 207. warning The separator \x40g is accepted even though it contains a 'g'. 208.endif 209 210 211# In the :t modifier, the :t must be followed by any of A, l, s, u. 212# expect: make: Bad modifier ":tx" for variable "WORDS" 213# expect+1: Malformed conditional (${WORDS:tx}) 214.if ${WORDS:tx} 215. error 216.else 217. error 218.endif 219 220# The word separator can only be a single character. 221# expect: make: Bad modifier ":ts\X" for variable "WORDS" 222# expect+1: Malformed conditional (${WORDS:ts\X}) 223.if ${WORDS:ts\X} 224. error 225.else 226. error 227.endif 228 229# After the backslash, only n, t, an octal number, or x and a hexadecimal 230# number are allowed. 231# expect+1: Malformed conditional (${WORDS:t\X} != "anything") 232.if ${WORDS:t\X} != "anything" 233. info This line is not reached. 234.endif 235 236 237# Since 2003.07.23.18.06.46 and before 2016.03.07.20.20.35, the modifier ':ts' 238# interpreted an "octal escape" as decimal if the first digit was not '0'. 239.if ${:Ua b:ts\61} != "a1b" # decimal would have been "a=b" 240. error 241.endif 242 243# Since the character escape is always interpreted as octal, let's see what 244# happens for non-octal digits. From 2003.07.23.18.06.46 to 245# 2016.02.27.16.20.06, the result was '1E2', since 2016.03.07.20.20.35 make no 246# longer accepts this escape and complains. 247# expect: make: Bad modifier ":ts\69" for variable "" 248# expect+1: Malformed conditional (${:Ua b:ts\69}) 249.if ${:Ua b:ts\69} 250. error 251.else 252. error 253.endif 254 255# Try whether bmake is Unicode-ready. 256# expect+2: Invalid character number at "1F60E}" 257# expect+1: Malformed conditional (${:Ua b:ts\x1F60E}) 258.if ${:Ua b:ts\x1F60E} # U+1F60E "smiling face with sunglasses" 259. error 260.else 261. error 262.endif 263