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 Mar 04 20:15:02 +0000 2012
>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

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.