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