Sun Jul 26 21:09:49 2020 UTC ()
make(1): add test for unclosed variables


(rillig)
diff -r1.11 -r1.12 src/usr.bin/make/unit-tests/varmisc.exp
diff -r1.15 -r1.16 src/usr.bin/make/unit-tests/varmisc.mk

cvs diff -r1.11 -r1.12 src/usr.bin/make/unit-tests/varmisc.exp (switch to unified diff)

--- src/usr.bin/make/unit-tests/varmisc.exp 2020/07/26 20:30:42 1.11
+++ src/usr.bin/make/unit-tests/varmisc.exp 2020/07/26 21:09:49 1.12
@@ -1,47 +1,53 @@ @@ -1,47 +1,53 @@
1 1
2:D expanded when var set 2:D expanded when var set
3true 3true
4TRUE 4TRUE
5:U expanded when var undef 5:U expanded when var undef
6true 6true
7TRUE 7TRUE
8:D skipped if var undef 8:D skipped if var undef
9 9
10:U skipped when var set 10:U skipped when var set
11is set 11is set
12:? only lhs when value true 12:? only lhs when value true
13true 13true
14TRUE 14TRUE
15:? only rhs when value false 15:? only rhs when value false
16false 16false
17FALSE 17FALSE
18do not evaluate or expand :? if discarding 18do not evaluate or expand :? if discarding
19is set 19is set
20year=2016 month=04 day=01 20year=2016 month=04 day=01
21date=20160401 21date=20160401
22Version=123.456.789 == 123456789 22Version=123.456.789 == 123456789
23Literal=3.4.5 == 3004005 23Literal=3.4.5 == 3004005
24We have target specific vars 24We have target specific vars
25MAN= make.1 25MAN= make.1
26save-dollars: 0 = $ 26save-dollars: 0 = $
27save-dollars: 1 = $$ 27save-dollars: 1 = $$
28save-dollars: 2 = $$ 28save-dollars: 2 = $$
29save-dollars: False = $ 29save-dollars: False = $
30save-dollars: True = $$ 30save-dollars: True = $$
31save-dollars: false = $ 31save-dollars: false = $
32save-dollars: true = $$ 32save-dollars: true = $$
33save-dollars: Yes = $$ 33save-dollars: Yes = $$
34save-dollars: No = $ 34save-dollars: No = $
35save-dollars: yes = $$ 35save-dollars: yes = $$
36save-dollars: no = $ 36save-dollars: no = $
37save-dollars: On = $$ 37save-dollars: On = $$
38save-dollars: Off = $ 38save-dollars: Off = $
39save-dollars: ON = $$ 39save-dollars: ON = $$
40save-dollars: OFF = $ 40save-dollars: OFF = $
41save-dollars: on = $$ 41save-dollars: on = $$
42save-dollars: off = $ 42save-dollars: off = $
43export-appended: env 43export-appended: env
44export-appended: env 44export-appended: env
45export-appended: env mk 45export-appended: env mk
46parse-dynamic: parse-dynamic parse-dynamic before 46parse-dynamic: parse-dynamic parse-dynamic before
 47varerror-unclosed:begin
 48
 49make: Unclosed variable specification (expecting '}') for "UNCLOSED" (value "") modifier M
 50
 51
 52varerror-unclosed:end
47exit status 0 53exit status 0

cvs diff -r1.15 -r1.16 src/usr.bin/make/unit-tests/varmisc.mk (switch to unified diff)

--- src/usr.bin/make/unit-tests/varmisc.mk 2020/07/26 20:30:42 1.15
+++ src/usr.bin/make/unit-tests/varmisc.mk 2020/07/26 21:09:49 1.16
@@ -1,176 +1,186 @@ @@ -1,176 +1,186 @@
1# $Id: varmisc.mk,v 1.15 2020/07/26 20:30:42 rillig Exp $ 1# $Id: varmisc.mk,v 1.16 2020/07/26 21:09:49 rillig Exp $
2# 2#
3# Miscellaneous variable tests. 3# Miscellaneous variable tests.
4 4
5all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \ 5all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
6 strftime cmpv manok 6 strftime cmpv manok
7all: save-dollars 7all: save-dollars
8all: export-appended 8all: export-appended
9all: parse-dynamic 9all: parse-dynamic
 10all: varerror-unclosed
