2023-04-24 23:44:30 +00:00
|
|
|
# $NetBSD: parse-var.mk,v 1.8 2023/02/18 11:16:09 rillig Exp $
|
2023-01-28 00:23:54 +00:00
|
|
|
#
|
|
|
|
# Tests for parsing variable expressions.
|
|
|
|
#
|
|
|
|
# TODO: Add systematic tests for all of the below combinations.
|
|
|
|
#
|
|
|
|
# Written form:
|
|
|
|
# short form
|
|
|
|
# long form with braces endc == '}'
|
|
|
|
# long form with parentheses endc == ')'
|
|
|
|
# indirect modifiers endc == '\0'
|
|
|
|
#
|
|
|
|
# Based on:
|
|
|
|
# undefined variable
|
|
|
|
# global variable
|
|
|
|
# command-line variable
|
|
|
|
# environment variable
|
|
|
|
# target-local variable
|
|
|
|
# legacy variable '@F'
|
|
|
|
#
|
|
|
|
# VarEvalMode:
|
|
|
|
# parse
|
|
|
|
# eval
|
|
|
|
# eval-undeferr
|
|
|
|
# eval-keep-dollar
|
|
|
|
# eval-keep-undef
|
|
|
|
# eval-keep-dollar-undef
|
|
|
|
#
|
|
|
|
# Global mode:
|
|
|
|
# without -dL
|
|
|
|
# with -dL
|
|
|
|
#
|
|
|
|
# Modifiers:
|
|
|
|
# no
|
|
|
|
# yes, stay undefined
|
|
|
|
# convert to defined
|
|
|
|
# indirect modifiers, involving changes to VarEvalMode
|
|
|
|
#
|
|
|
|
# Error conditions:
|
|
|
|
# for the short form, EOF after the '$'
|
|
|
|
# for the short form, each character
|
|
|
|
# for the long forms, EOF right after '${'
|
|
|
|
# for the long forms, EOF after the variable name
|
|
|
|
# for the long forms, EOF after the ':'
|
|
|
|
# for the long forms, EOF after parsing a modifier
|
|
|
|
# for the long forms, ':}'
|
|
|
|
# for each modifier: syntactic error
|
|
|
|
# for each modifier: evaluation error
|
|
|
|
#
|
|
|
|
# Context:
|
|
|
|
# in a condition, only operand, unquoted
|
|
|
|
# in a condition, only operand, quoted
|
|
|
|
# in a condition, left-hand side, unquoted
|
|
|
|
# in a condition, left-hand side, quoted
|
|
|
|
# in a condition, right-hand side, unquoted
|
|
|
|
# in a condition, right-hand side, quoted
|
|
|
|
# left-hand side of a variable assignment
|
|
|
|
# right-hand side of a ':=' variable assignment
|
|
|
|
# right-hand side of a '!=' variable assignment
|
|
|
|
# shell command in a target
|
|
|
|
# .info directive
|
|
|
|
# dependency line
|
|
|
|
# items in a .for loop
|
|
|
|
# everywhere else Var_Parse is called
|
|
|
|
#
|
|
|
|
# Further influences:
|
|
|
|
# multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}'
|
|
|
|
#
|
|
|
|
# Effects:
|
|
|
|
# How much does the parsing position advance (pp)?
|
2023-04-24 23:44:30 +00:00
|
|
|
# What's the value of the expression (return value)?
|
2023-01-28 00:23:54 +00:00
|
|
|
# What error messages are printed (Parse_Error)?
|
|
|
|
# What no-effect error messages are printed (Error)?
|
|
|
|
# What error messages should be printed but aren't?
|
|
|
|
# What other side effects are there?
|
2020-11-07 19:39:21 +00:00
|
|
|
|
|
|
|
.MAKEFLAGS: -dL
|
|
|
|
|
2023-01-28 00:23:54 +00:00
|
|
|
# In variable assignments, there may be spaces in the middle of the left-hand
|
|
|
|
# side of the assignment, but only if they occur inside variable expressions.
|
|
|
|
# Leading spaces (but not tabs) are possible but unusual.
|
|
|
|
# Trailing spaces are common in some coding styles, others omit them.
|
2020-11-07 19:39:21 +00:00
|
|
|
VAR.${:U param }= value
|
|
|
|
.if ${VAR.${:U param }} != "value"
|
|
|
|
. error
|
|
|
|
.endif
|
|
|
|
|
2023-04-24 23:44:30 +00:00
|
|
|
# Since var.c 1.323 from 2020-07-26 18:11 and until var.c 1.1047 from
|
|
|
|
# 2023-02-18, the exact way of parsing an expression with subexpressions
|
|
|
|
# depended on whether the expression was actually evaluated or merely parsed.
|
2023-01-28 00:23:54 +00:00
|
|
|
#
|
|
|
|
# If it was evaluated, nested expressions were parsed correctly, parsing each
|
|
|
|
# modifier according to its exact definition (see varmod.mk).
|
|
|
|
#
|
|
|
|
# If the expression was merely parsed but not evaluated (for example, because
|
|
|
|
# its value would not influence the outcome of the condition, or during the
|
|
|
|
# first pass of the ':@var@body@' modifier), and the expression contained a
|
|
|
|
# modifier, and that modifier contained a nested expression, the nested
|
|
|
|
# expression was not parsed correctly. Instead, make only counted the opening
|
|
|
|
# and closing delimiters, which failed for nested modifiers with unbalanced
|
|
|
|
# braces.
|
|
|
|
|
|
|
|
#.MAKEFLAGS: -dcpv
|
|
|
|
# Keep these braces outside the conditions below, to keep them simple to
|
2023-04-24 23:44:30 +00:00
|
|
|
# understand. If the expression ${BRACE_PAIR:...} had been replaced with the
|
|
|
|
# literal ${:U{}}, the '}' would have to be escaped, but not the '{'. This
|
|
|
|
# asymmetry would have made the example even more complicated to understand.
|
2023-01-28 00:23:54 +00:00
|
|
|
BRACE_PAIR= {}
|
2023-04-24 23:44:30 +00:00
|
|
|
# In this test word, the below conditions will replace the '{{}' in the middle
|
|
|
|
# with the string '<lbraces>'.
|
2023-01-28 00:23:54 +00:00
|
|
|
BRACE_GROUP= {{{{}}}}
|
|
|
|
|
|
|
|
# The inner ':S' modifier turns the word '{}' into '{{}'.
|
|
|
|
# The outer ':S' modifier then replaces '{{}' with '<lbraces>'.
|
2023-04-24 23:44:30 +00:00
|
|
|
# Due to the always-true condition '1', the outer expression is relevant and
|
|
|
|
# is parsed correctly.
|
2023-01-28 00:23:54 +00:00
|
|
|
.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
|
|
|
|
.endif
|
2023-04-24 23:44:30 +00:00
|
|
|
# Due to the always-false condition '0', the outer expression is irrelevant.
|
|
|
|
# In this case, in the parts of the outer ':S' modifier, the expression parser
|
|
|
|
# only counted the braces, and since the inner expression '${BRACE_PAIR:...}'
|
|
|
|
# contains more '{' than '}', parsing failed with the error message 'Unfinished
|
|
|
|
# modifier for "BRACE_GROUP"'. Fixed in var.c 1.1047 from 2023-02-18.
|
2023-01-28 00:23:54 +00:00
|
|
|
.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
|
|
|
|
.endif
|
|
|
|
#.MAKEFLAGS: -d0
|
|
|
|
|
|
|
|
|
|
|
|
all: .PHONY
|