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