varmod-subst-regex.mk revision 1.6 1 1.6 rillig # $NetBSD: varmod-subst-regex.mk,v 1.6 2020/12/05 18:13:44 rillig Exp $
2 1.1 rillig #
3 1.2 rillig # Tests for the :C,from,to, variable modifier.
4 1.1 rillig
5 1.3 rillig all: mod-regex-compile-error
6 1.2 rillig all: mod-regex-limits
7 1.2 rillig all: mod-regex-errors
8 1.1 rillig
9 1.3 rillig # The variable expression expands to 4 words. Of these words, none matches
10 1.3 rillig # the regular expression "a b" since these words don't contain any
11 1.3 rillig # whitespace.
12 1.3 rillig .if ${:Ua b b c:C,a b,,} != "a b b c"
13 1.4 rillig . error
14 1.3 rillig .endif
15 1.2 rillig
16 1.3 rillig # Using the '1' modifier does not change anything. The '1' modifier just
17 1.3 rillig # means to apply at most 1 replacement in the whole variable expression.
18 1.3 rillig .if ${:Ua b b c:C,a b,,1} != "a b b c"
19 1.4 rillig . error
20 1.3 rillig .endif
21 1.3 rillig
22 1.3 rillig # The 'W' modifier treats the whole variable value as a single big word,
23 1.3 rillig # containing whitespace. This big word matches the regular expression,
24 1.3 rillig # therefore it gets replaced. Whitespace is preserved after replacing.
25 1.3 rillig .if ${:Ua b b c:C,a b,,W} != " b c"
26 1.4 rillig . error
27 1.3 rillig .endif
28 1.3 rillig
29 1.3 rillig # The 'g' modifier does not have any effect here since each of the words
30 1.3 rillig # contains the character 'b' a single time.
31 1.3 rillig .if ${:Ua b b c:C,b,,g} != "a c"
32 1.4 rillig . error
33 1.3 rillig .endif
34 1.3 rillig
35 1.3 rillig # The first :C modifier has the 'W' modifier, which makes the whole
36 1.3 rillig # expression a single word. The 'g' modifier then replaces all occurrences
37 1.3 rillig # of "1 2" with "___". The 'W' modifier only applies to this single :C
38 1.3 rillig # modifier. This is demonstrated by the :C modifier that follows. If the
39 1.3 rillig # 'W' modifier would be preserved, only a single underscore would have been
40 1.3 rillig # replaced with an 'x'.
41 1.3 rillig .if ${:U1 2 3 1 2 3:C,1 2,___,Wg:C,_,x,} != "x__ 3 x__ 3"
42 1.4 rillig . error
43 1.3 rillig .endif
44 1.3 rillig
45 1.3 rillig # The regular expression does not match in the first word.
46 1.3 rillig # It matches once in the second word, and the \0\0 doubles that word.
47 1.3 rillig # In the third word, the regular expression matches as early as possible,
48 1.3 rillig # and since the matches must not overlap, the next possible match would
49 1.3 rillig # start at the 6, but at that point, there is only one character left,
50 1.3 rillig # and that cannot match the regular expression "..". Therefore only the
51 1.5 rillig # "45" is doubled in the third word.
52 1.3 rillig .if ${:U1 23 456:C,..,\0\0,} != "1 2323 45456"
53 1.4 rillig . error
54 1.3 rillig .endif
55 1.3 rillig
56 1.3 rillig # The modifier '1' applies the replacement at most once, across the whole
57 1.5 rillig # expression value, no matter whether it is a single big word or many small
58 1.3 rillig # words.
59 1.3 rillig #
60 1.3 rillig # Up to 2020-08-28, the manual page said that the modifiers '1' and 'g'
61 1.5 rillig # were orthogonal, which was wrong. It doesn't make sense to specify both
62 1.5 rillig # 'g' and '1' at the same time.
63 1.3 rillig .if ${:U12345 12345:C,.,\0\0,1} != "112345 12345"
64 1.4 rillig . error
65 1.3 rillig .endif
66 1.3 rillig
67 1.5 rillig # A regular expression that matches the empty string applies before every
68 1.5 rillig # single character of the word.
69 1.5 rillig # XXX: Most other places where regular expression are used match at the end
70 1.5 rillig # of the string as well.
71 1.5 rillig .if ${:U1a2b3c:C,a*,*,g} != "*1**2*b*3*c"
72 1.5 rillig . error
73 1.5 rillig .endif
74 1.5 rillig
75 1.5 rillig # A dot in the regular expression matches any character, even a newline.
76 1.5 rillig # In most other contexts where regular expressions are used, a dot matches
77 1.5 rillig # any character except newline. In make, regcomp is called without
78 1.5 rillig # REG_NEWLINE, thus newline is an ordinary character.
79 1.5 rillig .if ${:U"${.newline}":C,.,.,g} != "..."
80 1.5 rillig . error
81 1.5 rillig .endif
82 1.5 rillig
83 1.3 rillig # Multiple asterisks form an invalid regular expression. This produces an
84 1.3 rillig # error message and (as of 2020-08-28) stops parsing in the middle of the
85 1.3 rillig # variable expression. The unparsed part of the expression is then copied
86 1.3 rillig # verbatim to the output, which is unexpected and can lead to strange shell
87 1.3 rillig # commands being run.
88 1.3 rillig mod-regex-compile-error:
89 1.3 rillig @echo $@: ${:Uword1 word2:C,****,____,g:C,word,____,:Q}.
90 1.3 rillig
91 1.3 rillig # These tests generate error messages but as of 2020-08-28 just continue
92 1.3 rillig # parsing and execution as if nothing bad had happened.
93 1.2 rillig mod-regex-limits:
94 1.2 rillig @echo $@:11-missing:${:U1 23 456:C,..,\1\1,:Q}
95 1.2 rillig @echo $@:11-ok:${:U1 23 456:C,(.).,\1\1,:Q}
96 1.2 rillig @echo $@:22-missing:${:U1 23 456:C,..,\2\2,:Q}
97 1.2 rillig @echo $@:22-missing:${:U1 23 456:C,(.).,\2\2,:Q}
98 1.2 rillig @echo $@:22-ok:${:U1 23 456:C,(.)(.),\2\2,:Q}
99 1.2 rillig # The :C modifier only handles single-digit capturing groups,
100 1.2 rillig # which is more than enough for daily use.
101 1.2 rillig @echo $@:capture:${:UabcdefghijABCDEFGHIJrest:C,(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.),\9\8\7\6\5\4\3\2\1\0\10\11\12,}
102 1.2 rillig
103 1.2 rillig mod-regex-errors:
104 1.2 rillig @echo $@: ${UNDEF:Uvalue:C,[,,}
105 1.6 rillig
106 1.6 rillig # If the replacement pattern produces a parse error because of an
107 1.6 rillig # unknown modifier, the parse error is ignored in ParseModifierPart
108 1.6 rillig # and the faulty variable expression expands to "".
109 1.6 rillig @echo $@: ${word:L:C,.*,x${:U:Z}y,W}
110