xref: /freebsd/contrib/bmake/unit-tests/directive-for.mk (revision 2c3632d14fe37fa35c262ee9fb66835be0a52621)
1*2c3632d1SSimon J. Gerraty# $NetBSD: directive-for.mk,v 1.2 2020/09/02 22:58:59 rillig Exp $
2*2c3632d1SSimon J. Gerraty#
3*2c3632d1SSimon J. Gerraty# Tests for the .for directive.
4*2c3632d1SSimon J. Gerraty
5*2c3632d1SSimon J. Gerraty# Using the .for loop, lists of values can be produced.
6*2c3632d1SSimon J. Gerraty# In simple cases, the :@var@${var}@ variable modifier can be used to
7*2c3632d1SSimon J. Gerraty# reach the same effects.
8*2c3632d1SSimon J. Gerraty#
9*2c3632d1SSimon J. Gerraty.undef NUMBERS
10*2c3632d1SSimon J. Gerraty.for num in 1 2 3
11*2c3632d1SSimon J. GerratyNUMBERS+=	${num}
12*2c3632d1SSimon J. Gerraty.endfor
13*2c3632d1SSimon J. Gerraty.if ${NUMBERS} != "1 2 3"
14*2c3632d1SSimon J. Gerraty.  error
15*2c3632d1SSimon J. Gerraty.endif
16*2c3632d1SSimon J. Gerraty
17*2c3632d1SSimon J. Gerraty# The .for loop also works for multiple iteration variables.
18*2c3632d1SSimon J. Gerraty.for name value in VARNAME value NAME2 value2
19*2c3632d1SSimon J. Gerraty${name}=	${value}
20*2c3632d1SSimon J. Gerraty.endfor
21*2c3632d1SSimon J. Gerraty.if ${VARNAME} != "value" || ${NAME2} != "value2"
22*2c3632d1SSimon J. Gerraty.  error
23*2c3632d1SSimon J. Gerraty.endif
24*2c3632d1SSimon J. Gerraty
25*2c3632d1SSimon J. Gerraty# The .for loop splits the items at whitespace, taking quotes into account,
26*2c3632d1SSimon J. Gerraty# just like the :M or :S variable modifiers.
27*2c3632d1SSimon J. Gerraty#
28*2c3632d1SSimon J. Gerraty# Until 2012-06-03, it had split the items exactly at whitespace, without
29*2c3632d1SSimon J. Gerraty# taking the quotes into account.
30*2c3632d1SSimon J. Gerraty#
31*2c3632d1SSimon J. Gerraty.undef WORDS
32*2c3632d1SSimon J. Gerraty.for var in one t\ w\ o "three three" 'four four' `five six`
33*2c3632d1SSimon J. GerratyWORDS+=	counted
34*2c3632d1SSimon J. Gerraty.endfor
35*2c3632d1SSimon J. Gerraty.if ${WORDS:[#]} != 6
36*2c3632d1SSimon J. Gerraty.  error
37*2c3632d1SSimon J. Gerraty.endif
38*2c3632d1SSimon J. Gerraty
39*2c3632d1SSimon J. Gerraty# In the body of the .for loop, the iteration variables can be accessed
40*2c3632d1SSimon J. Gerraty# like normal variables, even though they are not really variables.
41*2c3632d1SSimon J. Gerraty#
42*2c3632d1SSimon J. Gerraty# Instead, the expression ${var} is transformed into ${:U1}, ${:U2} and so
43*2c3632d1SSimon J. Gerraty# on, before the loop body is evaluated.
44*2c3632d1SSimon J. Gerraty#
45*2c3632d1SSimon J. Gerraty# A notable effect of this implementation technique is that the .for
46*2c3632d1SSimon J. Gerraty# iteration variables and the normal global variables live in separate
47*2c3632d1SSimon J. Gerraty# namespaces and do not influence each other.
48*2c3632d1SSimon J. Gerraty#
49*2c3632d1SSimon J. Gerratyvar=	value before
50*2c3632d1SSimon J. Gerratyvar2=	value before
51*2c3632d1SSimon J. Gerraty.for var var2 in 1 2 3 4
52*2c3632d1SSimon J. Gerraty.endfor
53*2c3632d1SSimon J. Gerraty.if ${var} != "value before"
54*2c3632d1SSimon J. Gerraty.  warning After the .for loop, var must still have its original value.
55*2c3632d1SSimon J. Gerraty.endif
56*2c3632d1SSimon J. Gerraty.if ${var2} != "value before"
57*2c3632d1SSimon J. Gerraty.  warning After the .for loop, var2 must still have its original value.
58*2c3632d1SSimon J. Gerraty.endif
59*2c3632d1SSimon J. Gerraty
60*2c3632d1SSimon J. Gerraty# Everything from the paragraph above also applies if the loop body is
61*2c3632d1SSimon J. Gerraty# empty, even if there is no actual iteration since the loop items are
62*2c3632d1SSimon J. Gerraty# also empty.
63*2c3632d1SSimon J. Gerraty#
64*2c3632d1SSimon J. Gerratyvar=	value before
65*2c3632d1SSimon J. Gerratyvar2=	value before
66*2c3632d1SSimon J. Gerraty.for var var2 in ${:U}
67*2c3632d1SSimon J. Gerraty.endfor
68*2c3632d1SSimon J. Gerraty.if ${var} != "value before"
69*2c3632d1SSimon J. Gerraty.  warning After the .for loop, var must still have its original value.
70*2c3632d1SSimon J. Gerraty.endif
71*2c3632d1SSimon J. Gerraty.if ${var2} != "value before"
72*2c3632d1SSimon J. Gerraty.  warning After the .for loop, var2 must still have its original value.
73*2c3632d1SSimon J. Gerraty.endif
74*2c3632d1SSimon J. Gerraty
75*2c3632d1SSimon J. Gerraty# Until 2008-12-21, the values of the iteration variables were simply
76*2c3632d1SSimon J. Gerraty# inserted as plain text and then parsed as usual, which made it possible
77*2c3632d1SSimon J. Gerraty# to achieve all kinds of strange effects.
78*2c3632d1SSimon J. Gerraty#
79*2c3632d1SSimon J. Gerraty# Before that date, the .for loop expanded to:
80*2c3632d1SSimon J. Gerraty#	EXPANSION+= value
81*2c3632d1SSimon J. Gerraty# Since that date, the .for loop expands to:
82*2c3632d1SSimon J. Gerraty#	EXPANSION${:U+}= value
83*2c3632d1SSimon J. Gerraty#
84*2c3632d1SSimon J. GerratyEXPANSION=	before
85*2c3632d1SSimon J. GerratyEXPANSION+ =	before
86*2c3632d1SSimon J. Gerraty.for plus in +
87*2c3632d1SSimon J. GerratyEXPANSION${plus}=	value
88*2c3632d1SSimon J. Gerraty.endfor
89*2c3632d1SSimon J. Gerraty.if ${EXPANSION} != "before"
90*2c3632d1SSimon J. Gerraty.  error This must be a make from before 2009.
91*2c3632d1SSimon J. Gerraty.endif
92*2c3632d1SSimon J. Gerraty.if ${EXPANSION+} != "value"
93*2c3632d1SSimon J. Gerraty.  error This must be a make from before 2009.
94*2c3632d1SSimon J. Gerraty.endif
95*2c3632d1SSimon J. Gerraty
96*2c3632d1SSimon J. Gerratyall:
97*2c3632d1SSimon J. Gerraty	@:;
98