+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([RECODE transformation])
m4_define([RECODE_SAMPLE_DATA],
AT_CHECK([pspp -O format=csv recode.sps], [0],
[Table: Data List
s,t,s0,s1,s2,s3,t0,t1,t2,t3
-,,,,xyz ,,,,xyz ,
-a ,a ,b ,,xyz ,,b ,,xyz ,b @&t@
-ab ,ab ,bc ,,xyz ,,bc ,,xyz ,
-abc ,abc ,,,def ,,,,def ,
-abcd,abcd ,,xyzw,xyz ,,,xyzw ,xyz ,
-123 ,123 ,,,xyz ,,,,xyz ,
-123,123 ,,,xyz ,,,,xyz ,
-+1 ,+1 ,,,xyz ,,,,xyz ,
-1x ,1x ,,,xyz ,,,,xyz ,
-abcd,abcdefghi ,,xyzw,xyz ,,,,xyz ,xyz @&t@
-xxx ,abcdefghij,,,xyz ,gone,,,xyz ,jklmnopqr @&t@
+,,,,xyz,,,,xyz,
+a,a,b,,xyz,,b,,xyz,b
+ab,ab,bc,,xyz,,bc,,xyz,
+abc,abc,,,def,,,,def,
+abcd,abcd,,xyzw,xyz,,,xyzw,xyz,
+123,123,,,xyz,,,,xyz,
+123,123,,,xyz,,,,xyz,
++1,+1,,,xyz,,,,xyz,
+1x,1x,,,xyz,,,,xyz,
+abcd,abcdefghi,,xyzw,xyz,,,,xyz,xyz
+xxx,abcdefghij,,,xyz,gone,,,xyz,jklmnopqr
])
AT_CLEANUP
AT_CHECK([pspp -O format=csv recode.sps], [0],
[Table: Data List
s,t,cs0,cs1,cs2,ct0,ct1,ct2,ct3
-,,,,xyz ,,,xyz ,
-a ,a ,b ,a ,xyz ,b ,a ,xyz ,b @&t@
-ab ,ab ,bc ,ab ,xyz ,bc ,ab ,xyz ,ab @&t@
-abc ,abc ,abc ,abc ,def ,abc ,abc ,def ,abc @&t@
-abcd,abcd ,abcd,xyzw,xyz ,abcd ,xyzw ,xyz ,abcd @&t@
-123 ,123 ,123 ,123 ,xyz ,123 ,123 ,xyz ,123 @&t@
-123,123 ,123,123,xyz ,123 ,123 ,xyz ,123 @&t@
-+1 ,+1 ,+1 ,+1 ,xyz ,+1 ,+1 ,xyz ,+1 @&t@
-1x ,1x ,1x ,1x ,xyz ,1x ,1x ,xyz ,1x @&t@
-abcd,abcdefghi ,abcd,xyzw,xyz ,abcdefghi ,abcdefghi ,xyz ,xyz @&t@
-xxx ,abcdefghij,xxx ,xxx ,xyz ,abcdefghij,abcdefghij,xyz ,jklmnopqr @&t@
+,,,,xyz,,,xyz,
+a,a,b,a,xyz,b,a,xyz,b
+ab,ab,bc,ab,xyz,bc,ab,xyz,ab
+abc,abc,abc,abc,def,abc,abc,def,abc
+abcd,abcd,abcd,xyzw,xyz,abcd,xyzw,xyz,abcd
+123,123,123,123,xyz,123,123,xyz,123
+123,123,123,123,xyz,123,123,xyz,123
++1,+1,+1,+1,xyz,+1,+1,xyz,+1
+1x,1x,1x,1x,xyz,1x,1x,xyz,1x
+abcd,abcdefghi,abcd,xyzw,xyz,abcdefghi,abcdefghi,xyz,xyz
+xxx,abcdefghij,xxx,xxx,xyz,abcdefghij,abcdefghij,xyz,jklmnopqr
])
AT_CLEANUP
[Table: Data List
s,t,ns0,ns1,ns2,nt0,nt1,nt2
,,.,0,3,.,0,3
-a ,a ,.,.,3,.,.,3
-ab ,ab ,.,.,3,.,.,3
-abc ,abc ,.,.,3,.,.,3
-abcd,abcd ,1,1,2,1,1,2
-123 ,123 ,123,123,3,123,123,3
-123,123 ,123,123,3,123,123,3
-+1 ,+1 ,1,1,3,1,1,3
-1x ,1x ,.,.,1,.,.,1
-abcd,abcdefghi ,1,1,2,.,.,3
-xxx ,abcdefghij,.,.,3,.,.,3
+a,a,.,.,3,.,.,3
+ab,ab,.,.,3,.,.,3
+abc,abc,.,.,3,.,.,3
+abcd,abcd,1,1,2,1,1,2
+123,123,123,123,3,123,123,3
+123,123,123,123,3,123,123,3
++1,+1,1,1,3,1,1,3
+1x,1x,.,.,1,.,.,1
+abcd,abcdefghi,1,1,2,.,.,3
+xxx,abcdefghij,.,.,3,.,.,3
])
AT_CLEANUP
AT_CHECK([pspp -O format=csv recode.sps], [0],
[Table: Data List
x,sx0,sx1,sx2
-0,,xxx ,foobar @&t@
-1,abcdefghij,xxx ,foobar @&t@
-2,abcdefghij,,xyz @&t@
-3,abcdefghij,xxx ,xyz @&t@
-4,abcdefghij,,xyz @&t@
-5,abcdefghij,xxx ,xyz @&t@
-6,abcdefghij,,xyz @&t@
-7,abcdefghij,xxx ,foobar @&t@
-8,abcdefghij,,foobar @&t@
-9,abcdefghij,xxx ,foobar @&t@
-.,,xxx ,xyz @&t@
+0,,xxx,foobar
+1,abcdefghij,xxx,foobar
+2,abcdefghij,,xyz
+3,abcdefghij,xxx,xyz
+4,abcdefghij,,xyz
+5,abcdefghij,xxx,xyz
+6,abcdefghij,,xyz
+7,abcdefghij,xxx,foobar
+8,abcdefghij,,foobar
+9,abcdefghij,xxx,foobar
+.,,xxx,xyz
])
AT_CLEANUP
])
AT_CHECK([pspp -O format=csv recode.sps], [1], [dnl
-"error: Cannot recode because the variable x would require a width of 5 bytes or greater, but it has a width of only 1 bytes."
+recode.sps:9: error: RECODE: At least one target variable is too narrow for the output values.
+
+"recode.sps:9.19-9.25: note: RECODE: This recoding output value has width 5.
+ 9 | recode x y (""a"" = ""first"") .
+ | ^~~~~~~"
+
+"recode.sps:9.8-9.10: note: RECODE: Target variable x only has width 1.
+ 9 | recode x y (""a"" = ""first"") .
+ | ^~~"
Table: Data List
x,y,z
-a,a ,2.00
-a,two ,2.00
-b,three ,2.00
-c,b ,2.00
+a,a,2.00
+a,two,2.00
+b,three,2.00
+c,b,2.00
])
AT_CLEANUP
+
+
+
+AT_SETUP([RECODE crash on invalid dest variable])
+
+AT_DATA([recode.sps],[dnl
+DATA LIST LIST NOTABLE/x (f1) s (a4) t (a10).
+MISSING VALUES x(9)/s('xxx').
+BEGIN DATA.
+0, '', ''
+1, a, a
+2, ab, ab
+3, abc, abc
+END DATA.
+
+RECODE x (1=9) INTO ".
+EXECUTE.
+dnl "
+])
+
+AT_CHECK([pspp -O format=csv recode.sps], [1], [ignore])
+
+AT_CLEANUP
+
+
+AT_SETUP([RECODE syntax errors])
+AT_DATA([recode.sps], [dnl
+DATA LIST LIST NOTABLE/n1 to n4 (F8.0) s1 (A1) s2 (A2) s3 (A3) s4 (A4).
+RECODE **.
+RECODE n1 **.
+RECODE n1(**).
+RECODE s1(**).
+RECODE s1('x' THRU 'y').
+RECODE n1(1=**).
+RECODE n1(CONVERT).
+RECODE n1(1=2)(1='x').
+RECODE n1(1='x')(1=2).
+RECODE s1(CONVERT)('1'='1').
+RECODE n1(1=2 **).
+RECODE n1(CONVERT).
+RECODE s1(CONVERT) INTO n1 n2.
+RECODE n1(1='1') INTO xyzzy.
+RECODE n1(1='1').
+RECODE s1('1'=1).
+RECODE n1(1='1') INTO n2.
+RECODE s1(CONVERT) INTO s2.
+RECODE n1 TO n4(1='123456') INTO s1 TO s4.
+])
+AT_CHECK([pspp -O format=csv recode.sps], [1], [dnl
+"recode.sps:2.8-2.9: error: RECODE: Syntax error expecting variable name.
+ 2 | RECODE **.
+ | ^~"
+
+"recode.sps:3.11-3.12: error: RECODE: Syntax error expecting `('.
+ 3 | RECODE n1 **.
+ | ^~"
+
+"recode.sps:4.11-4.12: error: RECODE: Syntax error expecting number.
+ 4 | RECODE n1(**).
+ | ^~"
+
+"recode.sps:5.11-5.12: error: RECODE: Syntax error expecting string.
+ 5 | RECODE s1(**).
+ | ^~"
+
+"recode.sps:6.15-6.18: error: RECODE: THRU is not allowed with string variables.
+ 6 | RECODE s1('x' THRU 'y').
+ | ^~~~"
+
+"recode.sps:7.13-7.14: error: RECODE: Syntax error expecting output value.
+ 7 | RECODE n1(1=**).
+ | ^~"
+
+"recode.sps:8.11-8.17: error: RECODE: CONVERT requires string input values.
+ 8 | RECODE n1(CONVERT).
+ | ^~~~~~~"
+
+recode.sps:9: error: RECODE: Output values must be all numeric or all string.
+
+"recode.sps:9.13: note: RECODE: This output value is numeric.
+ 9 | RECODE n1(1=2)(1='x').
+ | ^"
+
+"recode.sps:9.18-9.20: note: RECODE: This output value is string.
+ 9 | RECODE n1(1=2)(1='x').
+ | ^~~"
+
+recode.sps:10: error: RECODE: Output values must be all numeric or all string.
+
+"recode.sps:10.20: note: RECODE: This output value is numeric.
+ 10 | RECODE n1(1='x')(1=2).
+ | ^"
+
+"recode.sps:10.13-10.15: note: RECODE: This output value is string.
+ 10 | RECODE n1(1='x')(1=2).
+ | ^~~"
+
+recode.sps:11: error: RECODE: Output values must be all numeric or all string.
+
+"recode.sps:11.11-11.17: note: RECODE: This output value is numeric.
+ 11 | RECODE s1(CONVERT)('1'='1').
+ | ^~~~~~~"
+
+"recode.sps:11.24-11.26: note: RECODE: This output value is string.
+ 11 | RECODE s1(CONVERT)('1'='1').
+ | ^~~"
+
+"recode.sps:12.15-12.16: error: RECODE: Syntax error expecting `)'.
+ 12 | RECODE n1(1=2 **).
+ | ^~"
+
+"recode.sps:13.11-13.17: error: RECODE: CONVERT requires string input values.
+ 13 | RECODE n1(CONVERT).
+ | ^~~~~~~"
+
+recode.sps:14: error: RECODE: Source and target variable counts must match.
+
+"recode.sps:14.8-14.9: note: RECODE: There is 1 source variable.
+ 14 | RECODE s1(CONVERT) INTO n1 n2.
+ | ^~"
+
+"recode.sps:14.25-14.29: note: RECODE: There are 2 target variables.
+ 14 | RECODE s1(CONVERT) INTO n1 n2.
+ | ^~~~~"
+
+recode.sps:15: error: RECODE: All string variables specified on INTO must already exist. (Use the STRING command to create a string variable.)
+
+"recode.sps:15.23-15.27: note: RECODE: There is no variable named xyzzy.
+ 15 | RECODE n1(1='1') INTO xyzzy.
+ | ^~~~~"
+
+"recode.sps:16.10-16.16: error: RECODE: INTO is required with numeric input values and string output values.
+ 16 | RECODE n1(1='1').
+ | ^~~~~~~"
+
+"recode.sps:17.10-17.16: error: RECODE: INTO is required with string input values and numeric output values.
+ 17 | RECODE s1('1'=1).
+ | ^~~~~~~"
+
+"recode.sps:18.23-18.24: error: RECODE: Type mismatch: cannot store string data in numeric variable n2.
+ 18 | RECODE n1(1='1') INTO n2.
+ | ^~"
+
+"recode.sps:19.25-19.26: error: RECODE: Type mismatch: cannot store numeric data in string variable s2.
+ 19 | RECODE s1(CONVERT) INTO s2.
+ | ^~"
+
+recode.sps:20: error: RECODE: At least one target variable is too narrow for the output values.
+
+"recode.sps:20.19-20.26: note: RECODE: This recoding output value has width 6.
+ 20 | RECODE n1 TO n4(1='123456') INTO s1 TO s4.
+ | ^~~~~~~~"
+
+"recode.sps:20.29-20.41: note: RECODE: Target variable s1 only has width 1.
+ 20 | RECODE n1 TO n4(1='123456') INTO s1 TO s4.
+ | ^~~~~~~~~~~~~"
+])
+AT_CLEANUP
\ No newline at end of file