aboutsummaryrefslogtreecommitdiff
path: root/contrib/bmake/unit-tests/varmod.mk
blob: c749dfb9659d6af1f7f26b9bbafca7dbf5aafda4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# $NetBSD: varmod.mk,v 1.11 2024/04/20 10:18:56 rillig Exp $
#
# Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback.
#
# See also:
#	varparse-errors.mk

# As of 2022-08-06, the possible behaviors during parsing are:
#
# * `strict`: the parsing style used by most modifiers:
#   * either uses `ParseModifierPart` or parses the modifier literal
#   * other modifiers may follow, separated by a ':'
#
# * `greedy`: calls `ParseModifierPart` with `ch->endc`; this means
#   that no further modifiers are parsed in that expression.
#
# * `no-colon`: after parsing this modifier, the following modifier
#   does not need to be separated by a colon.
#   Omitting this colon is bad style.
#
# * `individual`: parsing this modifier does not follow the common
#   pattern of calling `ParseModifierPart`.
#
# The SysV column says whether a parse error in the modifier falls back
# trying the `:from=to` System V modifier.
#
# | **Operator** | **Behavior** | **Remarks**        | **SysV** |
# |--------------|--------------|--------------------|----------|
# | `!`          | no-colon     |                    | no       |
# | `:=`         | greedy       |                    | yes      |
# | `?:`         | greedy       |                    | no       |
# | `@`          | no-colon     |                    | no       |
# | `C`          | no-colon     |                    | no       |
# | `D`          | individual   | custom parser      | N/A      |
# | `E`          | strict       |                    | yes      |
# | `H`          | strict       |                    | yes      |
# | `L`          | no-colon     |                    | N/A      |
# | `M`          | individual   | custom parser      | N/A      |
# | `N`          | individual   | custom parser      | N/A      |
# | `O`          | strict       | only literal value | no       |
# | `P`          | no-colon     |                    | N/A      |
# | `Q`          | strict       |                    | yes      |
# | `R`          | strict       |                    | yes      |
# | `S`          | no-colon     |                    | N/A      |
# | `T`          | strict       |                    | N/A      |
# | `U`          | individual   | custom parser      | N/A      |
# | `[`          | strict       |                    | no       |
# | `_`          | individual   | strcspn            | yes      |
# | `gmtime`     | strict       | only literal value | yes      |
# | `hash`       | strict       |                    | N/A      |
# | `localtime`  | strict       | only literal value | yes      |
# | `q`          | strict       |                    | yes      |
# | `range`      | strict       |                    | N/A      |
# | `sh`         | strict       |                    | N/A      |
# | `t`          | strict       |                    | no       |
# | `u`          | strict       |                    | yes      |
# | `from=to`    | greedy       | SysV, fallback     | N/A      |

# These tests assume
.MAKE.SAVE_DOLLARS = yes

DOLLAR1=	$$
DOLLAR2=	${:U\$}

# To get a single '$' sign in the value of an expression, it has to
# be written as '$$' in a literal variable value.
#
# See Var_Parse, where it calls Var_Subst.
.if ${DOLLAR1} != "\$"
.  error
.endif

# Another way to get a single '$' sign is to use the :U modifier.  In the
# argument of that modifier, a '$' is escaped using the backslash instead.
#
# See Var_Parse, where it calls Var_Subst.
.if ${DOLLAR2} != "\$"
.  error
.endif

# It is also possible to use the :U modifier directly in the expression.
#
# See Var_Parse, where it calls Var_Subst.
.if ${:U\$} != "\$"
.  error
.endif

# XXX: As of 2020-09-13, it is not possible to use '$$' in a variable name
# to mean a single '$'.  This contradicts the manual page, which says that
# '$' can be escaped as '$$'.
.if ${$$:L} != ""
.  error
.endif

# In lint mode, make prints helpful error messages.
# For compatibility, make does not print these error messages in normal mode.
# Should it?
.MAKEFLAGS: -dL
# expect+2: To escape a dollar, use \$, not $$, at "$$:L} != """
# expect+1: Invalid variable name ':', at "$:L} != """
.if ${$$:L} != ""
.  error
.endif

# A '$' followed by nothing is an error as well.
# expect+1: while evaluating "${:Uword:@word@${word}$@} != "word"": Dollar followed by nothing
.if ${:Uword:@word@${word}$@} != "word"
.  error
.endif

# The variable modifier :P does not fall back to the SysV modifier.
# Therefore the modifier :P=RE generates a parse error.
# XXX: The .error should not be reached since the expression is
# malformed, and this error should be propagated up to Cond_EvalLine.
VAR=	STOP
# expect+1: while evaluating variable "VAR": Missing delimiter ':' after modifier "P"
.if ${VAR:P=RE} != "STORE"
# expect+1: Missing argument for ".error"
.  error
.endif

all: # nothing