autoconf-patches
[Top][All Lists]
Advanced

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

[PATCH] AC_INIT: properly quote package name containing m4 macro


From: Eric Blake
Subject: [PATCH] AC_INIT: properly quote package name containing m4 macro
Date: Thu, 17 Mar 2011 08:18:37 -0600

_AC_INIT_PACKAGE was woefully underquoted when it tried to convert $1
into AC_PACKAGE_TARNAME; several other places were likewise suspect in
their use of AC_PACKAGE variables.  The first argument to AC_INIT
makes more sense as a literal package name that should not undergo
further m4 expansion.

Then _AC_INIT_LITERAL was tripping up on a limitation of m4_expand
coupled with autoconf's insanity of re-exposing 'changequote' into the
macro namespace (rather than keeping it m4_changequote, like autotest
and other sane m4sh clients).  There is just no way to safely expand a
nested changequote within m4_expand, but with quadrigraphs and
other workarounds, it should never be necessary (after all, we
document that use of changequote is dangerous).  It might be nicer
if m4 had pushquote/popquote; oh well.

* lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Don't expand $1.
(_AC_INIT_LITERAL): Work around m4_expand limitation.
(_AC_INIT_NOTICE, _AC_INIT_DEFAULTS, _AC_INIT_HELP)
(_AC_INIT_VERSION, _AC_INIT_CONFIG_LOG): Don't expand
AC_PACKAGE_*.
* lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL_BODY):
Likewise.
* lib/autoconf/status.m4 (_AC_OUTPUT_CONFIG_STATUS): Likewise.
* lib/m4sugar/m4sugar.m4 (m4_expand): Protect against infinite
recursion.
* tests/tools.at (package with m4 macro in name): New test.
Reported by Stefano Lattarini.

Signed-off-by: Eric Blake <address@hidden>
---

The test now passes, but I have not pushed this yet.

Note that this is a subtle semantic change.  It used to be that you
could do:

m4_define([pkg_name], [foo])
AC_INIT([pkg_name], [1.0])

and that would result in AC_SUBST of PACKAGE_NAME=foo

With this patch, it results in PACKAGE_NAME=pkg_name.

Note that this patch still has an implicit limitation that you can't
do AC_INIT([m4_...]) for many m4sugar macro names; but as the m4_
prefix is less likely to appear in a real package name, I'm not as
worried (after all, m4 can't code around every possible string without
an insane amount of overhead, so focusing on efficiently handling just
the majority of useful strings is okay).

However, we were inconsistent; at least _AS_DETECT_BETTER_SHELL was
already using m4_defn([AC_PACKAGE_NAME]), which would report pkg_name
in the above situation rather than foo.  That alone argues that we
should either always expand or always treat as a literal string; this
patch goes for the literal string aspect.

I don't see too much harm in making this change, and stating that the
arguments to AC_INIT are never re-expanded for macros by autoconf
itself.  For most packages it won't matter - you don't define macros
for your package name; for automake, it will avoid the testsuite
failures encountered when the test name included an m4 builtin that
later became an AC_INIT argument.  And for computation purposes, you
can _always_ do this, pre- and post-patch, to get PACKAGE_NAME=foo:

m4_define([pkg_name], [foo])
AC_INIT(pkg_name, [1.0])

I think that I need to also touch up docs/autoconf.texi and NEWS
before pushing this, in case someone really was expecting macro
invocation after the fact.

 ChangeLog               |   16 ++++++++++++
 lib/autoconf/general.m4 |   62 +++++++++++++++++++++++++++-------------------
 lib/autoconf/headers.m4 |    2 +-
 lib/autoconf/status.m4  |   14 ++++++----
 lib/m4sugar/m4sugar.m4  |    2 +
 tests/tools.at          |   24 ++++++++++++++++++
 6 files changed, 87 insertions(+), 33 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 30dfced..16d01d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-03-16  Eric Blake  <address@hidden>
