1 # Hand crafted tests for GNU M4. -*- Autotest -*-
2 # Copyright (C) 2001, 2006, 2007, 2008 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([Macro definitions.])
21 # Checking everything related to macro definitions: the expansion of
22 # user macros, the propagation of various bits (tracing, number of
23 # arguments and so on).
25 ## ---------------- ##
27 ## ---------------- ##
29 AT_SETUP([Arity and defn])
31 # Check that the arity checking of define is correctly propagated.
34 [[define(`defun', defn(`define'))
38 define(`foo', `bar', `baz')
43 defun(`foo', `bar', `baz')
59 AT_CHECK_M4([input.m4], 0, [expout],
60 [[m4:input.m4:5: Warning: define: extra arguments ignored: 3 > 2
61 m4:input.m4:10: Warning: defun: extra arguments ignored: 3 > 2
67 ## ------------------------- ##
68 ## Arity, defn, and freeze. ##
69 ## ------------------------- ##
71 AT_SETUP([Arity, defn, and freeze])
74 AT_DATA([[freezeme.m4]],
75 [[define(`defun', defn(`define'))dnl
79 AT_CHECK_M4([--freeze-state=frozen.m4f freezeme.m4], 0)
85 defun(`foo', `bar', `baz')
95 AT_CHECK_M4([--reload-state=frozen.m4f input.m4], 0, expout,
96 [[m4:input.m4:4: Warning: defun: extra arguments ignored: 3 > 2
99 AT_CLEANUP(freezeme.m4 frozen.m4f)
102 ## ------------------- ##
103 ## Command line define ##
104 ## ------------------- ##
106 AT_SETUP([Command line define])
108 dnl Test that -D after last file still affects m4wrap'd text.
109 AT_DATA([in1], [[m4wrap(`foo
114 AT_CHECK_M4([-Dfoo=1 in1 -Dfoo=2 in2 -Dfoo=3], [0],
120 dnl Test that -D only affects top-most definition.
121 AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
127 AT_CHECK_M4([in1 -Dfoo=3 in2], [0],
133 dnl Test that -D and -U interact in correct order
136 AT_CHECK_M4([-Dfoo=bar in -Ufoo in], [0], [[bar
139 AT_CHECK_M4([-Ufoo in -Dfoo=bar in], [0], [[foo
143 dnl Test macro arguments defined via -D
144 AT_DATA([in], [[-foo-foo(1)-foo(1,2)-
145 -bar-bar(1)-bar(1,2)-
147 AT_CHECK_M4([-Dfoo -Dbar='$@' in], [0],
156 ## -------------------- ##
157 ## Command line pushdef ##
158 ## -------------------- ##
160 AT_SETUP([Command line pushdef])
162 dnl Test that -p after last file still affects m4wrap'd text.
163 AT_DATA([in1], [[m4wrap(`foo
168 AT_CHECK_M4([-pfoo=1 in1 -pfoo=2 in2 -pfoo=3], [0],
174 dnl Test that -p adds a definition.
175 AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
181 AT_CHECK_M4([in1 -pfoo=3 in2], [0],
187 dnl Test that --pushdef and --popdef interact in correct order
190 AT_CHECK_M4([-Dfoo=1 --pushdef=foo=2 in --popdef=foo in], [0],
194 AT_CHECK_M4([--popdef=foo in --pushdef=foo=1 in], [0],
203 ## ---------------- ##
204 ## pushdef/popdef. ##
205 ## ---------------- ##
207 AT_SETUP([pushdef/popdef])
209 AT_DATA([[pushpop.m4]],
211 pushdef(`hej', `def 1.')
213 pushdef(`hej', `def 2.')
215 pushdef(`hej', `def 3.')
217 pushdef(`hej', `def 4.')
233 AT_CHECK_M4([pushpop.m4], 0, [],
241 m4:pushpop.m4:18: Warning: dumpdef: undefined macro `hej'
242 m4:pushpop.m4:20: Warning: dumpdef: undefined macro `mac2'
243 m4:pushpop.m4:21: Warning: popdef: undefined macro `mac2'
250 ## ---------------------- ##
251 ## Tracing Hanoi Towers. ##
252 ## ---------------------- ##
254 AT_SETUP([Tracing Hanoi Towers])
256 AT_DATA([[trace.m4]],
260 define(`move', `Move one disk from `$1' to `$2'.
263 # _hanoi (cnt, from, to, aux)
264 define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
265 `_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
268 define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
285 traceon(`move', `_hanoi')
293 Move one disk from source to auxilliary.
294 Move one disk from source to destination.
295 Move one disk from auxilliary to destination.
300 Move one disk from source to auxilliary.
301 Move one disk from source to destination.
302 Move one disk from auxilliary to destination.
307 Move one disk from source to auxilliary.
308 Move one disk from source to destination.
309 Move one disk from auxilliary to destination.
315 Move one disk from source to auxilliary.
316 Move one disk from source to destination.
317 Move one disk from auxilliary to destination.
337 m4trace: -1- debugmode
338 m4trace: -1- hanoi(`2') -> `_hanoi(`2', source, destination, auxilliary)'
339 m4trace: -1- _hanoi(`2', `source', `destination', `auxilliary') -> `ifelse(eval(`2'<=1), 1, `move(source, destination)',
340 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')'
341 m4trace: -2- eval(`2<=1') -> `0'
342 m4trace: -1- ifelse(`0', `1', `move(source, destination)', `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)') -> `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)'
343 m4trace: -2- decr(`2') -> `1'
344 m4trace: -1- _hanoi(`1', `source', `auxilliary', `destination') -> `ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
345 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')'
346 m4trace: -2- eval(`1<=1') -> `1'
347 m4trace: -1- ifelse(`1', `1', `move(source, auxilliary)', `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)') -> `move(source, auxilliary)'
348 m4trace: -1- move(`source', `auxilliary') -> `Move one disk from `source' to `auxilliary'.
350 m4trace: -1- move(`source', `destination') -> `Move one disk from `source' to `destination'.
352 m4trace: -2- decr(`2') -> `1'
353 m4trace: -1- _hanoi(`1', `auxilliary', `destination', `source') -> `ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
354 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')'
355 m4trace: -2- eval(`1<=1') -> `1'
356 m4trace: -1- ifelse(`1', `1', `move(auxilliary, destination)', `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)') -> `move(auxilliary, destination)'
357 m4trace: -1- move(`auxilliary', `destination') -> `Move one disk from `auxilliary' to `destination'.
359 m4trace: -1- debugmode -> `'
360 m4trace: -1- _hanoi(2, source, destination, auxilliary) -> ifelse(eval(`2'<=1), 1, `move(source, destination)',
361 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')
362 m4trace: -1- _hanoi(1, source, auxilliary, destination) -> ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
363 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')
364 m4trace: -1- move(source, auxilliary) -> Move one disk from `source' to `auxilliary'.
366 m4trace: -1- move(source, destination) -> Move one disk from `source' to `destination'.
368 m4trace: -1- _hanoi(1, auxilliary, destination, source) -> ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
369 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')
370 m4trace: -1- move(auxilliary, destination) -> Move one disk from `auxilliary' to `destination'.
374 AT_CHECK_M4([trace.m4], 0, expout, experr)
380 ## ------------------------------- ##
381 ## Propagation of trace requests. ##
382 ## ------------------------------- ##
384 AT_SETUP([Propagation of traceon])
386 AT_DATA([[trace2.m4]],
390 # copy the `define' builtin definition to another symbol
391 define(`my_define', defn(`define'))
393 # delete the original
397 my_define(`foo', `bar')
399 # Use the new definition to redefine the original symbol
400 my_define(`define', defn(`my_define'))
402 # Torture the flag propogation
403 undefine(`my_define')
404 define(`my_define', defn(`define'))
406 # There are now 2 symbols pointing to the same builtin function
407 my_define(`foo', `bar')
415 # copy the `define' builtin definition to another symbol
418 # delete the original
424 # Use the new definition to redefine the original symbol
427 # Torture the flag propogation
431 # There are now 2 symbols pointing to the same builtin function
437 [[m4trace: -1- define(`my_define', <define>) -> `'
438 m4trace: -1- define(`my_define', <define>) -> `'
439 m4trace: -1- define(`foo', `bar') -> `'
442 AT_CHECK_M4([trace2.m4], 0, expout, experr)
448 ## ------------------------ ##
449 ## Propagation of --trace. ##
450 ## ------------------------ ##
452 AT_SETUP([Propagation of --trace])
454 AT_DATA([[trace3.m4]],
455 [[# copy the `define' builtin definition to another symbol
456 define(`my_define', defn(`define'))
458 # delete the original
462 my_define(`foo', `bar')
464 # Use the new definition to redefine the original symbol
465 my_define(`define', defn(`my_define'))
467 # Torture the flag propogation
468 undefine(`my_define')
469 define(`my_define', defn(`define'))
471 # There are now 2 symbols pointing to the same builtin function
472 my_define(`foo', `bar')
477 [[# copy the `define' builtin definition to another symbol
480 # delete the original
486 # Use the new definition to redefine the original symbol
489 # Torture the flag propogation
493 # There are now 2 symbols pointing to the same builtin function
499 [[m4trace: -1- define(`my_define', <define>) -> `'
500 m4trace: -1- define(`my_define', <define>) -> `'
501 m4trace: -1- define(`foo', `bar') -> `'
504 AT_CHECK_M4([-t define -daeq trace3.m4], 0, expout, experr)
509 ## --------------------- ##
510 ## Renamesyms collisions ##
511 ## --------------------- ##
513 AT_SETUP([Renamesyms collisions])
515 dnl FIXME - We should gracefully detect rename collisions, rather than
516 dnl violating the invariants of the symbol table.
519 AT_DATA([in], [[define(`bar', `1')define(`baz', `2')dnl
520 renamesyms(`^ba.$', `baa')
523 AT_CHECK_M4([in], [0], [[
529 ## ----------------- ##
530 ## Rescanning macros ##
531 ## ----------------- ##
533 AT_SETUP([Rescanning macros])
535 dnl This is a series of tests that used to be included as undocumented tests
536 dnl in the branch m4.texinfo. They exercise rescanning issues not stressed
537 dnl anywhere else in the suite, but which are used by autoconf.
538 AT_DATA([in], [[define(`x1', `len(`$1'')dnl
539 define(`y1', ``$1')')dnl
540 x1(`01234567890123456789')y1(`98765432109876543210')
543 AT_CHECK_M4([in], [0], [[40
546 AT_DATA([in], [[define(`echo', `$@')dnl
547 define(`foo', echo(`01234567890123456789')echo(`98765432109876543210'))dnl
551 AT_CHECK_M4([in], [0], [[0123456789012345678998765432109876543210
554 AT_DATA([in], [[define(`a', `A')define(`echo', `$@')define(`join', `$1$2')dnl
555 define(`abcdefghijklmnopqrstuvwxyz', `Z')dnl
556 join(`a', `bcdefghijklmnopqrstuvwxyz')
557 join(`a', echo(`bcdefghijklmnopqrstuvwxyz'))
560 AT_CHECK_M4([in], [0], [[Z
564 AT_DATA([in], [[define(`echo', `$@')dnl
565 echo(echo(`01234567890123456789', `01234567890123456789')
566 echo(`98765432109876543210', `98765432109876543210'))
567 len((echo(`01234567890123456789',
568 `01234567890123456789')echo(`98765432109876543210',
569 `98765432109876543210')))
570 indir(`echo', indir(`echo', `01234567890123456789',
571 `01234567890123456789')
572 indir(`echo', `98765432109876543210', `98765432109876543210'))
573 define(`argn', `$#')dnl
574 define(`echo1', `-$@-')define(`echo2', `,$@,')dnl
575 echo1(`1', `2', `3') argn(echo1(`1', `2', `3'))
576 echo2(`1', `2', `3') argn(echo2(`1', `2', `3'))
579 AT_CHECK_M4([in], [0], [[01234567890123456789,01234567890123456789
580 98765432109876543210,98765432109876543210
582 01234567890123456789,01234567890123456789
583 98765432109876543210,98765432109876543210