NetBSD Problem Report #46139

From dholland@netbsd.org  Sat Mar  3 23:40:12 2012
Return-Path: <dholland@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id B1A1E63BFFC
	for <gnats-bugs@gnats.NetBSD.org>; Sat,  3 Mar 2012 23:40:12 +0000 (UTC)
Message-Id: <20120303234017.EB0D514A1A1@mail.netbsd.org>
Date: Sat,  3 Mar 2012 23:40:17 +0000 (UTC)
From: dholland@netbsd.org
Reply-To: dholland@netbsd.org
To: gnats-bugs@gnats.NetBSD.org
Subject: irregularities in backslash handling in make
X-Send-Pr-Version: 3.95

>Number:         46139
>Category:       bin
>Synopsis:       irregularities in backslash handling in make
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dholland
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 03 23:45:00 +0000 2012
>Last-Modified:  Sun Jun 29 11:05:01 +0000 2025
>Originator:     David A. Holland
>Release:        NetBSD 6.99.3 (20120303)
>Organization:
>Environment:
n/a
>Description:

(1)

Try to get a string ending in a backslash into a make variable.
If you write
   VAR=foo\
the backslash is treated as a line continuation. However, if you write
   VAR=foo\\
you get two backslashes. If you write
   VAR=foo\ 
with trailing whitespace, you get a value with one backslash... and
trailing whitespace.

As far as I can tell the only way is to append a backslash with the S
or C modifier.

(2)

Now try to match this string using the :M modifier.

Expressions of the forms

	.if !empty(VAR:Mx\)
	.if !empty(VAR:Mx\\)

produce an error message:
   make: Unclosed variable specification (expecting ')') for "VAR" (value "") modifier M
(the printed value is wrong too). This is true no matter how many
backslashes are used; I tried up to 8.

If you add another modifier afterwards, then the parser accepts it.

	.if !empty(VAR:Mx\:Nzzz)
	.if !empty(VAR:Mx\\:Nzzz)

However, it still doesn't match. (Again, I tried up to 8 backslashes.)

One can also ascertain that the second modifier isn't being processed
correctly:

	.if !empty(VAR:Mx\:S/^/foo/)
	.if !empty(VAR:Mx\\:S/^/foo/)

etc. should all be true, but none are. (Again, up to 8 backslashes.)

Note that matching the backslash with a wildcard does work:

	.if !empty(VAR:Mx?)
	.if !empty(VAR:Mx*)
and even
	.if !empty(VAR:Mx[Z-a])

all are true.

>How-To-Repeat:

Edit the following makefile as above:

EMPTY=
BACKSLASH=$(EMPTY:S/$/\\/)

VAR=x$(BACKSLASH)

all:
	@echo @'${VAR}'@
.if !empty(VAR:Mx?)
	@echo 'matched'
.endif

>Fix:

As far as I can tell the string matching code is fine; the blame lies
with the parser, and the fact that pieces of the parser are strewn all
over the program.

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: bin-bug-people->dholland
Responsible-Changed-By: dholland@NetBSD.org
Responsible-Changed-When: Sun, 04 Mar 2012 00:09:02 +0000
Responsible-Changed-Why:
Realistically, the only person likely to do the major rototill of make
needed to fix this kind of problem permanently is me.

If anyone else wants to try, of course, don't let me stop you.


From: David Laight <david@l8s.co.uk>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/46139: irregularities in backslash handling in make
Date: Sun, 4 Mar 2012 20:08:30 +0000

 On Sat, Mar 03, 2012 at 11:45:00PM +0000, dholland@netbsd.org wrote:
 > >Number:         46139
 > >Category:       bin
 > >Synopsis:       irregularities in backslash handling in make

 > As far as I can tell the string matching code is fine; the blame lies
 > with the parser, and the fact that pieces of the parser are strewn all
 > over the program.

 From my recollection the problem is that various random bits of make
 have been changed to treat '\' as an escape character.
 But it general it isn't one, and can't be allowed to be one.

 The line continuation is defined, so I suspect the \\ at end of line
 is a simple bug.

 You only have to look at the variable table when pkgsrc is running
 to see the complete fubar that attempts to escape whitespace has.

 IIRC the correct way to use characters that need escaping is to
 put them into a variable that is evaluated late enough.
 But even that is troublesome since variables are expanded recursively
 and can generate certain forms of syntax.

 	David

 -- 
 David Laight: david@l8s.co.uk

From: "Roland Illig" <rillig@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/46139 CVS commit: src
Date: Sun, 29 Jun 2025 09:40:14 +0000

 Module Name:	src
 Committed By:	rillig
 Date:		Sun Jun 29 09:40:14 UTC 2025

 Modified Files:
 	src/distrib/sets/lists/tests: mi
 	src/usr.bin/make/unit-tests: Makefile varmod-match.exp varmod-match.mk
 Added Files:
 	src/usr.bin/make/unit-tests: char-005c-reverse-solidus.exp
 	    char-005c-reverse-solidus.mk

 Log Message:
 tests/make: test backslash at the end of a line and in the :M modifier

 As described in PR bin/46139 by David A. Holland.


 To generate a diff of this commit:
 cvs rdiff -u -r1.1381 -r1.1382 src/distrib/sets/lists/tests/mi
 cvs rdiff -u -r1.368 -r1.369 src/usr.bin/make/unit-tests/Makefile
 cvs rdiff -u -r0 -r1.1 \
     src/usr.bin/make/unit-tests/char-005c-reverse-solidus.exp \
     src/usr.bin/make/unit-tests/char-005c-reverse-solidus.mk
 cvs rdiff -u -r1.26 -r1.27 src/usr.bin/make/unit-tests/varmod-match.exp
 cvs rdiff -u -r1.31 -r1.32 src/usr.bin/make/unit-tests/varmod-match.mk

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Roland Illig" <rillig@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/46139 CVS commit: src/usr.bin/make
Date: Sun, 29 Jun 2025 11:02:18 +0000

 Module Name:	src
 Committed By:	rillig
 Date:		Sun Jun 29 11:02:18 UTC 2025

 Modified Files:
 	src/usr.bin/make: var.c
 	src/usr.bin/make/unit-tests: varmod.exp varmod.mk

 Log Message:
 make: fix parsing of modifier parts for :gmtime and :localtime

 There's no practical use for escaping the ":" or "}" in these two
 modifiers, but the same scheme may prove useful for the :M and :N
 modifiers, which are currently parsed in a completely different manner,
 thus adding needless complexity.

 Parsing of the :M and :N modifiers is discussed in PR bin/46139.


 To generate a diff of this commit:
 cvs rdiff -u -r1.1170 -r1.1171 src/usr.bin/make/var.c
 cvs rdiff -u -r1.24 -r1.25 src/usr.bin/make/unit-tests/varmod.exp
 cvs rdiff -u -r1.28 -r1.29 src/usr.bin/make/unit-tests/varmod.mk

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.49 2026/05/14 01:52:41 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.