autoconf-commit
[Top][All Lists]
Advanced

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

[SCM] GNU Autoconf source repository branch, master, updated. v2.63-97-g


From: Eric Blake
Subject: [SCM] GNU Autoconf source repository branch, master, updated. v2.63-97-gd0c5f48
Date: Fri, 24 Oct 2008 13:49:50 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Autoconf source repository".

http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=d0c5f482d5aa2eb662758921e441d39dd0277531

The branch, master has been updated
       via  d0c5f482d5aa2eb662758921e441d39dd0277531 (commit)
       via  2922868b72bb0847d5df79dfc95fd93a2049cf42 (commit)
      from  21bd2e490b0804a0223b7044e89d5d31bd9f6476 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d0c5f482d5aa2eb662758921e441d39dd0277531
Author: Eric Blake <address@hidden>
Date:   Thu Oct 23 15:08:45 2008 -0600

    Optimize clients of AS_REQUIRE.
    
    * lib/m4sugar/m4sugar.m4 (m4_defun): Add undocumented third
    argument.
    (m4_defun_init): New undocumented macro.
    * lib/m4sugar/m4sh.m4 (_AS_ECHO_LOG, AS_MESSAGE, AS_BASENAME)
    (_AS_DIRNAME_EXPR, AS_DIRNAME, AS_ECHO, AS_ECHO_N, AS_TEST_X)
    (AS_LN_S, AS_MKDIR_P, _AS_PATH_WALK, AS_VERSION_COMPARE)
    (AS_TR_SH, AS_TR_CPP, AS_VAR_APPEND, AS_VAR_PUSHDEF): Use it to
    simplify these macros once the one-shot initialization is
    complete.
    * tests/m4sugar.at (m4@&address@hidden: one-shot initialization): New
    test.
    
    Signed-off-by: Eric Blake <address@hidden>

commit 2922868b72bb0847d5df79dfc95fd93a2049cf42
Author: Eric Blake <address@hidden>
Date:   Thu Oct 23 21:17:25 2008 -0600

    Improve m4_copy.
    
    * lib/m4sugar/m4sugar.m4 (m4_copy): Add second implementation for
    public use.
    (_m4_copy): New macro, which preserves pushdef stacks.
    (_m4_defun_pro_outer): Bypass it, for speed.
    (m4_init): Bypass new implementation, since it breaks on m4_defn.
    * bin/autoupdate.in (handle_autoconf_macros): Likewise.
    * lib/autoconf/general.m4 (AC_PREREQ): Undefine before redefining,
    now that m4_copy checks this.
    * doc/autoconf.texi (Redefined M4 Macros) <m4_copy>: Document
    this, as well as m4_rename.
    * lib/autoconf/autoconf.m4 (m4_copy): Temporarily redefine when
    renaming builtins.
    * NEWS: Likewise.
    * tests/m4sugar.at (m4@&address@hidden): Enhance test.
    
    Signed-off-by: Eric Blake <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                |   31 +++++++++++
 NEWS                     |    5 ++-
 bin/autoupdate.in        |    3 +-
 doc/autoconf.texi        |   19 +++++++
 lib/autoconf/autoconf.m4 |   12 ++++-
 lib/autoconf/general.m4  |    1 +
 lib/m4sugar/m4sh.m4      |   72 +++++++++++++-------------
 lib/m4sugar/m4sugar.m4   |  126 ++++++++++++++++++++++++++++++++++------------
 tests/m4sugar.at         |   46 ++++++++++++++++-
 9 files changed, 242 insertions(+), 73 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0a83589..ac48cd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,36 @@
 2008-10-24  Eric Blake  <address@hidden>
 
