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)
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])
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])
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(], [)], [,]))
69 m4_stack_foreach([abc], [doit])]],
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],
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],
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],
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
144 m4_rename([a], [b])dnl
148 m4_popdef([b], [c])dnl
150 m4_popdef([b], [c])dnl
152 m4_popdef([b], [c])dnl
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])
189 m4_dumpdefs([oops], [a])
190 m4_divert_pop([KILL])dnl
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__])])
203 m4_dumpdef([m4_define])
206 AT_CHECK_M4SUGAR([-o-], [0], [],
210 AT_DATA_M4SUGAR([script.4s],
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>
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
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],
239 m4_defun([cross_warning], [m4_warn([cross], [cross])])
242 m4_warn([obsolete], [obsolete])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
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
315 AT_DATA_M4SUGAR([script.4s],
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],
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],
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
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
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])
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
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])])
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
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
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
447 m4_indir([.], [goodbye])
448 m4_indir([-], [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
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
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
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
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
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
611 m4_defun([e], [[e]])dnl
612 m4_defun([f], [[f]m4_require([e])])dnl
616 m4_defun([h], [[h]m4_require([g])])dnl
618 m4_defun([i], [[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
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],
662 m4_cond([side(2)], [1], [a],
666 m4_cond([side(3)], [1], [a],
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
677 m4_cond([1], [1], [a])b
678 m4_cond([1], [2], [3], [a])b
708 AT_SETUP([m4@&t@_split])
710 AT_CHECK_M4SUGAR_TEXT(
711 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
716 m4_split([ active active ])end
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])
735 [], [active], [active], []end
738 [], [active active], []end
743 [a], [], [B], [], [c]
744 [a], [)}>=@&t@-], [b], [-@&t@=<{(], [c]
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
762 m4_unquote(m4_join([], [a], [b]))c
763 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
765 m4_unquote(m4_join([], [a], [b]))c
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
791 m4_undefine([active])dnl
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
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
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
818 m4_append([list], [one], [[, ]])dnl
819 m4_append([list], [two], [[, ]])dnl
820 m4_append([list], [three], [[, ]])dnl
823 m4_append_uniq_w([numbers], [1 1 2])dnl
824 m4_append_uniq_w([numbers], [ 2 3 ])dnl
827 [[This is an ACTIVE symbol.
828 This is an active symbol.
841 [one],[two],[three],[two]
847 AT_DATA_M4SUGAR([script.4s],
849 m4_append_uniq([str], [a], [ ])
850 m4_append_uniq([str], [a b], [ ])
855 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
856 ]], [[script.4s:3: warning: m4@&t@_append_uniq: `a b' contains ` '
866 AT_SETUP([m4@&t@_join])
868 AT_KEYWORDS([m4@&t@_joinall])
870 AT_CHECK_M4SUGAR_TEXT(
871 [[m4_define([active], [ACTIVE])
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])
888 m4_joinall([-], [one])
917 AT_SETUP([m4@&t@_expand])
919 AT_CHECK_M4SUGAR_TEXT(
920 [[m4_define([active], [ACTIVE])dnl
923 m4_expand([[active]])
924 dnl properly quoted case statements
925 m4_expand([case a in @%:@(
931 dnl unbalanced underquoted `)', but we manage anyway (gasp!)
932 m4_expand([case c in #(
938 dnl unterminated comment/dnl
939 m4_expand([active # active])
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
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])
1011 First, second , third, [,quoted]
1018 AT_CHECK_M4SUGAR([-o-], 0, [expout])
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])])
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])
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])
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
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$*$@], [\$\*], [$#])
1168 ## -------------- ##
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
1181 m4_esyscmd_s([echo hello world])
1182 m4_esyscmd_s([echo '[goodbye,
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, , -)
1242 m4_foreach([myvar], [[a], [b, c], [d], [e
1244 m4_foreach_w([myvar], [a b c, d,e f
1247 m4_map_args_w([a b c, d,e f
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)
1288 a| b| c,| d,e| f| g|
1290 a| b| c,| d,e| f| g|
1301 dnl bounds checking in m4_for
1302 AT_DATA_M4SUGAR([script.4s],
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],
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],
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],
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
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], [[],
1363 m4_mapall([ m4_count], [[],
1366 m4_map_sep([m4_eval], [,], [[[1+2]],
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]],
1372 m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
1373 m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
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
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
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
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])
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)
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
1517 -a- a -a+ a +a- a +a+
1524 ## -------------- ##
1526 ## -------------- ##
1528 AT_SETUP([m4@&t@_max and m4@&t@_min])
1530 AT_DATA_M4SUGAR([script.4s],
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],
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
1560 m4_min(1m4_for([i], 2, 100, , [,i]))
1561 m4_min(m4_for([i], 100, 2, , [i,])1)
1572 m4_max(1m4_for([i], 2, 100, , [,i]))
1573 m4_max(m4_for([i], 100, 2, , [i,])1)
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],
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]))))
1645 AT_CHECK_M4SUGAR([-o-], [0], [[48894
1660 AT_DATA_M4SUGAR([script.4s],
1661 [[m4_ifdef([__m4_version__],
1662 [m4_undefine([__m4_version__])],
1663 [m4_divert_push(0)48894
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]))))
1702 AT_CHECK_M4SUGAR([-o-], [0], [[48894
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
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])
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)])])
1761 m4_set_remove([a], [2])
1762 m4_dquote(m4_set_list([a]))
1766 m4_dquote(m4_set_list([a]))
1767 m4_indir([m4_dquote]m4_set_listc([a]))
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
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], [,])
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])):])
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, [-])])]))
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])))