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