Home | History | Annotate | Line # | Download | only in unit-tests
varparse-errors.mk revision 1.21
      1  1.21  rillig # $NetBSD: varparse-errors.mk,v 1.21 2025/03/29 21:30:48 rillig Exp $
      2   1.1  rillig 
      3  1.10  rillig # Tests for parsing and evaluating all kinds of expressions.
      4   1.1  rillig #
      5   1.1  rillig # This is the basis for redesigning the error handling in Var_Parse and
      6   1.1  rillig # Var_Subst, collecting typical and not so typical use cases.
      7   1.1  rillig #
      8   1.1  rillig # See also:
      9   1.1  rillig #	Var_Parse
     10   1.1  rillig #	Var_Subst
     11   1.1  rillig 
     12   1.1  rillig PLAIN=		plain value
     13   1.1  rillig 
     14   1.1  rillig LITERAL_DOLLAR=	To get a dollar, double $$ it.
     15   1.1  rillig 
     16   1.1  rillig INDIRECT=	An ${:Uindirect} value.
     17   1.1  rillig 
     18   1.1  rillig REF_UNDEF=	A reference to an ${UNDEF}undefined variable.
     19   1.1  rillig 
     20  1.11  rillig ERR_UNCLOSED=	An ${UNCLOSED expression.
     21   1.1  rillig 
     22   1.1  rillig ERR_BAD_MOD=	An ${:Uindirect:Z} expression with an unknown modifier.
     23   1.1  rillig 
     24   1.1  rillig ERR_EVAL=	An evaluation error ${:Uvalue:C,.,\3,}.
     25   1.1  rillig 
     26  1.10  rillig # In a conditional, an expression that is not enclosed in quotes is
     27  1.13  rillig # expanded using the mode VARE_EVAL_DEFINED.
     28   1.1  rillig # The variable itself must be defined.
     29   1.1  rillig # It may refer to undefined variables though.
     30   1.1  rillig .if ${REF_UNDEF} != "A reference to an undefined variable."
     31   1.1  rillig .  error
     32   1.1  rillig .endif
     33   1.1  rillig 
     34   1.2  rillig # As of 2020-12-01, errors in the variable name are silently ignored.
     35   1.3  rillig # Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result
     36   1.3  rillig # in an error message and a non-zero exit status.
     37  1.20  rillig # expect+1: Unknown modifier ":Z"
     38   1.2  rillig VAR.${:U:Z}=	unknown modifier in the variable name
     39   1.2  rillig .if ${VAR.} != "unknown modifier in the variable name"
     40   1.2  rillig .  error
     41   1.2  rillig .endif
     42   1.2  rillig 
     43   1.2  rillig # As of 2020-12-01, errors in the variable name are silently ignored.
     44   1.3  rillig # Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result
     45   1.3  rillig # in an error message and a non-zero exit status.
     46  1.20  rillig # expect+1: Unknown modifier ":Z"
     47   1.2  rillig VAR.${:U:Z}post=	unknown modifier with text in the variable name
     48   1.2  rillig .if ${VAR.post} != "unknown modifier with text in the variable name"
     49   1.2  rillig .  error
     50   1.2  rillig .endif
     51   1.2  rillig 
     52   1.5  rillig # Demonstrate an edge case in which the 'static' for 'errorReported' in
     53   1.5  rillig # Var_Subst actually makes a difference, preventing "a plethora of messages".
     54   1.5  rillig # Given that this is an edge case and the error message is wrong and thus
     55   1.5  rillig # misleading anyway, that piece of code is probably not necessary.  The wrong
     56   1.5  rillig # condition was added in var.c 1.185 from 2014-05-19.
     57   1.5  rillig #
     58   1.5  rillig # To trigger this difference, the variable assignment must use the assignment
     59   1.5  rillig # operator ':=' to make VarEvalMode_ShouldKeepUndef return true.  There must
     60   1.5  rillig # be 2 expressions that create a parse error, which in this case is ':OX'.
     61   1.5  rillig # These expressions must be nested in some way.  The below expressions are
     62   1.5  rillig # minimal, that is, removing any part of it destroys the effect.
     63   1.5  rillig #
     64   1.5  rillig # Without the 'static', there would be one more message like this:
     65   1.5  rillig #	Undefined variable "${:U:OX"
     66   1.5  rillig #
     67   1.5  rillig #.MAKEFLAGS: -dv
     68   1.5  rillig IND=	${:OX}
     69  1.19  rillig # expect+4: Bad modifier ":OX"
     70  1.19  rillig # expect+3: Bad modifier ":OX"
     71  1.19  rillig # expect+2: Bad modifier ":OX"
     72  1.19  rillig # expect+1: Bad modifier ":OX"
     73   1.5  rillig _:=	${:U:OX:U${IND}} ${:U:OX:U${IND}}
     74   1.5  rillig #.MAKEFLAGS: -d0
     75   1.5  rillig 
     76   1.7  rillig 
     77   1.7  rillig # Before var.c 1.032 from 2022-08-24, make complained about 'Unknown modifier'
     78   1.7  rillig # or 'Bad modifier' when in fact the modifier was entirely correct, it was
     79   1.7  rillig # just not delimited by either ':' or '}' but instead by '\0'.
     80  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "Q"
     81   1.6  rillig UNCLOSED:=	${:U:Q
     82  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "sh"
     83   1.6  rillig UNCLOSED:=	${:U:sh
     84  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "tA"
     85   1.6  rillig UNCLOSED:=	${:U:tA
     86  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "tsX"
     87   1.6  rillig UNCLOSED:=	${:U:tsX
     88  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "ts"
     89   1.6  rillig UNCLOSED:=	${:U:ts
     90  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "ts\040"
     91   1.6  rillig UNCLOSED:=	${:U:ts\040
     92  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "u"
     93   1.6  rillig UNCLOSED:=	${:U:u
     94  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "H"
     95   1.6  rillig UNCLOSED:=	${:U:H
     96  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "[1]"
     97   1.6  rillig UNCLOSED:=	${:U:[1]
     98  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "hash"
     99   1.6  rillig UNCLOSED:=	${:U:hash
    100  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "range"
    101   1.6  rillig UNCLOSED:=	${:U:range
    102  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "_"
    103   1.6  rillig UNCLOSED:=	${:U:_
    104  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "gmtime"
    105   1.6  rillig UNCLOSED:=	${:U:gmtime
    106  1.19  rillig # expect+1: Unclosed expression, expecting '}' for modifier "localtime"
    107   1.6  rillig UNCLOSED:=	${:U:localtime
    108  1.21  rillig 
    109  1.21  rillig 
    110  1.21  rillig # In a stack trace that has both evaluation details and included files, list
    111  1.21  rillig # the current file twice: Once in the first line and once in the call
    112  1.21  rillig # hierarchy. While this is redundant, omitting the current file from the
    113  1.21  rillig # call hierarchy is more confusing, as the '.include' line does not contain
    114  1.21  rillig # the faulty expression.
    115  1.21  rillig #
    116  1.21  rillig # expect: make: "varparse-errors.tmp" line 1: Unknown modifier ":Z"
    117  1.21  rillig # expect:	while evaluating "${:Z}" with value ""
    118  1.21  rillig # expect:	while evaluating variable "INDIRECT" with value "${:Z}"
    119  1.21  rillig # expect:	while evaluating variable "VALUE" with value "${INDIRECT}"
    120  1.21  rillig # expect:	in varparse-errors.tmp:1
    121  1.21  rillig # expect:	in varparse-errors.mk:126
    122  1.21  rillig _!=	echo '.info $${VALUE}' > varparse-errors.tmp
    123  1.21  rillig VALUE=	${INDIRECT}
    124  1.21  rillig INDIRECT=	${:Z}
    125  1.21  rillig # The "./" is necessary to skip the directory cache.
    126  1.21  rillig .include "./varparse-errors.tmp"
    127  1.21  rillig _!=	rm -f varparse-errors.tmp
    128