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