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=92f059a8d7e6e6f96e791fcc14d6dcbdba7b3b9c The branch, branch-1.6 has been updated via 92f059a8d7e6e6f96e791fcc14d6dcbdba7b3b9c (commit) from 5559d1ca4d1f516c2b7fb44ee92cb8f6bac94402 (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 92f059a8d7e6e6f96e791fcc14d6dcbdba7b3b9c Author: Eric Blake <[email protected]> Date: Thu Dec 18 10:28:06 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. * examples/Makefile.am (EXTRA_DIST): Distribute it. Signed-off-by: Eric Blake <[email protected]> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 10 ++++ doc/m4.texinfo | 113 +++++++++++++++++++++++++++++++++++++++++++++++- examples/Makefile.am | 1 + 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 63a0516..895d17a 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. + * examples/Makefile.am (EXTRA_DIST): Distribute it. + 2008-12-10 Eric Blake <[email protected]> Double size of temp file cache. diff --git a/doc/m4.texinfo b/doc/m4.texinfo index 7c6bf56..50d0ace 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -272,6 +272,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} @@ -3742,13 +3743,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', @@ -3885,6 +3886,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 @@ -3900,7 +3918,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 @@ -8101,6 +8122,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} @@ -8709,6 +8731,91 @@ include(`loop.m4')dnl @end ignore +...@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/Makefile.am b/examples/Makefile.am index 1a97347..0db3a88 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -58,6 +58,7 @@ quote.m4 \ regexp.m4 \ reverse.m4 \ stack.m4 \ +stack_sep.m4 \ stackovf.sh \ sync-lines.m4 \ sysv-args.m4 \ 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
