modmisc.mk revision 1.43 1 # $Id: modmisc.mk,v 1.43 2020/08/16 12:48:55 rillig Exp $
2 #
3 # miscellaneous modifier tests
4
5 # do not put any dirs in this list which exist on some
6 # but not all target systems - an exists() check is below.
7 path=:/bin:/tmp::/:.:/no/such/dir:.
8 # strip cwd from path.
9 MOD_NODOT=S/:/ /g:N.:ts:
10 # and decorate, note that $'s need to be doubled. Also note that
11 # the modifier_variable can be used with other modifiers.
12 MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@
13 # another mod - pretend it is more interesting
14 MOD_HOMES=S,/home/,/homes/,
15 MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
16 MOD_SEP=S,:, ,g
17
18 all: modvar modvarloop modsysv mod-HTE emptyvar undefvar
19 all: mod-tu-space
20 all: mod-quote
21 all: mod-break-many-words
22 all: mod-remember
23 all: mod-localtime
24 all: mod-hash
25 all: mod-range
26
27 # See also sysv.mk.
28 modsysv:
29 @echo "The answer is ${libfoo.a:L:libfoo.a=42}"
30
31 # Demonstrates modifiers that are given indirectly from a variable.
32 modvar:
33 @echo "path='${path}'"
34 @echo "path='${path:${MOD_NODOT}}'"
35 @echo "path='${path:S,home,homes,:${MOD_NODOT}}'"
36 @echo "path=${path:${MOD_NODOTX}:ts:}"
37 @echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}"
38
39 .for d in ${path:${MOD_SEP}:N.} /usr/xbin
40 path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/
41 paths+= ${d:${MOD_OPT}:${MOD_HOMES}}
42 .endfor
43
44 modvarloop:
45 @echo "path_/usr/xbin=${path_/usr/xbin}"
46 @echo "paths=${paths}"
47 @echo "PATHS=${paths:tu}"
48
49 PATHNAMES= a/b/c def a.b.c a.b/c a a.a .gitignore a a.a
50 mod-HTE:
51 @echo "dirname of '"${PATHNAMES:Q}"' is '"${PATHNAMES:H:Q}"'"
52 @echo "basename of '"${PATHNAMES:Q}"' is '"${PATHNAMES:T:Q}"'"
53 @echo "suffix of '"${PATHNAMES:Q}"' is '"${PATHNAMES:E:Q}"'"
54 @echo "root of '"${PATHNAMES:Q}"' is '"${PATHNAMES:R:Q}"'"
55
56 # When a modifier is applied to the "" variable, the result is discarded.
57 emptyvar:
58 @echo S:${:S,^$,empty,}
59 @echo C:${:C,^$,empty,}
60 @echo @:${:@var@${var}@}
61
62 # The :U modifier turns even the "" variable into something that has a value.
63 # The resulting variable is empty, but is still considered to contain a
64 # single empty word. This word can be accessed by the :S and :C modifiers,
65 # but not by the :@ modifier since it explicitly skips empty words.
66 undefvar:
67 @echo S:${:U:S,^$,empty,}
68 @echo C:${:U:C,^$,empty,}
69 @echo @:${:U:@var@empty@}
70
71 mod-tu-space:
72 # The :tu and :tl modifiers operate on the variable value
73 # as a single string, not as a list of words. Therefore,
74 # the adjacent spaces are preserved.
75 @echo $@: ${a b:L:tu:Q}
76
77 mod-quote:
78 @echo $@: new${.newline:Q}${.newline:Q}line
79
80 # Cover the bmake_realloc in brk_string.
81 mod-break-many-words:
82 @echo $@: ${UNDEF:U:range=500:[#]}
83
84 # Demonstrate the :_ modifier.
85 # In the parameterized form, having the variable name on the right side
86 # of the = assignment operator is confusing. Luckily this modifier is
87 # only rarely needed.
88 mod-remember:
89 @echo $@: ${1 2 3:L:_:@var@${_}@}
90 @echo $@: ${1 2 3:L:@var@${var:_=SAVED:}@}, SAVED=${SAVED}
91
92 mod-localtime:
93 @echo $@:
94 @echo ${%Y:L:localtim=1593536400} # modifier name too short
95 @echo ${%Y:L:localtime=1593536400} # 2020-07-01T00:00:00Z
96 @echo ${%Y:L:localtimer=1593536400} # modifier name too long
97
98 mod-hash:
99 @echo $@:
100 @echo ${12345:L:has} # modifier name too short
101 @echo ${12345:L:hash} # ok
102 @echo ${12345:L:hash=SHA-256} # :hash does not accept '='
103 @echo ${12345:L:hasX} # misspelled
104 @echo ${12345:L:hashed} # modifier name too long
105
106 mod-range:
107 @echo $@:
108 @echo ${a b c:L:rang} # modifier name too short
109 @echo ${a b c:L:range} # ok
110 @echo ${a b c:L:rango} # misspelled
111 @echo ${a b c:L:ranger} # modifier name too long
112
113 # To apply a modifier indirectly via another variable, the whole
114 # modifier must be put into a single variable.
115 .if ${value:L:${:US}${:U,value,replacement,}} != "S,value,replacement,}"
116 .warning unexpected
117 .endif
118
119 # Adding another level of indirection (the 2 nested :U expressions) helps.
120 .if ${value:L:${:U${:US}${:U,value,replacement,}}} != "replacement"
121 .warning unexpected
122 .endif
123
124 # Multiple indirect modifiers can be applied one after another as long as
125 # they are separated with colons.
126 .if ${value:L:${:US,a,A,}:${:US,e,E,}} != "vAluE"
127 .warning unexpected
128 .endif
129
130 # An indirect variable that evaluates to the empty string is allowed though.
131 # This makes it possible to define conditional modifiers, like this:
132 #
133 # M.little-endian= S,1234,4321,
134 # M.big-endian= # none
135 .if ${value:L:${:Dempty}S,a,A,} != "vAlue"
136 .warning unexpected
137 .endif
138
139