1*8d5c8e21SSimon J. Gerraty# $NetBSD: parse-var.mk,v 1.10 2024/06/02 15:31:26 rillig Exp $ 24fde40d9SSimon J. Gerraty# 3d5e0a182SSimon J. Gerraty# Tests for parsing expressions. 44fde40d9SSimon J. Gerraty# 54fde40d9SSimon J. Gerraty# TODO: Add systematic tests for all of the below combinations. 64fde40d9SSimon J. Gerraty# 74fde40d9SSimon J. Gerraty# Written form: 84fde40d9SSimon J. Gerraty# short form 94fde40d9SSimon J. Gerraty# long form with braces endc == '}' 104fde40d9SSimon J. Gerraty# long form with parentheses endc == ')' 114fde40d9SSimon J. Gerraty# indirect modifiers endc == '\0' 124fde40d9SSimon J. Gerraty# 134fde40d9SSimon J. Gerraty# Based on: 144fde40d9SSimon J. Gerraty# undefined variable 154fde40d9SSimon J. Gerraty# global variable 164fde40d9SSimon J. Gerraty# command-line variable 174fde40d9SSimon J. Gerraty# environment variable 184fde40d9SSimon J. Gerraty# target-local variable 194fde40d9SSimon J. Gerraty# legacy variable '@F' 204fde40d9SSimon J. Gerraty# 214fde40d9SSimon J. Gerraty# VarEvalMode: 224fde40d9SSimon J. Gerraty# parse 23*8d5c8e21SSimon J. Gerraty# parse-balanced 244fde40d9SSimon J. Gerraty# eval 25*8d5c8e21SSimon J. Gerraty# eval-defined 26*8d5c8e21SSimon J. Gerraty# eval-keep-undefined 27*8d5c8e21SSimon J. Gerraty# eval-keep-dollar-and-undefined 284fde40d9SSimon J. Gerraty# 294fde40d9SSimon J. Gerraty# Global mode: 304fde40d9SSimon J. Gerraty# without -dL 314fde40d9SSimon J. Gerraty# with -dL 324fde40d9SSimon J. Gerraty# 334fde40d9SSimon J. Gerraty# Modifiers: 344fde40d9SSimon J. Gerraty# no 354fde40d9SSimon J. Gerraty# yes, stay undefined 364fde40d9SSimon J. Gerraty# convert to defined 374fde40d9SSimon J. Gerraty# indirect modifiers, involving changes to VarEvalMode 384fde40d9SSimon J. Gerraty# 394fde40d9SSimon J. Gerraty# Error conditions: 404fde40d9SSimon J. Gerraty# for the short form, EOF after the '$' 414fde40d9SSimon J. Gerraty# for the short form, each character 424fde40d9SSimon J. Gerraty# for the long forms, EOF right after '${' 434fde40d9SSimon J. Gerraty# for the long forms, EOF after the variable name 444fde40d9SSimon J. Gerraty# for the long forms, EOF after the ':' 454fde40d9SSimon J. Gerraty# for the long forms, EOF after parsing a modifier 464fde40d9SSimon J. Gerraty# for the long forms, ':}' 474fde40d9SSimon J. Gerraty# for each modifier: syntactic error 484fde40d9SSimon J. Gerraty# for each modifier: evaluation error 494fde40d9SSimon J. Gerraty# 504fde40d9SSimon J. Gerraty# Context: 514fde40d9SSimon J. Gerraty# in a condition, only operand, unquoted 524fde40d9SSimon J. Gerraty# in a condition, only operand, quoted 534fde40d9SSimon J. Gerraty# in a condition, left-hand side, unquoted 544fde40d9SSimon J. Gerraty# in a condition, left-hand side, quoted 554fde40d9SSimon J. Gerraty# in a condition, right-hand side, unquoted 564fde40d9SSimon J. Gerraty# in a condition, right-hand side, quoted 574fde40d9SSimon J. Gerraty# left-hand side of a variable assignment 584fde40d9SSimon J. Gerraty# right-hand side of a ':=' variable assignment 594fde40d9SSimon J. Gerraty# right-hand side of a '!=' variable assignment 604fde40d9SSimon J. Gerraty# shell command in a target 614fde40d9SSimon J. Gerraty# .info directive 624fde40d9SSimon J. Gerraty# dependency line 634fde40d9SSimon J. Gerraty# items in a .for loop 644fde40d9SSimon J. Gerraty# everywhere else Var_Parse is called 654fde40d9SSimon J. Gerraty# 664fde40d9SSimon J. Gerraty# Further influences: 674fde40d9SSimon J. Gerraty# multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}' 684fde40d9SSimon J. Gerraty# 694fde40d9SSimon J. Gerraty# Effects: 704fde40d9SSimon J. Gerraty# How much does the parsing position advance (pp)? 718c973ee2SSimon J. Gerraty# What's the value of the expression (return value)? 724fde40d9SSimon J. Gerraty# What error messages are printed (Parse_Error)? 734fde40d9SSimon J. Gerraty# What no-effect error messages are printed (Error)? 744fde40d9SSimon J. Gerraty# What error messages should be printed but aren't? 754fde40d9SSimon J. Gerraty# What other side effects are there? 76956e45f6SSimon J. Gerraty 77956e45f6SSimon J. Gerraty.MAKEFLAGS: -dL 78956e45f6SSimon J. Gerraty 794fde40d9SSimon J. Gerraty# In variable assignments, there may be spaces in the middle of the left-hand 80d5e0a182SSimon J. Gerraty# side of the assignment, but only if they occur inside expressions. 814fde40d9SSimon J. Gerraty# Leading spaces (but not tabs) are possible but unusual. 824fde40d9SSimon J. Gerraty# Trailing spaces are common in some coding styles, others omit them. 83956e45f6SSimon J. GerratyVAR.${:U param }= value 84956e45f6SSimon J. Gerraty.if ${VAR.${:U param }} != "value" 85956e45f6SSimon J. Gerraty. error 86956e45f6SSimon J. Gerraty.endif 87956e45f6SSimon J. Gerraty 888c973ee2SSimon J. Gerraty# Since var.c 1.323 from 2020-07-26 18:11 and until var.c 1.1047 from 898c973ee2SSimon J. Gerraty# 2023-02-18, the exact way of parsing an expression with subexpressions 908c973ee2SSimon J. Gerraty# depended on whether the expression was actually evaluated or merely parsed. 914fde40d9SSimon J. Gerraty# 924fde40d9SSimon J. Gerraty# If it was evaluated, nested expressions were parsed correctly, parsing each 934fde40d9SSimon J. Gerraty# modifier according to its exact definition (see varmod.mk). 944fde40d9SSimon J. Gerraty# 954fde40d9SSimon J. Gerraty# If the expression was merely parsed but not evaluated (for example, because 964fde40d9SSimon J. Gerraty# its value would not influence the outcome of the condition, or during the 974fde40d9SSimon J. Gerraty# first pass of the ':@var@body@' modifier), and the expression contained a 984fde40d9SSimon J. Gerraty# modifier, and that modifier contained a nested expression, the nested 994fde40d9SSimon J. Gerraty# expression was not parsed correctly. Instead, make only counted the opening 1004fde40d9SSimon J. Gerraty# and closing delimiters, which failed for nested modifiers with unbalanced 1014fde40d9SSimon J. Gerraty# braces. 1024fde40d9SSimon J. Gerraty 1034fde40d9SSimon J. Gerraty#.MAKEFLAGS: -dcpv 1044fde40d9SSimon J. Gerraty# Keep these braces outside the conditions below, to keep them simple to 1058c973ee2SSimon J. Gerraty# understand. If the expression ${BRACE_PAIR:...} had been replaced with the 1068c973ee2SSimon J. Gerraty# literal ${:U{}}, the '}' would have to be escaped, but not the '{'. This 1078c973ee2SSimon J. Gerraty# asymmetry would have made the example even more complicated to understand. 1084fde40d9SSimon J. GerratyBRACE_PAIR= {} 1098c973ee2SSimon J. Gerraty# In this test word, the below conditions will replace the '{{}' in the middle 1108c973ee2SSimon J. Gerraty# with the string '<lbraces>'. 1114fde40d9SSimon J. GerratyBRACE_GROUP= {{{{}}}} 1124fde40d9SSimon J. Gerraty 1134fde40d9SSimon J. Gerraty# The inner ':S' modifier turns the word '{}' into '{{}'. 1144fde40d9SSimon J. Gerraty# The outer ':S' modifier then replaces '{{}' with '<lbraces>'. 1158c973ee2SSimon J. Gerraty# Due to the always-true condition '1', the outer expression is relevant and 1168c973ee2SSimon J. Gerraty# is parsed correctly. 1174fde40d9SSimon J. Gerraty.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 1184fde40d9SSimon J. Gerraty.endif 1198c973ee2SSimon J. Gerraty# Due to the always-false condition '0', the outer expression is irrelevant. 1208c973ee2SSimon J. Gerraty# In this case, in the parts of the outer ':S' modifier, the expression parser 1218c973ee2SSimon J. Gerraty# only counted the braces, and since the inner expression '${BRACE_PAIR:...}' 1228c973ee2SSimon J. Gerraty# contains more '{' than '}', parsing failed with the error message 'Unfinished 1238c973ee2SSimon J. Gerraty# modifier for "BRACE_GROUP"'. Fixed in var.c 1.1047 from 2023-02-18. 1244fde40d9SSimon J. Gerraty.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 1254fde40d9SSimon J. Gerraty.endif 1264fde40d9SSimon J. Gerraty#.MAKEFLAGS: -d0 1274fde40d9SSimon J. Gerraty 1284fde40d9SSimon J. Gerraty 1294fde40d9SSimon J. Gerratyall: .PHONY 130