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