Home | History | Annotate | Line # | Download | only in unit-tests
var-op-assign.mk revision 1.12
      1  1.12  rillig # $NetBSD: var-op-assign.mk,v 1.12 2025/06/28 22:39:29 rillig Exp $
      2   1.1  rillig #
      3   1.2  rillig # Tests for the = variable assignment operator, which overwrites an existing
      4   1.2  rillig # variable or creates it.
      5   1.1  rillig 
      6   1.3  rillig # This is a simple variable assignment.
      7   1.3  rillig # To the left of the assignment operator '=' there is the variable name,
      8   1.7  rillig # and to the right is the variable value.  The variable value is stored as-is,
      9   1.7  rillig # it is not expanded in any way.
     10   1.3  rillig #
     11   1.3  rillig VAR=	value
     12   1.3  rillig 
     13   1.3  rillig # This condition demonstrates that whitespace around the assignment operator
     14   1.3  rillig # is discarded.  Otherwise the value would start with a single tab.
     15   1.3  rillig #
     16   1.3  rillig .if ${VAR} != "value"
     17   1.5  rillig .  error
     18   1.3  rillig .endif
     19   1.3  rillig 
     20   1.3  rillig # Whitespace to the left of the assignment operator is ignored as well.
     21   1.3  rillig # The variable value can contain arbitrary characters.
     22   1.3  rillig #
     23   1.3  rillig # The '#' needs to be escaped with a backslash, this happens in a very
     24   1.3  rillig # early stage of parsing and applies to all line types, except for the
     25   1.3  rillig # commands, which are indented with a tab.
     26   1.3  rillig #
     27   1.3  rillig # The '$' needs to be escaped with another '$', otherwise it would refer to
     28   1.3  rillig # another variable.
     29   1.3  rillig #
     30   1.6  rillig VAR=	new value and \# some $$ special characters	# comment
     31   1.3  rillig 
     32   1.3  rillig # When a string literal appears in a condition, the escaping rules are
     33   1.3  rillig # different.  Run make with the -dc option to see the details.
     34   1.3  rillig .if ${VAR} != "new value and \# some \$ special characters"
     35   1.5  rillig .  error ${VAR}
     36   1.3  rillig .endif
     37   1.3  rillig 
     38   1.3  rillig # The variable value may contain references to other variables.
     39   1.3  rillig # In this example, the reference is to the variable with the empty name,
     40   1.7  rillig # which is never defined.
     41   1.7  rillig #
     42   1.7  rillig # This alone would not produce any side-effects, therefore the variable has
     43   1.7  rillig # a :!...! modifier that executes a shell command.  The :!...! modifier turns
     44   1.7  rillig # an undefined expression into a defined one, see ApplyModifier_ShellCommand,
     45   1.8  rillig # the call to Expr_Define.
     46   1.7  rillig #
     47   1.7  rillig # Since the right-hand side of a '=' assignment is not expanded at the time
     48   1.7  rillig # when the variable is defined, the first command is not run at all.
     49   1.3  rillig VAR=	${:! echo 'not yet evaluated' 1>&2 !}
     50   1.3  rillig VAR=	${:! echo 'this will be evaluated later' 1>&2 !}
     51   1.3  rillig 
     52   1.3  rillig # Now force the variable to be evaluated.
     53   1.3  rillig # This outputs the line to stderr.
     54   1.3  rillig .if ${VAR}
     55   1.3  rillig .endif
     56   1.1  rillig 
     57   1.4  rillig # In a variable assignment, the variable name must consist of a single word.
     58   1.7  rillig # The following line therefore generates a parse error.
     59  1.12  rillig # expect+1: Invalid line "VARIABLE NAME=	variable value"
     60   1.4  rillig VARIABLE NAME=	variable value
     61   1.4  rillig 
     62   1.4  rillig # But if the whitespace appears inside parentheses or braces, everything is
     63   1.4  rillig # fine.
     64   1.4  rillig #
     65   1.4  rillig # XXX: This was not an intentional decision, as variable names typically
     66   1.4  rillig # neither contain parentheses nor braces.  This is only a side-effect from
     67   1.4  rillig # the implementation of the parser, which cheats when parsing a variable
     68   1.4  rillig # name.  It only counts parentheses and braces instead of properly parsing
     69  1.11  rillig # nested expressions such as VAR.${param}.
     70   1.4  rillig #
     71   1.4  rillig VAR(spaces in parentheses)=	()
     72   1.4  rillig VAR{spaces in braces}=		{}
     73   1.4  rillig 
     74   1.4  rillig # Be careful and use indirect variable names here, to prevent accidentally
     75   1.4  rillig # accepting the test in case the parser just uses "VAR" as the variable name,
     76   1.4  rillig # ignoring all the rest.
     77   1.4  rillig #
     78   1.4  rillig VARNAME_PAREN=	VAR(spaces in parentheses)
     79   1.4  rillig VARNAME_BRACES=	VAR{spaces in braces}
     80   1.4  rillig 
     81   1.4  rillig .if ${${VARNAME_PAREN}} != "()"
     82   1.5  rillig .  error
     83   1.4  rillig .endif
     84   1.4  rillig 
     85   1.4  rillig .if ${${VARNAME_BRACES}} != "{}"
     86   1.5  rillig .  error
     87   1.4  rillig .endif
     88   1.4  rillig 
     89   1.4  rillig # In safe mode, parsing would stop immediately after the "VARIABLE NAME="
     90   1.4  rillig # line, since any commands run after that are probably working with
     91   1.4  rillig # unexpected variable values.
     92   1.4  rillig #
     93   1.4  rillig # Therefore, just output an info message.
     94   1.9  rillig # expect+1: Parsing still continues until here.
     95   1.4  rillig .info Parsing still continues until here.
     96   1.4  rillig 
     97   1.1  rillig all:
     98   1.1  rillig 	@:;
     99