1 # Hand crafted tests for GNU M4. -*- Autotest -*-
2 # Copyright (C) 2001, 2006 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2, or (at your option)
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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],
137 ## ---------------- ##
138 ## pushdef/popdef. ##
139 ## ---------------- ##
141 AT_SETUP([pushdef/popdef])
143 AT_DATA([[pushpop.m4]],
145 pushdef(`hej', `def 1.')
147 pushdef(`hej', `def 2.')
149 pushdef(`hej', `def 3.')
151 pushdef(`hej', `def 4.')
167 AT_CHECK_M4([pushpop.m4], 0, [],
175 m4:pushpop.m4:18: Warning: dumpdef: undefined macro `hej'
176 m4:pushpop.m4:20: Warning: dumpdef: undefined macro `mac2'
177 m4:pushpop.m4:21: Warning: popdef: undefined macro `mac2'
184 ## ---------------------- ##
185 ## Tracing Hanoi Towers. ##
186 ## ---------------------- ##
188 AT_SETUP([Tracing Hanoi Towers])
190 AT_DATA([[trace.m4]],
194 define(`move', `Move one disk from `$1' to `$2'.
197 # _hanoi (cnt, from, to, aux)
198 define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
199 `_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
202 define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
219 traceon(`move', `_hanoi')
227 Move one disk from source to auxilliary.
228 Move one disk from source to destination.
229 Move one disk from auxilliary to destination.
234 Move one disk from source to auxilliary.
235 Move one disk from source to destination.
236 Move one disk from auxilliary to destination.
241 Move one disk from source to auxilliary.
242 Move one disk from source to destination.
243 Move one disk from auxilliary to destination.
249 Move one disk from source to auxilliary.
250 Move one disk from source to destination.
251 Move one disk from auxilliary to destination.
271 m4trace: -1- debugmode
272 m4trace: -1- hanoi(`2') -> `_hanoi(`2', source, destination, auxilliary)'
273 m4trace: -1- _hanoi(`2', `source', `destination', `auxilliary') -> `ifelse(eval(`2'<=1), 1, `move(source, destination)',
274 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')'
275 m4trace: -2- eval(`2<=1') -> `0'
276 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)'
277 m4trace: -2- decr(`2') -> `1'
278 m4trace: -1- _hanoi(`1', `source', `auxilliary', `destination') -> `ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
279 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')'
280 m4trace: -2- eval(`1<=1') -> `1'
281 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)'
282 m4trace: -1- move(`source', `auxilliary') -> `Move one disk from `source' to `auxilliary'.
284 m4trace: -1- move(`source', `destination') -> `Move one disk from `source' to `destination'.
286 m4trace: -2- decr(`2') -> `1'
287 m4trace: -1- _hanoi(`1', `auxilliary', `destination', `source') -> `ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
288 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')'
289 m4trace: -2- eval(`1<=1') -> `1'
290 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)'
291 m4trace: -1- move(`auxilliary', `destination') -> `Move one disk from `auxilliary' to `destination'.
293 m4trace: -1- debugmode -> @&t@
294 m4trace: -1- _hanoi(2, source, destination, auxilliary) -> ifelse(eval(`2'<=1), 1, `move(source, destination)',
295 `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')
296 m4trace: -1- _hanoi(1, source, auxilliary, destination) -> ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
297 `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')
298 m4trace: -1- move(source, auxilliary) -> Move one disk from `source' to `auxilliary'.
300 m4trace: -1- move(source, destination) -> Move one disk from `source' to `destination'.
302 m4trace: -1- _hanoi(1, auxilliary, destination, source) -> ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
303 `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')
304 m4trace: -1- move(auxilliary, destination) -> Move one disk from `auxilliary' to `destination'.
308 AT_CHECK_M4([trace.m4], 0, expout, experr)
314 ## ------------------------------- ##
315 ## Propagation of trace requests. ##
316 ## ------------------------------- ##
318 AT_SETUP([Propagation of traceon])
320 AT_DATA([[trace2.m4]],
324 # copy the `define' builtin definition to another symbol
325 define(`my_define', defn(`define'))
327 # delete the original
331 my_define(`foo', `bar')
333 # Use the new definition to redefine the original symbol
334 my_define(`define', defn(`my_define'))
336 # Torture the flag propogation
337 undefine(`my_define')
338 define(`my_define', defn(`define'))
340 # There are now 2 symbols pointing to the same builtin function
341 my_define(`foo', `bar')
349 # copy the `define' builtin definition to another symbol
352 # delete the original
358 # Use the new definition to redefine the original symbol
361 # Torture the flag propogation
365 # There are now 2 symbols pointing to the same builtin function
371 [[m4trace: -1- define(`my_define', <define>) -> `'
372 m4trace: -1- define(`my_define', <define>) -> `'
373 m4trace: -1- define(`foo', `bar') -> `'
376 AT_CHECK_M4([trace2.m4], 0, expout, experr)
382 ## ------------------------ ##
383 ## Propagation of --trace. ##
384 ## ------------------------ ##
386 AT_SETUP([Propagation of --trace])
388 AT_DATA([[trace3.m4]],
389 [[# copy the `define' builtin definition to another symbol
390 define(`my_define', defn(`define'))
392 # delete the original
396 my_define(`foo', `bar')
398 # Use the new definition to redefine the original symbol
399 my_define(`define', defn(`my_define'))
401 # Torture the flag propogation
402 undefine(`my_define')
403 define(`my_define', defn(`define'))
405 # There are now 2 symbols pointing to the same builtin function
406 my_define(`foo', `bar')
411 [[# copy the `define' builtin definition to another symbol
414 # delete the original
420 # Use the new definition to redefine the original symbol
423 # Torture the flag propogation
427 # There are now 2 symbols pointing to the same builtin function
433 [[m4trace: -1- define(`my_define', <define>) -> `'
434 m4trace: -1- define(`my_define', <define>) -> `'
435 m4trace: -1- define(`foo', `bar') -> `'
438 AT_CHECK_M4([-t define -daeq trace3.m4], 0, expout, experr)
443 ## --------------------- ##
444 ## Renamesyms collisions ##
445 ## --------------------- ##
447 AT_SETUP([Renamesyms collisions])
449 dnl FIXME - We should gracefully detect rename collisions, rather than
450 dnl violating the invariants of the symbol table.
453 AT_DATA([in], [[define(`bar', `1')define(`baz', `2')dnl
454 renamesyms(`^ba.$', `baa')
457 AT_CHECK_M4([in], [0], [[