1# $NetBSD: parse-var.mk,v 1.6 2022/09/25 21:26:23 rillig Exp $ 2# 3# Tests for parsing variable expressions. 4# 5# TODO: Add systematic tests for all of the below combinations. 6# 7# Written form: 8# short form 9# long form with braces endc == '}' 10# long form with parentheses endc == ')' 11# indirect modifiers endc == '\0' 12# 13# Based on: 14# undefined variable 15# global variable 16# command-line variable 17# environment variable 18# target-local variable 19# legacy variable '@F' 20# 21# VarEvalMode: 22# parse 23# eval 24# eval-undeferr 25# eval-keep-dollar 26# eval-keep-undef 27# eval-keep-dollar-undef 28# 29# Global mode: 30# without -dL 31# with -dL 32# 33# Modifiers: 34# no 35# yes, stay undefined 36# convert to defined 37# indirect modifiers, involving changes to VarEvalMode 38# 39# Error conditions: 40# for the short form, EOF after the '$' 41# for the short form, each character 42# for the long forms, EOF right after '${' 43# for the long forms, EOF after the variable name 44# for the long forms, EOF after the ':' 45# for the long forms, EOF after parsing a modifier 46# for the long forms, ':}' 47# for each modifier: syntactic error 48# for each modifier: evaluation error 49# 50# Context: 51# in a condition, only operand, unquoted 52# in a condition, only operand, quoted 53# in a condition, left-hand side, unquoted 54# in a condition, left-hand side, quoted 55# in a condition, right-hand side, unquoted 56# in a condition, right-hand side, quoted 57# left-hand side of a variable assignment 58# right-hand side of a ':=' variable assignment 59# right-hand side of a '!=' variable assignment 60# shell command in a target 61# .info directive 62# dependency line 63# items in a .for loop 64# everywhere else Var_Parse is called 65# 66# Further influences: 67# multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}' 68# 69# Effects: 70# How much does the parsing position advance (pp)? 71# What's the value of the expression (out_val)? 72# What's the status after parsing the expression (VarParseResult)? 73# What error messages are printed (Parse_Error)? 74# What no-effect error messages are printed (Error)? 75# What error messages should be printed but aren't? 76# What other side effects are there? 77 78.MAKEFLAGS: -dL 79 80# In variable assignments, there may be spaces in the middle of the left-hand 81# side of the assignment, but only if they occur inside variable expressions. 82# Leading spaces (but not tabs) are possible but unusual. 83# Trailing spaces are common in some coding styles, others omit them. 84VAR.${:U param }= value 85.if ${VAR.${:U param }} != "value" 86. error 87.endif 88 89# XXX: The following paragraph already uses past tense, in the hope that the 90# parsing behavior can be cleaned up soon. 91 92# Since var.c 1.323 from 2020-07-26 18:11 and except for var.c 1.1028 from 93# 2022-08-08, the exact way of parsing an expression depended on whether the 94# expression was actually evaluated or merely parsed. 95# 96# If it was evaluated, nested expressions were parsed correctly, parsing each 97# modifier according to its exact definition (see varmod.mk). 98# 99# If the expression was merely parsed but not evaluated (for example, because 100# its value would not influence the outcome of the condition, or during the 101# first pass of the ':@var@body@' modifier), and the expression contained a 102# modifier, and that modifier contained a nested expression, the nested 103# expression was not parsed correctly. Instead, make only counted the opening 104# and closing delimiters, which failed for nested modifiers with unbalanced 105# braces. 106# 107# This naive brace counting was implemented in ParseModifierPartDollar. As of 108# var.c 1.1029, there are still several other places that merely count braces 109# instead of properly parsing subexpressions. 110 111#.MAKEFLAGS: -dcpv 112# Keep these braces outside the conditions below, to keep them simple to 113# understand. If the BRACE_PAIR had been replaced with ':U{}', the '}' would 114# have to be escaped, but not the '{'. This asymmetry would have made the 115# example even more complicated to understand. 116BRACE_PAIR= {} 117# In this test word, the '{{}' in the middle will be replaced. 118BRACE_GROUP= {{{{}}}} 119 120# The inner ':S' modifier turns the word '{}' into '{{}'. 121# The outer ':S' modifier then replaces '{{}' with '<lbraces>'. 122# In the first case, the outer expression is relevant and is parsed correctly. 123.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 124.endif 125# In the second case, the outer expression was irrelevant. In this case, in 126# the parts of the outer ':S' modifier, make only counted the braces, and since 127# the inner expression '${BRACE_PAIR:...}' contains more '{' than '}', parsing 128# failed with the error message 'Unfinished modifier for "BRACE_GROUP"'. Fixed 129# in var.c 1.1028 from 2022-08-08, reverted in var.c 1.1029 from 2022-08-23. 130.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 131.endif 132#.MAKEFLAGS: -d0 133 134 135all: .PHONY 136