1# $NetBSD: varmod-match-escape.mk,v 1.5 2020/11/01 19:49:28 rillig Exp $ 2# 3# As of 2020-08-01, the :M and :N modifiers interpret backslashes differently, 4# depending on whether there was a variable expression somewhere before the 5# first backslash or not. See ApplyModifier_Match, "copy = TRUE". 6# 7# Apart from the different and possibly confusing debug output, there is no 8# difference in behavior. When parsing the modifier text, only \{, \} and \: 9# are unescaped, and in the pattern matching these have the same meaning as 10# their plain variants '{', '}' and ':'. In the pattern matching from 11# Str_Match, only \*, \? or \[ would make a noticeable difference. 12 13.MAKEFLAGS: -dcv 14 15SPECIALS= \: : \\ * \* 16.if ${SPECIALS:M${:U}\:} != ${SPECIALS:M\:${:U}} 17. warning unexpected 18.endif 19 20# And now both cases combined: A single modifier with both an escaped ':' 21# as well as a variable expression that expands to a ':'. 22# 23# XXX: As of 2020-11-01, when an escaped ':' occurs before the variable 24# expression, the whole modifier text is subject to unescaping '\:' to ':', 25# before the variable expression is expanded. This means that the '\:' in 26# the variable expression is expanded as well, turning ${:U\:} into a simple 27# ${:U:}, which silently expands to an empty string, instead of generating 28# an error message. 29# 30# XXX: As of 2020-11-01, the modifier on the right-hand side of the 31# comparison is parsed differently though. First, the variable expression 32# is parsed, resulting in ':' and needSubst=TRUE. After that, the escaped 33# ':' is seen, and this time, copy=TRUE is not executed but stays copy=FALSE. 34# Therefore the escaped ':' is kept as-is, and the final pattern becomes 35# ':\:'. 36# 37# If ApplyModifier_Match had used the same parsing algorithm as Var_Subst, 38# both patterns would end up as '::'. 39# 40VALUES= : :: :\: 41.if ${VALUES:M\:${:U\:}} != ${VALUES:M${:U\:}\:} 42. warning XXX: Oops 43.endif 44 45.MAKEFLAGS: -d0 46 47# XXX: As of 2020-11-01, unlike all other variable modifiers, a '$' in the 48# :M and :N modifiers is written as '$$', not as '\$'. This is confusing, 49# undocumented and hopefully not used in practice. 50.if ${:U\$:M$$} != "\$" 51. error 52.endif 53 54# XXX: As of 2020-11-01, unlike all other variable modifiers, '\$' is not 55# parsed as an escaped '$'. Instead, ApplyModifier_Match first scans for 56# the ':' at the end of the modifier, which results in the pattern '\$'. 57# No unescaping takes place since the pattern neither contained '\:' nor 58# '\{' nor '\}'. But the text is expanded, and a lonely '$' at the end 59# is silently discarded. The resulting expanded pattern is thus '\', that 60# is a single backslash. 61.if ${:U\$:M\$} != "" 62. error 63.endif 64 65# In lint mode, the case of a lonely '$' is covered with an error message. 66.MAKEFLAGS: -dL 67.if ${:U\$:M\$} != "" 68. error 69.endif 70 71all: 72 @:; 73