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. 8cf99d7ccdace1cd


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, master, updated. 8cf99d7ccdace1cddb3db6a127634afc6dcf06b5
Date: Wed, 31 Oct 2007 16:00:23 +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=8cf99d7ccdace1cddb3db6a127634afc6dcf06b5

The branch, master has been updated
       via  8cf99d7ccdace1cddb3db6a127634afc6dcf06b5 (commit)
      from  91b8f5afc665a8ba0cc2b0f06f371d4ae475809a (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 8cf99d7ccdace1cddb3db6a127634afc6dcf06b5
Author: Eric Blake <address@hidden>
Date:   Wed Oct 31 08:50:30 2007 -0600

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

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

Summary of changes:
 ChangeLog             |   10 ++++++
 Makefile.am           |    2 +
 doc/m4.texinfo        |   78 ++++++++++++++++++++++++++++++++++++++++++++-----
 examples/foreachq3.m4 |   10 ++++++
 examples/loop.m4      |   17 ++++++++++
 tests/macros.at       |    6 ++++
 6 files changed, 115 insertions(+), 8 deletions(-)
 create mode 100644 examples/foreachq3.m4
 create mode 100644 examples/loop.m4

diff --git a/ChangeLog b/ChangeLog
index a78c048..f953db2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2007-10-31  Eric Blake  <address@hidden>
+
+       Test more corner cases.
+       * tests/macros.at (Rescanning macros): Beef up test.
+       * doc/m4.texinfo (Changecom): Beef up test.
+       (Improved foreach): Document alternate foreachq style.
+       * examples/foreachq3.m4: New file.
+       * examples/loop.m4: New file.
+       * Makefile.am (dist_pkgdata_DATA): Distribute them.
+
 2007-10-28  Eric Blake  <address@hidden>
 
        More test coverage for autoconf usage patterns.
diff --git a/Makefile.am b/Makefile.am
index 22917a4..d9f107f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -324,6 +324,7 @@ dist_pkgdata_DATA = \
                  examples/foreach2.m4 \
                  examples/foreachq.m4 \
                  examples/foreachq2.m4 \
+                 examples/foreachq3.m4 \
                  examples/forloop.m4 \
                  examples/forloop2.m4 \
                  examples/fstab.m4 \
@@ -332,6 +333,7 @@ dist_pkgdata_DATA = \
                  examples/incl.m4 \
                  examples/include.m4 \
                  examples/indir.m4 \
+                 examples/loop.m4 \
                  examples/misc.m4 \
                  examples/multiquotes.m4 \
                  examples/patsubst.m4 \
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 54884a3..4014344 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -4315,26 +4315,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.
@@ -8210,7 +8216,61 @@ 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 examples
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
@@ -8254,9 +8314,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/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
diff --git a/tests/macros.at b/tests/macros.at
index 3596baf..4c57bd0 100644
--- a/tests/macros.at
+++ b/tests/macros.at
@@ -538,9 +538,15 @@ AT_DATA([in], [[define(`echo', `$@')dnl
 len((echo(`01234567890123456789',
           `01234567890123456789')echo(`98765432109876543210',
                                       `98765432109876543210')))
+define(`argn', `$#')dnl
+define(`echo1', address@hidden')define(`echo2', `,$@,')dnl
+echo1(`1', `2', `3') argn(echo1(`1', `2', `3'))
+echo2(`1', `2', `3') argn(echo2(`1', `2', `3'))
 ]])
 
 AT_CHECK_M4([in], [0], [[84
+-1,2,3- 3
+,1,2,3, 5
 ]])
 
 AT_CLEANUP


hooks/post-receive
--
GNU M4 source repository




reply via email to

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