freebsd-nq/contrib/bmake/unit-tests/var-op-assign.mk
Simon J. Gerraty 2c3632d14f Update to bmake-20200902
Lots of code refactoring, simplification and cleanup.
Lots of new unit-tests providing much higher code coverage.
All courtesy of rillig at netbsd.

Other significant changes:

o new read-only variable .SHELL which provides the path of the shell
  used to run scripts (as defined by  the .SHELL target).

o variable parsing detects more errors.

o new debug option -dl: LINT mode, does the equivalent of := for all
  variable assignments so that file and line number are reported for
  variable parse errors.
2020-09-05 19:29:42 +00:00

90 lines
2.9 KiB
Makefile

# $NetBSD: var-op-assign.mk,v 1.4 2020/08/25 16:20:32 rillig Exp $
#
# Tests for the = variable assignment operator, which overwrites an existing
# variable or creates it.
# This is a simple variable assignment.
# To the left of the assignment operator '=' there is the variable name,
# and to the right is the variable value.
#
VAR= value
# This condition demonstrates that whitespace around the assignment operator
# is discarded. Otherwise the value would start with a single tab.
#
.if ${VAR} != "value"
.error
.endif
# Whitespace to the left of the assignment operator is ignored as well.
# The variable value can contain arbitrary characters.
#
# The '#' needs to be escaped with a backslash, this happens in a very
# early stage of parsing and applies to all line types, except for the
# commands, which are indented with a tab.
#
# The '$' needs to be escaped with another '$', otherwise it would refer to
# another variable.
#
VAR =new value and \# some $$ special characters # comment
# When a string literal appears in a condition, the escaping rules are
# different. Run make with the -dc option to see the details.
.if ${VAR} != "new value and \# some \$ special characters"
.error ${VAR}
.endif
# The variable value may contain references to other variables.
# In this example, the reference is to the variable with the empty name,
# which always expands to an empty string. This alone would not produce
# any side-effects, therefore the variable has a :!...! modifier that
# executes a shell command.
VAR= ${:! echo 'not yet evaluated' 1>&2 !}
VAR= ${:! echo 'this will be evaluated later' 1>&2 !}
# Now force the variable to be evaluated.
# This outputs the line to stderr.
.if ${VAR}
.endif
# In a variable assignment, the variable name must consist of a single word.
#
VARIABLE NAME= variable value
# But if the whitespace appears inside parentheses or braces, everything is
# fine.
#
# XXX: This was not an intentional decision, as variable names typically
# neither contain parentheses nor braces. This is only a side-effect from
# the implementation of the parser, which cheats when parsing a variable
# name. It only counts parentheses and braces instead of properly parsing
# nested variable expressions such as VAR.${param}.
#
VAR(spaces in parentheses)= ()
VAR{spaces in braces}= {}
# Be careful and use indirect variable names here, to prevent accidentally
# accepting the test in case the parser just uses "VAR" as the variable name,
# ignoring all the rest.
#
VARNAME_PAREN= VAR(spaces in parentheses)
VARNAME_BRACES= VAR{spaces in braces}
.if ${${VARNAME_PAREN}} != "()"
.error
.endif
.if ${${VARNAME_BRACES}} != "{}"
.error
.endif
# In safe mode, parsing would stop immediately after the "VARIABLE NAME="
# line, since any commands run after that are probably working with
# unexpected variable values.
#
# Therefore, just output an info message.
.info Parsing still continues until here.
all:
@:;