NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/46139: irregularities in backslash handling in make



>Number:         46139
>Category:       bin
>Synopsis:       irregularities in backslash handling in make
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 03 23:45:00 +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.



Home | Main Index | Thread Index | Old Index