maint: run update-copyright for 2014.
[m4/ericb.git] / tests / macros.at
blob11f32ee60cdfe6678131132a8125c7c3a05ae93d
1 # Hand crafted tests for GNU M4.                               -*- Autotest -*-
2 # Copyright (C) 2001, 2006-2008, 2010, 2013-2014 Free Software
3 # Foundation, Inc.
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 ## ---------------- ##
27 ## Arity and defn.  ##
28 ## ---------------- ##
30 AT_SETUP([Arity and defn])
32 # Check that the arity checking of define is correctly propagated.
34 AT_DATA([[input.m4]],
35 [[define(`defun', defn(`define'))
36 define
37 define(`foo')
38 define(`foo', `bar')
39 define(`foo', `bar', `baz')
41 defun
42 defun(`foo')
43 defun(`foo', `bar')
44 defun(`foo', `bar', `baz')
45 ]])
47 AT_DATA([[expout]],
49 define
54 defun
58 ]])
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
63 ]])
65 AT_CLEANUP
68 ## ------------------------- ##
69 ## Arity, defn, and freeze.  ##
70 ## ------------------------- ##
72 AT_SETUP([Arity, defn, and freeze])
73 AT_KEYWORDS([frozen])
75 AT_DATA([[freezeme.m4]],
76 [[define(`defun', defn(`define'))dnl
77 undefine(`define')dnl
78 ]])
80 AT_CHECK_M4([--freeze-state=frozen.m4f freezeme.m4], 0)
82 AT_DATA([[input.m4]],
83 [[defun
84 defun(`foo')
85 defun(`foo', `bar')
86 defun(`foo', `bar', `baz')
87 ]])
89 AT_DATA([[expout]],
90 [[defun
94 ]])
96 AT_CHECK_M4([--reload-state=frozen.m4f input.m4], 0, expout,
97 [[m4:input.m4:4: warning: defun: extra arguments ignored: 3 > 2
98 ]])
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
111 ')foo
113 AT_DATA([in2], [[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
124 AT_DATA([in2], [[foo
125 popdef(`foo')foo
126 popdef(`foo')foo
128 AT_CHECK_M4([in1 -Dfoo=3 in2], [0],
134 dnl Test that -D and -U interact in correct order
135 AT_DATA([in], [[foo
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],
149 [[----
150 --1-1,2-
153 AT_CLEANUP
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
165 ')foo
167 AT_DATA([in2], [[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
178 AT_DATA([in2], [[foo
179 popdef(`foo')foo
180 popdef(`foo')foo
182 AT_CHECK_M4([in1 -pfoo=3 in2], [0],
188 dnl Test that --pushdef and --popdef interact in correct order
189 AT_DATA([in], [[foo
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],
196 [[foo
200 AT_CLEANUP
204 ## ---------------- ##
205 ## pushdef/popdef.  ##
206 ## ---------------- ##
208 AT_SETUP([pushdef/popdef])
210 AT_DATA([[pushpop.m4]],
211 [[divert(-1)
212 pushdef(`hej', `def 1.')
213 dumpdef(`hej')
214 pushdef(`hej', `def 2.')
215 dumpdef(`hej')
216 pushdef(`hej', `def 3.')
217 dumpdef(`hej')
218 pushdef(`hej', `def 4.')
219 dumpdef(`hej')
221 popdef(`hej')
222 dumpdef(`hej')
223 popdef(`hej')
224 dumpdef(`hej')
225 popdef(`hej')
226 dumpdef(`hej')
227 popdef(`hej')
228 dumpdef(`hej')
230 dumpdef(`mac2')
231 popdef(`mac2')
234 AT_CHECK_M4([pushpop.m4], 0, [],
235 [[hej:  `def 1.'
236 hej:    `def 2.'
237 hej:    `def 3.'
238 hej:    `def 4.'
239 hej:    `def 3.'
240 hej:    `def 2.'
241 hej:    `def 1.'
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'
247 AT_CLEANUP
251 ## ---------------------- ##
252 ## Tracing Hanoi Towers.  ##
253 ## ---------------------- ##
255 AT_SETUP([Tracing Hanoi Towers])
257 AT_DATA([[trace.m4]],
258 [[divert(-1)
260 # move(from, to)
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)')')
268 # hanoi (cnt)
269 define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
270 divert`'dnl
272 # Debugmode t
273 debugmode(`t')
274 hanoi(2)
276 # Debugmode taeq
277 debugmode(`taeq')
278 hanoi(2)
280 # Debugmode OFF
281 debugmode
282 hanoi(2)
284 # Debugmode ae
285 debugmode(`ae')
286 traceon(`move', `_hanoi')
287 hanoi(2)
290 AT_DATA([[expout]],
292 # Debugmode t
294 Move one disk from source to auxilliary.
295 Move one disk from source to destination.
296 Move one disk from auxilliary to destination.
299 # Debugmode taeq
301 Move one disk from source to auxilliary.
302 Move one disk from source to destination.
303 Move one disk from auxilliary to destination.
306 # Debugmode OFF
308 Move one disk from source to auxilliary.
309 Move one disk from source to destination.
310 Move one disk from auxilliary to destination.
313 # Debugmode ae
316 Move one disk from source to auxilliary.
317 Move one disk from source to destination.
318 Move one disk from auxilliary to destination.
322 AT_DATA([[experr]],
323 [[m4trace: -1- hanoi
324 m4trace: -1- _hanoi
325 m4trace: -2- eval
326 m4trace: -1- ifelse
327 m4trace: -2- decr
328 m4trace: -1- _hanoi
329 m4trace: -2- eval
330 m4trace: -1- ifelse
331 m4trace: -1- move
332 m4trace: -1- move
333 m4trace: -2- decr
334 m4trace: -1- _hanoi
335 m4trace: -2- eval
336 m4trace: -1- ifelse
337 m4trace: -1- move
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)
377 AT_CLEANUP
381 ## ------------------------------- ##
382 ## Propagation of trace requests.  ##
383 ## ------------------------------- ##
385 AT_SETUP([Propagation of traceon])
387 AT_DATA([[trace2.m4]],
388 [[traceon(`define')
389 debugmode(`aeq')
391 # copy the `define' builtin definition to another symbol
392 define(`my_define', defn(`define'))
394 # delete the original
395 undefine(`define')
397 # Does it work?
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')
409 define(`foo', `bar')
412 AT_DATA([[expout]],
416 # copy the `define' builtin definition to another symbol
419 # delete the original
422 # Does it work?
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
437 AT_DATA([[experr]],
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)
445 AT_CLEANUP
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
460 undefine(`define')
462 # Does it work?
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')
474 define(`foo', `bar')
477 AT_DATA([[expout]],
478 [[# copy the `define' builtin definition to another symbol
481 # delete the original
484 # Does it work?
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
499 AT_DATA([[experr]],
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)
507 AT_CLEANUP
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.
518 AT_XFAIL_IF([:])
520 AT_DATA([in], [[define(`bar', `1')define(`baz', `2')dnl
521 renamesyms(`^ba.$', `baa')
524 AT_CHECK_M4([in], [0], [[
525 ]], [ignore])
527 AT_CLEANUP
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
585 -1,2,3- 3
586 ,1,2,3, 5
589 AT_CLEANUP