Re: Quoting special characters (was: Re: Possible solution for special characters in makefile paths)
Paul Smith <[email protected]>
| Newsgroups | gmane.comp.gnu.make.devel |
|---|---|
| Organization | GNU's Not UNIX! |
| Message-ID | <1393281016.2823.384.camel@pdsdesk> |
On Mon, 2014-02-24 at 18:58 +0200, Eli Zaretskii wrote: > > From: Paul Smith <[email protected]> > > Cc: [email protected] > > Date: Sun, 23 Feb 2014 16:09:58 -0500 > > > > > 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. > > They are not entirely separable, but they can surely be addressed > separately, one after the other. That is what I meant. 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. > > Sorry, why is this a syntax error? Because it's illegal shell syntax; we're talking about how to expand variables containing backslash-whitespace in a make recipe and if the command make runs contains the above text it will fail: ~$ case 'foo bar' in (a b) echo 'foo bar' ;; esac sh: Syntax error: word unexpected (expecting ")") > > The above instance of BAR must be rewritten as: > > > > BAR = case '$@' in (a\\ b) echo '$(FOO)' ;; esac > > Then why didn't the user write just that? I think we're not communicating here. They didn't write that, because the result of expanding that definition of $(BAR) in a make recipe would fail in all versions of make ever created up until now: ~$ case 'foo bar' in (a\\ b) echo 'foo bar' ;; esac sh: Syntax error: word unexpected (expecting ")") > > FOO = a\ b > > all: ; @echo '$(FOO)' > > > > MUST print "a\ b". It CANNOT print "a b". > > You are just collecting use cases we need to address. Which is good, > but I still see no catastrophe in these seemingly complicated > requirements. That naive expansion doesn't quite get it is not a sign > that we should give up. Did you really think this will be easy? You asked for concrete examples of the problems we'll have and I'm trying to give concrete examples. I don't consider these to be simply individual use-cases to be taken care of; I'm using these examples to attempt to highlight what I see as unresolvable problems with the original proposal. If you think that we can solve these problems, then please provide me with some thoughts on how to do it! It's one thing to say these are not catastrophic, but saying it doesn't move us toward an implementation. > > > > 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 ;-) > > Exactly. Which means that with enough heuristics, a solution might > present itself in this case as well. "Might" is not enough anymore; we've moved beyond "might". Now we need "how". Drivespecs are possible because they can easily be recognized looking at the first two characters of a word. I don't see any heuristic that would solve the problem with backslash-whitespace. And not for lack of trying. 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' On the other hand POSIX, and 40 years of history and writing of makefiles, requires that this: FOO = foo\ bar all: ; @echo '$(FOO)' runs this command: echo 'foo\ bar' How can we square this circle? What heuristic can we apply? I don't see it! > > 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. > > If you are saying that $[string with spaces] is another candidate that > we should consider, I agree. If you are saying something else, I'm > afraid I didn't get it yet. My original proposal was that we would quote content on the input side using a new quoting method. One possible syntax I proposed was using $[...] where everything inside the brackets was quoted. So: FOO = $[foo bar] would be equivalent to this, using your backslash suggestion: FOO = foo\ bar That's what (I thought) this sub-thread was talking about: I'm saying there's no compatibility problem between the proposal to use "$[...]" for quoting strings in a makefile, and the use of "[" (or "[.exe") in a make recipe.