Reduce blank lines in AC_DEFUN_ONCE macros.
[autoconf.git] / tests / m4sugar.at
blob6286af2dce2235931bb95bbf0078d0373ca17d3b
1 #                                                       -*- Autotest -*-
3 AT_BANNER([M4sugar.])
5 # Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2009 Free
6 # Software Foundation, Inc.
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 # 02110-1301, USA.
24 # AT_CHECK_M4SUGAR_TEXT(CODE, STDOUT, STDERR)
25 # -------------------------------------------
26 # Check that m4sugar CODE expands to STDOUT and emits STDERR.
27 m4_define([AT_CHECK_M4SUGAR_TEXT],
29 AT_DATA_M4SUGAR([script.4s],
30 [[m4_init
31 m4_divert_push(0)[]dnl
32 ]$1[[]dnl
33 m4_divert_pop(0)
34 ]])
36 AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
37 ])# AT_CHECK_M4SUGAR_TEXT
40 ## ------------------ ##
41 ## m4_stack_foreach.  ##
42 ## ------------------ ##
44 AT_SETUP([m4@&t@_stack])
46 AT_KEYWORDS([m4@&t@_stack_foreach m4@&t@_stack_foreach_lifo])
47 AT_KEYWORDS([m4@&t@_stack_foreach_sep m4@&t@_stack_foreach_sep_lifo])
48 AT_KEYWORDS([m4@&t@_copy m4@&t@_n])
50 # Test the semantics of macros to walk stacked macro definitions.
51 AT_CHECK_M4SUGAR_TEXT([[dnl
52 m4_pushdef([abc], [def])dnl
53 m4_pushdef([abc], [ghi])dnl
54 m4_pushdef([abc], [jkl])dnl
55 m4_stack_foreach([abc], [m4_n])
56 abc
57 m4_stack_foreach_lifo([abc], [m4_n])
58 m4_stack_foreach([abc], [m4_n])
59 m4_copy([abc], [foo])dnl
60 m4_stack_foreach([foo], [m4_n])
61 m4_stack_foreach_lifo([foo], [m4_n])
62 m4_stack_foreach_sep([abc], [ m4_index([abcdefghijkl],], [)])
63 m4_define([colon], [:])m4_define([lt], [<])m4_define([gt], [>])dnl
64 m4_stack_foreach_sep_lifo([abc], [lt], [gt], [colon])
65 m4_pushdef([xyz], [123])dnl
66 m4_pushdef([xyz], [456])dnl
67 m4_define([doit], [[$1](m4_stack_foreach_sep([xyz], [m4_dquote(], [)], [,]))
68 ])dnl
69 m4_stack_foreach([abc], [doit])]],
70 [[def
71 ghi
72 jkl
74 jkl
75 jkl
76 ghi
77 def
79 def
80 ghi
81 jkl
83 def
84 ghi
85 jkl
87 jkl
88 ghi
89 def
91  3 6 9
92 <jkl>:<ghi>:<def>
93 def([123],[456])
94 ghi([123],[456])
95 jkl([123],[456])
96 ]])
98 AT_CLEANUP
101 ## --------- ##
102 ## m4_defn.  ##
103 ## --------- ##
105 AT_SETUP([m4@&t@_defn])
107 AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine m4@&t@_copy m4@&t@_rename])
109 # Ensure that m4sugar dies when dereferencing undefined macros, whether
110 # this is provided by m4 natively or faked by wrappers in m4sugar.
112 AT_DATA_M4SUGAR([script.4s],
113 [[m4_define([good])
114 m4_defn([good], [oops])
117 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
118 AT_CHECK([grep good stderr], [1])
119 AT_CHECK([grep 'm4@&t@_defn: undefined.*oops' stderr], [0], [ignore])
121 AT_DATA_M4SUGAR([script.4s],
122 [[m4_define([good])
123 m4_popdef([good], [oops])
126 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
127 AT_CHECK([grep good stderr], [1])
128 AT_CHECK([grep 'm4@&t@_popdef: undefined.*oops' stderr], [0], [ignore])
130 AT_DATA_M4SUGAR([script.4s],
131 [[m4_define([good])
132 m4_undefine([good], [oops])
135 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
136 AT_CHECK([grep good stderr], [1])
137 AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])
139 # Check that pushdef stacks can be renamed.
140 AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl
141 m4_pushdef([a], [2])dnl
142 m4_pushdef([a], m4_defn([m4_divnum]))dnl
143 a b c
144 m4_rename([a], [b])dnl
145 a b c
146 m4_copy([b], [c])dnl
147 a b c
148 m4_popdef([b], [c])dnl
149 a b c
150 m4_popdef([b], [c])dnl
151 a b c
152 m4_popdef([b], [c])dnl
153 a b c
154 ]], [[0 b c
155 a 0 c
156 a 0 0
157 a 2 2
158 a 1 1
159 a b c
162 AT_CLEANUP
165 ## ------------ ##
166 ## m4_dumpdef.  ##
167 ## ------------ ##
169 AT_SETUP([m4@&t@_dumpdef])
171 AT_KEYWORDS([m4@&t@_dumpdefs])
173 # Ensure that m4sugar dies when dereferencing undefined macros.
175 AT_DATA_M4SUGAR([script.4s],
176 [[m4_define([good], [yep])
177 m4_dumpdef([good], [oops])
180 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
181 AT_CHECK([grep '^good:  \[[yep\]]$' stderr], [0], [ignore])
182 AT_CHECK([grep 'm4@&t@_dumpdef: undefined.*oops' stderr], [0], [ignore])
184 # Check that pushdef stacks can be dumped.
185 AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL])
186 m4_pushdef([a], [1])
187 m4_pushdef([a], [2])
188 m4_dumpdef([a])
189 m4_dumpdefs([oops], [a])
190 m4_divert_pop([KILL])dnl
191 ]], [],
192 [[a:    [2]
193 a:      [2]
194 a:      [1]
197 # Check behavior when dumping builtins.  Unfortunately, when using M4 1.4.x
198 # (or more precisely, when __m4_version__ is undefined), builtins get
199 # flattened to an empty string.  It takes M4 1.6 to work around this.
200 AT_DATA_M4SUGAR([script.4s],
201 [[m4_ifdef([__m4_version__], [_m4_undefine([__m4_version__])])
202 m4_init
203 m4_dumpdef([m4_define])
206 AT_CHECK_M4SUGAR([-o-], [0], [],
207 [[m4_define:    []
210 AT_DATA_M4SUGAR([script.4s],
211 [[m4_init
212 m4_ifdef([__m4_version__],
213 [m4_dumpdef([m4_define])],
214 [m4_errprintn([m4_define:       <define>])])
217 AT_CHECK_M4SUGAR([-o-], [0], [],
218 [[m4_define:    <define>
221 AT_CLEANUP
224 ## --------- ##
225 ## m4_warn.  ##
226 ## --------- ##
228 AT_SETUP([m4@&t@_warn])
230 # m4_text_wrap is used to display the help strings.  Also, check that
231 # commas are not swallowed.  This can easily happen because of
232 # m4-listification.
234 # FIXME: For the time being we use -f to make sure we do issue the
235 # warnings.  But maybe autom4te should handle that by itself?
237 AT_DATA_M4SUGAR([script.4s],
238 [[m4_init
239 m4_defun([cross_warning], [m4_warn([cross],  [cross])])
241 m4_divert([0])dnl
242 m4_warn([obsolete],  [obsolete])dnl
243 cross_warning[]dnl
244 m4_warn([syntax], [syntax])dnl
247 AT_CHECK_M4SUGAR([-o-], 0, [],
248 [script.4s:7: warning: syntax
251 AT_CHECK_M4SUGAR([-o- -Wall -f], 0, [],
252 [script.4s:5: warning: obsolete
253 script.4s:6: warning: cross
254 script.4s:2: cross_warning is expanded from...
255 script.4s:6: the top level
256 script.4s:7: warning: syntax
259 AT_CHECK_M4SUGAR([-o- -Wnone,cross -f], 0, [],
260 [script.4s:6: warning: cross
261 script.4s:2: cross_warning is expanded from...
262 script.4s:6: the top level
265 AT_CHECK_M4SUGAR([-o- -Wnone,cross,error -f], 1, [],
266 [[script.4s:6: warning: cross
267 script.4s:2: cross_warning is expanded from...
268 script.4s:6: the top level
271 AT_CLEANUP
274 ## ----------------- ##
275 ## m4_divert_stack.  ##
276 ## ----------------- ##
278 AT_SETUP([m4@&t@_divert_stack])
279 AT_KEYWORDS([m4@&t@_divert m4@&t@_divert_push m4@&t@_divert_pop
280 m4@&t@_undivert m4@&t@_cleardivert m4@&t@_divert_text])
282 AT_CHECK_M4SUGAR_TEXT([[1.m4_divert_stack
283 m4_divert_push([10])2.m4_divert_stack
284 m4_divert_text([20], [3.m4_divert_stack])dnl
285 m4_divert([30])4.m4_divert_stack
286 m4_divert_pop([30])dnl
287 5.m4_undivert([20], [30])
288 m4_pattern_allow([^m4_divert])dnl
289 ]], [[1.script.4s:2: m4@&t@_divert_push: 0
290 script.4s:1: m4@&t@_divert: KILL
291 5.3.script.4s:5: m4@&t@_divert_push: 20
292 script.4s:4: m4@&t@_divert_push: 10
293 script.4s:2: m4@&t@_divert_push: 0
294 script.4s:1: m4@&t@_divert: KILL
295 4.script.4s:6: m4@&t@_divert: 30
296 script.4s:2: m4@&t@_divert_push: 0
297 script.4s:1: m4@&t@_divert: KILL
299 2.script.4s:4: m4@&t@_divert_push: 10
300 script.4s:2: m4@&t@_divert_push: 0
301 script.4s:1: m4@&t@_divert: KILL
304 AT_CHECK_M4SUGAR_TEXT([[dnl
305 m4_divert_text([3], [three])dnl
306 m4_divert_text([4], [four])dnl
307 m4_divert_text([1], [one])dnl
308 m4_divert_text([2], [two])dnl
309 m4_cleardivert([2], [3])dnl
311 [[one
312 four
315 AT_DATA_M4SUGAR([script.4s],
316 [[m4_divert_pop
318 AT_CHECK_M4SUGAR([-o-], [1], [],
319 [[script.4s:1: error: too many m4@&t@_divert_pop
320 script.4s:1: the top level
321 autom4te: m4 failed with exit status: 1
324 AT_DATA_M4SUGAR([script.4s],
325 [[m4_init
326 m4_divert_push([1])
327 m4_divert_pop([2])
329 AT_CHECK_M4SUGAR([-o-], [1], [],
330 [[script.4s:3: error: m4@&t@_divert_pop(2): diversion mismatch:
331 script.4s:2: m4@&t@_divert_push: 1
332 script.4s:1: m4@&t@_divert: KILL
333 script.4s:3: the top level
334 autom4te: m4 failed with exit status: 1
337 AT_DATA_M4SUGAR([script.4s],
338 [[m4_divert([1])
339 m4_init
340 m4_divert_push([2])
342 AT_CHECK_M4SUGAR([-o-], [1], [],
343 [[script.4s:2: error: m4@&t@_init: unbalanced m4@&t@_divert_push:
344 script.4s:3: m4@&t@_divert_push: 2
345 script.4s:2: m4@&t@_divert: KILL
346 script.4s:2: the top level
347 autom4te: m4 failed with exit status: 1
350 AT_CLEANUP
353 ## -------------------- ##
354 ## m4_expansion_stack.  ##
355 ## -------------------- ##
357 AT_SETUP([m4@&t@_expansion_stack])
359 AT_CHECK_M4SUGAR_TEXT([[1.m4_expansion_stack
360 m4_defun([a], [b])dnl
361 m4_define([c], [d])dnl
362 m4_defun([d], [2.m4_expansion_stack])dnl
363 m4_defun([b], [c])dnl
365 3.m4_ifdef([_m4_expansion_stack], [m4_expansion_stack])
366 ]], [[1.script.4s:3: the top level
367 2.script.4s:6: d is expanded from...
368 script.4s:7: b is expanded from...
369 script.4s:4: a is expanded from...
370 script.4s:8: the top level
374 AT_CLEANUP
377 ## --------------------------- ##
378 ## m4_require: error message.  ##
379 ## --------------------------- ##
381 AT_SETUP([m4@&t@_require: error message])
382 AT_KEYWORDS([m4@&t@_require])
384 AT_DATA_M4SUGAR([script.4s],
385 [[m4_defun([foo], [FOO])
386 m4_require([foo])
389 AT_CHECK_M4SUGAR([], 1, [],
390 [[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro
391 script.4s:2: the top level
392 autom4te: m4 failed with exit status: 1
394 AT_CLEANUP
397 ## ----------------------------------- ##
398 ## m4_require: circular dependencies.  ##
399 ## ----------------------------------- ##
401 AT_SETUP([m4@&t@_require: circular dependencies])
402 AT_KEYWORDS([m4@&t@_require])
404 AT_DATA_M4SUGAR([script.4s],
405 [[m4_defun([foo], [m4_require([bar])])
407 m4_defun([bar], [m4_require([foo])])
409 m4_defun([baz], [m4_require([foo])])
411 m4_init
412 m4_divert([0])dnl
416 AT_CHECK_M4SUGAR([], 1, [],
417 [[script.4s:9: error: m4@&t@_require: circular dependency of foo
418 script.4s:3: bar is expanded from...
419 script.4s:1: foo is expanded from...
420 script.4s:5: baz is expanded from...
421 script.4s:9: the top level
422 autom4te: m4 failed with exit status: 1
424 AT_CLEANUP
427 ## ---------------------- ##
428 ## m4_require: one-shot.  ##
429 ## ---------------------- ##
431 AT_SETUP([m4@&t@_require: one-shot initialization])
432 AT_KEYWORDS([m4@&t@_require])
433 AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy m4@&t@_defun_once])
435 dnl check out m4_defun_init, m4_copy, and odd macro names
436 AT_CHECK_M4SUGAR_TEXT([[
437 m4_defun_init([a], [[init a
438 ]], [[common a]])dnl
439 m4_defun([b], [[b]m4_require([a])])dnl
440 m4_defun([c], [[c]m4_require([a])])dnl
444 m4_defun_init([-], [hello, ], [m4_if([$#], [0], [world], [[$1]])])dnl
445 m4_copy([-], [.])dnl
446 m4_indir([.])
447 m4_indir([.], [goodbye])
448 m4_indir([-], [again])
449 ]], [[
450 init a
451 common a
454 common a
455 hello, world
456 goodbye
457 hello, again
460 dnl Check m4_defun_once behavior
461 AT_CHECK_M4SUGAR_TEXT([[
462 m4_defun_once([a], [[a]])dnl
463 m4_defun([b], [[b]m4_require([a])])dnl
464 m4_defun([c], [[c]a[]m4_require([b])])dnl
467 m4_defun_once([d], [[d]m4_require([a])])dnl
469 m4_defun_once([e], [[e]])dnl
470 m4_defun([f], [[f]m4_require([e])e])dnl
472 ]], [[
483 AT_CLEANUP
486 ## -------------------- ##
487 ## m4_require: nested.  ##
488 ## -------------------- ##
490 AT_SETUP([m4@&t@_require: nested])
491 AT_KEYWORDS([m4@&t@_require m4@&t@_defun])
493 dnl From the m4sugar.m4 discourse: Require chains, top level
494 AT_CHECK_M4SUGAR_TEXT([[dnl
495 m4_defun([a], [[a]])dnl aka TEST2a
496 m4_defun([b], [[b]m4_require([a])])dnl aka TEST3
497 m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b
498 m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1
502 post
504 [[pre
510 post
513 dnl From the m4sugar.m4 discourse: Require chains, nested
514 AT_CHECK_M4SUGAR_TEXT([[dnl
515 m4_defun([a], [[a]])dnl aka TEST2a
516 m4_defun([b], [[b]m4_require([a])])dnl aka TEST3
517 m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b
518 m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1
519 m4_defun([wrap],
520 [pre
523 post])dnl
524 wrap
532 post
535 dnl Direct invocation, nested requires, top level
536 AT_CHECK_M4SUGAR_TEXT([[dnl
537 m4_defun([a], [[a]])dnl
538 m4_defun([b], [[b]m4_require([a])])dnl
539 m4_defun([c], [[c]m4_require([b])])dnl
545 post
547 [[pre
553 post
556 dnl Direct invocation, nested requires, nested defun.  This is an example
557 dnl of expansion before requirement, such that b occurs before its
558 dnl prerequisite a.  This indicates a bug in the macros (but not in
559 dnl autoconf), so we should be emitting a warning.
560 AT_CHECK_M4SUGAR_TEXT([[dnl
561 m4_defun([a], [[a]])dnl
562 m4_defun([b], [[b]m4_require([a])])dnl
563 m4_defun([c], [[c]m4_require([b])])dnl
564 m4_defun([outer],
565 [pre
570 post])dnl
571 outer
580 post
582 [[script.4s:14: warning: m4@&t@_require: `a' was expanded before it was required
583 script.4s:5: b is expanded from...
584 script.4s:6: c is expanded from...
585 script.4s:7: outer is expanded from...
586 script.4s:14: the top level
589 dnl Direct invocation, expand-before-require but no nested require.  As this
590 dnl is common in real life, but does not result in out-of-order expansion,
591 dnl we silently permit this.
592 AT_CHECK_M4SUGAR_TEXT([[dnl
593 m4_defun([a], [[a]])dnl
594 m4_defun([b], [[b]m4_require([a])])dnl
595 m4_defun([c], [[c]])dnl
596 m4_defun([d], [[d]m4_require([c])])dnl
597 pre1
602 post1
603 m4_defun([outer],
604 [pre2
609 post2])dnl
610 outer
611 m4_defun([e], [[e]])dnl
612 m4_defun([f], [[f]m4_require([e])])dnl
613 m4_defun([g], [[g]
615 f])dnl
616 m4_defun([h], [[h]m4_require([g])])dnl
618 m4_defun([i], [[i]])dnl
619 m4_defun([j], [[j]
620 i])dnl
621 m4_defun([k], [[k]m4_require([i])])dnl
622 m4_defun([l], [[l]m4_require([k])])dnl
623 m4_defun([m], [[m]m4_require([j])m4_require([l])])dnl
626 [[pre1
631 post1
632 pre2
637 post2
649 AT_CLEANUP
652 ## --------- ##
653 ## m4_cond.  ##
654 ## --------- ##
656 AT_SETUP([m4@&t@_cond])
658 AT_CHECK_M4SUGAR_TEXT([[m4_define([side], [m4_errprintn([$1])$1])
659 m4_cond([side(1)], [1], [a],
660         [side(1)], [1], [b],
661         [side(1)], [2], [c])
662 m4_cond([side(2)], [1], [a],
663         [side(2)], [1], [b],
664         [side(2)], [2], [c],
665         [side(2)])
666 m4_cond([side(3)], [1], [a],
667         [side(3)], [1], [b],
668         [side(3)], [2], [c],
669         [side(3)])
670 m4_cond([a,a], [a,a], [yes], [no])
671 m4_cond([[a,a]], [a,a], [yes])
672 m4_cond([a,a], [a,b], [yes], [no])
673 m4_cond([a,a], [a,b], [yes])
674 m4_cond([m4_eval([0xa])])
675 m4_define([ab], [AB])dnl
676 m4_cond([a])b
677 m4_cond([1], [1], [a])b
678 m4_cond([1], [2], [3], [a])b
679 ]], [[
691 ]], [[1
701 AT_CLEANUP
704 ## ---------- ##
705 ## m4_split.  ##
706 ## ---------- ##
708 AT_SETUP([m4@&t@_split])
710 AT_CHECK_M4SUGAR_TEXT(
711 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
712 m4_split
713 m4_split([[]])
714 m4_split([ ])
715 m4_split([active])
716 m4_split([ active       active ])end
717 m4_split([ ], [ ])
718 m4_split([active], [ ])
719 m4_split([ active       active ], [ ])end
720 m4_split([abcde], [bd])
721 m4_split([abcde], [[bd]])
722 m4_split([foo=`` bar=''])
723 m4_split([foo='' bar=``])
724 dnl these next two are from the manual; keep this in sync if the internal
725 dnl quoting strings in m4_split are changed
726 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
727 m4_split([a )}>=- b -=<{( c])
728 m4_split([a )}@&t@>=- b -=<@&t@{( c])
732 [[]]
733 [], []
734 [active]
735 [], [active], [active], []end
736 [], []
737 [active]
738 [], [active     active], []end
739 [abcde]
740 [a], [c], [e]
741 [foo=``], [bar='']
742 [foo=''], [bar=``]
743 [a], [], [B], [], [c]
744 [a], [)}>=@&t@-], [b], [-@&t@=<{(], [c]
747 AT_CLEANUP
750 ## ------- ##
751 ## m4_do.  ##
752 ## ------- ##
754 AT_SETUP([m4@&t@_do])
756 AT_CHECK_M4SUGAR_TEXT(
757 [[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl
758 m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl
759 m4_do
760 m4_do([a])
761 m4_do([a], [b])c
762 m4_unquote(m4_join([], [a], [b]))c
763 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
764 m4_do([a], [b])c
765 m4_unquote(m4_join([], [a], [b]))c
775 AT_CLEANUP
778 ## ----------- ##
779 ## m4_append.  ##
780 ## ----------- ##
782 AT_SETUP([m4@&t@_append])
783 AT_KEYWORDS([m4@&t@_append_uniq m4@&t@_append_uniq_w])
785 AT_CHECK_M4SUGAR_TEXT(
786 [[m4_define([active], [ACTIVE])dnl
787 m4_append([sentence], [This is an])dnl
788 m4_append([sentence], [ active ])dnl
789 m4_append([sentence], [symbol.])dnl
790 sentence
791 m4_undefine([active])dnl
792 sentence
793 m4_define([active], [ACTIVE])dnl
794 m4_append([hooks], [m4_define([act1], [act2])])dnl
795 m4_append([hooks], [m4_define([act2], [active])])dnl
796 m4_undefine([active])dnl
797 act1
798 hooks
799 act1
800 dnl Test for bug fixed in 2.62 when separator is active.
801 m4_define([a], [A])dnl
802 m4_append_uniq([foo], [-], [a])dnl
803 m4_append_uniq([foo], [-], [a])dnl
804 m4_append_uniq([bar], [-], [a])dnl
805 m4_append_uniq([bar], [~], [a])dnl
806 m4_append_uniq([bar], [-], [a])dnl
807 m4_defn([foo])
808 m4_defn([bar])
811 m4_append_uniq([blah], [one], [, ], [new], [existing])
812 m4_append_uniq([blah], [two], [, ], [new], [existing])
813 m4_append_uniq([blah], [two], [, ], [new], [existing])
814 m4_append_uniq([blah], [three], [, ], [new], [existing])
815 m4_append([blah], [two], [, ])dnl
816 blah
817 m4_dquote(blah)
818 m4_append([list], [one], [[, ]])dnl
819 m4_append([list], [two], [[, ]])dnl
820 m4_append([list], [three], [[, ]])dnl
821 list
822 m4_dquote(list)
823 m4_append_uniq_w([numbers], [1 1 2])dnl
824 m4_append_uniq_w([numbers], [ 2 3 ])dnl
825 numbers
827 [[This is an ACTIVE symbol.
828 This is an active symbol.
829 act1
831 active
838 existing
840 one, two, three, two
841 [one],[two],[three],[two]
842 one, two, three
843 [one, two, three]
844 1 2 3
847 AT_DATA_M4SUGAR([script.4s],
848 [[m4_init[]dnl
849 m4_append_uniq([str], [a], [ ])
850 m4_append_uniq([str], [a b], [ ])
851 m4_divert([0])dnl
855 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
856 ]], [[script.4s:3: warning: m4@&t@_append_uniq: `a b' contains ` '
859 AT_CLEANUP
862 ## --------- ##
863 ## m4_join.  ##
864 ## --------- ##
866 AT_SETUP([m4@&t@_join])
868 AT_KEYWORDS([m4@&t@_joinall])
870 AT_CHECK_M4SUGAR_TEXT(
871 [[m4_define([active], [ACTIVE])
872 m4_join
873 m4_join([|])
874 m4_join([, ], [one], [two])
875 m4_dquote(m4_join([, ], [one], [two]))
876 m4_join([|], [active], [active])
877 m4_join([|], ,,,[one])
878 m4_join([|], [one],,,)
879 m4_join([], ,,,[two])
880 m4_join([], [two],,,)
881 m4_join([ active ], [one], , [two])
882 m4_join([], [one], [two])
883 m4_joinall([-], [one], [], [two])
884 m4_joinall([-], [], [], [three], [], [])
885 m4_joinall([], [one], [], [two])
886 m4_joinall
887 m4_joinall([-])
888 m4_joinall([-], [one])
893 one, two
894 [one, two]
895 active|active
900 one active two
901 onetwo
902 one--two
903 --three--
904 onetwo
910 AT_CLEANUP
913 ## ----------- ##
914 ## m4_expand.  ##
915 ## ----------- ##
917 AT_SETUP([m4@&t@_expand])
919 AT_CHECK_M4SUGAR_TEXT(
920 [[m4_define([active], [ACTIVE])dnl
921 m4_expand([#active
922 active])
923 m4_expand([[active]])
924 dnl properly quoted case statements
925 m4_expand([case a in @%:@(
926   *) echo active, ;;
927 esac
928 case b in
929   *[)] echo active, ;;
930 esac])
931 dnl unbalanced underquoted `)', but we manage anyway (gasp!)
932 m4_expand([case c in #(
933   *) echo active, ;;
934 esac
935 case d in
936   *) echo active, ;;
937 esac])
938 dnl unterminated comment/dnl
939 m4_expand([active # active])
940 m4_expand([a
941 dnl])
942 m4_expand([a
943 -dnl])
945 [[#active
946 ACTIVE
947 active
948 case a in #(
949   *) echo ACTIVE, ;;
950 esac
951 case b in
952   *) echo ACTIVE, ;;
953 esac
954 case c in #(
955   *) echo ACTIVE, ;;
956 esac
957 case d in
958   *) echo ACTIVE, ;;
959 esac
960 ACTIVE # active
966 AT_CLEANUP
969 ## -------------- ##
970 ## m4_text_wrap.  ##
971 ## -------------- ##
973 AT_SETUP([m4@&t@_text_wrap])
975 # m4_text_wrap is used to display the help strings.  Also, check that
976 # commas and $ are not swallowed.  This can easily happen because of
977 # m4-listification.
979 AT_DATA_M4SUGAR([script.4s],
980 [[m4_init[]m4_divert([0])dnl
981 m4_text_wrap([Short string */], [   ], [/* ], 20)
983 m4_text_wrap([Much longer string */], [   ], [/* ], 20)
985 m4_text_wrap([Short doc.], [          ], [  --short ], 30)
987 m4_text_wrap([Short doc.], [          ], [  --too-wide], 30)
989 m4_text_wrap([Super long documentation.], [          ], [  --too-wide], 30)
991 m4_text_wrap([First, second  , third, [,quoted]])
992 m4_define([xfff], [oops])
993 m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
996 AT_DATA([expout],
997 [[/* Short string */
999 /* Much longer
1000    string */
1002   --short Short doc.
1004   --too-wide
1005           Short doc.
1007   --too-wide
1008           Super long
1009           documentation.
1011 First, second , third, [,quoted]
1013  $@ Some $1 $2 $3
1014  $* $4 embedded
1015  $* dollars.
1018 AT_CHECK_M4SUGAR([-o-], 0, [expout])
1020 AT_CLEANUP
1022 ## -------------------- ##
1023 ## m4_version_compare.  ##
1024 ## -------------------- ##
1026 AT_SETUP([m4@&t@_version_compare])
1028 AT_KEYWORDS([m4@&t@_list_cmp])
1030 AT_CHECK_M4SUGAR_TEXT(
1031 [[m4_version_compare([1.1], [2.0])
1032 m4_version_compare([2.0b], [2.0a])
1033 m4_version_compare([2.0z], [2.0y])
1034 m4_version_compare([1.1.1], [1.1.1a])
1035 m4_version_compare([1.2], [1.1.1a])
1036 m4_version_compare([1.0], [1])
1037 m4_version_compare([1.0a], [1.0a])
1038 m4_version_compare([1.1a], [1.1a.1])
1039 m4_version_compare([1.10], [1.1a])
1040 m4_version_compare([1-1a], [1,1A])
1041 m4_define([a], [oops])dnl
1042 m4_version_compare([1.1a], [1.1A])
1043 m4_version_compare([1z], [1aa])
1044 m4_version_compare([2.61a], [2.61a-248-dc51])
1045 m4_version_compare([2.61b], [2.61a-248-dc51])
1046 m4_version_compare([08], [09])
1047 m4_version_compare([010], [8])
1048 dnl Test that side effects to m4_list_cmp occur exactly once
1049 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
1050             [[0], [0], [0]m4_errprintn([hi])])
1051 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
1052             [[0], [0], [0]m4_errprintn([bye])])
1054 [[-1
1072 ]], [[hi
1078 AT_CLEANUP
1080 ## ------------------------------ ##
1081 ## Standard regular expressions.  ##
1082 ## ------------------------------ ##
1084 AT_SETUP([Standard regular expressions])
1086 # AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = `ok' | `')
1087 # ------------------------------------------------
1088 # Check whether RE-NAME (a macro whose definition is a regular expression)
1089 # matches TEXT.  INTENT = `ok' if the match should succeed or else empty.
1090 m4_define([AT_CHECK_M4RE],
1091 [AT_CHECK_M4SUGAR_TEXT(
1092 [[m4_bregexp([$2], ^m4_defn([$1])$, [ok])
1093 ]], [$3
1094 ])])
1096 AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok])
1097 AT_CHECK_M4RE([m4_re_word], [_9abc], [ok])
1098 AT_CHECK_M4RE([m4_re_word], [9ab_c])
1100 AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok])
1101 AT_CHECK_M4RE([m4_re_string], [_9abc], [ok])
1102 AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok])
1103 AT_CHECK_M4RE([m4_re_string], [9a@_c])
1105 AT_CLEANUP
1107 ## ----------- ##
1108 ## m4_bmatch.  ##
1109 ## ----------- ##
1111 AT_SETUP([m4@&t@_bmatch])
1113 AT_CHECK_M4SUGAR_TEXT(
1114 [[m4_bmatch([abc], [default\])
1115 m4_bmatch([abc], [^a], [yes])
1116 m4_bmatch([abc], [^a], [yes], [no])
1117 m4_bmatch([abc], [^.a], [yes])
1118 m4_bmatch([abc], [^.a], [yes], [no\])
1119 m4_bmatch([abc], [a], [1], [b], [2])
1120 m4_bmatch([abc], [A], [1], [b], [2])
1121 m4_define([ab], [AB])dnl
1122 m4_bmatch([$*], [a])b
1123 m4_bmatch([$*], [\*], [a])b
1124 m4_bmatch([$*], [1], [2], [a])b
1125 ]], [[default\
1137 AT_CLEANUP
1139 ## --------------- ##
1140 ## m4_bpatsubsts.  ##
1141 ## --------------- ##
1143 AT_SETUP([m4@&t@_bpatsubsts])
1145 AT_CHECK_M4SUGAR_TEXT(
1146 [[m4_bpatsubsts([11], [^..$])
1147 m4_bpatsubsts([11], [\(.\)1], [\12])
1148 m4_bpatsubsts([11], [^..$], [], [1], [2])
1149 m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3])
1150 m4_define([a], [oops])m4_define([c], [oops])dnl
1151 m4_define([AB], [good])m4_define([bc], [good])dnl
1152 m4_bpatsubsts([abc], [a], [A], [b], [B], [c])
1153 m4_bpatsubsts([ab], [a])c
1154 m4_bpatsubsts([ab], [c], [C], [a])c
1155 m4_bpatsubsts([$1$*$@], [\$\*], [$#])
1156 ]], [[11
1160 good
1161 good
1162 good
1163 $1$#$@
1166 AT_CLEANUP
1168 ## -------------- ##
1169 ## m4_esyscmd_s.  ##
1170 ## -------------- ##
1172 AT_SETUP([m4@&t@_esyscmd_s])
1173 AT_KEYWORDS([m4@&t@_chomp m4@&t@_chomp_all])
1175 AT_CHECK_M4SUGAR_TEXT(
1176 [[m4_define([world], [WORLD])dnl
1177 m4_chomp([abc])
1178 m4_chomp([world
1181 m4_esyscmd_s([echo hello world])
1182 m4_esyscmd_s([echo '[goodbye,
1183 cruel world
1185 ]'])
1186 ]], [[abc
1187 world
1189 hello WORLD
1190 goodbye,
1191 cruel world
1194 AT_CLEANUP
1196 ## ---------- ##
1197 ## M4 Loops.  ##
1198 ## ---------- ##
1200 AT_SETUP([M4 loops])
1202 AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w m4@&t@_map_args_w])
1204 AT_CHECK_M4SUGAR_TEXT([[dnl
1205 m4_define([myvar], [outer value])dnl
1206 m4_for([myvar], 1, 3, 1, [ myvar])
1207 m4_for([myvar], 1, 3,  , [ myvar])
1208 m4_for([myvar], 3, 1,-1, [ myvar])
1209 m4_for([myvar], 3, 1,  , [ myvar])
1210 m4_for([myvar], 1, 3, 2, [ myvar])
1211 m4_for([myvar], 3, 1,-2, [ myvar])
1212 m4_for([myvar],-1,-3,-2, [ myvar])
1213 m4_for([myvar],-3,-1, 2, [ myvar])
1214 dnl Make sure we recalculate the bounds correctly:
1215 m4_for([myvar], 1, 3, 3, [ myvar])
1216 m4_for([myvar], 1, 6, 3, [ myvar])
1217 m4_for([myvar],22,-7,-5, [ myvar])
1218 m4_for([myvar],-2,-7,-4, [ myvar])
1219 m4_for([myvar],-7,-2, 4, [ myvar])
1220 dnl Make sure we are not exposed to division truncation:
1221 m4_for([myvar], 2, 5, 2, [ myvar])
1222 m4_for([myvar],-5,-2, 2, [ myvar])
1223 m4_for([myvar], 5, 2,-2, [ myvar])
1224 m4_for([myvar],-2,-5,-2, [ myvar])
1225 dnl Make sure we do not divide by zero:
1226 m4_for([myvar], 1, 1,  , [ myvar])
1227 m4_for([myvar], 1, 1,+2, [ myvar])
1228 m4_for([myvar], 1, 1,-2, [ myvar])
1229 dnl Make sure we do not loop endlessly
1230 m4_for([myval], 1, 1, 0, [ myval])
1231 dnl Make sure to properly parenthesize
1232 m4_for([myvar], 3-5, -2+8, , [ myvar])
1233 m4_for([myvar], -2+8, 3-5, , [ myvar])
1234 m4_for([myvar], 8, 16, 3 * 2, [ myvar])
1235 m4_for([myvar], 8, 16, -3 * -2, [ myvar])
1236 m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar])
1237 dnl Modifying var does not affect the number of iterations
1238 m4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)])
1239 dnl Make sure we can do nameless iteration
1240 m4_for(, 1, 10, , -)
1241 dnl foreach tests
1242 m4_foreach([myvar], [[a], [b, c], [d], [e
1243 ],[f]], [ myvar|])
1244 m4_foreach_w([myvar], [a  b c, d,e f
1245 g], [ myvar|])
1246 myvar
1247 m4_map_args_w([a  b c, d,e f
1248 g], [ ], [|])
1249 m4_map_args_w([a b], [\1], [/])
1250 m4_define([dashes], [--])dnl
1251 m4_map_args_w([a b c], [/], [\1], [dashes])
1252 dnl only one side effect expansion, prior to visiting list elements
1253 m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
1254 dnl shifting forms an important part of loops
1255 m4_shift3:m4_shift3(1,2,3):m4_shift3(1,2,3,4)
1256 m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
1258 [[ 1 2 3
1259  1 2 3
1260  3 2 1
1261  3 2 1
1262  1 3
1263  3 1
1264  -1 -3
1265  -3 -1
1267  1 4
1268  22 17 12 7 2 -3
1269  -2 -6
1270  -7 -3
1271  2 4
1272  -5 -3
1273  5 3
1274  -2 -4
1279  -2 -1 0 1 2 3 4 5 6
1280  6 5 4 3 2 1 0 -1 -2
1281  8 14
1282  8 14
1283  8 14
1284  1 2 3 4 5
1285 ----------
1286  a| b, c| d| e
1287 | f|
1288  a| b| c,| d,e| f| g|
1289 outer value
1290  a| b| c,| d,e| f| g|
1291 \1a/\1b/
1292 /a\1--/b\1--/c\1
1295 ]], [[hi
1301 dnl bounds checking in m4_for
1302 AT_DATA_M4SUGAR([script.4s],
1303 [[m4_init
1304 m4_divert([0])dnl
1305 m4_for([myvar], 1, 3,-1, [ myvar])
1307 AT_CHECK_M4SUGAR([], 1, [],
1308 [[script.4s:3: error: assert failed: -1 > 0
1309 script.4s:3: the top level
1310 autom4te: m4 failed with exit status: 1
1313 AT_DATA_M4SUGAR([script.4s],
1314 [[m4_init
1315 m4_divert([0])dnl
1316 m4_for([myvar], 1, 2, 0, [ myvar])
1318 AT_CHECK_M4SUGAR([], 1, [],
1319 [[script.4s:3: error: assert failed: 0 > 0
1320 script.4s:3: the top level
1321 autom4te: m4 failed with exit status: 1
1324 AT_DATA_M4SUGAR([script.4s],
1325 [[m4_init
1326 m4_divert([0])dnl
1327 m4_for([myvar], 2, 1, 0, [ myvar])
1329 AT_CHECK_M4SUGAR([], 1, [],
1330 [[script.4s:3: error: assert failed: 0 < 0
1331 script.4s:3: the top level
1332 autom4te: m4 failed with exit status: 1
1335 dnl m4_shiftn also does bounds checking
1336 AT_DATA_M4SUGAR([script.4s],
1337 [[m4_init
1338 m4_divert([0])dnl
1339 m4_shiftn(3,1,2)
1341 AT_CHECK_M4SUGAR([], 1, [],
1342 [[script.4s:3: error: assert failed: 0 < 3 && 3 < 3
1343 script.4s:3: the top level
1344 autom4te: m4 failed with exit status: 1
1347 AT_CLEANUP
1350 ## --------------------- ##
1351 ## m4_map{,all}{,_sep}.  ##
1352 ## --------------------- ##
1354 AT_SETUP([m4@&t@_map])
1355 AT_KEYWORDS([m4@&t@_apply m4@&t@_map_sep m4@&t@_mapall m4@&t@_mapall_sep])
1356 AT_KEYWORDS([m4@&t@_count])
1358 AT_CHECK_M4SUGAR_TEXT([[dnl
1359 m4_map([m4_count], [])
1360 m4_map([ m4_count], [[],
1361                      [[1]],
1362                      [[1], [2]]])
1363 m4_mapall([ m4_count], [[],
1364                         [[1]],
1365                         [[1], [2]]])
1366 m4_map_sep([m4_eval], [,], [[[1+2]],
1367                             [[10], [16]]])
1368 m4_count(m4_map_sep([m4_echo], [,], [[], [[1]], [[2]]]))
1369 m4_count(m4_mapall_sep([m4_echo], [,], [[], [[1]], [[2]]]))
1370 m4_map_sep([m4_eval], [[,]], [[[1+2]],
1371                               [[10], [16]]])
1372 m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
1373 m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
1374 m4_map([-], [[]])
1375 m4_mapall([-], [[]])
1376 m4_map_sep([-], [:], [[]])
1377 m4_mapall_sep([-], [:], [[]])
1378 m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl
1379 m4_define([a1], [oops])dnl
1380 m4_define([pass1], [oops])dnl
1381 m4_map([a], [[[a]]])1
1382 m4_map([m4_unquote([a])], [m4_dquote([a])])
1383 dnl only one side effect expansion, prior to visiting list elements
1384 m4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1385 m4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1386 m4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1387 m4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1390  1 2
1391  0 1 2
1402 pass1
1403 pass
1404 ]], [[hi
1422 AT_CLEANUP
1425 ## --------------------------------------- ##
1426 ## m4_map_args{,_sep,_pair} and m4_curry.  ##
1427 ## --------------------------------------- ##
1429 AT_SETUP([m4@&t@_map_args and m4@&t@_curry])
1430 AT_KEYWORDS([m4@&t@_map_args_sep m4@&t@_map_args_pair m4@&t@_reverse
1431 m4@&t@_map])
1433 dnl First, make sure we can curry in isolation.
1434 AT_CHECK_M4SUGAR_TEXT(
1435 [[m4_curry([m4_echo])([1])
1436 m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
1437 m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1438 m4_define([add_one], [m4_curry([add], [1])])dnl
1439 add_one()([4])
1442 3, 2, 1
1446 dnl Now, check that we can map a list of arguments.
1447 AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnl
1448 m4_map_args([ m4_echo])
1449 m4_map_args([ m4_echo], [plain], [active])
1450 m4_map_args([m4_unquote], [plain], [active])
1451 m4_map_args_pair([, m4_reverse], [])
1452 m4_map_args_pair([, m4_reverse], [], [1])
1453 m4_map_args_pair([, m4_reverse], [], [1], [2])
1454 m4_map_args_pair([, m4_reverse], [], [1], [2], [3])
1455 m4_map_args_pair([, m4_reverse], [], [1], [2], [3], [4])
1456 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1])
1457 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2])
1458 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3])
1459 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
1460 m4_map_args_sep([<], [>], [:], [1], [2], [3])
1461 m4_map_args_sep([m4_echo(], [)], [ ], [plain], [active])
1464  plain active
1465 plainACTIVE
1467 , 1
1468 , 2, 1
1469 , 2, 1, 3
1470 , 2, 1, 4, 3
1471 , [1]
1472 , 2, 1
1473 , 2, 1, [3]
1474 , 2, 1, 4, 3
1475 <1>:<2>:<3>
1476 plain active
1479 dnl Finally, put the two concepts together, to show the real power of the API.
1480 AT_CHECK_M4SUGAR_TEXT(
1481 [[m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1482 m4_define([list], [[-1], [0], [1]])dnl
1483 dnl list_add_n(value, arg...)
1484 dnl add VALUE to each ARG and output the resulting list
1485 m4_define([list_add_n],
1486   [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))])
1487 list_add_n([1], list)
1488 list_add_n([2], list)
1489 ]], [[
1490 0,1,2
1491 1,2,3
1494 AT_CLEANUP
1497 ## ------------ ##
1498 ## m4_combine.  ##
1499 ## ------------ ##
1501 AT_SETUP([m4@&t@_combine])
1503 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
1504 m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
1505 m4_combine([, ], [[a], [b]], [-])
1506 m4_combine([, ], [[a], [b]], [-], [])
1507 m4_combine([, ], [], [-], [a], [b])
1508 m4_combine([, ], [[]], [-], [a], [b])
1509 m4_combine([ a ], [[-], [+]], [a], [-], [+])
1510 m4_combine([$* ], [[$1], [$2]], [$#], [$@])
1512 [[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
1514 a-, b-
1516 -a, -b
1517 -a- a -a+ a +a- a +a+
1518 $1$#$@$* $2$#$@
1519 ]], [])
1521 AT_CLEANUP
1524 ## -------------- ##
1525 ## m4_{max,min}.  ##
1526 ## -------------- ##
1528 AT_SETUP([m4@&t@_max and m4@&t@_min])
1530 AT_DATA_M4SUGAR([script.4s],
1531 [[m4_max
1534 AT_CHECK_M4SUGAR([], 1, [],
1535 [[script.4s:1: error: too few arguments to m4@&t@_max
1536 script.4s:1: the top level
1537 autom4te: m4 failed with exit status: 1
1540 AT_DATA_M4SUGAR([script.4s],
1541 [[m4_min
1544 AT_CHECK_M4SUGAR([], 1, [],
1545 [[script.4s:1: error: too few arguments to m4@&t@_min
1546 script.4s:1: the top level
1547 autom4te: m4 failed with exit status: 1
1550 AT_CHECK_M4SUGAR_TEXT([[dnl
1551 m4_min(0)
1552 m4_min(0xa)
1553 m4_min(0, 0)
1554 m4_min(0, 1)
1555 m4_min(1, 0)
1556 m4_min(0+1, 1+1)
1557 m4_min(0+1, 1+0)
1558 m4_min(0, 1, 2)
1559 m4_min(2, 1, 0)
1560 m4_min(1m4_for([i], 2, 100, , [,i]))
1561 m4_min(m4_for([i], 100, 2, , [i,])1)
1562 ----
1563 m4_max(0)
1564 m4_max(0xa)
1565 m4_max(0, 0)
1566 m4_max(0, 1)
1567 m4_max(1, 0)
1568 m4_max(1+0, 1+1)
1569 m4_max(1+0, 1+0)
1570 m4_max(0, 1, 2)
1571 m4_max(2, 1, 0)
1572 m4_max(1m4_for([i], 2, 100, , [,i]))
1573 m4_max(m4_for([i], 100, 2, , [i,])1)
1586 ----
1598 ]], [])
1600 AT_CLEANUP
1603 ## ----------- ##
1604 ## Recursion.  ##
1605 ## ----------- ##
1607 AT_SETUP([recursion])
1609 AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond
1610 m4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse
1611 m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
1612 m4@&t@_bmatch m4@&t@_map_args m4@&t@_map_args_pair])
1614 dnl This test completes in a reasonable time if m4_foreach is linear,
1615 dnl but thrashes if it is quadratic.  If we are testing with m4 1.4.x,
1616 dnl only the slower foreach.m4 implementation will work.  But if we
1617 dnl are testing with m4 1.6, we can rerun the test with __m4_version__
1618 dnl undefined to exercise the alternate code path.
1619 AT_DATA_M4SUGAR([script.4s],
1620 [[m4_init
1621 m4_divert_push(0)[]dnl
1622 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
1623 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
1624 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
1625 m4_len(m4_joinall([--], m4_map([, m4_echo],
1626   m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
1627 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
1628   [,i]))m4_for([i], [2], [10000], [], [,i]))
1629 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
1630 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
1631   m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
1632 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
1633 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
1634 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
1635 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
1636 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
1637 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
1638 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
1639 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
1640 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
1641   [1], [10000], [], [,i]))))
1642 m4_divert_pop(0)
1645 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1646 9999,10000
1647 78896
1648 58894
1649 10000
1655 ^9998$
1656 9990 9990
1657 5001
1660 AT_DATA_M4SUGAR([script.4s],
1661 [[m4_ifdef([__m4_version__],
1662 [m4_undefine([__m4_version__])],
1663 [m4_divert_push(0)48894
1664 9999,10000
1665 78896
1666 58894
1667 10000
1673 ^9998$
1674 9990 9990
1675 5001
1676 m4_exit([0])])
1677 m4_init
1678 m4_divert_push(0)[]dnl
1679 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
1680 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
1681 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
1682 m4_len(m4_joinall([--], m4_map([, m4_echo],
1683   m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
1684 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
1685   [,i]))m4_for([i], [2], [10000], [], [,i]))
1686 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
1687 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
1688   m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
1689 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
1690 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
1691 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
1692 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
1693 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
1694 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
1695 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
1696 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
1697 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
1698   [1], [10000], [], [,i]))))
1699 m4_divert_pop(0)
1702 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1703 9999,10000
1704 78896
1705 58894
1706 10000
1712 ^9998$
1713 9990 9990
1714 5001
1717 AT_CLEANUP
1720 ## ---------- ##
1721 ## m4_set_*.  ##
1722 ## ---------- ##
1724 AT_SETUP([m4@&t@_set])
1726 AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_contains
1727 m4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dump
1728 m4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_list
1729 m4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_size
1730 m4@&t@_set_union])
1732 # Simple tests
1733 AT_CHECK_M4SUGAR_TEXT([[m4_set_contains([a], [1], [yes], [no])
1734 m4_set_add([a], [1], [added], [dup])
1735 m4_set_contains([a], [1], [yes], [no])
1736 m4_set_add([a], [1], [added], [dup])
1737 m4_set_contents([a])
1738 m4_set_remove([a], [1], [removed], [missing])
1739 m4_set_contains([a], [1], [yes], [no])
1740 m4_set_remove([a], [1], [removed], [missing])
1741 m4_set_add([a], [2], [added], [dup])
1742 m4_set_empty([a], [yes], [no])
1743 m4_set_delete([a])
1744 m4_set_empty([a], [yes], [no])
1745 m4_set_add_all([c], [1], [2], [3])
1746 m4_set_add_all([a]m4_set_listc([c]))
1747 m4_set_contents([c], [-])
1748 m4_set_dump([a], [-])
1749 m4_set_contents([a])
1750 m4_set_add_all([a], [1], [2], [3])m4_set_add_all([b], [3], [], [4])
1751 m4_set_difference([a], [b])
1752 m4_set_difference([b], [a])
1753 m4_set_intersection([a], [b])
1754 m4_set_union([a], [b])
1755 m4_define([printodd], [m4_if(m4_eval([$1 & 1]), [1], [:$1])])dnl
1756 m4_set_map([a], [printodd])
1757 m4_set_foreach([a], [i], [m4_if(m4_eval(i & 1), [1], [m4_set_remove([a], i)])])
1758 m4_set_list([a])
1759 m4_set_add([a], [])
1760 m4_set_list([a])
1761 m4_set_remove([a], [2])
1762 m4_dquote(m4_set_list([a]))
1763 m4_set_listc([a])
1764 m4_set_size([a])
1765 m4_set_delete([a])
1766 m4_dquote(m4_set_list([a]))
1767 m4_indir([m4_dquote]m4_set_listc([a]))
1768 m4_set_listc([a])
1769 m4_set_size([a])
1770 ]], [[no
1771 added
1775 removed
1777 missing
1778 added
1784 1-2-3
1785 3-2-1
1788 ,1,2
1791 ,1,2,3,,4
1792 :1:3
1808 # Stress tests - check for unusual names/values
1809 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
1810 m4_set_add([a], [a])dnl
1811 m4_set_remove([a], [oops], [yes], [no])
1812 m4_set_add([a,b], [c])dnl
1813 m4_set_add([a,b], [$*[]])dnl
1814 m4_set_add_all([a], [b,c])dnl
1815 m4_set_size([a])
1816 m4_count(m4_set_contents([a], [,]))
1817 m4_count(m4_set_list([a], [,]))
1818 m4_set_dump([a], [,])
1819 m4_set_contents([a,b], [,])
1820 m4_set_list([a,b])
1821 m4_set_foreach([$*[]], [$*[]], [oops])
1822 m4_set_add([$*[]], [])dnl
1823 m4_set_remove([$*[]], [a], [yes], [no])
1824 m4_set_add([$*[]], [a])dnl
1825 m4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-])
1826 m4_set_remove([$*[]], [], [yes], [no])
1827 m4_set_add([c], [,])dnl
1828 m4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):])
1829 ]],[[no
1833 b,c,a
1834 c,$*[]
1835 c,$*[]
1838 ---aoops-
1840 :,,::,a:
1843 # Stress tests - check for linear scaling (won't necessarily fail if
1844 # quadratic, but hopefully users will complain if it appears to hang)
1845 AT_CHECK_M4SUGAR_TEXT([[dnl
1846 m4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnl
1847 m4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnl
1848 m4_set_remove([a], [1])dnl
1849 m4_set_remove([b], [10000])dnl
1850 m4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnl
1851 m4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnl
1852 m4_len(m4_set_contents([a]))
1853 m4_len(m4_set_foreach([b], [b], [m4_if(m4_eval(b & 1), [1],
1854   [m4_set_remove([b], b, [-])])]))
1855 m4_set_size([b])
1856 m4_define([prune3x], [m4_if(m4_eval([$1 % 3]), [0],
1857   [m4_set_remove([a], [$1], [-])])])dnl
1858 m4_len(m4_set_map([a], [prune3x]))
1859 m4_count(m4_shift(m4_set_intersection([a], [b])))
1860 ]], [[38894
1861 5000
1862 5000
1863 3333
1864 3334
1867 AT_CLEANUP