Home | History | Annotate | Line # | Download | only in unit-tests
parse-var.mk revision 1.8
      1  1.8  rillig # $NetBSD: parse-var.mk,v 1.8 2023/02/18 11:16:09 rillig Exp $
      2  1.2  rillig #
      3  1.2  rillig # Tests for parsing variable 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.6  rillig #	eval
     24  1.6  rillig #	eval-undeferr
     25  1.6  rillig #	eval-keep-dollar
     26  1.6  rillig #	eval-keep-undef
     27  1.6  rillig #	eval-keep-dollar-undef
     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.2  rillig # side of the assignment, but only if they occur inside variable 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