parse-var.mk revision 1.6 1 1.6 rillig # $NetBSD: parse-var.mk,v 1.6 2022/09/25 21:26:23 rillig Exp $
2 1.2 rillig #
3 1.2 rillig # Tests for parsing variable expressions.
4 1.6 rillig #
5 1.6 rillig # TODO: Add systematic tests for all of the below combinations.
6 1.6 rillig #
7 1.6 rillig # Written form:
8 1.6 rillig # short form
9 1.6 rillig # long form with braces endc == '}'
10 1.6 rillig # long form with parentheses endc == ')'
11 1.6 rillig # indirect modifiers endc == '\0'
12 1.6 rillig #
13 1.6 rillig # Based on:
14 1.6 rillig # undefined variable
15 1.6 rillig # global variable
16 1.6 rillig # command-line variable
17 1.6 rillig # environment variable
18 1.6 rillig # target-local variable
19 1.6 rillig # legacy variable '@F'
20 1.6 rillig #
21 1.6 rillig # VarEvalMode:
22 1.6 rillig # parse
23 1.6 rillig # eval
24 1.6 rillig # eval-undeferr
25 1.6 rillig # eval-keep-dollar
26 1.6 rillig # eval-keep-undef
27 1.6 rillig # eval-keep-dollar-undef
28 1.6 rillig #
29 1.6 rillig # Global mode:
30 1.6 rillig # without -dL
31 1.6 rillig # with -dL
32 1.6 rillig #
33 1.6 rillig # Modifiers:
34 1.6 rillig # no
35 1.6 rillig # yes, stay undefined
36 1.6 rillig # convert to defined
37 1.6 rillig # indirect modifiers, involving changes to VarEvalMode
38 1.6 rillig #
39 1.6 rillig # Error conditions:
40 1.6 rillig # for the short form, EOF after the '$'
41 1.6 rillig # for the short form, each character
42 1.6 rillig # for the long forms, EOF right after '${'
43 1.6 rillig # for the long forms, EOF after the variable name
44 1.6 rillig # for the long forms, EOF after the ':'
45 1.6 rillig # for the long forms, EOF after parsing a modifier
46 1.6 rillig # for the long forms, ':}'
47 1.6 rillig # for each modifier: syntactic error
48 1.6 rillig # for each modifier: evaluation error
49 1.6 rillig #
50 1.6 rillig # Context:
51 1.6 rillig # in a condition, only operand, unquoted
52 1.6 rillig # in a condition, only operand, quoted
53 1.6 rillig # in a condition, left-hand side, unquoted
54 1.6 rillig # in a condition, left-hand side, quoted
55 1.6 rillig # in a condition, right-hand side, unquoted
56 1.6 rillig # in a condition, right-hand side, quoted
57 1.6 rillig # left-hand side of a variable assignment
58 1.6 rillig # right-hand side of a ':=' variable assignment
59 1.6 rillig # right-hand side of a '!=' variable assignment
60 1.6 rillig # shell command in a target
61 1.6 rillig # .info directive
62 1.6 rillig # dependency line
63 1.6 rillig # items in a .for loop
64 1.6 rillig # everywhere else Var_Parse is called
65 1.6 rillig #
66 1.6 rillig # Further influences:
67 1.6 rillig # multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}'
68 1.6 rillig #
69 1.6 rillig # Effects:
70 1.6 rillig # How much does the parsing position advance (pp)?
71 1.6 rillig # What's the value of the expression (out_val)?
72 1.6 rillig # What's the status after parsing the expression (VarParseResult)?
73 1.6 rillig # What error messages are printed (Parse_Error)?
74 1.6 rillig # What no-effect error messages are printed (Error)?
75 1.6 rillig # What error messages should be printed but aren't?
76 1.6 rillig # What other side effects are there?
77 1.1 rillig
78 1.1 rillig .MAKEFLAGS: -dL
79 1.1 rillig
80 1.2 rillig # In variable assignments, there may be spaces in the middle of the left-hand
81 1.2 rillig # side of the assignment, but only if they occur inside variable expressions.
82 1.2 rillig # Leading spaces (but not tabs) are possible but unusual.
83 1.2 rillig # Trailing spaces are common in some coding styles, others omit them.
84 1.1 rillig VAR.${:U param }= value
85 1.1 rillig .if ${VAR.${:U param }} != "value"
86 1.1 rillig . error
87 1.1 rillig .endif
88 1.1 rillig
89 1.5 rillig # XXX: The following paragraph already uses past tense, in the hope that the
90 1.5 rillig # parsing behavior can be cleaned up soon.
91 1.2 rillig
92 1.5 rillig # Since var.c 1.323 from 2020-07-26 18:11 and except for var.c 1.1028 from
93 1.4 rillig # 2022-08-08, the exact way of parsing an expression depended on whether the
94 1.4 rillig # expression was actually evaluated or merely parsed.
95 1.2 rillig #
96 1.3 rillig # If it was evaluated, nested expressions were parsed correctly, parsing each
97 1.3 rillig # modifier according to its exact definition (see varmod.mk).
98 1.2 rillig #
99 1.3 rillig # If the expression was merely parsed but not evaluated (for example, because
100 1.3 rillig # its value would not influence the outcome of the condition, or during the
101 1.3 rillig # first pass of the ':@var@body@' modifier), and the expression contained a
102 1.3 rillig # modifier, and that modifier contained a nested expression, the nested
103 1.3 rillig # expression was not parsed correctly. Instead, make only counted the opening
104 1.3 rillig # and closing delimiters, which failed for nested modifiers with unbalanced
105 1.3 rillig # braces.
106 1.3 rillig #
107 1.3 rillig # This naive brace counting was implemented in ParseModifierPartDollar. As of
108 1.5 rillig # var.c 1.1029, there are still several other places that merely count braces
109 1.3 rillig # instead of properly parsing subexpressions.
110 1.2 rillig
111 1.2 rillig #.MAKEFLAGS: -dcpv
112 1.2 rillig # Keep these braces outside the conditions below, to keep them simple to
113 1.2 rillig # understand. If the BRACE_PAIR had been replaced with ':U{}', the '}' would
114 1.2 rillig # have to be escaped, but not the '{'. This asymmetry would have made the
115 1.2 rillig # example even more complicated to understand.
116 1.2 rillig BRACE_PAIR= {}
117 1.2 rillig # In this test word, the '{{}' in the middle will be replaced.
118 1.2 rillig BRACE_GROUP= {{{{}}}}
119 1.2 rillig
120 1.2 rillig # The inner ':S' modifier turns the word '{}' into '{{}'.
121 1.2 rillig # The outer ':S' modifier then replaces '{{}' with '<lbraces>'.
122 1.2 rillig # In the first case, the outer expression is relevant and is parsed correctly.
123 1.2 rillig .if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
124 1.2 rillig .endif
125 1.3 rillig # In the second case, the outer expression was irrelevant. In this case, in
126 1.3 rillig # the parts of the outer ':S' modifier, make only counted the braces, and since
127 1.3 rillig # the inner expression '${BRACE_PAIR:...}' contains more '{' than '}', parsing
128 1.3 rillig # failed with the error message 'Unfinished modifier for "BRACE_GROUP"'. Fixed
129 1.5 rillig # in var.c 1.1028 from 2022-08-08, reverted in var.c 1.1029 from 2022-08-23.
130 1.2 rillig .if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
131 1.2 rillig .endif
132 1.2 rillig #.MAKEFLAGS: -d0
133 1.2 rillig
134 1.2 rillig
135 1.2 rillig all: .PHONY
136