]> git.saurik.com Git - bison.git/commitdiff
Partial m4sugar merge from autoconf: m4_shiftn.
authorEric Blake <ebb9@byu.net>
Thu, 7 Aug 2008 03:22:06 +0000 (21:22 -0600)
committerEric Blake <ebb9@byu.net>
Thu, 7 Aug 2008 03:22:06 +0000 (21:22 -0600)
* data/m4sugar/m4sugar.m4 (m4_shiftn): Faster implementation.
(m4_shift2, m4_shift3): New macros.
(m4_case, m4_bmatch, m4_bpatsubsts, m4_join): Adjust clients.
* data/c.m4 (b4_c_function_def, b4_c_ansi_function_def)
(b4_c_ansi_function_decl, b4_c_function_call): Likewise.
* data/java.m4 (b4_remove_comma): Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
data/c.m4
data/java.m4
data/m4sugar/m4sugar.m4

index 114f5e2c926bd2199b9bc2bf4fb91df158724035..5af268ee1805939745113e0dda4225ae7d4bd60e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2008-08-06  Eric Blake  <ebb9@byu.net>
 
+       Partial m4sugar merge from autoconf: m4_shiftn.
+       * data/m4sugar/m4sugar.m4 (m4_shiftn): Faster implementation.
+       (m4_shift2, m4_shift3): New macros.
+       (m4_case, m4_bmatch, m4_bpatsubsts, m4_join): Adjust clients.
+       * data/c.m4 (b4_c_function_def, b4_c_ansi_function_def)
+       (b4_c_ansi_function_decl, b4_c_function_call): Likewise.
+       * data/java.m4 (b4_remove_comma): Likewise.
+
        Partial m4sugar merge from autoconf: m4_wrap vs. m4 1.6.
        * data/m4sugar/m4sugar.m4 (m4_unquote, m4_wrap_lifo): New macros.
        (m4_wrap): Guarantee FIFO order, in spite of m4 1.6.
index dbec53c6520ba9ce5ae97743e7f78c9b37b2bee7..ced2b1e2b399a38d1c3c39725b1e4f43a8f20427 100644 (file)
--- a/data/c.m4
+++ b/data/c.m4
@@ -1,7 +1,8 @@
                                                             -*- Autoconf -*-
 
 # C M4 Macros for Bison.
-# Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software
+# Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -228,8 +229,8 @@ m4_define([b4_c_function_def],
 b4_c_ansi_function_def($@)
 #else
 $2
-$1 (b4_c_knr_formal_names(m4_shiftn(2, $@)))
-b4_c_knr_formal_decls(m4_shiftn(2, $@))
+$1 (b4_c_knr_formal_names(m4_shift2($@)))
+b4_c_knr_formal_decls(m4_shift2($@))
 #endif[]dnl
 ])
 
@@ -239,7 +240,7 @@ b4_c_knr_formal_decls(m4_shiftn(2, $@))
 # Declare the function NAME in ANSI.
 m4_define([b4_c_ansi_function_def],
 [$2
-$1 (b4_c_ansi_formals(m4_shiftn(2, $@)))[]dnl
+$1 (b4_c_ansi_formals(m4_shift2($@)))[]dnl
 ])
 
 
@@ -301,7 +302,7 @@ $2 $1 ();
 # ----------------------------------------------------------------
 # Declare the function NAME.
 m4_define([b4_c_ansi_function_decl],
-[$2 $1 (b4_c_ansi_formals(m4_shiftn(2, $@)));[]dnl
+[$2 $1 (b4_c_ansi_formals(m4_shift2($@)));[]dnl
 ])
 
 
@@ -316,7 +317,7 @@ m4_define([b4_c_ansi_function_decl],
 # -----------------------------------------------------------
 # Call the function NAME with arguments NAME1, NAME2 etc.
 m4_define([b4_c_function_call],
-[$1 (b4_c_args(m4_shiftn(2, $@)))[]dnl
+[$1 (b4_c_args(m4_shift2($@)))[]dnl
 ])
 
 
index 3f259fd5d7759523a1b25bbef755cd28318d0d29..13876941c98050a53248eda8769f0e668cabbe5e 100644 (file)
@@ -2,7 +2,7 @@
 
 # Java language support for Bison
 
-# Copyright (C) 2007 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ m4_define([b4_identification],
 m4_define([b4_int_type],
 [m4_if(b4_ints_in($@,   [-128],   [127]), [1], [byte],
        b4_ints_in($@, [-32768], [32767]), [1], [short],
-                                                      [int])])
+                                              [int])])
 
 # b4_int_type_for(NAME)
 # ---------------------
@@ -205,7 +205,7 @@ m4_define([b4_param_decls],
          [m4_map([b4_param_decl], [$@])])
 m4_define([b4_param_decl], [, $1])
 
-m4_define([b4_remove_comma], [m4_ifval($1, [$1, ], [])m4_shiftn(2, $@)])
+m4_define([b4_remove_comma], [m4_ifval($1, [$1, ], [])m4_shift2($@)])
 
 
 
index 4fa54b39a9da58f49649ec89589dd54047b4caac..97b38a4dcfbbd1f0fdfe02f97cd6a5f74920d817 100644 (file)
@@ -366,7 +366,7 @@ m4_define([m4_case],
        [$#], 1, [],
        [$#], 2, [$2],
        [$1], [$2], [$3],
-       [$0([$1], m4_shiftn(3, $@))])])
+       [$0([$1], m4_shift3($@))])])
 
 
 # m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT)
