m4-commit
[Top][All Lists]
Advanced

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

[SCM] GNU M4 source repository branch, branch-1_4, updated. v1.4.10-26-g


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, branch-1_4, updated. v1.4.10-26-g86f05e7
Date: Wed, 31 Oct 2007 16:00:15 +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=86f05e746830963af686d61d746a68205abeadf8

The branch, branch-1_4 has been updated
       via  86f05e746830963af686d61d746a68205abeadf8 (commit)
      from  08d5b5e080e2ff7e6808cd32956031e03a467095 (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 86f05e746830963af686d61d746a68205abeadf8
Author: Eric Blake <address@hidden>
Date:   Wed Oct 31 08:50:30 2007 -0600

    Test more corner cases.
    
    * doc/m4.texinfo (Changecom, Pseudo Arguments): Beef up tests.
    (Improved foreach): Document alternate foreachq style.
    * examples/foreachq3.m4: New file.
    * examples/loop.m4: New file.
    * examples/Makefile.am (EXTRA_DIST): Distribute them.
    
    Signed-off-by: Eric Blake <address@hidden>

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

Summary of changes:
 ChangeLog             |    9 +++++
 doc/m4.texinfo        |   85 +++++++++++++++++++++++++++++++++++++++++++-----
 examples/Makefile.am  |    2 +
 examples/foreachq3.m4 |   10 ++++++
 examples/loop.m4      |   17 ++++++++++
 5 files changed, 114 insertions(+), 9 deletions(-)
 create mode 100644 examples/foreachq3.m4
 create mode 100644 examples/loop.m4

diff --git a/ChangeLog b/ChangeLog
index 737a6ec..a25c84d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-10-31  Eric Blake  <address@hidden>
+
+       Test more corner cases.
+       * doc/m4.texinfo (Changecom, Pseudo Arguments): Beef up tests.
+       (Improved foreach): Document alternate foreachq style.
+       * examples/foreachq3.m4: New file.
+       * examples/loop.m4: New file.
+       * examples/Makefile.am (EXTRA_DIST): Distribute them.
+
 2007-10-28  Eric Blake  <address@hidden>
 
        More test coverage for autoconf usage patterns.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index d7c8140..42c5438 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -1942,11 +1942,17 @@ foo)
 @comment levels.
 
 @example
