[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [SCM] GNU M4 source repository branch, master, updated. 8cf99d7ccdace1cddb3db6a127634afc6dcf06b5,
Eric Blake <=