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 General 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 <http://www.gnu.org/licenses/>.
dnl
AT_BANNER([DO REPEAT])

AT_SETUP([DO REPEAT -- simple])
AT_DATA([do-repeat.sps], [dnl
INPUT PROGRAM.
STRING y(A1).
DO REPEAT xval = 1 2 3 / yval = 'a' 'b' 'c' / var = a b c.
COMPUTE x=xval.
COMPUTE y=yval.
COMPUTE var=xval.
END CASE.
END REPEAT PRINT.
END FILE.
END INPUT PROGRAM.
LIST.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
COMPUTE x=1.
COMPUTE y='a'.
COMPUTE a=1.
END CASE.

COMPUTE x=2.
COMPUTE y='b'.
COMPUTE b=2.
END CASE.

COMPUTE x=3.
COMPUTE y='c'.
COMPUTE c=3.
END CASE.

Table: Data List
y,x,a,b,c
a,1.00,1.00,.  ,.  @&t@
b,2.00,.  ,2.00,.  @&t@
c,3.00,.  ,.  ,3.00
])
AT_CLEANUP

AT_SETUP([DO REPEAT -- containing BEGIN DATA])
AT_DATA([do-repeat.sps], [dnl
DO REPEAT offset = 1 2 3.
DATA LIST NOTABLE /x 1-2.
BEGIN DATA.
10
20
30
END DATA.
COMPUTE x = x + offset.
LIST.
END REPEAT.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
x
11
21
31

Table: Data List
x
12
22
32

Table: Data List
x
13
23
33
])
AT_CLEANUP

AT_SETUP([DO REPEAT -- dummy vars not expanded in include files])
AT_DATA([include.sps], [dnl
COMPUTE y = y + x + 10.
])
AT_DATA([do-repeat.sps], [dnl
INPUT PROGRAM.
COMPUTE x = 0.
COMPUTE y = 0.
END CASE.
END FILE.
END INPUT PROGRAM.

DO REPEAT x = 1 2 3.
INCLUDE include.sps.
END REPEAT.

LIST.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps], [0], [dnl
do-repeat.sps:8.11: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
    8 | DO REPEAT x = 1 2 3.
      |           ^
])
AT_CHECK([cat pspp.csv], [0], [dnl
"do-repeat.sps:8.11: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
    8 | DO REPEAT x = 1 2 3.
      |           ^"

Table: Data List
x,y
.00,30.00
])
AT_CLEANUP

