opt-debug-lint.mk revision 1.23 1 1.23 rillig # $NetBSD: opt-debug-lint.mk,v 1.23 2025/03/29 19:08:52 rillig Exp $
2 1.1 rillig #
3 1.1 rillig # Tests for the -dL command line option, which runs additional checks
4 1.16 rillig # to catch common mistakes, such as unclosed expressions.
5 1.11 rillig
6 1.2 rillig .MAKEFLAGS: -dL
7 1.2 rillig
8 1.2 rillig # Since 2020-09-13, undefined variables that are used on the left-hand side
9 1.2 rillig # of a condition at parse time get a proper error message. Before, the
10 1.2 rillig # error message was "Malformed conditional" only, which was wrong and
11 1.2 rillig # misleading. The form of the condition is totally fine, it's the evaluation
12 1.2 rillig # that fails.
13 1.2 rillig #
14 1.4 rillig # Since 2020-09-13, the "Malformed conditional" error message is not printed
15 1.4 rillig # anymore.
16 1.4 rillig #
17 1.4 rillig # See also:
18 1.4 rillig # cond-undef-lint.mk
19 1.22 rillig # expect+1: Variable "X" is undefined
20 1.2 rillig .if $X
21 1.2 rillig . error
22 1.2 rillig .endif
23 1.2 rillig
24 1.2 rillig # The dynamic variables like .TARGET are treated specially. It does not make
25 1.2 rillig # sense to expand them in the global scope since they will never be defined
26 1.2 rillig # there under normal circumstances. Therefore they expand to a string that
27 1.2 rillig # will later be expanded correctly, when the variable is evaluated again in
28 1.2 rillig # the scope of an actual target.
29 1.2 rillig #
30 1.2 rillig # Even though the "@" variable is not defined at this point, this is not an
31 1.2 rillig # error. In all practical cases, this is no problem. This particular test
32 1.2 rillig # case is made up and unrealistic.
33 1.2 rillig .if $@ != "\$(.TARGET)"
34 1.2 rillig . error
35 1.2 rillig .endif
36 1.1 rillig
37 1.3 rillig # Since 2020-09-13, Var_Parse properly reports errors for undefined variables,
38 1.3 rillig # but only in lint mode. Before, it had only silently returned var_Error,
39 1.3 rillig # hoping for the caller to print an error message. This resulted in the
40 1.3 rillig # well-known "Malformed conditional" error message, even though the
41 1.3 rillig # conditional was well-formed and the only error was an undefined variable.
42 1.22 rillig # expect+1: Variable "UNDEF" is undefined
43 1.3 rillig .if ${UNDEF}
44 1.3 rillig . error
45 1.3 rillig .endif
46 1.3 rillig
47 1.5 rillig # Since 2020-09-14, dependency lines may contain undefined variables.
48 1.5 rillig # Before, undefined variables were forbidden, but this distinction was not
49 1.5 rillig # observable from the outside of the function Var_Parse.
50 1.5 rillig ${UNDEF}: ${UNDEF}
51 1.5 rillig
52 1.6 rillig # In a condition that has a defined(UNDEF) guard, all guarded conditions
53 1.6 rillig # may assume that the variable is defined since they will only be evaluated
54 1.6 rillig # if the variable is indeed defined. Otherwise they are only parsed, and
55 1.6 rillig # for parsing it doesn't make a difference whether the variable is defined
56 1.6 rillig # or not.
57 1.6 rillig .if defined(UNDEF) && exists(${UNDEF})
58 1.6 rillig . error
59 1.6 rillig .endif
60 1.6 rillig
61 1.10 rillig # Since 2020-10-03, in lint mode the variable modifier must be separated
62 1.10 rillig # by colons. See varparse-mod.mk.
63 1.20 rillig # expect+2: Missing delimiter ':' after modifier "L"
64 1.20 rillig # expect+1: Missing delimiter ':' after modifier "P"
65 1.10 rillig .if ${value:LPL} != "value"
66 1.10 rillig . error
67 1.10 rillig .endif
68 1.10 rillig
69 1.12 rillig # Between 2020-10-03 and var.c 1.752 from 2020-12-20, in lint mode the
70 1.12 rillig # variable modifier had to be separated by colons. This was wrong though
71 1.12 rillig # since make always fell back trying to parse the indirect modifier as a
72 1.12 rillig # SysV modifier.
73 1.23 rillig # expect+1: Unknown modifier ":${"
74 1.10 rillig .if ${value:${:UL}PL} != "LPL}" # FIXME: "LPL}" is unexpected here.
75 1.10 rillig . error ${value:${:UL}PL}
76 1.10 rillig .endif
77 1.10 rillig
78 1.12 rillig # Typically, an indirect modifier is followed by a colon or the closing
79 1.12 rillig # brace. This one isn't, therefore make falls back to parsing it as the SysV
80 1.12 rillig # modifier ":lue=lid".
81 1.12 rillig .if ${value:L:${:Ulue}=${:Ulid}} != "valid"
82 1.12 rillig . error
83 1.12 rillig .endif
84 1.12 rillig
85 1.14 rillig # In lint mode, the whole variable text is evaluated to check for unclosed
86 1.14 rillig # expressions and unknown operators. During this check, the subexpression
87 1.14 rillig # '${:U2}' is not expanded, instead it is copied verbatim into the regular
88 1.14 rillig # expression, leading to '.*=.{1,${:U2}}$'.
89 1.14 rillig #
90 1.14 rillig # Before var.c 1.856 from 2021-03-14, this regular expression was then
91 1.14 rillig # compiled even though that was not necessary for checking the syntax at the
92 1.16 rillig # level of expressions. The unexpanded '$' then resulted in a wrong
93 1.14 rillig # error message.
94 1.13 rillig #
95 1.13 rillig # This only happened in lint mode since in default mode the early check for
96 1.13 rillig # unclosed expressions and unknown modifiers is skipped.
97 1.13 rillig #
98 1.13 rillig # See VarCheckSyntax, ApplyModifier_Regex.
99 1.13 rillig #
100 1.13 rillig VARMOD_REGEX= ${:UA=111 B=222 C=33:C/.*=.{1,${:U2}}$//g}
101