Home | History | Annotate | Line # | Download | only in unit-tests
      1  1.18  rillig # $NetBSD: varname.mk,v 1.18 2025/06/28 22:39:29 rillig Exp $
      2   1.1  rillig #
      3  1.17  rillig # Tests for variable names.
      4   1.1  rillig 
      5   1.5  rillig .MAKEFLAGS: -dv
      6   1.5  rillig 
      7  1.17  rillig # In a variable assignment, braces are allowed in the variable name, but they
      8  1.17  rillig # must be balanced.  Parentheses and braces may be mixed.
      9   1.5  rillig VAR{{{}}}=	3 braces
     10   1.5  rillig .if "${VAR{{{}}}}" != "3 braces"
     11   1.5  rillig .  error
     12   1.5  rillig .endif
     13   1.5  rillig 
     14  1.14  rillig # In expressions, the parser works differently.  It doesn't treat
     15   1.5  rillig # braces and parentheses equally, therefore the first closing brace already
     16   1.5  rillig # marks the end of the variable name.
     17   1.5  rillig VARNAME=	VAR(((
     18   1.5  rillig ${VARNAME}=	3 open parentheses
     19   1.5  rillig .if "${VAR(((}}}}" != "3 open parentheses}}}"
     20   1.5  rillig .  error
     21   1.5  rillig .endif
     22   1.5  rillig 
     23   1.5  rillig # In the above test, the variable name is constructed indirectly.  Neither
     24   1.5  rillig # of the following expressions produces the intended effect.
     25   1.7  rillig #
     26   1.7  rillig # This is not a variable assignment since the parentheses and braces are not
     27   1.7  rillig # balanced.  At the end of the line, there are still 3 levels open, which
     28   1.7  rillig # means the variable name is not finished.
     29  1.18  rillig # expect+2: Missing ")" in archive specification
     30  1.16  rillig # expect+1: Error in archive specification: "VAR"
     31   1.6  rillig ${:UVAR(((}=	try1
     32   1.8  rillig # On the left-hand side of a variable assignments, the backslash is not parsed
     33   1.8  rillig # as an escape character, therefore the parentheses still count to the nesting
     34   1.8  rillig # level, which at the end of the line is still 3.  Therefore this is not a
     35   1.8  rillig # variable assignment as well.
     36  1.18  rillig # expect+1: Invalid line "${:UVAR\(\(\(}=	try2", expanded to "VAR\(\(\(=	try2"
     37   1.6  rillig ${:UVAR\(\(\(}=	try2
     38   1.8  rillig # To assign to a variable with an arbitrary name, the variable name has to
     39   1.8  rillig # come from an external source, not the text that is parsed in the assignment
     40   1.8  rillig # itself.  This is exactly the reason why further above, the indirect
     41   1.8  rillig # ${VARNAME} works, while all other attempts fail.
     42   1.8  rillig ${VARNAME}=	try3
     43   1.5  rillig 
     44   1.5  rillig .MAKEFLAGS: -d0
     45   1.1  rillig 
     46   1.9  rillig # All variable names of a scope are stored in the same hash table, using a
     47  1.10  rillig # simple hash function.  Ensure that HashTable_Find handles collisions
     48   1.9  rillig # correctly and that the correct variable is looked up.  The strings "0x" and
     49   1.9  rillig # "1Y" have the same hash code, as 31 * '0' + 'x' == 31 * '1' + 'Y'.
     50   1.9  rillig V.0x=	0x
     51   1.9  rillig V.1Y=	1Y
     52   1.9  rillig .if ${V.0x} != "0x" || ${V.1Y} != "1Y"
     53   1.9  rillig .  error
     54   1.9  rillig .endif
     55   1.9  rillig 
     56   1.9  rillig # The string "ASDZguv", when used as a prefix of a variable name, keeps the
     57   1.9  rillig # hash code unchanged, its own hash code is 0.
     58   1.9  rillig ASDZguvV.0x=	0x
     59   1.9  rillig ASDZguvV.1Y=	1Y
     60   1.9  rillig .if ${ASDZguvV.0x} != "0x"
     61   1.9  rillig .  error
     62   1.9  rillig .elif ${ASDZguvV.1Y} != "1Y"
     63   1.9  rillig .  error
     64   1.9  rillig .endif
     65   1.9  rillig 
     66   1.9  rillig # Ensure that variables with the same hash code whose name is a prefix of the
     67   1.9  rillig # other can be accessed.  In this case, the shorter variable name is defined
     68   1.9  rillig # first to make it appear later in the bucket of the hash table.
     69   1.9  rillig ASDZguv=	once
     70   1.9  rillig ASDZguvASDZguv=	twice
     71   1.9  rillig .if ${ASDZguv} != "once"
     72   1.9  rillig .  error
     73   1.9  rillig .elif ${ASDZguvASDZguv} != "twice"
     74   1.9  rillig .  error
     75   1.9  rillig .endif
     76   1.9  rillig 
     77   1.9  rillig # Ensure that variables with the same hash code whose name is a prefix of the
     78   1.9  rillig # other can be accessed.  In this case, the longer variable name is defined
     79   1.9  rillig # first to make it appear later in the bucket of the hash table.
     80   1.9  rillig ASDZguvASDZguv.param=	twice
     81   1.9  rillig ASDZguv.param=		once
     82   1.9  rillig .if ${ASDZguv.param} != "once"
     83   1.9  rillig .  error
     84   1.9  rillig .elif ${ASDZguvASDZguv.param} != "twice"
     85   1.9  rillig .  error
     86   1.9  rillig .endif
     87   1.9  rillig 
     88  1.17  rillig 
     89  1.17  rillig # Warn about expressions in the style of GNU make, as these would silently
     90  1.17  rillig # expand to an empty string instead.
     91  1.17  rillig #
     92  1.17  rillig # https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html says:
     93  1.17  rillig #	a macro name shall not contain an <equals-sign>, <blank>, or control
     94  1.17  rillig #	character.
     95  1.17  rillig #
     96  1.17  rillig GNU_MAKE_IF=	$(if ${HAVE_STRLEN},yes,no)
     97  1.17  rillig # expect+1: warning: Invalid character " " in variable name "if ,yes,no"
     98  1.17  rillig .if ${GNU_MAKE_IF} != ""
     99  1.17  rillig .  error
    100  1.17  rillig .endif
    101  1.17  rillig #
    102  1.17  rillig # This requirement needs to be ignored for expressions with a ":L" or ":?:"
    103  1.17  rillig # modifier, as these modifiers rely on arbitrary characters in the expression
    104  1.17  rillig # name.
    105  1.17  rillig .if ${"left" == "right":?equal:unequal} != "unequal"
    106  1.17  rillig .  error
    107  1.17  rillig .endif
    108  1.17  rillig #
    109  1.17  rillig # In fact, this requirement is ignored for any expression that has a modifier.
    110  1.17  rillig # In this indirect case, though, the expression with the space in the name is
    111  1.17  rillig # a nested expression, so the ":U" modifier doesn't affect the warning.
    112  1.17  rillig # expect+1: warning: Invalid character " " in variable name "if ,yes,no"
    113  1.17  rillig .if ${GNU_MAKE_IF:Ufallback} != ""
    114  1.17  rillig .  error
    115  1.17  rillig .endif
    116  1.17  rillig #
    117  1.17  rillig # A modifier in a nested expression does not affect the warning.
    118  1.17  rillig GNU_MAKE_IF_EXPR=	$(if ${HAVE_STRLEN},${HEADERS:.h=.c},)
    119  1.17  rillig # expect+1: warning: Invalid character " " in variable name "if ,,"
    120  1.17  rillig .if ${GNU_MAKE_IF_EXPR} != ""
    121  1.17  rillig .  error
    122  1.17  rillig .endif
    123  1.17  rillig #
    124  1.17  rillig # When the GNU make expression contains a colon, chances are good that the
    125  1.17  rillig # colon is interpreted as an unknown modifier.
    126  1.17  rillig GNU_MAKE_IF_MODIFIER=	$(if ${HAVE_STRLEN},answer:yes,answer:no)
    127  1.17  rillig # expect+1: Unknown modifier ":yes,answer"
    128  1.17  rillig .if ${GNU_MAKE_IF_MODIFIER} != "no)"
    129  1.17  rillig .  error
    130  1.17  rillig .endif
    131  1.17  rillig #
    132  1.17  rillig # If the variable name contains a non-printable character, the warning
    133  1.17  rillig # contains the numeric character value instead, to prevent control sequences
    134  1.17  rillig # in the output.
    135  1.17  rillig CONTROL_CHARACTER=	${:U a b:ts\t}
    136  1.17  rillig # expect+2: warning: Invalid character "\x09" in variable name "a	b"
    137  1.17  rillig # expect+1: Variable "a	b" is undefined
    138  1.17  rillig .if ${${CONTROL_CHARACTER}} != ""
    139  1.17  rillig .endif
    140  1.17  rillig #
    141  1.17  rillig # For now, only whitespace generates a warning, non-ASCII characters don't.
    142  1.17  rillig UMLAUT=		
    143  1.17  rillig # expect+1: Variable "" is undefined
    144  1.17  rillig .if ${${UMLAUT}} != ""
    145  1.17  rillig .endif
    146