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