1 # Hand crafted tests for GNU M4. -*- Autotest -*-
2 # Copyright (C) 2001, 2006-2008, 2010, 2013-2014 Free Software
5 # This file is part of GNU M4.
7 # GNU M4 is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # GNU M4 is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 AT_BANNER([Macro definitions.])
22 # Checking everything related to macro definitions: the expansion of
23 # user macros, the propagation of various bits (tracing, number of
24 # arguments and so on).
26 ## ---------------- ##
28 ## ---------------- ##
30 AT_SETUP([Arity and defn])
32 # Check that the arity checking of define is correctly propagated.
35 [[define(`defun', defn(`define'))
39 define(`foo', `bar', `baz')
44 defun(`foo', `bar', `baz')
60 AT_CHECK_M4([input.m4], 0, [expout],
61 [[m4:input.m4:5: warning: define: extra arguments ignored: 3 > 2
62 m4:input.m4:10: warning: defun: extra arguments ignored: 3 > 2
68 ## ------------------------- ##
69 ## Arity, defn, and freeze. ##
70 ## ------------------------- ##
72 AT_SETUP([Arity, defn, and freeze])
75 AT_DATA([[freezeme.m4]],
76 [[define(`defun', defn(`define'))dnl
80 AT_CHECK_M4([--freeze-state=frozen.m4f freezeme.m4], 0)
86 defun(`foo', `bar', `baz')
96 AT_CHECK_M4([--reload-state=frozen.m4f input.m4], 0, expout,
97 [[m4:input.m4:4: warning: defun: extra arguments ignored: 3 > 2
100 AT_CLEANUP(freezeme.m4 frozen.m4f)
103 ## ------------------- ##
104 ## Command line define ##
105 ## ------------------- ##
107 AT_SETUP([Command line define])
109 dnl Test that -D after last file still affects m4wrap'd text.
110 AT_DATA([in1], [[m4wrap(`foo
115 AT_CHECK_M4([-Dfoo=1 in1 -Dfoo=2 in2 -Dfoo=3], [0],
121 dnl Test that -D only affects top-most definition.
122 AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
128 AT_CHECK_M4([in1 -Dfoo=3 in2], [0],
134 dnl Test that -D and -U interact in correct order
137 AT_CHECK_M4([-Dfoo=bar in -Ufoo in], [0], [[bar
140 AT_CHECK_M4([-Ufoo in -Dfoo=bar in], [0], [[foo
144 dnl Test macro arguments defined via -D
145 AT_DATA([in], [[-foo-foo(1)-foo(1,2)-
146 -bar-bar(1)-bar(1,2)-
148 AT_CHECK_M4([-Dfoo -Dbar='$@' in], [0],
157 ## -------------------- ##
158 ## Command line pushdef ##
159 ## -------------------- ##
161 AT_SETUP([Command line pushdef])
163 dnl Test that -p after last file still affects m4wrap'd text.
164 AT_DATA([in1], [[m4wrap(`foo
169 AT_CHECK_M4([-pfoo=1 in1 -pfoo=2 in2 -pfoo=3], [0],
175 dnl Test that -p adds a definition.
176 AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
182 AT_CHECK_M4([in1 -pfoo=3 in2], [0],
188 dnl Test that --pushdef and --popdef interact in correct order
191 AT_CHECK_M4([-Dfoo=1 --pushdef=foo=2 in --popdef=foo in], [0],
195 AT_CHECK_M4([--popdef=foo in --pushdef=foo=1 in], [0],
204 ## ---------------- ##
205 ## pushdef/popdef. ##
206 ## ---------------- ##
208 AT_SETUP([pushdef/popdef])
210 AT_DATA([[pushpop.m4]],
212 pushdef(`hej', `def 1.')
214 pushdef(`hej', `def 2.')
216 pushdef(`hej', `def 3.')
218 pushdef(`hej', `def 4.')
234 AT_CHECK_M4([pushpop.m4], 0, [],
242 m4:pushpop.m4:18: warning: dumpdef: undefined macro 'hej'
243 m4:pushpop.m4:20: warning: dumpdef: undefined macro 'mac2'
244 m4:pushpop.m4:21: warning: popdef: undefined macro 'mac2'
251 ## ---------------------- ##
252 ## Tracing Hanoi Towers. ##
253 ## ---------------------- ##
255 AT_SETUP([Tracing Hanoi Towers])
257 AT_DATA([[trace.m4]],
261 define(`move', `Move one disk from `$1' to `$2'.
264 # _hanoi (cnt, from, to, aux)
265 define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
266 `_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
269 define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
286 traceon(`move', `_hanoi')
294 Move one disk from source to auxilliary.
295 Move one disk from source to destination.
296 Move one disk from auxilliary to destination.
301 Move one disk from source to auxilliary.
302 Move one disk from source to destination.
303 Move one disk from auxilliary to destination.
308 Move one disk from source to auxilliary.
309 Move one disk from source to destination.
310 Move one disk from auxilliary to destination.
316 Move one disk from source to auxilliary.
317 Move one disk from source to destination.
318 Move one disk from auxilliary to destination.
338 m4trace: -1- debugmode
339 m4trace: -1- hanoi(`2') -> `_hanoi(`2', source, destination, auxilliary)'
340 m4trace: -1- _hanoi(`2', `source', `destination', `auxilliary') -> `ifelse(eval(`2'<=1), 1, `move(source, destination)',
341 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')'
342 m4trace: -2- eval(`2<=1') -> `0'
343 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)'
344 m4trace: -2- decr(`2') -> `1'
345 m4trace: -1- _hanoi(`1', `source', `auxilliary', `destination') -> `ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
346 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')'
347 m4trace: -2- eval(`1<=1') -> `1'
348 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)'
349 m4trace: -1- move(`source', `auxilliary') -> `Move one disk from `source' to `auxilliary'.
351 m4trace: -1- move(`source', `destination') -> `Move one disk from `source' to `destination'.
353 m4trace: -2- decr(`2') -> `1'
354 m4trace: -1- _hanoi(`1', `auxilliary', `destination', `source') -> `ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
355 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')'
356 m4trace: -2- eval(`1<=1') -> `1'
357 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)'
358 m4trace: -1- move(`auxilliary', `destination') -> `Move one disk from `auxilliary' to `destination'.
360 m4trace: -1- debugmode -> `'
361 m4trace: -1- _hanoi(2, source, destination, auxilliary) -> ifelse(eval(`2'<=1), 1, `move(source, destination)',
362 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')
363 m4trace: -1- _hanoi(1, source, auxilliary, destination) -> ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
364 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')
365 m4trace: -1- move(source, auxilliary) -> Move one disk from `source' to `auxilliary'.
367 m4trace: -1- move(source, destination) -> Move one disk from `source' to `destination'.
369 m4trace: -1- _hanoi(1, auxilliary, destination, source) -> ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
370 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')
371 m4trace: -1- move(auxilliary, destination) -> Move one disk from `auxilliary' to `destination'.
375 AT_CHECK_M4([trace.m4], 0, expout, experr)
381 ## ------------------------------- ##
382 ## Propagation of trace requests. ##
383 ## ------------------------------- ##
385 AT_SETUP([Propagation of traceon])
387 AT_DATA([[trace2.m4]],
391 # copy the `define' builtin definition to another symbol
392 define(`my_define', defn(`define'))
394 # delete the original
398 my_define(`foo', `bar')
400 # Use the new definition to redefine the original symbol
401 my_define(`define', defn(`my_define'))
403 # Torture the flag propogation
404 undefine(`my_define')
405 define(`my_define', defn(`define'))
407 # There are now 2 symbols pointing to the same builtin function
408 my_define(`foo', `bar')
416 # copy the `define' builtin definition to another symbol
419 # delete the original
425 # Use the new definition to redefine the original symbol
428 # Torture the flag propogation
432 # There are now 2 symbols pointing to the same builtin function
438 [[m4trace: -1- define(`my_define', <define>) -> `'
439 m4trace: -1- define(`my_define', <define>) -> `'
440 m4trace: -1- define(`foo', `bar') -> `'
443 AT_CHECK_M4([trace2.m4], 0, expout, experr)
449 ## ------------------------ ##
450 ## Propagation of --trace. ##
451 ## ------------------------ ##
453 AT_SETUP([Propagation of --trace])
455 AT_DATA([[trace3.m4]],
456 [[# copy the `define' builtin definition to another symbol
457 define(`my_define', defn(`define'))
459 # delete the original
463 my_define(`foo', `bar')
465 # Use the new definition to redefine the original symbol
466 my_define(`define', defn(`my_define'))
468 # Torture the flag propogation
469 undefine(`my_define')
470 define(`my_define', defn(`define'))
472 # There are now 2 symbols pointing to the same builtin function
473 my_define(`foo', `bar')
478 [[# copy the `define' builtin definition to another symbol
481 # delete the original
487 # Use the new definition to redefine the original symbol
490 # Torture the flag propogation
494 # There are now 2 symbols pointing to the same builtin function
500 [[m4trace: -1- define(`my_define', <define>) -> `'
501 m4trace: -1- define(`my_define', <define>) -> `'
502 m4trace: -1- define(`foo', `bar') -> `'
505 AT_CHECK_M4([-t define -daeq trace3.m4], 0, expout, experr)
510 ## --------------------- ##
511 ## Renamesyms collisions ##
512 ## --------------------- ##
514 AT_SETUP([Renamesyms collisions])
516 dnl FIXME - We should gracefully detect rename collisions, rather than
517 dnl violating the invariants of the symbol table.
520 AT_DATA([in], [[define(`bar', `1')define(`baz', `2')dnl
521 renamesyms(`^ba.$', `baa')
524 AT_CHECK_M4([in], [0], [[
530 ## ----------------- ##
531 ## Rescanning macros ##
532 ## ----------------- ##
534 AT_SETUP([Rescanning macros])
536 dnl This is a series of tests that used to be included as undocumented tests
537 dnl in the branch m4.texinfo. They exercise rescanning issues not stressed
538 dnl anywhere else in the suite, but which are used by autoconf.
539 AT_DATA([in], [[define(`x1', `len(`$1'')dnl
540 define(`y1', ``$1')')dnl
541 x1(`01234567890123456789')y1(`98765432109876543210')
544 AT_CHECK_M4([in], [0], [[40
547 AT_DATA([in], [[define(`echo', `$@')dnl
548 define(`foo', echo(`01234567890123456789')echo(`98765432109876543210'))dnl
552 AT_CHECK_M4([in], [0], [[0123456789012345678998765432109876543210
555 AT_DATA([in], [[define(`a', `A')define(`echo', `$@')define(`join', `$1$2')dnl
556 define(`abcdefghijklmnopqrstuvwxyz', `Z')dnl
557 join(`a', `bcdefghijklmnopqrstuvwxyz')
558 join(`a', echo(`bcdefghijklmnopqrstuvwxyz'))
561 AT_CHECK_M4([in], [0], [[Z
565 AT_DATA([in], [[define(`echo', `$@')dnl
566 echo(echo(`01234567890123456789', `01234567890123456789')
567 echo(`98765432109876543210', `98765432109876543210'))
568 len((echo(`01234567890123456789',
569 `01234567890123456789')echo(`98765432109876543210',
570 `98765432109876543210')))
571 indir(`echo', indir(`echo', `01234567890123456789',
572 `01234567890123456789')
573 indir(`echo', `98765432109876543210', `98765432109876543210'))
574 define(`argn', `$#')dnl
575 define(`echo1', `-$@-')define(`echo2', `,$@,')dnl
576 echo1(`1', `2', `3') argn(echo1(`1', `2', `3'))
577 echo2(`1', `2', `3') argn(echo2(`1', `2', `3'))
580 AT_CHECK_M4([in], [0], [[01234567890123456789,01234567890123456789
581 98765432109876543210,98765432109876543210
583 01234567890123456789,01234567890123456789
584 98765432109876543210,98765432109876543210