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