dnl PSPP - a program for statistical analysis.
dnl Copyright (C) 2017 Free Software Foundation, Inc.
dnl
dnl This program is free software: you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation, either version 3 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU nGeneral Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program. If not, see .
dnl
AT_BANNER([DEFINE])
AT_SETUP([simple macro expansion])
AT_DATA([define.sps], [dnl
DEFINE !macro()
a b c d
e f g h.
i j k l
1,2,3,4.
5+6+7.
m(n,o).
"a" "b" "c" 'a' 'b' 'c'.
"x "" y".
!ENDDEFINE.
DEBUG EXPAND.
!macro
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
a b c d e f g h.
i j k l 1, 2, 3, 4.
5 + 6 + 7.
m(n, o).
"a" "b" "c" 'a' 'b' 'c'.
"x "" y".
])
AT_CLEANUP
AT_SETUP([redefining a macro])
AT_DATA([define.sps], [dnl
DEFINE !macro() 0 !ENDDEFINE.
DEFINE !macro() 1 !ENDDEFINE.
DEBUG EXPAND.
!macro.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
1
])
AT_CLEANUP
AT_SETUP([macro expansion - one !TOKENS(1) positional argument])
AT_KEYWORDS([TOKENS])
AT_DATA([define.sps], [dnl
DEFINE !t1(!positional=!tokens(1)) t1 (!1) !ENDDEFINE.
DEBUG EXPAND.
!t1 a.
!t1 b.
!t1 a b.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
t1(a)
t1(b)
t1(a)
note: unexpanded token "b"
])
AT_CLEANUP
AT_SETUP([macro expansion with positional arguments])
AT_DATA([define.sps], [dnl
DEFINE !title(!positional !tokens(1)) !1 !ENDDEFINE.
DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE.
DEFINE !t2(!positional !tokens(2)) t2 (!1) !ENDDEFINE.
DEFINE !ce(!positional=!charend('/')) ce (!1) !ENDDEFINE.
DEFINE !ce2(!positional=!charend('(')
/!positional !charend(')'))
ce2 (!1, !2)
!ENDDEFINE.
DEFINE !e(!positional !enclose('{','}')) e (!1) !ENDDEFINE.
DEFINE !cmd(!positional !cmdend) cmd(!1) !ENDDEFINE.
DEFINE !cmd2(!positional !cmdend
/!positional !tokens(1))
cmd2(!1, !2)
!ENDDEFINE.
DEFINE !p(!positional !tokens(1)
/!positional !tokens(1)
/!positional !tokens(1))
p(!1, !2, !3)(!*)
!ENDDEFINE.
DEBUG EXPAND.
!title "!TOKENS(1) argument."
!t1 a.
!t1 b.
!t1 a b.
!title "!TOKENS(2) argument."
!t2 a b.
!t2 b c d.
!title "!CHAREND argument."
!ce/.
!ce x/.
!ce x y/.
!ce x y z/.
!title "Two !CHAREND arguments."
!ce2 x(y).
!ce2 1 2 3 4().
!title "!ENCLOSE argument."
!e {}.
!e {a}.
!e {a b}.
!title "!CMDEND argument."
!cmd 1 2 3 4.
!cmd2 5 6.
7.
!title "Three !TOKENS(1) arguments."
!p a b c.
!p 1 -2 -3.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
"!TOKENS(1) argument."
t1(a)
t1(b)
t1(a)
note: unexpanded token "b"
"!TOKENS(2) argument."
t2(a b)
t2(b c)
note: unexpanded token "d"
"!CHAREND argument."
ce( )
ce(x)
ce(x y)
ce(x y z)
"Two !CHAREND arguments."
ce2(x, y)
ce2(1 2 3 4, )
"!ENCLOSE argument."
e( )
e(a)
e(a b)
"!CMDEND argument."
cmd(1 2 3 4)
cmd2(5 6, )
note: unexpanded token "7"
"Three !TOKENS(1) arguments."
p(a, b, c) (a b c)
p(1, -2, -3) (1 -2 -3)
])
AT_CLEANUP
AT_SETUP([macro call missing positional !TOKENS arguments])
AT_KEYWORDS([TOKENS])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !tokens(1) !default(x)
/!positional !tokens(1) !default(y)
/!positional !tokens(1) !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p a b c.
!p a b.
!p a.
!p.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
(a, b, c)
(a, b, z)
(a, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([macro call incomplete positional !TOKENS arguments])
AT_KEYWORDS([TOKENS])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !tokens(2) !default(x)
/!positional !tokens(2) !default(y)
/!positional !tokens(2) !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p a1 a2 b1 b2 c1 c2.
!p a1 a2 b1 b2 c1.
!p a1 a2 b1 b2.
!p a1 a2 b1.
!p a1 a2.
!p a1.
!p.
])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
(a1 a2, b1 b2, c1 c2)
define.sps:8.18: error: DEBUG EXPAND: Reached end of command expecting 1 more
token in argument !3 to macro !p.
(a1 a2, b1 b2, c1)
(a1 a2, b1 b2, z)
define.sps:10.12: error: DEBUG EXPAND: Reached end of command expecting 1 more
token in argument !2 to macro !p.
(a1 a2, b1, z)
(a1 a2, y, z)
define.sps:12.6: error: DEBUG EXPAND: Reached end of command expecting 1 more
token in argument !1 to macro !p.
(a1, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([macro call empty positional !CHAREND arguments])
AT_KEYWORDS([CHAREND])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !charend(',') !default(x)
/!positional !charend(';') !default(y)
/!positional !charend(':') !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p a,b;c:.
!p a,b;:.
!p a,;c:.
!p a,;:.
!p,b;c:.
!p,b;:.
!p,;c:.
!p,;:.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
(a, b, c)
(a, b, )
(a, , c)
(a, , )
(, b, c)
(, b, )
(, , c)
(, , )
])
AT_CLEANUP
AT_SETUP([macro call missing positional !CHAREND arguments])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !charend(',') !default(x)
/!positional !charend(';') !default(y)
/!positional !charend(':') !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p a,b;c:.
!p a,b;.
!p a,;.
!p ,b;.
!p ,;.
!p a,.
!p ,.
!p.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
(a, b, c)
(a, b, z)
(a, , z)
(, b, z)
(, , z)
(a, y, z)
(, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([macro call incomplete positional !CHAREND arguments])
AT_KEYWORDS([CHAREND])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !charend(',') !default(x)
/!positional !charend(';') !default(y)
/!positional !charend(':') !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p a,b;c:.
!p a,b;c.
!p a,b;.
!p a,b.
!p a,.
!p a.
!p.
])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
(a, b, c)
define.sps:8.9: error: DEBUG EXPAND: Reached end of command expecting ":" in
argument !3 to macro !p.
(a, b, c)
(a, b, z)
define.sps:10.7: error: DEBUG EXPAND: Reached end of command expecting ";" in
argument !2 to macro !p.
(a, b, z)
(a, y, z)
define.sps:12.5: error: DEBUG EXPAND: Reached end of command expecting "," in
argument !1 to macro !p.
(a, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([macro call missing positional !ENCLOSE arguments])
AT_KEYWORDS([ENCLOSE])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !enclose('(',')') !default(x)
/!positional !enclose('<','>') !default(y)
/!positional !enclose('{','}') !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p (a){c}.
!p (a).
!p (a).
!p.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
(a, b, c)
(a, b, z)
(a, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([macro call incomplete positional !ENCLOSE arguments])
AT_KEYWORDS([ENCLOSE])
AT_DATA([define.sps], [dnl
DEFINE !p(!positional !enclose('(',')') !default(x)
/!positional !enclose('<','>') !default(y)
/!positional !enclose('{','}') !default(z))
(!1, !2, !3)
!ENDDEFINE.
DEBUG EXPAND.
!p (a){c}.
!p (a){c.
!p (a){.
!p (a).
!p (a)" in
argument !2 to macro !p.
(a, b, z)
define.sps:12.8: error: DEBUG EXPAND: Reached end of command expecting ">" in
argument !2 to macro !p.
(a, , z)
(a, y, z)
define.sps:14.6: error: DEBUG EXPAND: Reached end of command expecting ")" in
argument !1 to macro !p.
(a, y, z)
define.sps:15.5: error: DEBUG EXPAND: Reached end of command expecting ")" in
argument !1 to macro !p.
(, y, z)
(x, y, z)
])
AT_CLEANUP
AT_SETUP([keyword macro argument name with ! prefix])
AT_DATA([define.sps], [dnl
DEFINE !macro(!x !TOKENS(1).
])
AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
"define.sps:1.15-1.16: error: DEFINE: Syntax error at `!x': Keyword macro parameter must be named in definition without ""!"" prefix."
])
AT_CLEANUP
AT_SETUP([reserved macro keyword argument name])
AT_DATA([define.sps], [dnl
DEFINE !macro(if=!TOKENS(1).
])
AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
"define.sps:1.15-1.16: error: DEFINE: Syntax error at `if': Cannot use macro keyword ""if"" as an argument name."
])
AT_CLEANUP
AT_SETUP([macro expansion - one !TOKENS(1) keyword argument])
AT_KEYWORDS([TOKENS])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 = !TOKENS(1)) k(!arg1) !ENDDEFINE.
DEBUG EXPAND.
!k arg1=x.
!k arg1=x y.
!k.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
k(x)
k(x)
note: unexpanded token "y"
k( )
])
AT_CLEANUP
AT_SETUP([macro expansion - one !TOKENS(1) keyword argument - negative])
AT_KEYWORDS([TOKENS])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 !TOKENS(1)) k(!arg1) !ENDDEFINE.
DEBUG EXPAND.
!k arg1.
!k arg1=.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
define.sps:3.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
argument !arg1 to macro !k.
k( )
define.sps:4.9: error: DEBUG EXPAND: Reached end of command expecting 1 more
token in argument !arg1 to macro !k.
k( )
])
AT_CLEANUP
AT_SETUP([macro expansion - !CHAREND keyword arguments])
AT_KEYWORDS([CHAREND])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 = !CHAREND('/')
/arg2 = !CHAREND('/'))
k(!arg1, !arg2)
!ENDDEFINE.
DEBUG EXPAND.
!k arg1=x/ arg2=y/.
!k arg1=x/.
!k arg2=y/.
!k.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
k(x, y)
k(x, )
k(, y)
k(, )
])
AT_CLEANUP
AT_SETUP([macro expansion - !CHAREND keyword arguments - negative])
AT_KEYWORDS([CHAREND])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 = !CHAREND('/')
/arg2 = !CHAREND('/'))
k(!arg1, !arg2)
!ENDDEFINE.
DEBUG EXPAND.
!k arg1.
!k arg1=.
!k arg1=x.
!k arg1=x/ arg2=y.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
define.sps:6.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
argument !arg1 to macro !k.
k(, )
define.sps:7.9: error: DEBUG EXPAND: Reached end of command expecting "/" in
argument !arg1 to macro !k.
k(, )
define.sps:8.10: error: DEBUG EXPAND: Reached end of command expecting "/" in
argument !arg1 to macro !k.
k(x, )
define.sps:9.18: error: DEBUG EXPAND: Reached end of command expecting "/" in
argument !arg2 to macro !k.
k(x, y)
])
AT_CLEANUP
AT_SETUP([macro expansion - !ENCLOSE keyword arguments])
AT_KEYWORDS([ENCLOSE])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 = !ENCLOSE('(',')')
/arg2 = !ENCLOSE('{','}'))
k(!arg1, !arg2)
!ENDDEFINE.
DEBUG EXPAND.
!k arg1=(x) arg2={y}.
!k arg1=(x).
!k arg2={y}.
!k.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
k(x, y)
k(x, )
k(, y)
k(, )
])
AT_CLEANUP
AT_SETUP([macro expansion - !ENCLOSE keyword arguments - negative])
AT_KEYWORDS([ENCLOSE])
AT_DATA([define.sps], [dnl
DEFINE !k(arg1 = !ENCLOSE('(',')')
/arg2 = !ENCLOSE('{','}'))
k(!arg1, !arg2)
!ENDDEFINE.
DEBUG EXPAND.
!k arg1.
!k arg1=.
!k arg1=x.
!k arg1=(x.
!k arg1=(x) arg2.
!k arg1=(x) arg2=.
!k arg1=(x) arg2=y.
!k arg1=(x) arg2=(y.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
define.sps:6.8: error: DEBUG EXPAND: Found `.' while expecting `=' reading
argument !arg1 to macro !k.
k(, )
define.sps:7.9: error: DEBUG EXPAND: Found `.' while expecting `@{:@' reading
argument !arg1 to macro !k.
k(, )
define.sps:8.9: error: DEBUG EXPAND: Found `x' while expecting `@{:@' reading
argument !arg1 to macro !k.
k(, )
note: unexpanded token "x"
define.sps:9.11: error: DEBUG EXPAND: Reached end of command expecting "@:}@" in
argument !arg1 to macro !k.
k(x, )
define.sps:10.17: error: DEBUG EXPAND: Found `.' while expecting `=' reading
argument !arg2 to macro !k.
k(x, )
define.sps:11.18: error: DEBUG EXPAND: Found `.' while expecting `{' reading
argument !arg2 to macro !k.
k(x, )
define.sps:12.18: error: DEBUG EXPAND: Found `y' while expecting `{' reading
argument !arg2 to macro !k.
k(x, )
note: unexpanded token "y"
define.sps:13.18: error: DEBUG EXPAND: Found `@{:@' while expecting `{' reading
argument !arg2 to macro !k.
k(x, )
note: unexpanded token "@{:@"
note: unexpanded token "y"
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !BLANKS in the manual.
AT_SETUP([macro expansion - !BLANKS])
AT_KEYWORDS([BLANKS])
AT_DATA([define.sps], [dnl
DEFINE !b()
!BLANKS(0).
!QUOTE(!BLANKS(0)).
!BLANKS(1).
!QUOTE(!BLANKS(1)).
!BLANKS(2).
!QUOTE(!BLANKS(2)).
!BLANKS(5).
!QUOTE(!BLANKS(5)).
!ENDDEFINE.
DEBUG EXPAND.
!b.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
.
''.
.
' '.
.
' '.
.
' '.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !CONCAT in the manual.
AT_SETUP([macro expansion - !CONCAT])
AT_KEYWORDS([CONCAT])
AT_DATA([define.sps], [dnl
DEFINE !c()
!CONCAT(x, y).
!CONCAT('x', 'y').
!CONCAT(12, 34).
!CONCAT(!NULL, 123).
!CONCAT(x, 0).
!CONCAT(x, 0, y).
!CONCAT(0, x).
!CONCAT(0, x, y).
!ENDDEFINE.
DEBUG EXPAND.
!c
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
xy.
xy.
1234.
123.
x0.
x0y.
0 x.
0 xy.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !EVAL in the manual.
AT_SETUP([macro expansion - !EVAL])
AT_KEYWORDS([EVAL])
AT_DATA([define.sps], [dnl
DEFINE !vars() a b c !ENDDEFINE.
DEFINE !e()
!vars.
!QUOTE(!vars).
!EVAL(!vars).
!QUOTE(!EVAL(!vars)).
!ENDDEFINE
DEFINE !e2(!positional !enclose('(',')'))
!1.
!QUOTE(!1).
!EVAL(!1).
!QUOTE(!EVAL(!1)).
!ENDDEFINE.
DEBUG EXPAND.
!e.
!e2(!vars).
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
a b c.
'!vars'.
a b c.
'a b c'.
a b c.
'!vars'.
a b c.
'a b c'.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !HEAD in the manual.
AT_SETUP([macro expansion - !HEAD])
AT_KEYWORDS([HEAD])
AT_DATA([define.sps], [dnl
DEFINE !h()
!HEAD('a b c').
!HEAD('a').
!HEAD(!NULL).
!HEAD('').
!ENDDEFINE.
DEBUG EXPAND.
!h.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
a.
a.
.
.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !TAIL in the manual.
AT_SETUP([macro expansion - !TAIL])
AT_KEYWORDS([TAIL])
AT_DATA([define.sps], [dnl
DEFINE !t()
!TAIL('a b c').
!TAIL('a').
!TAIL(!NULL).
!TAIL('').
!ENDDEFINE.
DEBUG EXPAND.
!t.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
b c.
.
.
.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !INDEX in the manual.
AT_SETUP([macro expansion - !INDEX])
AT_KEYWORDS([INDEX])
AT_DATA([define.sps], [dnl
DEFINE !i()
!INDEX(banana, an).
!INDEX(banana, nan).
!INDEX(banana, apple).
!INDEX("banana", nan).
!INDEX("banana", "nan").
!INDEX(!UNQUOTE("banana"), !UNQUOTE("nan")).
!ENDDEFINE.
DEBUG EXPAND.
!i.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
2.
3.
0.
4.
0.
3.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !LENGTH in the manual.
AT_SETUP([macro expansion - !LENGTH])
AT_KEYWORDS([LENGTH])
AT_DATA([define.sps], [dnl
DEFINE !l()
!LENGTH(123).
!LENGTH(123.00).
!LENGTH( 123 ).
!LENGTH("123").
!LENGTH(xyzzy).
!LENGTH("xyzzy").
!LENGTH("xy""zzy").
!LENGTH(!UNQUOTE("xyzzy")).
!LENGTH(!UNQUOTE("xy""zzy")).
!LENGTH(!NULL).
!ENDDEFINE.
DEFINE !la(!positional !enclose('(',')'))
!LENGTH(!1).
!ENDDEFINE.
DEBUG EXPAND.
!l.
!la(a b c).
!la().
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
3.
6.
3.
5.
5.
7.
9.
5.
6.
0.
5.
0.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !NULL in the manual.
AT_SETUP([macro expansion - !NULL])
AT_KEYWORDS([NULL])
AT_DATA([define.sps], [dnl
DEFINE !n()
!NULL.
!QUOTE(!NULL).
!ENDDEFINE.
DEBUG EXPAND.
!n.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
.
''.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !QUOTE and !UNQUOTE in the manual.
AT_SETUP([macro expansion - !QUOTE and !UNQUOTE])
AT_KEYWORDS([QUOTE UNQUOTE])
AT_DATA([define.sps], [dnl
DEFINE !q(!POS !CMDEND)
!QUOTE(123.0).
!QUOTE( 123 ).
!QUOTE('a b c').
!QUOTE("a b c").
!QUOTE(!1).
!UNQUOTE(123.0).
!UNQUOTE( 123 ).
!UNQUOTE('a b c').
!UNQUOTE("a b c").
!UNQUOTE(!1).
!QUOTE(!UNQUOTE(123.0)).
!QUOTE(!UNQUOTE( 123 )).
!QUOTE(!UNQUOTE('a b c')).
!QUOTE(!UNQUOTE("a b c")).
!QUOTE(!UNQUOTE(!1)).
!ENDDEFINE.
DEBUG EXPAND.
!q a 'b' c.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
'123.0'.
'123'.
'a b c'.
"a b c".
'a ''b'' c'.
123.0.
123.
a b c.
a b c.
a 'b' c.
'123.0'.
'123'.
'a b c'.
'a b c'.
'a ''b'' c'.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !SUBSTR in the manual.
AT_SETUP([macro expansion - !SUBSTR])
AT_KEYWORDS([SUBSTR])
AT_DATA([define.sps], [dnl
DEFINE !s()
!SUBSTR(banana, 3).
!SUBSTR(banana, 3, 3).
!SUBSTR("banana", 1, 3).
!SUBSTR(!UNQUOTE("banana"), 3).
!SUBSTR("banana", 3, 3).
!SUBSTR(banana, 3, 0).
!SUBSTR(banana, 3, 10).
!SUBSTR(banana, 10, 3).
!ENDDEFINE.
DEBUG EXPAND.
!s.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [1], [dnl
define.sps:1-10: At `"ba' in the expansion of `!s',dnl "
define.sps:12.1-12.2: error: DEBUG EXPAND: Unterminated string constant.
nana.
nan.
.
nana.
ana.
.
nana.
.
])
AT_CLEANUP
dnl Keep this test in sync with the examples for !UPCASE in the manual.
AT_SETUP([macro expansion - !UPCASE])
AT_KEYWORDS([UPCASE])
AT_DATA([define.sps], [dnl
DEFINE !u()
!UPCASE(freckle).
!UPCASE('freckle').
!UPCASE('a b c').
!UPCASE('A B C').
!ENDDEFINE.
DEBUG EXPAND.
!u.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
FRECKLE.
FRECKLE.
A B C.
A B C.
])
AT_CLEANUP
dnl !* is implemented separately inside and outside function arguments
dnl so this test makes sure to include both.
AT_SETUP([macro expansion - !*])
AT_DATA([define.sps], [dnl
DEFINE !m(!POSITIONAL !TOKENS(1)
/!POSITIONAL !TOKENS(1))
!*/
!LENGTH(!*)/
!SUBSTR(!*, 3)/
!QUOTE(!*).
!ENDDEFINE.
DEBUG EXPAND.
!m 123 b
!m 2 3
!m '' 'b'.
])
AT_CAPTURE_FILE([define.sps])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
123 b / 5 / 3 b / '123 b'.
2 3 / 3 / 3 / '2 3'.
'' 'b' / 6 / 'b' / ''''' ''b'''.
])
AT_CLEANUP
AT_SETUP([macro maximum nesting level (MNEST)])
AT_KEYWORDS([MNEST])
AT_DATA([define.sps], [dnl
DEFINE !macro()
!macro
!ENDDEFINE.
!macro.
])
AT_CHECK([pspp -O format=csv define.sps], [1], [dnl
"define.sps:1-3: In the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:1-3: inside the expansion of `!macro',
define.sps:4.1-4.6: error: DEFINE: Maximum nesting level 50 exceeded. (Use SET MNEST to change the limit.)"
define.sps:4.1-4.6: error: Syntax error at `!macro' (in expansion of `!macro'): expecting command name.
])
AT_CLEANUP
AT_SETUP([macro !IF condition])
AT_KEYWORDS([if])
for operators in \
'!eq !ne !lt !gt !le !ge' \
' = <> < > <= >='
do
set $operators
AS_BOX([$operators])
cat > define.sps < < > <= >='
do
set $operators
AS_BOX([$operators])
cat > define.sps < define.sps <title.sps <expout <')) !a(!tmp) !ENDDEFINE.
DEBUG EXPAND.
!b{y}.
!c{y}.
])
AT_CHECK([pspp --testing-mode define.sps], [0], [dnl
[[x y z]]
[[ < y > ]]
])
AT_CLEANUP