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. 7path=:/bin:/tmp::/:.:/no/such/dir:. 8# strip cwd from path. 9MOD_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. 12MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@ 13# another mod - pretend it is more interesting 14MOD_HOMES=S,/home/,/homes/, 15MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@ 16MOD_SEP=S,:, ,g 17 18all: modvar modvarloop modsysv mod-HTE emptyvar undefvar 19all: mod-tu-space 20all: mod-quote 21all: mod-break-many-words 22all: mod-remember 23all: mod-localtime 24all: mod-hash 25all: mod-range 26 27# See also sysv.mk. 28modsysv: 29 @echo "The answer is ${libfoo.a:L:libfoo.a=42}" 30 31# Demonstrates modifiers that are given indirectly from a variable. 32modvar: 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 40path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/ 41paths+= ${d:${MOD_OPT}:${MOD_HOMES}} 42.endfor 43 44modvarloop: 45 @echo "path_/usr/xbin=${path_/usr/xbin}" 46 @echo "paths=${paths}" 47 @echo "PATHS=${paths:tu}" 48 49PATHNAMES= a/b/c def a.b.c a.b/c a a.a .gitignore a a.a 50mod-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. 57emptyvar: 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. 66undefvar: 67 @echo S:${:U:S,^$,empty,} 68 @echo C:${:U:C,^$,empty,} 69 @echo @:${:U:@var@empty@} 70 71mod-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 77mod-quote: 78 @echo $@: new${.newline:Q}${.newline:Q}line 79 80# Cover the bmake_realloc in brk_string. 81mod-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. 88mod-remember: 89 @echo $@: ${1 2 3:L:_:@var@${_}@} 90 @echo $@: ${1 2 3:L:@var@${var:_=SAVED:}@}, SAVED=${SAVED} 91 92mod-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 98mod-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 106mod-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