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