Home | History | Annotate | Line # | Download | only in unit-tests
cond-token-plain.mk revision 1.9
      1 # $NetBSD: cond-token-plain.mk,v 1.9 2021/01/21 13:52:32 rillig Exp $
      2 #
      3 # Tests for plain tokens (that is, string literals without quotes)
      4 # in .if conditions.
      5 
      6 .MAKEFLAGS: -dc
      7 
      8 .if ${:Uvalue} != value
      9 .  error
     10 .endif
     11 
     12 # Malformed condition since comment parsing is done in an early phase
     13 # and removes the '#' and everything behind it long before the condition
     14 # parser gets to see it.
     15 #
     16 # XXX: The error message is missing for this malformed condition.
     17 # The right-hand side of the comparison is just a '"', before unescaping.
     18 .if ${:U} != "#hash"
     19 .  error
     20 .endif
     21 
     22 # To get a '#' into a condition, it has to be escaped using a backslash.
     23 # This prevents the comment parser from removing it, and in turn, it becomes
     24 # visible to CondParser_String.
     25 .if ${:U\#hash} != "\#hash"
     26 .  error
     27 .endif
     28 
     29 # Since 2002-12-30, and still as of 2020-09-11, CondParser_Token handles
     30 # the '#' specially, even though at this point, there should be no need for
     31 # comment handling anymore.  The comments are supposed to be stripped off
     32 # in a very early parsing phase.
     33 #
     34 # See https://gnats.netbsd.org/19596 for example makefiles demonstrating the
     35 # original problems.  This workaround is probably not needed anymore.
     36 #
     37 # XXX: Missing error message for the malformed condition. The right-hand
     38 # side before unescaping is double-quotes, backslash, backslash.
     39 .if ${:U\\} != "\\#hash"
     40 .  error
     41 .endif
     42 
     43 # The right-hand side of a comparison is not parsed as a token, therefore
     44 # the code from CondParser_Token does not apply to it.
     45 # TODO: Explain the consequences.
     46 # TODO: Does this mean that more syntactic variants are allowed here?
     47 .if ${:U\#hash} != \#hash
     48 .  error
     49 .endif
     50 
     51 # XXX: What is the purpose of treating an escaped '#' in the following
     52 # condition as a comment?  And why only at the beginning of a token,
     53 # just as in the shell?
     54 .if 0 \# This is treated as a comment, but why?
     55 .  error
     56 .endif
     57 
     58 # Ah, ok, this can be used to add an end-of-condition comment.  But does
     59 # anybody really use this?  This is neither documented nor obvious since
     60 # the '#' is escaped.  It's much clearer to write a comment in the line
     61 # above the condition.
     62 .if ${0 \# comment :?yes:no} != no
     63 .  error
     64 .endif
     65 .if ${1 \# comment :?yes:no} != yes
     66 .  error
     67 .endif
     68 
     69 # Usually there is whitespace around the comparison operator, but this is
     70 # not required.
     71 .if ${UNDEF:Uundefined}!=undefined
     72 .  error
     73 .endif
     74 .if ${UNDEF:U12345}>12345
     75 .  error
     76 .endif
     77 .if ${UNDEF:U12345}<12345
     78 .  error
     79 .endif
     80 .if (${UNDEF:U0})||0
     81 .  error
     82 .endif
     83 
     84 # Only the comparison operator terminates the comparison operand, and it's
     85 # a coincidence that the '!' is both used in the '!=' comparison operator
     86 # as well as for negating a comparison result.
     87 #
     88 # The boolean operators '&' and '|' don't terminate a comparison operand.
     89 .if ${:Uvar}&&name != "var&&name"
     90 .  error
     91 .endif
     92 .if ${:Uvar}||name != "var||name"
     93 .  error
     94 .endif
     95 
     96 # A bare word may appear alone in a condition, without any comparison
     97 # operator.  It is implicitly converted into defined(bare).
     98 .if bare
     99 .  error
    100 .else
    101 .  info A bare word is treated like defined(...), and the variable $\
    102 	'bare' is not defined.
    103 .endif
    104 
    105 VAR=	defined
    106 .if VAR
    107 .  info A bare word is treated like defined(...).
    108 .else
    109 .  error
    110 .endif
    111 
    112 # Bare words may be intermixed with variable expressions.
    113 .if V${:UA}R
    114 .  info ok
    115 .else
    116 .  error
    117 .endif
    118 
    119 # In bare words, even undefined variables are allowed.  Without the bare
    120 # words, undefined variables are not allowed.  That feels inconsistent.
    121 .if V${UNDEF}AR
    122 .  info Undefined variables in bare words expand to an empty string.
    123 .else
    124 .  error
    125 .endif
    126 
    127 .if 0${:Ux00}
    128 .  error
    129 .else
    130 .  info Numbers can be composed from literals and variable expressions.
    131 .endif
    132 
    133 .if 0${:Ux01}
    134 .  info Numbers can be composed from literals and variable expressions.
    135 .else
    136 .  error
    137 .endif
    138 
    139 # If the right-hand side is missing, it's a parse error.
    140 .if "" ==
    141 .  error
    142 .else
    143 .  error
    144 .endif
    145 
    146 # If the left-hand side is missing, it's a parse error as well, but without
    147 # a specific error message.
    148 .if == ""
    149 .  error
    150 .else
    151 .  error
    152 .endif
    153 
    154 # The '\\' is not a line continuation.  Neither is it an unquoted string
    155 # literal.  Instead, it is parsed as a function argument (ParseFuncArg),
    156 # and in that context, the backslash is just an ordinary character. The
    157 # function argument thus stays '\\' (2 backslashes).  This string is passed
    158 # to FuncDefined, and since there is no variable named '\\', the condition
    159 # evaluates to false.
    160 .if \\
    161 .  error
    162 .else
    163 .  info The variable '\\' is not defined.
    164 .endif
    165 
    166 ${:U\\\\}=	backslash
    167 .if \\
    168 .  info Now the variable '\\' is defined.
    169 .else
    170 .  error
    171 .endif
    172 
    173 # Anything that doesn't start with a double quote is considered a "bare word".
    174 # Strangely, a bare word may contain double quotes inside.  Nobody should ever
    175 # depend on this since it may well be unintended.  See CondParser_String.
    176 .if "unquoted\"quoted" != unquoted"quoted
    177 .  error
    178 .endif
    179 
    180 # See cond-token-string.mk for similar tests where the condition is enclosed
    181 # in "quotes".
    182 
    183 all:
    184 	@:;
    185