make-alpha
[Top][All Lists]
Advanced

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

Re: Backslash quoting (was: Re: Possible solution for special characters


From: Frank Heckenbach
Subject: Re: Backslash quoting (was: Re: Possible solution for special characters in makefile paths)
Date: Wed, 12 Mar 2014 08:30:48 +0100

Paul Smith wrote:

> This thread is for discussing the alternative quoting proposal, put
> forth by Eli.  This proposal would take the current handling of
> backslashes to quote special characters (see my previous post on this
> subject) and extend it.

I agree with most of what you wrote, just want to add a few points.

But before I go on, let me make clear my own intention. What I'd
like to see is a way to have make work on *any* file name supported
by the OS, just like it's possible with (modern) shells. Currently,
my personal rule is, don't use any non-trivial characters in
filenames used by make. (That's a bit too strict, but I'm rather
safe than sorry here.) If the new proposal just expands the set of
allowed characters somewhat (most notably, including spaces), I'm
not very interested, quite frankly. I think if you're going to make
a bigger change like this, you should aim for the whole thing.

This means, the following should work when the user follows a
well-documented way of quoting/escaping some-file-name[-list] in the
makefile (be it \, $[], $(quote) or whatever) which is applicable to
any file name; and if they quote variables in the recipe according
to a well-documented rule which also must work for any file name
(whether that rule is "do nothing" as in this proposal, or "apply
$(SHELL_QUOTE) to each variable" in another proposal):

FOO = some-file-name
BAR = some-file-name-list

$(FOO): $(BAR); echo Generating $(FOO) from $(BAR); cat $^ > $@

Likewise, given a rule like this (again, with quoting according to a
well-documented rule):

%.x: %.y; cat $< > $@

one should be able to call «execlp ("make", filename, NULL);» where
filename contains any valid filename ending in «.x». (Of course, one
would usually call it from a shell prompt, but to steer clear of
shell-unquoting before make is invoked, I'm using execlp here.)

> When considering backward-compatibility, we would be changing the way
> backslashes currently behave (see my previous email from last week about
> this behavior): today when a make string is "expanded" in a makefile
> context (as a target or prerequisite for example) any backslashes are
> removed from the string at that time, and the value of $@ or $< or
> whatever gives the backslash-removed string.  In the new environment
> that would change and the backslashes would be preserved.

They would be preserved in the value of $@ or $<, but of course
removed for the file names actually used as a target or prerequisite
(or e.g. an argument to $(wildcard)).

One point to take care of, however, is what to do when encountering
unescaped special characters in those circumstances, e.g.:

FOO = a'b'c
$(FOO): ; touch $@

Since ' is not special to make, it wouldn't (so far) do anything
about it, i.e. have a rule for a target called «a'b'c», but it's
special to the shell which would create a file called «abc».

That's what I was getting at with my proposal to support full shell
style quoting in make, but I see now that's not sufficient if you
consider cases like:

FOO = a`cat foo`c
$(FOO): ; touch $@

FOO = a>b
$(FOO): ; touch $@

AFAICS, there's only two ways to deal with this in a sane way:

- Have make automatically quote those special characters, so in the
  last example make silently turns foo into «a\>b» which both make
  and the shell would then interpret as referring to a file called
  «a>b».

  I don't think this is a good idea, since the following is
  perfectly valid now (though maybe unusual), and would break then
  (unless we'd auto-quote the value of $(FOO) only if it appears in
  a target list etc., which seems even more confusing):

  FOO = a>b
  all: ; echo $(FOO)

- Simply reject shell-but-not-make-special characters in those
  positions.

  This might also be preferable from a backward-compatibility point,
  since some problematic cases would fail fast and let the user fix
  them by explicitly quoting those characters.

  However, this in turn also means that when make auto-quotes values
  ($(wildcard ...) results, command-line goals), it would need to
  quote all shell-special characters, to avoid producing a value it
  would fail on when used:

  %: ; echo $@

  make 'a>b'

  The goal should become «a\>b» which make and the shell would
  interpret as a file named «a>b».

> Disadvantages to this model:
>
>      B. We'll need to do something about the quoting when dealing with
>         alternative settings of SHELL, for interpreters which do not
>         handle backslashes the same way the UNIX shell does.  This could
>         be a tricky problem, because we don't know which backslashes are
>         intended and which are there to quote special characters.

AFAICS, one always needs different treatment for different shells
with any proposal. With this one, it's "do nothing" for POSIX sh,
and some kind of reencoding for other shells. With other proposals,
it's one kind of encoding for POSIX sh, other kinds of encoding for
other shells. Eli said (roughly ;), screw other shells, POSIX sh is
by far the most common, but whether or not you agree, it's hardly a
disadvantage of one particular model, but a necessity in any case.

>      C. Either all of make's internal code must be enhanced to ignore
>         backslash escape sequences, or else we'll need to do encoding /
>         decoding similar to what was described in the other proposal.

Yes, it's probably more work implementation-wise, but in the end it
might make the code more maintably by more clearly documenting what
is happening where. After all, using a single string to contain a
list of (arbitrary) strings is a contortion to start with, so
isolating the special handling required due to that to a particular
set of functions may make the code clearer.



reply via email to

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