cond-undef-lint.mk revision 1.5 1 # $NetBSD: cond-undef-lint.mk,v 1.5 2024/08/06 18:00:17 rillig Exp $
2 #
3 # Tests for defined and undefined variables in .if conditions, in lint mode.
4 #
5 # As of 2020-09-14, lint mode contains experimental code for printing
6 # accurate error messages in case of undefined variables, instead of the
7 # wrong "Malformed condition".
8 #
9 # See also:
10 # opt-debug-lint.mk
11
12 .MAKEFLAGS: -dL
13
14 # DEF is defined, UNDEF is not.
15 DEF= defined
16
17 # An expression based on a defined variable is fine.
18 .if !${DEF}
19 . error
20 .endif
21
22 # Since the condition fails to evaluate, neither of the branches is taken.
23 # expect+2: Malformed conditional '${UNDEF}'
24 # expect+1: Variable "UNDEF" is undefined
25 .if ${UNDEF}
26 . error
27 .else
28 . error
29 .endif
30
31 # The variable name depends on the undefined variable, which is probably a
32 # mistake. The variable UNDEF, as used here, can be easily turned into
33 # an expression that is always defined, using the :U modifier.
34 #
35 # The outer expression does not generate an error message since there was
36 # already an error evaluating this variable's name.
37 #
38 # TODO: Suppress the error message "Variable VAR. is undefined". That part
39 # of the expression must not be evaluated at all.
40 # expect+3: Variable "UNDEF" is undefined
41 # expect+2: Variable "VAR." is undefined
42 # expect+1: Malformed conditional '${VAR.${UNDEF}}'
43 .if ${VAR.${UNDEF}}
44 . error
45 .else
46 . error
47 .endif
48
49 # The variable VAR.defined is not defined and thus generates an error message.
50 #
51 # TODO: This pattern looks a lot like CFLAGS.${OPSYS}, which is at least
52 # debatable. Or would any practical use of CFLAGS.${OPSYS} be via an indirect
53 # expression, as in the next example?
54 # expect+2: Variable "VAR.defined" is undefined
55 # expect+1: Malformed conditional '${VAR.${DEF}}'
56 .if ${VAR.${DEF}}
57 . error
58 .else
59 . error
60 .endif
61
62
63 # Variables that are referenced indirectly may be undefined in a condition.
64 #
65 # A practical example for this is CFLAGS, which consists of CWARNS, COPTS
66 # and a few others. Just because these nested variables are not defined,
67 # this does not make the condition invalid.
68 #
69 # The crucial point is that at the point where the variable appears in the
70 # condition, there is no way to influence the definedness of the nested
71 # variables. In particular, there is no modifier that would turn undefined
72 # nested variables into empty strings, as an equivalent to the :U modifier.
73 INDIRECT= ${NESTED_UNDEF} ${NESTED_DEF}
74 NESTED_DEF= nested-defined
75
76 # Since NESTED_UNDEF is not controllable at this point, it must not generate
77 # an error message, and it doesn't do so, since 2020-09-14.
78 .if !${INDIRECT}
79 . error
80 .endif
81