]> git.ipfire.org Git - thirdparty/autoconf.git/commit
WIP: replace AS_ESCAPE and _AS_QUOTE with AS_QUOTE_D.
authorZack Weinberg <zack@owlfolio.org>
Wed, 26 Jun 2024 18:42:44 +0000 (14:42 -0400)
committerZack Weinberg <zack@owlfolio.org>
Wed, 26 Jun 2024 20:03:57 +0000 (16:03 -0400)
commitec192f7fc9b5cab9aa34c8135e60aba3670edf53
tree8c60fa17fd28741ee4626fba31e5fd01e4695cd2
parent4ffd73054a515af570168d98d97c8644b06f1951
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:

    - ‘allow-vars’: Allow variable and arithmetic interpolation.
    - ‘allow-commands’: Allow command substitution.

  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?
doc/autoconf.texi
lib/autoconf/autoheader.m4
lib/autoconf/general.m4
lib/autoconf/headers.m4
lib/autoconf/types.m4
lib/autotest/general.m4
lib/m4sugar/m4sh.m4