Home | History | Annotate | Line # | Download | only in unit-tests
var-op-expand.mk revision 1.10
      1 # $NetBSD: var-op-expand.mk,v 1.10 2020/12/28 00:19:41 rillig Exp $
      2 #
      3 # Tests for the := variable assignment operator, which expands its
      4 # right-hand side.
      5 
      6 
      7 # If the right-hand side does not contain a dollar sign, the ':=' assignment
      8 # operator has the same effect as the '=' assignment operator.
      9 VAR:=			value
     10 .if ${VAR} != "value"
     11 .  error
     12 .endif
     13 
     14 # When a ':=' assignment is performed, its right-hand side is evaluated and
     15 # expanded as far as possible.  Contrary to other situations, '$$' and
     16 # variable expressions based on undefined variables are preserved though.
     17 #
     18 # Whether a variable expression is undefined or not is determined at the end
     19 # of evaluating the expression.  The consequence is that ${:Ufallback} expands
     20 # to "fallback"; initially this expression is undefined since it is based on
     21 # the variable named "", which is guaranteed to be never defined, but at the
     22 # end of evaluating the expression ${:Ufallback}, the modifier ':U' has turned
     23 # the expression into a defined expression.
     24 
     25 
     26 # literal dollar signs
     27 VAR:=		$$ $$$$ $$$$$$$$
     28 .if ${VAR} != "\$ \$\$ \$\$\$\$"
     29 .  error
     30 .endif
     31 
     32 
     33 # reference to a variable containing a literal dollar sign
     34 REF=		$$ $$$$ $$$$$$$$
     35 VAR:=		${REF}
     36 REF=		too late
     37 .if ${VAR} != "\$ \$\$ \$\$\$\$"
     38 .  error
     39 .endif
     40 
     41 
     42 # reference to an undefined variable
     43 .undef UNDEF
     44 VAR:=		<${UNDEF}>
     45 UNDEF=		after
     46 .if ${VAR} != "<after>"
     47 .  error
     48 .endif
     49 
     50 
     51 # reference to a variable whose name is computed from another variable
     52 REF2=		referred to
     53 REF=		REF2
     54 VAR:=		${${REF}}
     55 REF=		too late
     56 .if ${VAR} != "referred to"
     57 .  error
     58 .endif
     59 
     60 
     61 # expression with an indirect modifier referring to an undefined variable
     62 .undef UNDEF
     63 VAR:=		${:${UNDEF}}
     64 UNDEF=		Uwas undefined
     65 .if ${VAR} != "was undefined"
     66 .  error
     67 .endif
     68 
     69 
     70 # expression with an indirect modifier referring to another variable that
     71 # in turn refers to an undefined variable
     72 #
     73 # XXX: Even though this is a ':=' assignment, the '${UNDEF}' in the part of
     74 # the variable modifier is not preserved.  To preserve it, ParseModifierPart
     75 # would have to call VarSubstExpr somehow since this is the only piece of
     76 # code that takes care of this global variable.
     77 .undef UNDEF
     78 REF=		U${UNDEF}
     79 #.MAKEFLAGS: -dv
     80 VAR:=		${:${REF}}
     81 #.MAKEFLAGS: -d0
     82 REF=		too late
     83 UNDEF=		Uwas undefined
     84 .if ${VAR} != ""
     85 .  error
     86 .endif
     87 
     88 
     89 # In variable assignments using the ':=' operator, undefined variables are
     90 # preserved, no matter how indirectly they are referenced.
     91 .undef REF3
     92 REF2=		<${REF3}>
     93 REF=		${REF2}
     94 VAR:=		${REF}
     95 REF3=		too late
     96 .if ${VAR} != "<too late>"
     97 .  error
     98 .endif
     99 
    100 
    101 # In variable assignments using the ':=' operator, '$$' are preserved, no
    102 # matter how indirectly they are referenced.
    103 REF2=		REF2:$$ $$$$
    104 REF=		REF:$$ $$$$ ${REF2}
    105 VAR:=		VAR:$$ $$$$ ${REF}
    106 .if ${VAR} != "VAR:\$ \$\$ REF:\$ \$\$ REF2:\$ \$\$"
    107 .  error
    108 .endif
    109 
    110 
    111 # In variable assignments using the ':=' operator, '$$' are preserved in the
    112 # expressions of the top level, but not in expressions that are nested.
    113 VAR:=		top:$$ ${:Unest1\:\$\$} ${:Unest2${:U\:\$\$}}
    114 .if ${VAR} != "top:\$ nest1:\$ nest2:\$"
    115 .  error
    116 .endif
    117 
    118 
    119 # In variable assignments using the ':=' operator, there may be expressions
    120 # containing variable modifiers, and these modifiers may refer to other
    121 # variables.  These referred-to variables are expanded at the time of
    122 # assignment.  The undefined variables are kept as-is and are later expanded
    123 # when evaluating the condition.
    124 #
    125 # Contrary to the assignment operator '=', the assignment operator ':='
    126 # consumes the '$' from modifier parts.
    127 REF.word=	1:$$ 2:$$$$ 4:$$$$$$$$
    128 .undef REF.undef
    129 VAR:=		${:Uword undef:@word@${REF.${word}}@}, direct: ${REF.word} ${REF.undef}
    130 REF.word=	word.after
    131 REF.undef=	undef.after
    132 .if ${VAR} != "1:2:\$ 4:\$\$ undef.after, direct: 1:\$ 2:\$\$ 4:\$\$\$\$ undef.after"
    133 .  error
    134 .endif
    135 
    136 # Just for comparison, the previous example using the assignment operator '='
    137 # instead of ':='.  The right-hand side of the assignment is not evaluated at
    138 # the time of assignment but only later, when ${VAR} appears in the condition.
    139 #
    140 # At that point, both REF.word and REF.undef are defined.
    141 REF.word=	1:$$ 2:$$$$ 4:$$$$$$$$
    142 .undef REF.undef
    143 VAR=		${:Uword undef:@word@${REF.${word}}@}, direct: ${REF.word} ${REF.undef}
    144 REF.word=	word.after
    145 REF.undef=	undef.after
    146 .if ${VAR} != "word.after undef.after, direct: word.after undef.after"
    147 .  error
    148 .endif
    149 
    150 
    151 # Between var.c 1.42 from 2000-05-11 and before parse.c 1.520 from 2020-12-27,
    152 # if the variable name in a ':=' assignment referred to an undefined variable,
    153 # there were actually 2 assignments to different variables:
    154 #
    155 #	Global["VAR_SUBST_${UNDEF}"] = ""
    156 #	Global["VAR_SUBST_"] = ""
    157 #
    158 # The variable name with the empty value actually included a dollar sign.
    159 # Variable names with dollars are not used in practice.
    160 #
    161 # It might be a good idea to forbid undefined variables on the left-hand side
    162 # of a variable assignment.
    163 .undef UNDEF
    164 VAR_ASSIGN_${UNDEF}=	assigned by '='
    165 VAR_SUBST_${UNDEF}:=	assigned by ':='
    166 .if ${VAR_ASSIGN_} != "assigned by '='"
    167 .  error
    168 .endif
    169 .if defined(${:UVAR_SUBST_\${UNDEF\}})
    170 .  error
    171 .endif
    172 .if ${VAR_SUBST_} != "assigned by ':='"
    173 .  error
    174 .endif
    175 
    176 all:
    177 	@:;
    178