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 M4 source repository".

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

The branch, master has been updated
       via  dac0f533e2fdd06e0ff5948b6f03042fea3d9402 (commit)
      from  64df649442038cace6b063fa5bd36c7007193dcc (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 dac0f533e2fdd06e0ff5948b6f03042fea3d9402
Author: Eric Blake <[email protected]>
Date:   Thu Dec 18 11:02:39 2008 -0700

    Deal with M4 1.4.x limitation on builtin tokens.
    
    * doc/m4.texinfo (Composition): Mention limitation on curry.
    (Improved copy): New node.
    (Stacks): Fix typo.
    * examples/stack.m4: Likewise.
    * examples/stack_sep.m4: New file.
    * Makefile.am (dist_pkgdata_DATA): Distribute it.
    
    Signed-off-by: Eric Blake <[email protected]>
    (cherry picked from commit 92f059a8d7e6e6f96e791fcc14d6dcbdba7b3b9c)

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

Summary of changes:
 ChangeLog             |   10 ++++
 Makefile.am           |    1 +
 doc/m4.texinfo        |  113 +++++++++++++++++++++++++++++++++++++++++++++++-
 examples/stack.m4     |    4 +-
 examples/stack_sep.m4 |   17 +++++++
 5 files changed, 140 insertions(+), 5 deletions(-)
 create mode 100644 examples/stack_sep.m4

diff --git a/ChangeLog b/ChangeLog
index a73ba6e..917c239 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-12-18  Eric Blake  <[email protected]>
+
+       Deal with M4 1.4.x limitation on builtin tokens.
+       * doc/m4.texinfo (Composition): Mention limitation on curry.
+       (Improved copy): New node.
+       (Stacks): Fix typo.
+       * examples/stack.m4: Likewise.
+       * examples/stack_sep.m4: New file.
+       * Makefile.am (dist_pkgdata_DATA): Distribute it.
+
 2008-12-15  Eric Blake  <[email protected]>
 
        Double size of temp file cache.
diff --git a/Makefile.am b/Makefile.am
index 1b9130d..683a84e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -343,6 +343,7 @@ dist_pkgdata_DATA = \
                  examples/regexp.m4 \
                  examples/reverse.m4 \
                  examples/stack.m4 \
+                 examples/stack_sep.m4 \
                  examples/sysv-args.m4 \
                  examples/trace.m4 \
                  examples/translit.m4 \
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 173921c..3b78bc7 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -291,6 +291,7 @@ Correct version of some examples
 * Improved exch::               Solution for @code{exch}
 * Improved forloop::            Solution for @code{forloop}
 * Improved foreach::            Solution for @code{foreach}
+* Improved copy::               Solution for @code{copy}
 * Improved m4wrap::             Solution for @code{m4wrap}
 * Improved cleardivert::        Solution for @code{cleardivert}
 * Improved capitalize::         Solution for @code{capitalize}
@@ -3839,13 +3840,13 @@ undefined during the algorithm.
 $ @kbd{m4 -I examples}
 undivert(`stack.m4')dnl
 @result{}divert(`-1')
-...@result{}# stack_foreach(action, macro)
+...@result{}# stack_foreach(macro, action)
 @result{}# Invoke ACTION with a single argument of each definition
 @result{}# from the definition stack of MACRO, starting with the oldest.
 @result{}define(`stack_foreach',
 @result{}`_stack_reverse(`$1', `tmp-$1')'dnl
 @result{}`_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
-...@result{}# stack_foreach_lifo(action, macro)
+...@result{}# stack_foreach_lifo(macro, action)
 @result{}# Invoke ACTION with a single argument of each definition
 @result{}# from the definition stack of MACRO, starting with the newest.
 @result{}define(`stack_foreach_lifo',
@@ -3982,6 +3983,23 @@ undivert(`curry.m4')dnl
 @result{}divert`'dnl
 @end example
 
+Unfortunately, with M4 1.4.x, @code{curry} is unable to handle builtin
+tokens, which are silently flattened to the empty string when passed
+through another text macro.  The following example demonstrates a usage
+of @code{curry} that works in M4 1.6, but is not portable to earlier
+versions:
+
+...@comment examples
+...@example
+$ @kbd{m4 -I examples}
+include(`curry.m4')
+...@result{}
+curry(`define', `mylen')(defn(`len'))
+...@result{}
+mylen(`abc')
+...@result{}3
+...@end example
+
 @cindex renaming macros
 @cindex copying macros
 @cindex macros, copying
@@ -3997,7 +4015,10 @@ few macros, such as @code{copy} or @code{defn}, which 
cannot be copied
 via this macro.
 @end deffn
 
-The implementation is relatively straightforward:
+The implementation is relatively straightforward (although since it uses
+...@code{curry}, it is unable to copy builtin macros when used with M4
+1.4.x.  See if you can design a portable version that works across all
+M4 versions, or @pxref{Improved copy, , Answers}).
 
 @comment examples
 @example
@@ -9191,6 +9212,7 @@ presented here.
 * Improved exch::               Solution for @code{exch}
 * Improved forloop::            Solution for @code{forloop}
 * Improved foreach::            Solution for @code{foreach}
+* Improved copy::               Solution for @code{copy}
 * Improved m4wrap::             Solution for @code{m4wrap}
 * Improved cleardivert::        Solution for @code{cleardivert}
 * Improved capitalize::         Solution for @code{capitalize}
@@ -9744,6 +9766,91 @@ foreachq(`x', ```active'', ``active''', `<x>
 @result{}<active>
 @end example
 
+...@node Improved copy
+...@section Solution for @code{copy}
+
+The macro @code{copy} presented above works with M4 1.6 and newer, but
+is unable to handle builtin tokens with M4 1.4.x, because it tries to
+pass the builtin token through the macro @code{curry}, where it is
+silently flattened to an empty string (@pxref{Composition}).  Rather
+than using the problematic @code{curry} to work around the limitation
+that @code{stack_foreach} expects to invoke a macro that takes exactly
+one argument, we can write a new macro that lets us form the exact
+two-argument @code{pushdef} call sequence needed, so that we are no
+longer passing a builtin token through a text macro.
+
+...@deffn Composite stack_foreach_sep (@var{macro}, @var{pre}, @var{post}, @
+  @var{sep})
+...@deffnx Composite stack_foreach_sep_lifo (@var{macro}, @var{pre}, @
+  @var{post}, @var{sep})
+For each of the @code{pushdef} definitions associated with @var{macro},
+expand the sequence @sa...@var{pre}`'definition`'@var{post}}.
+Additionally, expand @var{sep} between definitions.
+...@code{stack_foreach_sep} visits the oldest definition first, while
+...@code{stack_foreach_sep_lifo} visits the current definition first.  The
+expansion may dereference @var{macro}, but should not modify it.  There
+are a few special macros, such as @code{defn}, which cannot be used as
+the @var{macro} parameter.
+...@end deffn
+
+Note that @code{stack_foreach(`...@var{macro}', `...@var{action}')} is
+equivalent to @code{stack_foreach_sep(`...@var{macro}', `...@var{action}(',
+`)')}.  By supplying explicit parentheses, split among the @var{pre} and
+...@var{post} arguments to @code{stack_foreach_sep}, it is now possible to
+construct macro calls with more than one argument, without passing
+builtin tokens through a macro call.  It is likewise possible to
+directly reference the stack definitions without a macro call, by
+leaving @var{pre} and @var{post} empty.  The new macro also adds a
+separator that is only output after the first iteration of the helper
+...@var{_stack_reverse_sep}, implemented by prepending the original
+...@var{sep} to @var{pre} and omitting a @var{sep} argument in subsequent
+iterations.  As an added bonus, using @code{stack_foreach_sep} to
+implement @code{copy} performs fewer macro invocations.  The improved
+stack walking macros are available in
+...@file{m4-@value{VERSION}/@/examples/@/stack_sep.m4}:
+
+...@comment examples
+...@example
+$ @kbd{m4 -I examples}
+include(`stack_sep.m4')
+...@result{}
+define(`copy', `ifdef(`$2', `errprint(`$2 already defined
+')m4exit(`1')',
+   `stack_foreach_sep(`$1', `pushdef(`$2',', `)')')')dnl
+pushdef(`a', `1')pushdef(`a', defn(`divnum'))
+...@result{}
+copy(`a', `b')
+...@result{}
+b
+...@result{}0
+popdef(`b')
+...@result{}
+b
+...@result{}1
+pushdef(`c', `1')pushdef(`c', `2')
+...@result{}
+stack_foreach_sep_lifo(`c', `', `', `, ')
+...@result{}2, 1
+undivert(`stack_sep.m4')dnl
+...@result{}divert(`-1')
+...@result{}# stack_foreach_sep(macro, pre, post, sep)
+...@result{}# Invoke PRE`'defn`'POST with a single argument of each definition
+...@result{}# from the definition stack of MACRO, starting with the oldest, and
+...@result{}# separated by SEP between definitions.
+...@result{}define(`stack_foreach_sep',
+...@result{}`_stack_reverse_sep(`$1', `tmp-$1')'dnl
+...@result{}`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
+...@result{}# stack_foreach_sep_lifo(macro, pre, post, sep)
+...@result{}# Like stack_foreach_sep, but starting with the newest definition.
+...@result{}define(`stack_foreach_sep_lifo',
+...@result{}`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
+...@result{}`_stack_reverse_sep(`tmp-$1', `$1')')
+...@result{}define(`_stack_reverse_sep',
+...@result{}`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
+...@result{}  `$1', `$2', `$4`'$3')')')
+...@result{}divert`'dnl
+...@end example
+
 @node Improved m4wrap
 @section Solution for @code{m4wrap}
 
diff --git a/examples/stack.m4 b/examples/stack.m4
index ae3c48e..c1b9833 100644
--- a/examples/stack.m4
+++ b/examples/stack.m4
@@ -1,11 +1,11 @@
 divert(`-1')
-# stack_foreach(action, macro)
+# stack_foreach(macro, action)
 # Invoke ACTION with a single argument of each definition
 # from the definition stack of MACRO, starting with the oldest.
 define(`stack_foreach',
 `_stack_reverse(`$1', `tmp-$1')'dnl
 `_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
-# stack_foreach_lifo(action, macro)
+# stack_foreach_lifo(macro, action)
 # Invoke ACTION with a single argument of each definition
 # from the definition stack of MACRO, starting with the newest.
 define(`stack_foreach_lifo',
diff --git a/examples/stack_sep.m4 b/examples/stack_sep.m4
new file mode 100644
index 0000000..b11bc83
--- /dev/null
+++ b/examples/stack_sep.m4
@@ -0,0 +1,17 @@
+divert(`-1')
+# stack_foreach_sep(macro, pre, post, sep)
+# Invoke PRE`'defn`'POST with a single argument of each definition
+# from the definition stack of MACRO, starting with the oldest, and
+# separated by SEP between definitions.
+define(`stack_foreach_sep',
+`_stack_reverse_sep(`$1', `tmp-$1')'dnl
+`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
+# stack_foreach_sep_lifo(macro, pre, post, sep)
+# Like stack_foreach_sep, but starting with the newest definition.
+define(`stack_foreach_sep_lifo',
+`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
+`_stack_reverse_sep(`tmp-$1', `$1')')
+define(`_stack_reverse_sep',
+`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
+  `$1', `$2', `$4`'$3')')')
+divert`'dnl


hooks/post-receive
--
GNU M4 source repository


Reply via email to