From: Eric Blake Date: 2008年2月16日 21:39:41 +0000 (-0700) Subject: Add regression test for multi-character quote recursion. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=06991b51ef43dcbafa3d878b2beefd1dcc00adc0;p=m4.git 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 --- diff --git a/ChangeLog b/ChangeLog index d0ba987d..6a89c565 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2008年02月16日 Eric Blake + 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 c3139842..571c0dc7 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -8256,7 +8256,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', -@result{} `pushdef(`1ドル', eval(`2ドル'))_forloop(`1ドル', +@result{} `pushdef(`1ドル', eval(`2ドル'))_0ドル(`1ドル', @result{} eval(`3ドル'), `4ドル')popdef(`1ドル')')') @result{}define(`_forloop', @result{} `3ドル`'ifelse(indir(`1ドル'), `2ドル', `', @@ -8275,6 +8275,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 +@samp{_foreach}, 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. + +@comment options: -L9 +@comment status: 1 +@comment examples +@example +$ @kbd{m4 -d -L 9 -I examples} +define(`arg1', `1ドル')include(`forloop2.m4')include(`quote.m4') +@result{} +define(`double', `define(`1ドル'`2', + arg1(patsubst(dquote(defn(`1ドル')), `[`']', `\&\&')))') +@result{} +double(`forloop')double(`_forloop')defn(`forloop2') +@result{}ifelse(eval(``(3ドル)>= (2ドル)''), ``1'', +@result{} ``pushdef(``1ドル'', eval(``2ドル''))_0ドル(``1ドル'', +@result{} eval(``3ドル''), ``4ドル'')popdef(``1ドル'')'') +forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)') +@result{} +changequote(`[', `]')changequote([``], ['']) +@result{} +forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'') +@result{} +changequote`'include(`forloop.m4') +@result{} +double(`forloop')double(`_forloop')defn(`forloop2') +@result{}pushdef(``1ドル'', ``2ドル'')_forloop($@@)popdef(``1ドル'') +forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)') +@result{} +changequote(`[', `]')changequote([``], ['']) +@result{} +forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'') +@error{}m4:stdin:12: recursion limit of 9 exceeded, use -L to change it +@end 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 @@ -8339,7 +8381,7 @@ undivert(`foreachq2.m4')dnl @result{}divert(`-1') @result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt) @result{}# quoted list, improved version -@result{}define(`foreachq', `pushdef(`1ドル')_foreachq($@@)popdef(`1ドル')') +@result{}define(`foreachq', `pushdef(`1ドル')_0ドル($@@)popdef(`1ドル')') @result{}define(`_arg1q', ``1ドル'') @result{}define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@@))')') @result{}define(`_foreachq', `ifelse(`2ドル', `', `', @@ -8436,7 +8478,7 @@ undivert(`foreach2.m4')dnl @result{}divert(`-1') @result{}# foreach(x, (item_1, item_2, ..., item_n), stmt) @result{}# parenthesized list, improved version -@result{}define(`foreach', `pushdef(`1ドル')_foreach(`1ドル', +@result{}define(`foreach', `pushdef(`1ドル')_0ドル(`1ドル', @result{} (dquote(dquote_elt2ドル)), `3ドル')popdef(`1ドル')') @result{}define(`_arg1', `1ドル') @result{}define(`_foreach', `ifelse(`2ドル', `(`')', `', diff --git a/examples/foreach2.m4 b/examples/foreach2.m4 index 4acf0c26..74d00fb6 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_elt2ドル)), `3ドル')popdef(`1ドル')') define(`_arg1', `1ドル') define(`_foreach', `ifelse(`2ドル', `(`')', `', diff --git a/examples/foreachq2.m4 b/examples/foreachq2.m4 index 345ddfed..f57d3edf 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 f1bdf0ef..41e0e165 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 c4a7c147..32fd8a41 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 a79dbcdd..92ce9816 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

AltStyle によって変換されたページ (->オリジナル) /