+
+       AC_INIT: properly quote package name containing m4 macro
+       * lib/autoconf/general.m4 (_AC_INIT_PACKAGE): Don't expand $1.
+       (_AC_INIT_LITERAL): Work around m4_expand limitation.
+       (_AC_INIT_NOTICE, _AC_INIT_DEFAULTS, _AC_INIT_HELP)
+       (_AC_INIT_VERSION, _AC_INIT_CONFIG_LOG): Don't expand
+       AC_PACKAGE_*.
+       * lib/autoconf/headers.m4 (_AC_CHECK_HEADER_MONGREL_BODY):
+       Likewise.
+       * lib/autoconf/status.m4 (_AC_OUTPUT_CONFIG_STATUS): Likewise.
+       * lib/m4sugar/m4sugar.m4 (m4_expand): Protect against infinite
+       recursion.
+       * tests/tools.at (package with m4 macro in name): New test.
+       Reported by Stefano Lattarini.
+
 2011-03-08  Colin Watson  <address@hidden>  (tiny change)
            Ralf Wildenhues  <address@hidden>

diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index dd20e71..7b8c873 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -227,10 +227,14 @@ AU_ALIAS([AC_HELP_STRING], [AS_HELP_STRING])
 # Reject STRING if it contains newline, or if it cannot be used as-is
 # in single-quoted strings, double-quoted strings, and quoted and
 # unquoted here-docs.
+#
+# Special case changequote to work around m4_expand limitations.
 m4_define([_AC_INIT_LITERAL],
+[m4_rename([changequote], [_m4_changequote])]dnl
 [m4_if(m4_index(m4_translit([[$1]], [
 ""], ['']), ['])AS_LITERAL_HEREDOC_IF([$1], [-]), [-1-], [],
-  [m4_warn([syntax], [AC_INIT: not a literal: $1])])])
+  [m4_warn([syntax], [AC_INIT: not a literal: $1])])]dnl
+[m4_rename([_m4_changequote], [changequote])])

 # _AC_INIT_PACKAGE(PACKAGE-NAME, VERSION, BUG-REPORT, [TARNAME], [URL])
 # ---------------------------------------------------------------------
@@ -241,12 +245,10 @@ _AC_INIT_LITERAL([$3])
 m4_ifndef([AC_PACKAGE_NAME],
          [m4_define([AC_PACKAGE_NAME],     [$1])])
 m4_ifndef([AC_PACKAGE_TARNAME],
-         [m4_define([AC_PACKAGE_TARNAME],
-                    m4_default([$4],
-                               [m4_bpatsubst(m4_tolower(m4_bpatsubst([[$1]],
-                                                                    [GNU ])),
-                                [[^_abcdefghijklmnopqrstuvwxyz0123456789]],
-                                [-])]))])
+  [m4_define([AC_PACKAGE_TARNAME],
+    m4_if([$4], [],
+      [m4_translit(_AS_TR_SH_LITERAL(m4_bpatsubst([[[$1]]],
+       [^\(..\)GNU ], [\1])), [_A-Z], [-a-z])], [[$4]]))])
 m4_ifndef([AC_PACKAGE_VERSION],
          [m4_define([AC_PACKAGE_VERSION],   [$2])])
 m4_ifndef([AC_PACKAGE_STRING],
@@ -341,12 +343,12 @@ m4_define([_AC_INIT_NOTICE],
 [m4_divert_text([HEADER-COMMENT],
 address@hidden:@ Guess values for system-dependent variables and create 
Makefiles.
 @%:@ Generated by m4_PACKAGE_STRING[]dnl
-m4_ifset([AC_PACKAGE_STRING], [ for AC_PACKAGE_STRING]).])
+m4_ifset([AC_PACKAGE_STRING], [ for m4_defn([AC_PACKAGE_STRING])]).])

 m4_ifset([AC_PACKAGE_BUGREPORT],
         [m4_divert_text([HEADER-COMMENT],
                         address@hidden:@
address@hidden:@ Report bugs to <AC_PACKAGE_BUGREPORT>.])])
address@hidden:@ Report bugs to <m4_defn([AC_PACKAGE_BUGREPORT])>.])])
 ])


