m4-commit
[Top][All Lists]
Advanced

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

[SCM] GNU M4 source repository branch, master, updated. cvs-readonly-177


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, master, updated. cvs-readonly-177-gdac0f53
Date: Thu, 18 Dec 2008 18:16:39 +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 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 <address@hidden>
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 <address@hidden>
    (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  <address@hidden>
+
+       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  <address@hidden>
 
        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')
address@hidden stack_foreach(action, macro)
address@hidden 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'))')')
address@hidden stack_foreach_lifo(action, macro)
address@hidden 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:
+
address@hidden examples
address@hidden
+$ @kbd{m4 -I examples}
+include(`curry.m4')
address@hidden
+curry(`define', `mylen')(defn(`len'))
address@hidden
+mylen(`abc')
address@hidden
address@hidden 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
address@hidden, 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
 
address@hidden Improved copy
address@hidden 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.
+
address@hidden Composite stack_foreach_sep (@var{macro}, @var{pre}, @var{post}, 
@
+  @var{sep})
address@hidden 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 @address@hidden'definition`'@var{post}}.
+Additionally, expand @var{sep} between definitions.
address@hidden visits the oldest definition first, while
address@hidden 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.
address@hidden deffn
+
+Note that @code{stack_foreach(address@hidden', address@hidden')} is
+equivalent to @code{stack_foreach_sep(address@hidden', address@hidden(',
+`)')}.  By supplying explicit parentheses, split among the @var{pre} and
address@hidden 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
address@hidden, implemented by prepending the original
address@hidden 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
address@hidden@value{VERSION}/@/examples/@/stack_sep.m4}:
+
address@hidden examples
address@hidden
+$ @kbd{m4 -I examples}
+include(`stack_sep.m4')
address@hidden
+define(`copy', `ifdef(`$2', `errprint(`$2 already defined
+')m4exit(`1')',
+   `stack_foreach_sep(`$1', `pushdef(`$2',', `)')')')dnl
+pushdef(`a', `1')pushdef(`a', defn(`divnum'))
address@hidden
+copy(`a', `b')
address@hidden
+b
address@hidden
+popdef(`b')
address@hidden
+b
address@hidden
+pushdef(`c', `1')pushdef(`c', `2')
address@hidden
+stack_foreach_sep_lifo(`c', `', `', `, ')
address@hidden, 1
+undivert(`stack_sep.m4')dnl
address@hidden(`-1')
address@hidden stack_foreach_sep(macro, pre, post, sep)
address@hidden Invoke PRE`'defn`'POST with a single argument of each definition
address@hidden from the definition stack of MACRO, starting with the oldest, and
address@hidden separated by SEP between definitions.
address@hidden(`stack_foreach_sep',
address@hidden(`$1', `tmp-$1')'dnl
address@hidden(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4')')
address@hidden stack_foreach_sep_lifo(macro, pre, post, sep)
address@hidden Like stack_foreach_sep, but starting with the newest definition.
address@hidden(`stack_foreach_sep_lifo',
address@hidden(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4')'dnl
address@hidden(`tmp-$1', `$1')')
address@hidden(`_stack_reverse_sep',
address@hidden(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
address@hidden  `$1', `$2', `$4`'$3')')')
address@hidden'dnl
address@hidden 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

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