+       Optimize clients of AS_REQUIRE.
+       * lib/m4sugar/m4sugar.m4 (m4_defun): Add undocumented third
+       argument.
+       (m4_defun_init): New undocumented macro.
+       * lib/m4sugar/m4sh.m4 (_AS_ECHO_LOG, AS_MESSAGE, AS_BASENAME)
+       (_AS_DIRNAME_EXPR, AS_DIRNAME, AS_ECHO, AS_ECHO_N, AS_TEST_X)
+       (AS_LN_S, AS_MKDIR_P, _AS_PATH_WALK, AS_VERSION_COMPARE)
+       (AS_TR_SH, AS_TR_CPP, AS_VAR_APPEND, AS_VAR_PUSHDEF): Use it to
+       simplify these macros once the one-shot initialization is
+       complete.
+       * tests/m4sugar.at (m4@&address@hidden: one-shot initialization): New
+       test.
+
+       Improve m4_copy.
+       * lib/m4sugar/m4sugar.m4 (m4_copy): Add second implementation for
+       public use.
+       (_m4_copy): New macro, which preserves pushdef stacks.
+       (_m4_defun_pro_outer): Bypass it, for speed.
+       (m4_init): Bypass new implementation, since it breaks on m4_defn.
+       * bin/autoupdate.in (handle_autoconf_macros): Likewise.
+       * lib/autoconf/general.m4 (AC_PREREQ): Undefine before redefining,
+       now that m4_copy checks this.
+       * doc/autoconf.texi (Redefined M4 Macros) <m4_copy>: Document
+       this, as well as m4_rename.
+       * lib/autoconf/autoconf.m4 (m4_copy): Temporarily redefine when
+       renaming builtins, since it breaks on m4_ifdef.
+       * NEWS: Likewise.
+       * tests/m4sugar.at (m4@&address@hidden): Enhance test.
+
+2008-10-24  Eric Blake  <address@hidden>
+
        AC_FUNC_GETGROUPS: Revert regression.
        * lib/autoconf/functions.m4 (AC_FUNC_GETGROUPS): Only set
        ac_cv_func_getgroups_works=no when it is not available.
diff --git a/NEWS b/NEWS
index 8b682b8..496fac7 100644
--- a/NEWS
+++ b/NEWS
@@ -12,10 +12,13 @@ GNU Autoconf NEWS - User visible changes.
 
 ** Configure scripts now use shell functions.
 
-** The following m4sugar macros are new:
+** The following documented m4sugar macros are new:
    m4_curry  m4_default_quoted  m4_map_args  m4_map_args_pair
    m4_set_map
 
+** The following m4sugar macros are documented now:
+   m4_copy  m4_rename
+
 ** The following documented m4sh macros are new:
    AS_LINENO_PREPARE  AS_ME_PREPARE  AS_VAR_APPEND  AS_VAR_COPY
 
diff --git a/bin/autoupdate.in b/bin/autoupdate.in
index d23048a..c923559 100644
--- a/bin/autoupdate.in
+++ b/bin/autoupdate.in
@@ -271,7 +271,8 @@ foreach my $file (@ARGV)
       define([_au__include], defn([include]))
       define([_au___undefine], defn([undefine]))
       define([_au__undefine], [_au__ifdef([$1], [_au___undefine([$1])])])
-      define([_au__save], [m4_ifdef([$1], [m4_copy([$1], [_au_$1])])])
+      define([_au__save], [m4_ifdef([$1],
+       [m4_define([_au_$1], _m4_defn([$1]))])])
       define([_au__restore],
        [_au_m4_ifdef([_au_$1],
          [_au_m4_define([$1], _au__defn([_au_$1]))])])
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 71f507f..8509322 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10363,6 +10363,25 @@ is kept for future versions of M4sugar, once 
@acronym{GNU} M4 2.0 is
 released and supports extended regular expression syntax.
 @end defmac
 
address@hidden m4_copy (@var{source}, @var{dest})
address@hidden m4_rename (@var{source}, @var{dest})
address@hidden
address@hidden
+These macros aren't directly builtins, but are closely related to
address@hidden and @code{m4_defn}.  They both ensures that @var{dest}
+is undefined, then proceed to copy the entire pushdef stack of
+definitions of @var{source}.  @code{m4_copy} preserves the source, while
address@hidden undefines the original macro name.
+
+Note that attempting to invoke a renamed macro might not work, since the
+macro may have a dependence on helper macros accessed via composition of
address@hidden but that were not also renamed; likewise, other macros may
+have a hard-coded dependence on @var{source} and could break if
address@hidden has been deleted.  On the other hand, it is always safe to
+rename a macro to temporarily move it out of the way, then rename it
+back later to restore original semantics.
address@hidden defmac
+
 @defmac m4_defn (@address@hidden)
 @msindex{defn}
 This macro fails if @var{macro} is not defined, even when using older
