1dbb5be7fSSimon J. Gerraty# $NetBSD: parse-var.mk,v 1.10 2024/06/02 15:31:26 rillig Exp $ 22e36ab23SSimon J. Gerraty# 37a05a715SSimon J. Gerraty# Tests for parsing expressions. 42e36ab23SSimon J. Gerraty# 52e36ab23SSimon J. Gerraty# TODO: Add systematic tests for all of the below combinations. 62e36ab23SSimon J. Gerraty# 72e36ab23SSimon J. Gerraty# Written form: 82e36ab23SSimon J. Gerraty# short form 92e36ab23SSimon J. Gerraty# long form with braces endc == '}' 102e36ab23SSimon J. Gerraty# long form with parentheses endc == ')' 112e36ab23SSimon J. Gerraty# indirect modifiers endc == '\0' 122e36ab23SSimon J. Gerraty# 132e36ab23SSimon J. Gerraty# Based on: 142e36ab23SSimon J. Gerraty# undefined variable 152e36ab23SSimon J. Gerraty# global variable 162e36ab23SSimon J. Gerraty# command-line variable 172e36ab23SSimon J. Gerraty# environment variable 182e36ab23SSimon J. Gerraty# target-local variable 192e36ab23SSimon J. Gerraty# legacy variable '@F' 202e36ab23SSimon J. Gerraty# 212e36ab23SSimon J. Gerraty# VarEvalMode: 222e36ab23SSimon J. Gerraty# parse 23dbb5be7fSSimon J. Gerraty# parse-balanced 242e36ab23SSimon J. Gerraty# eval 25dbb5be7fSSimon J. Gerraty# eval-defined 26dbb5be7fSSimon J. Gerraty# eval-keep-undefined 27dbb5be7fSSimon J. Gerraty# eval-keep-dollar-and-undefined 282e36ab23SSimon J. Gerraty# 292e36ab23SSimon J. Gerraty# Global mode: 302e36ab23SSimon J. Gerraty# without -dL 312e36ab23SSimon J. Gerraty# with -dL 322e36ab23SSimon J. Gerraty# 332e36ab23SSimon J. Gerraty# Modifiers: 342e36ab23SSimon J. Gerraty# no 352e36ab23SSimon J. Gerraty# yes, stay undefined 362e36ab23SSimon J. Gerraty# convert to defined 372e36ab23SSimon J. Gerraty# indirect modifiers, involving changes to VarEvalMode 382e36ab23SSimon J. Gerraty# 392e36ab23SSimon J. Gerraty# Error conditions: 402e36ab23SSimon J. Gerraty# for the short form, EOF after the '$' 412e36ab23SSimon J. Gerraty# for the short form, each character 422e36ab23SSimon J. Gerraty# for the long forms, EOF right after '${' 432e36ab23SSimon J. Gerraty# for the long forms, EOF after the variable name 442e36ab23SSimon J. Gerraty# for the long forms, EOF after the ':' 452e36ab23SSimon J. Gerraty# for the long forms, EOF after parsing a modifier 462e36ab23SSimon J. Gerraty# for the long forms, ':}' 472e36ab23SSimon J. Gerraty# for each modifier: syntactic error 482e36ab23SSimon J. Gerraty# for each modifier: evaluation error 492e36ab23SSimon J. Gerraty# 502e36ab23SSimon J. Gerraty# Context: 512e36ab23SSimon J. Gerraty# in a condition, only operand, unquoted 522e36ab23SSimon J. Gerraty# in a condition, only operand, quoted 532e36ab23SSimon J. Gerraty# in a condition, left-hand side, unquoted 542e36ab23SSimon J. Gerraty# in a condition, left-hand side, quoted 552e36ab23SSimon J. Gerraty# in a condition, right-hand side, unquoted 562e36ab23SSimon J. Gerraty# in a condition, right-hand side, quoted 572e36ab23SSimon J. Gerraty# left-hand side of a variable assignment 582e36ab23SSimon J. Gerraty# right-hand side of a ':=' variable assignment 592e36ab23SSimon J. Gerraty# right-hand side of a '!=' variable assignment 602e36ab23SSimon J. Gerraty# shell command in a target 612e36ab23SSimon J. Gerraty# .info directive 622e36ab23SSimon J. Gerraty# dependency line 632e36ab23SSimon J. Gerraty# items in a .for loop 642e36ab23SSimon J. Gerraty# everywhere else Var_Parse is called 652e36ab23SSimon J. Gerraty# 662e36ab23SSimon J. Gerraty# Further influences: 672e36ab23SSimon J. Gerraty# multi-level evaluations like 'other=${OTHER}' with OTHER='$$ ${THIRD}' 682e36ab23SSimon J. Gerraty# 692e36ab23SSimon J. Gerraty# Effects: 702e36ab23SSimon J. Gerraty# How much does the parsing position advance (pp)? 7151d8a8b4SSimon J. Gerraty# What's the value of the expression (return value)? 722e36ab23SSimon J. Gerraty# What error messages are printed (Parse_Error)? 732e36ab23SSimon J. Gerraty# What no-effect error messages are printed (Error)? 742e36ab23SSimon J. Gerraty# What error messages should be printed but aren't? 752e36ab23SSimon J. Gerraty# What other side effects are there? 76302da1a3SSimon J. Gerraty 77302da1a3SSimon J. Gerraty.MAKEFLAGS: -dL 78302da1a3SSimon J. Gerraty 792e36ab23SSimon J. Gerraty# In variable assignments, there may be spaces in the middle of the left-hand 807a05a715SSimon J. Gerraty# side of the assignment, but only if they occur inside expressions. 812e36ab23SSimon J. Gerraty# Leading spaces (but not tabs) are possible but unusual. 822e36ab23SSimon J. Gerraty# Trailing spaces are common in some coding styles, others omit them. 83302da1a3SSimon J. GerratyVAR.${:U param }= value 84302da1a3SSimon J. Gerraty.if ${VAR.${:U param }} != "value" 85302da1a3SSimon J. Gerraty. error 86302da1a3SSimon J. Gerraty.endif 87302da1a3SSimon J. Gerraty 8851d8a8b4SSimon J. Gerraty# Since var.c 1.323 from 2020-07-26 18:11 and until var.c 1.1047 from 8951d8a8b4SSimon J. Gerraty# 2023-02-18, the exact way of parsing an expression with subexpressions 9051d8a8b4SSimon J. Gerraty# depended on whether the expression was actually evaluated or merely parsed. 912e36ab23SSimon J. Gerraty# 922e36ab23SSimon J. Gerraty# If it was evaluated, nested expressions were parsed correctly, parsing each 932e36ab23SSimon J. Gerraty# modifier according to its exact definition (see varmod.mk). 942e36ab23SSimon J. Gerraty# 952e36ab23SSimon J. Gerraty# If the expression was merely parsed but not evaluated (for example, because 962e36ab23SSimon J. Gerraty# its value would not influence the outcome of the condition, or during the 972e36ab23SSimon J. Gerraty# first pass of the ':@var@body@' modifier), and the expression contained a 982e36ab23SSimon J. Gerraty# modifier, and that modifier contained a nested expression, the nested 992e36ab23SSimon J. Gerraty# expression was not parsed correctly. Instead, make only counted the opening 1002e36ab23SSimon J. Gerraty# and closing delimiters, which failed for nested modifiers with unbalanced 1012e36ab23SSimon J. Gerraty# braces. 1022e36ab23SSimon J. Gerraty 1032e36ab23SSimon J. Gerraty#.MAKEFLAGS: -dcpv 1042e36ab23SSimon J. Gerraty# Keep these braces outside the conditions below, to keep them simple to 10551d8a8b4SSimon J. Gerraty# understand. If the expression ${BRACE_PAIR:...} had been replaced with the 10651d8a8b4SSimon J. Gerraty# literal ${:U{}}, the '}' would have to be escaped, but not the '{'. This 10751d8a8b4SSimon J. Gerraty# asymmetry would have made the example even more complicated to understand. 1082e36ab23SSimon J. GerratyBRACE_PAIR= {} 10951d8a8b4SSimon J. Gerraty# In this test word, the below conditions will replace the '{{}' in the middle 11051d8a8b4SSimon J. Gerraty# with the string '<lbraces>'. 1112e36ab23SSimon J. GerratyBRACE_GROUP= {{{{}}}} 1122e36ab23SSimon J. Gerraty 1132e36ab23SSimon J. Gerraty# The inner ':S' modifier turns the word '{}' into '{{}'. 1142e36ab23SSimon J. Gerraty# The outer ':S' modifier then replaces '{{}' with '<lbraces>'. 11551d8a8b4SSimon J. Gerraty# Due to the always-true condition '1', the outer expression is relevant and 11651d8a8b4SSimon J. Gerraty# is parsed correctly. 1172e36ab23SSimon J. Gerraty.if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 1182e36ab23SSimon J. Gerraty.endif 11951d8a8b4SSimon J. Gerraty# Due to the always-false condition '0', the outer expression is irrelevant. 12051d8a8b4SSimon J. Gerraty# In this case, in the parts of the outer ':S' modifier, the expression parser 12151d8a8b4SSimon J. Gerraty# only counted the braces, and since the inner expression '${BRACE_PAIR:...}' 12251d8a8b4SSimon J. Gerraty# contains more '{' than '}', parsing failed with the error message 'Unfinished 12351d8a8b4SSimon J. Gerraty# modifier for "BRACE_GROUP"'. Fixed in var.c 1.1047 from 2023-02-18. 1242e36ab23SSimon J. Gerraty.if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,} 1252e36ab23SSimon J. Gerraty.endif 1262e36ab23SSimon J. Gerraty#.MAKEFLAGS: -d0 1272e36ab23SSimon J. Gerraty 1282e36ab23SSimon J. Gerraty 1292e36ab23SSimon J. Gerratyall: .PHONY 130