Home | History | Annotate | Line # | Download | only in unit-tests
parse-var.mk revision 1.6
      1  1.6  rillig # $NetBSD: parse-var.mk,v 1.6 2022/09/25 21:26:23 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.6  rillig #	What's the value of the expression (out_val)?
     72  1.6  rillig #	What's the status after parsing the expression (VarParseResult)?
     73  1.6  rillig #	What error messages are printed (Parse_Error)?
     74  1.6  rillig #	What no-effect error messages are printed (Error)?
     75  1.6  rillig #	What error messages should be printed but aren't?
     76  1.6  rillig #	What other side effects are there?
     77  1.1  rillig 
     78  1.1  rillig .MAKEFLAGS: -dL
     79  1.1  rillig 
     80  1.2  rillig # In variable assignments, there may be spaces in the middle of the left-hand
     81  1.2  rillig # side of the assignment, but only if they occur inside variable expressions.
     82  1.2  rillig # Leading spaces (but not tabs) are possible but unusual.
     83  1.2  rillig # Trailing spaces are common in some coding styles, others omit them.
     84  1.1  rillig VAR.${:U param }=	value
     85  1.1  rillig .if ${VAR.${:U param }} != "value"
     86  1.1  rillig .  error
     87  1.1  rillig .endif
     88  1.1  rillig 
     89  1.5  rillig # XXX: The following paragraph already uses past tense, in the hope that the
     90  1.5  rillig # parsing behavior can be cleaned up soon.
     91  1.2  rillig 
     92  1.5  rillig # Since var.c 1.323 from 2020-07-26 18:11 and except for var.c 1.1028 from
     93  1.4  rillig # 2022-08-08, the exact way of parsing an expression depended on whether the
     94  1.4  rillig # expression was actually evaluated or merely parsed.
     95  1.2  rillig #
     96  1.3  rillig # If it was evaluated, nested expressions were parsed correctly, parsing each
     97  1.3  rillig # modifier according to its exact definition (see varmod.mk).
     98  1.2  rillig #
     99  1.3  rillig # If the expression was merely parsed but not evaluated (for example, because
    100  1.3  rillig # its value would not influence the outcome of the condition, or during the
    101  1.3  rillig # first pass of the ':@var@body@' modifier), and the expression contained a
    102  1.3  rillig # modifier, and that modifier contained a nested expression, the nested
    103  1.3  rillig # expression was not parsed correctly.  Instead, make only counted the opening
    104  1.3  rillig # and closing delimiters, which failed for nested modifiers with unbalanced
    105  1.3  rillig # braces.
    106  1.3  rillig #
    107  1.3  rillig # This naive brace counting was implemented in ParseModifierPartDollar.  As of
    108  1.5  rillig # var.c 1.1029, there are still several other places that merely count braces
    109  1.3  rillig # instead of properly parsing subexpressions.
    110  1.2  rillig 
    111  1.2  rillig #.MAKEFLAGS: -dcpv
    112  1.2  rillig # Keep these braces outside the conditions below, to keep them simple to
    113  1.2  rillig # understand.  If the BRACE_PAIR had been replaced with ':U{}', the '}' would
    114  1.2  rillig # have to be escaped, but not the '{'.  This asymmetry would have made the
    115  1.2  rillig # example even more complicated to understand.
    116  1.2  rillig BRACE_PAIR=	{}
    117  1.2  rillig # In this test word, the '{{}' in the middle will be replaced.
    118  1.2  rillig BRACE_GROUP=	{{{{}}}}
    119  1.2  rillig 
    120  1.2  rillig # The inner ':S' modifier turns the word '{}' into '{{}'.
    121  1.2  rillig # The outer ':S' modifier then replaces '{{}' with '<lbraces>'.
    122  1.2  rillig # In the first case, the outer expression is relevant and is parsed correctly.
    123  1.2  rillig .if 1 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
    124  1.2  rillig .endif
    125  1.3  rillig # In the second case, the outer expression was irrelevant.  In this case, in
    126  1.3  rillig # the parts of the outer ':S' modifier, make only counted the braces, and since
    127  1.3  rillig # the inner expression '${BRACE_PAIR:...}' contains more '{' than '}', parsing
    128  1.3  rillig # failed with the error message 'Unfinished modifier for "BRACE_GROUP"'.  Fixed
    129  1.5  rillig # in var.c 1.1028 from 2022-08-08, reverted in var.c 1.1029 from 2022-08-23.
    130  1.2  rillig .if 0 && ${BRACE_GROUP:S,${BRACE_PAIR:S,{,{{,},<lbraces>,}
    131  1.2  rillig .endif
    132  1.2  rillig #.MAKEFLAGS: -d0
    133  1.2  rillig 
    134  1.2  rillig 
    135  1.2  rillig all: .PHONY
    136