Re: Quoting special characters (was: Re: Possible solution for special characters in makefile paths)
Frank Heckenbach <[email protected]>
| Newsgroups | gmane.comp.gnu.make.devel |
|---|---|
| Message-ID | <[email protected]> |
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?