diff --git a/lib/autoconf/autoconf.m4 b/lib/autoconf/autoconf.m4
index c802959..0a838a6 100644
--- a/lib/autoconf/autoconf.m4
+++ b/lib/autoconf/autoconf.m4
@@ -1,7 +1,7 @@
 # This file is part of Autoconf.                -*- Autoconf -*-
 # Driver that loads the Autoconf macro files.
 #
-# Copyright (C) 1994, 1999, 2000, 2001, 2002, 2006 Free Software
+# Copyright (C) 1994, 1999, 2000, 2001, 2002, 2006, 2008 Free Software
 # Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -76,6 +76,14 @@ m4_include([autoconf/oldnames.m4])
 # names too.  But users may still depend upon these, so reestablish
 # them.
 
+# In order to copy pushdef stacks, m4_copy temporarily destroys the
+# current pushdef stack.  But these builtins are so primitive that:
+#   1. they should not have more than one pushdef definition
+#   2. undefining the pushdef stack to copy breaks m4_copy
+# Hence, we temporarily restore a simpler m4_copy.
+
+m4_pushdef([m4_copy], [m4_define([$2], m4_defn([$1]))])
+
 m4_copy_unm4([m4_builtin])
 m4_copy_unm4([m4_changequote])
 m4_copy_unm4([m4_decr])
@@ -104,6 +112,8 @@ m4_copy_unm4([m4_translit])
 m4_copy_unm4([m4_undefine])
 m4_copy_unm4([m4_undivert])
 