@@ -388,7 +388,7 @@ m4_define([m4_bmatch],
 [m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
        [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
        [$#], 2, [$2],
-       [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shiftn(3, $@))],
+       [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shift3($@))],
              [$3])])])
 
 
@@ -445,13 +445,19 @@ m4_define([m4_map_sep],
 # I would have liked to name this macro `m4_bpatsubst', unfortunately,
 # due to quotation problems, I need to double quote $1 below, therefore
 # the anchors are broken :(  I can't let users be trapped by that.
+#
+# Recall that m4_shift3 always results in an argument.  Hence, we need
+# to distinguish between a final deletion vs. ending recursion.
 m4_define([m4_bpatsubsts],
 [m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
        [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
-       [$#], 2, [m4_builtin([patsubst], $@)],
+       [$#], 2, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2]))],
+       [$#], 3, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2], [$3]))],
+       [_$0($@m4_if(m4_eval($# & 1), 0, [,]))])])
+m4_define([_m4_bpatsubsts],
+[m4_if([$#], 2, [$1],
        [$0(m4_builtin([patsubst], [[$1]], [$2], [$3]),
-          m4_shiftn(3, $@))])])
-
+          m4_shift3($@))])])
 
 
 # m4_do(STRING, ...)
@@ -555,14 +561,45 @@ m4_define([m4_noquote],
 # m4_shiftn(N, ...)
 # -----------------
 # Returns ... shifted N times.  Useful for recursive "varargs" constructs.
+#
+# Autoconf does not use this macro, because it is inherently slower than
+# calling the common cases of m4_shift2 or m4_shift3 directly.  But it
+# might as well be fast for other clients, such as Libtool.  One way to
+# do this is to expand $@ only once in _m4_shiftn (otherwise, for long
+# lists, the expansion of m4_if takes twice as much memory as what the
+# list itself occupies, only to throw away the unused branch).  The end
+# result is strictly equivalent to
+#   m4_if([$1], 1, [m4_shift(,m4_shift(m4_shift($@)))],
+#         [_m4_shiftn(m4_decr([$1]), m4_shift(m4_shift($@)))])
+# but with the final `m4_shift(m4_shift($@)))' shared between the two
+# paths.  The first leg uses a no-op m4_shift(,$@) to balance out the ().
 m4_define([m4_shiftn],
-[m4_assert(($1 >= 0) && ($# > $1))dnl
-_m4_shiftn($@)])
+[m4_assert(0 < $1 && $1 < $#)_$0($@)])
 
 m4_define([_m4_shiftn],
-[m4_if([$1], 0,
-       [m4_shift($@)],
-       [_m4_shiftn(m4_eval([$1]-1), m4_shift(m4_shift($@)))])])
+[m4_if([$1], 1, [m4_shift(],
+       [$0(m4_decr([$1])]), m4_shift(m4_shift($@)))])
+
+# m4_shift2(...)
+# m4_shift3(...)
+# -----------------
+# Returns ... shifted twice, and three times.  Faster than m4_shiftn.
+m4_define([m4_shift2], [m4_shift(m4_shift($@))])
+m4_define([m4_shift3], [m4_shift(m4_shift(m4_shift($@)))])
+
+# _m4_shift2(...)
+# _m4_shift3(...)
+# ---------------
+# Like m4_shift2 or m4_shift3, except include a leading comma unless shifting
+# consumes all arguments.  Why?  Because in recursion, it is nice to
+# distinguish between 1 element left and 0 elements left, based on how many
+# arguments this shift expands to.
+m4_define([_m4_shift2],
+[m4_if([$#], [2], [],
+       [, m4_shift(m4_shift($@))])])
+m4_define([_m4_shift3],
+[m4_if([$#], [3], [],
+       [, m4_shift(m4_shift(m4_shift($@)))])])
 
 
 # m4_undefine(NAME)
@@ -717,7 +754,9 @@ m4_if($1, [$2], [],
 # Hence the design below.
 #
 # The M4 manual now includes a chapter devoted to this issue, with
-# the lessons learned from m4sugar.
+# the lessons learned from m4sugar.  And still, this design is only
+# optimal for M4 1.6; see foreach.m4 for yet more comments on why
+# M4 1.4.x uses yet another implementation.
 
 
 # m4_foreach(VARIABLE, LIST, EXPRESSION)
@@ -1524,13 +1563,24 @@ m4_define([m4_normalize],
 
 # m4_join(SEP, ARG1, ARG2...)
 # ---------------------------
-# Produce ARG1SEPARG2...SEPARGn.
-m4_defun([m4_join],
-[m4_case([$#],
-        [1], [],
-        [2], [[$2]],
-        [[$2][$1]$0([$1], m4_shiftn(2, $@))])])
-
+# Produce ARG1SEPARG2...SEPARGn.  Avoid back-to-back SEP when a given ARG
+# is the empty string.  No expansion is performed on SEP or ARGs.
+#
+# Since the number of arguments to join can be arbitrarily long, we
+# want to avoid having more than one $@ in the macro definition;
+# otherwise, the expansion would require twice the memory of the already
+# long list.  Hence, m4_join merely looks for the first non-empty element,
+# and outputs just that element; while _m4_join looks for all non-empty
+# elements, and outputs them following a separator.  The final trick to
+# note is that we decide between recursing with $0 or _$0 based on the
+# nested m4_if ending with `_'.
+m4_define([m4_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift2($@))])])
+m4_define([_m4_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift2($@))])])
 
 
 # m4_append(MACRO-NAME, STRING, [SEPARATOR])