Add m4_joinall.
[autoconf.git] / tests / m4sugar.at
blobb6a4cac5ebf253af636410f7edf10ac3636d4906
1 #                                                       -*- Autotest -*-
3 AT_BANNER([M4sugar.])
5 # Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software
6 # Foundation, Inc.
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 # 02110-1301, USA.
24 # AT_CHECK_M4SUGAR_TEXT(CODE, STDOUT, STDERR)
25 # -------------------------------------------
26 # Check that m4sugar CODE expands to STDOUT and emits STDERR.
27 m4_define([AT_CHECK_M4SUGAR_TEXT],
29 AT_DATA_M4SUGAR([script.4s],
30 [[m4_init
31 m4_divert_push(0)[]dnl
32 ]$1[[]dnl
33 m4_divert_pop(0)
34 ]])
36 AT_CHECK_M4SUGAR([-o-],, [$2], [$3])
37 ])# AT_CHECK_M4SUGAR_TEXT
40 # Order of the tests:
41 # - m4_warn
43 # - m4_require
44 # uses warn/error code.
46 # - m4_split
48 # - m4_append
50 # - m4_join
52 # - m4_text_wrap
53 # uses m4_split code.
55 ## --------- ##
56 ## m4_warn.  ##
57 ## --------- ##
59 AT_SETUP([m4@&t@_warn])
61 # m4_text_wrap is used to display the help strings.  Also, check that
62 # commas are not swallowed.  This can easily happen because of
63 # m4-listification.
65 # FIXME: For the time being we use -f to make sure we do issue the
66 # warnings.  But maybe autom4te should handle that by itself?
68 AT_DATA_M4SUGAR([script.4s],
69 [[m4_init
70 m4_defun([cross_warning], [m4_warn([cross],  [cross])])
72 m4_divert([0])dnl
73 m4_warn([obsolete],  [obsolete])dnl
74 cross_warning[]dnl
75 m4_warn([syntax], [syntax])dnl
76 ]])
78 AT_CHECK_M4SUGAR([-o-], 0, [],
79 [script.4s:7: warning: syntax
82 AT_CHECK_M4SUGAR([-o- -Wall -f], 0, [],
83 [script.4s:5: warning: obsolete
84 script.4s:6: warning: cross
85 script.4s:2: cross_warning is expanded from...
86 script.4s:6: the top level
87 script.4s:7: warning: syntax
90 AT_CHECK_M4SUGAR([-o- -Wnone,cross -f], 0, [],
91 [script.4s:6: warning: cross
92 script.4s:2: cross_warning is expanded from...
93 script.4s:6: the top level
96 AT_CHECK_M4SUGAR([-o- -Wnone,cross,error -f], 1, [],
97 [[script.4s:6: warning: cross
98 script.4s:2: cross_warning is expanded from...
99 script.4s:6: the top level
102 AT_CLEANUP
105 ## --------------------------- ##
106 ## m4_require: error message.  ##
107 ## --------------------------- ##
109 AT_SETUP([m4@&t@_require: error message])
111 AT_DATA_M4SUGAR([script.4s],
112 [[m4_defun([foo], [FOO])
113 m4_require([foo])
116 AT_CHECK_M4SUGAR([], 1, [],
117 [[script.4s:2: error: m4@&t@_require(foo): cannot be used outside of an m4_defun'd macro
118 script.4s:2: the top level
119 autom4te: m4 failed with exit status: 1
121 AT_CLEANUP
124 ## ----------------------------------- ##
125 ## m4_require: circular dependencies.  ##
126 ## ----------------------------------- ##
128 AT_SETUP([m4@&t@_require: circular dependencies])
130 AT_DATA_M4SUGAR([script.4s],
131 [[m4_defun([foo], [m4_require([bar])])
133 m4_defun([bar], [m4_require([foo])])
135 m4_defun([baz], [m4_require([foo])])
137 m4_init
138 m4_divert([0])dnl
142 AT_CHECK_M4SUGAR([], 1, [],
143 [[script.4s:9: error: m4@&t@_require: circular dependency of foo
144 script.4s:3: bar is expanded from...
145 script.4s:1: foo is expanded from...
146 script.4s:5: baz is expanded from...
147 script.4s:9: the top level
148 autom4te: m4 failed with exit status: 1
150 AT_CLEANUP
153 ## ---------- ##
154 ## m4_split.  ##
155 ## ---------- ##
157 AT_SETUP([m4@&t@_split])
159 AT_CHECK_M4SUGAR_TEXT(
160 [[m4_define([active], [ACT, IVE])m4_define([bd], [oops])
161 m4_split
162 m4_split([[]])
163 m4_split([ ])
164 m4_split([active])
165 m4_split([ active       active ])end
166 m4_split([ ], [ ])
167 m4_split([active], [ ])
168 m4_split([ active       active ], [ ])end
169 m4_split([abcde], [bd])
170 m4_split([abcde], [[bd]])
171 m4_split([foo=`` bar=''])
172 m4_split([foo='' bar=``])
173 dnl these next two are from the manual; keep this in sync if the internal
174 dnl quoting strings in m4_split are changed
175 m4_define([a], [A])m4_define([b], [B])m4_define([c], [C])dnl
176 m4_split([a )}>=- b -=<{( c])
177 m4_split([a )}@&t@>=- b -=<@&t@{( c])
181 [[]]
182 [], []
183 [active]
184 [], [active], [active], []end
185 [], []
186 [active]
187 [], [active     active], []end
188 [abcde]
189 [a], [c], [e]
190 [foo=``], [bar='']
191 [foo=''], [bar=``]
192 [a], [], [B], [], [c]
193 [a], [)}>=-], [b], [-=<{(], [c]
196 AT_CLEANUP
199 ## ----------- ##
200 ## m4_append.  ##
201 ## ----------- ##
203 AT_SETUP([m4@&t@_append])
205 AT_CHECK_M4SUGAR_TEXT(
206 [[m4_define([active], [ACTIVE])dnl
207 m4_append([sentence], [This is an])dnl
208 m4_append([sentence], [ active ])dnl
209 m4_append([sentence], [symbol.])dnl
210 sentence
211 m4_undefine([active])dnl
212 sentence
213 m4_define([active], [ACTIVE])dnl
214 m4_append([hooks], [m4_define([act1], [act2])])dnl
215 m4_append([hooks], [m4_define([act2], [active])])dnl
216 m4_undefine([active])dnl
217 act1
218 hooks
219 act1
220 dnl Test for bug fixed in 2.62 when separator is active.
221 m4_define([a], [A])dnl
222 m4_append_uniq([foo], [-], [a])dnl
223 m4_append_uniq([foo], [-], [a])dnl
224 m4_append_uniq([bar], [-], [a])dnl
225 m4_append_uniq([bar], [~], [a])dnl
226 m4_append_uniq([bar], [-], [a])dnl
227 m4_defn([foo])
228 m4_defn([bar])
231 m4_append_uniq([blah], [one], [, ], [new], [existing])
232 m4_append_uniq([blah], [two], [, ], [new], [existing])
233 m4_append_uniq([blah], [two], [, ], [new], [existing])
234 m4_append_uniq([blah], [three], [, ], [new], [existing])
235 m4_append([blah], [two], [, ])dnl
236 blah
237 m4_dquote(blah)
238 m4_append([list], [one], [[, ]])dnl
239 m4_append([list], [two], [[, ]])dnl
240 m4_append([list], [three], [[, ]])dnl
241 list
242 m4_dquote(list)
243 m4_append_uniq_w([numbers], [1 1 2])dnl
244 m4_append_uniq_w([numbers], [ 2 3 ])dnl
245 numbers
247 [[This is an ACTIVE symbol.
248 This is an active symbol.
249 act1
251 active
258 existing
260 one, two, three, two
261 [one],[two],[three],[two]
262 one, two, three
263 [one, two, three]
264 1 2 3
267 AT_DATA_M4SUGAR([script.4s],
268 [[m4_append_uniq([str], [a], [ ])
269 m4_append_uniq([str], [a b], [ ])
270 m4_divert([0])dnl
274 AT_CHECK_M4SUGAR([-o-], 0, [[a a b
275 ]], [[script.4s:2: warning: m4@&t@_append_uniq: `a b' contains ` '
278 AT_CLEANUP
281 ## --------- ##
282 ## m4_join.  ##
283 ## --------- ##
285 AT_SETUP([m4@&t@_join])
287 AT_KEYWORDS([m4@&t@_joinall])
289 AT_CHECK_M4SUGAR_TEXT(
290 [[m4_define([active], [ACTIVE])
291 m4_join
292 m4_join([|])
293 m4_join([, ], [one], [two])
294 m4_dquote(m4_join([, ], [one], [two]))
295 m4_join([|], [active], [active])
296 m4_join([|], ,,,[one])
297 m4_join([|], [one],,,)
298 m4_join([], ,,,[two])
299 m4_join([], [two],,,)
300 m4_join([ active ], [one], , [two])
301 m4_join([], [one], [two])
302 m4_joinall([-], [one], [], [two])
303 m4_joinall([-], [], [], [three], [], [])
304 m4_joinall([], [one], [], [two])
305 m4_joinall
306 m4_joinall([-])
307 m4_joinall([-], [one])
312 one, two
313 [one, two]
314 active|active
319 one active two
320 onetwo
321 one--two
322 --three--
323 onetwo
329 AT_CLEANUP
332 ## -------------- ##
333 ## m4_text_wrap.  ##
334 ## -------------- ##
336 AT_SETUP([m4@&t@_text_wrap])
338 # m4_text_wrap is used to display the help strings.  Also, check that
339 # commas and $ are not swallowed.  This can easily happen because of
340 # m4-listification.
342 AT_DATA_M4SUGAR([script.4s],
343 [[m4_divert([0])dnl
344 m4_text_wrap([Short string */], [   ], [/* ], 20)
346 m4_text_wrap([Much longer string */], [   ], [/* ], 20)
348 m4_text_wrap([Short doc.], [          ], [  --short ], 30)
350 m4_text_wrap([Short doc.], [          ], [  --too-wide], 30)
352 m4_text_wrap([Super long documentation.], [          ], [  --too-wide], 30)
354 m4_text_wrap([First, second  , third, [,quoted]])
355 m4_define([xfff], [oops])
356 m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
359 AT_DATA([expout],
360 [[/* Short string */
362 /* Much longer
363    string */
365   --short Short doc.
367   --too-wide
368           Short doc.
370   --too-wide
371           Super long
372           documentation.
374 First, second , third, [,quoted]
376  $@ Some $1 $2 $3
377  $* $4 embedded
378  $* dollars.
381 AT_CHECK_M4SUGAR([-o-], 0, [expout])
383 AT_CLEANUP
385 ## -------------------- ##
386 ## m4_version_compare.  ##
387 ## -------------------- ##
389 AT_SETUP([m4@&t@_version_compare])
391 AT_CHECK_M4SUGAR_TEXT(
392 [[m4_version_compare([1.1], [2.0])
393 m4_version_compare([2.0b], [2.0a])
394 m4_version_compare([2.0z], [2.0y])
395 m4_version_compare([1.1.1], [1.1.1a])
396 m4_version_compare([1.2], [1.1.1a])
397 m4_version_compare([1.0], [1])
398 m4_version_compare([1.0a], [1.0a])
399 m4_version_compare([1.1a], [1.1a.1])
400 m4_version_compare([1.10], [1.1a])
401 m4_version_compare([1-1a], [1,1A])
402 m4_define([a], [oops])dnl
403 m4_version_compare([1.1a], [1.1A])
404 m4_version_compare([1z], [1aa])
405 m4_version_compare([2.61a], [2.61a-248-dc51])
406 m4_version_compare([2.61b], [2.61a-248-dc51])
408 [[-1
424 AT_CLEANUP
426 ## ------------------------------ ##
427 ## Standard regular expressions.  ##
428 ## ------------------------------ ##
430 AT_SETUP([Standard regular expressions])
432 # AT_CHECK_M4RE(RE-NAME, TEXT, INTENT = `ok' | `')
433 # ------------------------------------------------
434 # Check whether RE-NAME (a macro whose definition is a regular expression)
435 # matches TEXT.  INTENT = `ok' if the match should succeed or else empty.
436 m4_define([AT_CHECK_M4RE],
437 [AT_CHECK_M4SUGAR_TEXT(
438 [[m4_bregexp([$2], ^m4_defn([$1])$, [ok])
439 ]], [$3
440 ])])
442 AT_CHECK_M4RE([m4_re_word], [ab9_c], [ok])
443 AT_CHECK_M4RE([m4_re_word], [_9abc], [ok])
444 AT_CHECK_M4RE([m4_re_word], [9ab_c])
446 AT_CHECK_M4RE([m4_re_string], [ab9_c], [ok])
447 AT_CHECK_M4RE([m4_re_string], [_9abc], [ok])
448 AT_CHECK_M4RE([m4_re_string], [9ab_c], [ok])
449 AT_CHECK_M4RE([m4_re_string], [9a@_c])
451 AT_CLEANUP
453 ## ---------- ##
454 ## M4 Loops.  ##
455 ## ---------- ##
457 AT_SETUP([M4 loops])
459 AT_CHECK_M4SUGAR_TEXT([[dnl
460 m4_define([myvar], [outer value])dnl
461 m4_for([myvar], 1, 3, 1, [ myvar])
462 m4_for([myvar], 1, 3,  , [ myvar])
463 m4_for([myvar], 3, 1,-1, [ myvar])
464 m4_for([myvar], 3, 1,  , [ myvar])
465 m4_for([myvar], 1, 3, 2, [ myvar])
466 m4_for([myvar], 3, 1,-2, [ myvar])
467 m4_for([myvar],-1,-3,-2, [ myvar])
468 m4_for([myvar],-3,-1, 2, [ myvar])
469 dnl Make sure we recalculate the bounds correctly:
470 m4_for([myvar], 1, 3, 3, [ myvar])
471 m4_for([myvar], 1, 6, 3, [ myvar])
472 m4_for([myvar],22,-7,-5, [ myvar])
473 m4_for([myvar],-2,-7,-4, [ myvar])
474 m4_for([myvar],-7,-2, 4, [ myvar])
475 dnl Make sure we are not exposed to division truncation:
476 m4_for([myvar], 2, 5, 2, [ myvar])
477 m4_for([myvar],-5,-2, 2, [ myvar])
478 m4_for([myvar], 5, 2,-2, [ myvar])
479 m4_for([myvar],-2,-5,-2, [ myvar])
480 dnl Make sure we do not divide by zero:
481 m4_for([myvar], 1, 1,  , [ myvar])
482 m4_for([myvar], 1, 1,+2, [ myvar])
483 m4_for([myvar], 1, 1,-2, [ myvar])
484 dnl Make sure we do not loop endlessly
485 m4_for([myval], 1, 1, 0, [ myval])
486 dnl Make sure to properly parenthesize
487 m4_for([myvar], 3-5, -2+8, , [ myvar])
488 m4_for([myvar], -2+8, 3-5, , [ myvar])
489 m4_for([myvar], 8, 16, 3 * 2, [ myvar])
490 m4_for([myvar], 8, 16, -3 * -2, [ myvar])
491 m4_for([myvar], [2<<2], [2<<3], [-3 * (-2)], [ myvar])
492 dnl Make sure we can do nameless iteration
493 m4_for(, 1, 10, , -)
494 dnl foreach tests
495 m4_foreach([myvar], [[a], [b, c], [d], [e
496 ],[f]], [ myvar|])
497 m4_foreach_w([myvar], [a  b c, d,e f
498 g], [ myvar|])
499 myvar
501 [[ 1 2 3
502  1 2 3
503  3 2 1
504  3 2 1
505  1 3
506  3 1
507  -1 -3
508  -3 -1
510  1 4
511  22 17 12 7 2 -3
512  -2 -6
513  -7 -3
514  2 4
515  -5 -3
516  5 3
517  -2 -4
522  -2 -1 0 1 2 3 4 5 6
523  6 5 4 3 2 1 0 -1 -2
524  8 14
525  8 14
526  8 14
527 ----------
528  a| b, c| d| e
529 | f|
530  a| b| c,| d,e| f| g|
531 outer value
532 ]], [])
534 AT_DATA_M4SUGAR([script.4s],
535 [[m4_init
536 m4_divert([0])dnl
537 m4_for([myvar], 1, 3,-1, [ myvar])
540 AT_CHECK_M4SUGAR([], 1, [],
541 [[script.4s:3: error: assert failed: -1 > 0
542 script.4s:3: the top level
543 autom4te: m4 failed with exit status: 1
546 AT_DATA_M4SUGAR([script.4s],
547 [[m4_init
548 m4_divert([0])dnl
549 m4_for([myvar], 1, 2, 0, [ myvar])
552 AT_CHECK_M4SUGAR([], 1, [],
553 [[script.4s:3: error: assert failed: 0 > 0
554 script.4s:3: the top level
555 autom4te: m4 failed with exit status: 1
558 AT_DATA_M4SUGAR([script.4s],
559 [[m4_init
560 m4_divert([0])dnl
561 m4_for([myvar], 2, 1, 0, [ myvar])
564 AT_CHECK_M4SUGAR([], 1, [],
565 [[script.4s:3: error: assert failed: 0 < 0
566 script.4s:3: the top level
567 autom4te: m4 failed with exit status: 1
569 AT_CLEANUP
572 ## --------------- ##
573 ## m4_map{,_sep}.  ##
574 ## --------------- ##
576 AT_SETUP([m4@&t@_map])
577 AT_KEYWORDS([m4@&t@_apply])
578 AT_KEYWORDS([m4@&t@_count])
580 AT_CHECK_M4SUGAR_TEXT([[dnl
581 m4_map([m4_count], [])
582 m4_map([ m4_count], [[],
583                      [[1]],
584                      [[1], [2]]])
585 m4_map_sep([m4_eval], [,], [[[1+2]],
586                             [[10], [16]]])
587 m4_define([a], [m4_if([$#], [0], [oops], [$1], [a], [pass], [oops])])dnl
588 m4_define([a1], [oops])dnl
589 m4_define([pass1], [oops])dnl
590 m4_map([a], [[[a]]])1
591 m4_map([m4_unquote([a])], [m4_dquote([a])])
594  0 1 2
596 pass1
597 pass
598 ]], [])
600 AT_CLEANUP
603 ## ------------ ##
604 ## m4_combine.  ##
605 ## ------------ ##
607 AT_SETUP([m4@&t@_combine])
609 AT_CHECK_M4SUGAR_TEXT([[m4_define([a], [oops])dnl
610 m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3])
611 m4_combine([, ], [[a], [b]], [-])
612 m4_combine([, ], [[a], [b]], [-], [])
613 m4_combine([, ], [], [-], [a], [b])
614 m4_combine([, ], [[]], [-], [a], [b])
615 m4_combine([ a ], [[-], [+]], [a], [-], [+])
616 m4_combine([$* ], [[$1], [$2]], [$#], [$@])
618 [[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
620 a-, b-
622 -a, -b
623 -a- a -a+ a +a- a +a+
624 $1$#$@$* $2$#$@
625 ]], [])
627 AT_CLEANUP
630 ## -------------- ##
631 ## m4_{max,min}.  ##
632 ## -------------- ##
634 AT_SETUP([m4@&t@_max and m4@&t@_min])
636 AT_DATA_M4SUGAR([script.4s],
637 [[m4_max
640 AT_CHECK_M4SUGAR([], 1, [],
641 [[script.4s:1: error: too few arguments to m4@&t@_max
642 script.4s:1: the top level
643 autom4te: m4 failed with exit status: 1
646 AT_DATA_M4SUGAR([script.4s],
647 [[m4_min
650 AT_CHECK_M4SUGAR([], 1, [],
651 [[script.4s:1: error: too few arguments to m4@&t@_min
652 script.4s:1: the top level
653 autom4te: m4 failed with exit status: 1
656 AT_CHECK_M4SUGAR_TEXT([[dnl
657 m4_min(0)
658 m4_min(0xa)
659 m4_min(0, 0)
660 m4_min(0, 1)
661 m4_min(1, 0)
662 m4_min(0+1, 1+1)
663 m4_min(0+1, 1+0)
664 m4_min(0, 1, 2)
665 m4_min(2, 1, 0)
666 m4_min(1m4_for([i], 2, 100, , [,i]))
667 m4_min(m4_for([i], 100, 2, , [i,])1)
668 ----
669 m4_max(0)
670 m4_max(0xa)
671 m4_max(0, 0)
672 m4_max(0, 1)
673 m4_max(1, 0)
674 m4_max(1+0, 1+1)
675 m4_max(1+0, 1+0)
676 m4_max(0, 1, 2)
677 m4_max(2, 1, 0)
678 m4_max(1m4_for([i], 2, 100, , [,i]))
679 m4_max(m4_for([i], 100, 2, , [i,])1)
692 ----
704 ]], [])
706 AT_CLEANUP