1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
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.
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.
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/>.
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
26 AT_CAPTURE_FILE([define.sps])
29 AT_CHECK([pspp --testing-mode define.sps | sed '/^$/d'], [$6], [expout])
32 AT_SETUP([simple macro expansion])
33 AT_DATA([define.sps], [dnl
41 "a" "b" "c" 'a' 'b' 'c'.
47 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
52 "a" "b" "c" 'a' 'b' 'c'.
57 PSPP_CHECK_MACRO_EXPANSION([one !TOKENS(1) positional argument],
58 [DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE.],
65 note: unexpanded token "b"])
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.
73 DEFINE !ce(!positional !charend('/')) ce (!1) !ENDDEFINE.
74 DEFINE !ce2(!positional !charend('(')
75 /!positional !charend(')'))
79 DEFINE !e(!positional !enclose('{','}')) e (!1) !ENDDEFINE.
81 DEFINE !cmd(!positional !cmdend) cmd(!1) !ENDDEFINE.
82 DEFINE !cmd2(!positional !cmdend
83 /!positional !tokens(1))
87 DEFINE !p(!positional !tokens(1)
88 /!positional !tokens(1)
89 /!positional !tokens(1))
94 !title "!TOKENS(1) argument."
99 !title "!TOKENS(2) argument."
103 !title "!CHAREND argument."
109 !title "Two !CHAREND arguments."
113 !title "!ENCLOSE argument."
118 !title "!CMDEND argument."
123 !title "Three !TOKENS(1) arguments."
127 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
128 "!TOKENS(1) argument."
136 note: unexpanded token "b"
138 "!TOKENS(2) argument."
144 note: unexpanded token "d"
156 "Two !CHAREND arguments."
176 "Three !TOKENS(1) arguments."
180 p(1, -2, -3) (1 -2 -3)
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))
193 DEFINE !ce(!positional !charend('/')) ce(!1) !ENDDEFINE.
195 DEFINE !enc1(!positional !enclose('{', '}')) enc1(!1) !ENDDEFINE.
197 !title "Too few tokens for !TOKENS."
202 !title "Missing charend delimiter."
205 !title "Missing start delimiter."
208 !title "Missing end delimiter."
211 AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
212 "Too few tokens for !TOKENS."
214 define.sps:13: error: DEBUG EXPAND: Unexpected end of command reading
215 argument !3 to macro !p.
217 note: unexpanded token "!p"
219 note: unexpanded token "a"
221 note: unexpanded token "b"
223 define.sps:14: error: DEBUG EXPAND: Unexpected end of command reading
224 argument !2 to macro !p.
226 note: unexpanded token "!p"
228 note: unexpanded token "a"
230 define.sps:15: error: DEBUG EXPAND: Unexpected end of command reading
231 argument !1 to macro !p.
233 note: unexpanded token "!p"
235 "Missing charend delimiter."
237 define.sps:18: error: DEBUG EXPAND: Unexpected end of command reading
238 argument !1 to macro !ce.
240 note: unexpanded token "!ce"
242 note: unexpanded token "a"
244 note: unexpanded token "b"
246 note: unexpanded token "c"
248 "Missing start delimiter."
250 define.sps:21: error: DEBUG EXPAND: Found `a' while expecting `{' reading
251 argument !1 to macro !enc1.
253 note: unexpanded token "!enc1"
255 note: unexpanded token "a"
257 note: unexpanded token "b"
259 note: unexpanded token "c"
261 "Missing end delimiter."
263 define.sps:24: error: DEBUG EXPAND: Unexpected end of command reading
264 argument !1 to macro !enc1.
266 note: unexpanded token "!enc1"
268 note: unexpanded token "{"
270 note: unexpanded token "a"
272 note: unexpanded token "b"
274 note: unexpanded token "c"
278 PSPP_CHECK_MACRO_EXPANSION([one !TOKENS(1) keyword argument],
279 [DEFINE !k(arg1 = !TOKENS(1)) k(!arg1) !ENDDEFINE.],
285 note: unexpanded token "y"
288 PSPP_CHECK_MACRO_EXPANSION([one !TOKENS(1) keyword argument - negative],
289 [DEFINE !k(arg1 = !TOKENS(1)) k(!arg1) !ENDDEFINE.],
292 define.sps:3: error: DEBUG EXPAND: Found `.' while expecting `=' reading
293 argument !arg1 to macro !k.
294 note: unexpanded token "!k"
295 note: unexpanded token "arg1"
296 define.sps:4: error: DEBUG EXPAND: Unexpected end of command reading argument !
298 note: unexpanded token "!k"
299 note: unexpanded token "arg1"
300 note: unexpanded token "="], [1])
302 PSPP_CHECK_MACRO_EXPANSION([!CHAREND('/') keyword arguments], [dnl
303 DEFINE !k(arg1 = !CHAREND('/')
304 /arg2 = !CHAREND('/'))
316 PSPP_CHECK_MACRO_EXPANSION([!CHAREND('/') keyword arguments - negative], [dnl
317 DEFINE !k(arg1 = !CHAREND('/')
318 /arg2 = !CHAREND('/'))
325 [define.sps:6: error: DEBUG EXPAND: Found `.' while expecting `=' reading
326 argument !arg1 to macro !k.
327 note: unexpanded token "!k"
328 note: unexpanded token "arg1"
329 define.sps:7: error: DEBUG EXPAND: Unexpected end of command reading argument !
331 note: unexpanded token "!k"
332 note: unexpanded token "arg1"
333 note: unexpanded token "="
334 define.sps:8: error: DEBUG EXPAND: Unexpected end of command reading argument !
336 note: unexpanded token "!k"
337 note: unexpanded token "arg1"
338 note: unexpanded token "="
339 note: unexpanded token "x"
340 define.sps:9: error: DEBUG EXPAND: Unexpected end of command reading argument !
342 note: unexpanded token "!k"
343 note: unexpanded token "arg1"
344 note: unexpanded token "="
345 note: unexpanded token "x"
346 note: unexpanded token "/"
347 note: unexpanded token "arg2"
348 note: unexpanded token "="
349 note: unexpanded token "y"])
351 PSPP_CHECK_MACRO_EXPANSION([default keyword arguments],
352 [DEFINE !k(arg1 = !DEFAULT(a b c) !CMDEND) k(!arg1) !ENDDEFINE],
358 dnl Keep this test in sync with the examples for !BLANKS in the manual.
359 PSPP_CHECK_MACRO_EXPANSION([!BLANKS],
380 dnl Keep this test in sync with the examples for !CONCAT in the manual.
381 PSPP_CHECK_MACRO_EXPANSION([!CONCAT],
402 dnl Keep this test in sync with the examples for !EVAL in the manual.
403 PSPP_CHECK_MACRO_EXPANSION([!EVAL],
404 [DEFINE !vars() a b c !ENDDEFINE.
409 !QUOTE(!EVAL(!vars)).
411 DEFINE !e2(!positional !enclose('(',')'))
428 dnl Keep this test in sync with the examples for !HEAD in the manual.
429 PSPP_CHECK_MACRO_EXPANSION([!HEAD],
442 dnl Keep this test in sync with the examples for !TAIL in the manual.
443 PSPP_CHECK_MACRO_EXPANSION([!TAIL],
456 dnl Keep this test in sync with the examples for !INDEX in the manual.
457 PSPP_CHECK_MACRO_EXPANSION([!INDEX],
461 !INDEX(banana, apple).
462 !INDEX("banana", nan).
463 !INDEX("banana", "nan").
464 !INDEX(!UNQUOTE("banana"), !UNQUOTE("nan")).
474 dnl Keep this test in sync with the examples for !LENGTH in the manual.
475 PSPP_CHECK_MACRO_EXPANSION([!LENGTH],
484 !LENGTH(!UNQUOTE("xyzzy")).
485 !LENGTH(!UNQUOTE("xy""zzy")).
488 DEFINE !la(!positional !enclose('(',')'))
507 dnl Keep this test in sync with the examples for !SUBSTR in the manual.
508 PSPP_CHECK_MACRO_EXPANSION([!SUBSTR],
511 !SUBSTR(banana, 3, 3).
512 !SUBSTR("banana", 3).
513 !SUBSTR(!UNQUOTE("banana"), 3).
514 !SUBSTR("banana", 3, 3).
515 !SUBSTR(banana, 3, 0).
516 !SUBSTR(banana, 3, 10).
517 !SUBSTR(banana, 10, 3).
530 dnl Keep this test in sync with the examples for !UPCASE in the manual.
531 PSPP_CHECK_MACRO_EXPANSION([!UPCASE],
545 dnl !* is implemented separately inside and outside function arguments
546 dnl so this test makes sure to include both.
547 PSPP_CHECK_MACRO_EXPANSION([!*], [dnl
548 DEFINE !m(!POSITIONAL !TOKENS(1)
549 /!POSITIONAL !TOKENS(1))
558 ], [123 b / 5 / 3 b / '123 b'.
560 '' 'b' / 6 / 'b' / ''''' ''b'''.])
562 AT_SETUP([macro maximum nesting level (MNEST)])
564 AT_DATA([define.sps], [dnl
570 AT_CHECK([pspp define.sps], [1], [dnl
571 maximum nesting level exceeded
572 define.sps.1: error: Syntax error at `!macro': expecting command name.
576 AT_SETUP([macro !IF condition])
579 '!eq !ne !lt !gt !le !ge' \
584 cat > define.sps <<EOF
585 DEFINE !test(!positional !tokens(1))
586 !if (!1 $1 1) !then true !else false !ifend
587 !if (!1 $2 1) !then true !else false !ifend
588 !if (!1 $3 1) !then true !else false !ifend
589 !if (!1 $4 1) !then true !else false !ifend
590 !if (!1 $5 1) !then true !else false !ifend
591 !if (!1 $6 1) !then true !else false !ifend.
600 AT_CAPTURE_FILE([define.sps])
601 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
602 false true true false true false.
604 true false false false true true.
606 false true false true false true.
608 true false false false true true.
610 false true false true false true.
615 AT_SETUP([macro !IF condition -- case sensitivity])
618 '!eq !ne !lt !gt !le !ge' \
623 cat > define.sps <<EOF
624 DEFINE !test(!positional !tokens(1))
625 !if (!1 $1 a) !then true !else false !ifend
626 !if (!1 $1 A) !then true !else false !ifend
627 !if (!1 $2 a) !then true !else false !ifend
628 !if (!1 $2 A) !then true !else false !ifend
629 !if (!1 $3 a) !then true !else false !ifend
630 !if (!1 $3 A) !then true !else false !ifend
631 !if (!1 $4 a) !then true !else false !ifend
632 !if (!1 $4 A) !then true !else false !ifend
633 !if (!1 $5 a) !then true !else false !ifend
634 !if (!1 $5 A) !then true !else false !ifend
635 !if (!1 $6 a) !then true !else false !ifend
636 !if (!1 $6 A) !then true !else false !ifend
637 !if (!1 $1 !null) !then true !else false !ifend
638 !if (!1 $2 !null) !then true !else false !ifend.
646 AT_CAPTURE_FILE([define.sps])
647 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
648 true false false true false false false true true false true true false true.
650 false true true false true false false false true true false true false true.
652 false false true true false false true true false false true true false true.
654 false false true true true false false true true false false true false true.
659 AT_SETUP([macro !IF condition -- logical operators])
667 cat > define.sps <<EOF
668 DEFINE !test_binary(!positional !tokens(1)/!positional !tokens(1))
669 !if !1 $1 !2 !then true !else false !ifend
670 !if !1 $2 !2 !then true !else false !ifend.
673 DEFINE !test_unary(!positional !tokens(1))
674 !if $3 !1 !then true !else false !ifend.
681 DEFINE !test_prec(!pos !tokens(1)/!pos !tokens(1)/!pos !tokens(1))
682 !if $3 !1 $1 !2 $2 !3 !then true !else false !ifend
683 !if $3 (!1 $1 !2) $2 !3 !then true !else false !ifend
684 !if $3 !1 $1 (!2 $2 !3) !then true !else false !ifend
694 !test_prec 0 0 0 !test_prec 0 0 1 !test_prec 0 1 0 !test_prec 0 1 1.
695 !test_prec 1 0 0 !test_prec 1 0 1 !test_prec 1 1 0 !test_prec 1 1 1.
697 AT_CAPTURE_FILE([define.sps])
698 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
724 AT_SETUP([macro !LET])
726 AT_DATA([define.sps], [dnl
727 DEFINE !macro(!POS !CMDEND)
728 !LET !v1 = !CONCAT('x',!1,'y')
729 !LET !v2 = !QUOTE(!v1)
730 !LET !v3 = (!LENGTH(!1) = 1)
731 !LET !v4 = (!SUBSTR(!1, 3) = !NULL)
742 AT_CHECK([pspp --testing-mode define.sps], [0], [dnl