-define(`echo', `$@')dnl
+define(`echo', `$@@')dnl
 len((echo(`01234567890123456789',
           `01234567890123456789')echo(`98765432109876543210',
                                       `98765432109876543210')))
 @result{}84
+define(`argn', `$#')dnl
+define(`echo1', `-$@@-')define(`echo2', `,$@@,')dnl
+echo1(`1', `2', `3') argn(echo1(`1', `2', `3'))
address@hidden,2,3- 3
+echo2(`1', `2', `3') argn(echo2(`1', `2', `3'))
address@hidden,1,2,3, 5
 @end example
 @end ignore
 
@@ -3801,26 +3807,32 @@ implementations, it is a good idea to avoid @samp{(}, 
@samp{,}, and
 @samp{)} as the first character in @var{start}.
 
 @example
-define(`echo', `$#:$@@:')
+define(`echo', `$#:$*:$@@:')
 @result{}
 define(`hi', `HI')
 @result{}
 changecom(`(',`)')
 @result{}
 echo(hi)
address@hidden::(hi)
address@hidden:::(hi)
 changecom
 @result{}
 changecom(`((', `))')
 @result{}
 echo(hi)
address@hidden:HI:
address@hidden:HI:HI:
 echo((hi))
address@hidden::((hi))
address@hidden:::((hi))
 changecom(`,', `)')
 @result{}
 echo(hi,hi)bye)
address@hidden:HI,hi)bye:
address@hidden:HI,hi)bye:HI,hi)bye:
+changecom
address@hidden
+echo(hi,`,`'hi',hi)
address@hidden:HI,,HI,HI:HI,,`'hi,HI:
+echo(hi,`,`'hi',hi`'changecom(`,,', `hi'))
address@hidden:HI,,`'hi,HI:HI,,`'hi,HI:
 @end example
 
 It is an error if the end of file occurs within a comment.
@@ -6803,7 +6815,60 @@ Contrast the use of @address@hidden, which quotes the 
first list
 element, with @address@hidden of the earlier implementation that
 returned the first list element directly.
 
-For a different approach, the improved version of @code{foreach},
+The astute m4 programmer might notice that the solution above still uses
+more memory, and thus more time, than strictly necessary.  Note that
address@hidden, which contains an arbitrarily long quoted list, is expanded
+and rescanned three times per iteration of @code{_foreachq}.
+Furthermore, every iteration of the algorithm effectively unboxes then
+reboxes the list, which costs a couple of macro invocations.  It is
+possible to rewrite the algorithm for a bit more speed by swapping the
+order of the arguments to @code{_foreachq} in order to operate on an
+unboxed list in the first place, and by using the fixed-length @samp{$#}
+instead of an arbitrary length list as the key to end recursion.  This
+alternative approach is available as
address@hidden@value{VERSION}/@/examples/@/foreach3.m4}:
+
address@hidden
+$ @kbd{m4 -I examples}
+include(`foreachq3.m4')
address@hidden
+undivert(`foreachq3.m4')dnl
address@hidden(`-1')
address@hidden foreachq(x, `item_1, item_2, ..., item_n', stmt)
address@hidden   quoted list, alternate improved version
address@hidden(`foreachq',
address@hidden(`$1')_$0(`$1', `$3'ifelse(`$2', `', `',
address@hidden  `, $2'))popdef(`$1')')
address@hidden(`_foreachq', `ifelse(`$#', `2', `',
address@hidden  `define(`$1', `$3')$2`'$0(`$1', `$2'ifelse(`$#', `3', `',
address@hidden    `, shift(shift(shift($@@)))'))')')
address@hidden'dnl
+traceon(`shift')debugmode(`aq')
address@hidden
+foreachq(`x', ``1', `2', `3', `4'', `x
+')dnl
address@hidden
address@hidden: -4- shift(`x', `x
address@hidden', `1', `2', `3', `4')
address@hidden: -3- shift(`x
address@hidden', `1', `2', `3', `4')
address@hidden: -2- shift(`1', `2', `3', `4')
address@hidden
address@hidden: -4- shift(`x', `x
address@hidden', `2', `3', `4')
address@hidden: -3- shift(`x
address@hidden', `2', `3', `4')
address@hidden: -2- shift(`2', `3', `4')
address@hidden
address@hidden: -4- shift(`x', `x
address@hidden', `3', `4')
address@hidden: -3- shift(`x
address@hidden', `3', `4')
address@hidden: -2- shift(`3', `4')
address@hidden
address@hidden example
+
+For yet another approach, the improved version of @code{foreach},
 available in @address@hidden/@/examples/@/foreach2.m4}, simply
 overquotes the arguments to @address@hidden to begin with, using
 @code{dquote_elt}.  Then @address@hidden can just use
@@ -6846,9 +6911,11 @@ In summary, recursion over list elements is trickier 
than it appeared at
 first glance, but provides a powerful idiom within @code{m4} processing.
 As a final demonstration, both list styles are now able to handle
 several scenarios that would wreak havoc on the original
-implementations.  This points out one other difference between the two
+implementations.  This points out one other difference between the
 list styles.  @code{foreach} evaluates unquoted list elements only once,
-in preparation for calling @address@hidden  But @code{foreachq}
+in preparation for calling @address@hidden, similary for
address@hidden as provided by @file{foreachq3.m4}.  But
address@hidden, as provided by @file{foreachq2.m4},
 evaluates unquoted list elements twice while visiting the first list
 element, once in @address@hidden and once in @address@hidden  When
 deciding which list style to use, one must take into account whether
diff --git a/examples/Makefile.am b/examples/Makefile.am
index e7672f9..b1ef68a 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -33,6 +33,7 @@ foreach.m4 \
 foreach2.m4 \
 foreachq.m4 \
 foreachq2.m4 \
+foreachq3.m4 \
 forloop.m4 \
 forloop2.m4 \
 fstab.m4 \
@@ -41,6 +42,7 @@ incl-test.m4 \
 incl.m4 \
 include.m4 \
 indir.m4 \
+loop.m4 \
 misc.m4 \
 multiquotes.m4 \
 patsubst.m4 \
diff --git a/examples/foreachq3.m4 b/examples/foreachq3.m4
new file mode 100644
index 0000000..beab455
--- /dev/null
+++ b/examples/foreachq3.m4
@@ -0,0 +1,10 @@
+divert(`-1')
+# foreachq(x, `item_1, item_2, ..., item_n', stmt)
+#   quoted list, alternate improved version
+define(`foreachq',
+`pushdef(`$1')_$0(`$1', `$3'ifelse(`$2', `', `',
+  `, $2'))popdef(`$1')')
+define(`_foreachq', `ifelse(`$#', `2', `',
+  `define(`$1', `$3')$2`'$0(`$1', `$2'ifelse(`$#', `3', `',
+    `, shift(shift(shift($@)))'))')')
+divert`'dnl
diff --git a/examples/loop.m4 b/examples/loop.m4
new file mode 100644
index 0000000..31761c9
--- /dev/null
+++ b/examples/loop.m4
@@ -0,0 +1,17 @@
+dnl Stress test for recursion algorithms.  Usage:
+dnl m4 -Ipath/to/examples [-Doptions] loop.m4
+dnl Options include:
+dnl -Dalt - test with foreachq3 instead of foreachq2
+dnl -Dlimit=<num> - set upper limit of sequence to <num>, default 1000
+dnl -Dverbose - print the sequence to the screen, rather than discarding
+dnl -Ddebug[=<code>] - execute <code> after forloop but before foreach
+dnl -Dsleep=<num> - sleep for <num> seconds before exit, to allow time
+dnl   to examine peak process memory usage
+include(`forloop2.m4')dnl
+include(`quote.m4')dnl
+include(ifdef(`alt', ``foreachq3.m4'', ``foreachq2.m4''))dnl
+ifdef(`limit', `', `define(`limit', `1000')')dnl
+ifdef(`verbose', `', `divert(`-1')')dnl
+ifdef(`debug', `', `define(`debug')')dnl
+foreachq(`i', dquote(1forloop(`i', `2', limit, `,i'))debug, ` i')
+ifdef(`sleep',`syscmd(`echo done>/dev/tty;sleep 'sleep)')dnl


hooks/post-receive
--
GNU M4 source repository




reply via email to

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