AT_SETUP([DO REPEAT -- nested])
AT_DATA([do-repeat.sps], [dnl
DATA LIST NOTABLE /a 1.
BEGIN DATA.
0
END DATA.

DO REPEAT h = h0 TO h3 / x = 0 TO 3 / y = 8, 7.5, 6, 5.
	COMPUTE h = x + y.
END REPEAT.

VECTOR v(6).
COMPUTE #idx = 0.
DO REPEAT i = 1 TO 2.
	DO REPEAT j = 3 TO 5.
		COMPUTE #x = i + j.
		COMPUTE #idx = #idx + 1.
		COMPUTE v(#idx) = #x.
	END REPEAT.
END REPEAT.

LIST.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
Table: Data List
a,h0,h1,h2,h3,v1,v2,v3,v4,v5,v6
0,8.00,8.50,8.00,8.00,4.00,5.00,6.00,5.00,6.00,7.00
])
AT_CLEANUP

dnl This program tests for a bug that crashed PSPP given an empty DO
dnl REPEAT...END REPEAT block.  See bug #18407.
AT_SETUP([DO REPEAT -- empty])
AT_DATA([do-repeat.sps], [dnl
DATA LIST NOTABLE /a 1.
BEGIN DATA.
0
END DATA.

DO REPEAT h = a.
END REPEAT.
])
AT_CHECK([pspp -o pspp.csv do-repeat.sps])
AT_CHECK([cat pspp.csv], [0], [dnl
])
AT_CLEANUP

dnl This program tests for a bug that crashed PSPP when END REPEAT
dnl was missing.  See bug #31016.
AT_SETUP([DO REPEAT -- missing END REPEAT])
AT_DATA([do-repeat.sps], [dnl
DATA LIST NOTABLE /x 1.
DO REPEAT y = 1 TO 10.
])
AT_CHECK([pspp -O format=csv do-repeat.sps], [1], [dnl
error: DO REPEAT: At end of input: Syntax error expecting END REPEAT.
])
AT_CLEANUP

AT_SETUP([DO REPEAT -- syntax errors])
AT_DATA([do-repeat.sps], [dnl
DATA LIST LIST NOTABLE /x.
DO REPEAT **.
END REPEAT.
DO REPEAT x **.
END REPEAT.
DO REPEAT y=1/y=2.
END REPEAT.
DO REPEAT y=a b c **.
END REPEAT.
DO REPEAT y=1 2 **.
END REPEAT.
DO REPEAT y='a' 'b' **.
END REPEAT.
DO REPEAT y=**.
END REPEAT.
DO REPEAT y=1 2 3/z=4.
])
AT_DATA([insert.sps], [dnl
INSERT FILE='do-repeat.sps' ERROR=IGNORE.
])
AT_CHECK([pspp --testing-mode -O format=csv insert.sps], [1], [dnl
"do-repeat.sps:2.11-2.12: error: DO REPEAT: Syntax error expecting identifier.
    2 | DO REPEAT **.
      |           ^~"

"do-repeat.sps:4.11: warning: DO REPEAT: Dummy variable name `x' hides dictionary variable `x'.
    4 | DO REPEAT x **.
      |           ^"

"do-repeat.sps:4.13-4.14: error: DO REPEAT: Syntax error expecting `='.
    4 | DO REPEAT x **.
      |             ^~"

"do-repeat.sps:6.15: error: DO REPEAT: Dummy variable name `y' is given twice.
    6 | DO REPEAT y=1/y=2.
      |               ^"

"do-repeat.sps:8.19-8.20: error: DO REPEAT: Syntax error expecting `/' or end of command.
    8 | DO REPEAT y=a b c **.
      |                   ^~"

"do-repeat.sps:10.17-10.18: error: DO REPEAT: Syntax error expecting number.
   10 | DO REPEAT y=1 2 **.
      |                 ^~"

"do-repeat.sps:12.21-12.22: error: DO REPEAT: Syntax error expecting string.
   12 | DO REPEAT y='a' 'b' **.
      |                     ^~"

"do-repeat.sps:14.13-14.14: error: DO REPEAT: Syntax error expecting substitution values.
   14 | DO REPEAT y=**.
      |             ^~"

do-repeat.sps:16: error: DO REPEAT: Each dummy variable must have the same number of substitutions.

"do-repeat.sps:16.11-16.17: note: DO REPEAT: Dummy variable y had 3 substitutions.
   16 | DO REPEAT y=1 2 3/z=4.
      |           ^~~~~~~"

"do-repeat.sps:16.19-16.21: note: DO REPEAT: Dummy variable z had 1 substitution.
   16 | DO REPEAT y=1 2 3/z=4.
      |                   ^~~"

error: DO REPEAT: At end of input: Syntax error expecting END REPEAT.
])
AT_CLEANUP

AT_SETUP([DO REPEAT -- duplicate substitutions])
AT_DATA([do-repeat.sps], [dnl
DATA LIST LIST NOTABLE / numer1 numer2 denom1.
BEGIN DATA
30 25 100
20 15 100
10 40 100
20 10 100
END DATA.

* Check that duplicates are OK for both existing (denom1)
  and nonexistent (perc1) variables.
DO REPEAT n=numer1 numer2
     /d = denom1 denom1
     /p = perc1 perc1.
   COMPUTE p = n / d * 100.
END REPEAT PRINT.
])
AT_CHECK([pspp do-repeat.sps], [0], [dnl
   COMPUTE perc1 = numer1 / denom1 * 100.

   COMPUTE perc1 = numer2 / denom1 * 100.
])
AT_CLEANUP