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