tech-toolchain archive

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

Re: make :Q breakage



On Sat, May 26, 2018 at 20:14:01 +0300, Valery Ushakov wrote:

> On Sat, May 26, 2018 at 11:59:27 -0400, Christos Zoulas wrote:
> 
> > On May 26,  6:25pm, uwe%stderr.spb.ru@localhost (Valery Ushakov) wrote:
> > -- Subject: Re: make :Q breakage
> > 
> > | :Q is defined to quote *shell* meta-characters.  The problem with $$
> > | $$$$ $$$$$$$$ etc is not unique to make but is endemic to all
> > | macro-processors in some form.  At least make does recursive
> > | expansion, so you mostly (only?) run into this with submakes.
> > | 
> > | As far as I understand you don't really need a new modifier, as
> > | existing :S should do:
> > | 
> > |     DOLLAR=$$
> > |     ...
> > |         make DOLLAR=${DOLLAR:S/\$/&&/g:Q}
> > | 
> > | When a variable is expanded, the only remaining '$' characters in it
> > | are from $$ in the original, since you know you are passing this to
> > | another make you use :S to double them again for the nested make.  And
> > | shell-quote the result with :Q
> > | 
> > | E.g.
> > | 
> > | # ---8<--- d.mk ---8<---
> > | PID=$$$$
> > | .if !defined(NESTED)
> > | all:
> > | 	echo ${PID}
> > | 	echo ${PID:Q}
> > | 	make -f d.mk NESTED=${PID:S/\$/&&/g:Q}
> > | .else
> > | all:
> > | 	echo ${NESTED}
> > | 	echo ${NESTED:Q}
> > | .endif
> > | # ---8<---
> > | 
> > | 
> > | If you want to hide the gory details you can probably even do
> > | something like
> > | 
> > | MAKEQUOTE=S/\$$/&&/g:Q
> > | ...
> > | 	make .... NESTED=${PID:${MAKEQUOTE}}
> > 
> > This is still ugly. When would you *not* want :Q to do this automatically?
> 
> When you want to pass e.g. variable reference to be interpreted by the
> submake?  I.e.
> 
> # FOO and BAR are defined in the submake, you can select which one you
> # want to use
> #DEFVAR=$${FOO}
> DEFVAR=$${BAR}
> 
> 	make -f other.mk VAR=${DEFVAR:Q}
> 
> Which is like setting VAR=${BAR} in the submake.  You want :Q for the
> shell, but you do mean to pass single $ here that you need to express
> with $$ in the caller.
> 
> Actually, the variable can be a shell variable too and not necessarily
> quoted to pass to a submake.  The use case your change broke with
> pkgsrc tools is exactly that for shell's $@

It can also be literal input to something with a dollar in it, e.g.

EDCMD=	3,$$d
all:
	seq 5 > seq.txt
	(echo ${EDCMD:Q}; echo wq ) | ed seq.txt
	cat seq.txt

where you want shell-quoting but not make-quoting.

To reiterate - there are two distinct operations here.  One is quoting
of meta-characters interpreted by shell, the other is quoting the
meta-characters interpreted by make.  In the latter case the character
is just '$' and to "quote" it, you need to change it to $$, which you
can do with :S.  Since it's only one character, the :S expression is
not that unwieldy, so may be we don't necessarily want to introduce a
brand new modifier just for that. Even if we do, it's still
conceptually a separate operation from :Q

OTOH, since we will almost always want to apply shell-quoting after
make-quoting anyway, it might be convenient to introduce a version of
:Q that first applies make-quoting, so that you can write ${VAR:QM}
instead of ${VAR:S/\$/&&/g:Q} or ${VAR:${MAKEQUOTE}}.  If you need
just the make-quoting you can still use :S

-uwe


Home | Main Index | Thread Index | Old Index