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: Paul Smith
Subject: Re: Quoting special characters (was: Re: Possible solution for special characters in makefile paths)
Date: Sun, 23 Feb 2014 16:09:58 -0500

On Sun, 2014-02-23 at 21:18 +0200, Eli Zaretskii wrote:
> >   FOO = foo\ bar
> >   $(FOO): ; @echo '"$@"' '"$(FOO)"' '"$(addsuffix .txt,$(FOO))"'
> > 
> > In your suggested implementation what is printed?
> > 
> >   "foo bar" "foo bar" "foo bar.txt"
> > or
> >   "foo bar" "foo\ bar" "foo\ bar.txt"
> > or
> >   "foo bar" "foo\ bar" "foo\.txt bar.txt"
> 
> The first, I hope.

Excellent!  I agree 100% that would be the ideal outcome in that
situation.

I will point out, just for clarity, that the current behavior of
backslash-colon escaping does NOT work that way, and that's what I, at
least, mean when I talk about the problems with backslash-escaped
colons;  from this:

   FOO = foo\:bar
   $(FOO): ; @echo '$@' '$(FOO)'

we get "foo:bar foo\:bar".  Although this is unpleasant, if $(FOO)
yielded 'foo:bar' it would be a big problem, as I'll show below.

> But again, let's first find the best way of expressing such strings in
> a Makefile, and get to their expansion after that.  These are two
> separate issues.

It would be nice if that were true, but IMHO it's not really the case.
In fact these issues are only partially separable, because some methods
of expression in the makefile imply massive problems if we want to have
a particular expansion.

Lets posit that we have decided to use the suggestion above (whitespace
is escaped with a backslash), and move on to the next step: how to
expand.  Say we have this makefile:

   FOO = foo\ bar
   BAR = case '$@' in (a\ b) echo '$(FOO)' ;; esac

   $(FOO): ; $(BAR)

We have said that we would like the expansion of $(FOO) to be simply
"foo bar", without a backslash.

So that would mean that the expansion of $(BAR) would have to remove the
backslash in the case statement, too: make cannot know whether the
variable is being expanded to be used as a filename, or for some other
reason.  That gives this result:

  case 'foo bar' in (a b) echo 'foo bar' ;; esac

which is a syntax error.

This is what I was trying (badly) to get at before.  In this scenario
every single instance of backslash-whitespace anywhere in a makefile
must be modified to quote the backslash.  The above instance of BAR must
be rewritten as:

   BAR = case '$@' in (a\\ b) echo '$(FOO)' ;; esac

(or (a" "b), but in any event, rewritten).  Now, instances of
backslash-whitespace are not rare at all; in fact I find them in every
single automake-generated makefile including the one that is used to
build GNU make itself:

  am__make_running_with_option = \
    ...
      case $$MAKEFLAGS in \
        *\\[\ \   ]*) \
    ...

Not only that, but this would be incompatible with all other versions of
make out there, and further it would violate POSIX requirements.  A
POSIX-conforming make, given the makefile:

   FOO = a\ b
   all: ; @echo '$(FOO)'

MUST print "a\ b".  It CANNOT print "a b".

> > The fact is that colons ARE rare in filenames.
> 
> Not on Windows ;-)

Very true, and you'll note we don't ask everyone to escape the colons in
their Windows drivespecs ;-)

> > > > The difference between this and $[ is that (a) backslashes are much more
> > > > common than someone using "[" as a make variable, and (b) assigning to
> > > > [ can be detected by make and a warning or error generated, so users
> > > > know that there is a backward compat problem.  Adding new backslash
> > > > quoting leads to silent changes in behavior.
> > > 
> > > There's a program called [.exe on my disk, did you consider that?
> > 
> > There's a program called "[" on my disk, too... :-).  But I don't see
> > how that conflicts with the make variable $[... ?
> 
> You only think about Make variables, but I also consider the
> complications with command lines.  Shell-like quoting and escaping has
> the advantage that it will never conflict with command lines.

I'm thinking about ALL aspects, not just variables.

There's no way $[ could possibly conflict with a command line: that's
because make's "$" escaping is escaping done right and make's backslash
escaping is escaping done badly.

In any make recipe today, $[ is a make variable reference.  Always.
Even if the variable is not set, it's still a variable reference and it
can never, ever refer to any command like "[" or whatever.  There can be
no conflict with the command line.




reply via email to

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