varmod.mk revision 1.6 1 # $NetBSD: varmod.mk,v 1.6 2022/08/06 07:06:58 rillig Exp $
2 #
3 # Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback.
4
5 # As of 2022-08-06, the possible behaviors during parsing are:
6 #
7 # * `strict`: the parsing style used by most modifiers:
8 # * either uses `ParseModifierPart` or parses the modifier literal
9 # * other modifiers may follow, separated by a ':'
10 #
11 # * `greedy`: calls `ParseModifierPart` with `ch->endc`; this means
12 # that no further modifiers are parsed in that expression.
13 #
14 # * `no-colon`: after parsing this modifier, the following modifier
15 # does not need to be separated by a colon.
16 # Omitting this colon is bad style.
17 #
18 # * `individual`: parsing this modifier does not follow the common
19 # pattern of calling `ParseModifierPart`.
20 #
21 # The SysV column says whether a parse error in the modifier falls back
22 # trying the `:from=to` System V modifier.
23 #
24 # | **Operator** | **Behavior** | **Remarks** | **SysV** |
25 # |--------------|--------------|--------------------|----------|
26 # | `!` | no-colon | | no |
27 # | `:=` | greedy | | yes |
28 # | `?:` | greedy | | no |
29 # | `@` | no-colon | | no |
30 # | `C` | no-colon | | no |
31 # | `D` | individual | custom parser | N/A |
32 # | `E` | strict | | yes |
33 # | `H` | strict | | yes |
34 # | `L` | no-colon | | N/A |
35 # | `M` | individual | custom parser | N/A |
36 # | `N` | individual | custom parser | N/A |
37 # | `O` | strict | only literal value | no |
38 # | `P` | no-colon | | N/A |
39 # | `Q` | strict | | yes |
40 # | `R` | strict | | yes |
41 # | `S` | no-colon | | N/A |
42 # | `T` | strict | | N/A |
43 # | `U` | individual | custom parser | N/A |
44 # | `[` | strict | | no |
45 # | `_` | individual | strcspn | yes |
46 # | `gmtime` | strict | only literal value | yes |
47 # | `hash` | strict | | N/A |
48 # | `localtime` | strict | only literal value | yes |
49 # | `q` | strict | | yes |
50 # | `range` | strict | | N/A |
51 # | `sh` | strict | | N/A |
52 # | `t` | strict | | no |
53 # | `u` | strict | | yes |
54 # | `from=to` | greedy | SysV, fallback | N/A |
55
56 DOLLAR1= $$
57 DOLLAR2= ${:U\$}
58
59 # To get a single '$' sign in the value of a variable expression, it has to
60 # be written as '$$' in a literal variable value.
61 #
62 # See Var_Parse, where it calls Var_Subst.
63 .if ${DOLLAR1} != "\$"
64 . error
65 .endif
66
67 # Another way to get a single '$' sign is to use the :U modifier. In the
68 # argument of that modifier, a '$' is escaped using the backslash instead.
69 #
70 # See Var_Parse, where it calls Var_Subst.
71 .if ${DOLLAR2} != "\$"
72 . error
73 .endif
74
75 # It is also possible to use the :U modifier directly in the expression.
76 #
77 # See Var_Parse, where it calls Var_Subst.
78 .if ${:U\$} != "\$"
79 . error
80 .endif
81
82 # XXX: As of 2020-09-13, it is not possible to use '$$' in a variable name
83 # to mean a single '$'. This contradicts the manual page, which says that
84 # '$' can be escaped as '$$'.
85 .if ${$$:L} != ""
86 . error
87 .endif
88
89 # In lint mode, make prints helpful error messages.
90 # For compatibility, make does not print these error messages in normal mode.
91 # Should it?
92 .MAKEFLAGS: -dL
93 .if ${$$:L} != ""
94 . error
95 .endif
96
97 # A '$' followed by nothing is an error as well.
98 .if ${:Uword:@word@${word}$@} != "word"
99 . error
100 .endif
101
102 # The variable modifier :P does not fall back to the SysV modifier.
103 # Therefore the modifier :P=RE generates a parse error.
104 # XXX: The .error should not be reached since the variable expression is
105 # malformed, and this error should be propagated up to Cond_EvalLine.
106 VAR= STOP
107 .if ${VAR:P=RE} != "STORE"
108 . error
109 .endif
110
111 all: # nothing
112