xref: /freebsd/contrib/bmake/unit-tests/directive-for-errors.mk (revision 95eb4b873b6a8b527c5bd78d7191975dfca38998)
1# $NetBSD: directive-for-errors.mk,v 1.13 2024/07/06 10:14:35 rillig Exp $
2#
3# Tests for error handling in .for loops.
4
5
6# A .for directive must be followed by whitespace, everything else results
7# in a parse error.
8# expect+1: Unknown directive "fori"
9.fori in 1 2 3
10# expect+1: warning: <>
11.  warning <${i}>
12# expect+1: for-less endfor
13.endfor
14
15
16# A slash is not whitespace, therefore this is not parsed as a .for loop.
17#
18# XXX: The error message is misleading though.  As of 2020-12-31, it says
19# 'Unknown directive "for"', but that directive is actually known.  This is
20# because ForEval does not detect the .for loop as such, so parsing
21# continues in ParseLine > ParseDependencyLine > ParseDependency >
22# ParseDependencyTargets > ParseErrorNoDependency, and there the directive
23# name is parsed a bit differently.
24# expect+1: Unknown directive "for"
25.for/i in 1 2 3
26# expect+1: warning: <>
27.  warning <${i}>
28# expect+1: for-less endfor
29.endfor
30
31
32# Before for.c 1.173 from 2023-05-08, the variable name could be an arbitrary
33# word, it only needed to be separated by whitespace.  Even '$' and '\' were
34# valid variable names, which was not useful in practice.
35#
36# The '$$' was not replaced with the values '1' or '3' from the .for loop,
37# instead it was kept as-is, and when the .info directive expanded its
38# argument, each '$$' got replaced with a single '$'.  The "long
39# expression" ${$} got replaced though, even though this would be a parse
40# error everywhere outside a .for loop.
41${:U\$}=	dollar		# see whether the "variable" '$' is local
42${:U\\}=	backslash	# see whether the "variable" '\' is local
43# expect+1: invalid character '$' in .for loop variable name
44.for a b $ \ in 1 2 3 4
45.  info Dollar $$ ${$} $($) and backslash $\ ${\} $(\).
46.endfor
47
48# If there are no variables, there is no point in expanding the .for loop
49# since this would end up in an endless loop, consuming 0 of the 3 values in
50# each iteration.
51# expect+1: no iteration variables in for
52.for in 1 2 3
53# XXX: This should not be reached.  It should be skipped, as already done
54# when the number of values is not a multiple of the number of variables,
55# see below.
56.  warning Should not be reached.
57.endfor
58
59
60# There are 3 variables and 5 values.  These 5 values cannot be split evenly
61# among the variables, therefore the loop is not expanded at all, it is
62# skipped instead.
63# expect+1: Wrong number of words (5) in .for substitution list with 3 variables
64.for a b c in 1 2 3 4 5
65.  warning Should not be reached.
66.endfor
67
68
69# The list of values after the 'in' may be empty, no matter if this emptiness
70# comes from an expanded expression or from a syntactically empty line.
71.for i in
72.  info Would be reached if there were items to loop over.
73.endfor
74
75
76# A missing 'in' should parse the .for loop but skip the body.
77# expect+1: missing `in' in for
78.for i over k
79# XXX: As of 2020-12-31, this line is reached once.
80.  warning Should not be reached.
81.endfor
82
83
84# A malformed modifier should be detected and skip the body of the loop.
85#
86# XXX: As of 2020-12-31, Var_Subst doesn't report any errors, therefore
87# the loop body is expanded as if no error had happened.
88# expect+1: while evaluating "${:U3:Z} 4" with value "3": Unknown modifier "Z"
89.for i in 1 2 ${:U3:Z} 4
90# expect+3: warning: Should not be reached.
91# expect+2: warning: Should not be reached.
92# expect+1: warning: Should not be reached.
93.  warning Should not be reached.
94.endfor
95