10 11
11unmatched_var_paren: 12unmatched_var_paren:
12 @echo ${foo::=foo-text} 13 @echo ${foo::=foo-text}
13 14
14True = ${echo true >&2:L:sh}TRUE 15True = ${echo true >&2:L:sh}TRUE
15False= ${echo false >&2:L:sh}FALSE 16False= ${echo false >&2:L:sh}FALSE
16 17
17VSET= is set 18VSET= is set
18.undef UNDEF 19.undef UNDEF
19 20
20U_false: 21U_false:
21 @echo :U skipped when var set 22 @echo :U skipped when var set
22 @echo ${VSET:U${False}} 23 @echo ${VSET:U${False}}
23 24
24D_false: 25D_false:
25 @echo :D skipped if var undef 26 @echo :D skipped if var undef
26 @echo ${UNDEF:D${False}} 27 @echo ${UNDEF:D${False}}
27 28
28U_true: 29U_true:
29 @echo :U expanded when var undef 30 @echo :U expanded when var undef
30 @echo ${UNDEF:U${True}} 31 @echo ${UNDEF:U${True}}
31 32
32D_true: 33D_true:
33 @echo :D expanded when var set 34 @echo :D expanded when var set
34 @echo ${VSET:D${True}} 35 @echo ${VSET:D${True}}
35 36
36Q_lhs: 37Q_lhs:
37 @echo :? only lhs when value true 38 @echo :? only lhs when value true
38 @echo ${1:L:?${True}:${False}} 39 @echo ${1:L:?${True}:${False}}
39 40
40Q_rhs: 41Q_rhs:
41 @echo :? only rhs when value false 42 @echo :? only rhs when value false
42 @echo ${0:L:?${True}:${False}} 43 @echo ${0:L:?${True}:${False}}
43 44
44NQ_none: 45NQ_none:
45 @echo do not evaluate or expand :? if discarding 46 @echo do not evaluate or expand :? if discarding
46 @echo ${VSET:U${1:L:?${True}:${False}}} 47 @echo ${VSET:U${1:L:?${True}:${False}}}
47 48
48April1= 1459494000 49April1= 1459494000
49 50
50# slightly contorted syntax to use utc via variable 51# slightly contorted syntax to use utc via variable
51strftime: 52strftime:
52 @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000} 53 @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000}
53 @echo date=${%Y%m%d:L:${gmtime=${April1}:L}} 54 @echo date=${%Y%m%d:L:${gmtime=${April1}:L}}
54 55
55# big jumps to handle 3 digits per step 56# big jumps to handle 3 digits per step
56M_cmpv.units = 1 1000 1000000 57M_cmpv.units = 1 1000 1000000
57M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh 58M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
58 59
59Version = 123.456.789 60Version = 123.456.789
60cmpv.only = target specific vars 61cmpv.only = target specific vars
61 62
62cmpv: 63cmpv:
63 @echo Version=${Version} == ${Version:${M_cmpv}} 64 @echo Version=${Version} == ${Version:${M_cmpv}}
64 @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}} 65 @echo Literal=3.4.5 == ${3.4.5:L:${M_cmpv}}
65 @echo We have ${${.TARGET:T}.only} 66 @echo We have ${${.TARGET:T}.only}
66 67
67# catch misshandling of nested vars in .for loop 68# catch misshandling of nested vars in .for loop
68MAN= 69MAN=
69MAN1= make.1 70MAN1= make.1
70.for s in 1 2 71.for s in 1 2
71.if defined(MAN$s) && !empty(MAN$s) 72.if defined(MAN$s) && !empty(MAN$s)
72MAN+= ${MAN$s} 73MAN+= ${MAN$s}
73.endif 74.endif
74.endfor 75.endfor
75 76
76manok: 77manok:
77 @echo MAN=${MAN} 78 @echo MAN=${MAN}
78 79
79# This is an expanded variant of the above .for loop. 80# This is an expanded variant of the above .for loop.
80# Between 2020-06-28 and 2020-07-02 this paragraph generated a wrong 81# Between 2020-06-28 and 2020-07-02 this paragraph generated a wrong
81# error message "Variable VARNAME is recursive". 82# error message "Variable VARNAME is recursive".
82# When evaluating the !empty expression, the ${:U1} was not expanded and 83# When evaluating the !empty expression, the ${:U1} was not expanded and
83# thus resulted in the seeming definition VARNAME=${VARNAME}, which is 84# thus resulted in the seeming definition VARNAME=${VARNAME}, which is
84# obviously recursive. 85# obviously recursive.
85VARNAME= ${VARNAME${:U1}} 86VARNAME= ${VARNAME${:U1}}
86.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2}) 87.if defined(VARNAME${:U2}) && !empty(VARNAME${:U2})
87.endif 88.endif
88 89
89# begin .MAKE.SAVE_DOLLARS; see Var_Set_with_flags and s2Boolean. 90# begin .MAKE.SAVE_DOLLARS; see Var_Set_with_flags and s2Boolean.
90SD_VALUES= 0 1 2 False True false true Yes No yes no On Off ON OFF on off 91SD_VALUES= 0 1 2 False True false true Yes No yes no On Off ON OFF on off
91SD_4_DOLLARS= $$$$ 92SD_4_DOLLARS= $$$$
92 93
93.for val in ${SD_VALUES} 94.for val in ${SD_VALUES}
94.MAKE.SAVE_DOLLARS:= ${val} # Must be := since a simple = has no effect. 95.MAKE.SAVE_DOLLARS:= ${val} # Must be := since a simple = has no effect.
95SD.${val}:= ${SD_4_DOLLARS} 96SD.${val}:= ${SD_4_DOLLARS}
96.endfor 97.endfor
97.MAKE.SAVE_DOLLARS:= yes 98.MAKE.SAVE_DOLLARS:= yes
98 99
99save-dollars: 100save-dollars:
100.for val in ${SD_VALUES} 101.for val in ${SD_VALUES}
101 @printf '%s: %-8s = %s\n' $@ ${val} ${SD.${val}:Q} 102 @printf '%s: %-8s = %s\n' $@ ${val} ${SD.${val}:Q}
102.endfor 103.endfor
103 104
104# Appending to an undefined variable does not add a space in front. 105# Appending to an undefined variable does not add a space in front.
105.undef APPENDED 106.undef APPENDED
106APPENDED+= value 107APPENDED+= value
107.if ${APPENDED} != "value" 108.if ${APPENDED} != "value"
108.error "${APPENDED}" 109.error "${APPENDED}"
109.endif 110.endif
110 111
111# Appending to an empty variable adds a space between the old value 112# Appending to an empty variable adds a space between the old value
112# and the additional value. 113# and the additional value.
113APPENDED= # empty 114APPENDED= # empty
114APPENDED+= value 115APPENDED+= value
115.if ${APPENDED} != " value" 116.if ${APPENDED} != " value"
116.error "${APPENDED}" 117.error "${APPENDED}"
117.endif 118.endif
118 119
119# Appending to parameterized variables works as well. 120# Appending to parameterized variables works as well.
120PARAM= param 121PARAM= param
121VAR.${PARAM}= 1 122VAR.${PARAM}= 1
122VAR.${PARAM}+= 2 123VAR.${PARAM}+= 2
123.if ${VAR.param} != "1 2" 124.if ${VAR.param} != "1 2"
124.error "${VAR.param}" 125.error "${VAR.param}"
125.endif 126.endif
126 127
127# The variable name can contain arbitrary characters. 128# The variable name can contain arbitrary characters.
128# If the expanded variable name ends in a +, this still does not influence 129# If the expanded variable name ends in a +, this still does not influence
129# the parser. The assignment operator is still a simple assignment. 130# the parser. The assignment operator is still a simple assignment.
130# Therefore, there is no need to add a space between the variable name 131# Therefore, there is no need to add a space between the variable name
131# and the assignment operator. 132# and the assignment operator.
132PARAM= + 133PARAM= +
133VAR.${PARAM}= 1 134VAR.${PARAM}= 1
134VAR.${PARAM}+= 2 135VAR.${PARAM}+= 2
135.if ${VAR.+} != "1 2" 136.if ${VAR.+} != "1 2"
136.error "${VAR.+}" 137.error "${VAR.+}"
137.endif 138.endif
138.for param in + ! ? 139.for param in + ! ?
139VAR.${param}= ${param} 140VAR.${param}= ${param}
140.endfor 141.endfor
141.if ${VAR.+} != "+" || ${VAR.!} != "!" || ${VAR.?} != "?" 142.if ${VAR.+} != "+" || ${VAR.!} != "!" || ${VAR.?} != "?"
142.error "${VAR.+}" "${VAR.!}" "${VAR.?}" 143.error "${VAR.+}" "${VAR.!}" "${VAR.?}"
143.endif 144.endif
144 145
145# Appending to a variable from the environment creates a copy of that variable 146# Appending to a variable from the environment creates a copy of that variable
146# in the global context. 147# in the global context.
147# The appended value is not exported automatically. 148# The appended value is not exported automatically.
148# When a variable is exported, the exported value is taken at the time of the 149# When a variable is exported, the exported value is taken at the time of the
149# .export directive. Later changes to the variable have no effect. 150# .export directive. Later changes to the variable have no effect.
150.export FROM_ENV_BEFORE 151.export FROM_ENV_BEFORE
151FROM_ENV+= mk 152FROM_ENV+= mk
152FROM_ENV_BEFORE+= mk 153FROM_ENV_BEFORE+= mk
153FROM_ENV_AFTER+= mk 154FROM_ENV_AFTER+= mk
154.export FROM_ENV_AFTER 155.export FROM_ENV_AFTER
155 156
156export-appended: 157export-appended:
157 @echo $@: "$$FROM_ENV" 158 @echo $@: "$$FROM_ENV"
158 @echo $@: "$$FROM_ENV_BEFORE" 159 @echo $@: "$$FROM_ENV_BEFORE"
159 @echo $@: "$$FROM_ENV_AFTER" 160 @echo $@: "$$FROM_ENV_AFTER"
160 161
161# begin parse-dynamic 162# begin parse-dynamic
162# 163#
163# Demonstrate that the target-specific variables are not evaluated in 164# Demonstrate that the target-specific variables are not evaluated in
164# the global context. They are preserved until there is a local context 165# the global context. They are preserved until there is a local context
165# in which resolving them makes sense. 166# in which resolving them makes sense.
166 167
167${:U>}= before 168${:U>}= before
168G_TARGET:= $@ 169G_TARGET:= $@
169G_MEMBER:= $% 170G_MEMBER:= $%
170G_PREFIX:= $* 171G_PREFIX:= $*
171G_ARCHIVE:= $! 172G_ARCHIVE:= $!
172G_ALLSRC:= $> 173G_ALLSRC:= $>
173${:U>}= after 174${:U>}= after
174 175
175parse-dynamic: 176parse-dynamic:
176 @echo $@: ${G_TARGET} ${G_MEMBER} ${G_PREFIX} ${G_ARCHIVE} ${G_ALLSRC} 177 @echo $@: ${G_TARGET} ${G_MEMBER} ${G_PREFIX} ${G_ARCHIVE} ${G_ALLSRC}
 178
 179# As of 2020-07-26, make does not complain about unclosed variables.
 180# It does complain about unclosed variables when parsing modifiers though.
 181varerror-unclosed:
 182 @echo $@:begin
 183 @echo ${UNCLOSED
 184 @echo ${UNCLOSED:M${PATTERN
 185 @echo ${UNCLOSED.${param
 186 @echo $@:end