cond-op.mk revision 1.6 1 1.6 rillig # $NetBSD: cond-op.mk,v 1.6 2020/09/11 05:12:08 rillig Exp $
2 1.1 rillig #
3 1.2 rillig # Tests for operators like &&, ||, ! in .if conditions.
4 1.3 rillig #
5 1.3 rillig # See also:
6 1.3 rillig # cond-op-and.mk
7 1.3 rillig # cond-op-not.mk
8 1.3 rillig # cond-op-or.mk
9 1.3 rillig # cond-op-parentheses.mk
10 1.3 rillig
11 1.3 rillig # In make, && binds more tightly than ||, like in C.
12 1.3 rillig # If make had the same precedence for both && and ||, the result would be
13 1.3 rillig # different.
14 1.3 rillig # If || were to bind more tightly than &&, the result would be different
15 1.3 rillig # as well.
16 1.3 rillig .if !(1 || 1 && 0)
17 1.3 rillig .error
18 1.3 rillig .endif
19 1.3 rillig
20 1.3 rillig # If make were to interpret the && and || operators like the shell, the
21 1.3 rillig # implicit binding would be this:
22 1.3 rillig .if (1 || 1) && 0
23 1.3 rillig .error
24 1.3 rillig .endif
25 1.3 rillig
26 1.3 rillig # The precedence of the ! operator is different from C though. It has a
27 1.3 rillig # lower precedence than the comparison operators.
28 1.3 rillig .if !"word" == "word"
29 1.3 rillig .error
30 1.3 rillig .endif
31 1.3 rillig
32 1.3 rillig # This is how the above condition is actually interpreted.
33 1.3 rillig .if !("word" == "word")
34 1.3 rillig .error
35 1.3 rillig .endif
36 1.1 rillig
37 1.3 rillig # TODO: Demonstrate that the precedence of the ! and == operators actually
38 1.3 rillig # makes a difference. There is a simple example for sure, I just cannot
39 1.3 rillig # wrap my head around it.
40 1.1 rillig
41 1.4 rillig # This condition is malformed because the '!' on the right-hand side must not
42 1.4 rillig # appear unquoted. If any, it must be enclosed in quotes.
43 1.4 rillig # In any case, it is not interpreted as a negation of an unquoted string.
44 1.6 rillig # See CondParser_String.
45 1.4 rillig .if "!word" == !word
46 1.4 rillig .error
47 1.4 rillig .endif
48 1.4 rillig
49 1.4 rillig # Surprisingly, the ampersand and pipe are allowed in bare strings.
50 1.4 rillig # That's another opportunity for writing confusing code.
51 1.5 rillig # See CondParser_String, which only has '!' in the list of stop characters.
52 1.4 rillig .if "a&&b||c" != a&&b||c
53 1.4 rillig .error
54 1.4 rillig .endif
55 1.4 rillig
56 1.6 rillig # As soon as the parser sees the '$', it knows that the condition will
57 1.6 rillig # be malformed. Therefore there is no point in evaluating it.
58 1.6 rillig # As of 2020-09-11, that part of the condition is evaluated nevertheless.
59 1.6 rillig .if 0 ${ERR::=evaluated}
60 1.6 rillig . error
61 1.6 rillig .endif
62 1.6 rillig .if ${ERR:Uundefined} == evaluated
63 1.6 rillig . warning After detecting a parse error, the rest is evaluated.
64 1.6 rillig .endif
65 1.6 rillig
66 1.4 rillig # Just in case that parsing should ever stop on the first error.
67 1.4 rillig .info Parsing continues until here.
68 1.4 rillig
69 1.1 rillig all:
70 1.1 rillig @:;
71