Home | History | Annotate | Line # | Download | only in unit-tests
cond-token-plain.mk revision 1.9
      1  1.9  rillig # $NetBSD: cond-token-plain.mk,v 1.9 2021/01/21 13:52:32 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.7  rillig # See cond-token-string.mk for similar tests where the condition is enclosed
    181  1.7  rillig # in "quotes".
    182  1.7  rillig 
    183  1.1  rillig all:
    184  1.1  rillig 	@:;
    185