WIP: replace AS_ESCAPE and _AS_QUOTE with AS_QUOTE_D.
AS_ESCAPE is difficult or even impossible to use correctly,
depending on what you’re trying to do with it:
+ AS_ESCAPE([text], [`\"]) is intended to permit variable interpolation
but prevent command substitution. This does not work anymore,
because we have $(...) command substitution nowadays, Solaris 10
notwithstanding.
+ It is incorrect to leave \ or " out of the [chars] argument, but people
do this all the dang time both in our own code and in third-party code.
+ It is incorrect to put anything in [chars] besides $ ` \ ", but people
also do this. In particular, 'AS_ESCAPE([text], [\'])' *does not*
produce a correct single-quoted string, but at least one third-party
m4 macro does this anyway.
+ In most cases you need to write AS_ESCAPE(m4_dquote(m4_expand([text])))
or else M4 macros inside [text] will be expanded *after* the quotation
process is complete, and the text they expand to won’t get escaped.
*Our* code using AS_ESCAPE was diligent about this, but almost no
no third-party uses bothered.
+ Almost all uses of AS_ESCAPE are constructing double-quoted strings,
so it would be more ergonomic if it added the outermost quotes for you.
(All assertions about third-party code courtesy of
<http://codesearch.debian.net/search?q=%5CbAS_ESCAPE%5Cb+-pkg%3Aautoconf+-pkg%3Aautoconf2.69&literal=0>.)
The internal _AS_QUOTE macro is also almost impossible to use
correctly, for the above reasons plus the fact that it includes some
20-year-old *internal* backward compatibility logic that doesn’t
distinguish ${variable} from $(command) either.
Replace with a safer API:
+ New macro AS_QUOTE_S([text]) turns TEXT into a single-quoted string,
*correctly* escaping embedded single quotes, and supplying an outer
pair of quotes. Macros in TEXT are expanded once before quotation.
+ New macro AS_QUOTE_D([text], [interpolation]) turns TEXT into a
double-quoted string, supplying an outer pair of quotes. Macros in
TEXT are expanded once before quotation.
The INTERPOLATION argument is a comma-separated list of keywords
specifying what types of interpolation will be permitted:
If the argument is empty or omitted, no interpolation is allowed.
This is intentionally verbose and there is no ‘allow-all’, because
I want people to think hard about if it’s really a good idea before
enabling command substitution, and I want it to be easy to find all
the place’s it’s being used. (Almost all uses of AS_ESCAPE, both
internally and externally, want either no interpolation or only
variable interpolation.) Both `...` and $(...) are handled correctly
in all modes.
+ AS_ESCAPE is changed to map each of the valid possibilities for CHARS
to the AS_QUOTE_D interpolation mode that was probably intended,
papering over the bugs in third party macros. (For example, both
[`\"] and [`] by itself will be mapped to allow-vars mode, because
we presume that someone who wrote [‘] didn’t think it through and
there’s a latent bug.) Invalid CHARS arguments now raise an error
instead of silently doing something nonsensical. All uses trigger
a -Wobsolete warning. AS_ESCAPE cannot be autoupdated to AS_QUOTE_D
(because it’s an m4sh macro, and because autoupdate can’t edit out
the surrounding quote marks) so instead I wrote a whole bunch of
advice for manual conversion in the manual.
WIP: buggy (partially but not entirely because of the bugs in
m4_join_uniq); one internal use of AS_ESCAPE remains; need to
write tests and NEWS; unresolved design decisions including
+ should ‘allow-arithmetic’ be a third interpolation keyword, separate
from ‘allow-vars’?
+ do we want a public API for escaping *without* adding surrounding
quotes? Autotest was doing this but it didn’t particularly need to.
+ should the result of AS_QUOTE_[DS] be M4-quoted? Currently it isn’t.
+ is expand-once-then-quote [i.e. shellquote(m4_dquote(m4_expand([text])))]
the most ergonomic behavior?