more testsuite coverage for autoconf idioms
Eric Blake <[email protected]>
| Newsgroups | gmane.comp.gnu.m4.patches |
|---|---|
| Message-ID | <[email protected]> |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I have been working away on a series of patches to speed up recursive macro handling (with a goal to make $@ handling linear instead of quadratic). That series is not ready yet, but in the process, I reached a point where a series of incremental patches all would pass the m4 testsuite, but the final build failed miserably when trying to use it with autoconf. So I'm enhancing the m4 testsuite to trigger these cases, making it easier to pinpoint where the regressions were added in my patch series. For the branch, the testsuite is contained entirely within the m4.texinfo, hence adding some tests within @ignore blocks. But for head, I will move those tests to a more appropriate tests/*.at file. - -- Don't work too hard, make some time for fun as well! Eric Blake [email protected] -----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 iD8DBQFHJSe184KuGfSFAYARAl4kAKDVk3v9ECmSA5ZRJPbW3E80SIOA6gCguqAM 0yJpFVCyxBsjTLxB1jVqRSY= =e4Jx -----END PGP SIGNATURE----- _______________________________________________ M4-patches mailing list [email protected] http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch289
(text/plain, 6.3 KB)
From 08d5b5e080e2ff7e6808cd32956031e03a467095 Mon Sep 17 00:00:00 2001 From: Eric Blake <[email protected]> Date: Sun, 28 Oct 2007 16:51:28 -0600 Subject: [PATCH] More test coverage for autoconf usage patterns. * doc/m4.texinfo (Inhibiting Invocation, Pseudo Arguments) (Builtin): Add new undocumented tests. (Shift): Document cond macro, and add new test. Signed-off-by: Eric Blake <[email protected]> --- ChangeLog | 7 ++++ doc/m4.texinfo | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 992ae22..737a6ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-10-28 Eric Blake <[email protected]> + + More test coverage for autoconf usage patterns. + * doc/m4.texinfo (Inhibiting Invocation, Pseudo Arguments) + (Builtin): Add new undocumented tests. + (Shift): Document cond macro, and add new test. + 2007-10-27 Eric Blake <[email protected]> Document one use of changequote(`(',`)'). diff --git a/doc/m4.texinfo b/doc/m4.texinfo index 677c859..d7c8140 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -1346,18 +1346,31 @@ empty string. @cindex rescanning The output of macro evaluations is always rescanned. The following -example would yield the string @samp{de}, exactly as if @code{m4} -has been given @w{@samp{substr(`abcde', `3', `2')}} as input: +example would yield the string @samp{bcd}, exactly as if @code{m4} +has been given @w{@samp{substr(`abcde', `1', `3')}} as input: @example define(`x', `substr(ab') @result{} -define(`y', `cde, `3', `2')') +define(`y', `cde, `1', `3')') @result{} x`'y -@result{}de +@result{}bcd @end example +@ignore +@comment Similar, but with argument references, to ensure good test +@comment coverage. +@example +define(`x1', `len(`$1'') +@result{} +define(`y1', ``$1')') +@result{} +x1(`01234567890123456789')y1(`98765432109876543210') +@result{}40 +@end example +@end ignore + Unquoted strings on either side of a quoted string are subject to being recognized as macro names. In the following example, quoting the empty string allows for the second @code{macro} to be recognized as such: @@ -1923,6 +1936,20 @@ foo) @result{}bar' @end example +@ignore +@comment Not worth putting in the manual, but this example is needed for +@comment good test coverage of copying large strings across recursion +@comment levels. + +@example +define(`echo', `$@')dnl +len((echo(`01234567890123456789', + `01234567890123456789')echo(`98765432109876543210', + `98765432109876543210'))) +@result{}84 +@end example +@end ignore + A @samp{$} sign in the expansion text, that is not followed by anything @code{m4} understands, is simply copied to the macro expansion, as any other text is. @@ -2416,6 +2443,17 @@ builtin(`builtin',) @result{} @end example +@ignore +@comment This example is not worth putting in the manual, but it is +@comment needed for full coverage. Autoconf's m4_include relies heavily +@comment on this feature. + +@example +builtin(`include', `foo')dnl +@result{}bar +@end example +@end ignore + @node Conditionals @chapter Conditionals, loops, and recursion @@ -2475,7 +2513,7 @@ as a multibranch, depending on the number of arguments supplied: @deffnx Builtin ifelse (@var{string-1}, @var{string-2}, @var{equal}, @ @ovar{not-equal}) @deffnx Builtin ifelse (@var{string-1}, @var{string-2}, @var{equal-1}, @ - @var{string-3}, @var{string-4}, @var{equal-2}, @dots{}) + @var{string-3}, @var{string-4}, @var{equal-2}, @dots{}, @ovar{not-equal}) Used with only one argument, the @code{ifelse} simply discards it and produces no output. @@ -2619,8 +2657,65 @@ reverse(`foo', `bar', `gnats', `and gnus') While not a very interesting macro, it does show how simple loops can be made with @code{shift}, @code{ifelse} and recursion. It also shows -that @code{shift} is usually used with @samp{$@@}. Sometimes, a -recursive algorithm requires adding quotes to each element: +that @code{shift} is usually used with @samp{$@@}. Another example of +this is an implementation of a short-circuiting conditional operator. + +@cindex short-circuiting conditional +@cindex conditional, short-circuiting +@deffn Composite cond (@var{test-1}, @var{string-1}, @var{equal-1}, @ + @ovar{test-2}, @ovar{string-2}, @ovar{equal-2}, @dots{}, @ovar{not-equal}) +Similar to @code{ifelse}, where an equal comparison between the first +two strings results in the third, otherwise the first three arguments +are discarded and the process repeats. The difference is that each +@var{test-<n>} is expanded only when it is encountered. This means that +every third argument to @code{cond} is normally given one more level of +quoting than the corresponding argument to @code{ifelse}. +@end deffn + +Here is the implementation of @code{cond}, along with a demonstration of +how it can short-circuit the side effects in @code{side}. Notice how +all the unquoted side effects happen regardless of how many comparisons +are made with @code{ifelse}, compared with only the relevant effects +with @code{cond}. + +@example +define(`cond', +`ifelse(`$#', `1', `$1', + `ifelse($1, `$2', `$3', + `$0(shift(shift(shift($@@))))')')')dnl +define(`side', `define(`counter', incr(counter))$1')dnl +define(`example1', +`define(`counter', `0')dnl +ifelse(side(`$1'), `yes', `one comparison: ', + side(`$1'), `no', `two comparisons: ', + side(`$1'), `maybe', `three comparisons: ', + `side(`default answer: ')')counter')dnl +define(`example2', +`define(`counter', `0')dnl +cond(`side(`$1')', `yes', `one comparison: ', + `side(`$1')', `no', `two comparisons: ', + `side(`$1')', `maybe', `three comparisons: ', + `side(`default answer: ')')counter')dnl +example1(`yes') +@result{}one comparison: 3 +example1(`no') +@result{}two comparisons: 3 +example1(`maybe') +@result{}three comparisons: 3 +example1(`feeling rather indecisive today') +@result{}default answer: 4 +example2(`yes') +@result{}one comparison: 1 +example2(`no') +@result{}two comparisons: 2 +example2(`maybe') +@result{}three comparisons: 3 +example2(`feeling rather indecisive today') +@result{}default answer: 4 +@end example + +Sometimes, a recursive algorithm requires adding quotes to each element, +or treating multiple arguments as a single element: @deffn Composite quote (@dots{}) @deffnx Composite dquote (@dots{}) -- 1.5.3.2