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