m4-patches
[Top][All Lists]
Advanced

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

another regression test


From: Eric Blake
Subject: another regression test
Date: Sat, 16 Feb 2008 15:27:58 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071031 Thunderbird/2.0.0.9 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

While working on porting stage 16 to head, I noticed that I wasn't really
exercising recursive code with multi-character quoting.  Ultimately, the
speedup for linear speed on recursion only applies to single-character
quoting (because with multi-character quoting, the parser can't bypass
checking arguments, in case characters are concatenated together to form a
quote delimiter), but I at least wanted to ensure it doesn't break with
all the optimizations being added for single-character quotes.  And in the
process of adding that test, I had a hard time using the
examples/forloop2.m4 file as is once I translated it to use different
quoting, so I adjusted the example and added some documentation why.  This
patch applies to both the branch and head.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHt2Nt84KuGfSFAYARAsYPAKDAzuba1VfMq9gwyIB3Yllft0A+mQCeLagz
rkGq4h8kfnJ79IPgS9Mu3DA=
=NKMJ
-----END PGP SIGNATURE-----
>From 702a3fe3e8a61c0d4c6da09221559deeff43fabb Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Sat, 16 Feb 2008 14:39:41 -0700
Subject: [PATCH] Add regression test for multi-character quote recursion.

* examples/foreach2.m4: Use $0 rather than spelling out name.
* examples/foreachq2.m4: Likewise.
* examples/forloop2.m4: Likewise.
* examples/hanoi.m4: Likewise.
* examples/trace.m4: Likewise.
* doc/m4.texinfo (Improved forloop): Document advantage of $0.
(Improved foreach): Adjust dump from file.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog             |    9 +++++++++
 doc/m4.texinfo        |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 examples/foreach2.m4  |    2 +-
 examples/foreachq2.m4 |    2 +-
 examples/forloop2.m4  |    2 +-
 examples/hanoi.m4     |    4 ++--
 examples/trace.m4     |    4 ++--
 7 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0baa3c1..76fcac3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2008-02-16  Eric Blake  <address@hidden>
 
+       Add regression test for multi-character quote recursion.
+       * examples/foreach2.m4: Use $0 rather than spelling out name.
+       * examples/foreachq2.m4: Likewise.
+       * examples/forloop2.m4: Likewise.
+       * examples/hanoi.m4: Likewise.
+       * examples/trace.m4: Likewise.
+       * doc/m4.texinfo (Improved forloop): Document advantage of $0.
+       (Improved foreach): Adjust dump from file.
+
        Stage 15: return argv refs back to collect_arguments.
        Collect an entire $@ reference at once rather than one argument at
        a time, outside of quotes (but inside quotes, $@ is still
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 32cb0a9..6172277 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -6987,7 +6987,7 @@ undivert(`forloop2.m4')dnl
 @result{}#   performs sanity check that FROM is larger than TO
 @result{}#   allows complex numerical expressions in TO and FROM
 @result{}define(`forloop', `ifelse(eval(`($3) >= ($2)'), `1',
address@hidden  `pushdef(`$1', eval(`$2'))_forloop(`$1',
address@hidden  `pushdef(`$1', eval(`$2'))_$0(`$1',
 @result{}    eval(`$3'), `$4')popdef(`$1')')')
 @result{}define(`_forloop',
 @result{}  `$3`'ifelse(indir(`$1'), `$2', `',
