5 # Copyright (C) 2000-2002, 2005-2017, 2020-2024 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 3 of the License, or
11 # (at your option) 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, see <https://www.gnu.org/licenses/>.
22 # AT_CHECK_M4SUGAR_TEXT(CODE, STDOUT, STDERR)
23 # -------------------------------------------
24 # Check that m4sugar CODE expands to STDOUT and emits STDERR.
25 m4_define([AT_CHECK_M4SUGAR_TEXT],
27 AT_DATA_M4SUGAR([script.4s],
29 m4_divert_push([])[]dnl
34 AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
35 ])# AT_CHECK_M4SUGAR_TEXT
38 ## ------------------ ##
39 ## m4_stack_foreach. ##
40 ## ------------------ ##
42 AT_SETUP([m4@&t@_stack])
44 AT_KEYWORDS([m4@&t@_stack_foreach m4@&t@_stack_foreach_lifo])
45 AT_KEYWORDS([m4@&t@_stack_foreach_sep m4@&t@_stack_foreach_sep_lifo])
46 AT_KEYWORDS([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_stack_foreach_sep([abc], [ m4_index([abcdefghijkl],], [)])
61 m4_define([colon], [:])m4_define([lt], [<])m4_define([gt], [>])dnl
62 m4_stack_foreach_sep_lifo([abc], [lt], [gt], [colon])
63 m4_pushdef([xyz], [123])dnl
64 m4_pushdef([xyz], [456])dnl
65 m4_define([doit], [[$1](m4_stack_foreach_sep([xyz], [m4_dquote(], [)], [,]))
67 m4_stack_foreach([abc], [doit])]],
103 AT_SETUP([m4@&t@_defn])
105 AT_KEYWORDS([m4@&t@_popdef m4@&t@_undefine m4@&t@_copy m4@&t@_rename
106 m4@&t@_copy_force m4@&t@_rename_force])
108 # Ensure that m4sugar dies when dereferencing undefined macros, whether
109 # this is provided by m4 natively or faked by wrappers in m4sugar.
111 AT_DATA_M4SUGAR([script.4s],
113 m4_defn([good], [oops])
116 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
117 AT_CHECK([grep good stderr], [1])
118 AT_CHECK([grep 'm4@&t@_defn: undefined.*oops' stderr], [0], [ignore])
120 AT_DATA_M4SUGAR([script.4s],
122 m4_popdef([good], [oops])
125 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
126 AT_CHECK([grep good stderr], [1])
127 AT_CHECK([grep 'm4@&t@_popdef: undefined.*oops' stderr], [0], [ignore])
129 AT_DATA_M4SUGAR([script.4s],
131 m4_undefine([good], [oops])
134 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
135 AT_CHECK([grep good stderr], [1])
136 AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])
138 # Cannot rename an undefined macro.
139 AT_DATA_M4SUGAR([script.4s],
140 [[m4_rename([oops], [good])
143 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
144 AT_CHECK([grep 'm4@&t@_undefine: undefined.*oops' stderr], [0], [ignore])
146 # Check that pushdef stacks can be renamed.
147 AT_CHECK_M4SUGAR_TEXT([[m4_pushdef([a], [1])dnl
148 m4_pushdef([a], [2])dnl
149 m4_pushdef([a], m4_defn([m4_divnum]))dnl
151 m4_rename([a], [b])dnl
155 m4_popdef([b], [c])dnl
157 m4_popdef([b], [c])dnl
159 m4_popdef([b], [c])dnl
161 dnl m4_copy is intentionally a no-op on undefined source
162 m4_copy([oops], [dummy])m4_ifdef([dummy], [[oops]])dnl
163 dnl allow forceful overwrites
164 m4_define([d], [4])m4_define([e], [5])m4_define([f], [6])dnl
165 m4_copy_force([d], [e])dnl
166 m4_rename_force([d], [f])dnl
168 m4_popdef([e], [f])dnl
187 AT_SETUP([m4@&t@_dumpdef])
189 AT_KEYWORDS([m4@&t@_dumpdefs])
191 # Ensure that m4sugar dies when dereferencing undefined macros.
193 AT_DATA_M4SUGAR([script.4s],
194 [[m4_define([good], [yep])
195 m4_dumpdef([good], [oops])
198 AT_CHECK_M4SUGAR([-o-], 1, [], [stderr])
199 AT_CHECK([grep '^good: \[[yep]]$' stderr], [0], [ignore])
200 AT_CHECK([grep 'm4@&t@_dumpdef: undefined.*oops' stderr], [0], [ignore])
202 # Check that pushdef stacks can be dumped.
203 AT_CHECK_M4SUGAR_TEXT([[m4_divert_push([KILL])
207 m4_dumpdefs([oops], [a])
208 m4_divert_pop([KILL])dnl
215 # Check behavior when dumping builtins. Unfortunately, when using M4 1.4.x
216 # (or more precisely, when __m4_version__ is undefined), builtins get
217 # flattened to an empty string. It takes M4 1.6 to work around this.
218 AT_DATA_M4SUGAR([script.4s],
219 [[m4_ifdef([__m4_version__], [_m4_undefine([__m4_version__])])
221 m4_dumpdef([m4_define])
224 AT_CHECK_M4SUGAR([-o-], [0], [],
228 AT_DATA_M4SUGAR([script.4s],
230 m4_ifdef([__m4_version__],
231 [m4_dumpdef([m4_define])],
232 [m4_errprintn([m4_define: <define>])])
235 AT_CHECK_M4SUGAR([-o-], [0], [],
236 [[m4_define: <define>
246 AT_SETUP([m4@&t@_warn])
247 AT_KEYWORDS([m4@&t@_warn])
249 AT_DATA_M4SUGAR([script.4s],
251 m4_defun([cross_warning], [m4_warn([cross], [cross])])
254 m4_warn([obsolete], [obsolete])dnl
256 m4_warn([syntax], [syntax])dnl
258 m4_warn([syntax], [syntax])dnl
261 AT_CHECK_M4SUGAR([-o-], 0, [],
262 [script.4s:4: warning: prefer named diversions
263 script.4s:5: warning: obsolete
264 script.4s:7: warning: syntax
265 script.4s:9: warning: syntax
268 AT_CHECK_M4SUGAR([-o- -Wall], 0, [],
269 [script.4s:4: warning: prefer named diversions
270 script.4s:5: warning: obsolete
271 script.4s:6: warning: cross
272 script.4s:2: cross_warning is expanded from...
273 script.4s:6: the top level
274 script.4s:7: warning: syntax
275 script.4s:8: warning: cross
276 script.4s:2: cross_warning is expanded from...
277 script.4s:8: the top level
278 script.4s:9: warning: syntax
281 AT_CHECK_M4SUGAR([-o- -Wnone,cross], 0, [],
282 [script.4s:6: warning: cross
283 script.4s:2: cross_warning is expanded from...
284 script.4s:6: the top level
285 script.4s:8: warning: cross
286 script.4s:2: cross_warning is expanded from...
287 script.4s:8: the top level
290 AT_CHECK_M4SUGAR([-o- -Wnone,cross,error], 1, [],
291 [[script.4s:6: warning: cross
292 script.4s:2: cross_warning is expanded from...
293 script.4s:6: the top level
294 script.4s:8: warning: cross
295 script.4s:2: cross_warning is expanded from...
296 script.4s:8: the top level
301 ## ----------------------------------------------- ##
302 ## Bad m4_warn categories (Autoconf bug #110872). ##
303 ## ----------------------------------------------- ##
305 AT_SETUP([m4@&t@_warn (bad categories)])
306 AT_KEYWORDS([m4@&t@_warn])
308 AT_DATA_M4SUGAR([script.4s],
310 m4_warn([], [empty category])dnl
311 m4_warn([bogus], [invalid category])dnl
312 m4_warn([!"\ %^&*], [line noise category])dnl " unconfuse editor
313 m4_warn([all], ['all' used as a category])dnl
314 m4_warn([none], ['none' used as a category])dnl
315 m4_warn([no-syntax], ['no-syntax' used as a category])dnl
316 m4_warn([no-bogus], ['no-bogus' used as a category])dnl
317 m4_warn([error], [oddly enough, this works])dnl
320 AT_CHECK_M4SUGAR([-o- -Wnone], 1, [],
321 [script.4s:3: error: unknown diagnostic category "bogus"
322 script.4s:4: error: unknown diagnostic category "!\"\\\x09%^&*"
323 script.4s:6: error: -W accepts "none", but it is not a diagnostic category
324 script.4s:7: error: -W accepts "no-syntax", but it is not a diagnostic category
325 script.4s:8: error: unknown diagnostic category "no-bogus"
326 script.4s:9: error: oddly enough, this works
329 AT_CHECK_M4SUGAR([-o- -Wnone,obsolete], 1, [],
330 [script.4s:2: warning: use of "" as a diagnostic category is obsolete
331 script.4s:2: (see autom4te --help for a list of valid categories)
332 script.4s:3: error: unknown diagnostic category "bogus"
333 script.4s:4: error: unknown diagnostic category "!\"\\\x09%^&*"
334 script.4s:5: warning: use of "all" as a diagnostic category is obsolete
335 script.4s:5: (see autom4te --help for a list of valid categories)
336 script.4s:6: error: -W accepts "none", but it is not a diagnostic category
337 script.4s:7: error: -W accepts "no-syntax", but it is not a diagnostic category
338 script.4s:8: error: unknown diagnostic category "no-bogus"
339 script.4s:9: error: oddly enough, this works
342 AT_CHECK_M4SUGAR([-o- -Wnone,obsolete,syntax], 1, [],
343 [script.4s:2: warning: use of "" as a diagnostic category is obsolete
344 script.4s:2: (see autom4te --help for a list of valid categories)
345 script.4s:2: warning: empty category
346 script.4s:3: error: unknown diagnostic category "bogus"
347 script.4s:3: warning: invalid category
348 script.4s:4: error: unknown diagnostic category "!\"\\\x09%^&*"
349 script.4s:4: warning: line noise category
350 script.4s:5: warning: use of "all" as a diagnostic category is obsolete
351 script.4s:5: (see autom4te --help for a list of valid categories)
352 script.4s:5: warning: 'all' used as a category
353 script.4s:6: error: -W accepts "none", but it is not a diagnostic category
354 script.4s:6: warning: 'none' used as a category
355 script.4s:7: error: -W accepts "no-syntax", but it is not a diagnostic category
356 script.4s:7: warning: 'no-syntax' used as a category
357 script.4s:8: error: unknown diagnostic category "no-bogus"
358 script.4s:8: warning: 'no-bogus' used as a category
359 script.4s:9: error: oddly enough, this works
364 ## ----------------- ##
365 ## m4_divert_stack. ##
366 ## ----------------- ##
368 AT_SETUP([m4@&t@_divert_stack])
369 AT_KEYWORDS([m4@&t@_divert m4@&t@_divert_push m4@&t@_divert_pop
370 m4@&t@_undivert m4@&t@_cleardivert m4@&t@_divert_text])
372 dnl This test names some diversions to avoid a warning.
373 AT_CHECK_M4SUGAR_TEXT([[m4_define([_m4_divert(ten)], [10])dnl
374 m4_define([_m4_divert(twenty)], [20])dnl
375 m4_define([_m4_divert(thirty)], [30])dnl
377 m4_divert_push([ten])2.m4_divert_stack
378 m4_divert_text([twenty], [3.m4_divert_stack])dnl
379 m4_divert([thirty])4.m4_divert_stack
380 m4_divert_pop([thirty])dnl
381 5.m4_undivert([twenty], [thirty])
382 m4_pattern_allow([^m4_divert])dnl
383 ]], [[1.script.4s:2: m4@&t@_divert_push:
384 script.4s:1: m4@&t@_divert: KILL
385 5.3.script.4s:8: m4@&t@_divert_push: twenty
386 script.4s:7: m4@&t@_divert_push: ten
387 script.4s:2: m4@&t@_divert_push:
388 script.4s:1: m4@&t@_divert: KILL
389 4.script.4s:9: m4@&t@_divert: thirty
390 script.4s:2: m4@&t@_divert_push:
391 script.4s:1: m4@&t@_divert: KILL
393 2.script.4s:7: m4@&t@_divert_push: ten
394 script.4s:2: m4@&t@_divert_push:
395 script.4s:1: m4@&t@_divert: KILL
398 AT_CHECK_M4SUGAR_TEXT([[dnl
399 m4_divert_text([3], [three])dnl
400 m4_divert_text([4], [four])dnl
401 m4_divert_text([1], [one])dnl
402 m4_divert_text([2], [two])dnl
403 m4_cleardivert([2], [3])dnl
408 [[script.4s:4: warning: prefer named diversions
409 script.4s:5: warning: prefer named diversions
410 script.4s:6: warning: prefer named diversions
411 script.4s:7: warning: prefer named diversions
412 script.4s:8: warning: prefer named diversions
415 AT_DATA_M4SUGAR([script.4s],
418 AT_CHECK_M4SUGAR([-o-], [1], [],
419 [[script.4s:1: error: too many m4@&t@_divert_pop
420 script.4s:1: the top level
421 autom4te: error: m4 failed with exit status: 1
424 AT_DATA_M4SUGAR([script.4s],
429 AT_CHECK_M4SUGAR([-o-], [1], [],
430 [[script.4s:3: error: m4@&t@_divert_pop(2): diversion mismatch:
431 script.4s:2: m4@&t@_divert_push: 1
432 script.4s:1: m4@&t@_divert: KILL
433 script.4s:3: the top level
434 autom4te: error: m4 failed with exit status: 1
437 AT_DATA_M4SUGAR([script.4s],
442 AT_CHECK_M4SUGAR([-o-], [1], [],
443 [[script.4s:2: error: m4@&t@_init: unbalanced m4@&t@_divert_push:
444 script.4s:3: m4@&t@_divert_push: 2
445 script.4s:2: m4@&t@_divert: KILL
446 script.4s:2: the top level
447 autom4te: error: m4 failed with exit status: 1
453 ## -------------------- ##
454 ## m4_expansion_stack. ##
455 ## -------------------- ##
457 AT_SETUP([m4@&t@_expansion_stack])
459 AT_CHECK_M4SUGAR_TEXT([[1.m4_expansion_stack
460 m4_defun([a], [b])dnl
461 m4_define([c], [d])dnl
462 m4_defun([d], [2.m4_expansion_stack])dnl
463 m4_defun([b], [c])dnl
465 3.m4_ifdef([_m4_expansion_stack], [m4_expansion_stack])
466 ]], [[1.script.4s:3: the top level
467 2.script.4s:6: d is expanded from...
468 script.4s:7: b is expanded from...
469 script.4s:4: a is expanded from...
470 script.4s:8: the top level
477 ## --------------------------- ##
478 ## m4_require: error message. ##
479 ## --------------------------- ##
481 AT_SETUP([m4@&t@_require: error message])
482 AT_KEYWORDS([m4@&t@_require])
484 AT_DATA_M4SUGAR([script.4s],
485 [[m4_defun([foo], [FOO])
489 AT_CHECK_M4SUGAR([], 1, [],
490 [[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro
491 script.4s:2: the top level
492 autom4te: error: m4 failed with exit status: 1
497 ## ----------------------------- ##
498 ## m4_require: warning message. ##
499 ## ----------------------------- ##
501 AT_SETUP([m4@&t@_require: warning message])
502 AT_KEYWORDS([m4@&t@_require m4@&t@_require_silent_probe])
504 # Mirror the job of aclocal on a typical scenario: the user invokes a
505 # single macro that comes from one included file, which in turn requires
506 # another macro from a second file. When using the incomplete set of
507 # files, we want a warning, unless we are merely learning which additional
508 # macros are needed in order to regenerate the list of files to include.
509 AT_DATA_M4SUGAR([script.4s],
511 m4_include([script1.4s])
515 AT_DATA_M4SUGAR([script1.4s],
516 [[m4_defun([foo], [m4_require([bar])])
519 AT_DATA_M4SUGAR([script2.4s],
520 [[m4_defun([bar], [BAR])
523 AT_CHECK_M4SUGAR([], [0], [],
524 [[script.4s:3: warning: bar is m4@&t@_require'd but not m4@&t@_defun'd
525 script1.4s:1: foo is expanded from...
526 script.4s:3: the top level
529 # Inline expansion of AT_CHECK_M4SUGAR, mirroring how aclocal will
530 # inject a definition of our witness macro for a silent run.
531 echo 'm4@&t@_define([m4@&t@_require_silent_probe])' |
532 AT_CHECK_AUTOM4TE([--language=m4sugar - script.4s -o script],
535 # Now that we have recomputed the set of include files, things should work.
536 AT_DATA_M4SUGAR([script.4s],
538 m4_include([script1.4s])
539 m4_include([script2.4s])
543 AT_CHECK_M4SUGAR([], [0], [], [])
548 ## ----------------------------------- ##
549 ## m4_require: circular dependencies. ##
550 ## ----------------------------------- ##
552 AT_SETUP([m4@&t@_require: circular dependencies])
553 AT_KEYWORDS([m4@&t@_require])
555 AT_DATA_M4SUGAR([script.4s],
556 [[m4_defun([foo], [m4_require([bar])])
558 m4_defun([bar], [m4_require([foo])])
560 m4_defun([baz], [m4_require([foo])])
567 AT_CHECK_M4SUGAR([], 1, [],
568 [[script.4s:9: error: m4@&t@_require: circular dependency of foo
569 script.4s:3: bar is expanded from...
570 script.4s:1: foo is expanded from...
571 script.4s:5: baz is expanded from...
572 script.4s:9: the top level
573 autom4te: error: m4 failed with exit status: 1
578 ## ---------------------- ##
579 ## m4_require: one-shot. ##
580 ## ---------------------- ##
582 AT_SETUP([m4@&t@_require: one-shot initialization])
583 AT_KEYWORDS([m4@&t@_require])
584 AT_KEYWORDS([m4@&t@_defun_init m4@&t@_copy m4@&t@_defun_once])
586 dnl check out m4_defun_init, m4_copy, and odd macro names
587 AT_CHECK_M4SUGAR_TEXT([[
588 m4_define([t], [text])dnl
589 m4_defun_init([a], [[init a
590 ]], [[common a] t])dnl
591 m4_defun([b], [[b]m4_require([a])])dnl
592 m4_defun([c], [[c]m4_require([a])])dnl
597 m4_defun_init([-], [hello, ], [m4_if([$#], [0], [world], [[$1]])])dnl
600 m4_indir([.], [goodbye])
601 m4_indir([-], [again])
613 dnl Check m4_defun_once behavior
614 AT_CHECK_M4SUGAR_TEXT([[
615 m4_defun_once([a], [[a]])dnl
616 m4_defun([b], [[b]m4_require([a])])dnl
617 m4_defun([c], [[c]a[]m4_require([b])])dnl
620 m4_defun_once([d], [[d]m4_require([a])])dnl
622 m4_defun_once([e], [[e]])dnl
623 m4_defun([f], [[f]m4_require([e])e])dnl
639 ## -------------------- ##
640 ## m4_require: nested. ##
641 ## -------------------- ##
643 AT_SETUP([m4@&t@_require: nested])
644 AT_KEYWORDS([m4@&t@_require m4@&t@_defun])
646 dnl From the m4sugar.m4 discourse: Require chains, top level
647 AT_CHECK_M4SUGAR_TEXT([[dnl
648 m4_defun([a], [[a]])dnl aka TEST2a
649 m4_defun([b], [[b]m4_require([a])])dnl aka TEST3
650 m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b
651 m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1
666 dnl From the m4sugar.m4 discourse: Require chains, nested
667 AT_CHECK_M4SUGAR_TEXT([[dnl
668 m4_defun([a], [[a]])dnl aka TEST2a
669 m4_defun([b], [[b]m4_require([a])])dnl aka TEST3
670 m4_defun([c], [[c]m4_require([b])])dnl aka TEST2b
671 m4_defun([d], [[d]m4_require([a])m4_require([c])])dnl aka TEST1
688 dnl Direct invocation, nested requires, top level
689 AT_CHECK_M4SUGAR_TEXT([[dnl
690 m4_defun([a], [[a]])dnl
691 m4_defun([b], [[b]m4_require([a])])dnl
692 m4_defun([c], [[c]m4_require([b])])dnl
709 dnl Direct invocation, nested requires, nested defun. This is an example
710 dnl of expansion before requirement, such that b occurs before its
711 dnl prerequisite a. This indicates a bug in the macros (but not in
712 dnl autoconf), so we should be emitting a warning.
713 AT_CHECK_M4SUGAR_TEXT([[dnl
714 m4_defun([a], [[a]])dnl
715 m4_defun([b], [[b]m4_require([a])])dnl
716 m4_defun([c], [[c]m4_require([b])])dnl
717 dnl the extra macro layer works around line number differences in older m4
718 m4_define([foo], [m4_defun([outer],
736 [[script.4s:15: warning: m4@&t@_require: 'a' was expanded before it was required
737 script.4s:15: https://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
738 script.4s:5: b is expanded from...
739 script.4s:6: c is expanded from...
740 script.4s:14: outer is expanded from...
741 script.4s:15: the top level
744 dnl Direct invocation, expand-before-require but no nested require. As this
745 dnl is common in real life, but does not result in out-of-order expansion,
746 dnl we silently permit this.
747 AT_CHECK_M4SUGAR_TEXT([[dnl
748 m4_defun([a], [[a]])dnl
749 m4_defun([b], [[b]m4_require([a])])dnl
750 m4_defun([c], [[c]])dnl
751 m4_defun([d], [[d]m4_require([c])])dnl
766 m4_defun([e], [[e]])dnl
767 m4_defun([f], [[f]m4_require([e])])dnl
771 m4_defun([h], [[h]m4_require([g])])dnl
773 m4_defun([i], [[i]])dnl
776 m4_defun([k], [[k]m4_require([i])])dnl
777 m4_defun([l], [[l]m4_require([k])])dnl
778 m4_defun([m], [[m]m4_require([j])m4_require([l])])dnl
807 ## ------------------------------------------------- ##
808 ## m4_ifval, m4_ifblank, m4_ifset, m4_default, etc. ##
809 ## ------------------------------------------------- ##
811 AT_SETUP([m4sugar shorthand conditionals])
812 AT_KEYWORDS([m4@&t@_ifval m4@&t@_ifblank m4@&t@_ifnblank m4@&t@_ifset
813 m4@&t@_default m4@&t@_default_quoted m4@&t@_default_nblank
814 m4@&t@_default_nblank_quoted])
816 AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])m4_define([empty])
817 m4_ifval([active], [yes], [no])
818 m4_ifval([empty], [yes], [no])
819 m4_ifval([ ], [yes], [no])
820 m4_ifval([], [yes], [no])
821 m4_ifblank([active], [yes], [no])
822 m4_ifblank([empty], [yes], [no])
823 m4_ifblank([ ], [yes], [no])
824 m4_ifblank([], [yes], [no])
825 m4_ifnblank([active], [yes], [no])
826 m4_ifnblank([empty], [yes], [no])
827 m4_ifnblank([ ], [yes], [no])
828 m4_ifnblank([], [yes], [no])
829 m4_ifset([active], [yes], [no])
830 m4_ifset([empty], [yes], [no])
831 m4_ifset([ ], [yes], [no])
832 m4_ifset([], [yes], [no])
834 m4_define([demo1], [m4_default([$1], [$2])])dnl
835 m4_define([demo2], [m4_default_quoted([$1], [$2])])dnl
836 m4_define([demo3], [m4_default_nblank([$1], [$2])])dnl
837 m4_define([demo4], [m4_default_nblank_quoted([$1], [$2])])dnl
838 demo1([active], [default])
840 demo1([empty], [text])
841 -demo1([ ], [active])-
842 demo2([active], [default])
844 demo2([empty], [text])
845 -demo2([ ], [active])-
846 demo3([active], [default])
848 demo3([empty], [text])
849 -demo3([ ], [active])-
850 demo4([active], [default])
852 demo4([empty], [text])
853 -demo4([ ], [active])-
896 AT_SETUP([m4@&t@_cond])
898 AT_CHECK_M4SUGAR_TEXT([[m4_define([side], [m4_errprintn([$1])$1])
899 m4_cond([side(1)], [1], [a],
902 m4_cond([side(2)], [1], [a],
906 m4_cond([side(3)], [1], [a],
910 m4_cond([a,a], [a,a], [yes], [no])
911 m4_cond([[a,a]], [a,a], [yes])
912 m4_cond([a,a], [a,b], [yes], [no])
913 m4_cond([a,a], [a,b], [yes])
914 m4_cond([m4_eval([0xa])])
915 m4_define([ab], [AB])dnl
917 m4_cond([1], [1], [a])b
918 m4_cond([1], [2], [3], [a])b
950 AT_KEYWORDS([m4@&t@_car m4@&t@_cdr m4@&t@_argn _m4@&t_cdr])
952 AT_CHECK_M4SUGAR_TEXT([[dnl
953 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])
954 m4_argn([1], [a], [b], [c])
955 m4_argn([2], [a], [b], [c])
956 m4_argn([3], [a], [b], [c])
957 m4_argn([4], [a], [b], [c])
958 m4_car([a], [b], [c])
959 m4_cdr([a], [b], [c])
962 _m4_cdr([a], [b], [c])
965 m4_if(m4_cdr([], []), [[]], [good], [bad])
966 m4_if(m4_cdr([]), [], [good], [bad])
983 AT_DATA_M4SUGAR([script.4s],
985 m4_argn([0], [a], [b], [c])
987 AT_CHECK_M4SUGAR([-o-], [1], [],
988 [[script.4s:2: error: assert failed: 0 < 0
989 script.4s:2: the top level
990 autom4te: error: m4 failed with exit status: 1
1000 AT_SETUP([m4@&t@_split])
1002 AT_CHECK_M4SUGAR_TEXT(
1003 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
1008 m4_split([ active active ])end
1010 m4_split([active], [ ])
1011 m4_split([ active active ], [ ])end
1012 m4_split([abcde], [bd])
1013 m4_split([abcde], [[bd]])
1014 m4_split([foo=`` bar=''])
1015 m4_split([foo='' bar=``])
1016 dnl these next two are from the manual; keep this in sync if the internal
1017 dnl quoting strings in m4_split are changed
1018 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
1019 m4_split([a )}>=- b -=<{( c])
1020 m4_split([a )}@&t@>=- b -=<@&t@{( c])
1027 [], [active], [active], []end
1030 [], [active active], []end
1035 [a], [], [B], [], [c]
1036 [a], [)}>=@&t@-], [b], [-@&t@=<{(], [c]
1046 AT_SETUP([m4@&t@_do])
1048 AT_CHECK_M4SUGAR_TEXT(
1049 [[m4_define([ab], [1])m4_define([bc], [2])m4_define([abc], [3])dnl
1050 m4_define([AB], [4])m4_define([BC], [5])m4_define([ABC], [6])dnl
1054 m4_unquote(m4_join([], [a], [b]))c
1055 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
1057 m4_unquote(m4_join([], [a], [b]))c
1074 AT_SETUP([m4@&t@_append])
1075 AT_KEYWORDS([m4@&t@_append_uniq m4@&t@_append_uniq_w])
1077 AT_CHECK_M4SUGAR_TEXT(
1078 [[m4_define([active], [ACTIVE])dnl
1079 m4_append([sentence], [This is an])dnl
1080 m4_append([sentence], [ active ])dnl
1081 m4_append([sentence], [symbol.])dnl
1083 m4_undefine([active])dnl
1085 m4_define([active], [ACTIVE])dnl
1086 m4_append([hooks], [m4_define([act1], [act2])])dnl
1087 m4_append([hooks], [m4_define([act2], [active])])dnl
1088 m4_undefine([active])dnl
1092 dnl Test for bug fixed in 2.62 when separator is active.
1093 m4_define([a], [A])dnl
1094 m4_append_uniq([foo], [-], [a])dnl
1095 m4_append_uniq([foo], [-], [a])dnl
1096 m4_append_uniq([bar], [-], [a])dnl
1097 m4_append_uniq([bar], [~], [a])dnl
1098 m4_append_uniq([bar], [-], [a])dnl
1103 m4_append_uniq([blah], [one], [, ], [new], [existing])
1104 m4_append_uniq([blah], [two], [, ], [new], [existing])
1105 m4_append_uniq([blah], [two], [, ], [new], [existing])
1106 m4_append_uniq([blah], [three], [, ], [new], [existing])
1107 m4_append([blah], [two], [, ])dnl
1110 m4_append([list], [one], [[, ]])dnl
1111 m4_append([list], [two], [[, ]])dnl
1112 m4_append([list], [three], [[, ]])dnl
1115 m4_append_uniq_w([numbers], [1 1 2])dnl
1116 m4_append_uniq_w([numbers], [ 2 3 ])dnl
1119 [[This is an ACTIVE symbol.
1120 This is an active symbol.
1132 one, two, three, two
1133 [one],[two],[three],[two]
1139 AT_DATA_M4SUGAR([script.4s],
1141 m4_append_uniq([str], [a], [ ])
1142 m4_append_uniq([str], [a b], [ ])
1147 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
1148 ]], [[script.4s:3: warning: m4@&t@_append_uniq: 'a b' contains ' '
1158 AT_SETUP([m4@&t@_join])
1160 AT_KEYWORDS([m4@&t@_joinall])
1162 AT_CHECK_M4SUGAR_TEXT(
1163 [[m4_define([active], [ACTIVE])
1166 m4_join([, ], [one], [two])
1167 m4_dquote(m4_join([, ], [one], [two]))
1168 m4_join([|], [active], [active])
1169 m4_join([|], ,,,[one])
1170 m4_join([|], [one],,,)
1171 m4_join([], ,,,[two])
1172 m4_join([], [two],,,)
1173 m4_join([ active ], [one], , [two])
1174 m4_join([], [one], [two])
1175 m4_joinall([-], [one], [], [two])
1176 m4_joinall([-], [], [], [three], [], [])
1177 m4_joinall([], [one], [], [two])
1180 m4_joinall([-], [one])
1209 AT_SETUP([m4@&t@_expand])
1211 AT_CHECK_M4SUGAR_TEXT(
1212 [[m4_define([active], [ACTIVE])dnl
1215 m4_expand([[active]])
1216 dnl properly quoted case statements
1217 m4_expand([case a in @%:@(
1221 *[)] echo active, ;;
1223 dnl unbalanced underquoted ')', but we manage anyway (gasp!)
1224 m4_expand([case c in #(
1230 dnl unterminated comment/dnl
1231 m4_expand([active # active])
1265 AT_SETUP([m4@&t@_text_box])
1267 AT_CHECK_M4SUGAR_TEXT([[
1268 m4_text_box([a $1 @&t@b])
1269 m4_text_box([a $1 @&t@b], [$])
1270 m4_text_box([a $1 @&t@b], [,])
1285 ## -------------- ##
1287 ## -------------- ##
1289 AT_SETUP([m4@&t@_text_wrap])
1290 AT_KEYWORDS([m4@&t@_escape])
1292 # m4_text_wrap is used to display the help strings. Also, check that
1293 # commas and $ are not swallowed. This can easily happen because of
1296 AT_DATA_M4SUGAR([script.4s],
1297 [[m4_init[]m4_divert([])dnl
1298 m4_define([a], [OOPS])dnl
1299 m4_escape([a[b $c#]d])
1300 m4_if(m4_escape([a[b $c#]d]), [a[b $c#]d], [oops],
1301 m4_escape([a[b $c#]d]), [a@<:@b @S|@c@%:@@:>@d], [pass], [oops])
1303 m4_text_wrap([Short string */], [ ], [/* ], 20)
1305 m4_text_wrap([Much longer string */], [ ], [/* ], 20)
1307 m4_text_wrap([Short doc.], [ ], [ --short ], 30)
1309 m4_text_wrap([Short doc.], [ ], [ --too-wide], 30)
1311 m4_text_wrap([Super long documentation.], [ ], [ --too-wide], 30)
1313 m4_text_wrap([First, second , third, [,quoted space]])
1314 m4_define([xfff], [oops])
1315 m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
1336 First, second , third, [,quoted space]
1343 AT_CHECK_M4SUGAR([-o-], 0, [expout])
1347 ## -------------------- ##
1348 ## m4_version_compare. ##
1349 ## -------------------- ##
1351 AT_SETUP([m4@&t@_version_compare])
1353 AT_KEYWORDS([m4@&t@_list_cmp])
1355 AT_CHECK_M4SUGAR_TEXT(
1356 [[m4_version_compare([1.1], [2.0])
1357 m4_version_compare([2.0b], [2.0a])
1358 m4_version_compare([2.0z], [2.0y])
1359 m4_version_compare([1.1.1], [1.1.1a])
1360 m4_version_compare([1.2], [1.1.1a])
1361 m4_version_compare([1.0], [1])
1362 m4_version_compare([1.0a], [1.0a])
1363 m4_version_compare([1.1a], [1.1a.1])
1364 m4_version_compare([1.10], [1.1a])
1365 m4_version_compare([1-1a], [1,1A])
1366 m4_define([a], [oops])dnl
1367 m4_version_compare([1.1a], [1.1A])
1368 m4_version_compare([1z], [1aa])
1369 m4_version_compare([2.61a], [2.61a-248-dc51])
1370 m4_version_compare([2.61b], [2.61a-248-dc51])
1371 m4_version_compare([08], [09])
1372 m4_version_compare([010], [8])
1373 dnl Test that side effects to m4_list_cmp occur exactly once
1374 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
1375 [[0], [0], [0]m4_errprintn([hi])])
1376 m4_list_cmp([[0], [0], [0]m4_errprintn([hi])],
1377 [[0], [0], [0]m4_errprintn([bye])])
1405 ## ------------------------------ ##
1406 ## Standard regular expressions. ##
1407 ## ------------------------------ ##
1409 AT_SETUP([Standard regular expressions])
1411 # AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = 'ok' | '')
1412 # ------------------------------------------------
1413 # Check whether RE-NAME (a macro whose definition is a regular expression)
1414 # matches TEXT. INTENT = 'ok' if the match should succeed or else empty.
1415 m4_define([AT_CHECK_M4RE],
1416 [AT_CHECK_M4SUGAR_TEXT(
1417 [[m4_bregexp([$2], ^m4_defn([$1])$, [ok])
1421 AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok])
1422 AT_CHECK_M4RE([m4_re_word], [_9abc], [ok])
1423 AT_CHECK_M4RE([m4_re_word], [9ab_c])
1425 AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok])
1426 AT_CHECK_M4RE([m4_re_string], [_9abc], [ok])
1427 AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok])
1428 AT_CHECK_M4RE([m4_re_string], [9a@_c])
1436 AT_SETUP([m4@&t@_bmatch])
1438 AT_CHECK_M4SUGAR_TEXT(
1439 [[m4_bmatch([abc], [default\])
1440 m4_bmatch([abc], [^a], [yes])
1441 m4_bmatch([abc], [^a], [yes], [no])
1442 m4_bmatch([abc], [^.a], [yes])
1443 m4_bmatch([abc], [^.a], [yes], [no\])
1444 m4_bmatch([abc], [a], [1], [b], [2])
1445 m4_bmatch([abc], [A], [1], [b], [2])
1446 m4_define([ab], [AB])dnl
1447 m4_bmatch([$*], [a])b
1448 m4_bmatch([$*], [\*], [a])b
1449 m4_bmatch([$*], [1], [2], [a])b
1464 ## ------------------------ ##
1465 ## m4_toupper, m4_tolower. ##
1466 ## ------------------------ ##
1468 AT_SETUP([m4@&t@_toupper and m4@&t@_tolower])
1470 AT_CHECK_M4SUGAR_TEXT(
1471 [[m4_define([abc], [hI])m4_define([ABC], [Hi])
1472 m4_toupper(abc aBc ABC)
1473 m4_tolower(abc aBc ABC)
1474 m4_toupper([abc aBc ABC])
1475 m4_tolower([abc aBc ABC])
1476 m4_echo(m4_toupper(abc aBc ABC))
1477 m4_echo(m4_tolower(abc aBc ABC))
1478 m4_echo(m4_toupper([abc aBc ABC]))
1479 m4_echo(m4_tolower([abc aBc ABC]))
1480 m4_do(m4_toupper(abc aBc ABC))
1481 m4_do(m4_tolower(abc aBc ABC))
1482 m4_do(m4_toupper([abc aBc ABC]))
1483 m4_do(m4_tolower([abc aBc ABC]))
1501 ## --------------- ##
1502 ## m4_bpatsubsts. ##
1503 ## --------------- ##
1505 AT_SETUP([m4@&t@_bpatsubsts])
1507 AT_CHECK_M4SUGAR_TEXT(
1508 [[m4_bpatsubsts([11], [^..$])
1509 m4_bpatsubsts([11], [\(.\)1], [\12])
1510 m4_bpatsubsts([11], [^..$], [], [1], [2])
1511 m4_bpatsubsts([11], [\(.\)1], [\12], [1], [3])
1512 m4_define([a], [oops])m4_define([c], [oops])dnl
1513 m4_define([AB], [good])m4_define([bc], [good])dnl
1514 m4_bpatsubsts([abc], [a], [A], [b], [B], [c])
1515 m4_bpatsubsts([ab], [a])c
1516 m4_bpatsubsts([ab], [c], [C], [a])c
1517 m4_bpatsubsts([$1$*$@], [\$\*], [$#])
1530 ## -------------- ##
1532 ## -------------- ##
1534 AT_SETUP([m4@&t@_esyscmd_s])
1535 AT_KEYWORDS([m4@&t@_chomp m4@&t@_chomp_all])
1537 AT_CHECK_M4SUGAR_TEXT(
1538 [[m4_define([world], [WORLD])dnl
1543 m4_esyscmd_s([echo hello world])
1544 m4_esyscmd_s([echo '[goodbye,
1562 AT_SETUP([M4 loops])
1564 AT_KEYWORDS([m4@&t@_for m4@&t@_foreach m4@&t@_foreach_w m4@&t@_map_args_w])
1566 AT_CHECK_M4SUGAR_TEXT([[dnl
1567 m4_define([myvar], [outer value])dnl
1568 m4_for([myvar], 1, 3, 1, [ myvar])
1569 m4_for([myvar], 1, 3, , [ myvar])
1570 m4_for([myvar], 3, 1,-1, [ myvar])
1571 m4_for([myvar], 3, 1, , [ myvar])
1572 m4_for([myvar], 1, 3, 2, [ myvar])
1573 m4_for([myvar], 3, 1,-2, [ myvar])
1574 m4_for([myvar],-1,-3,-2, [ myvar])
1575 m4_for([myvar],-3,-1, 2, [ myvar])
1576 dnl Make sure we recalculate the bounds correctly:
1577 m4_for([myvar], 1, 3, 3, [ myvar])
1578 m4_for([myvar], 1, 6, 3, [ myvar])
1579 m4_for([myvar],22,-7,-5, [ myvar])
1580 m4_for([myvar],-2,-7,-4, [ myvar])
1581 m4_for([myvar],-7,-2, 4, [ myvar])
1582 dnl Make sure we are not exposed to division truncation:
1583 m4_for([myvar], 2, 5, 2, [ myvar])
1584 m4_for([myvar],-5,-2, 2, [ myvar])
1585 m4_for([myvar], 5, 2,-2, [ myvar])
1586 m4_for([myvar],-2,-5,-2, [ myvar])
1587 dnl Make sure we do not divide by zero:
1588 m4_for([myvar], 1, 1, , [ myvar])
1589 m4_for([myvar], 1, 1,+2, [ myvar])
1590 m4_for([myvar], 1, 1,-2, [ myvar])
1591 dnl Make sure we do not loop endlessly
1592 m4_for([myval], 1, 1, 0, [ myval])
1593 dnl Make sure to properly parenthesize
1594 m4_for([myvar], 3-5, -2+8, , [ myvar])
1595 m4_for([myvar], -2+8, 3-5, , [ myvar])
1596 m4_for([myvar], 8, 16, 3 * 2, [ myvar])
1597 m4_for([myvar], 8, 16, -3 * -2, [ myvar])
1598 m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar])
1599 dnl Modifying var does not affect the number of iterations
1600 m4_for([myvar], 1, 5, , [ myvar[]m4_define([myvar], 5)])
1601 dnl Make sure we can do nameless iteration
1602 m4_for(, 1, 10, , -)
1604 m4_foreach([myvar], [[a], [b, c], [d], [e
1606 m4_foreach_w([myvar], [a b c, d,e f
1609 m4_map_args_w([a b c, d,e f
1611 m4_map_args_w([a b], [\1], [/])
1612 m4_define([dashes], [--])dnl
1613 m4_map_args_w([a b c], [/], [\1], [dashes])
1614 dnl only one side effect expansion, prior to visiting list elements
1615 m4_foreach([i], [[1], [2], [3]m4_errprintn([hi])], [m4_errprintn(i)])dnl
1616 dnl shifting forms an important part of loops
1617 m4_shift3:m4_shift3(1,2,3):m4_shift3(1,2,3,4)
1618 m4_shiftn(3,1,2,3):m4_shiftn(3,1,2,3,4)
1650 a| b| c,| d,e| f| g|
1652 a| b| c,| d,e| f| g|
1663 dnl bounds checking in m4_for
1664 AT_DATA_M4SUGAR([script.4s],
1667 m4_for([myvar], 1, 3,-1, [ myvar])
1669 AT_CHECK_M4SUGAR([], 1, [],
1670 [[script.4s:3: error: assert failed: -1 > 0
1671 script.4s:3: the top level
1672 autom4te: error: m4 failed with exit status: 1
1675 AT_DATA_M4SUGAR([script.4s],
1678 m4_for([myvar], 1, 2, 0, [ myvar])
1680 AT_CHECK_M4SUGAR([], 1, [],
1681 [[script.4s:3: error: assert failed: 0 > 0
1682 script.4s:3: the top level
1683 autom4te: error: m4 failed with exit status: 1
1686 AT_DATA_M4SUGAR([script.4s],
1689 m4_for([myvar], 2, 1, 0, [ myvar])
1691 AT_CHECK_M4SUGAR([], 1, [],
1692 [[script.4s:3: error: assert failed: 0 < 0
1693 script.4s:3: the top level
1694 autom4te: error: m4 failed with exit status: 1
1697 dnl m4_shiftn also does bounds checking
1698 AT_DATA_M4SUGAR([script.4s],
1703 AT_CHECK_M4SUGAR([], 1, [],
1704 [[script.4s:3: error: assert failed: 0 < 3 && 3 < 3
1705 script.4s:3: the top level
1706 autom4te: error: m4 failed with exit status: 1
1712 ## --------------------- ##
1713 ## m4_map{,all}{,_sep}. ##
1714 ## --------------------- ##
1716 AT_SETUP([m4@&t@_map])
1717 AT_KEYWORDS([m4@&t@_apply m4@&t@_map_sep m4@&t@_mapall m4@&t@_mapall_sep])
1718 AT_KEYWORDS([m4@&t@_count])
1720 AT_CHECK_M4SUGAR_TEXT([[dnl
1721 m4_map([m4_count], [])
1722 m4_map([ m4_count], [[],
1725 m4_mapall([ m4_count], [[],
1728 m4_map_sep([m4_eval], [,], [[[1+2]],
1730 m4_count(m4_map_sep([m4_echo], [,], [[], [[1]], [[2]]]))
1731 m4_count(m4_mapall_sep([m4_echo], [,], [[], [[1]], [[2]]]))
1732 m4_map_sep([m4_eval], [[,]], [[[1+2]],
1734 m4_count(m4_map_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
1735 m4_count(m4_mapall_sep([m4_echo], [[,]], [[], [[1]], [[2]]]))
1737 m4_mapall([-], [[]])
1738 m4_map_sep([-], [:], [[]])
1739 m4_mapall_sep([-], [:], [[]])
1740 m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl
1741 m4_define([a1], [oops])dnl
1742 m4_define([pass1], [oops])dnl
1743 m4_map([a], [[[a]]])1
1744 m4_map([m4_unquote([a])], [m4_dquote([a])])
1745 dnl only one side effect expansion, prior to visiting list elements
1746 m4_map([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1747 m4_map_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1748 m4_mapall([m4_errprintn], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1749 m4_mapall_sep([m4_errprintn], [], [[[1]], [[2]], [[3]]m4_errprintn([hi])])dnl
1787 ## --------------------------------------- ##
1788 ## m4_map_args{,_sep,_pair} and m4_curry. ##
1789 ## --------------------------------------- ##
1791 AT_SETUP([m4@&t@_map_args and m4@&t@_curry])
1792 AT_KEYWORDS([m4@&t@_map_args_sep m4@&t@_map_args_pair m4@&t@_reverse
1795 dnl First, make sure we can curry in isolation.
1796 AT_CHECK_M4SUGAR_TEXT(
1797 [[m4_curry([m4_echo])([1])
1798 m4_curry([m4_curry], [m4_reverse], [1])([2])([3])
1799 m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1800 m4_define([add_one], [m4_curry([add], [1])])dnl
1808 dnl Now, check that we can map a list of arguments.
1809 AT_CHECK_M4SUGAR_TEXT([[m4_define([active], [ACTIVE])dnl
1810 m4_map_args([ m4_echo])
1811 m4_map_args([ m4_echo], [plain], [active])
1812 m4_map_args([m4_unquote], [plain], [active])
1813 m4_map_args_pair([, m4_reverse], [])
1814 m4_map_args_pair([, m4_reverse], [], [1])
1815 m4_map_args_pair([, m4_reverse], [], [1], [2])
1816 m4_map_args_pair([, m4_reverse], [], [1], [2], [3])
1817 m4_map_args_pair([, m4_reverse], [], [1], [2], [3], [4])
1818 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1])
1819 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2])
1820 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3])
1821 m4_map_args_pair([, m4_reverse], [, m4_dquote], [1], [2], [3], [4])
1822 m4_map_args_sep([<], [>], [:], [1], [2], [3])
1823 m4_map_args_sep([m4_echo(], [)], [ ], [plain], [active])
1841 dnl Finally, put the two concepts together, to show the real power of the API.
1842 AT_CHECK_M4SUGAR_TEXT(
1843 [[m4_define([add], [m4_eval(([$1]) + ([$2]))])dnl
1844 m4_define([list], [[-1], [0], [1]])dnl
1845 dnl list_add_n(value, arg...)
1846 dnl add VALUE to each ARG and output the resulting list
1847 m4_define([list_add_n],
1848 [m4_shift(m4_map_args([,m4_curry([add], [$1])], m4_shift($@)))])
1849 list_add_n([1], list)
1850 list_add_n([2], list)
1863 AT_SETUP([m4@&t@_combine])
1865 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
1866 m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
1867 m4_combine([, ], [[a], [b]], [-])
1868 m4_combine([, ], [[a], [b]], [-], [])
1869 m4_combine([, ], [], [-], [a], [b])
1870 m4_combine([, ], [[]], [-], [a], [b])
1871 m4_combine([ a ], [[-], [+]], [a], [-], [+])
1872 m4_combine([$* ], [[$1], [$2]], [$#], [$@])
1874 [[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
1879 -a- a -a+ a +a- a +a+
1886 ## -------------- ##
1888 ## -------------- ##
1890 AT_SETUP([m4@&t@_max and m4@&t@_min])
1892 AT_DATA_M4SUGAR([script.4s],
1896 AT_CHECK_M4SUGAR([], 1, [],
1897 [[script.4s:1: error: too few arguments to m4@&t@_max
1898 script.4s:1: the top level
1899 autom4te: error: m4 failed with exit status: 1
1902 AT_DATA_M4SUGAR([script.4s],
1906 AT_CHECK_M4SUGAR([], 1, [],
1907 [[script.4s:1: error: too few arguments to m4@&t@_min
1908 script.4s:1: the top level
1909 autom4te: error: m4 failed with exit status: 1
1912 AT_CHECK_M4SUGAR_TEXT([[dnl
1922 m4_min(1m4_for([i], 2, 100, , [,i]))
1923 m4_min(m4_for([i], 100, 2, , [i,])1)
1934 m4_max(1m4_for([i], 2, 100, , [,i]))
1935 m4_max(m4_for([i], 100, 2, , [i,])1)
1969 AT_SETUP([recursion])
1971 AT_KEYWORDS([m4@&t@_foreach m4@&t@_foreach_w m4@&t@_case m4@&t@_cond
1972 m4@&t@_bpatsubsts m4@&t@_shiftn m4@&t@_do m4@&t@_dquote_elt m4@&t@_reverse
1973 m4@&t@_map m4@&t@_join m4@&t@_joinall m4@&t@_list_cmp m4@&t@_max m4@&t@_min
1974 m4@&t@_bmatch m4@&t@_map_args m4@&t@_map_args_pair])
1976 dnl This test completes in a reasonable time if m4_foreach is linear,
1977 dnl but thrashes if it is quadratic. If we are testing with m4 1.4.x,
1978 dnl only the slower foreach.m4 implementation will work. But if we
1979 dnl are testing with m4 1.6, we can rerun the test with __m4_version__
1980 dnl undefined to exercise the alternate code path.
1981 AT_DATA_M4SUGAR([script.4s],
1983 m4_divert_push([])[]dnl
1984 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
1985 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
1986 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
1987 m4_len(m4_joinall([--], m4_map([, m4_echo],
1988 m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
1989 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
1990 [,i]))m4_for([i], [2], [10000], [], [,i]))
1991 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
1992 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
1993 m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
1994 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
1995 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
1996 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
1997 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
1998 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
1999 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
2000 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
2001 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
2002 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
2003 [1], [10000], [], [,i]))))
2007 AT_CHECK_M4SUGAR([-o-], [0], [[48894
2022 AT_DATA_M4SUGAR([script.4s],
2023 [[m4_ifdef([__m4_version__],
2024 [m4_undefine([__m4_version__])],
2025 [m4_divert_push([])48894
2040 m4_divert_push([])[]dnl
2041 m4_len(m4_foreach_w([j], m4_do(m4_for([i], [1], [10000], [], [,i ])), [j ]))
2042 m4_shiftn(9998m4_for([i], [1], [10000], [], [,i]))
2043 m4_len(m4_join([--],, m4_dquote_elt(m4_for([i], [1], [10000], [], [,i])),))
2044 m4_len(m4_joinall([--], m4_map([, m4_echo],
2045 m4_dquote([1]m4_for([i], [2], [10000], [], [,i])))))
2046 m4_max(m4_min([1]m4_for([i], [2], [10000], [],
2047 [,i]))m4_for([i], [2], [10000], [], [,i]))
2048 m4_case([10000]m4_for([i], [1], [10000], [], [,i]),[end])
2049 m4_list_cmp(m4_dquote(1m4_for([i], [2], [10000], [], [,i])),
2050 m4_dquote(m4_reverse(10000m4_for([i], [9999], [1], [], [,i])), [0]))
2051 m4_list_cmp([0], [0m4_for([i], [1], [10000], [], [,0])])
2052 m4_list_cmp([0m4_for([i], [1], [10000], [], [,0])], [0])
2053 m4_for([i], [1], [10000], [], [m4_define(i)])dnl
2054 m4_undefine(1m4_for([i], [2], [10000], [], [,i]))dnl
2055 m4_bpatsubsts([a1]m4_for([i], [1], [10000], [], [,i]), [a2], [A])
2056 m4_bmatch([9997]m4_for([i], [1], [10000], [], [,^i$]))
2057 m4_define([up], [m4_define([$1], m4_incr($1))$1])m4_define([j], 0)dnl
2058 m4_cond(m4_for([i], [1], [10000], [], [[up([j])], [9990], i,]) [oops]) j
2059 m4_count(m4_map_args_pair([,m4_quote], []m4_map_args([,m4_echo]m4_for([i],
2060 [1], [10000], [], [,i]))))
2064 AT_CHECK_M4SUGAR([-o-], [0], [[48894
2086 AT_SETUP([m4@&t@_set])
2088 AT_KEYWORDS([m4@&t@_set_add m4@&t@_set_add_all m4@&t@_set_contains
2089 m4@&t@_set_contents m4@&t@_set_delete m4@&t@_set_difference m4@&t@_set_dump
2090 m4@&t@_set_empty m4@&t@_set_foreach m4@&t@_set_intersection m4@&t@_set_list
2091 m4@&t@_set_listc m4@&t@_set_map m4@&t@_set_remove m4@&t@_set_size
2095 AT_CHECK_M4SUGAR_TEXT([[m4_set_contains([a], [1], [yes], [no])
2096 m4_set_add([a], [1], [added], [dup])
2097 m4_set_contains([a], [1], [yes], [no])
2098 m4_set_add([a], [1], [added], [dup])
2099 m4_set_contents([a])
2100 m4_set_remove([a], [1], [removed], [missing])
2101 m4_set_contains([a], [1], [yes], [no])
2102 m4_set_remove([a], [1], [removed], [missing])
2103 m4_set_add([a], [2], [added], [dup])
2104 m4_set_empty([a], [yes], [no])
2106 m4_set_empty([a], [yes], [no])
2107 m4_set_add_all([c], [1], [2], [3])
2108 m4_set_add_all([a]m4_set_listc([c]))
2109 m4_set_contents([c], [-])
2110 m4_set_dump([a], [-])
2111 m4_set_contents([a])
2112 m4_set_add_all([a], [1], [2], [3])m4_set_add_all([b], [3], [], [4])
2113 m4_set_difference([a], [b])
2114 m4_set_difference([b], [a])
2115 m4_set_intersection([a], [b])
2116 m4_set_union([a], [b])
2117 m4_define([printodd], [m4_if(m4_eval([$1 & 1]), [1], [:$1])])dnl
2118 m4_set_map([a], [printodd])
2119 m4_set_foreach([a], [i], [m4_if(m4_eval(i & 1), [1], [m4_set_remove([a], i)])])
2123 m4_set_remove([a], [2])
2124 m4_dquote(m4_set_list([a]))
2128 m4_dquote(m4_set_list([a]))
2129 m4_indir([m4_dquote]m4_set_listc([a]))
2170 # Stress tests - check for unusual names/values
2171 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
2172 m4_set_add([a], [a])dnl
2173 m4_set_remove([a], [oops], [yes], [no])
2174 m4_set_add([a,b], [c])dnl
2175 m4_set_add([a,b], [$*[]])dnl
2176 m4_set_add_all([a], [b,c])dnl
2178 m4_count(m4_set_contents([a], [,]))
2179 m4_count(m4_set_list([a], [,]))
2180 m4_set_dump([a], [,])
2181 m4_set_contents([a,b], [,])
2183 m4_set_foreach([$*[]], [$*[]], [oops])
2184 m4_set_add([$*[]], [])dnl
2185 m4_set_remove([$*[]], [a], [yes], [no])
2186 m4_set_add([$*[]], [a])dnl
2187 m4_set_foreach([$*[]], [$*[]], [-m4_defn([$*[]])m4_indir([$*[]])-])
2188 m4_set_remove([$*[]], [], [yes], [no])
2189 m4_set_add([c], [,])dnl
2190 m4_set_foreach([a,b], [set], [:m4_set_listc(_m4_defn([set])):])
2205 # Stress tests - check for linear scaling (won't necessarily fail if
2206 # quadratic, but hopefully users will complain if it appears to hang)
2207 AT_CHECK_M4SUGAR_TEXT([[dnl
2208 m4_for([i], [1], [10000], [], [m4_set_add([a], i)])dnl
2209 m4_set_add_all([b]m4_for([i], [1], [10000], [], [,i]))dnl
2210 m4_set_remove([a], [1])dnl
2211 m4_set_remove([b], [10000])dnl
2212 m4_set_add_all([a]m4_for([i], [1], [10000], [], [,i]))dnl
2213 m4_for([i], [1], [10000], [], [m4_set_add([b], i)])dnl
2214 m4_len(m4_set_contents([a]))
2215 m4_len(m4_set_foreach([b], [b], [m4_if(m4_eval(b & 1), [1],
2216 [m4_set_remove([b], b, [-])])]))
2218 m4_define([prune3x], [m4_if(m4_eval([$1 % 3]), [0],
2219 [m4_set_remove([a], [$1], [-])])])dnl
2220 m4_len(m4_set_map([a], [prune3x]))
2221 m4_count(m4_shift(m4_set_intersection([a], [b])))
2232 ## ---------------------- ##
2233 ## __file__ and __line__. ##
2234 ## ---------------------- ##
2236 AT_SETUP([[__file__ and __line__]])
2238 # Check that __file__ and __line__ work.
2239 # Check that m4__file__ and m4__line__ are not defined
2240 # (and get them to pass by the undefined-macro check).
2241 # Try to not assume too much about AT_CHECK_M4SUGAR_TEXT.
2242 AT_CHECK_M4SUGAR_TEXT([[dnl
2243 m4_pattern_allow([m4__file__])dnl
2244 m4_pattern_allow([m4__line__])dnl
2248 m4_define([first], __line__)dnl
2249 m4_define([second], __line__)dnl
2250 m4_assert(first + 1 == second)dnl
2251 ]], [[m4@&t@__@&t@file__