Silence verbose testsuite runs.
[m4.git] / tests / builtins.at
blob4f1192717c90988b862036de6dc59df7307dcc09
1 # Hand crafted tests for GNU M4.                               -*- Autotest -*-
2 # Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 # This file is part of GNU M4.
6 # GNU M4 is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # GNU M4 is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 AT_BANNER([Torturing builtins.])
22 ## -------- ##
23 ## __file__ ##
24 ## -------- ##
26 AT_SETUP([__@&t@file__])
28 dnl Unfortunately, AT_DATA does not make it easy to create files without
29 dnl a trailing newline.
30 [echo $ECHO_N "__line"__:__"file__$ECHO_C"] > nested
31 AT_DATA([outer],
32 [[__file__:__line__
33 include(`nested')
34 __file__:__line__
35 ]])
37 dnl Make sure line numbers are consistent, even if include file does not
38 dnl end with a newline
39 AT_CHECK_M4([outer], [0],
40 [[outer:1
41 1:nested
42 outer:3
43 ]])
45 AT_CLEANUP
48 ## -------- ##
49 ## __line__ ##
50 ## -------- ##
52 AT_SETUP([__@&t@line__])
54 dnl Unfortunately, AT_DATA does not make it easy to create files without
55 dnl a trailing newline.
56 [echo $ECHO_N "__file"__:__"line__$ECHO_C"] > nested
57 AT_DATA([outer],
58 [[__file__:__line__
59 include(`nested')
60 __file__:__line__
61 ]])
63 dnl Make sure line numbers are consistent, even if include file does not
64 dnl end with a newline
65 AT_CHECK_M4([outer], [0],
66 [[outer:1
67 nested:1
68 outer:3
69 ]])
71 AT_CLEANUP
74 ## -------------- ##
75 ## __m4_version__ ##
76 ## -------------- ##
78 AT_SETUP([__m4_@&t@version__])
80 AT_DATA([in], [[defn(`__m4_version__')
81 ]])
82 AT_CHECK_M4([--version], [0], [stdout])
83 AT_CHECK([[$SED -e 's/.*(GNU M4\(.*\)) \([^ ]*\).*/\2\1/;q' < stdout]],
84 [0], [stdout])
85 mv stdout expout
86 AT_CHECK_M4([in], [0], [expout])
88 dnl Prove that __m4_version__ is unquoted, by making '.' an active character.
89 AT_DATA([in], [[changesyntax(`A.')define(`.', `errprint(`hi
90 ')undefine(`.').')dnl
91 __m4_version__
92 ]])
93 AT_CHECK_M4([in], [0], [expout], [[hi
94 ]])
96 AT_CLEANUP
99 ## ------- ##
100 ## builtin ##
101 ## ------- ##
103 AT_SETUP([builtin])
105 dnl This was a regression in 1.4.10b.
106 AT_DATA([in.m4],
107 [[define(`s', `builtin(`shift', $@)')dnl
108 define(`loop', `ifelse(`$2', `', `-', `$1$2: $0(`$1', s(s($@)))')')dnl
109 loop(`1')
110 loop(`1', `2')
111 loop(`1', `2', `3')
112 loop(`1', `2', `3', `4')
113 loop(`1', `2', `3', `4', `5')
115 AT_CHECK_M4([in.m4], [0],
117 12: -
118 12: 13: -
119 12: 13: 14: -
120 12: 13: 14: 15: -
123 AT_CLEANUP
126 ## ----------- ##
127 ## changequote ##
128 ## ----------- ##
130 AT_SETUP([changequote])
132 AT_DATA([in.m4],
133 [[define(`aaaaaaaaaaaaaaaaaaaa', `A')define(`q', `"$@"')
134 changequote(`"', `"')
135 q(q("aaaaaaaaaaaaaaaaaaaa", "a"))
136 changequote`'define(`echo', `$@')dnl
137 changequote(`<<<', `>>')dnl
138 echo(<<<a<<<b>>>>)
141 AT_CHECK_M4([in.m4], [0], [[
144 a<<<b>>
147 AT_CLEANUP
150 ## ----- ##
151 ## debug ##
152 ## ----- ##
154 AT_SETUP([debug])
156 AT_DATA([[debug.m4]],
157 [[define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')')
158 debugmode(`aeqc')
159 traceon(`countdown')
160 countdown(2)
163 AT_DATA([[expout]],
167 2 1 0 Liftoff
170 AT_DATA([[experr]],
171 [[m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
172 m4trace: -1- countdown(`2') -> `2 ifelse(eval(2 > 0), 1, `countdown(decr(2))', `Liftoff')'
173 m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
174 m4trace: -1- countdown(`1') -> `1 ifelse(eval(1 > 0), 1, `countdown(decr(1))', `Liftoff')'
175 m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
176 m4trace: -1- countdown(`0') -> `0 ifelse(eval(0 > 0), 1, `countdown(decr(0))', `Liftoff')'
179 AT_CHECK_M4([debug.m4], 0, expout, experr)
181 dnl Test a regression introduced 2008-05-08, fixed 2008-07-30.
182 AT_DATA([debug.m4], [[debugmode(`e')traceon(`ifelse')dnl
183 define(`e', `ifelse(`$1', `$2', `ifelse(`$1', `$2', `e(shift($@))')', `$2')')
184 e(`1', `1', `a')
187 AT_CHECK_M4([debug.m4], [0], [[
189 ]], [[m4trace: -1- ifelse -> ifelse(`1', `1', `e(shift(`1',`1',`a'))')
190 m4trace: -1- ifelse -> e(shift(`1',`1',`a'))
191 m4trace: -1- ifelse -> a
194 AT_CLEANUP
197 ## ------ ##
198 ## define ##
199 ## ------ ##
201 AT_SETUP([define])
203 AT_DATA([[define.m4]],
204 [[undefine(`macro')dnl
205 pushdef(`macro', `base value')dnl
206 pushdef(`macro', `hello, world')dnl
207 pushdef(`macro', `top value')dnl
208 define(`macro', `new value')dnl
209 macro.
210 popdef(`macro')dnl
211 macro.
212 popdef(`macro')dnl
213 macro.
216 AT_CHECK_M4([define.m4], 0,
217 [[new value.
218 hello, world.
219 base value.
220 ]], [[m4:define.m4:1: Warning: undefine: undefined macro `macro'
223 AT_CHECK_M4([--traditional define.m4], 0,
224 [[new value.
225 hello, world.
226 base value.
227 ]], [[m4:define.m4:1: Warning: undefine: undefined macro `macro'
230 dnl check regression present 2008-02-22 to 2008-04-30.
231 AT_DATA([in.m4], [[define(`qq', ``$*;$@'')dnl
232 define(`foo', qq(`a', `b'))dnl
234 defn(`foo')
236 AT_CHECK_M4([in.m4], [0], [[a,b;a,b
237 a,b;`a',`b'
240 AT_CLEANUP
244 ## ---- ##
245 ## defn ##
246 ## ---- ##
248 AT_SETUP([defn])
250 AT_DATA([[in.m4]],
251 [[define(`e', `$@')define(`q', ``$@'')define(`u', `$*')
252 define(`cmp', `ifelse($1, $2, `yes', `no')')define(`d', defn(`defn'))
253 cmp(`defn(`defn')', `defn(`d')')
254 cmp(`defn(`defn')', ``<defn>'')
255 cmp(`q(defn(`defn'))', `q(defn(`d'))')
256 cmp(`q(defn(`defn'))', `q(`<defn>')')
257 cmp(`q(defn(`defn'))', ``'')
258 cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', defn(`d'))')
259 cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', `<defn>')')
260 cmp(`q(`1', `2', defn(`defn'))', ```1',`2',<defn>'')
261 cmp(`q(`1', `2', defn(`defn'))', ```1',`2',`''')
262 define(`cat', `$1`'ifelse(`$@%:@', `1', `', `$0(shift($@))')')
263 cat(`define(`foo',', defn(`divnum'), `)foo')
264 cat(e(`define(`bar',', defn(`divnum'), `)bar'))
265 m4wrap(`u('q(`cat(`define(`baz','', defn(`divnum'), ``)baz')')`)
269 AT_CHECK_M4([in.m4], [0], [[
287 AT_CLEANUP
290 ## ------ ##
291 ## divert ##
292 ## ------ ##
294 AT_SETUP([divert])
296 AT_DATA([[divert.m4]],
297 [[divert(1)Text diverted a first time.
298 divert(0)undivert(1)dnl
299 divert(1)Text diverted a second time.
300 divert(0)undivert(1)dnl
303 AT_CHECK_M4([divert.m4], 0,
304 [[Text diverted a first time.
305 Text diverted a second time.
308 dnl Test second divert argument, added for m4 2.0
309 AT_DATA([in.m4], [[define(`echo',`$1')dnl
310 divert(`-1', `discarded without warning')
311 divert`'dnl
312 echo(` world'divert(divnum, `hello'))
315 AT_CHECK_M4([-s in.m4], [0], [[#line 4 "in.m4"
316 hello world
319 dnl Test large diversions, which were broken in m4 1.4.8-1.4.10.
320 dnl Hopefully $SED doesn't choke on the over-long second line.
321 AT_CHECK([echo 'divert(1)hi
322 format(%1000000d, 1)' | $M4 | $SED -n 1p], [0], [[hi
325 AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`2')f`'dnl
326 divert(`1')hello
327 divert(`3')goodbye
330 dnl Rather than open-code the 1 megabyte expected output, we reduce the
331 dnl size of testsuite by constructing it.
332 AT_DATA([expout], [[
334 cat expout expout > expout2
335 cat expout2 expout2 > expout
336 cat expout expout > expout2
337 cat expout2 expout2 > expout
338 cat expout expout > expout2
339 cat expout2 expout2 > expout
340 cat expout expout > expout2
341 cat expout2 expout2 > expout
342 cat expout expout > expout2
343 cat expout2 expout2 > expout
344 cat expout expout > expout2
345 cat expout2 expout2 > expout
346 cat expout expout > expout2
347 cat expout2 expout2 > expout
348 cat expout expout > expout2
349 cat expout2 expout2 > expout
350 cat expout expout > expout2
351 cat expout2 expout2 > expout
352 cat expout expout > expout2 # 512 kilobytes
353 echo hello > expout
354 cat expout2 expout2 >> expout # 1 megabyte
355 echo goodbye >> expout
356 rm expout2
358 AT_CHECK_M4([in.m4], [0], [expout])
360 dnl Avoid quadratic copying time when transferring diversions; test
361 dnl both in-memory and diversions spilled to a file.
362 AT_DATA([in.m4], [[include(`forloop2.m4')dnl
363 divert(`1')format(`%10000s', `')dnl
364 forloop(`i', `1', `10000',
365   `divert(incr(i))undivert(i)')dnl
366 divert(`9001')format(`%1000000s', `')dnl
367 forloop(`i', `9001', `10000',
368   `divert(incr(i))undivert(i)')dnl
369 divert(`-1')undivert
372 AT_CHECK_M4([-I "$top_srcdir/examples" in.m4])
374 AT_CLEANUP
377 ## --- ##
378 ## dnl ##
379 ## --- ##
381 AT_SETUP([d@&t@nl])
383 dnl Unfortunately, AT_DATA does not make it easy to create files without
384 dnl a trailing newline.
385 [echo $ECHO_N "__file"__:__"line__ d""nl ignored$ECHO_C"] > nested
386 AT_DATA([outer],
387 [[__file__:__line__
388 include(`nested') still ignored
389 __file__:__line__
390 define(`foo', `dnl
391 __file__:__line__ include(`nested') ignored
392 dnl')dnl
393 foo ignored
394 __file__:__line__
397 dnl Make sure line numbers are consistent, even if include file does not
398 dnl end with a newline
399 AT_CHECK_M4([outer], [0],
400 [[outer:1
401 nested:1 outer:3
402 outer:7 nested:1 outer:8
405 AT_CLEANUP
408 ## ------- ##
409 ## dumpdef ##
410 ## ------- ##
412 AT_SETUP([dumpdef])
414 dnl Make sure that stderr and stdout are properly interleaved when directed
415 dnl to the same file.
416 AT_DATA([in], [[1dumpdef(`defn')3
418 AT_CHECK_M4([in], [0], [[13
419 ]], [[defn:     <defn>
421 AT_CHECK_M4([in 2>&1], [0], [[1defn:    <defn>
425 AT_CLEANUP
428 ## -------- ##
429 ## errprint ##
430 ## -------- ##
432 AT_SETUP([errprint])
434 dnl Make sure that stderr and stdout are properly interleaved when directed
435 dnl to the same file.
436 AT_DATA([in], [[1errprint(`2')3errprint(`
439 AT_CHECK_M4([in], [0], [[13
440 ]], [[2
442 AT_CHECK_M4([in 2>&1], [0], [[123
446 AT_CLEANUP
449 ## ------- ##
450 ## esyscmd ##
451 ## ------- ##
453 AT_SETUP([esyscmd])
455 AT_DATA([[esyscmd.m4]],
456 [[# Cannot use real hostname program because test would fail
457 define(`hostname', esyscmd(`echo www.gnu.org'))dnl
458 `hostname = >>'hostname`<<'
459 define(`hostname',
460 pushdef(`_tmp', `$1')_tmp(translit(esyscmd(`echo www.gnu.org'), `.', `,'))`'popdef(`_tmp'))dnl
461 `hostname = >>'hostname`<<'
464 AT_CHECK_M4([esyscmd.m4], 0,
465 [[# Cannot use real hostname program because test would fail
466 hostname = >>www.gnu.org
468 hostname = >>www<<
471 dnl Ensure that esyscmd does not inherit any unnecessary fds from trace.
472 AT_DATA([in.m4], [[esyscmd(`echo hi >&3')ifelse(sysval,
473 `0', `skipping: sh cannot detect closed fds
474 m4exit(`77')')dnl
476 AT_CHECK_M4([3>&-], [0], [], [stderr], [in.m4])
477 mv stderr experr
478 AT_CHECK_M4([--debugfile=trace -tdnl 3>&-], [0], [], [experr], [in.m4])
479 AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
482 dnl Ensure that esyscmd does not inherit any unnecessary fds from diversions.
483 AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
484 world
485 esyscmd(`echo hi >&3')divert
486 hello
488 AT_CHECK_M4([3>&-], [0], [stdout-nolog], [experr], [in.m4])
489 AT_CHECK([$SED -ne '/./p' stdout], [0], [[hello
490 world
493 dnl Ensure that esyscmd does not inherit any unnecessary fds from input files.
494 AT_DATA([in.m4], [[hello esyscmd(`cat <&3')dnl
495 dnl this line should not be read by cat
496 world
498 AT_CHECK_M4([3>&-], [0], [[hello world
499 ]], [stderr], [in.m4])
500 mv stderr experr
501 AT_CHECK_M4([in.m4 3>&-], [0], [[hello world
502 ]], [experr])
504 AT_CLEANUP
507 ## ------ ##
508 ## ifelse ##
509 ## ------ ##
511 AT_TEST_M4([ifelse],
512 dnl ensure that comparisons work regardless of reference chains in the middle
513 [[define(`e', `$@')define(`long', `01234567890123456789')
514 dnl in isolation
515 ifelse(long, `01234567890123456789', `yes', `no')
516 ifelse(`01234567890123456789', long, `yes', `no')
517 ifelse(long, `01234567890123456789-', `yes', `no')
518 ifelse(`01234567890123456789-', long, `yes', `no')
519 dnl through macro expansion
520 ifelse(e(long), `01234567890123456789', `yes', `no')
521 ifelse(`01234567890123456789', e(long), `yes', `no')
522 ifelse(e(long), `01234567890123456789-', `yes', `no')
523 ifelse(`01234567890123456789-', e(long), `yes', `no')
524 dnl concatenate macro expansion with unquoted characters
525 ifelse(-e(long), `-01234567890123456789', `yes', `no')
526 ifelse(-`01234567890123456789', -e(long), `yes', `no')
527 ifelse(-e(long), `-01234567890123456789-', `yes', `no')
528 ifelse(`-01234567890123456789-', -e(long), `yes', `no')
529 ifelse(-e(long)-, `-01234567890123456789-', `yes', `no')
530 ifelse(-`01234567890123456789-', -e(long)-, `yes', `no')
531 ifelse(-e(long)-, `-01234567890123456789', `yes', `no')
532 ifelse(`-01234567890123456789', -e(long)-, `yes', `no')
533 dnl concatenate macro expansion with quoted characters
534 ifelse(`-'e(long), `-01234567890123456789', `yes', `no')
535 ifelse(-`01234567890123456789', `-'e(long), `yes', `no')
536 ifelse(`-'e(long), `-01234567890123456789-', `yes', `no')
537 ifelse(`-01234567890123456789-', `-'e(long), `yes', `no')
538 ifelse(`-'e(long)`-', `-01234567890123456789-', `yes', `no')
539 ifelse(-`01234567890123456789-', `-'e(long)`-', `yes', `no')
540 ifelse(`-'e(long)`-', `-01234567890123456789', `yes', `no')
541 ifelse(`-01234567890123456789', `-'e(long)`-', `yes', `no')
542 ]], [[
570 ## ------- ##
571 ## include ##
572 ## ------- ##
574 AT_SETUP([include])
576 AT_DATA([[include.m4]],
577 [[Beginning.
578 include(`NOFILE')
579 Intermediate
580 include(`incl-test.m4')
581 After
582 include(`NOFILE')
583 very late
586 AT_DATA([[incl-test.m4]],
587 [[dnl noauto
588 `include test file.'
589 define()
592 AT_DATA([[expout]],
593 [[Beginning.
595 Intermediate
596 include test file.
599 After
601 very late
604 AT_DATA([[experr]],
605 [[m4:include.m4:2: include: cannot open `NOFILE': No such file or directory
606 m4:include.m4:6: include: cannot open `NOFILE': No such file or directory
609 AT_CHECK_M4([include.m4], 1, expout, experr)
611 dnl make sure files are handled correctly even via builtin
612 AT_DATA([foo], [[bar
614 AT_DATA([in], [[builtin(`include', `foo')dnl
617 AT_CHECK_M4([in], [0], [[bar
620 AT_CLEANUP
624 ## ----- ##
625 ## index ##
626 ## ----- ##
628 AT_SETUP([index])
630 dnl This used to be quadratic, taking millions of comparisons,
631 dnl but should now operate in linear time with only several thousand checks.
632 AT_DATA([in], [M4_ONE_MEG_DEFN[dnl
633 index(substr(f, `0', `500000')-, substr(f, `0', `100000')-)
635 AT_CHECK_M4([in], [0], [[400000
638 dnl This validates that index is 8-bit safe.
639 AT_DATA([in], [[index(`1«2', `»')
640 index(`1«2', `«')
641 index(`1«2', `«1')
642 index(`1«2', `«2')
644 AT_CHECK_M4([in], [0], [[-1
650 AT_CLEANUP
654 ## ----- ##
655 ## indir ##
656 ## ----- ##
658 AT_SETUP([indir])
660 AT_DATA([[indir.m4]],
661 [[define(`%%$$##', `>>>$0<<< cnt $#')
663 # indir(`%%$$##', nonsense, nonsense)
664 indir(`%%$$##', nonsense, nonsense)
666 # indir(`indir', `%%$$##', nonsense)
667 indir(`indir', `%%$$##', nonsense)
669 # indir(`indir', `indir', `indir', `indir', `%%$$##')
670 indir(`indir', `indir', `indir', `indir', `%%$$##')
673 AT_DATA([[expout]],
676 # indir(`%%$$##', nonsense, nonsense)
677 >>>%%$$##<<< cnt 2
679 # indir(`indir', `%%$$##', nonsense)
680 >>>%%$$##<<< cnt 1
682 # indir(`indir', `indir', `indir', `indir', `%%$$##')
683 >>>%%$$##<<< cnt 0
686 AT_CHECK_M4([indir.m4], 0, expout)
688 AT_CLEANUP
691 ## ------ ##
692 ## m4exit ##
693 ## ------ ##
695 AT_SETUP([m4exit])
697 dnl Ensure that spilled diversions are gracefully cleaned up
698 AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
699 m4exit
701 AT_CHECK([rm -Rf tmpdir && mkdir tmpdir && test -d tmpdir])
702 TMPDIR=tmpdir
703 export TMPDIR
704 AT_CHECK_M4([in.m4], [0])
705 AT_CHECK([rmdir tmpdir])
707 AT_CLEANUP
710 ## ------- ##
711 ## mkdtemp ##
712 ## ------- ##
714 AT_SETUP([mkdtemp])
716 dnl Check that on error, the expansion is void
717 AT_DATA([[in]],
718 [[mkdtemp(`no_such_dir/m4-fooXXXXXX')
720 AT_CHECK_M4([in], [0], [[
721 ]], [[m4:in:1: Warning: mkdtemp: cannot create directory from template `no_such_dir/m4-fooXXXXXX': No such file or directory
724 dnl Check that umask has an effect.  drws--S--T is okay.
725 AT_DATA([[in]],
726 [[translit(substr(esyscmd(`ls -ld 'mkdtemp(`m4-fooXXXXXX')), `0', `10'),
727            `SsT', `-x-')
729 AT_CHECK([$M4 < in], [0], [[drwx------
731 AT_CHECK([umask 700; $M4 < in], [0], [[d---------
734 AT_CLEANUP
737 ## -------- ##
738 ## maketemp ##
739 ## -------- ##
741 AT_SETUP([mkstemp])
743 AT_KEYWORDS([maketemp])
745 dnl Check that on error, the expansion is void
746 AT_DATA([[in]],
747 [[mkstemp(`no_such_dir/m4-fooXXXXXX')
749 AT_CHECK_M4([in], [0], [[
750 ]], [[m4:in:1: Warning: mkstemp: cannot create file from template `no_such_dir/m4-fooXXXXXX': No such file or directory
753 dnl Check that extra X are appended, but not trailing NUL
754 AT_DATA([[in]], [[len(mkstemp(`m4-fooXXXXX'))
756 AT_CHECK_M4([in], [0], [[12
759 dnl Check that umask has an effect
760 AT_DATA([[in]],
761 [[substr(esyscmd(`ls -ld 'mkstemp(`m4-fooXXXXXX')), `0', `10')
763 AT_CHECK([$M4 < in], [0], [[-rw-------
765 AT_CHECK([umask 700; $M4 < in], [0], [[----------
768 dnl Check for Solaris compatibility of maketemp.  Hopefully the pid is
769 dnl less than 20 decimal digits.  Also check that --safer does not affect
770 dnl traditional behavior of maketemp, which is textual only.
771 AT_DATA([[in]],
772 [[maketemp()
773 maketemp(X)
774 maketemp(XX)
775 maketemp(XXXXXXXXXXXXXXXXXXXXX)
776 maketemp(no_such_dir/XXXXXX)
778 dnl Abuse our knowledge of AT_CHECK_M4 so that we can get stderr filtering...
779 AT_CHECK_M4([-G -Q --safer], [0], [stdout], [],
780 [in& echo $! > pid; wait $!])
781 pid=`cat pid`
782 cat >expout <<EOF
785 X`$SED -e 's/.*\(.\)$/\1/' pid`
786 X`echo "$pid" | $SED -e "s/.*/00000000000000000000&/" -e 's/.*\(.\{20\}$\)/\1/'`
787 no_such_dir/`echo "$pid" | $SED -e "s/.*/000000&/" -e 's/.*\(.\{6\}$\)/\1/'`
789 AT_CHECK([cat stdout], [0], [expout])
791 AT_CLEANUP
794 ## ------ ##
795 ## mpeval ##
796 ## ------ ##
798 AT_SETUP([mpeval])
799 AT_CHECK_DYNAMIC_MODULE
800 AT_CHECK_GMP
802 AT_DATA([[in]],
803 [[divert(-1)
804 # forloop(i, from, to, stmt)
806 define(`forloop', `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
807 define(`_forloop',
808        `$4`'ifelse($1, `$3', ,
809                          `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
810 divert
811 forloop(`x', 1, 100, `2**x = mpeval(2**x)
815 AT_DATA([[expout]],
817 2**1 = 2
818 2**2 = 4
819 2**3 = 8
820 2**4 = 16
821 2**5 = 32
822 2**6 = 64
823 2**7 = 128
824 2**8 = 256
825 2**9 = 512
826 2**10 = 1024
827 2**11 = 2048
828 2**12 = 4096
829 2**13 = 8192
830 2**14 = 16384
831 2**15 = 32768
832 2**16 = 65536
833 2**17 = 131072
834 2**18 = 262144
835 2**19 = 524288
836 2**20 = 1048576
837 2**21 = 2097152
838 2**22 = 4194304
839 2**23 = 8388608
840 2**24 = 16777216
841 2**25 = 33554432
842 2**26 = 67108864
843 2**27 = 134217728
844 2**28 = 268435456
845 2**29 = 536870912
846 2**30 = 1073741824
847 2**31 = 2147483648
848 2**32 = 4294967296
849 2**33 = 8589934592
850 2**34 = 17179869184
851 2**35 = 34359738368
852 2**36 = 68719476736
853 2**37 = 137438953472
854 2**38 = 274877906944
855 2**39 = 549755813888
856 2**40 = 1099511627776
857 2**41 = 2199023255552
858 2**42 = 4398046511104
859 2**43 = 8796093022208
860 2**44 = 17592186044416
861 2**45 = 35184372088832
862 2**46 = 70368744177664
863 2**47 = 140737488355328
864 2**48 = 281474976710656
865 2**49 = 562949953421312
866 2**50 = 1125899906842624
867 2**51 = 2251799813685248
868 2**52 = 4503599627370496
869 2**53 = 9007199254740992
870 2**54 = 18014398509481984
871 2**55 = 36028797018963968
872 2**56 = 72057594037927936
873 2**57 = 144115188075855872
874 2**58 = 288230376151711744
875 2**59 = 576460752303423488
876 2**60 = 1152921504606846976
877 2**61 = 2305843009213693952
878 2**62 = 4611686018427387904
879 2**63 = 9223372036854775808
880 2**64 = 18446744073709551616
881 2**65 = 36893488147419103232
882 2**66 = 73786976294838206464
883 2**67 = 147573952589676412928
884 2**68 = 295147905179352825856
885 2**69 = 590295810358705651712
886 2**70 = 1180591620717411303424
887 2**71 = 2361183241434822606848
888 2**72 = 4722366482869645213696
889 2**73 = 9444732965739290427392
890 2**74 = 18889465931478580854784
891 2**75 = 37778931862957161709568
892 2**76 = 75557863725914323419136
893 2**77 = 151115727451828646838272
894 2**78 = 302231454903657293676544
895 2**79 = 604462909807314587353088
896 2**80 = 1208925819614629174706176
897 2**81 = 2417851639229258349412352
898 2**82 = 4835703278458516698824704
899 2**83 = 9671406556917033397649408
900 2**84 = 19342813113834066795298816
901 2**85 = 38685626227668133590597632
902 2**86 = 77371252455336267181195264
903 2**87 = 154742504910672534362390528
904 2**88 = 309485009821345068724781056
905 2**89 = 618970019642690137449562112
906 2**90 = 1237940039285380274899124224
907 2**91 = 2475880078570760549798248448
908 2**92 = 4951760157141521099596496896
909 2**93 = 9903520314283042199192993792
910 2**94 = 19807040628566084398385987584
911 2**95 = 39614081257132168796771975168
912 2**96 = 79228162514264337593543950336
913 2**97 = 158456325028528675187087900672
914 2**98 = 316912650057057350374175801344
915 2**99 = 633825300114114700748351602688
916 2**100 = 1267650600228229401496703205376
920 AT_CHECK_M4([-m mpeval in], 0, expout)
922 AT_CLEANUP
926 ## ----------- ##
927 ## multiquotes ##
928 ## ----------- ##
930 AT_SETUP([multiquotes])
932 AT_DATA([[multiquotes.m4]],
933 [[traceon
934 changequote([,])dnl
935 changequote([``], [''])dnl
936 ````traceon''''
937 define(``foo'', ````FOO'''')dnl
938 dumpdef(``foo'')dnl
939 changequote(``!'', ``!'')dnl
940 !foo!
942 dumpdef(!foo!)dnl
943 define(!bar!, !BAR!)
945 changequote(!>*>*>*>*>!, !<*<*<*<*<!)dnl five of each
946 >*>*>*>*>foo bar<*<*<*<*<
947 foo bar
948 >*>*>*>*>*>*><*<*<*<*<*<*<
949 dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<)dnl
952 AT_DATA([[expout]],
954 ``traceon''
956 ``FOO''
959 foo bar
960 ``FOO'' BAR
961 *>*>*<*<
964 AT_DATA([[experr]],
965 [[m4trace: -1- changequote(`[', `]') -> []
966 m4trace: -1- dnl -> []
967 m4trace: -1- changequote([``], ['']) -> ``''
968 m4trace: -1- dnl -> ``''
969 m4trace: -1- define(``foo'', ````FOO'''') -> ``''
970 m4trace: -1- dnl -> ``''
971 foo:    ````FOO''''
972 m4trace: -1- dumpdef(``foo'') -> ``''
973 m4trace: -1- dnl -> ``''
974 m4trace: -1- changequote(``!'', ``!'') -> !!
975 m4trace: -1- dnl -> !!
976 m4trace: -1- foo -> !``FOO''!
977 foo:    !``FOO''!
978 m4trace: -1- dumpdef(!foo!) -> !!
979 m4trace: -1- dnl -> !!
980 m4trace: -1- define(!bar!, !BAR!) -> !!
981 m4trace: -1- bar -> !BAR!
982 m4trace: -1- changequote(!>*>*>*>*>!, !<*<*<*<*<!) -> >*>*>*>*><*<*<*<*<
983 m4trace: -1- dnl -> >*>*>*>*><*<*<*<*<
984 m4trace: -1- foo -> >*>*>*>*>``FOO''<*<*<*<*<
985 m4trace: -1- bar -> >*>*>*>*>BAR<*<*<*<*<
986 bar:    >*>*>*>*>BAR<*<*<*<*<
987 foo:    >*>*>*>*>``FOO''<*<*<*<*<
988 m4trace: -1- dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<) -> >*>*>*>*><*<*<*<*<
989 m4trace: -1- dnl -> >*>*>*>*><*<*<*<*<
992 AT_CHECK_M4([multiquotes.m4], 0, expout, experr)
994 AT_CLEANUP
998 ## -------- ##
999 ## patsubst ##
1000 ## -------- ##
1002 AT_SETUP([patsubst])
1004 AT_DATA([[patsubst.m4]],
1005 [[# traceon(`patsubst')
1006 patsubst(`GNUs not Unix.', `^', `OBS: ')
1007 patsubst(`GNUs not Unix.', `\<', `OBS: ')
1008 patsubst(`GNUs not Unix.', `\<\w', `\&=')
1009 patsubst(`GNUs not Unix.', `\w*', `(\&)')
1010 patsubst(`GNUs not Unix.', `\w+', `(\&)')
1011 patsubst(`GNUs not Unix.', `\w+')
1012 patsubst(`GNUs   not  '`         Unix.', `[      ]+', ` ')
1015 AT_DATA([[expout]],
1016 [[# traceon(`patsubst')
1017 OBS: GNUs not Unix.
1018 OBS: GNUs OBS: not OBS: Unix.
1019 G=NUs n=ot U=nix.
1020 (GNUs)() (not)() (Unix)().()
1021 (GNUs) (not) (Unix).
1022   .
1023 GNUs not Unix.
1026 AT_CHECK_M4([patsubst.m4], 0, expout)
1028 AT_CLEANUP
1032 ## ------ ##
1033 ## regexp ##
1034 ## ------ ##
1036 AT_SETUP([regexp])
1038 AT_DATA([[regexp.m4]],
1039 [[traceon(`regexp')dnl
1040 regexp(`hej med dig', `.*', `>>\&<<')
1041 regexp(`hej med dig', `\w*', `>>\&<<')
1042 regexp(`hej med dig', `.+', `>>\&<<')
1043 regexp(`hej med dig', `m\w+', `>>\&<<')
1044 regexp(`hej med dig', `m\(.*\)', `>>\&<< >>\1<<')
1046 regexp(`hej med dig', `.*')
1047 regexp(`hej med dig', `\w*')
1048 regexp(`hej med dig', `.+')
1049 regexp(`hej med dig', `m\w+')
1050 regexp(`hej med dig', `m\(.*\)')
1053 AT_DATA([[expout]],
1054 [[>>hej med dig<<
1055 >>hej<<
1056 >>hej med dig<<
1057 >>med<<
1058 >>med dig<< >>ed dig<<
1067 AT_DATA([[experr]],
1068 [[m4trace: -1- regexp(`hej med dig', `.*', `>>\&<<') -> `>>hej med dig<<'
1069 m4trace: -1- regexp(`hej med dig', `\w*', `>>\&<<') -> `>>hej<<'
1070 m4trace: -1- regexp(`hej med dig', `.+', `>>\&<<') -> `>>hej med dig<<'
1071 m4trace: -1- regexp(`hej med dig', `m\w+', `>>\&<<') -> `>>med<<'
1072 m4trace: -1- regexp(`hej med dig', `m\(.*\)', `>>\&<< >>\1<<') -> `>>med dig<< >>ed dig<<'
1073 m4trace: -1- regexp(`hej med dig', `.*') -> `0'
1074 m4trace: -1- regexp(`hej med dig', `\w*') -> `0'
1075 m4trace: -1- regexp(`hej med dig', `.+') -> `0'
1076 m4trace: -1- regexp(`hej med dig', `m\w+') -> `4'
1077 m4trace: -1- regexp(`hej med dig', `m\(.*\)') -> `4'
1080 AT_CHECK_M4([regexp.m4], 0, expout, experr)
1082 AT_CLEANUP
1086 ## ------------ ##
1087 ## sync-lines.  ##
1088 ## ------------ ##
1090 AT_SETUP([sync-lines])
1092 AT_DATA([[in]],
1093 [[syncoutput(on)dnl
1094 # Several input lines, expanding to one
1095 define(`foo', ``foo' line one.
1096 `foo' line two.
1097 `foo' line three.') xyz
1099 # Several input lines, expanding to none
1100 define(`foo', ``foo' line one.
1101 `foo' line two.
1102 `foo' line three.')dnl
1103 # one input line, expanding to several output lines
1104 foo foo
1107 AT_CHECK_M4([[in]], 0,
1108 [[#line 2 "in"
1109 # Several input lines, expanding to one
1110 #line 5
1111  xyz
1112 foo line one.
1113 #line 6
1114 foo line two.
1115 #line 6
1116 foo line three.
1117 # Several input lines, expanding to none
1118 #line 11
1119 # one input line, expanding to several output lines
1120 foo line one.
1121 #line 12
1122 foo line two.
1123 #line 12
1124 foo line three. foo line one.
1125 #line 12
1126 foo line two.
1127 #line 12
1128 foo line three.
1131 AT_CLEANUP
1134 ## ------ ##
1135 ## syscmd ##
1136 ## ------ ##
1138 AT_SETUP([syscmd])
1140 dnl Ensure that syscmd does not inherit any unnecessary fds from trace.
1141 AT_DATA([in.m4], [[syscmd(`echo hi >&3')ifelse(sysval,
1142 `0', `skipping: sh cannot detect closed fds
1143 m4exit(`77')')dnl
1145 AT_CHECK_M4([3>&-], [0], [], [stderr], [in.m4])
1146 mv stderr experr
1147 AT_CHECK_M4([--debugfile=trace -tdnl 3>&-], [0], [], [experr], [in.m4])
1148 AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
1151 dnl Ensure that syscmd does not inherit any unnecessary fds from diversions.
1152 AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
1153 world
1154 syscmd(`echo hi >&3')divert
1155 hello
1157 AT_CHECK_M4([3>&-], [0], [stdout-nolog], [experr], [in.m4])
1158 AT_CHECK([$SED -ne '/./p' stdout], [0], [[hello
1159 world
1162 dnl Ensure that syscmd does not inherit any unnecessary fds from input files.
1163 AT_DATA([in.m4], [[hello syscmd(`cat <&3')dnl
1164 dnl this line should not be read by cat
1165 world
1167 AT_CHECK_M4([3>&-], [0], [[hello world
1168 ]], [stderr], [in.m4])
1169 mv stderr experr
1170 AT_CHECK_M4([in.m4 3>&-], [0], [[hello world
1171 ]], [experr])
1173 AT_CLEANUP
1176 ## -------- ##
1177 ## translit ##
1178 ## -------- ##
1180 AT_SETUP([translit])
1182 AT_DATA([[translit.m4]],
1183 [[# traceon(`translit')dnl
1184 translit(`GNUs not Unix', `a-z')
1185 translit(`GNUs not Unix', `a-z', `A-Z')
1186 translit(`GNUs not Unix', `A-Z', `a-z')
1187 translit(`GNUs not Unix', `A-Z')
1188 translit(`a-z', `a-')
1189 translit(`A-Z', `A-Z-', `-A-Z')
1190 translit(`GNUs not Unix', `Z-A', `a-z')
1193 AT_CHECK_M4([translit.m4], 0,
1194 [[# traceon(`translit')dnl
1195 GNU  U
1196 GNUS NOT UNIX
1197 gnus not unix
1198 s not nix
1201 tmfs not fnix
1204 dnl This used to be quadratic, taking millions of comparisons,
1205 dnl but should now operate in linear time with only several thousand checks.
1206 AT_DATA([in], [M4_ONE_MEG_DEFN[dnl
1207 define(`a_', translit(substr(f, `0', `50000'), `
1208 ', `a'))dnl
1209 define(`b_', translit(substr(f, `0', `50000'), `
1210 ', `b'))dnl
1211 define(`d_', translit(substr(f, `0', `50000'), `
1212 ', `d'))dnl
1213 define(`c'd_, `pass')dnl
1214 translit(`a'b_, a_`b', `c'd_)
1216 AT_CHECK_M4([in], [0], [[pass
1219 dnl This validates that ranges are built using unsigned chars.
1220 AT_DATA([in], [[translit(`«abc~', `~-»')
1222 AT_CHECK_M4([in], [0], [[abc
1225 dnl Validate short strings, which take a different code path.
1226 AT_DATA([in], [[dnl
1227 translit(`abcdeabcde', `a')
1228 translit(`abcdeabcde', `ab')
1229 translit(`abcdeabcde', `a', `f')
1230 translit(`abcdeabcde', `aa', `fg')
1231 translit(`abcdeabcde', `a', `fg')
1232 translit(`abcdeabcde', `ab', `f')
1233 translit(`abcdeabcde', `ab', `fg')
1234 translit(`abcdeabcde', `ab', `ba')
1235 translit(`abcdeabcde', `e', `f')
1236 translit(`abc', `', `cde')
1237 translit(`', `a', `bc')
1239 AT_CHECK_M4([in], [0], [[bcdebcde
1240 cdecde
1241 fbcdefbcde
1242 fbcdefbcde
1243 fbcdefbcde
1244 fcdefcde
1245 fgcdefgcde
1246 bacdebacde
1247 abcdfabcdf
1252 AT_CLEANUP
1256 ## -------- ##
1257 ## undivert ##
1258 ## -------- ##
1260 AT_SETUP([undivert])
1262 AT_DATA([[undivert.m4]],
1263 [[define(`undiverted', `UNDIVERTED')
1264 # undiverted file.
1265 undivert(`undivert.incl')
1266 # included file.
1267 include(`undivert.incl')
1270 AT_DATA([[undivert.incl]],
1271 [[This is to be undiverted soon.
1274 AT_CHECK_M4([undivert.m4], 0,
1276 # undiverted file.
1277 This is to be undiverted soon.
1279 # included file.
1280 This is to be UNDIVERTED soon.
1284 AT_CLEANUP
1288 ## ---- ##
1289 ## wrap ##
1290 ## ---- ##
1292 AT_SETUP([wrap])
1294 AT_DATA([[wrap.m4]],
1295 [[divert(-1)
1296 m4wrap(`Wrapper no. 1
1299 m4wrap(`Wrapper no. 2
1300 m4wrap(`Wrapper no. 3
1301 m4wrap(`Wrapper no. 4
1302 ')')')
1303 divert
1304 No. 33: The End.
1307 AT_CHECK_M4([wrap.m4], 0,
1309 No. 33: The End.
1310 Wrapper no. 1
1311 Wrapper no. 2
1312 Wrapper no. 3
1313 Wrapper no. 4
1316 AT_CLEANUP