+m4_popdef([m4_copy])
+
 # Yet some people have started to use m4_patsubst and m4_regexp.
 m4_define([m4_patsubst],
 [m4_expand_once([m4_warn([syntax],
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 158391c..4f13b58 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -317,6 +317,7 @@ AU_DEFUN([AC_PREREQ],
 # AC_PREREQ(VERSION)
 # ------------------
 # Complain and exit if the Autoconf version is less than VERSION.
+m4_undefine([AC_PREREQ])
 m4_copy([m4_version_prereq], [AC_PREREQ])
 
 
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index b96ec09..6620a56 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -648,8 +648,8 @@ m4_define([_AS_ECHO],
 # _AS_ECHO_LOG(STRING)
 # --------------------
 # Log the string to AS_MESSAGE_LOG_FD.
-m4_define([_AS_ECHO_LOG],
-[AS_REQUIRE([_AS_LINENO_PREPARE])]dnl
+m4_defun_init([_AS_ECHO_LOG],
+[AS_REQUIRE([_AS_LINENO_PREPARE])],
 [_AS_ECHO([$as_me:${as_lineno-$LINENO}: $1], [AS_MESSAGE_LOG_FD])])
 
 
@@ -685,8 +685,9 @@ m4_define([_AS_ECHO_N],
 
 # AS_MESSAGE(STRING, [FD = AS_MESSAGE_FD])
 # ----------------------------------------
-m4_define([AS_MESSAGE],
-[AS_REQUIRE([_AS_ME_PREPARE])]dnl
+# Output "`basename $0`: "STRING to the open file FD.
+m4_defun_init([AS_MESSAGE],
+[AS_REQUIRE([_AS_ME_PREPARE])],
 [m4_ifset([AS_MESSAGE_LOG_FD],
          [{ _AS_ECHO_LOG([$1])
 _AS_ECHO([$as_me: $1], [$2]);}],
@@ -757,8 +758,8 @@ m4_defun([_AS_BASENAME_SED],
          }
          s/.*/./; q']])
 
-m4_defun([AS_BASENAME],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_BASENAME],
+[AS_REQUIRE([_$0_PREPARE])],
 [$as_basename -- $1 ||
 _AS_BASENAME_EXPR([$1]) 2>/dev/null ||
 _AS_BASENAME_SED([$1])])
@@ -768,8 +769,7 @@ _AS_BASENAME_SED([$1])])
 # --------------------
 # Avoid Solaris 9 /usr/ucb/basename, as `basename /' outputs an empty line.
 # Also, traditional basename mishandles --.  Require here _AS_EXPR_PREPARE,
-# to avoid problems when _AS_BASENAME is called from the M4SH-INIT diversion
-# (AS_REQUIRE is nowhere near being as sophisticated as AC_REQUIRE).
+# to avoid problems when _AS_BASENAME is called from the M4SH-INIT diversion.
 m4_defun([_AS_BASENAME_PREPARE],
 [AS_REQUIRE([_AS_EXPR_PREPARE])]dnl
 [if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; 
then
@@ -791,8 +791,8 @@ fi
 # a silly length limit that causes expr to fail if the matched
 # substring is longer than 120 bytes.  So fall back on echo|sed if
 # expr fails.
-m4_defun([_AS_DIRNAME_EXPR],
-[AS_REQUIRE([_AS_EXPR_PREPARE])]dnl
+m4_defun_init([_AS_DIRNAME_EXPR],
+[AS_REQUIRE([_AS_EXPR_PREPARE])],
 [$as_expr X[]$1 : 'X\(.*[[^/]]\)//*[[^/][^/]]*/*$' \| \
         X[]$1 : 'X\(//\)[[^/]]' \| \
         X[]$1 : 'X\(//\)$' \| \
@@ -818,8 +818,8 @@ m4_defun([_AS_DIRNAME_SED],
          }
          s/.*/./; q']])
 
-m4_defun([AS_DIRNAME],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_DIRNAME],
+[AS_REQUIRE([_$0_PREPARE])],
 [$as_dirname -- $1 ||
 _AS_DIRNAME_EXPR([$1]) 2>/dev/null ||
 _AS_DIRNAME_SED([$1])])
@@ -842,16 +842,16 @@ fi
 # Output WORD followed by a newline.  WORD must be a single shell word
 # (typically a quoted string).  The bytes of WORD are output as-is, even
 # if it starts with "-" or contains "\".
-m4_defun([AS_ECHO],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_ECHO],
+[AS_REQUIRE([_$0_PREPARE])],
 [$as_echo $1])
 
 
 # AS_ECHO_N(WORD)
 # -------------
 # Like AS_ECHO(WORD), except do not output the trailing newline.
-m4_defun([AS_ECHO_N],
-[AS_REQUIRE([_AS_ECHO_PREPARE])]dnl
+m4_defun_init([AS_ECHO_N],
+[AS_REQUIRE([_AS_ECHO_PREPARE])],
 [$as_echo_n $1])
 
 
@@ -898,16 +898,16 @@ fi
 # AS_TEST_X
 # ---------
 # Check whether a file has executable or search permissions.
-m4_defun([AS_TEST_X],
-[AS_REQUIRE([_AS_TEST_PREPARE])]dnl
+m4_defun_init([AS_TEST_X],
+[AS_REQUIRE([_AS_TEST_PREPARE])],
 [$as_test_x $1[]])# AS_TEST_X
 
 
 # AS_EXECUTABLE_P
 # ---------------
 # Check whether a file is a regular file that has executable permissions.
-m4_defun([AS_EXECUTABLE_P],
-[AS_REQUIRE([_AS_TEST_PREPARE])]dnl
+m4_defun_init([AS_EXECUTABLE_P],
+[AS_REQUIRE([_AS_TEST_PREPARE])],
 [{ test -f $1 && AS_TEST_X([$1]); }])# AS_EXECUTABLE_P
 
 
@@ -1045,8 +1045,8 @@ rmdir conf$$.dir 2>/dev/null
 # -------------------
 # FIXME: Should we add the glue code to handle properly relative symlinks
 # simulated with `ln' or `cp'?
-m4_defun([AS_LN_S],
-[AS_REQUIRE([_AS_LN_S_PREPARE])]dnl
+m4_defun_init([AS_LN_S],
+[AS_REQUIRE([_AS_LN_S_PREPARE])],
 [$as_ln_s $1 $2])
 
 
@@ -1077,8 +1077,8 @@ m4_define([_AS_MKDIR_P],
 # AS_MKDIR_P(DIR)
 # ---------------
 # Emulate `mkdir -p' with plain `mkdir' if needed.
-m4_define([AS_MKDIR_P],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_MKDIR_P],
+[AS_REQUIRE([_$0_PREPARE])],
 [as_dir=$1; as_func_mkdir_p])# AS_MKDIR_P
 
 
@@ -1126,8 +1126,8 @@ fi
 # expansions, not on literal text.  This closes a longstanding sh security
 # hole.  Optimize it away when not needed, i.e., if there are no literal
 # path separators.
-m4_define([_AS_PATH_WALK],
-[AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE])]dnl
+m4_defun_init([_AS_PATH_WALK],
+[AS_REQUIRE([_AS_PATH_SEPARATOR_PREPARE])],
 [as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 m4_bmatch([$1], [[:;]],
 [as_dummy="$1"
@@ -1498,8 +1498,8 @@ m4_defun([_AS_VERSION_COMPARE_PREPARE],
 #
 # This usage is portable even to ancient awk,
 # so don't worry about finding a "nice" awk version.
-m4_defun([AS_VERSION_COMPARE],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_VERSION_COMPARE],
+[AS_REQUIRE([_$0_PREPARE])],
 [as_arg_v1=$1
 as_arg_v2=$2
 awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null
@@ -1557,8 +1557,8 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[[^_$as_cr_alnum]]%_%g'"
 # fact to skip worrying about the length of m4_cr_not_symbols2.
 #
 # For speed, we inline the literal definitions that can be computed up front.
-m4_defun([AS_TR_SH],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_TR_SH],
+[AS_REQUIRE([_$0_PREPARE])],
 [AS_LITERAL_IF([$1],
              [m4_translit([$1], [*+[]]]]dnl
 m4_dquote(m4_dquote(m4_defn([m4_cr_not_symbols2])))[[,
@@ -1584,8 +1584,8 @@ as_tr_cpp="eval sed 
'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[[^_$as_cr_alnum]]%_%g
 # of `$as_tr_cpp' if you change this.
 #
 # See implementation comments in AS_TR_SH.
-m4_defun([AS_TR_CPP],
-[AS_REQUIRE([_$0_PREPARE])]dnl
+m4_defun_init([AS_TR_CPP],
+[AS_REQUIRE([_$0_PREPARE])],
 [AS_LITERAL_IF([$1],
              [m4_translit([$1], [*[]]]]dnl
 m4_dquote(m4_dquote(m4_defn([m4_cr_letters])m4_defn([m4_cr_not_symbols2])))[[,
@@ -1659,9 +1659,9 @@ m4_define([_AS_VAR_APPEND_WORKS],
 # contents of VAR outweigh the typical VALUE size of repeated appends.
 # Note that unlike AS_VAR_SET, VALUE must be properly quoted to avoid
 # field splitting and file name expansion.
-m4_define([AS_VAR_APPEND],
+m4_defun_init([AS_VAR_APPEND],
 [_AS_DETECT_SUGGESTED([_AS_VAR_APPEND_WORKS])]dnl
-[AS_REQUIRE([_AS_VAR_APPEND_PREPARE], [], [M4SH-INIT-FN])]dnl
+[AS_REQUIRE([_AS_VAR_APPEND_PREPARE], [], [M4SH-INIT-FN])],
 [as_func_append $1 $2])
 
 
@@ -1741,8 +1741,8 @@ m4_define([AS_VAR_POPDEF],
 # calls that trigger AS_LITERAL_IF([VARNAME]), and that macro performs
 # expansion inside an argument collection context, where diversions
 # don't work.  Therefore, we must require the preparation ourselves.
-m4_define([AS_VAR_PUSHDEF],
-[AS_REQUIRE([_AS_TR_SH_PREPARE])]dnl
+m4_defun_init([AS_VAR_PUSHDEF],
+[AS_REQUIRE([_AS_TR_SH_PREPARE])],
 [AS_LITERAL_IF([$2],
               [m4_pushdef([$1], [AS_TR_SH($2)])],
               [as_$1=AS_TR_SH($2)
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index ee8ee63..13a1ddb 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -91,6 +91,10 @@ m4_undefine([undefine])
 # Nevertheless, one huge difference is the handling of `$0'.  If `from'
 # uses `$0', then with 1, `to''s `$0' is `to', while it is `from' in 2.
 # The user would certainly prefer to see `to'.
+#
+# This definition is in effect during m4sugar initialization, when
+# there are no pushdef stacks; later on, we redefine it to something
+# more powerful for all other clients to use.
 m4_define([m4_copy],
 [m4_define([$2], m4_defn([$1]))])
 
@@ -166,6 +170,28 @@ m4_rename_m4([traceon])
 m4_rename_m4([translit])
 m4_undefine([undivert])
 
+# _m4_defn(ARG)
+# ----------------
+# _m4_defn is for internal use only - it bypasses the wrapper, so it
+# must only be used on one argument at a time, and only on macros
+# known to be defined.  Make sure this still works if the user renames
+# m4_defn but not _m4_defn.
+m4_copy([m4_defn], [_m4_defn])
+
+# _m4_popdef(ARG...)
+# ------------------
+# _m4_popdef is for internal use only - it bypasses the wrapper, so it
+# must only be used on macros known to be defined.  Make sure this
+# still works if the user renames m4_popdef but not _m4_popdef.
+m4_copy([m4_popdef], [_m4_popdef])
+
+# _m4_undefine(ARG...)
+# --------------------
+# _m4_undefine is for internal use only - it bypasses the wrapper, so
+# it must only be used on macros known to be defined.  Make sure this
+# still works if the user renames m4_undefine but not _m4_undefine.
+m4_copy([m4_undefine], [_m4_undefine])
+
 
 ## ------------------- ##
 ## 2. Error messages.  ##
@@ -501,6 +527,28 @@ m4_define([_m4_bpatsubsts],
           m4_shift3($@))])])
 
 
+# m4_copy(SRC, DST)
+# -----------------
+# Define the pushdef stack DST as a copy of the pushdef stack SRC;
+# give an error if DST is already defined.  This is particularly nice
+# for copying self-modifying pushdef stacks, where the top definition
+# includes one-shot initialization that is later popped to the normal
+# definition.
+#
+# The recursive worker destructively swaps the order of a stack.  We
+# use a temporary stack, and swap directions twice, using the third
+# argument to restore the original stack.
+#
+# Some macros simply can't be renamed with this method: namely,
+# anything involved in the implementation of _m4_copy.
+m4_define([m4_copy],
+[m4_ifdef([$2], [m4_fatal([$0: won't overwrite defined macro: $2])],
+         [_$0([$1], [m4_tmp])_$0([m4_tmp], [$2],
+  [m4_pushdef([$1], _m4_defn([m4_tmp]))])])])
+m4_define([_m4_copy],
+[m4_ifdef([$1], [m4_pushdef([$2], _m4_defn([$1]))$3[]_m4_popdef([$1])$0($@)])])
+
+
 # m4_define_default(MACRO, VALUE)
 # -------------------------------
 # If MACRO is undefined, set it to VALUE.
@@ -547,12 +595,6 @@ m4_define([m4_default_quoted],
 # This macro is called frequently, so minimize the amount of additional
 # expansions by skipping m4_ifndef.  Better yet, if __m4_version__ exists,
 # (added in M4 1.6), then let m4 do the job for us (see m4_init).
-#
-# _m4_defn is for internal use only - it bypasses the wrapper, so it
-# must only be used on one argument at a time, and only on macros
-# known to be defined.  Make sure this still works if the user renames
-# m4_defn but not _m4_defn.
-m4_copy([m4_defn], [_m4_defn])
 m4_define([m4_defn],
 [m4_if([$#], [0], [[$0]],
        [$#], [1], [m4_ifdef([$1], [_m4_defn([$1])],
@@ -596,11 +638,6 @@ _m4_dumpdefs_down([$1])])
 # This macro is called frequently, so minimize the amount of additional
 # expansions by skipping m4_ifndef.  Better yet, if __m4_version__ exists,
 # (added in M4 1.6), then let m4 do the job for us (see m4_init).
-#
-# _m4_popdef is for internal use only - it bypasses the wrapper, so it
-# must only be used on macros known to be defined.  Make sure this
-# still works if the user renames m4_popdef but not _m4_popdef.
-m4_copy([m4_popdef], [_m4_popdef])
 m4_define([m4_popdef],
 [m4_if([$#], [0], [[$0]],
        [$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])],
@@ -662,11 +699,6 @@ m4_define([_m4_shift3],
 # This macro is called frequently, so minimize the amount of additional
 # expansions by skipping m4_ifndef.  Better yet, if __m4_version__ exists,
 # (added in M4 1.6), then let m4 do the job for us (see m4_init).
-#
-# _m4_undefine is for internal use only - it bypasses the wrapper, so
-# it must only be used on macros known to be defined.  Make sure this
-# still works if the user renames m4_undefine but not _m4_undefine.
-m4_copy([m4_undefine], [_m4_undefine])
 m4_define([m4_undefine],
 [m4_if([$#], [0], [[$0]],
        [$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])],
@@ -1578,7 +1610,8 @@ m4_do([[m4_ifdef([m4_expansion_stack], [], 
[_m4_defun_pro_outer[]])]],
       [[m4_pushdef([_m4_expanding($1)])]]))
 
 m4_define([_m4_defun_pro_outer],
-[m4_copy([_m4_divert_diversion], [_m4_divert_dump])m4_divert_push([GROW])])
+[m4_define([_m4_divert_dump],
+  m4_defn([_m4_divert_diversion]))m4_divert_push([GROW])])
 
 # _m4_defun_epi(MACRO-NAME)
 # -------------------------
@@ -1611,25 +1644,51 @@ m4_define([m4_divert_require],
   [_m4_require_call([$2], [$3], [$1])])])
 
 
-# m4_defun(NAME, EXPANSION)
-# -------------------------
-# Define a macro which automatically provides itself.  Add machinery
-# so the macro automatically switches expansion to the diversion
-# stack if it is not already using it.  In this case, once finished,
-# it will bring back all the code accumulated in the diversion stack.
-# This, combined with m4_require, achieves the topological ordering of
-# macros.  We don't use this macro to define some frequently called
-# macros that are not involved in ordering constraints, to save m4
-# processing.
+# m4_defun(NAME, EXPANSION, [MACRO = m4_define])
+# ----------------------------------------------
+# Define a macro NAME which automatically provides itself.  Add
+# machinery so the macro automatically switches expansion to the
+# diversion stack if it is not already using it, prior to EXPANSION.
+# In this case, once finished, it will bring back all the code
+# accumulated in the diversion stack.  This, combined with m4_require,
+# achieves the topological ordering of macros.  We don't use this
+# macro to define some frequently called macros that are not involved
+# in ordering constraints, to save m4 processing.
+#
+# MACRO is an undocumented argument; when set to m4_pushdef, and NAME
+# is already defined, the new definition is added to the pushdef
+# stack, rather than overwriting the current definition.  It can thus
+# be used to write self-modifying macros, which pop themselves to a
+# previously m4_define'd definition so that subsequent use of the
+# macro is faster.
 m4_define([m4_defun],
 [m4_define([m4_location($1)], m4_location)dnl
-m4_define([$1],
+m4_default([$3], [m4_define])([$1],
          [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])
 
 
+# m4_defun_init(NAME, INIT, COMMON)
+# ---------------------------------
+# Like m4_defun, but split EXPANSION into two portions: INIT which is
+# done only the first time NAME is invoked, and COMMON which is
+# expanded every time.
+#
+# For now, the COMMON definition is always m4_define'd, giving an even
+# lighter-weight definition.  m4_defun allows self-providing, but once
+# a macro is provided, m4_require no longer cares if it is m4_define'd
+# or m4_defun'd.  m4_defun also provides location tracking to identify
+# dependency bugs, but once the INIT has been expanded, we know there
+# are no dependency bugs.  However, if a future use needs COMMON to be
+# m4_defun'd, we can add a parameter, similar to the third parameter
+# to m4_defun.
+m4_define([m4_defun_init],
+[m4_define([$1], [$3])m4_defun([$1],
+   [$2[]_m4_popdef(]m4_dquote([$][0])[)$][0($][@)], [m4_pushdef])])
+
+
 # m4_defun_once(NAME, EXPANSION)
 # ------------------------------
-# As m4_defun, but issues the EXPANSION only once, and warns if used
+# Like m4_defun, but issues the EXPANSION only once, and warns if used
 # several times.
 m4_define([m4_defun_once],
 [m4_define([m4_location($1)], m4_location)dnl
@@ -2838,12 +2897,13 @@ m4_pattern_forbid([^dnl$])
 # But if it is missing, we assume we are being run by M4 1.4.x, that
 # $@ recursion is quadratic, and that we need foreach-based
 # replacement macros.  Use the raw builtin to avoid tripping up
-# include tracing.
+# include tracing.  Meanwhile, avoid m4_copy, since it temporarily
+# undefines m4_defn.
 m4_ifdef([__m4_version__],
 [m4_debugmode([+d])
-m4_copy([_m4_defn], [m4_defn])
-m4_copy([_m4_popdef], [m4_popdef])
-m4_copy([_m4_undefine], [m4_undefine])],
+m4_define([m4_defn], _m4_defn([m4_defn]))
+m4_define([m4_popdef], _m4_defn([m4_popdef]))
+m4_define([m4_undefine], _m4_defn([m4_undefine]))],
 [m4_builtin([include], [m4sugar/foreach.m4])])
 
 # _m4_divert_diversion should be defined:
diff --git a/tests/m4sugar.at b/tests/m4sugar.at
index f34bca3..cfaed3b 100644
--- a/tests/m4sugar.at
+++ b/tests/m4sugar.at
@@ -43,7 +43,7 @@ AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
 
 AT_SETUP([m4@&address@hidden)
 
-AT_KEYWORDS([m4@&address@hidden m4@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden m4@&address@hidden m4@&address@hidden 
m4@&address@hidden)
 
 # Ensure that m4sugar dies when dereferencing undefined macros, whether
 # this is provided by m4 natively or faked by wrappers in m4sugar.
@@ -75,6 +75,25 @@ AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
 AT_CHECK([grep good stderr], [1])
 AT_CHECK([grep 'm4@&address@hidden: undefined.*oops' stderr], [0], [ignore])
 
+# Check that pushdef stacks can be renamed.
+AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl
+m4_pushdef([a], [2])dnl
+a b c
+m4_rename([a], [b])dnl
+a b c
+m4_copy([b], [c])dnl
+a b c
+m4_popdef([b], [c])dnl
+a b c
+m4_popdef([b], [c])dnl
+a b c
+]], [[2 b c
+a 2 c
+a 2 2
+a 1 1
+a b c
+]])
+
 AT_CLEANUP
 
 
@@ -176,6 +195,31 @@ autom4te: m4 failed with exit status: 1
 AT_CLEANUP
 
 
+## ---------------------- ##
+## m4_require: one-shot.  ##
+## ---------------------- ##
+
+AT_SETUP([m4@&address@hidden: one-shot initialization])
+AT_KEYWORDS([m4@&address@hidden)
+
+AT_CHECK_M4SUGAR_TEXT([[
+m4_defun_init([a], [[init a
+]], [[common a]])dnl
+m4_defun([b], [[b]m4_require([a])])dnl
+m4_defun([c], [[c]m4_require([a])])dnl
+b
+c
+a
+]], [[
+init a
+common a
+b
+c
+common a
+]])
+AT_CLEANUP
+
+
 ## --------- ##
 ## m4_cond.  ##
 ## --------- ##


hooks/post-receive
--
GNU Autoconf source repository




reply via email to

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