directive-for-errors.mk revision 1.17 1 # $NetBSD: directive-for-errors.mk,v 1.17 2025/05/03 08:18:33 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' parses the .for loop but skips the body.
77 # expect+1: missing `in' in for
78 .for i over k
79 . error
80 .endfor
81
82
83 # An error in the items skips the body of the loop.
84 # expect+1: Unknown modifier ":Z"
85 .for i in 1 2 ${:U3:Z} 4
86 . error
87 .endfor
88