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