1# $NetBSD: varname.mk,v 1.14 2023/11/19 21:47:52 rillig Exp $ 2# 3# Tests for special variables, such as .MAKE or .PARSEDIR. 4# And for variable names in general. 5 6.MAKEFLAGS: -dv 7 8# In variable names, braces are allowed, but they must be balanced. 9# Parentheses and braces may be mixed. 10VAR{{{}}}= 3 braces 11.if "${VAR{{{}}}}" != "3 braces" 12. error 13.endif 14 15# In expressions, the parser works differently. It doesn't treat 16# braces and parentheses equally, therefore the first closing brace already 17# marks the end of the variable name. 18VARNAME= VAR((( 19${VARNAME}= 3 open parentheses 20.if "${VAR(((}}}}" != "3 open parentheses}}}" 21. error 22.endif 23 24# In the above test, the variable name is constructed indirectly. Neither 25# of the following expressions produces the intended effect. 26# 27# This is not a variable assignment since the parentheses and braces are not 28# balanced. At the end of the line, there are still 3 levels open, which 29# means the variable name is not finished. 30# expect+2: Error in archive specification: "VAR" 31# expect+1: No closing parenthesis in archive specification 32${:UVAR(((}= try1 33# On the left-hand side of a variable assignments, the backslash is not parsed 34# as an escape character, therefore the parentheses still count to the nesting 35# level, which at the end of the line is still 3. Therefore this is not a 36# variable assignment as well. 37# expect+1: Invalid line '${:UVAR\(\(\(}= try2', expanded to 'VAR\(\(\(= try2' 38${:UVAR\(\(\(}= try2 39# To assign to a variable with an arbitrary name, the variable name has to 40# come from an external source, not the text that is parsed in the assignment 41# itself. This is exactly the reason why further above, the indirect 42# ${VARNAME} works, while all other attempts fail. 43${VARNAME}= try3 44 45.MAKEFLAGS: -d0 46 47# All variable names of a scope are stored in the same hash table, using a 48# simple hash function. Ensure that HashTable_Find handles collisions 49# correctly and that the correct variable is looked up. The strings "0x" and 50# "1Y" have the same hash code, as 31 * '0' + 'x' == 31 * '1' + 'Y'. 51V.0x= 0x 52V.1Y= 1Y 53.if ${V.0x} != "0x" || ${V.1Y} != "1Y" 54. error 55.endif 56 57# The string "ASDZguv", when used as a prefix of a variable name, keeps the 58# hash code unchanged, its own hash code is 0. 59ASDZguvV.0x= 0x 60ASDZguvV.1Y= 1Y 61.if ${ASDZguvV.0x} != "0x" 62. error 63.elif ${ASDZguvV.1Y} != "1Y" 64. error 65.endif 66 67# Ensure that variables with the same hash code whose name is a prefix of the 68# other can be accessed. In this case, the shorter variable name is defined 69# first to make it appear later in the bucket of the hash table. 70ASDZguv= once 71ASDZguvASDZguv= twice 72.if ${ASDZguv} != "once" 73. error 74.elif ${ASDZguvASDZguv} != "twice" 75. error 76.endif 77 78# Ensure that variables with the same hash code whose name is a prefix of the 79# other can be accessed. In this case, the longer variable name is defined 80# first to make it appear later in the bucket of the hash table. 81ASDZguvASDZguv.param= twice 82ASDZguv.param= once 83.if ${ASDZguv.param} != "once" 84. error 85.elif ${ASDZguvASDZguv.param} != "twice" 86. error 87.endif 88 89all: 90