5 # Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software
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)
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
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],
31 m4_divert_push(0)[]dnl
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])
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])))
64 m4_stack_foreach([abc], [doit])]],
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],
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],
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],
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
136 m4_rename([a], [b])dnl
140 m4_popdef([b], [c])dnl
142 m4_popdef([b], [c])dnl
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])
180 m4_divert_pop([KILL])dnl
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
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],
205 m4_defun([cross_warning], [m4_warn([cross], [cross])])
208 m4_warn([obsolete], [obsolete])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
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])
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
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])])
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
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
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
306 m4_indir([.], [goodbye])
307 m4_indir([-], [again])
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],
331 m4_cond([side(2)], [1], [a],
335 m4_cond([side(3)], [1], [a],
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
346 m4_cond([1], [1], [a])b
347 m4_cond([1], [2], [3], [a])b
377 AT_SETUP([m4@&t@_split])
379 AT_CHECK_M4SUGAR_TEXT(
380 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
385 m4_split([ active active ])end
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])
404 [], [active], [active], []end
407 [], [active active], []end
412 [a], [], [B], [], [c]
413 [a], [)}>=-], [b], [-=<{(], [c]
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
431 m4_unquote(m4_join([], [a], [b]))c
432 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
434 m4_unquote(m4_join([], [a], [b]))c
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
459 m4_undefine([active])dnl
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
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
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
486 m4_append([list], [one], [[, ]])dnl
487 m4_append([list], [two], [[, ]])dnl
488 m4_append([list], [three], [[, ]])dnl
491 m4_append_uniq_w([numbers], [1 1 2])dnl
492 m4_append_uniq_w([numbers], [ 2 3 ])dnl
495 [[This is an ACTIVE symbol.
496 This is an active symbol.
509 [one],[two],[three],[two]
515 AT_DATA_M4SUGAR([script.4s],
517 m4_append_uniq([str], [a], [ ])
518 m4_append_uniq([str], [a b], [ ])
523 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
524 ]], [[script.4s:3: warning: m4@&t@_append_uniq: `a b' contains ` '
534 AT_SETUP([m4@&t@_join])
536 AT_KEYWORDS([m4@&t@_joinall])
538 AT_CHECK_M4SUGAR_TEXT(
539 [[m4_define([active], [ACTIVE])
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])
556 m4_joinall([-], [one])
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
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])
623 First, second , third, [,quoted]
630 AT_CHECK_M4SUGAR([-o-], 0, [expout])
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])])
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])
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])
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
747 ## --------------- ##
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$*$@], [\$\*], [$#])
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
822 m4_foreach([myvar], [[a], [b, c], [d], [e
824 m4_foreach_w([myvar], [a b c, d,e f
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)
873 dnl bounds checking in m4_for
874 AT_DATA_M4SUGAR([script.4s],
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],
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],
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],
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
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], [[],
935 m4_mapall([ m4_count], [[],
938 m4_map_sep([m4_eval], [,], [[[1+2]],
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]],
944 m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
945 m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
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
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
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])
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)
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
1084 -a- a -a+ a +a- a +a+
1091 ## -------------- ##
1093 ## -------------- ##
1095 AT_SETUP([m4@&t@_max and m4@&t@_min])
1097 AT_DATA_M4SUGAR([script.4s],
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],
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
1127 m4_min(1m4_for([i], 2, 100, , [,i]))
1128 m4_min(m4_for([i], 100, 2, , [i,])1)
1139 m4_max(1m4_for([i], 2, 100, , [,i]))
1140 m4_max(m4_for([i], 100, 2, , [i,])1)
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],
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]))))
1212 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1227 AT_DATA_M4SUGAR([script.4s],
1228 [[m4_ifdef([__m4_version__],
1229 [m4_undefine([__m4_version__])],
1230 [m4_divert_push(0)48894
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]))))
1269 AT_CHECK_M4SUGAR([-o-], [0], [[48894
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
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])
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)])])
1328 m4_set_remove([a], [2])
1329 m4_dquote(m4_set_list([a]))
1333 m4_dquote(m4_set_list([a]))
1334 m4_indir([m4_dquote]m4_set_listc([a]))
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
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], [,])
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])):])
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, [-])])]))
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])))