@@ -415,17 +417,23 @@ AC_SUBST([PATH_SEPARATOR])dnl

 # Identity of this package.
 AC_SUBST([PACKAGE_NAME],
-        [m4_ifdef([AC_PACKAGE_NAME],      ['AC_PACKAGE_NAME'])])dnl
+  m4_ifdef([AC_PACKAGE_NAME],
+   ['m4_dquote(m4_defn([AC_PACKAGE_NAME]))']))dnl
 AC_SUBST([PACKAGE_TARNAME],
-        [m4_ifdef([AC_PACKAGE_TARNAME],   ['AC_PACKAGE_TARNAME'])])dnl
+  m4_ifdef([AC_PACKAGE_TARNAME],
+   ['m4_dquote(m4_defn([AC_PACKAGE_TARNAME]))']))dnl
 AC_SUBST([PACKAGE_VERSION],
-        [m4_ifdef([AC_PACKAGE_VERSION],   ['AC_PACKAGE_VERSION'])])dnl
+  m4_ifdef([AC_PACKAGE_VERSION],
+   ['m4_dquote(m4_defn([AC_PACKAGE_VERSION]))']))dnl
 AC_SUBST([PACKAGE_STRING],
-        [m4_ifdef([AC_PACKAGE_STRING],    ['AC_PACKAGE_STRING'])])dnl
+  m4_ifdef([AC_PACKAGE_STRING],
+   ['m4_dquote(m4_defn([AC_PACKAGE_STRING]))']))dnl
 AC_SUBST([PACKAGE_BUGREPORT],
-        [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])dnl
+  m4_ifdef([AC_PACKAGE_BUGREPORT],
+   ['m4_dquote(m4_defn([AC_PACKAGE_BUGREPORT]))']))dnl
 AC_SUBST([PACKAGE_URL],
-        [m4_ifdef([AC_PACKAGE_URL],       ['AC_PACKAGE_URL'])])dnl
+  m4_ifdef([AC_PACKAGE_URL],
+   ['m4_dquote(m4_defn([AC_PACKAGE_URL]))']))dnl

 m4_divert_pop([DEFAULTS])dnl
 m4_wrap_lifo([m4_divert_text([DEFAULTS],
@@ -588,9 +596,9 @@ AC_SUBST([sharedstatedir], ['${prefix}/com'])dnl
 AC_SUBST([localstatedir],  ['${prefix}/var'])dnl
 AC_SUBST([includedir],     ['${prefix}/include'])dnl
 AC_SUBST([oldincludedir],  ['/usr/include'])dnl
-AC_SUBST([docdir],         [m4_ifset([AC_PACKAGE_TARNAME],
+AC_SUBST([docdir],         m4_ifset([AC_PACKAGE_TARNAME],
                                     ['${datarootdir}/doc/${PACKAGE_TARNAME}'],
-                                    ['${datarootdir}/doc/${PACKAGE}'])])dnl
+                                    [['${datarootdir}/doc/${PACKAGE}']]))dnl
 AC_SUBST([infodir],        ['${datarootdir}/info'])dnl
 AC_SUBST([htmldir],        ['${docdir}'])dnl
 AC_SUBST([dvidir],         ['${docdir}'])dnl
@@ -1019,7 +1027,7 @@ if test "$ac_init_help" = "long"; then
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
 \`configure' configures m4_ifset([AC_PACKAGE_STRING],
-                       [AC_PACKAGE_STRING],
+                       [m4_defn([AC_PACKAGE_STRING])],
                        [this package]) to adapt to many kinds of systems.

 Usage: $[0] [[OPTION]]... [[VAR=VALUE]]...
@@ -1070,7 +1078,7 @@ Fine tuning of the installation directories:
   --mandir=DIR            man documentation [DATAROOTDIR/man]
 ]AS_HELP_STRING([--docdir=DIR],
   [documentation root ]@<:@DATAROOTDIR/doc/m4_ifset([AC_PACKAGE_TARNAME],
-    [AC_PACKAGE_TARNAME], [PACKAGE])@:>@)[
+    [m4_defn([AC_PACKAGE_TARNAME])], [PACKAGE])@:>@)[
   --htmldir=DIR           html documentation [DOCDIR]
   --dvidir=DIR            dvi documentation [DOCDIR]
   --pdfdir=DIR            pdf documentation [DOCDIR]
@@ -1108,16 +1116,17 @@ fi
 if test -n "$ac_init_help"; then
 m4_ifset([AC_PACKAGE_STRING],
 [  case $ac_init_help in
-     short | recursive ) echo "Configuration of AC_PACKAGE_STRING:";;
+     short | recursive ) echo "Configuration of 
m4_defn([AC_PACKAGE_STRING]):";;
    esac])
   cat <<\_ACEOF
 m4_divert_pop([HELP_ENABLE])dnl
 m4_divert_push([HELP_END])dnl

-Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], [<AC_PACKAGE_BUGREPORT>],
+Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT],
+  [<m4_defn([AC_PACKAGE_BUGREPORT])>],
   [the package provider]).dnl
 m4_ifdef([AC_PACKAGE_NAME], [m4_ifset([AC_PACKAGE_URL], [
-AC_PACKAGE_NAME home page: <AC_PACKAGE_URL>.])dnl
+m4_defn([AC_PACKAGE_NAME]) home page: <m4_defn([AC_PACKAGE_URL])>.])dnl
 m4_if(m4_index(m4_defn([AC_PACKAGE_NAME]), [GNU ]), [0], [
 General help using GNU software: <http://www.gnu.org/gethelp/>.])])
 _ACEOF
@@ -1158,8 +1167,8 @@ m4_define([_AC_INIT_VERSION],
 [m4_divert_text([VERSION_BEGIN],
 [if $ac_init_version; then
   cat <<\_ACEOF
-m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])configure[]dnl
-m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])configure[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ m4_defn([AC_PACKAGE_VERSION])])
 generated by m4_PACKAGE_STRING])
 m4_divert_text([VERSION_END],
 [_ACEOF
@@ -1178,8 +1187,9 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.

-It was created by m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])dnl
-$as_me[]m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]), which was
+It was created by m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])dnl
+$as_me[]m4_ifset([AC_PACKAGE_VERSION],
+ [ m4_defn([AC_PACKAGE_VERSION])]), which was
 generated by m4_PACKAGE_STRING.  Invocation command line was

   $ $[0] address@hidden
diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4
index 4b02832..5e315ae 100644
--- a/lib/autoconf/headers.m4
+++ b/lib/autoconf/headers.m4
@@ -107,7 +107,7 @@ case 
$ac_header_compiler:$ac_header_preproc:$ac_[]_AC_LANG_ABBREV[]_preproc_warn
     AC_MSG_WARN([$[]2:     section "Present But Cannot Be Compiled"])
     AC_MSG_WARN([$[]2: proceeding with the compiler's result])
 m4_ifset([AC_PACKAGE_BUGREPORT],
-[m4_n([( AS_BOX([Report this to ]AC_PACKAGE_BUGREPORT)
+[m4_n([( AS_BOX([Report this to ]m4_defn([AC_PACKAGE_BUGREPORT]))
      ) | sed "s/^/$as_me: WARNING:     /" >&2])])dnl
     ;;
 esac
diff --git a/lib/autoconf/status.m4 b/lib/autoconf/status.m4
index 46a0341..46155bd 100644
--- a/lib/autoconf/status.m4
+++ b/lib/autoconf/status.m4
@@ -1335,8 +1335,9 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])dnl
-$as_me[]m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]), which was
+This file was extended by m4_ifset([AC_PACKAGE_NAME],
+ [m4_defn([AC_PACKAGE_NAME]) ])$as_me[]m4_ifset([AC_PACKAGE_VERSION],
+ [ m4_defn([AC_PACKAGE_VERSION])]), which was
 generated by m4_PACKAGE_STRING.  Invocation command line was

   CONFIG_FILES    = $CONFIG_FILES
@@ -1423,10 +1424,11 @@ m4_ifdef([_AC_SEEN_CONFIG(COMMANDS)],
 $config_commands

 ])dnl
-Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT], [<AC_PACKAGE_BUGREPORT>],
+Report bugs to m4_ifset([AC_PACKAGE_BUGREPORT],
+  [<m4_defn([AC_PACKAGE_BUGREPORT])>],
   [the package provider]).dnl
 m4_ifdef([AC_PACKAGE_NAME], [m4_ifset([AC_PACKAGE_URL], [
-AC_PACKAGE_NAME home page: <AC_PACKAGE_URL>.])dnl
+m4_defn([AC_PACKAGE_NAME]) home page: <m4_defn([AC_PACKAGE_URL])>.])dnl
 m4_if(m4_index(m4_defn([AC_PACKAGE_NAME]), [GNU ]), [0], [
 General help using GNU software: <http://www.gnu.org/gethelp/>.])])"

@@ -1434,8 +1436,8 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`AS_ECHO(["$ac_configure_args"]) | sed 's/^ //; 
s/[[\\""\`\$]]/\\\\&/g'`"
 ac_cs_version="\\
-m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.status[]dnl
-m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+m4_ifset([AC_PACKAGE_NAME], [m4_defn([AC_PACKAGE_NAME]) ])config.status[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ m4_defn([AC_PACKAGE_VERSION])])
 configured by $[0], generated by m4_PACKAGE_STRING,
   with options \\"\$ac_cs_config\\"

diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 00f1f4a..c053303 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -915,6 +915,8 @@ m4_define([m4_echo], address@hidden)
 # open-quote delimiter.  We must also ignore the slop from the
 # previous try.  The final macro is thus half line-noise, half art.
 m4_define([m4_expand],
+[m4_if(m4_index([$1], m4_ifdef([changequote], [], [[m4_]])[changequote]),
+  [-1], [], [m4_fatal([$0: cannot call changequote inside m4_expand])])]dnl
 [m4_pushdef([m4_divert], _m4_defn([_m4_divert_unsafe]))]dnl
 [m4_pushdef([m4_divert_push], _m4_defn([_m4_divert_unsafe]))]dnl
 [m4_chomp(_$0([$1
diff --git a/tests/tools.at b/tests/tools.at
index 0ccb387..cef6c47 100644
--- a/tests/tools.at
+++ b/tests/tools.at
@@ -1335,3 +1335,27 @@ END
 done

 AT_CLEANUP
+
+# package with m4 macro in name
+# -----------------------------
+
+AT_SETUP([package with m4 macro in name])
+
+dnl Why did autoconf ever re-expose the m4 builtins without the m4_ prefix?
+dnl In 2.68, this would create PACKAGE_NAME='10-disaster'.
+AT_DATA_M4SH([configure.ac],
+[[AC_INIT([divnum-disaster], [1.0])
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK([[grep [0-9]-disaster configure]], [1])
+
+dnl Even worse, changequote is a nightmare waiting to happen.
+dnl In Autoconf 2.68, this would exceed recursion limits.
+AT_DATA_M4SH([configure.ac],
+[[AC_INIT([perl-changequote-helper], [1.0])
+]])
+
+AT_CHECK_AUTOCONF
+
+AT_CLEANUP
-- 
1.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]