Assorted improvements to diagnostics.
[pspp] / tests / language / control / define.at
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU nGeneral Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([DEFINE])
18
19 AT_SETUP([simple macro expansion])
20 AT_DATA([define.sps], [dnl
21 DEFINE !macro()
22 a b c d
23 e f g h.
24 i j k l
25 1,2,3,4.
26 5+6+7.
27 m(n,o).
28 "a" "b" "c" 'a' 'b' 'c'.
29 "x "" y".
30 !ENDDEFINE.
31 DEBUG EXPAND.
32 !macro
33 ])
34 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
35 a b c d e f g h.
36 i j k l 1, 2, 3, 4.
37 5 + 6 + 7.
38 m(n, o).
39 "a" "b" "c" 'a' 'b' 'c'.
40 "x "" y".
41 ])
42 AT_CLEANUP
43
44 AT_SETUP([redefining a macro])
45 AT_DATA([define.sps], [dnl
46 DEFINE !macro() 0 !ENDDEFINE.
47 DEFINE !macro() 1 !ENDDEFINE.
48 DEBUG EXPAND.
49 !macro.
50 ])
51 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
52 1
53 ])
54 AT_CLEANUP
55
56 AT_SETUP([macro expansion - one !TOKENS(1) positional argument])
57 AT_KEYWORDS([TOKENS])
58 AT_DATA([define.sps], [dnl
59 DEFINE !t1(!positional=!tokens(1)) t1 (!1) !ENDDEFINE.
60 DEBUG EXPAND.
61 !t1 a.
62 !t1 b.
63 !t1 a b.
64 ])
65 AT_CAPTURE_FILE([define.sps])
66 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
67 t1(a)
68
69 t1(b)
70
71 t1(a)
72
73 note: unexpanded token "b"
74 ])
75 AT_CLEANUP
76
77 AT_SETUP([macro expansion with positional arguments])
78 AT_DATA([define.sps], [dnl
79 DEFINE !title(!positional !tokens(1)) !1 !ENDDEFINE.
80 DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE.
81 DEFINE !t2(!positional !tokens(2)) t2 (!1) !ENDDEFINE.
82
83 DEFINE !ce(!positional=!charend('/')) ce (!1) !ENDDEFINE.
84 DEFINE !ce2(!positional=!charend('(')
85            /!positional !charend(')'))
86 ce2 (!1, !2)
87 !ENDDEFINE.
88
89 DEFINE !e(!positional !enclose('{','}')) e (!1) !ENDDEFINE.
90
91 DEFINE !cmd(!positional !cmdend) cmd(!1) !ENDDEFINE.
92 DEFINE !cmd2(!positional !cmdend
93             /!positional !tokens(1))
94 cmd2(!1, !2)
95 !ENDDEFINE.
96
97 DEFINE !p(!positional !tokens(1)
98          /!positional !tokens(1)
99          /!positional !tokens(1))
100 p(!1, !2, !3)(!*)
101 !ENDDEFINE.
102
103 DEBUG EXPAND.
104 !title "!TOKENS(1) argument."
105 !t1 a.
106 !t1 b.
107 !t1 a b.
108
109 !title "!TOKENS(2) argument."
110 !t2 a b.
111 !t2 b c d.
112
113 !title "!CHAREND argument."
114 !ce/.
115 !ce x/.
116 !ce x y/.
117 !ce x y z/.
118
119 !title "Two !CHAREND arguments."
120 !ce2 x(y).
121 !ce2 1 2 3 4().
122
123 !title "!ENCLOSE argument."
124 !e {}.
125 !e {a}.
126 !e {a b}.
127
128 !title "!CMDEND argument."
129 !cmd 1 2 3 4.
130 !cmd2 5 6.
131 7.
132
133 !title "Three !TOKENS(1) arguments."
134 !p a b c.
135 !p 1 -2 -3.
136 ])
137 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
138 "!TOKENS(1) argument."
139
140 t1(a)
141
142 t1(b)
143
144 t1(a)
145
146 note: unexpanded token "b"
147
148 "!TOKENS(2) argument."
149
150 t2(a b)
151
152 t2(b c)
153
154 note: unexpanded token "d"
155
156 "!CHAREND argument."
157
158 ce( )
159
160 ce(x)
161
162 ce(x y)
163
164 ce(x y z)
165
166 "Two !CHAREND arguments."
167
168 ce2(x, y)
169
170 ce2(1 2 3 4, )
171
172 "!ENCLOSE argument."
173
174 e( )
175
176 e(a)
177
178 e(a b)
179
180 "!CMDEND argument."
181
182 cmd(1 2 3 4)
183
184 cmd2(5 6, )
185
186 note: unexpanded token "7"
187
188 "Three !TOKENS(1) arguments."
189
190 p(a, b, c) (a b c)
191
192 p(1, -2, -3) (1 -2 -3)
193 ])
194 AT_CLEANUP
195
196 AT_SETUP([macro call missing positional !TOKENS arguments])
197 AT_KEYWORDS([TOKENS])
198 AT_DATA([define.sps], [dnl
199 DEFINE !p(!positional !tokens(1) !default(x)
200          /!positional !tokens(1) !default(y)
201          /!positional !tokens(1) !default(z))
202 (!1, !2, !3)
203 !ENDDEFINE.
204 DEBUG EXPAND.
205 !p a b c.
206 !p a b.
207 !p a.
208 !p.
209 ])
210 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
211 (a, b, c)
212
213 (a, b, z)
214
215 (a, y, z)
216
217 (x, y, z)
218 ])
219 AT_CLEANUP
220
221 AT_SETUP([macro call incomplete positional !TOKENS arguments])
222 AT_KEYWORDS([TOKENS])
223 AT_DATA([define.sps], [dnl
224 DEFINE !p(!positional !tokens(2) !default(x)
225          /!positional !tokens(2) !default(y)
226          /!positional !tokens(2) !default(z))
227 (!1, !2, !3)
228 !ENDDEFINE.
229 DEBUG EXPAND.
230 !p a1 a2 b1 b2 c1 c2.
231 !p a1 a2 b1 b2 c1.
232 !p a1 a2 b1 b2.
233 !p a1 a2 b1.
234 !p a1 a2.
235 !p a1.
236 !p.
237 ])
238 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
239 (a1 a2, b1 b2, c1 c2)
240
241 define.sps:8.18: error: DEBUG EXPAND: Reached end of command expecting 1 more
242 token in argument !3 to macro !p.
243     8 | !p a1 a2 b1 b2 c1.
244       |                  ^
245
246 (a1 a2, b1 b2, c1)
247
248 (a1 a2, b1 b2, z)
249
250 define.sps:10.12: error: DEBUG EXPAND: Reached end of command expecting 1 more
251 token in argument !2 to macro !p.
252    10 | !p a1 a2 b1.
253       |            ^
254
255 (a1 a2, b1, z)
256
257 (a1 a2, y, z)
258
259 define.sps:12.6: error: DEBUG EXPAND: Reached end of command expecting 1 more
260 token in argument !1 to macro !p.
261    12 | !p a1.
262       |      ^
263
264 (a1, y, z)
265
266 (x, y, z)
267 ])
268 AT_CLEANUP
269
270 AT_SETUP([macro call empty positional !CHAREND arguments])
271 AT_KEYWORDS([CHAREND])
272 AT_DATA([define.sps], [dnl
273 DEFINE !p(!positional !charend(',') !default(x)
274          /!positional !charend(';') !default(y)
275          /!positional !charend(':') !default(z))
276 (!1, !2, !3)
277 !ENDDEFINE.
278 DEBUG EXPAND.
279 !p a,b;c:.
280 !p a,b;:.
281 !p a,;c:.
282 !p a,;:.
283 !p,b;c:.
284 !p,b;:.
285 !p,;c:.
286 !p,;:.
287 ])
288 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
289 (a, b, c)
290
291 (a, b, )
292
293 (a, , c)
294
295 (a, , )
296
297 (, b, c)
298
299 (, b, )
300
301 (, , c)
302
303 (, , )
304 ])
305 AT_CLEANUP
306
307 AT_SETUP([macro call missing positional !CHAREND arguments])
308 AT_DATA([define.sps], [dnl
309 DEFINE !p(!positional !charend(',') !default(x)
310          /!positional !charend(';') !default(y)
311          /!positional !charend(':') !default(z))
312 (!1, !2, !3)
313 !ENDDEFINE.
314 DEBUG EXPAND.
315 !p a,b;c:.
316 !p a,b;.
317 !p a,;.
318 !p ,b;.
319 !p ,;.
320
321 !p a,.
322 !p ,.
323
324 !p.
325 ])
326 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
327 (a, b, c)
328
329 (a, b, z)
330
331 (a, , z)
332
333 (, b, z)
334
335 (, , z)
336
337 (a, y, z)
338
339 (, y, z)
340
341 (x, y, z)
342 ])
343 AT_CLEANUP
344
345 AT_SETUP([macro call incomplete positional !CHAREND arguments])
346 AT_KEYWORDS([CHAREND])
347 AT_DATA([define.sps], [dnl
348 DEFINE !p(!positional !charend(',') !default(x)
349          /!positional !charend(';') !default(y)
350          /!positional !charend(':') !default(z))
351 (!1, !2, !3)
352 !ENDDEFINE.
353 DEBUG EXPAND.
354 !p a,b;c:.
355 !p a,b;c.
356 !p a,b;.
357 !p a,b.
358 !p a,.
359 !p a.
360 !p.
361 ])
362 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
363 (a, b, c)
364
365 define.sps:8.9: error: DEBUG EXPAND: Reached end of command expecting ":" in
366 argument !3 to macro !p.
367     8 | !p a,b;c.
368       |         ^
369
370 (a, b, c)
371
372 (a, b, z)
373
374 define.sps:10.7: error: DEBUG EXPAND: Reached end of command expecting ";" in
375 argument !2 to macro !p.
376    10 | !p a,b.
377       |       ^
378
379 (a, b, z)
380
381 (a, y, z)
382
383 define.sps:12.5: error: DEBUG EXPAND: Reached end of command expecting "," in
384 argument !1 to macro !p.
385    12 | !p a.
386       |     ^
387
388 (a, y, z)
389
390 (x, y, z)
391 ])
392 AT_CLEANUP
393
394 AT_SETUP([macro call missing positional !ENCLOSE arguments])
395 AT_KEYWORDS([ENCLOSE])
396 AT_DATA([define.sps], [dnl
397 DEFINE !p(!positional !enclose('(',')') !default(x)
398          /!positional !enclose('<','>') !default(y)
399          /!positional !enclose('{','}') !default(z))
400 (!1, !2, !3)
401 !ENDDEFINE.
402 DEBUG EXPAND.
403 !p (a)<b>{c}.
404 !p (a)<b>.
405 !p (a).
406 !p.
407 ])
408 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
409 (a, b, c)
410
411 (a, b, z)
412
413 (a, y, z)
414
415 (x, y, z)
416 ])
417 AT_CLEANUP
418
419 AT_SETUP([macro call incomplete positional !ENCLOSE arguments])
420 AT_KEYWORDS([ENCLOSE])
421 AT_DATA([define.sps], [dnl
422 DEFINE !p(!positional !enclose('(',')') !default(x)
423          /!positional !enclose('<','>') !default(y)
424          /!positional !enclose('{','}') !default(z))
425 (!1, !2, !3)
426 !ENDDEFINE.
427 DEBUG EXPAND.
428 !p (a)<b>{c}.
429 !p (a)<b>{c.
430 !p (a)<b>{.
431 !p (a)<b>.
432 !p (a)<b.
433 !p (a)<.
434 !p (a).
435 !p (a.
436 !p (.
437 !p.
438 ])
439 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
440 (a, b, c)
441
442 define.sps:8.12: error: DEBUG EXPAND: Reached end of command expecting "}" in
443 argument !3 to macro !p.
444     8 | !p (a)<b>{c.
445       |            ^
446
447 (a, b, c)
448
449 define.sps:9.11: error: DEBUG EXPAND: Reached end of command expecting "}" in
450 argument !3 to macro !p.
451     9 | !p (a)<b>{.
452       |           ^
453
454 (a, b, )
455
456 (a, b, z)
457
458 define.sps:11.9: error: DEBUG EXPAND: Reached end of command expecting ">" in
459 argument !2 to macro !p.
460    11 | !p (a)<b.
461       |         ^
462
463 (a, b, z)
464
465 define.sps:12.8: error: DEBUG EXPAND: Reached end of command expecting ">" in
466 argument !2 to macro !p.
467    12 | !p (a)<.
468       |        ^
469
470 (a, , z)
471
472 (a, y, z)
473
474 define.sps:14.6: error: DEBUG EXPAND: Reached end of command expecting ")" in
475 argument !1 to macro !p.
476    14 | !p (a.
477       |      ^
478
479 (a, y, z)
480
481 define.sps:15.5: error: DEBUG EXPAND: Reached end of command expecting ")" in
482 argument !1 to macro !p.
483    15 | !p (.
484       |     ^
485
486 (, y, z)
487
488 (x, y, z)
489 ])
490 AT_CLEANUP
491
492 AT_SETUP([keyword macro argument name with ! prefix])
493 AT_DATA([define.sps], [dnl
494 DEFINE !macro(!x !TOKENS(1).
495 ])
496 AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
497 "define.sps:1.15-1.16: error: DEFINE: Keyword macro parameter must be named in definition without ""!"" prefix.
498     1 | DEFINE !macro@{:@!x !TOKENS(1).
499       |               ^~"
500 ])
501 AT_CLEANUP
502
503 AT_SETUP([reserved macro keyword argument name])
504 AT_DATA([define.sps], [dnl
505 DEFINE !macro(if=!TOKENS(1).
506 ])
507 AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
508 "define.sps:1.15-1.16: error: DEFINE: Cannot use macro keyword ""if"" as an argument name.
509     1 | DEFINE !macro@{:@if=!TOKENS(1).
510       |               ^~"
511 ])
512 AT_CLEANUP
513
514 AT_SETUP([macro expansion - one !TOKENS(1) keyword argument])
515 AT_KEYWORDS([TOKENS])
516 AT_DATA([define.sps], [dnl
517 DEFINE !k(arg1 = !TOKENS(1)) k(!arg1) !ENDDEFINE.
518 DEBUG EXPAND.
519 !k arg1=x.
520 !k arg1=x y.
521 !k.
522 ])
523 AT_CAPTURE_FILE([define.sps])
524 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
525 k(x)
526
527 k(x)
528
529 note: unexpanded token "y"
530
531 k( )
532 ])
533 AT_CLEANUP
534
535 AT_SETUP([macro expansion - one !TOKENS(1) keyword argument - negative])
536 AT_KEYWORDS([TOKENS])
537 AT_DATA([define.sps], [dnl
538 DEFINE !k(arg1 !TOKENS(1)) k(!arg1) !ENDDEFINE.
539 DEBUG EXPAND.
540 !k arg1.
541 !k arg1=.
542 ])
543 AT_CAPTURE_FILE([define.sps])
544 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
545 define.sps:3.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
546 argument !arg1 to macro !k.
547     3 | !k arg1.
548       |        ^
549
550 k( )
551
552 define.sps:4.9: error: DEBUG EXPAND: Reached end of command expecting 1 more
553 token in argument !arg1 to macro !k.
554     4 | !k arg1=.
555       |         ^
556
557 k( )
558 ])
559 AT_CLEANUP
560
561 AT_SETUP([macro expansion - !CHAREND keyword arguments])
562 AT_KEYWORDS([CHAREND])
563 AT_DATA([define.sps], [dnl
564 DEFINE !k(arg1 = !CHAREND('/')
565          /arg2 = !CHAREND('/'))
566 k(!arg1, !arg2)
567 !ENDDEFINE.
568 DEBUG EXPAND.
569 !k arg1=x/ arg2=y/.
570 !k arg1=x/.
571 !k arg2=y/.
572 !k.
573 ])
574 AT_CAPTURE_FILE([define.sps])
575 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
576 k(x, y)
577
578 k(x, )
579
580 k(, y)
581
582 k(, )
583 ])
584 AT_CLEANUP
585
586 AT_SETUP([macro expansion - !CHAREND keyword arguments - negative])
587 AT_KEYWORDS([CHAREND])
588 AT_DATA([define.sps], [dnl
589 DEFINE !k(arg1 = !CHAREND('/')
590          /arg2 = !CHAREND('/'))
591 k(!arg1, !arg2)
592 !ENDDEFINE.
593 DEBUG EXPAND.
594 !k arg1.
595 !k arg1=.
596 !k arg1=x.
597 !k arg1=x/ arg2=y.
598 ])
599 AT_CAPTURE_FILE([define.sps])
600 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
601 define.sps:6.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
602 argument !arg1 to macro !k.
603     6 | !k arg1.
604       |        ^
605
606 k(, )
607
608 define.sps:7.9: error: DEBUG EXPAND: Reached end of command expecting "/" in
609 argument !arg1 to macro !k.
610     7 | !k arg1=.
611       |         ^
612
613 k(, )
614
615 define.sps:8.10: error: DEBUG EXPAND: Reached end of command expecting "/" in
616 argument !arg1 to macro !k.
617     8 | !k arg1=x.
618       |          ^
619
620 k(x, )
621
622 define.sps:9.18: error: DEBUG EXPAND: Reached end of command expecting "/" in
623 argument !arg2 to macro !k.
624     9 | !k arg1=x/ arg2=y.
625       |                  ^
626
627 k(x, y)
628 ])
629 AT_CLEANUP
630
631 AT_SETUP([macro expansion - !ENCLOSE keyword arguments])
632 AT_KEYWORDS([ENCLOSE])
633 AT_DATA([define.sps], [dnl
634 DEFINE !k(arg1 = !ENCLOSE('(',')')
635          /arg2 = !ENCLOSE('{','}'))
636 k(!arg1, !arg2)
637 !ENDDEFINE.
638 DEBUG EXPAND.
639 !k arg1=(x) arg2={y}.
640 !k arg1=(x).
641 !k arg2={y}.
642 !k.
643 ])
644 AT_CAPTURE_FILE([define.sps])
645 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
646 k(x, y)
647
648 k(x, )
649
650 k(, y)
651
652 k(, )
653 ])
654 AT_CLEANUP
655
656 AT_SETUP([macro expansion - !ENCLOSE keyword arguments - negative])
657 AT_KEYWORDS([ENCLOSE])
658 AT_DATA([define.sps], [dnl
659 DEFINE !k(arg1 = !ENCLOSE('(',')')
660          /arg2 = !ENCLOSE('{','}'))
661 k(!arg1, !arg2)
662 !ENDDEFINE.
663 DEBUG EXPAND.
664 !k arg1.
665 !k arg1=.
666 !k arg1=x.
667 !k arg1=(x.
668 !k arg1=(x) arg2.
669 !k arg1=(x) arg2=.
670 !k arg1=(x) arg2=y.
671 !k arg1=(x) arg2=(y.
672 ])
673 AT_CAPTURE_FILE([define.sps])
674 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
675 define.sps:6.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
676 argument !arg1 to macro !k.
677     6 | !k arg1.
678       |        ^
679
680 k(, )
681
682 define.sps:7.9: error: DEBUG EXPAND: Found `.' while expecting `@{:@' reading
683 argument !arg1 to macro !k.
684     7 | !k arg1=.
685       |         ^
686
687 k(, )
688
689 define.sps:8.9: error: DEBUG EXPAND: Found `x' while expecting `@{:@' reading
690 argument !arg1 to macro !k.
691     8 | !k arg1=x.
692       |         ^
693
694 k(, )
695
696 note: unexpanded token "x"
697
698 define.sps:9.11: error: DEBUG EXPAND: Reached end of command expecting "@:}@" in
699 argument !arg1 to macro !k.
700     9 | !k arg1=@{:@x.
701       |           ^
702
703 k(x, )
704
705 define.sps:10.17: error: DEBUG EXPAND: Found `.' while expecting `=' reading
706 argument !arg2 to macro !k.
707    10 | !k arg1=(x) arg2.
708       |                 ^
709
710 k(x, )
711
712 define.sps:11.18: error: DEBUG EXPAND: Found `.' while expecting `{' reading
713 argument !arg2 to macro !k.
714    11 | !k arg1=(x) arg2=.
715       |                  ^
716
717 k(x, )
718
719 define.sps:12.18: error: DEBUG EXPAND: Found `y' while expecting `{' reading
720 argument !arg2 to macro !k.
721    12 | !k arg1=(x) arg2=y.
722       |                  ^
723
724 k(x, )
725
726 note: unexpanded token "y"
727
728 define.sps:13.18: error: DEBUG EXPAND: Found `@{:@' while expecting `{' reading
729 argument !arg2 to macro !k.
730    13 | !k arg1=(x) arg2=@{:@y.
731       |                  ^
732
733 k(x, )
734
735 note: unexpanded token "@{:@"
736
737 note: unexpanded token "y"
738 ])
739 AT_CLEANUP
740
741 dnl Keep this test in sync with the examples for !BLANKS in the manual.
742 AT_SETUP([macro expansion - !BLANKS])
743 AT_KEYWORDS([BLANKS])
744 AT_DATA([define.sps], [dnl
745 DEFINE !b()
746 !BLANKS(0).
747 !QUOTE(!BLANKS(0)).
748 !BLANKS(1).
749 !QUOTE(!BLANKS(1)).
750 !BLANKS(2).
751 !QUOTE(!BLANKS(2)).
752 !BLANKS(5).
753 !QUOTE(!BLANKS(5)).
754 !ENDDEFINE.
755 DEBUG EXPAND.
756 !b.
757 ])
758 AT_CAPTURE_FILE([define.sps])
759 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
760 .
761 ''.
762 .
763 ' '.
764 .
765 '  '.
766 .
767 '     '.
768 ])
769 AT_CLEANUP
770
771 dnl Keep this test in sync with the examples for !CONCAT in the manual.
772 AT_SETUP([macro expansion - !CONCAT])
773 AT_KEYWORDS([CONCAT])
774 AT_DATA([define.sps], [dnl
775 DEFINE !c()
776 !CONCAT(x, y).
777 !CONCAT('x', 'y').
778 !CONCAT(12, 34).
779 !CONCAT(!NULL, 123).
780 !CONCAT(x, 0).
781 !CONCAT(x, 0, y).
782 !CONCAT(0, x).
783 !CONCAT(0, x, y).
784 !ENDDEFINE.
785 DEBUG EXPAND.
786 !c
787 ])
788 AT_CAPTURE_FILE([define.sps])
789 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
790 xy.
791 xy.
792 1234.
793 123.
794 x0.
795 x0y.
796 0 x.
797 0 xy.
798 ])
799 AT_CLEANUP
800
801 dnl Keep this test in sync with the examples for !EVAL in the manual.
802 AT_SETUP([macro expansion - !EVAL])
803 AT_KEYWORDS([EVAL])
804 AT_DATA([define.sps], [dnl
805 DEFINE !vars() a b c !ENDDEFINE.
806
807 DEFINE !e()
808 !vars.
809 !QUOTE(!vars).
810 !EVAL(!vars).
811 !QUOTE(!EVAL(!vars)).
812 !ENDDEFINE
813
814 DEFINE !e2(!positional !enclose('(',')'))
815 !1.
816 !QUOTE(!1).
817 !EVAL(!1).
818 !QUOTE(!EVAL(!1)).
819 !ENDDEFINE.
820 DEBUG EXPAND.
821 !e.
822 !e2(!vars).
823 ])
824 AT_CAPTURE_FILE([define.sps])
825 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
826 a b c.
827 '!vars'.
828 a b c.
829 'a b c'.
830
831 a b c.
832 '!vars'.
833 a b c.
834 'a b c'.
835 ])
836 AT_CLEANUP
837
838 dnl Keep this test in sync with the examples for !HEAD in the manual.
839 AT_SETUP([macro expansion - !HEAD])
840 AT_KEYWORDS([HEAD])
841 AT_DATA([define.sps], [dnl
842 DEFINE !h()
843 !HEAD('a b c').
844 !HEAD('a').
845 !HEAD(!NULL).
846 !HEAD('').
847 !ENDDEFINE.
848 DEBUG EXPAND.
849 !h.
850 ])
851 AT_CAPTURE_FILE([define.sps])
852 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
853 a.
854 a.
855 .
856 .
857 ])
858 AT_CLEANUP
859
860 dnl Keep this test in sync with the examples for !TAIL in the manual.
861 AT_SETUP([macro expansion - !TAIL])
862 AT_KEYWORDS([TAIL])
863 AT_DATA([define.sps], [dnl
864 DEFINE !t()
865 !TAIL('a b c').
866 !TAIL('a').
867 !TAIL(!NULL).
868 !TAIL('').
869 !ENDDEFINE.
870 DEBUG EXPAND.
871 !t.
872 ])
873 AT_CAPTURE_FILE([define.sps])
874 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
875 b c.
876 .
877 .
878 .
879 ])
880 AT_CLEANUP
881
882 dnl Keep this test in sync with the examples for !INDEX in the manual.
883 AT_SETUP([macro expansion - !INDEX])
884 AT_KEYWORDS([INDEX])
885 AT_DATA([define.sps], [dnl
886 DEFINE !i()
887 !INDEX(banana, an).
888 !INDEX(banana, nan).
889 !INDEX(banana, apple).
890 !INDEX("banana", nan).
891 !INDEX("banana", "nan").
892 !INDEX(!UNQUOTE("banana"), !UNQUOTE("nan")).
893 !ENDDEFINE.
894 DEBUG EXPAND.
895 !i.
896 ])
897 AT_CAPTURE_FILE([define.sps])
898 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
899 2.
900 3.
901 0.
902 4.
903 0.
904 3.
905 ])
906 AT_CLEANUP
907
908 dnl Keep this test in sync with the examples for !LENGTH in the manual.
909 AT_SETUP([macro expansion - !LENGTH])
910 AT_KEYWORDS([LENGTH])
911 AT_DATA([define.sps], [dnl
912 DEFINE !l()
913 !LENGTH(123).
914 !LENGTH(123.00).
915 !LENGTH( 123 ).
916 !LENGTH("123").
917 !LENGTH(xyzzy).
918 !LENGTH("xyzzy").
919 !LENGTH("xy""zzy").
920 !LENGTH(!UNQUOTE("xyzzy")).
921 !LENGTH(!UNQUOTE("xy""zzy")).
922 !LENGTH(!NULL).
923 !ENDDEFINE.
924 DEFINE !la(!positional !enclose('(',')'))
925 !LENGTH(!1).
926 !ENDDEFINE.
927 DEBUG EXPAND.
928 !l.
929 !la(a b c).
930 !la().
931 ])
932 AT_CAPTURE_FILE([define.sps])
933 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
934 3.
935 6.
936 3.
937 5.
938 5.
939 7.
940 9.
941 5.
942 6.
943 0.
944
945 5.
946
947 0.
948 ])
949 AT_CLEANUP
950
951 dnl Keep this test in sync with the examples for !NULL in the manual.
952 AT_SETUP([macro expansion - !NULL])
953 AT_KEYWORDS([NULL])
954 AT_DATA([define.sps], [dnl
955 DEFINE !n()
956 !NULL.
957 !QUOTE(!NULL).
958 !ENDDEFINE.
959 DEBUG EXPAND.
960 !n.
961 ])
962 AT_CAPTURE_FILE([define.sps])
963 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
964 .
965 ''.
966 ])
967 AT_CLEANUP
968
969 dnl Keep this test in sync with the examples for !QUOTE and !UNQUOTE in the manual.
970 AT_SETUP([macro expansion - !QUOTE and !UNQUOTE])
971 AT_KEYWORDS([QUOTE UNQUOTE])
972 AT_DATA([define.sps], [dnl
973 DEFINE !q(!POS !CMDEND)
974 !QUOTE(123.0).
975 !QUOTE( 123 ).
976 !QUOTE('a b c').
977 !QUOTE("a b c").
978 !QUOTE(!1).
979
980 !UNQUOTE(123.0).
981 !UNQUOTE( 123 ).
982 !UNQUOTE('a b c').
983 !UNQUOTE("a b c").
984 !UNQUOTE(!1).
985
986 !QUOTE(!UNQUOTE(123.0)).
987 !QUOTE(!UNQUOTE( 123 )).
988 !QUOTE(!UNQUOTE('a b c')).
989 !QUOTE(!UNQUOTE("a b c")).
990 !QUOTE(!UNQUOTE(!1)).
991 !ENDDEFINE.
992 DEBUG EXPAND.
993 !q a 'b' c.
994 ])
995 AT_CAPTURE_FILE([define.sps])
996 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
997 '123.0'.
998 '123'.
999 'a b c'.
1000 "a b c".
1001 'a ''b'' c'.
1002
1003 123.0.
1004 123.
1005 a b c.
1006 a b c.
1007 a 'b' c.
1008
1009 '123.0'.
1010 '123'.
1011 'a b c'.
1012 'a b c'.
1013 'a ''b'' c'.
1014 ])
1015 AT_CLEANUP
1016
1017 dnl Keep this test in sync with the examples for !SUBSTR in the manual.
1018 AT_SETUP([macro expansion - !SUBSTR])
1019 AT_KEYWORDS([SUBSTR])
1020 AT_DATA([define.sps], [dnl
1021 DEFINE !s()
1022 !SUBSTR(banana, 3).
1023 !SUBSTR(banana, 3, 3).
1024 !SUBSTR("banana", 1, 3).
1025 !SUBSTR(!UNQUOTE("banana"), 3).
1026 !SUBSTR("banana", 3, 3).
1027 !SUBSTR(banana, 3, 0).
1028 !SUBSTR(banana, 3, 10).
1029 !SUBSTR(banana, 10, 3).
1030 !ENDDEFINE.
1031 DEBUG EXPAND.
1032 !s.
1033 ])
1034 AT_CAPTURE_FILE([define.sps])
1035 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1036 define.sps:1-10: At `"ba' in the expansion of `!s',dnl "
1037
1038 define.sps:12.1-12.2: error: DEBUG EXPAND: Unterminated string constant.
1039    12 | !s.
1040       | ^~
1041
1042 nana.
1043 nan.
1044 .
1045 nana.
1046 ana.
1047 .
1048 nana.
1049 .
1050 ])
1051 AT_CLEANUP
1052
1053 dnl Keep this test in sync with the examples for !UPCASE in the manual.
1054 AT_SETUP([macro expansion - !UPCASE])
1055 AT_KEYWORDS([UPCASE])
1056 AT_DATA([define.sps], [dnl
1057 DEFINE !u()
1058 !UPCASE(freckle).
1059 !UPCASE('freckle').
1060 !UPCASE('a b c').
1061 !UPCASE('A B C').
1062 !ENDDEFINE.
1063 DEBUG EXPAND.
1064 !u.
1065 ])
1066 AT_CAPTURE_FILE([define.sps])
1067 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1068 FRECKLE.
1069 FRECKLE.
1070 A B C.
1071 A B C.
1072 ])
1073 AT_CLEANUP
1074
1075 dnl !* is implemented separately inside and outside function arguments
1076 dnl so this test makes sure to include both.
1077 AT_SETUP([macro expansion - !*])
1078 AT_DATA([define.sps], [dnl
1079 DEFINE !m(!POSITIONAL !TOKENS(1)
1080          /!POSITIONAL !TOKENS(1))
1081 !*/
1082 !LENGTH(!*)/
1083 !SUBSTR(!*, 3)/
1084 !QUOTE(!*).
1085 !ENDDEFINE.
1086 DEBUG EXPAND.
1087 !m 123 b
1088 !m 2 3
1089 !m '' 'b'.
1090 ])
1091 AT_CAPTURE_FILE([define.sps])
1092 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1093 123 b / 5 / 3 b / '123 b'.
1094
1095 2 3 / 3 / 3 / '2 3'.
1096
1097 '' 'b' / 6 / 'b' / ''''' ''b'''.
1098 ])
1099 AT_CLEANUP
1100
1101 AT_SETUP([macro maximum nesting level (MNEST)])
1102 AT_KEYWORDS([MNEST])
1103 AT_DATA([define.sps], [dnl
1104 DEFINE !macro()
1105 !macro
1106 !ENDDEFINE.
1107 !macro.
1108 ])
1109 AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
1110 "define.sps:1-3: In the expansion of `!macro',
1111 define.sps:1-3: inside the expansion of `!macro',
1112 define.sps:1-3: inside the expansion of `!macro',
1113 define.sps:1-3: inside the expansion of `!macro',
1114 define.sps:1-3: inside the expansion of `!macro',
1115 define.sps:1-3: inside the expansion of `!macro',
1116 define.sps:1-3: inside the expansion of `!macro',
1117 define.sps:1-3: inside the expansion of `!macro',
1118 define.sps:1-3: inside the expansion of `!macro',
1119 define.sps:1-3: inside the expansion of `!macro',
1120 define.sps:1-3: inside the expansion of `!macro',
1121 define.sps:1-3: inside the expansion of `!macro',
1122 define.sps:1-3: inside the expansion of `!macro',
1123 define.sps:1-3: inside the expansion of `!macro',
1124 define.sps:1-3: inside the expansion of `!macro',
1125 define.sps:1-3: inside the expansion of `!macro',
1126 define.sps:1-3: inside the expansion of `!macro',
1127 define.sps:1-3: inside the expansion of `!macro',
1128 define.sps:1-3: inside the expansion of `!macro',
1129 define.sps:1-3: inside the expansion of `!macro',
1130 define.sps:1-3: inside the expansion of `!macro',
1131 define.sps:1-3: inside the expansion of `!macro',
1132 define.sps:1-3: inside the expansion of `!macro',
1133 define.sps:1-3: inside the expansion of `!macro',
1134 define.sps:1-3: inside the expansion of `!macro',
1135 define.sps:1-3: inside the expansion of `!macro',
1136 define.sps:1-3: inside the expansion of `!macro',
1137 define.sps:1-3: inside the expansion of `!macro',
1138 define.sps:1-3: inside the expansion of `!macro',
1139 define.sps:1-3: inside the expansion of `!macro',
1140 define.sps:1-3: inside the expansion of `!macro',
1141 define.sps:1-3: inside the expansion of `!macro',
1142 define.sps:1-3: inside the expansion of `!macro',
1143 define.sps:1-3: inside the expansion of `!macro',
1144 define.sps:1-3: inside the expansion of `!macro',
1145 define.sps:1-3: inside the expansion of `!macro',
1146 define.sps:1-3: inside the expansion of `!macro',
1147 define.sps:1-3: inside the expansion of `!macro',
1148 define.sps:1-3: inside the expansion of `!macro',
1149 define.sps:1-3: inside the expansion of `!macro',
1150 define.sps:1-3: inside the expansion of `!macro',
1151 define.sps:1-3: inside the expansion of `!macro',
1152 define.sps:1-3: inside the expansion of `!macro',
1153 define.sps:1-3: inside the expansion of `!macro',
1154 define.sps:1-3: inside the expansion of `!macro',
1155 define.sps:1-3: inside the expansion of `!macro',
1156 define.sps:1-3: inside the expansion of `!macro',
1157 define.sps:1-3: inside the expansion of `!macro',
1158 define.sps:1-3: inside the expansion of `!macro',
1159 define.sps:1-3: inside the expansion of `!macro',
1160 define.sps:1-3: inside the expansion of `!macro',
1161 define.sps:4.1-4.6: error: DEFINE: Maximum nesting level 50 exceeded.  (Use SET MNEST to change the limit.)
1162     4 | !macro.
1163       | ^~~~~~"
1164
1165 "define.sps:4.1-4.6: error: In syntax expanded from `!macro': Syntax error expecting command name.
1166     4 | !macro.
1167       | ^~~~~~"
1168 ])
1169 AT_CLEANUP
1170
1171 AT_SETUP([macro !IF condition])
1172 AT_KEYWORDS([if])
1173 for operators in \
1174     '!eq !ne !lt !gt !le !ge' \
1175     '  =  <>   <   >  <=  >='
1176 do
1177     set $operators
1178     AS_BOX([$operators])
1179     cat > define.sps <<EOF
1180 DEFINE !test(!positional !tokens(1))
1181 !if (!1 $1 1) !then true !else false !ifend
1182 !if (!1 $2 1) !then true !else false !ifend
1183 !if (!1 $3 1) !then true !else false !ifend
1184 !if (!1 $4 1) !then true !else false !ifend
1185 !if (!1 $5 1) !then true !else false !ifend
1186 !if (!1 $6 1) !then true !else false !ifend.
1187 !ENDDEFINE.
1188 DEBUG EXPAND.
1189 !test 0
1190 !test 1
1191 !test 2
1192 !test '1'
1193 !test 1.0
1194 EOF
1195     AT_CAPTURE_FILE([define.sps])
1196     AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1197 false true true false true false.
1198
1199 true false false false true true.
1200
1201 false true false true false true.
1202
1203 true false false false true true.
1204
1205 false true false true false true.
1206 ])
1207 done
1208 AT_CLEANUP
1209
1210 AT_SETUP([macro !IF condition -- case sensitivity])
1211 AT_KEYWORDS([if])
1212 for operators in \
1213     '!eq !ne !lt !gt !le !ge' \
1214     '  =  <>   <   >  <=  >='
1215 do
1216     set $operators
1217     AS_BOX([$operators])
1218     cat > define.sps <<EOF
1219 DEFINE !test(!positional !tokens(1))
1220 !if (!1 $1 a) !then true !else false !ifend
1221 !if (!1 $1 A) !then true !else false !ifend
1222 !if (!1 $2 a) !then true !else false !ifend
1223 !if (!1 $2 A) !then true !else false !ifend
1224 !if (!1 $3 a) !then true !else false !ifend
1225 !if (!1 $3 A) !then true !else false !ifend
1226 !if (!1 $4 a) !then true !else false !ifend
1227 !if (!1 $4 A) !then true !else false !ifend
1228 !if (!1 $5 a) !then true !else false !ifend
1229 !if (!1 $5 A) !then true !else false !ifend
1230 !if (!1 $6 a) !then true !else false !ifend
1231 !if (!1 $6 A) !then true !else false !ifend
1232 !if (!1 $1 !null) !then true !else false !ifend
1233 !if (!1 $2 !null) !then true !else false !ifend.
1234 !ENDDEFINE.
1235 DEBUG EXPAND.
1236 !test a
1237 !test A
1238 !test b
1239 !test B
1240 EOF
1241     AT_CAPTURE_FILE([define.sps])
1242     AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1243 true false false true false false false true true false true true false true.
1244
1245 false true true false true false false false true true false true false true.
1246
1247 false false true true false false true true false false true true false true.
1248
1249 false false true true true false false true true false false true false true.
1250 ])
1251 done
1252 AT_CLEANUP
1253
1254 AT_SETUP([macro !IF condition -- logical operators])
1255 AT_KEYWORDS([if])
1256 for operators in \
1257     '!and !or !not' \
1258     '   &   |    ~'
1259 do
1260     set $operators
1261     AS_BOX([$operators])
1262     cat > define.sps <<EOF
1263 DEFINE !test_binary(!positional !tokens(1)/!positional !tokens(1))
1264 !if !1 $1 !2 !then true !else false !ifend
1265 !if !1 $2 !2 !then true !else false !ifend.
1266 !ENDDEFINE.
1267
1268 DEFINE !test_unary(!positional !tokens(1))
1269 !if $3 !1 !then true !else false !ifend.
1270 !ENDDEFINE.
1271
1272 * These are:
1273   ((not A) and B) or C
1274   not (A and B) or C
1275   not A and (B or C)
1276 DEFINE !test_prec(!pos !tokens(1)/!pos !tokens(1)/!pos !tokens(1))
1277 !if $3 !1 $1 !2 $2 !3 !then true !else false !ifend
1278 !if $3 (!1 $1 !2) $2 !3 !then true !else false !ifend
1279 !if $3 !1 $1 (!2 $2 !3) !then true !else false !ifend
1280 !ENDDEFINE.
1281
1282 DEBUG EXPAND.
1283 !test_binary 0 0
1284 !test_binary 0 1
1285 !test_binary 1 0
1286 !test_binary 1 1
1287 !test_unary 0
1288 !test_unary 1
1289 !test_prec 0 0 0 !test_prec 0 0 1 !test_prec 0 1 0 !test_prec 0 1 1.
1290 !test_prec 1 0 0 !test_prec 1 0 1 !test_prec 1 1 0 !test_prec 1 1 1.
1291 EOF
1292     AT_CAPTURE_FILE([define.sps])
1293     AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1294 false false.
1295
1296 false true.
1297
1298 false true.
1299
1300 true true.
1301
1302 true.
1303
1304 false.
1305
1306 false true false
1307 true true true
1308 true true true
1309 true true true
1310
1311 false true false
1312 true true false
1313 false false false
1314 true true false
1315 ])
1316 done
1317 AT_CLEANUP
1318
1319 AT_SETUP([macro !LET])
1320 AT_KEYWORDS([let])
1321 AT_DATA([define.sps], [dnl
1322 DEFINE !macro(!POS !CMDEND)
1323 !LET !v1 = !CONCAT('x',!1,'y')
1324 !LET !v2 = !QUOTE(!v1)
1325 !LET !v3 = (!LENGTH(!1) = 1)
1326 !LET !v4 = (!SUBSTR(!1, 3) = !NULL)
1327 v1=!v1.
1328 v2=!v2.
1329 v3=!v3.
1330 v4=!v4.
1331 !ENDDEFINE.
1332 DEBUG EXPAND.
1333 !macro 0.
1334 !macro.
1335 !macro xyzzy.
1336 ])
1337 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1338 v1 = x0y.
1339 v2 = x0y.
1340 v3 = 1.
1341 v4 = 1.
1342
1343 v1 = xy.
1344 v2 = xy.
1345 v3 = 0.
1346 v4 = 1.
1347
1348 v1 = xxyzzyy.
1349 v2 = xxyzzyy.
1350 v3 = 0.
1351 v4 = 0.
1352 ])
1353 AT_CLEANUP
1354
1355 AT_SETUP([macro indexed !DO])
1356 AT_KEYWORDS([index do])
1357 AT_DATA([define.sps], [dnl
1358 DEFINE !title(!POS !TOKENS(1)) !1. !ENDDEFINE.
1359
1360 DEFINE !for(!POS !TOKENS(1) / !POS !TOKENS(1))
1361 !DO !var = !1 !TO !2 !var !DOEND.
1362 !ENDDEFINE.
1363
1364 DEFINE !forby(!POS !TOKENS(1) / !POS !TOKENS(1) / !POS !TOKENS(1))
1365 !DO !var = !1 !TO !2 !BY !3 !var !DOEND.
1366 !ENDDEFINE.
1367
1368 DEBUG EXPAND.
1369 !title "increasing".
1370 !for 1 5.
1371 !forby 1 5 1.
1372 !forby 1 5 2.
1373 !forby 1 5 2.5.
1374 !forby 1 5 -1.
1375
1376 !title "decreasing".
1377 !for 5 1.
1378 !forby 5 1 1.
1379 !forby 5 1 -1.
1380 !forby 5 1 -2.
1381 !forby 5 1 -3.
1382
1383 !title "non-integer".
1384 !for 1.5 3.5.
1385 ])
1386 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1387 "increasing".
1388
1389 1 2 3 4 5.
1390
1391 1 2 3 4 5.
1392
1393 1 3 5.
1394
1395 1 3.5.
1396
1397 .
1398
1399 "decreasing".
1400
1401 .
1402
1403 .
1404
1405 5 4 3 2 1.
1406
1407 5 3 1.
1408
1409 5 2.
1410
1411 "non-integer".
1412
1413 1.5 2.5 3.5.
1414 ])
1415 AT_CLEANUP
1416
1417 AT_SETUP([macro !DO invalid variable names])
1418 AT_KEYWORDS([index do])
1419 AT_DATA([define.sps], [dnl
1420 DEFINE !for(x=!TOKENS(1) / y=!TOKENS(1))
1421 !DO !x = !x !TO !y !var !DOEND.
1422 !ENDDEFINE.
1423
1424 DEFINE !for2(x=!TOKENS(1) / y=!TOKENS(1))
1425 !DO !noexpand = !x !TO !y !var !DOEND.
1426 !ENDDEFINE.
1427
1428 DEBUG EXPAND.
1429 !for x=1 y=5.
1430 !for2 x=1 y=5.
1431 ])
1432 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1433 define.sps:1-3: At `!x' in the expansion of `!for',
1434 define.sps:10.1-10.12: error: DEBUG EXPAND: Cannot use argument name or macro
1435 keyword as !DO variable.
1436    10 | !for x=1 y=5.
1437       | ^~~~~~~~~~~~
1438
1439 !DO 1 = 1 !TO 5 !var !DOEND.
1440
1441 define.sps:5-7: At `!noexpand' in the expansion of `!for2',
1442 define.sps:11.1-11.13: error: DEBUG EXPAND: Cannot use argument name or macro
1443 keyword as !DO variable.
1444    11 | !for2 x=1 y=5.
1445       | ^~~~~~~~~~~~~
1446
1447 !DO !noexpand = 1 !TO 5 !var !DOEND.
1448 ])
1449 AT_CLEANUP
1450
1451 AT_SETUP([macro indexed !DO reaches MITERATE])
1452 AT_KEYWORDS([index do])
1453 AT_DATA([define.sps], [dnl
1454 DEFINE !title(!POS !TOKENS(1)) !1. !ENDDEFINE.
1455
1456 DEFINE !for(!POS !TOKENS(1) / !POS !TOKENS(1))
1457 !DO !var = !1 !TO !2 !var !DOEND.
1458 !ENDDEFINE.
1459
1460 DEFINE !forby(!POS !TOKENS(1) / !POS !TOKENS(1) / !POS !TOKENS(1))
1461 !DO !var = !1 !TO !2 !BY !3 !var !DOEND.
1462 !ENDDEFINE.
1463
1464 SET MITERATE=3.
1465 DEBUG EXPAND.
1466 !title "increasing".
1467 !for 1 5.
1468 !forby 1 5 1.
1469 !forby 1 5 2.
1470 !forby 1 5 2.5.
1471 !forby 1 5 -1.
1472
1473 !title "decreasing".
1474 !for 5 1.
1475 !forby 5 1 1.
1476 !forby 5 1 -1.
1477 !forby 5 1 -2.
1478 !forby 5 1 -3.
1479
1480 !title "non-integer".
1481 !for 1.5 3.5.
1482 ])
1483 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1484 "increasing".
1485
1486 In the expansion of `!DO',
1487 define.sps:3-5: inside the expansion of `!for',
1488 define.sps:14.1-14.8: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum
1489 number of iterations 3.  (Use SET MITERATE to change the limit.)
1490    14 | !for 1 5.
1491       | ^~~~~~~~
1492
1493 1 2 3 4.
1494
1495 In the expansion of `!DO',
1496 define.sps:7-9: inside the expansion of `!forby',
1497 define.sps:15.1-15.12: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum
1498 number of iterations 3.  (Use SET MITERATE to change the limit.)
1499    15 | !forby 1 5 1.
1500       | ^~~~~~~~~~~~
1501
1502 1 2 3 4.
1503
1504 1 3 5.
1505
1506 1 3.5.
1507
1508 .
1509
1510 "decreasing".
1511
1512 .
1513
1514 .
1515
1516 In the expansion of `!DO',
1517 define.sps:7-9: inside the expansion of `!forby',
1518 define.sps:23.1-23.13: error: DEBUG EXPAND: Numerical !DO loop exceeded maximum
1519 number of iterations 3.  (Use SET MITERATE to change the limit.)
1520    23 | !forby 5 1 -1.
1521       | ^~~~~~~~~~~~~
1522
1523 5 4 3 2.
1524
1525 5 3 1.
1526
1527 5 2.
1528
1529 "non-integer".
1530
1531 1.5 2.5 3.5.
1532 ])
1533 AT_CLEANUP
1534
1535 AT_SETUP([!BREAK with macro indexed !DO])
1536 AT_KEYWORDS([index do break])
1537 AT_DATA([define.sps], [dnl
1538 DEFINE !title(!POS !TOKENS(1)) !1. !ENDDEFINE.
1539
1540 DEFINE !for(!POS !TOKENS(1) / !POS !TOKENS(1) / !POS !TOKENS(1))
1541 !DO !var = !1 !TO !2
1542   !var
1543   !IF 1 !THEN
1544     !IF !var = !3 !THEN
1545       x
1546       !BREAK
1547       y
1548     !IFEND
1549     ,
1550   !IFEND
1551 !DOEND.
1552 !ENDDEFINE.
1553
1554 DEBUG EXPAND.
1555 !for 1 5 4.
1556 ])
1557 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1558 1, 2, 3, 4 x.
1559 ])
1560 AT_CLEANUP
1561
1562 AT_SETUP([macro list !DO])
1563 AT_KEYWORDS([index do])
1564 AT_DATA([define.sps], [dnl
1565 DEFINE !for(!POS !CMDEND)
1566 (!DO !i !IN (!1) (!i) !DOEND).
1567 !ENDDEFINE.
1568
1569 DEBUG EXPAND.
1570 !for a b c.
1571 !for 'foo bar baz quux'.
1572 !for.
1573 ])
1574 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1575 ( (a) (b) (c) ).
1576
1577 ( (foo) (bar) (baz) (quux) ).
1578
1579 ( ).
1580 ])
1581 AT_CLEANUP
1582
1583 AT_SETUP([macro list !DO reaches MITERATE])
1584 AT_KEYWORDS([index do])
1585 AT_DATA([define.sps], [dnl
1586 DEFINE !for(!POS !CMDEND)
1587 (!DO !i !IN (!1) (!i) !DOEND).
1588 !ENDDEFINE.
1589
1590 SET MITERATE=2.
1591 DEBUG EXPAND.
1592 !for a b c.
1593 !for 'foo bar baz quux'.
1594 !for.
1595 ])
1596 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1597 In the expansion of `!DO',
1598 define.sps:1-3: inside the expansion of `!for',
1599 define.sps:7.1-7.10: error: DEBUG EXPAND: !DO loop over list exceeded maximum
1600 number of iterations 2.  (Use SET MITERATE to change the limit.)
1601     7 | !for a b c.
1602       | ^~~~~~~~~~
1603
1604 ( (a) (b) ).
1605
1606 In the expansion of `!DO',
1607 define.sps:1-3: inside the expansion of `!for',
1608 define.sps:8.1-8.23: error: DEBUG EXPAND: !DO loop over list exceeded maximum
1609 number of iterations 2.  (Use SET MITERATE to change the limit.)
1610     8 | !for 'foo bar baz quux'.
1611       | ^~~~~~~~~~~~~~~~~~~~~~~
1612
1613 ( (foo) (bar) ).
1614
1615 ( ).
1616 ])
1617 AT_CLEANUP
1618
1619 AT_SETUP([!BREAK with macro list !DO])
1620 AT_KEYWORDS([index break do])
1621 AT_DATA([define.sps], [dnl
1622 DEFINE !for(!POS !TOKENS(1) / !POS !CMDEND)
1623 (!DO !i !IN (!2)
1624   (!i)
1625   !IF 1 !THEN
1626     !IF !i = !1 !THEN
1627       x
1628       !BREAK
1629       y
1630     !IFEND
1631     ,
1632   !IFEND
1633 !DOEND).
1634 !ENDDEFINE.
1635
1636 DEBUG EXPAND.
1637 !for d a b c.
1638 !for baz 'foo bar baz quux'.
1639 !for e.
1640 ])
1641 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1642 ( (a), (b), (c), ).
1643
1644 ( (foo), (bar), (baz)x).
1645
1646 ( ).
1647 ])
1648 AT_CLEANUP
1649
1650 AT_SETUP([macro !LET])
1651 AT_DATA([define.sps], [dnl
1652 DEFINE !macro(!pos !enclose('(',')'))
1653 !LET !x=!1
1654 !LET !y=!QUOTE(!1)
1655 !LET !z=(!y="abc")
1656 !y !z
1657 !ENDDEFINE.
1658
1659 DEBUG EXPAND.
1660 !macro(1+2).
1661 !macro(abc).
1662 ])
1663 AT_CHECK([pspp --testing-mode define.sps -O format=csv], [0], [dnl
1664 1 + 2 0
1665
1666 abc 1
1667 ])
1668 AT_CLEANUP
1669
1670 AT_SETUP([macro !LET invalid variable names])
1671 AT_DATA([define.sps], [dnl
1672 DEFINE !macro(x=!tokens(1))
1673 !LET !x=!x
1674 !ENDDEFINE.
1675
1676 DEFINE !macro2()
1677 !LET !do=x
1678 !ENDDEFINE.
1679
1680 DEBUG EXPAND.
1681 !macro x=1.
1682 !macro2.
1683 ])
1684 AT_CHECK([pspp --testing-mode define.sps -O format=csv], [1], [dnl
1685 "define.sps:1-3: At `!x' in the expansion of `!macro',
1686 define.sps:10.1-10.10: error: DEBUG EXPAND: Cannot use argument name or macro keyword ""!x"" as !LET variable.
1687    10 | !macro x=1.
1688       | ^~~~~~~~~~"
1689
1690 !LET 1 = 1
1691
1692 "define.sps:5-7: At `!do' in the expansion of `!macro2',
1693 define.sps:11.1-11.7: error: DEBUG EXPAND: Cannot use argument name or macro keyword ""!do"" as !LET variable.
1694    11 | !macro2.
1695       | ^~~~~~~"
1696
1697 "define.sps:5-7: At `=' in the expansion of `!macro2',
1698 define.sps:11.1-11.7: error: DEBUG EXPAND: Expected macro variable name following !DO.
1699    11 | !macro2.
1700       | ^~~~~~~"
1701
1702 !LET !do = x
1703 ])
1704 AT_CLEANUP
1705
1706 AT_SETUP([BEGIN DATA inside a macro])
1707 AT_DATA([define.sps], [dnl
1708 DEFINE !macro()
1709 DATA LIST NOTABLE /x 1.
1710 BEGIN DATA
1711 1
1712 2
1713 3
1714 END DATA.
1715 LIST.
1716 !ENDDEFINE.
1717
1718 !macro
1719 ])
1720 AT_CHECK([pspp define.sps -O format=csv], [0], [dnl
1721 Table: Data List
1722 x
1723 1
1724 2
1725 3
1726 ])
1727 AT_CLEANUP
1728
1729 AT_SETUP([TITLE and SUBTITLE with macros])
1730 AT_KEYWORDS([macro])
1731 for command in TITLE SUBTITLE; do
1732     cat >title.sps <<EOF
1733 DEFINE !paste(!POS !TOKENS(1) / !POS !TOKENS(1))
1734 !CONCAT(!1,!2)
1735 !ENDDEFINE.
1736 $command prefix !paste foo bar suffix.
1737 SHOW $command.
1738 EOF
1739     cat >expout <<EOF
1740 title.sps:5: note: SHOW: $command is prefix foobar suffix.
1741 EOF
1742     AT_CHECK([pspp -O format=csv title.sps], [0], [expout])
1743 done
1744 AT_CLEANUP
1745
1746 AT_SETUP([error message within macro expansion])
1747 AT_DATA([define.sps], [dnl
1748 DEFINE !vars(!POS !TOKENS(1)) a b C !ENDDEFINE.
1749 DATA LIST NOTABLE /a b 1-2.
1750 COMPUTE x = !vars x.
1751 ])
1752 AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
1753 "define.sps:3.13-3.19: error: COMPUTE: In syntax expanded from `!vars x': Syntax error expecting end of command.
1754     3 | COMPUTE x = !vars x.
1755       |             ^~~~~~~"
1756 ])
1757 AT_CLEANUP
1758
1759 dnl A macro with keyword arguments needs a token of lookahead
1760 dnl to find out whether another keyword is present.  Test that
1761 dnl this special case works OK.
1762 AT_SETUP([macro calls in each others' lookahead])
1763 AT_DATA([define.sps], [dnl
1764 DEFINE !k(x=!DEFAULT(0) !TOKENS(1)/y=!DEFAULT(0) !TOKENS(1))
1765 (x=!x)(y=!y)
1766 !ENDDEFINE.
1767 DEBUG EXPAND.
1768 !k
1769 !k x=1
1770 !k y=2
1771 !k y=2 x=1
1772 !k x=1 y=2.
1773 ])
1774 AT_CHECK([pspp -O format=csv define.sps --testing-mode], [0], [dnl
1775 (x = 0) (y = 0)
1776
1777 (x = 1) (y = 0)
1778
1779 (x = 0) (y = 2)
1780 (x = 1) (y = 2)
1781
1782 (x = 1) (y = 2)
1783 ])
1784 AT_CLEANUP
1785
1786 AT_SETUP([bad token in macro body])
1787 AT_DATA([define.sps], [dnl
1788 DEFINE !x()
1789 x'123'
1790 !ENDDEFINE.
1791 ])
1792 AT_CHECK([pspp define.sps], [1], [dnl
1793 define.sps:2.1-2.6: error: DEFINE: String of hex digits has 3 characters, which
1794 is not a multiple of 2.
1795     2 | x'123'
1796       | ^~~~~~
1797 ])
1798 AT_CLEANUP
1799
1800 AT_SETUP([macro name overlaps with macro function name])
1801 dnl !len is short for macro function !LENGTH.  PSPP used to
1802 dnl reject the following with "`(' expected following !LENGTH".
1803 dnl Now PSPP only consider macro functions when the name is
1804 dnl followed by '('.
1805 AT_DATA([define.sps], [dnl
1806 DEFINE !len() 5 !ENDDEFINE.
1807 DEFINE !x() !eval(!len) !ENDDEFINE.
1808 DEBUG EXPAND.
1809 !x
1810 ])
1811 AT_CHECK([pspp -O format=csv define.sps --testing-mode], [0], [dnl
1812 5
1813 ])
1814 AT_CLEANUP
1815
1816 AT_SETUP([generic macro function syntax errors])
1817 AT_DATA([define.sps], [dnl
1818
1819
1820 DEFINE !c() !SUBSTR(1x) !ENDDEFINE.
1821 DEFINE !d() !SUBSTR(1 !ENDDEFINE.
1822 DEFINE !narg_blanks() !BLANKS() !ENDDEFINE.
1823 DEFINE !narg_concat() !CONCAT() !ENDDEFINE.
1824 DEFINE !narg_eval() !EVAL() !ENDDEFINE.
1825 DEFINE !narg_head() !HEAD() !ENDDEFINE.
1826 DEFINE !narg_index() !INDEX() !ENDDEFINE.
1827 DEFINE !narg_length() !LENGTH() !ENDDEFINE.
1828 DEFINE !narg_null() !NULL() !ENDDEFINE.
1829 DEFINE !narg_quote() !QUOTE() !ENDDEFINE.
1830 DEFINE !narg_substr() !SUBSTR() !ENDDEFINE.
1831 DEFINE !narg_tail() !TAIL() !ENDDEFINE.
1832 DEFINE !narg_unquote() !UNQUOTE() !ENDDEFINE.
1833 DEFINE !narg_upcase() !UPCASE() !ENDDEFINE.
1834 dnl )
1835 DEBUG EXPAND.
1836
1837
1838 !c.
1839 !d.
1840 !narg_blanks.
1841 !narg_concat.
1842 !narg_eval.
1843 !narg_head.
1844 !narg_index.
1845 !narg_length.
1846 !narg_null.
1847 !narg_quote.
1848 !narg_substr.
1849 !narg_tail.
1850 !narg_unquote.
1851 !narg_upcase.
1852 ])
1853 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1854 define.sps:3: At `x' in the expansion of `!c',
1855 define.sps:20.1-20.2: error: DEBUG EXPAND: `,' or `@:}@' expected in call to macro
1856 function !SUBSTR.
1857    20 | !c.
1858       | ^~
1859
1860 !SUBSTR(1 x)
1861
1862 define.sps:4: In the expansion of `!d',
1863 define.sps:21.1-21.2: error: DEBUG EXPAND: Missing `@:}@' in call to macro
1864 function !SUBSTR.
1865    21 | !d.
1866       | ^~
1867
1868 !SUBSTR@{:@1
1869
1870 define.sps:5: In the expansion of `!narg_blanks',
1871 define.sps:22.1-22.12: error: DEBUG EXPAND: Macro function !BLANKS takes one
1872 argument (not 0).
1873    22 | !narg_blanks.
1874       | ^~~~~~~~~~~~
1875
1876 !BLANKS( )
1877
1878 define.sps:6: In the expansion of `!narg_concat',
1879 define.sps:23.1-23.12: error: DEBUG EXPAND: Macro function !CONCAT needs at
1880 least one argument.
1881    23 | !narg_concat.
1882       | ^~~~~~~~~~~~
1883
1884 !CONCAT( )
1885
1886 define.sps:7: In the expansion of `!narg_eval',
1887 define.sps:24.1-24.10: error: DEBUG EXPAND: Macro function !EVAL takes one
1888 argument (not 0).
1889    24 | !narg_eval.
1890       | ^~~~~~~~~~
1891
1892 !EVAL( )
1893
1894 define.sps:8: In the expansion of `!narg_head',
1895 define.sps:25.1-25.10: error: DEBUG EXPAND: Macro function !HEAD takes one
1896 argument (not 0).
1897    25 | !narg_head.
1898       | ^~~~~~~~~~
1899
1900 !HEAD( )
1901
1902 define.sps:9: In the expansion of `!narg_index',
1903 define.sps:26.1-26.11: error: DEBUG EXPAND: Macro function !INDEX takes two
1904 arguments (not 0).
1905    26 | !narg_index.
1906       | ^~~~~~~~~~~
1907
1908 !INDEX( )
1909
1910 define.sps:10: In the expansion of `!narg_length',
1911 define.sps:27.1-27.12: error: DEBUG EXPAND: Macro function !LENGTH takes one
1912 argument (not 0).
1913    27 | !narg_length.
1914       | ^~~~~~~~~~~~
1915
1916 !LENGTH( )
1917
1918 ( )
1919
1920 define.sps:12: In the expansion of `!narg_quote',
1921 define.sps:29.1-29.11: error: DEBUG EXPAND: Macro function !QUOTE takes one
1922 argument (not 0).
1923    29 | !narg_quote.
1924       | ^~~~~~~~~~~
1925
1926 !QUOTE( )
1927
1928 define.sps:13: In the expansion of `!narg_substr',
1929 define.sps:30.1-30.12: error: DEBUG EXPAND: Macro function !SUBSTR takes two or
1930 three arguments (not 0).
1931    30 | !narg_substr.
1932       | ^~~~~~~~~~~~
1933  
1934 !SUBSTR( )
1935
1936 define.sps:14: In the expansion of `!narg_tail',
1937 define.sps:31.1-31.10: error: DEBUG EXPAND: Macro function !TAIL takes one
1938 argument (not 0).
1939    31 | !narg_tail.
1940       | ^~~~~~~~~~
1941
1942 !TAIL( )
1943
1944 define.sps:15: In the expansion of `!narg_unquote',
1945 define.sps:32.1-32.13: error: DEBUG EXPAND: Macro function !UNQUOTE takes one
1946 argument (not 0).
1947    32 | !narg_unquote.
1948       | ^~~~~~~~~~~~~
1949
1950 !UNQUOTE( )
1951
1952 define.sps:16: In the expansion of `!narg_upcase',
1953 define.sps:33.1-33.12: error: DEBUG EXPAND: Macro function !UPCASE takes one
1954 argument (not 0).
1955    33 | !narg_upcase.
1956       | ^~~~~~~~~~~~
1957
1958 !UPCASE( )
1959 ])
1960 AT_CLEANUP
1961
1962 AT_SETUP([specific macro function syntax errors])
1963 AT_DATA([define.sps], [dnl
1964 DEFINE !a() !BLANKS(x). !ENDDEFINE.
1965 DEFINE !b() !SUBSTR(x, y). !ENDDEFINE.
1966 DEFINE !c() !SUBSTR(x, 1, z). !ENDDEFINE.
1967 DEBUG EXPAND.
1968 !a.
1969 !b.
1970 !c.
1971 ])
1972 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
1973 define.sps:1: In the expansion of `!a',
1974 define.sps:5.1-5.2: error: DEBUG EXPAND: Argument to !BLANKS must be non-
1975 negative integer (not "x").
1976     5 | !a.
1977       | ^~
1978
1979 !BLANKS(x).
1980
1981 define.sps:2: In the expansion of `!b',
1982 define.sps:6.1-6.2: error: DEBUG EXPAND: Second argument of !SUBSTR must be
1983 positive integer (not "y").
1984     6 | !b.
1985       | ^~
1986
1987 !SUBSTR(x, y).
1988
1989 define.sps:3: In the expansion of `!c',
1990 define.sps:7.1-7.2: error: DEBUG EXPAND: Third argument of !SUBSTR must be non-
1991 negative integer (not "z").
1992     7 | !c.
1993       | ^~
1994
1995 !SUBSTR(x, 1, z).
1996 ])
1997 AT_CLEANUP
1998
1999 AT_SETUP([macro expression errors])
2000 AT_DATA([define.sps], [dnl
2001 DEFINE !a() !LET !x = (1. !ENDDEFINE dnl )
2002
2003 DEFINE !b() !DO !x = x. !ENDDEFINE.
2004 DEFINE !c() !LET !x = (). !ENDDEFINE.
2005 DEBUG EXPAND.
2006 !a.
2007 !b.
2008 !c.
2009 ])
2010 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
2011 define.sps:1-2: At `.' in the expansion of `!a',
2012 define.sps:5.1-5.2: error: DEBUG EXPAND: Expecting ')' in macro expression.
2013     5 | !a.
2014       | ^~
2015
2016 !LET !x = (1.
2017
2018 At `x' in the expansion of `!DO',
2019 define.sps:2: inside the expansion of `!b',
2020 define.sps:6.1-6.2: error: DEBUG EXPAND: Macro expression must evaluate to a
2021 number (not "x").
2022     6 | !b.
2023       | ^~
2024
2025 !DO !x = x.
2026
2027 define.sps:3: At `)' in the expansion of `!c',
2028 define.sps:7.1-7.2: error: DEBUG EXPAND: Expecting literal or function
2029 invocation in macro expression.
2030     7 | !c.
2031       | ^~
2032
2033 !LET !x = ( ).
2034 ])
2035 AT_CLEANUP
2036
2037 AT_SETUP([macro !IF errors])
2038 AT_KEYWORDS([IF])
2039 AT_DATA([define.sps], [dnl
2040 DEFINE !a() !IF 1 !ENDDEFINE.
2041 DEFINE !b() !IF 1 !THEN !ENDDEFINE.
2042 DEFINE !c() !IF 1 !THEN !ELSE !ENDDEFINE.
2043 DEBUG EXPAND.
2044 !a.
2045 !b.
2046 !c.
2047 ])
2048 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
2049 define.sps:1: In the expansion of `!a',
2050 define.sps:5.1-5.2: error: DEBUG EXPAND: !THEN expected in macro !IF construct.
2051     5 | !a.
2052       | ^~
2053
2054 !IF 1
2055
2056 define.sps:2: In the expansion of `!b',
2057 define.sps:6.1-6.2: error: DEBUG EXPAND: !ELSE or !IFEND expected in macro !IF
2058 construct.
2059     6 | !b.
2060       | ^~
2061
2062 !IF 1 !THEN
2063
2064 define.sps:3: In the expansion of `!c',
2065 define.sps:7.1-7.2: error: DEBUG EXPAND: !IFEND expected in macro !IF
2066 construct.
2067     7 | !c.
2068       | ^~
2069
2070 !IF 1 !THEN !ELSE
2071 ])
2072 AT_CLEANUP
2073
2074 AT_SETUP([macro !LET errors])
2075 AT_KEYWORDS([LET])
2076 AT_DATA([define.sps], [dnl
2077 DEFINE !a() !LET !ENDDEFINE.
2078 DEFINE !b() !LET 0 !ENDDEFINE.
2079 DEFINE !c() !LET !x !ENDDEFINE.
2080 DEFINE !d() !LET !x y !ENDDEFINE.
2081 DEBUG EXPAND.
2082 !a.
2083 !b.
2084 !c.
2085 !d.
2086 ])
2087 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
2088 define.sps:1: In the expansion of `!a',
2089 define.sps:6.1-6.2: error: DEBUG EXPAND: Expected macro variable name following
2090 !LET.
2091     6 | !a.
2092       | ^~
2093
2094 !LET
2095
2096 define.sps:2: At `0' in the expansion of `!b',
2097 define.sps:7.1-7.2: error: DEBUG EXPAND: Expected macro variable name following
2098 !LET.
2099     7 | !b.
2100       | ^~
2101
2102 !LET 0
2103
2104 define.sps:3: In the expansion of `!c',
2105 define.sps:8.1-8.2: error: DEBUG EXPAND: Expected `=' following !LET.
2106     8 | !c.
2107       | ^~
2108
2109 !LET !x
2110
2111 define.sps:4: At `y' in the expansion of `!d',
2112 define.sps:9.1-9.2: error: DEBUG EXPAND: Expected `=' following !LET.
2113     9 | !d.
2114       | ^~
2115
2116 !LET !x y
2117 ])
2118 AT_CLEANUP
2119
2120 AT_SETUP([macro !DO errors])
2121 AT_KEYWORDS([DO])
2122 AT_DATA([define.sps], [dnl
2123 DEFINE !a() !DO !ENDDEFINE.
2124 DEFINE !b() !DO 0 !ENDDEFINE.
2125 DEFINE !c() !DO !x !ENDDEFINE.
2126 DEFINE !d() !DO !x !in (x) !ENDDEFINE.
2127 DEFINE !e() !DO !x = x. !ENDDEFINE.
2128 DEFINE !f() !DO !x = 5 x !ENDDEFINE.
2129 DEFINE !g() !DO !x = 5 !TO 6 !BY 0 !ENDDEFINE.
2130 DEFINE !h() !DO !x !ENDDEFINE.
2131 DEFINE !i() !DO !x 0 !ENDDEFINE.
2132 DEFINE !j() !BREAK !ENDDEFINE.
2133 DEBUG EXPAND.
2134 !a.
2135 !b.
2136 !c.
2137 !d.
2138 !e.
2139 !f.
2140 !g.
2141 !h.
2142 !i.
2143 !j.
2144 ])
2145 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
2146 define.sps:1: In the expansion of `!a',
2147 define.sps:12.1-12.2: error: DEBUG EXPAND: Expected macro variable name
2148 following !DO.
2149    12 | !a.
2150       | ^~
2151
2152 !DO
2153
2154 define.sps:2: At `0' in the expansion of `!b',
2155 define.sps:13.1-13.2: error: DEBUG EXPAND: Expected macro variable name
2156 following !DO.
2157    13 | !b.
2158       | ^~
2159
2160 !DO 0
2161
2162 define.sps:3: In the expansion of `!c',
2163 define.sps:14.1-14.2: error: DEBUG EXPAND: Expected `=' or !IN in !DO loop.
2164    14 | !c.
2165       | ^~
2166
2167 !DO !x
2168
2169 In the expansion of `!DO',
2170 define.sps:4: inside the expansion of `!d',
2171 define.sps:15.1-15.2: error: DEBUG EXPAND: Missing !DOEND.
2172    15 | !d.
2173       | ^~
2174
2175 !DO !x !in(x)
2176
2177 At `x' in the expansion of `!DO',
2178 define.sps:5: inside the expansion of `!e',
2179 define.sps:16.1-16.2: error: DEBUG EXPAND: Macro expression must evaluate to a
2180 number (not "x").
2181    16 | !e.
2182       | ^~
2183
2184 !DO !x = x.
2185
2186 At `x' in the expansion of `!DO',
2187 define.sps:6: inside the expansion of `!f',
2188 define.sps:17.1-17.2: error: DEBUG EXPAND: Expected !TO in numerical !DO loop.
2189    17 | !f.
2190       | ^~
2191
2192 !DO !x = 5 x
2193
2194 In the expansion of `!DO',
2195 define.sps:7: inside the expansion of `!g',
2196 define.sps:18.1-18.2: error: DEBUG EXPAND: !BY value cannot be zero.
2197    18 | !g.
2198       | ^~
2199
2200 !DO !x = 5 !TO 6 !BY 0
2201
2202 define.sps:8: In the expansion of `!h',
2203 define.sps:19.1-19.2: error: DEBUG EXPAND: Expected `=' or !IN in !DO loop.
2204    19 | !h.
2205       | ^~
2206
2207 !DO !x
2208
2209 define.sps:9: At `0' in the expansion of `!i',
2210 define.sps:20.1-20.2: error: DEBUG EXPAND: Expected `=' or !IN in !DO loop.
2211    20 | !i.
2212       | ^~
2213
2214 !DO !x 0
2215
2216 define.sps:10: At `!BREAK' in the expansion of `!j',
2217 define.sps:21.1-21.2: error: DEBUG EXPAND: !BREAK outside !DO.
2218    21 | !j.
2219       | ^~
2220
2221 ])
2222 AT_CLEANUP
2223
2224 AT_SETUP([macros in comments])
2225 AT_KEYWORDS([macro])
2226 AT_DATA([define.sps], [dnl
2227 DEFINE !macro() x y z !ENDDEFINE.
2228 /* !macro.
2229 *!macro.
2230 DEBUG EXPAND.
2231 !macro.
2232 ])
2233 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
2234 x y z
2235 ])
2236 AT_CLEANUP
2237
2238 AT_SETUP([DEFINE syntax errors])
2239 AT_KEYWORDS([macro])
2240 AT_DATA([define.sps], [dnl
2241 DEFINE !macro(!POSITIONAL !CHAREND('x y')) !ENDDEFINE.
2242 DEFINE !macro(a=!TOKENS(1)/!POSITIONAL !TOKENS(1)) !ENDDEFINE.
2243 DEFINE !macro(!a=!TOKENS(1)) !ENDDEFINE.
2244 DEFINE !macro(do=!TOKENS(1)) !ENDDEFINE.
2245 DEFINE 0() !ENDDEFINE.
2246 DEFINE x y () !ENDDEFINE.
2247 DEFINE !macro(1) !ENDDEFINE.
2248 DEFINE !macro(x 2) !ENDDEFINE.
2249 DEFINE !macro(x=!DEFAULT 3) !ENDDEFINE.
2250 DEFINE !macro(x=!TOKENS 4) !ENDDEFINE.
2251 DEFINE !macro(x=!TOKENS(x)) !ENDDEFINE.
2252 DEFINE !macro(x=!TOKENS(1 5)) !ENDDEFINE.
2253 DEFINE !macro(x=!ENCLOSE 6) !ENDDEFINE.
2254 DEFINE !macro(x=!ENCLOSE('x' y)) !ENDDEFINE.
2255 DEFINE !macro(x=!ENCLOSE('x',y)) !ENDDEFINE.
2256 DEFINE !macro(x=!ENCLOSE('x','y' z)) !ENDDEFINE.
2257 DEFINE !macro(x=!CHAREND 7) !ENDDEFINE.
2258 DEFINE !macro(x=!CHAREND(8)) !ENDDEFINE.
2259 DEFINE !macro(x=!CHAREND('x' 9)) !ENDDEFINE.
2260 DEFINE !macro(x=!WTF) !ENDDEFINE.
2261 DEFINE !macro(x=!TOKENS(1) x) !ENDDEFINE.
2262 DEFINE !macro(x=!DEFAULT() !DEFAULT()) !ENDDEFINE.
2263 DEFINE !macro(x=!TOKENS(1) !CMDEND) !ENDDEFINE.
2264 DEFINE !macro()
2265 ])
2266 AT_CHECK([pspp define.sps], [1], [dnl
2267 define.sps:1.36-1.40: error: DEFINE: String must contain exactly one token.
2268     1 | DEFINE !macro(!POSITIONAL !CHAREND('x y')) !ENDDEFINE.
2269       |                                    ^~~~~
2270
2271 define.sps:2.28-2.38: error: DEFINE: Positional parameters must precede keyword
2272 parameters.
2273     2 | DEFINE !macro(a=!TOKENS(1)/!POSITIONAL !TOKENS(1)) !ENDDEFINE.
2274       |                            ^~~~~~~~~~~
2275
2276 define.sps:2.15: note: DEFINE: Here is a previous keyword parameter.
2277     2 | DEFINE !macro(a=!TOKENS(1)/!POSITIONAL !TOKENS(1)) !ENDDEFINE.
2278       |               ^
2279
2280 define.sps:3.15-3.16: error: DEFINE: Keyword macro parameter must be named in
2281 definition without "!" prefix.
2282     3 | DEFINE !macro(!a=!TOKENS(1)) !ENDDEFINE.
2283       |               ^~
2284
2285 define.sps:4.15-4.16: error: DEFINE: Cannot use macro keyword "do" as an
2286 argument name.
2287     4 | DEFINE !macro(do=!TOKENS(1)) !ENDDEFINE.
2288       |               ^~
2289
2290 define.sps:5.8: error: DEFINE: Syntax error expecting identifier.
2291     5 | DEFINE 0() !ENDDEFINE.
2292       |        ^
2293
2294 define.sps:6.10: error: DEFINE: Syntax error expecting `@{:@'.
2295     6 | DEFINE x y () !ENDDEFINE.
2296       |          ^
2297
2298 define.sps:7.15: error: DEFINE: Syntax error expecting identifier.
2299     7 | DEFINE !macro(1) !ENDDEFINE.
2300       |               ^
2301
2302 define.sps:8.17: error: DEFINE: Syntax error expecting !TOKENS, !CHAREND, !
2303 ENCLOSE, or !CMDEND.
2304     8 | DEFINE !macro(x 2) !ENDDEFINE.
2305       |                 ^
2306
2307 define.sps:9.26: error: DEFINE: Syntax error expecting `@{:@'.
2308     9 | DEFINE !macro(x=!DEFAULT 3) !ENDDEFINE.
2309       |                          ^
2310
2311 define.sps:10.25: error: DEFINE: Syntax error expecting `@{:@'.
2312    10 | DEFINE !macro(x=!TOKENS 4) !ENDDEFINE.
2313       |                         ^
2314
2315 define.sps:11.25: error: DEFINE: Syntax error expecting positive integer for !
2316 TOKENS.
2317    11 | DEFINE !macro(x=!TOKENS(x)) !ENDDEFINE.
2318       |                         ^
2319
2320 define.sps:12.27: error: DEFINE: Syntax error expecting `@:}@'.
2321    12 | DEFINE !macro(x=!TOKENS(1 5)) !ENDDEFINE.
2322       |                           ^
2323
2324 define.sps:13.26: error: DEFINE: Syntax error expecting `@{:@'.
2325    13 | DEFINE !macro(x=!ENCLOSE 6) !ENDDEFINE.
2326       |                          ^
2327
2328 define.sps:14.30: error: DEFINE: Syntax error expecting `,'.
2329    14 | DEFINE !macro(x=!ENCLOSE('x' y)) !ENDDEFINE.
2330       |                              ^
2331
2332 define.sps:15.30: error: DEFINE: Syntax error expecting string.
2333    15 | DEFINE !macro(x=!ENCLOSE('x',y)) !ENDDEFINE.
2334       |                              ^
2335
2336 define.sps:16.34: error: DEFINE: Syntax error expecting `@:}@'.
2337    16 | DEFINE !macro(x=!ENCLOSE('x','y' z)) !ENDDEFINE.
2338       |                                  ^
2339
2340 define.sps:17.26: error: DEFINE: Syntax error expecting `@{:@'.
2341    17 | DEFINE !macro(x=!CHAREND 7) !ENDDEFINE.
2342       |                          ^
2343
2344 define.sps:18.26: error: DEFINE: Syntax error expecting string.
2345    18 | DEFINE !macro(x=!CHAREND(8)) !ENDDEFINE.
2346       |                          ^
2347
2348 define.sps:19.30: error: DEFINE: Syntax error expecting `@:}@'.
2349    19 | DEFINE !macro(x=!CHAREND('x' 9)) !ENDDEFINE.
2350       |                              ^
2351
2352 define.sps:20.17-20.20: error: DEFINE: Syntax error expecting !TOKENS, !
2353 CHAREND, !ENCLOSE, or !CMDEND.
2354    20 | DEFINE !macro(x=!WTF) !ENDDEFINE.
2355       |                 ^~~~
2356
2357 define.sps:21.28: error: DEFINE: Syntax error expecting `/'.
2358    21 | DEFINE !macro(x=!TOKENS(1) x) !ENDDEFINE.
2359       |                            ^
2360
2361 define.sps:22.28-22.35: error: DEFINE: !DEFAULT is allowed only once per
2362 argument.
2363    22 | DEFINE !macro(x=!DEFAULT() !DEFAULT()) !ENDDEFINE.
2364       |                            ^~~~~~~~
2365
2366 define.sps:23.28-23.34: error: DEFINE: Only one of !TOKENS, !CHAREND, !ENCLOSE,
2367 or !CMDEND is allowed.
2368    23 | DEFINE !macro(x=!TOKENS(1) !CMDEND) !ENDDEFINE.
2369       |                            ^~~~~~~
2370
2371 define.sps:25.1: error: DEFINE: Syntax error expecting macro body or !
2372 ENDDEFINE.
2373    25 |
2374       | ^
2375 ])
2376 AT_CLEANUP
2377
2378 AT_SETUP([macro expansion with token merging])
2379 AT_DATA([define.sps], [dnl
2380 DEFINE !foo() "foo" !ENDDEFINE.
2381 DEFINE !bar() "bar" !ENDDEFINE.
2382 DEFINE !plus() + !ENDDEFINE.
2383 DEFINE !minus() - !ENDDEFINE.
2384 DEFINE !one() 1 !ENDDEFINE.
2385 ECHO "foo" + "bar".
2386 ECHO !foo.
2387 ECHO !bar.
2388 ECHO !foo + "quux".
2389 ECHO "baz" + !bar.
2390 ECHO !foo + !bar.
2391 ECHO !foo !plus !bar.
2392 ECHO "two" "strings".
2393 N OF CASES -/**/1.
2394 N OF CASES !minus 1.
2395 N OF CASES - !one.
2396 N OF CASES !minus !one.
2397 ])
2398 AT_CHECK([pspp define.sps], [1], [dnl
2399 foobar
2400
2401 foo
2402
2403 bar
2404
2405 fooquux
2406
2407 bazbar
2408
2409 foobar
2410
2411 foobar
2412
2413 two
2414
2415 define.sps:13.12-13.20: error: ECHO: Syntax error expecting end of command.
2416    13 | ECHO "two" "strings".
2417       |            ^~~~~~~~~
2418
2419 define.sps:14.12-14.17: error: N OF CASES: Syntax error expecting positive
2420 integer for N OF CASES.
2421    14 | N OF CASES -/**/1.
2422       |            ^~~~~~
2423
2424 define.sps:15.12-15.19: error: N OF CASES: Syntax error expecting positive
2425 integer for N OF CASES.
2426    15 | N OF CASES !minus 1.
2427       |            ^~~~~~~~
2428
2429 define.sps:16.12-16.17: error: N OF CASES: Syntax error expecting positive
2430 integer for N OF CASES.
2431    16 | N OF CASES - !one.
2432       |            ^~~~~~
2433
2434 define.sps:17.12-17.22: error: N OF CASES: Syntax error expecting positive
2435 integer for N OF CASES.
2436    17 | N OF CASES !minus !one.
2437       |            ^~~~~~~~~~~
2438 ])
2439 AT_CLEANUP
2440
2441 AT_SETUP([one macro calls another])
2442 AT_DATA([define.sps], [dnl
2443 DEFINE !a(!pos !enclose('(',')')) [[!1]] !ENDDEFINE.
2444 DEFINE !b(!pos !enclose('{','}')) !a(x !1 z) !ENDDEFINE.
2445 DEFINE !c(!pos !enclose('{','}')) !let !tmp=!quote(!concat('<',!1,'>')) !a(!tmp) !ENDDEFINE.
2446 DEBUG EXPAND.
2447 !b{y}.
2448 !c{y}.
2449 ])
2450 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
2451 [[x y z]]
2452
2453 [[ < y > ]]
2454 ])
2455 AT_CLEANUP