make(1): add more tests for the variable modifier :M

Despite its popularity and usefulness, the variable modifier :M is
implemented so weirdly that it's not surprising people get confused
about make's parsing and escaping rules.
This commit is contained in:
rillig 2020-11-01 19:49:28 +00:00
parent 215a301198
commit ad6e88dcd8
2 changed files with 29 additions and 2 deletions

View File

@ -55,4 +55,7 @@ lhs = ":", rhs = "::", op = !=
make: "varmod-match-escape.mk" line 42: warning: XXX: Oops
Global:.MAKEFLAGS = -r -k -d cv -d
Global:.MAKEFLAGS = -r -k -d cv -d 0
exit status 0
make: "varmod-match-escape.mk" line 67: Dollar followed by nothing
make: Fatal errors encountered -- cannot continue
make: stopped in unit-tests
exit status 1

View File

@ -1,4 +1,4 @@
# $NetBSD: varmod-match-escape.mk,v 1.4 2020/11/01 19:25:23 rillig Exp $
# $NetBSD: varmod-match-escape.mk,v 1.5 2020/11/01 19:49:28 rillig Exp $
#
# As of 2020-08-01, the :M and :N modifiers interpret backslashes differently,
# depending on whether there was a variable expression somewhere before the
@ -44,5 +44,29 @@ VALUES= : :: :\:
.MAKEFLAGS: -d0
# XXX: As of 2020-11-01, unlike all other variable modifiers, a '$' in the
# :M and :N modifiers is written as '$$', not as '\$'. This is confusing,
# undocumented and hopefully not used in practice.
.if ${:U\$:M$$} != "\$"
. error
.endif
# XXX: As of 2020-11-01, unlike all other variable modifiers, '\$' is not
# parsed as an escaped '$'. Instead, ApplyModifier_Match first scans for
# the ':' at the end of the modifier, which results in the pattern '\$'.
# No unescaping takes place since the pattern neither contained '\:' nor
# '\{' nor '\}'. But the text is expanded, and a lonely '$' at the end
# is silently discarded. The resulting expanded pattern is thus '\', that
# is a single backslash.
.if ${:U\$:M\$} != ""
. error
.endif
# In lint mode, the case of a lonely '$' is covered with an error message.
.MAKEFLAGS: -dL
.if ${:U\$:M\$} != ""
. error
.endif
all:
@:;