Rewrite handling of diversion and expansion stack.
[autoconf.git] / tests / m4sugar.at
blob1dff27058872ae39985b17149063fade6c31aa0b
1 #                                                       -*- Autotest -*-
3 AT_BANNER([M4sugar.])
5 # Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software
6 # 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_foreach])
46 AT_KEYWORDS([m4@&t@_stack_foreach_lifo m4@&t@_copy m4@&t@_n])
48 # Test the semantics of macros to walk stacked macro definitions.
49 AT_CHECK_M4SUGAR_TEXT([[dnl
50 m4_pushdef([abc], [def])dnl
51 m4_pushdef([abc], [ghi])dnl
52 m4_pushdef([abc], [jkl])dnl
53 m4_stack_foreach([abc], [m4_n])
54 abc
55 m4_stack_foreach_lifo([abc], [m4_n])
56 m4_stack_foreach([abc], [m4_n])
57 m4_copy([abc], [foo])dnl
58 m4_stack_foreach([foo], [m4_n])
59 m4_stack_foreach_lifo([foo], [m4_n])
60 m4_pushdef([xyz], [123])dnl
61 m4_pushdef([xyz], [456])dnl
62 m4_define([doit], [[$1](m4_shift(m4_stack_foreach([xyz], [,m4_echo])))
63 ])dnl
64 m4_stack_foreach([abc], [doit])]],
65 [[def
66 ghi
67 jkl
69 jkl
70 jkl
71 ghi
72 def
74 def
75 ghi
76 jkl
78 def
79 ghi
80 jkl
82 jkl
83 ghi
84 def
86 def(123,456)
87 ghi(123,456)
88 jkl(123,456)
89 ]])
91 AT_CLEANUP
94 ## --------- ##
95 ## m4_defn.  ##
96 ## --------- ##
98 AT_SETUP([m4@&t@_defn])
100 AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine m4@&t@_copy m4@&t@_rename])
102 # Ensure that m4sugar dies when dereferencing undefined macros, whether
103 # this is provided by m4 natively or faked by wrappers in m4sugar.
105 AT_DATA_M4SUGAR([script.4s],
106 [[m4_define([good])
107 m4_defn([good], [oops])
110 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
111 AT_CHECK([grep good stderr], [1])
112 AT_CHECK([grep 'm4@&t@_defn: undefined.*oops' stderr], [0], [ignore])
114 AT_DATA_M4SUGAR([script.4s],
115 [[m4_define([good])
116 m4_popdef([good], [oops])
119 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
120 AT_CHECK([grep good stderr], [1])
121 AT_CHECK([grep 'm4@&t@_popdef: undefined.*oops' stderr], [0], [ignore])
123 AT_DATA_M4SUGAR([script.4s],
124 [[m4_define([good])
125 m4_undefine([good], [oops])
128 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
129 AT_CHECK([grep good stderr], [1])
130 AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])
132 # Check that pushdef stacks can be renamed.
133 AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl
134 m4_pushdef([a], [2])dnl
135 a b c
136 m4_rename([a], [b])dnl
137 a b c
138 m4_copy([b], [c])dnl
139 a b c
140 m4_popdef([b], [c])dnl
141 a b c
142 m4_popdef([b], [c])dnl
143 a b c
144 ]], [[2 b c
145 a 2 c
146 a 2 2
147 a 1 1
148 a b c
151 AT_CLEANUP
154 ## ------------ ##
155 ## m4_dumpdef.  ##
156 ## ------------ ##
158 AT_SETUP([m4@&t@_dumpdef])
160 AT_KEYWORDS([m4@&t@_dumpdefs])
162 # Ensure that m4sugar dies when dereferencing undefined macros.
164 AT_DATA_M4SUGAR([script.4s],
165 [[m4_define([good], [yep])
166 m4_dumpdef([good], [oops])
169 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
170 AT_CHECK([grep '^good:  \[[yep\]]$' stderr], [0], [ignore])
171 AT_CHECK([grep 'm4@&t@_dumpdef: undefined.*oops' stderr], [0], [ignore])
173 # Check that pushdef stacks can be dumped.
174 AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL])
175 m4_pushdef([a], [1])
176 m4_pushdef([a], [2])
177 m4_dumpdef([a])
178 m4_dumpdefs([a])
179 m4_dumpdefs([oops])
180 m4_divert_pop([KILL])dnl
181 ]], [],
182 [[a:    [2]
183 a:      [2]
184 a:      [1]
187 AT_CLEANUP
190 ## --------- ##
191 ## m4_warn.  ##
192 ## --------- ##
194 AT_SETUP([m4@&t@_warn])
196 # m4_text_wrap is used to display the help strings.  Also, check that
197 # commas are not swallowed.  This can easily happen because of
198 # m4-listification.
200 # FIXME: For the time being we use -f to make sure we do issue the
201 # warnings.  But maybe autom4te should handle that by itself?
203 AT_DATA_M4SUGAR([script.4s],
204 [[m4_init
205 m4_defun([cross_warning], [m4_warn([cross],  [cross])])
207 m4_divert([0])dnl
208 m4_warn([obsolete],  [obsolete])dnl
209 cross_warning[]dnl
210 m4_warn([syntax], [syntax])dnl
213 AT_CHECK_M4SUGAR([-o-], 0, [],
214 [script.4s:7: warning: syntax
217 AT_CHECK_M4SUGAR([-o- -Wall -f], 0, [],
218 [script.4s:5: warning: obsolete
219 script.4s:6: warning: cross
220 script.4s:2: cross_warning is expanded from...
221 script.4s:6: the top level
222 script.4s:7: warning: syntax
225 AT_CHECK_M4SUGAR([-o- -Wnone,cross -f], 0, [],
226 [script.4s:6: warning: cross
227 script.4s:2: cross_warning is expanded from...
228 script.4s:6: the top level
231 AT_CHECK_M4SUGAR([-o- -Wnone,cross,error -f], 1, [],
232 [[script.4s:6: warning: cross
233 script.4s:2: cross_warning is expanded from...
234 script.4s:6: the top level
237 AT_CLEANUP
240 ## --------------------------- ##
241 ## m4_require: error message.  ##
242 ## --------------------------- ##
244 AT_SETUP([m4@&t@_require: error message])
246 AT_DATA_M4SUGAR([script.4s],
247 [[m4_defun([foo], [FOO])
248 m4_require([foo])
251 AT_CHECK_M4SUGAR([], 1, [],
252 [[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro
253 script.4s:2: the top level
254 autom4te: m4 failed with exit status: 1
256 AT_CLEANUP
259 ## ----------------------------------- ##
260 ## m4_require: circular dependencies.  ##
261 ## ----------------------------------- ##
263 AT_SETUP([m4@&t@_require: circular dependencies])
265 AT_DATA_M4SUGAR([script.4s],
266 [[m4_defun([foo], [m4_require([bar])])
268 m4_defun([bar], [m4_require([foo])])
270 m4_defun([baz], [m4_require([foo])])
272 m4_init
273 m4_divert([0])dnl
277 AT_CHECK_M4SUGAR([], 1, [],
278 [[script.4s:9: error: m4@&t@_require: circular dependency of foo
279 script.4s:3: bar is expanded from...
280 script.4s:1: foo is expanded from...
281 script.4s:5: baz is expanded from...
282 script.4s:9: the top level
283 autom4te: m4 failed with exit status: 1
285 AT_CLEANUP
288 ## ---------------------- ##
289 ## m4_require: one-shot.  ##
290 ## ---------------------- ##
292 AT_SETUP([m4@&t@_require: one-shot initialization])
293 AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy])
295 AT_CHECK_M4SUGAR_TEXT([[
296 m4_defun_init([a], [[init a
297 ]], [[common a]])dnl
298 m4_defun([b], [[b]m4_require([a])])dnl
299 m4_defun([c], [[c]m4_require([a])])dnl
303 m4_defun_init([-], [hello, ], [m4_if([$#], [0], [world], [[$1]])])dnl
304 m4_copy([-], [.])dnl
305 m4_indir([.])
306 m4_indir([.], [goodbye])
307 m4_indir([-], [again])
308 ]], [[
309 init a
310 common a
313 common a
314 hello, world
315 goodbye
316 hello, again
318 AT_CLEANUP
321 ## --------- ##
322 ## m4_cond.  ##
323 ## --------- ##
325 AT_SETUP([m4@&t@_cond])
327 AT_CHECK_M4SUGAR_TEXT([[m4_define([side], [m4_errprintn([$1])$1])
328 m4_cond([side(1)], [1], [a],
329         [side(1)], [1], [b],
330         [side(1)], [2], [c])
331 m4_cond([side(2)], [1], [a],
332         [side(2)], [1], [b],
333         [side(2)], [2], [c],
334         [side(2)])
335 m4_cond([side(3)], [1], [a],
336         [side(3)], [1], [b],
337         [side(3)], [2], [c],
338         [side(3)])
339 m4_cond([a,a], [a,a], [yes], [no])
340 m4_cond([[a,a]], [a,a], [yes])
341 m4_cond([a,a], [a,b], [yes], [no])
342 m4_cond([a,a], [a,b], [yes])
343 m4_cond([m4_eval([0xa])])
344 m4_define([ab], [AB])dnl
345 m4_cond([a])b
346 m4_cond([1], [1], [a])b
347 m4_cond([1], [2], [3], [a])b
348 ]], [[
360 ]], [[1
370 AT_CLEANUP
373 ## ---------- ##
374 ## m4_split.  ##
375 ## ---------- ##
377 AT_SETUP([m4@&t@_split])
379 AT_CHECK_M4SUGAR_TEXT(
380 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
381 m4_split
382 m4_split([[]])
383 m4_split([ ])
384 m4_split([active])
385 m4_split([ active       active ])end
386 m4_split([ ], [ ])
387 m4_split([active], [ ])
388 m4_split([ active       active ], [ ])end
389 m4_split([abcde], [bd])
390 m4_split([abcde], [[bd]])
391 m4_split([foo=`` bar=''])
392 m4_split([foo='' bar=``])
393 dnl these next two are from the manual; keep this in sync if the internal
394 dnl quoting strings in m4_split are changed
395 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
396 m4_split([a )}>=- b -=<{( c])
397 m4_split([a )}@&t@>=- b -=<@&t@{( c])
401 [[]]
402 [], []
403 [active]
404 [], [active], [active], []end
405 [], []
406 [active]
407 [], [active     active], []end
408 [abcde]
409 [a], [c], [e]
410 [foo=``], [bar='']
411 [foo=''], [bar=``]
412 [a], [], [B], [], [c]
413 [a], [)}>=-], [b], [-=<{(], [c]
416 AT_CLEANUP
419 ## ------- ##
420 ## m4_do.  ##
421 ## ------- ##
423 AT_SETUP([m4@&t@_do])
425 AT_CHECK_M4SUGAR_TEXT(
426 [[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl
427 m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl
428 m4_do
429 m4_do([a])
430 m4_do([a], [b])c
431 m4_unquote(m4_join([], [a], [b]))c
432 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
433 m4_do([a], [b])c
434 m4_unquote(m4_join([], [a], [b]))c
444 AT_CLEANUP
447 ## ----------- ##
448 ## m4_append.  ##
449 ## ----------- ##
451 AT_SETUP([m4@&t@_append])
453 AT_CHECK_M4SUGAR_TEXT(
454 [[m4_define([active], [ACTIVE])dnl
455 m4_append([sentence], [This is an])dnl
456 m4_append([sentence], [ active ])dnl
457 m4_append([sentence], [symbol.])dnl
458 sentence
459 m4_undefine([active])dnl
460 sentence
461 m4_define([active], [ACTIVE])dnl
462 m4_append([hooks], [m4_define([act1], [act2])])dnl
463 m4_append([hooks], [m4_define([act2], [active])])dnl
464 m4_undefine([active])dnl
465 act1
466 hooks
467 act1
468 dnl Test for bug fixed in 2.62 when separator is active.
469 m4_define([a], [A])dnl
470 m4_append_uniq([foo], [-], [a])dnl
471 m4_append_uniq([foo], [-], [a])dnl
472 m4_append_uniq([bar], [-], [a])dnl
473 m4_append_uniq([bar], [~], [a])dnl
474 m4_append_uniq([bar], [-], [a])dnl
475 m4_defn([foo])
476 m4_defn([bar])
479 m4_append_uniq([blah], [one], [, ], [new], [existing])
480 m4_append_uniq([blah], [two], [, ], [new], [existing])
481 m4_append_uniq([blah], [two], [, ], [new], [existing])
482 m4_append_uniq([blah], [three], [, ], [new], [existing])
483 m4_append([blah], [two], [, ])dnl
484 blah
485 m4_dquote(blah)
486 m4_append([list], [one], [[, ]])dnl
487 m4_append([list], [two], [[, ]])dnl
488 m4_append([list], [three], [[, ]])dnl
489 list
490 m4_dquote(list)
491 m4_append_uniq_w([numbers], [1 1 2])dnl
492 m4_append_uniq_w([numbers], [ 2 3 ])dnl
493 numbers
495 [[This is an ACTIVE symbol.
496 This is an active symbol.
497 act1
499 active
506 existing
508 one, two, three, two
509 [one],[two],[three],[two]
510 one, two, three
511 [one, two, three]
512 1 2 3
515 AT_DATA_M4SUGAR([script.4s],
516 [[m4_init[]dnl
517 m4_append_uniq([str], [a], [ ])
518 m4_append_uniq([str], [a b], [ ])
519 m4_divert([0])dnl
523 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
524 ]], [[script.4s:3: warning: m4@&t@_append_uniq: `a b' contains ` '
527 AT_CLEANUP
530 ## --------- ##
531 ## m4_join.  ##
532 ## --------- ##
534 AT_SETUP([m4@&t@_join])
536 AT_KEYWORDS([m4@&t@_joinall])
538 AT_CHECK_M4SUGAR_TEXT(
539 [[m4_define([active], [ACTIVE])
540 m4_join
541 m4_join([|])
542 m4_join([, ], [one], [two])
543 m4_dquote(m4_join([, ], [one], [two]))
544 m4_join([|], [active], [active])
545 m4_join([|], ,,,[one])
546 m4_join([|], [one],,,)
547 m4_join([], ,,,[two])
548 m4_join([], [two],,,)
549 m4_join([ active ], [one], , [two])
550 m4_join([], [one], [two])
551 m4_joinall([-], [one], [], [two])
552 m4_joinall([-], [], [], [three], [], [])
553 m4_joinall([], [one], [], [two])
554 m4_joinall
555 m4_joinall([-])
556 m4_joinall([-], [one])
561 one, two
562 [one, two]
563 active|active
568 one active two
569 onetwo
570 one--two
571 --three--
572 onetwo
578 AT_CLEANUP
581 ## -------------- ##
582 ## m4_text_wrap.  ##
583 ## -------------- ##
585 AT_SETUP([m4@&t@_text_wrap])
587 # m4_text_wrap is used to display the help strings.  Also, check that
588 # commas and $ are not swallowed.  This can easily happen because of
589 # m4-listification.
591 AT_DATA_M4SUGAR([script.4s],
592 [[m4_init[]m4_divert([0])dnl
593 m4_text_wrap([Short string */], [   ], [/* ], 20)
595 m4_text_wrap([Much longer string */], [   ], [/* ], 20)
597 m4_text_wrap([Short doc.], [          ], [  --short ], 30)
599 m4_text_wrap([Short doc.], [          ], [  --too-wide], 30)
601 m4_text_wrap([Super long documentation.], [          ], [  --too-wide], 30)
603 m4_text_wrap([First, second  , third, [,quoted]])
604 m4_define([xfff], [oops])
605 m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
608 AT_DATA([expout],
609 [[/* Short string */
611 /* Much longer
612    string */
614   --short Short doc.
616   --too-wide
617           Short doc.
619   --too-wide
620           Super long
621           documentation.
623 First, second , third, [,quoted]
625  $@ Some $1 $2 $3
626  $* $4 embedded
627  $* dollars.
630 AT_CHECK_M4SUGAR([-o-], 0, [expout])
632 AT_CLEANUP
634 ## -------------------- ##
635 ## m4_version_compare.  ##
636 ## -------------------- ##
638 AT_SETUP([m4@&t@_version_compare])
640 AT_KEYWORDS([m4@&t@_list_cmp])
642 AT_CHECK_M4SUGAR_TEXT(
643 [[m4_version_compare([1.1], [2.0])
644 m4_version_compare([2.0b], [2.0a])
645 m4_version_compare([2.0z], [2.0y])
646 m4_version_compare([1.1.1], [1.1.1a])
647 m4_version_compare([1.2], [1.1.1a])
648 m4_version_compare([1.0], [1])
649 m4_version_compare([1.0a], [1.0a])
650 m4_version_compare([1.1a], [1.1a.1])
651 m4_version_compare([1.10], [1.1a])
652 m4_version_compare([1-1a], [1,1A])
653 m4_define([a], [oops])dnl
654 m4_version_compare([1.1a], [1.1A])
655 m4_version_compare([1z], [1aa])
656 m4_version_compare([2.61a], [2.61a-248-dc51])
657 m4_version_compare([2.61b], [2.61a-248-dc51])
658 dnl Test that side effects to m4_list_cmp occur exactly once
659 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
660             [[0], [0], [0]m4_errprintn([hi])])
661 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
662             [[0], [0], [0]m4_errprintn([bye])])
664 [[-1
680 ]], [[hi
686 AT_CLEANUP
688 ## ------------------------------ ##
689 ## Standard regular expressions.  ##
690 ## ------------------------------ ##
692 AT_SETUP([Standard regular expressions])
694 # AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = `ok' | `')
695 # ------------------------------------------------
696 # Check whether RE-NAME (a macro whose definition is a regular expression)
697 # matches TEXT.  INTENT = `ok' if the match should succeed or else empty.
698 m4_define([AT_CHECK_M4RE],
699 [AT_CHECK_M4SUGAR_TEXT(
700 [[m4_bregexp([$2], ^m4_defn([$1])$, [ok])
701 ]], [$3
702 ])])
704 AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok])
705 AT_CHECK_M4RE([m4_re_word], [_9abc], [ok])
706 AT_CHECK_M4RE([m4_re_word], [9ab_c])
708 AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok])
709 AT_CHECK_M4RE([m4_re_string], [_9abc], [ok])
710 AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok])
711 AT_CHECK_M4RE([m4_re_string], [9a@_c])
713 AT_CLEANUP
715 ## ----------- ##
716 ## m4_bmatch.  ##
717 ## ----------- ##
719 AT_SETUP([m4@&t@_bmatch])
721 AT_CHECK_M4SUGAR_TEXT(
722 [[m4_bmatch([abc], [default\])
723 m4_bmatch([abc], [^a], [yes])
724 m4_bmatch([abc], [^a], [yes], [no])
725 m4_bmatch([abc], [^.a], [yes])
726 m4_bmatch([abc], [^.a], [yes], [no\])
727 m4_bmatch([abc], [a], [1], [b], [2])
728 m4_bmatch([abc], [A], [1], [b], [2])
729 m4_define([ab], [AB])dnl
730 m4_bmatch([$*], [a])b
731 m4_bmatch([$*], [\*], [a])b
732 m4_bmatch([$*], [1], [2], [a])b
733 ]], [[default\
745 AT_CLEANUP
747 ## --------------- ##
748 ## m4_bpatsubsts.  ##
749 ## --------------- ##
751 AT_SETUP([m4@&t@_bpatsubsts])
753 AT_CHECK_M4SUGAR_TEXT(
754 [[m4_bpatsubsts([11], [^..$])
755 m4_bpatsubsts([11], [\(.\)1], [\12])
756 m4_bpatsubsts([11], [^..$], [], [1], [2])
757 m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3])
758 m4_define([a], [oops])m4_define([c], [oops])dnl
759 m4_define([AB], [good])m4_define([bc], [good])dnl
760 m4_bpatsubsts([abc], [a], [A], [b], [B], [c])
761 m4_bpatsubsts([ab], [a])c
762 m4_bpatsubsts([ab], [c], [C], [a])c
763 m4_bpatsubsts([$1$*$@], [\$\*], [$#])
764 ]], [[11
768 good
769 good
770 good
771 $1$#$@
774 AT_CLEANUP
776 ## ---------- ##
777 ## M4 Loops.  ##
778 ## ---------- ##
780 AT_SETUP([M4 loops])
782 AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w])
784 AT_CHECK_M4SUGAR_TEXT([[dnl
785 m4_define([myvar], [outer value])dnl
786 m4_for([myvar], 1, 3, 1, [ myvar])
787 m4_for([myvar], 1, 3,  , [ myvar])
788 m4_for([myvar], 3, 1,-1, [ myvar])
789 m4_for([myvar], 3, 1,  , [ myvar])
790 m4_for([myvar], 1, 3, 2, [ myvar])
791 m4_for([myvar], 3, 1,-2, [ myvar])
792 m4_for([myvar],-1,-3,-2, [ myvar])
793 m4_for([myvar],-3,-1, 2, [ myvar])
794 dnl Make sure we recalculate the bounds correctly:
795 m4_for([myvar], 1, 3, 3, [ myvar])
796 m4_for([myvar], 1, 6, 3, [ myvar])
797 m4_for([myvar],22,-7,-5, [ myvar])
798 m4_for([myvar],-2,-7,-4, [ myvar])
799 m4_for([myvar],-7,-2, 4, [ myvar])
800 dnl Make sure we are not exposed to division truncation:
801 m4_for([myvar], 2, 5, 2, [ myvar])
802 m4_for([myvar],-5,-2, 2, [ myvar])
803 m4_for([myvar], 5, 2,-2, [ myvar])
804 m4_for([myvar],-2,-5,-2, [ myvar])
805 dnl Make sure we do not divide by zero:
806 m4_for([myvar], 1, 1,  , [ myvar])
807 m4_for([myvar], 1, 1,+2, [ myvar])
808 m4_for([myvar], 1, 1,-2, [ myvar])
809 dnl Make sure we do not loop endlessly
810 m4_for([myval], 1, 1, 0, [ myval])
811 dnl Make sure to properly parenthesize
812 m4_for([myvar], 3-5, -2+8, , [ myvar])
813 m4_for([myvar], -2+8, 3-5, , [ myvar])
814 m4_for([myvar], 8, 16, 3 * 2, [ myvar])
815 m4_for([myvar], 8, 16, -3 * -2, [ myvar])
816 m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar])
817 dnl Modifying var does not affect the number of iterations
818 m4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)])
819 dnl Make sure we can do nameless iteration
820 m4_for(, 1, 10, , -)
821 dnl foreach tests
822 m4_foreach([myvar], [[a], [b, c], [d], [e
823 ],[f]], [ myvar|])
824 m4_foreach_w([myvar], [a  b c, d,e f
825 g], [ myvar|])
826 myvar
827 dnl only one side effect expansion, prior to visiting list elements
828 m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
829 dnl shifting forms an important part of loops
830 m4_shift3:m4_shift3(1,2,3):m4_shift3(1,2,3,4)
831 m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
833 [[ 1 2 3
834  1 2 3
835  3 2 1
836  3 2 1
837  1 3
838  3 1
839  -1 -3
840  -3 -1
842  1 4
843  22 17 12 7 2 -3
844  -2 -6
845  -7 -3
846  2 4
847  -5 -3
848  5 3
849  -2 -4
854  -2 -1 0 1 2 3 4 5 6
855  6 5 4 3 2 1 0 -1 -2
856  8 14
857  8 14
858  8 14
859  1 2 3 4 5
860 ----------
861  a| b, c| d| e
862 | f|
863  a| b| c,| d,e| f| g|
864 outer value
867 ]], [[hi
873 dnl bounds checking in m4_for
874 AT_DATA_M4SUGAR([script.4s],
875 [[m4_init
876 m4_divert([0])dnl
877 m4_for([myvar], 1, 3,-1, [ myvar])
879 AT_CHECK_M4SUGAR([], 1, [],
880 [[script.4s:3: error: assert failed: -1 > 0
881 script.4s:3: the top level
882 autom4te: m4 failed with exit status: 1
885 AT_DATA_M4SUGAR([script.4s],
886 [[m4_init
887 m4_divert([0])dnl
888 m4_for([myvar], 1, 2, 0, [ myvar])
890 AT_CHECK_M4SUGAR([], 1, [],
891 [[script.4s:3: error: assert failed: 0 > 0
892 script.4s:3: the top level
893 autom4te: m4 failed with exit status: 1
896 AT_DATA_M4SUGAR([script.4s],
897 [[m4_init
898 m4_divert([0])dnl
899 m4_for([myvar], 2, 1, 0, [ myvar])
901 AT_CHECK_M4SUGAR([], 1, [],
902 [[script.4s:3: error: assert failed: 0 < 0
903 script.4s:3: the top level
904 autom4te: m4 failed with exit status: 1
907 dnl m4_shiftn also does bounds checking
908 AT_DATA_M4SUGAR([script.4s],
909 [[m4_init
910 m4_divert([0])dnl
911 m4_shiftn(3,1,2)
913 AT_CHECK_M4SUGAR([], 1, [],
914 [[script.4s:3: error: assert failed: 0 < 3 && 3 < 3
915 script.4s:3: the top level
916 autom4te: m4 failed with exit status: 1
919 AT_CLEANUP
922 ## --------------------- ##
923 ## m4_map{,all}{,_sep}.  ##
924 ## --------------------- ##
926 AT_SETUP([m4@&t@_map])
927 AT_KEYWORDS([m4@&t@_apply m4@&t@_map_sep m4@&t@_mapall m4@&t@_mapall_sep])
928 AT_KEYWORDS([m4@&t@_count])
930 AT_CHECK_M4SUGAR_TEXT([[dnl
931 m4_map([m4_count], [])
932 m4_map([ m4_count], [[],
933                      [[1]],
934                      [[1], [2]]])
935 m4_mapall([ m4_count], [[],
936                         [[1]],
937                         [[1], [2]]])
938 m4_map_sep([m4_eval], [,], [[[1+2]],
939                             [[10], [16]]])
940 m4_count(m4_map_sep([m4_echo], [,], [[], [[1]], [[2]]]))
941 m4_count(m4_mapall_sep([m4_echo], [,], [[], [[1]], [[2]]]))
942 m4_map_sep([m4_eval], [[,]], [[[1+2]],
943                               [[10], [16]]])
944 m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
945 m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
946 m4_map([-], [[]])
947 m4_mapall([-], [[]])
948 m4_map_sep([-], [:], [[]])
949 m4_mapall_sep([-], [:], [[]])
950 m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl
951 m4_define([a1], [oops])dnl
952 m4_define([pass1], [oops])dnl
953 m4_map([a], [[[a]]])1
954 m4_map([m4_unquote([a])], [m4_dquote([a])])
955 dnl only one side effect expansion, prior to visiting list elements
956 m4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
957 m4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
958 m4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
959 m4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
962  1 2
963  0 1 2
974 pass1
975 pass
976 ]], [[hi
994 AT_CLEANUP
997 ## ---------------------------------- ##
998 ## m4_map_args{,_pair} and m4_curry.  ##
999 ## ---------------------------------- ##
1001 AT_SETUP([m4@&t@_map_args and m4@&t@_curry])
1002 AT_KEYWORDS([m4@&t@_map_args_pair m4@&t@_reverse])
1004 dnl First, make sure we can curry in isolation.
1005 AT_CHECK_M4SUGAR_TEXT(
1006 [[m4_curry([m4_echo])([1])
1007 m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
1008 m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1009 m4_define([add_one], [m4_curry([add], [1])])dnl
1010 add_one()([4])
1013 3, 2, 1
1017 dnl Now, check that we can map a list of arguments.
1018 AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnl
1019 m4_map_args([ m4_echo])
1020 m4_map_args([ m4_echo], [plain], [active])
1021 m4_map_args([m4_unquote], [plain], [active])
1022 m4_map_args_pair([, m4_reverse], [])
1023 m4_map_args_pair([, m4_reverse], [], [1])
1024 m4_map_args_pair([, m4_reverse], [], [1], [2])
1025 m4_map_args_pair([, m4_reverse], [], [1], [2], [3])
1026 m4_map_args_pair([, m4_reverse], [], [1], [2], [3], [4])
1027 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1])
1028 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2])
1029 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3])
1030 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
1033  plain active
1034 plainACTIVE
1036 , 1
1037 , 2, 1
1038 , 2, 1, 3
1039 , 2, 1, 4, 3
1040 , [1]
1041 , 2, 1
1042 , 2, 1, [3]
1043 , 2, 1, 4, 3
1046 dnl Finally, put the two concepts together, to show the real power of the API.
1047 AT_CHECK_M4SUGAR_TEXT(
1048 [[m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1049 m4_define([list], [[-1], [0], [1]])dnl
1050 dnl list_add_n(value, arg...)
1051 dnl add VALUE to each ARG and output the resulting list
1052 m4_define([list_add_n],
1053   [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))])
1054 list_add_n([1], list)
1055 list_add_n([2], list)
1056 ]], [[
1057 0,1,2
1058 1,2,3
1061 AT_CLEANUP
1064 ## ------------ ##
1065 ## m4_combine.  ##
1066 ## ------------ ##
1068 AT_SETUP([m4@&t@_combine])
1070 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
1071 m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
1072 m4_combine([, ], [[a], [b]], [-])
1073 m4_combine([, ], [[a], [b]], [-], [])
1074 m4_combine([, ], [], [-], [a], [b])
1075 m4_combine([, ], [[]], [-], [a], [b])
1076 m4_combine([ a ], [[-], [+]], [a], [-], [+])
1077 m4_combine([$* ], [[$1], [$2]], [$#], [$@])
1079 [[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
1081 a-, b-
1083 -a, -b
1084 -a- a -a+ a +a- a +a+
1085 $1$#$@$* $2$#$@
1086 ]], [])
1088 AT_CLEANUP
1091 ## -------------- ##
1092 ## m4_{max,min}.  ##
1093 ## -------------- ##
1095 AT_SETUP([m4@&t@_max and m4@&t@_min])
1097 AT_DATA_M4SUGAR([script.4s],
1098 [[m4_max
1101 AT_CHECK_M4SUGAR([], 1, [],
1102 [[script.4s:1: error: too few arguments to m4@&t@_max
1103 script.4s:1: the top level
1104 autom4te: m4 failed with exit status: 1
1107 AT_DATA_M4SUGAR([script.4s],
1108 [[m4_min
1111 AT_CHECK_M4SUGAR([], 1, [],
1112 [[script.4s:1: error: too few arguments to m4@&t@_min
1113 script.4s:1: the top level
1114 autom4te: m4 failed with exit status: 1
1117 AT_CHECK_M4SUGAR_TEXT([[dnl
1118 m4_min(0)
1119 m4_min(0xa)
1120 m4_min(0, 0)
1121 m4_min(0, 1)
1122 m4_min(1, 0)
1123 m4_min(0+1, 1+1)
1124 m4_min(0+1, 1+0)
1125 m4_min(0, 1, 2)
1126 m4_min(2, 1, 0)
1127 m4_min(1m4_for([i], 2, 100, , [,i]))
1128 m4_min(m4_for([i], 100, 2, , [i,])1)
1129 ----
1130 m4_max(0)
1131 m4_max(0xa)
1132 m4_max(0, 0)
1133 m4_max(0, 1)
1134 m4_max(1, 0)
1135 m4_max(1+0, 1+1)
1136 m4_max(1+0, 1+0)
1137 m4_max(0, 1, 2)
1138 m4_max(2, 1, 0)
1139 m4_max(1m4_for([i], 2, 100, , [,i]))
1140 m4_max(m4_for([i], 100, 2, , [i,])1)
1153 ----
1165 ]], [])
1167 AT_CLEANUP
1170 ## ----------- ##
1171 ## Recursion.  ##
1172 ## ----------- ##
1174 AT_SETUP([recursion])
1176 AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond
1177 m4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse
1178 m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
1179 m4@&t@_bmatch m4@&t@_map_args m4@&t@_map_args_pair])
1181 dnl This test completes in a reasonable time if m4_foreach is linear,
1182 dnl but thrashes if it is quadratic.  If we are testing with m4 1.4.x,
1183 dnl only the slower foreach.m4 implementation will work.  But if we
1184 dnl are testing with m4 1.6, we can rerun the test with __m4_version__
1185 dnl undefined to exercise the alternate code path.
1186 AT_DATA_M4SUGAR([script.4s],
1187 [[m4_init
1188 m4_divert_push(0)[]dnl
1189 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
1190 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
1191 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
1192 m4_len(m4_joinall([--], m4_map([, m4_echo],
1193   m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
1194 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
1195   [,i]))m4_for([i], [2], [10000], [], [,i]))
1196 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
1197 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
1198   m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
1199 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
1200 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
1201 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
1202 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
1203 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
1204 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
1205 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
1206 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
1207 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
1208   [1], [10000], [], [,i]))))
1209 m4_divert_pop(0)
1212 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1213 9999,10000
1214 78896
1215 58894
1216 10000
1222 ^9998$
1223 9990 9990
1224 5001
1227 AT_DATA_M4SUGAR([script.4s],
1228 [[m4_ifdef([__m4_version__],
1229 [m4_undefine([__m4_version__])],
1230 [m4_divert_push(0)48894
1231 9999,10000
1232 78896
1233 58894
1234 10000
1240 ^9998$
1241 9990 9990
1242 5001
1243 m4_exit([0])])
1244 m4_init
1245 m4_divert_push(0)[]dnl
1246 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
1247 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
1248 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
1249 m4_len(m4_joinall([--], m4_map([, m4_echo],
1250   m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
1251 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
1252   [,i]))m4_for([i], [2], [10000], [], [,i]))
1253 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
1254 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
1255   m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
1256 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
1257 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
1258 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
1259 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
1260 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
1261 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
1262 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
1263 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
1264 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
1265   [1], [10000], [], [,i]))))
1266 m4_divert_pop(0)
1269 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1270 9999,10000
1271 78896
1272 58894
1273 10000
1279 ^9998$
1280 9990 9990
1281 5001
1284 AT_CLEANUP
1287 ## ---------- ##
1288 ## m4_set_*.  ##
1289 ## ---------- ##
1291 AT_SETUP([m4@&t@_set])
1293 AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_contains
1294 m4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dump
1295 m4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_list
1296 m4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_size
1297 m4@&t@_set_union])
1299 # Simple tests
1300 AT_CHECK_M4SUGAR_TEXT([[m4_set_contains([a], [1], [yes], [no])
1301 m4_set_add([a], [1], [added], [dup])
1302 m4_set_contains([a], [1], [yes], [no])
1303 m4_set_add([a], [1], [added], [dup])
1304 m4_set_contents([a])
1305 m4_set_remove([a], [1], [removed], [missing])
1306 m4_set_contains([a], [1], [yes], [no])
1307 m4_set_remove([a], [1], [removed], [missing])
1308 m4_set_add([a], [2], [added], [dup])
1309 m4_set_empty([a], [yes], [no])
1310 m4_set_delete([a])
1311 m4_set_empty([a], [yes], [no])
1312 m4_set_add_all([c], [1], [2], [3])
1313 m4_set_add_all([a]m4_set_listc([c]))
1314 m4_set_contents([c], [-])
1315 m4_set_dump([a], [-])
1316 m4_set_contents([a])
1317 m4_set_add_all([a], [1], [2], [3])m4_set_add_all([b], [3], [], [4])
1318 m4_set_difference([a], [b])
1319 m4_set_difference([b], [a])
1320 m4_set_intersection([a], [b])
1321 m4_set_union([a], [b])
1322 m4_define([printodd], [m4_if(m4_eval([$1 & 1]), [1], [:$1])])dnl
1323 m4_set_map([a], [printodd])
1324 m4_set_foreach([a], [i], [m4_if(m4_eval(i & 1), [1], [m4_set_remove([a], i)])])
1325 m4_set_list([a])
1326 m4_set_add([a], [])
1327 m4_set_list([a])
1328 m4_set_remove([a], [2])
1329 m4_dquote(m4_set_list([a]))
1330 m4_set_listc([a])
1331 m4_set_size([a])
1332 m4_set_delete([a])
1333 m4_dquote(m4_set_list([a]))
1334 m4_indir([m4_dquote]m4_set_listc([a]))
1335 m4_set_listc([a])
1336 m4_set_size([a])
1337 ]], [[no
1338 added
1342 removed
1344 missing
1345 added
1351 1-2-3
1352 3-2-1
1355 ,1,2
1358 ,1,2,3,,4
1359 :1:3
1375 # Stress tests - check for unusual names/values
1376 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
1377 m4_set_add([a], [a])dnl
1378 m4_set_remove([a], [oops], [yes], [no])
1379 m4_set_add([a,b], [c])dnl
1380 m4_set_add([a,b], [$*[]])dnl
1381 m4_set_add_all([a], [b,c])dnl
1382 m4_set_size([a])
1383 m4_count(m4_set_contents([a], [,]))
1384 m4_count(m4_set_list([a], [,]))
1385 m4_set_dump([a], [,])
1386 m4_set_contents([a,b], [,])
1387 m4_set_list([a,b])
1388 m4_set_foreach([$*[]], [$*[]], [oops])
1389 m4_set_add([$*[]], [])dnl
1390 m4_set_remove([$*[]], [a], [yes], [no])
1391 m4_set_add([$*[]], [a])dnl
1392 m4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-])
1393 m4_set_remove([$*[]], [], [yes], [no])
1394 m4_set_add([c], [,])dnl
1395 m4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):])
1396 ]],[[no
1400 b,c,a
1401 c,$*[]
1402 c,$*[]
1405 ---aoops-
1407 :,,::,a:
1410 # Stress tests - check for linear scaling (won't necessarily fail if
1411 # quadratic, but hopefully users will complain if it appears to hang)
1412 AT_CHECK_M4SUGAR_TEXT([[dnl
1413 m4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnl
1414 m4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnl
1415 m4_set_remove([a], [1])dnl
1416 m4_set_remove([b], [10000])dnl
1417 m4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnl
1418 m4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnl
1419 m4_len(m4_set_contents([a]))
1420 m4_len(m4_set_foreach([b], [b], [m4_if(m4_eval(b & 1), [1],
1421   [m4_set_remove([b], b, [-])])]))
1422 m4_set_size([b])
1423 m4_define([prune3x], [m4_if(m4_eval([$1 % 3]), [0],
1424   [m4_set_remove([a], [$1], [-])])])dnl
1425 m4_len(m4_set_map([a], [prune3x]))
1426 m4_count(m4_shift(m4_set_intersection([a], [b])))
1427 ]], [[38894
1428 5000
1429 5000
1430 3333
1431 3334
1434 AT_CLEANUP