@@ -7006,6 +7006,48 @@ forloop(`i', `a', `b', `non-numeric bounds')
 @result{}
 @end example
 
+One other change to notice is that the improved version used @samp{_$0}
+rather than @samp{_foreach} to invoke the helper routine.  In general,
+this is a good practice to follow, because then the set of macros can be
+uniformly transformed.  The following example shows a transformation
+that doubles the current quoting and appends a suffix @samp{2} to each
+transformed macro.  If @code{foreach} refers to the literal
address@hidden, then @code{foreach2} invokes @code{_foreach} instead of
+the intended @code{_foreach2}, and the mixing of quoting paradigms leads
+to an infinite recursion loop in this example.
+
address@hidden options: -L9
address@hidden status: 1
address@hidden examples
address@hidden
+$ @kbd{m4 -d -L 9 -I examples}
+define(`arg1', `$1')include(`forloop2.m4')include(`quote.m4')
address@hidden
+define(`double', `define(`$1'`2',
+  arg1(patsubst(dquote(defn(`$1')), `[`']', `\&\&')))')
address@hidden
+double(`forloop')double(`_forloop')defn(`forloop2')
address@hidden(eval(``($3) >= ($2)''), ``1'',
address@hidden  ``pushdef(``$1'', eval(``$2''))_$0(``$1'',
address@hidden    eval(``$3''), ``$4'')popdef(``$1'')'')
+forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
address@hidden
+changequote(`[', `]')changequote([``], [''])
address@hidden
+forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
address@hidden
+changequote`'include(`forloop.m4')
address@hidden
+double(`forloop')double(`_forloop')defn(`forloop2')
address@hidden(``$1'', ``$2'')_forloop($@@)popdef(``$1'')
+forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
address@hidden
+changequote(`[', `]')changequote([``], [''])
address@hidden
+forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
address@hidden:stdin:12: recursion limit of 9 exceeded, use -L<N> to change it
address@hidden example
+
 Of course, it is possible to make even more improvements, such as
 adding an optional step argument, or allowing iteration through
 descending sequences.  @acronym{GNU} Autoconf provides some of these
@@ -7068,7 +7110,7 @@ undivert(`foreachq2.m4')dnl
 @result{}divert(`-1')
 @result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
 @result{}#   quoted list, improved version
address@hidden(`foreachq', `pushdef(`$1')_foreachq($@@)popdef(`$1')')
address@hidden(`foreachq', `pushdef(`$1')_$0($@@)popdef(`$1')')
 @result{}define(`_arg1q', ``$1'')
 @result{}define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@@))')')
 @result{}define(`_foreachq', `ifelse(`$2', `', `',
@@ -7163,7 +7205,7 @@ undivert(`foreach2.m4')dnl
 @result{}divert(`-1')
 @result{}# foreach(x, (item_1, item_2, ..., item_n), stmt)
 @result{}#   parenthesized list, improved version
address@hidden(`foreach', `pushdef(`$1')_foreach(`$1',
address@hidden(`foreach', `pushdef(`$1')_$0(`$1',
 @result{}  (dquote(dquote_elt$2)), `$3')popdef(`$1')')
 @result{}define(`_arg1', `$1')
 @result{}define(`_foreach', `ifelse(`$2', `(`')', `',
diff --git a/examples/foreach2.m4 b/examples/foreach2.m4
index 4acf0c2..74d00fb 100644
--- a/examples/foreach2.m4
+++ b/examples/foreach2.m4
@@ -2,7 +2,7 @@ include(`quote.m4')dnl
 divert(`-1')
 # foreach(x, (item_1, item_2, ..., item_n), stmt)
 #   parenthesized list, improved version
-define(`foreach', `pushdef(`$1')_foreach(`$1',
+define(`foreach', `pushdef(`$1')_$0(`$1',
   (dquote(dquote_elt$2)), `$3')popdef(`$1')')
 define(`_arg1', `$1')
 define(`_foreach', `ifelse(`$2', `(`')', `',
diff --git a/examples/foreachq2.m4 b/examples/foreachq2.m4
index 345ddfe..f57d3ed 100644
--- a/examples/foreachq2.m4
+++ b/examples/foreachq2.m4
@@ -2,7 +2,7 @@ include(`quote.m4')dnl
 divert(`-1')
 # foreachq(x, `item_1, item_2, ..., item_n', stmt)
 #   quoted list, improved version
-define(`foreachq', `pushdef(`$1')_foreachq($@)popdef(`$1')')
+define(`foreachq', `pushdef(`$1')_$0($@)popdef(`$1')')
 define(`_arg1q', ``$1'')
 define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@))')')
 define(`_foreachq', `ifelse(`$2', `', `',
diff --git a/examples/forloop2.m4 b/examples/forloop2.m4
index f1bdf0e..41e0e16 100644
--- a/examples/forloop2.m4
+++ b/examples/forloop2.m4
@@ -4,7 +4,7 @@ divert(`-1')
 #   performs sanity check that FROM is larger than TO
 #   allows complex numerical expressions in TO and FROM
 define(`forloop', `ifelse(eval(`($3) >= ($2)'), `1',
-  `pushdef(`$1', eval(`$2'))_forloop(`$1',
+  `pushdef(`$1', eval(`$2'))_$0(`$1',
     eval(`$3'), `$4')popdef(`$1')')')
 define(`_forloop',
   `$3`'ifelse(indir(`$1'), `$2', `',
diff --git a/examples/hanoi.m4 b/examples/hanoi.m4
index c4a80fc..d290866 100644
--- a/examples/hanoi.m4
+++ b/examples/hanoi.m4
@@ -6,10 +6,10 @@ define(`move', `Move one disk from `$1' to `$2'.
 
 # _hanoi (cnt, from, to, aux)
 define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
+`$0(decr($1), $2, $4, $3)move($2, $3)$0(decr($1), $4, $3, $2)')')
 
 # hanoi (cnt)
-define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
+define(`hanoi', `_$0(`$1', source, destination, auxilliary)')
 
 # traceon(`move', `_hanoi', `decr')
 divert`'dnl
diff --git a/examples/trace.m4 b/examples/trace.m4
index a79dbcd..92ce981 100644
--- a/examples/trace.m4
+++ b/examples/trace.m4
@@ -6,10 +6,10 @@ define(`move', `Move one disk from `$1' to `$2'.
 
 # _hanoi (cnt, from, to, aux)
 define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
+`$0(decr($1), $2, $4, $3)move($2, $3)$0(decr($1), $4, $3, $2)')')
 
 # hanoi (cnt)
-define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
+define(`hanoi', `_$0(`$1', source, destination, auxilliary)')
 divert`'dnl
 
 # Debugmode t
-- 
1.5.4


reply via email to

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