make-alpha
[Top][All Lists]
Advanced

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

Re: Quoting special characters (was: Re: Possible solution for special c


From: Frank Heckenbach
Subject: Re: Quoting special characters (was: Re: Possible solution for special characters in makefile paths)
Date: Tue, 25 Feb 2014 00:05:59 +0100

Paul Smith wrote:

> On Mon, 2014-02-24 at 18:58 +0200, Eli Zaretskii wrote:
> That's what I'm doing: assuming we implement your suggestion of
> backslash-quoted whitespace, which I do agree could work _on the parsing
> side_, let's discuss the problems that will have to be solved on the
> expansion side as a result of this syntax.
> 
> I need you to help me solve them, because I think they are insoluble
> (not just hard) but you seem to think it could be done.  So please help
> me see how it could be made to work.
> 
> > >    FOO = foo\ bar
> > >    BAR = case '$@' in (a\ b) echo '$(FOO)' ;; esac
> > > 
> > >    $(FOO): ; $(BAR)
> > > 
> > >   case 'foo bar' in (a b) echo 'foo bar' ;; esac
> > > 
> > > which is a syntax error.

Let me chime in with my interpretation of Eli's suggestion. In this
case, FOO would be stored as is (foo\ bar) with make understanding
that (every) variable value is a string quoted according to shell
syntax, so this would be treated as a single word (e.g. when used in
a prerequisite list, in $(addprefix) etc.). In the command-line it
would also substituted as is, so no change from the existing
behaviour here.

> > >    FOO = a\ b
> > >    all: ; @echo '$(FOO)'
> > >
> > > MUST print "a\ b".  It CANNOT print "a b".

Same here, echo 'a\ b' still prints "a\ b". OTOH, echo $(FOO) would
print "a b", of course.

> As discussed before, our desired result is that this makefile:
> 
>   FOO = foo\ bar
>   $(FOO): ; @echo '$(FOO)' > '$@'
> 
> would run this command:
> 
>   echo 'foo bar' > 'foo bar'

That's were I differ (but I hope Eli will follow me here). I'd say
it should run "echo 'foo\ bar' > 'foo\ bar'", i.e. write to a file
with an embedded backslash.

That's probably not what was intended, but I'd blame this on the
users. They should just write (without worries, if we declare that
$@ (or other variables) are always quoted (for a POSIX shell)):

   $(FOO): ; @echo $(FOO) > $@

Which also works today as long as $@ contains only harmless
characters, and which is what most makefiles actually do.

Actually, in all the examples above, there would be no change in
behaviour at all. Changes would occur where make gets strings that
need quoting e.g. from $(wildcard) and possibly from environment
variables; and most importantly, where it needs to do word
splitting, e.g. in target or dependency lists:

FOO = foo\ bar
all: $(FOO)

Now: Depends on "foo\" and "bar.

Then: Depends on "foo bar".

Possible problem: File names with a trailing \ (uncommon on Unix,
possible as directory names on Windows, but probably usually written
without a trailing \).

And in some built-in functions, e.g.:

FOO = foo\ bar
all: ; @echo '"$(addsuffix .txt,$(FOO))"'

Now: echo '"foo\.txt bar.txt"'

Then: echo '"foo\ bar.txt"'

(That corresponds to answer #2 in your previous quiz, while you and
Eli agreed on #1. But I say to get #1, don't quote manually.)

That's clearly a change, some would say for the better, but still
backward-incompatible. The question is, can we afford this
incompatibility and does POSIX allow it?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]