sys-file-reader: Fully verify multiple response set names.
[pspp] / tests / data / sys-file-reader.at
index e181b26eb580d691ef3d54b99d5b8b1b9f4f6511..8ca6d74494e846d1268b5afa5f7429c072590ac3 100644 (file)
@@ -1,3 +1,19 @@
+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([system file reader - positive])
 
 AT_SETUP([variable labels and missing values])
@@ -130,52 +146,52 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
+  AT_CHECK([cat pspp.csv], [0], [dnl
 File label: PSPP synthetic test file: ôõöø
 
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Label: Numeric variable 2's label (ùúû),,2
-,Format: F8.0,,
-num3,Format: F8.0,,3
-,Missing Values: 1,,
-num4,Label: Another numeric variable label,,4
-,Format: F8.0,,
-,Missing Values: 1,,
-num5,Format: F8.0,,5
-,Missing Values: 1; 2,,
-num6,Format: F8.0,,6
-,Missing Values: 1; 2; 3,,
-num7,Format: F8.0,,7
-,Missing Values: 1 THRU 3,,
-num8,Format: F8.0,,8
-,Missing Values: 1 THRU 3; 5,,
-num9,Format: F8.0,,9
-,Missing Values: 1 THRU HIGHEST; -5,,
-numàèìñò,Format: F8.0,,10
-,Missing Values: LOWEST THRU 1; 5,,
-str1,Format: A4,,11
-str2,Label: String variable 2's label,,12
-,Format: A4,,
-str3,Format: A4,,13
-,"Missing Values: ""MISS""",,
-str4,Label: Another string variable label,,14
-,Format: A4,,
-,"Missing Values: ""OTHR""",,
-str5,Format: A4,,15
-,"Missing Values: ""MISS""; ""OTHR""",,
-str6,Format: A4,,16
-,"Missing Values: ""MISS""; ""OTHR""; ""MORE""",,
-str7,Format: A11,,17
-,"Missing Values: ""first8by""",,
-str8,Format: A9,,18
-,"Missing Values: ""abcdefgh""",,
-str9,Format: A10,,19
-,"Missing Values: ""abcdefgh""; ""01234567""",,
-str10,Format: A11,,20
-,"Missing Values: ""abcdefgh""; ""01234567""; ""0       """,,
-str11,Label: 25-byte string,,21
-,Format: A25,,
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,"Label: Numeric variable 2's label (ùúû)
+Format: F8.0",2
+num3,"Format: F8.0
+Missing Values: 1",3
+num4,"Label: Another numeric variable label
+Format: F8.0
+Missing Values: 1",4
+num5,"Format: F8.0
+Missing Values: 1; 2",5
+num6,"Format: F8.0
+Missing Values: 1; 2; 3",6
+num7,"Format: F8.0
+Missing Values: 1 THRU 3",7
+num8,"Format: F8.0
+Missing Values: 1 THRU 3; 5",8
+num9,"Format: F8.0
+Missing Values: 1 THRU HIGHEST; -5",9
+numàèìñò,"Format: F8.0
+Missing Values: LOWEST THRU 1; 5",10
+str1,Format: A4,11
+str2,"Label: String variable 2's label
+Format: A4",12
+str3,"Format: A4
+Missing Values: ""MISS""",13
+str4,"Label: Another string variable label
+Format: A4
+Missing Values: ""OTHR""",14
+str5,"Format: A4
+Missing Values: ""MISS""; ""OTHR""",15
+str6,"Format: A4
+Missing Values: ""MISS""; ""OTHR""; ""MORE""",16
+str7,"Format: A11
+Missing Values: ""first8by""",17
+str8,"Format: A9
+Missing Values: ""abcdefgh""",18
+str9,"Format: A10
+Missing Values: ""abcdefgh""; ""01234567""",19
+str10,"Format: A11
+Missing Values: ""abcdefgh""; ""01234567""; ""0       """,20
+str11,"Label: 25-byte string
+Format: A25",21
 
 Table: Data List
 num1,num2,num3,num4,num5,num6,num7,num8,num9,numàèìñò,str1,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11
@@ -205,6 +221,9 @@ dnl Numeric variable, variable label.
 2; 0; 1; 0; 0x050800 *2; s8 "NUM2";
 26; "Numeric variable 2's label"; i8 0 *2;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -219,11 +238,11 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Label: Numeric variable 2's label,,2
-,Format: F8.0,,
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,"Label: Numeric variable 2's label
+Format: F8.0",2
 
 Table: Data List
 num1,num2
@@ -256,6 +275,9 @@ dnl Numeric variable, variable label.
 dnl Machine integer info record (SPSS 13).
 7; 3; 4; 8; 13; 2; 3; -1; 1; 1; ENDIAN; 1252;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -270,11 +292,11 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Label: Numeric variable 2's label,,2
-,Format: F8.0,,
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,"Label: Numeric variable 2's label
+Format: F8.0",2
 
 Table: Data List
 num1,num2
@@ -403,61 +425,95 @@ GET FILE='sys-file.sav'.
 DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-,1,один (in Russian),
-num2,Format: F8.0,,2
-,1,one,
-,2,two,
-num3,Format: F8.0,,3
-,3,three,
-,4,four,
-num4,Format: F8.0,,4
-,5,five,
-,7,seven,
-,8,eight,
-,9,nine,
-num5,Format: F8.0,,5
-,6,six,
-,7,seven,
-,8,eight,
-,10,ten,
-str1,Format: A1,,6
-,a,value label for `a',
-str2,Format: A2,,7
-,bc,value label for `bc',
-,de,value label for `de',
-str3,Format: A3,,8
-,fgh,value label for `fgh',
-,ijk,value label for `ijk',
-str4,Format: A4,,9
-,BCDE,value label for `BCDE',
-,lmno,value label for `lmno',
-,tuvw,value label for `tuvw',
-,xyzA,value label for `xyzA',
-str5,Format: A4,,10
-,FGHI,value label for `FGHI',
-,pqrs,value label for `pqrs',
-,tuvw,value label for `tuvw',
-,xyzA,value label for `xyzA',
-str6,Format: A6,,11
-,JKLMNO,value label for `JKLMNO',
-str7,Format: A7,,12
-,JKLMNOP,value label for `JKLMNOP',
-str8,Format: A8,,13
-,JKLMNOPQ,value label for `JKLMNOPQ',
-str9ж,Format: A9,,14
-,RSTUVWXYZ,value label for `RSTUVWXYZ',
-str12,Format: A12,,15
-,0123456789ab,value label for `0123456789ab',
-,cdefghijklmn,value label for `cdefghijklmn',
-str16,Format: A16,,16
-,EFGHIJKLMNOPQRST,value label for `EFGHIJKLMNOPQRST',
-,UVWXYZ0123456789,value label for `UVWXYZ0123456789' with Cyrillic letters: `фхц',
-,opqrstuvwxyzABCD,value label for `opqrstuvwxyzABCD',
-str17,Format: A17,,17
-,abcdefghijklmnopq,value label for `abcdefghijklmnopq',
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,"Format: F8.0
+
+Value,Label
+1,один (in Russian)",1
+num2,"Format: F8.0
+
+Value,Label
+1,one
+2,two",2
+num3,"Format: F8.0
+
+Value,Label
+3,three
+4,four",3
+num4,"Format: F8.0
+
+Value,Label
+5,five
+7,seven
+8,eight
+9,nine",4
+num5,"Format: F8.0
+
+Value,Label
+6,six
+7,seven
+8,eight
+10,ten",5
+str1,"Format: A1
+
+Value,Label
+a,value label for `a'",6
+str2,"Format: A2
+
+Value,Label
+bc,value label for `bc'
+de,value label for `de'",7
+str3,"Format: A3
+
+Value,Label
+fgh,value label for `fgh'
+ijk,value label for `ijk'",8
+str4,"Format: A4
+
+Value,Label
+BCDE,value label for `BCDE'
+lmno,value label for `lmno'
+tuvw,value label for `tuvw'
+xyzA,value label for `xyzA'",9
+str5,"Format: A4
+
+Value,Label
+FGHI,value label for `FGHI'
+pqrs,value label for `pqrs'
+tuvw,value label for `tuvw'
+xyzA,value label for `xyzA'",10
+str6,"Format: A6
+
+Value,Label
+JKLMNO,value label for `JKLMNO'",11
+str7,"Format: A7
+
+Value,Label
+JKLMNOP,value label for `JKLMNOP'",12
+str8,"Format: A8
+
+Value,Label
+JKLMNOPQ,value label for `JKLMNOPQ'",13
+str9ж,"Format: A9
+
+Value,Label
+RSTUVWXYZ,value label for `RSTUVWXYZ'",14
+str12,"Format: A12
+
+Value,Label
+0123456789ab,value label for `0123456789ab'
+cdefghijklmn,value label for `cdefghijklmn'",15
+str16,"Format: A16
+
+Value,Label
+EFGHIJKLMNOPQRST,value label for `EFGHIJKLMNOPQRST'
+UVWXYZ0123456789,value label for `UVWXYZ0123456789' with Cyrillic letters: `фхц'
+opqrstuvwxyzABCD,value label for `opqrstuvwxyzABCD'",16
+str17,"Format: A17
+
+Value,Label
+abcdefghijklmnopq,value label for `abcdefghijklmnopq'",17
 ])
 done
 AT_CLEANUP
@@ -528,6 +584,53 @@ num1
 done
 AT_CLEANUP
 
+AT_SETUP([empty document record])
+AT_KEYWORDS([sack synthetic system file positive])
+AT_DATA([sys-file.sack], [dnl
+dnl File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; dnl Layout code
+1; dnl Nominal case size
+0; dnl Not compressed
+0; dnl Not weighted 
+1; dnl 1 case.
+100.0; dnl Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+dnl Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+dnl Machine integer info record.
+7; 3; 4; 8; 1; 2; 3; -1; 1; 1; ENDIAN; 1252;
+
+dnl Document record.
+6; 0;
+
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+dnl Dictionary termination record.
+999; 0;
+
+dnl Data.
+1.0;
+])
+for variant in be le; do
+  AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
+  AT_DATA([sys-file.sps], [dnl
+GET FILE='sys-file.sav'.
+LIST.
+])
+  AT_CHECK([pspp -o pspp.csv sys-file.sps])
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Table: Data List
+num1
+1
+])
+done
+AT_CLEANUP
+
 AT_SETUP([multiple response sets])
 AT_KEYWORDS([sack synthetic system file positive])
 AT_DATA([sys-file.sack], [dnl
@@ -668,6 +771,9 @@ dnl Numeric variables.
 dnl Extra product info.
 7; 10; 1; COUNT ("Extra product info"; i8 13; "another line"; i8 13; "blah");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -740,6 +846,9 @@ dnl Variable display parameters
 0; 1;
 0; 2;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -751,55 +860,43 @@ DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0], [dnl
-Variable,Description,,Position
-a,Format: F8.0,,1
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-b,Format: F8.0,,2
-,Measure: Ordinal,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-c,Format: F8.0,,3
-,Measure: Scale,,
-,Display Alignment: Left,,
-,Display Width: 8,,
-d,Format: F8.0,,4
-,Measure: Nominal,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-h,Format: A3,,5
-,Measure: Ordinal,,
-,Display Alignment: Right,,
-,Display Width: 3,,
-i,Format: A3,,6
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 3,,
-j,Format: A3,,7
-,Measure: Nominal,,
-,Display Alignment: Center,,
-,Display Width: 3,,
-k,Format: A3,,8
-,Measure: Ordinal,,
-,Display Alignment: Center,,
-,Display Width: 3,,
-l,Format: A9,,9
-,Measure: Scale,,
-,Display Alignment: Center,,
-,Display Width: 9,,
-m,Format: A10,,10
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 10,,
-n,Format: A17,,11
-,Measure: Nominal,,
-,Display Alignment: Right,,
-,Display Width: 17,,
-o,Format: A25,,12
-,Measure: Nominal,,
-,Display Alignment: Center,,
-,Display Width: 25,,
+Variable,Description,Position
+a,"Format: F8.0
+Measure: Nominal
+Display Alignment: Left",1
+b,"Format: F8.0
+Measure: Ordinal
+Display Alignment: Left",2
+c,"Format: F8.0
+Measure: Scale
+Display Alignment: Left",3
+d,"Format: F8.0
+Measure: Nominal
+Display Alignment: Right",4
+h,"Format: A3
+Measure: Ordinal
+Display Alignment: Right",5
+i,"Format: A3
+Measure: Scale
+Display Alignment: Right",6
+j,"Format: A3
+Measure: Nominal
+Display Alignment: Center",7
+k,"Format: A3
+Measure: Ordinal
+Display Alignment: Center",8
+l,"Format: A9
+Measure: Scale
+Display Alignment: Center",9
+m,"Format: A10
+Measure: Nominal
+Display Alignment: Left",10
+n,"Format: A17
+Measure: Nominal
+Display Alignment: Right",11
+o,"Format: A25
+Measure: Nominal
+Display Alignment: Center",12
 ])
 done
 AT_CLEANUP
@@ -855,6 +952,9 @@ dnl Variable display parameters
 0; 11; 1;
 0; 12; 2;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -866,55 +966,55 @@ DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0], [dnl
-Variable,Description,,Position
-a,Format: F8.0,,1
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 1,,
-b,Format: F8.0,,2
-,Measure: Ordinal,,
-,Display Alignment: Left,,
-,Display Width: 2,,
-c,Format: F8.0,,3
-,Measure: Scale,,
-,Display Alignment: Left,,
-,Display Width: 3,,
-d,Format: F8.0,,4
-,Measure: Nominal,,
-,Display Alignment: Right,,
-,Display Width: 4,,
-h,Format: A3,,5
-,Measure: Ordinal,,
-,Display Alignment: Right,,
-,Display Width: 5,,
-i,Format: A3,,6
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 6,,
-j,Format: A3,,7
-,Measure: Nominal,,
-,Display Alignment: Center,,
-,Display Width: 7,,
-k,Format: A3,,8
-,Measure: Ordinal,,
-,Display Alignment: Center,,
-,Display Width: 8,,
-l,Format: A9,,9
-,Measure: Scale,,
-,Display Alignment: Center,,
-,Display Width: 9,,
-m,Format: A10,,10
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 10,,
-n,Format: A17,,11
-,Measure: Nominal,,
-,Display Alignment: Right,,
-,Display Width: 11,,
-o,Format: A25,,12
-,Measure: Nominal,,
-,Display Alignment: Center,,
-,Display Width: 12,,
+Variable,Description,Position
+a,"Format: F8.0
+Measure: Nominal
+Display Alignment: Left
+Display Width: 1",1
+b,"Format: F8.0
+Measure: Ordinal
+Display Alignment: Left
+Display Width: 2",2
+c,"Format: F8.0
+Measure: Scale
+Display Alignment: Left
+Display Width: 3",3
+d,"Format: F8.0
+Measure: Nominal
+Display Alignment: Right
+Display Width: 4",4
+h,"Format: A3
+Measure: Ordinal
+Display Alignment: Right
+Display Width: 5",5
+i,"Format: A3
+Measure: Scale
+Display Alignment: Right
+Display Width: 6",6
+j,"Format: A3
+Measure: Nominal
+Display Alignment: Center
+Display Width: 7",7
+k,"Format: A3
+Measure: Ordinal
+Display Alignment: Center
+Display Width: 8",8
+l,"Format: A9
+Measure: Scale
+Display Alignment: Center
+Display Width: 9",9
+m,"Format: A10
+Measure: Nominal
+Display Alignment: Left
+Display Width: 10",10
+n,"Format: A17
+Measure: Nominal
+Display Alignment: Right
+Display Width: 11",11
+o,"Format: A25
+Measure: Nominal
+Display Alignment: Center
+Display Width: 12",12
 ])
 done
 AT_CLEANUP
@@ -972,15 +1072,15 @@ GET FILE='sys-file.sav'.
 DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-LongVariableName1,Format: F8.0,,1
-LongVariableName2,Format: F8.0,,2
-LongVariableName3,Format: F8.0,,3
-LongVariableName4,Format: F8.0,,4
-Coördinate_X,Format: F8.0,,5
-Coördinate_Y,Format: F8.0,,6
-Coördinate_Z,Format: F8.0,,7
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+LongVariableName1,Format: F8.0,1
+LongVariableName2,Format: F8.0,2
+LongVariableName3,Format: F8.0,3
+LongVariableName4,Format: F8.0,4
+Coördinate_X,Format: F8.0,5
+Coördinate_Y,Format: F8.0,6
+Coördinate_Z,Format: F8.0,7
 ])
 done
 AT_CLEANUP
@@ -1041,10 +1141,10 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-séq256,Format: A256,,1
-str600,Format: A600,,2
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+séq256,Format: A256,1
+str600,Format: A600,2
 
 Table: Data List
 séq256,str600
@@ -1059,7 +1159,7 @@ AT_DATA([sys-file.sack], [dnl
 dnl File header.
 "$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
 2; dnl Layout code
-2; dnl Nominal case size
+3; dnl Nominal case size
 0; dnl Not compressed
 0; dnl Not weighted 
 0; dnl 1 case.
@@ -1070,6 +1170,7 @@ i8 0 *3;
 dnl Variables.
 2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
 2; 0; 0; 0; 0x050800 *2; s8 "SECONDVA";
+2; 0; 0; 0; 0x050800 *2; s8 "THIRDVAR";
 
 dnl Machine integer info record.
 7; 3; 4; 8; 1; 2; 3; -1; 1; 1; ENDIAN; 1252;
@@ -1078,6 +1179,7 @@ dnl Long variable names.
 7; 13; 1; COUNT (
 "FIRSTVAR=FirstVariable"; i8 9;
 "SECONDVA=S"; i8 233; "condVariable"; i8 9;
+"THIRDVAR=ThirdVariable"; i8 9
 );
 
 dnl Data file attributes record.
@@ -1096,6 +1198,10 @@ dnl Variable attributes record.
   "xyzzy('quux'"; i8 10; ")";
 );
 
+dnl Another variable attributes record.
+dnl Only system files written by "Stata 14.1/-savespss- 1.77 by S.Radyakin"
+dnl include multiple variable attributes records.
+7; 18; 1; COUNT ("ThirdVariable:fizz('buzz'"; i8 10; ")";);
 
 dnl Character encoding record.
 7; 20; 1; 12; "windows-1252";
@@ -1111,14 +1217,16 @@ DISPLAY @ATTRIBUTES.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0],
-[[Variable,Description,
-FirstVariable,Custom attributes:,
-,$@Role,1
-,adèle[1],23
-,adèle[2],34
-,bert,123
-SécondVariable,Custom attributes:,
-,xyzzy,quux
+[[Variable,Description
+FirstVariable,"Attribute,Value
+$@Role,1
+adèle[1],23
+adèle[2],34
+bert,123"
+SécondVariable,"Attribute,Value
+xyzzy,quux"
+ThirdVariable,"Attribute,Value
+fizz,buzz"
 
 Table: Custom data file attributes.
 Attribute,Value
@@ -1132,17 +1240,25 @@ GET FILE='sys-file.sav'.
 DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0],
-[[Variable,Description,,Position
-FirstVariable,Format: F8.0,,1
-,Role: Output,,
-,Custom attributes:,,
-,adèle[1],23,
-,adèle[2],34,
-,bert,123,
-SécondVariable,Format: F8.0,,2
-,Custom attributes:,,
-,xyzzy,quux,
+  AT_CHECK([cat pspp.csv], [0],
+[[Variable,Description,Position
+FirstVariable,"Format: F8.0
+Role: Output
+
+Attribute,Value
+adèle[1],23
+adèle[2],34
+bert,123",1
+SécondVariable,"Format: F8.0
+Role: Input
+
+Attribute,Value
+xyzzy,quux",2
+ThirdVariable,"Format: F8.0
+Role: Input
+
+Attribute,Value
+fizz,buzz",3
 
 Table: Custom data file attributes.
 Attribute,Value
@@ -1206,22 +1322,24 @@ DISPLAY DICTIONARY.
   AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [dnl
 warning: `sys-file.sav': Invalid role for variable x.
 ])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
+  AT_CHECK([cat pspp.csv], [0], [dnl
 warning: `sys-file.sav': Invalid role for variable x.
 
-Variable,Description,,Position
-i,Format: F8.0,,1
-o,Format: F8.0,,2
-,Role: Output,,
-b,Format: F8.0,,3
-,Role: Both,,
-n,Format: F8.0,,4
-,Role: None,,
-p,Format: F8.0,,5
-,Role: Partition,,
-s,Format: F8.0,,6
-,Role: Split,,
-x,Format: F8.0,,7
+Variable,Description,Position
+i,"Format: F8.0
+Role: Input",1
+o,"Format: F8.0
+Role: Output",2
+b,"Format: F8.0
+Role: Both",3
+n,"Format: F8.0
+Role: None",4
+p,"Format: F8.0
+Role: Partition",5
+s,"Format: F8.0
+Role: Split",6
+x,"Format: F8.0
+Role: Input",7
 ])
 done
 AT_CLEANUP
@@ -1250,6 +1368,9 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -1268,13 +1389,13 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Format: F8.0,,2
-str4,Format: A4,,3
-str8,Format: A8,,4
-str15,Format: A15,,5
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,Format: F8.0,2
+str4,Format: A4,3
+str8,Format: A8,4
+str15,Format: A15,5
 
 Table: Data List
 num1,num2,str4,str8,str15
@@ -1309,6 +1430,9 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -1327,13 +1451,13 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps], [0])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Format: F8.0,,2
-str4,Format: A4,,3
-str8,Format: A8,,4
-str15,Format: A15,,5
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,Format: F8.0,2
+str4,Format: A4,3
+str8,Format: A8,4
+str15,Format: A15,5
 
 Table: Data List
 num1,num2,str4,str8,str15
@@ -1368,6 +1492,9 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -1388,15 +1515,15 @@ LIST.
   AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], 
     [warning: `sys-file.sav' near offset 0x54: Compression bias is not the usual value of 100, or system file uses unrecognized floating-point format.
 ])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
+  AT_CHECK([cat pspp.csv], [0], [dnl
 "warning: `sys-file.sav' near offset 0x54: Compression bias is not the usual value of 100, or system file uses unrecognized floating-point format."
 
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Format: F8.0,,2
-str4,Format: A4,,3
-str8,Format: A8,,4
-str15,Format: A15,,5
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,Format: F8.0,2
+str4,Format: A4,3
+str8,Format: A8,4
+str15,Format: A15,5
 
 Table: Data List
 num1,num2,str4,str8,str15
@@ -1431,12 +1558,15 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
 dnl ZLIB data header.
-i64 0x178;    # zheader_ofs
-i64 0x1e9;    # ztrailer_ofs
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
 i64 48;       # ztrailer_len
 
 dnl ZLIB data block.
@@ -1465,8 +1595,8 @@ i64 0;        # ztrailer_zero
 1;            # n_blocks
 
 dnl ZLIB block descriptor:
-i64 0x178;    # uncompressed_ofs
-i64 0x190;    # compressed_ofs
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
 88;           # uncompressed_size
 89;           # compressed_size
 EOF
@@ -1484,13 +1614,13 @@ DISPLAY DICTIONARY.
 LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([grep -v Measure pspp.csv | grep -v Display], [0], [dnl
-Variable,Description,,Position
-num1,Format: F8.0,,1
-num2,Format: F8.0,,2
-str4,Format: A4,,3
-str8,Format: A8,,4
-str15,Format: A15,,5
+  AT_CHECK([cat pspp.csv], [0], [dnl
+Variable,Description,Position
+num1,Format: F8.0,1
+num2,Format: F8.0,2
+str4,Format: A4,3
+str8,Format: A8,4
+str15,Format: A15,5
 
 Table: Data List
 num1,num2,str4,str8,str15
@@ -1503,6 +1633,79 @@ AT_CLEANUP
 \f
 AT_BANNER([system file reader - negative])
 
+AT_SETUP([no variables])
+AT_KEYWORDS([sack synthetic system file negative])
+AT_DATA([sys-file.sack], [dnl
+dnl File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; dnl Layout code
+0; dnl Nominal case size (empty)
+0; dnl Not compressed
+0; dnl Not weighted
+0; dnl 0 cases.
+100.0; dnl Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+dnl Dictionary termination record.
+999; 0;
+])
+for variant in be le; do
+  AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
+  AT_DATA([sys-file.sps], [dnl
+GET FILE='sys-file.sav'.
+])
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1], [dnl
+sys-file.sps:1: error: GET: `sys-file.sav': Data file dictionary has no variables.
+])
+
+  dnl At one point pspp-convert would hang forever if there were no variables,
+  dnl so check against regression.
+  AT_CHECK([pspp-convert sys-file.sav sys-file.txt])
+  AT_CHECK([cat sys-file.txt], [0], [
+])
+done
+AT_CLEANUP
+
+AT_SETUP([unspecified character encoding])
+AT_KEYWORDS([sack synthetic system file positive])
+AT_DATA([sys-file.sack], [dnl
+dnl File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; dnl Layout code
+4; dnl Nominal case size
+0; dnl Not compressed
+0; dnl Not weighted
+0; dnl No cases.
+100.0; dnl Bias.
+"01 Jan 11"; "20:53:52";
+"PSPP synthetic test file: "; i8 244; i8 245; i8 246; i8 248; s34 "";
+i8 0 *3;
+
+dnl Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "A";
+2; 0; 0; 0; 0x050800 *2; s8 "B";
+2; 0; 0; 0; 0x050800 *2; s8 "C";
+2; 0; 0; 0; 0x050800 *2; s8 "D";
+
+dnl Dictionary termination record.
+999; 0;
+])
+for variant in be le; do
+  AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
+  AT_DATA([sys-file.sps], [dnl
+GET 'sys-file.sav'.
+])
+  AT_CHECK([pspp -O format=csv sys-file.sps], [0], [stdout])
+  AT_CHECK([sed 's/default encoding.*For/default encoding.  For/' stdout], [0], [dnl
+"warning: `sys-file.sav': This system file does not indicate its own character encoding.  Using default encoding.  For best results, specify an encoding explicitly.  Use SYSFILE INFO with ENCODING=""DETECT"" to analyze the possible encodings."
+])
+done
+AT_CLEANUP
+
 AT_SETUP([misplaced type 4 record])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
@@ -1559,6 +1762,9 @@ dnl File header.
 dnl Numeric variable.
 2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1582,6 +1788,9 @@ dnl File header.
 dnl Numeric variable.
 2; 0; 0; 0; 0x050800 *2; s8 >>"$UM1"<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1605,6 +1814,9 @@ dnl File header.
 dnl Numeric variable.
 2; 0; 0; 0; 0x050800 *2; s8 >>"TO"<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1628,6 +1840,9 @@ dnl File header.
 dnl String variable with invalid width 256.
 2; 256; 0; 0; 0x050800 *2; s8 "VAR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1654,6 +1869,9 @@ dnl Numeric variables.
 2; 0; 0; 0; 0x050800 *2; s8 "VAR1";
 2; 0; 0; 0; 0x050800 *2; s8 "VAR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1665,15 +1883,9 @@ DISPLAY DICTIONARY.
   AT_CHECK([pspp -O format=csv sys-file.sps], [0],
    [warning: `sys-file.sav' near offset 0xd4: Renaming variable with duplicate name `VAR1' to `VAR001'.
 
-Variable,Description,,Position
-var1,Format: F8.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-var001,Format: F8.0,,2
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
+Variable,Description,Position
+var1,Format: F8.0,1
+var001,Format: F8.0,2
 ])
 done
 AT_CLEANUP
@@ -1688,6 +1900,9 @@ dnl File header.
 dnl Numeric variable.
 2; 0; >>2<<; 0; 0x050800 *2; s8 "VAR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1711,6 +1926,9 @@ dnl File header.
 dnl Numeric variable.
 2; 0; 0; >>-1<<; 0x050800 *2; s8 "VAR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1734,6 +1952,9 @@ dnl File header.
 dnl String variable.
 2; 8; 0; >>4<<; 0x010800 *2; s8 "VAR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1758,6 +1979,9 @@ dnl String variable.
 2; 10; 0; 0; 0x010a00 *2; s8 "VAR1";
 >>2; 0; 0; 0; 0x050800 *2; s8 "VAR2";<<
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1792,6 +2016,9 @@ dnl String variable, numeric formats.
 dnl String variable, wrong width formats.
 2; 4; 0; 0; >>0x010800<<; >>0x020400<<; s8 "STR2";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1896,24 +2123,12 @@ warning: `sys-file.sav' near offset 0x257: Ignoring long string missing value re
 
 "warning: `sys-file.sav' near offset 0x270: Ignoring long string missing value 0 for variable str3, with width 11, that has bad value width 12."
 
-Variable,Description,,Position
-num1,Format: F8.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-str1,Format: A9,,2
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 9,,
-str2,Format: A10,,3
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 10,,
-,"Missing Values: ""abcdefgh""; ""ijklmnop""; ""qrstuvwx""",,
-str3,Format: A11,,4
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 11,,
+Variable,Description,Position
+num1,Format: F8.0,1
+str1,Format: A9,2
+str2,"Format: A10
+Missing Values: ""abcdefgh""; ""ijklmnop""; ""qrstuvwx""",3
+str3,Format: A11,4
 ])
 done
 AT_CLEANUP
@@ -1931,6 +2146,9 @@ dnl Numeric variable.
 dnl String variable.
 2; 4; 0; 0; 0x010400 *2; s8 "STR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1942,15 +2160,9 @@ DISPLAY DICTIONARY.
   AT_CHECK([pspp -O format=csv sys-file.sps], [0],
    [warning: `sys-file.sav': Ignoring string variable `STR1' set as weighting variable.
 
-Variable,Description,,Position
-num1,Format: F8.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
-str1,Format: A4,,2
-,Measure: Nominal,,
-,Display Alignment: Left,,
-,Display Width: 4,,
+Variable,Description,Position
+num1,Format: F8.0,1
+str1,Format: A4,2
 ])
 done
 AT_CLEANUP
@@ -1968,6 +2180,9 @@ dnl Numeric variable.
 dnl String variable.
 2; 4; 0; 0; 0x010400 *2; s8 "STR1";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -1995,6 +2210,9 @@ dnl Long string variable.
 2; 9; 0; 0; 0x010900 *2; s8 "STR1";
 (2; -1; 0; 0; 0; 0; s8 "");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2024,6 +2242,9 @@ dnl Two document records.
 dnl Dictionary termination record.
 999; 0;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Data.
 1.0;
 ])
@@ -2039,36 +2260,6 @@ done
 AT_CLEANUP
 
 
-AT_SETUP([empty document record])
-AT_KEYWORDS([sack synthetic system file negative])
-AT_DATA([sys-file.sack], [dnl
-dnl File header.
-"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
-2; 2; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
-
-dnl Numeric variable, no label or missing values.
-2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
-
-dnl Empty document record.
-6; >>0<<;
-
-dnl Dictionary termination record.
-999; 0;
-
-dnl Data.
-1.0;
-])
-for variant in be le; do
-  AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
-  AT_DATA([sys-file.sps], [dnl
-GET FILE='sys-file.sav'.
-])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], [dnl
-error: `sys-file.sav' near offset 0xd4: Number of document lines (0) must be greater than 0 and less than 26843545.
-])
-done
-AT_CLEANUP
-
 AT_SETUP([extension record too large])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
@@ -2106,6 +2297,9 @@ dnl Numeric variable, no label or missing values.
 dnl Unknown extension record type.
 7; 30; 1; 1; i8 0;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2114,8 +2308,8 @@ for variant in be le; do
   AT_DATA([sys-file.sps], [dnl
 GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [0], [dnl
-"warning: `sys-file.sav' near offset 0xd8: Unrecognized record type 7, subtype 30.  Please send a copy of this file, and the syntax which created it to bug-gnu-pspp@gnu.org."
+  AT_CHECK_UNQUOTED([pspp -O format=csv sys-file.sps], [0], [dnl
+"warning: \`sys-file.sav' near offset 0xd8: Unrecognized record type 7, subtype 30.  For help, please send this file to ${PACKAGE_BUGREPORT} and mention that you were using ${PACKAGE_STRING}."
 ])
 done
 AT_CLEANUP
@@ -2133,6 +2327,9 @@ dnl Numeric variable, no label or missing values.
 dnl Machine integer info record.
 7; 3; 4; >>9<<; 1; 2; 3; -1; 1; 1; ENDIAN; 1252; >>1234<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2160,6 +2357,9 @@ dnl Numeric variable, no label or missing values.
 dnl Machine integer info record.
 7; 3; 4; 8; 1; 2; 3; -1; >>2<<; 1; ENDIAN; 1252;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2187,6 +2387,9 @@ dnl Numeric variable, no label or missing values.
 dnl Machine integer info record.
 7; 3; 4; 8; 1; 2; 3; -1; 1; 1; >>3<<; 1252;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2200,11 +2403,8 @@ DISPLAY DICTIONARY.
   AT_CHECK_UNQUOTED([pspp -O format=csv sys-file.sps], [0], [dnl
 warning: \`sys-file.sav' near offset 0xd8: Integer format indicated by system file (3) differs from expected ($[2]).
 
-Variable,Description,,Position
-num1,Format: F8.0,,1
-,Measure: Scale,,
-,Display Alignment: Right,,
-,Display Width: 8,,
+Variable,Description,Position
+num1,Format: F8.0,1
 ])
 done
 AT_CLEANUP
@@ -2223,6 +2423,9 @@ dnl Numeric variable, no label or missing values.
 dnl Machine floating-point info record.
 7; 4; 8; >>4<<; SYSMIS; HIGHEST; LOWEST; 0.0;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2250,6 +2453,9 @@ dnl Numeric variable, no label or missing values.
 dnl Machine floating-point info record.
 7; 4; 8; 3; >>0.0<<; >>1.0<<; >>2.0<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2333,9 +2539,9 @@ for variant in be le; do
 MRSETS /DISPLAY NAME=ALL.
 ])
   AT_CHECK([pspp -O format=csv sys-file.sps], [0], [dnl
-warning: `sys-file.sav': Multiple response set name `b' does not begin with `$'.
+warning: `sys-file.sav': Invalid multiple response set name `b'.
 
-warning: `sys-file.sav': Multiple response set name `e' does not begin with `$'.
+warning: `sys-file.sav': Invalid multiple response set name `e'.
 
 Table: Multiple Response Sets
 Name,Variables,Details
@@ -2380,6 +2586,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=Cx");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2405,6 +2614,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=Ex");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2430,6 +2642,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=E 2");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2457,6 +2672,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2482,6 +2700,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=Dx");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2507,6 +2728,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=D1x");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2532,6 +2756,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=D4 abc");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2557,6 +2784,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=D3 abcx");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2582,6 +2812,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=C 0  NUM1");
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2609,6 +2842,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=C 0  NUM1 NUM1"; i8 10);
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2637,6 +2873,9 @@ dnl Variables.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=C 0  NUM1 STR1"; i8 10);
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2664,6 +2903,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=C 0  NUM1"; i8 10);
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2689,6 +2931,9 @@ dnl Numeric variable, no label or missing values.
 dnl Multiple response sets.
 7; 7; 1; COUNT("$a=C 0  NUM1"; i8 10; "$b=C 0  "; i8 10);
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 999; 0;
 ])
 for variant in be le; do
@@ -2716,6 +2961,9 @@ dnl Numeric variable, no label or missing values.
 dnl Display parameters record.
 7; 11; >>8<<; 2; 1.0; 1.0;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2742,6 +2990,9 @@ dnl Numeric variable, no label or missing values.
 dnl Display parameters record.
 7; 11; 4; >>4<<; 1; 1; 2; 2;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2768,6 +3019,9 @@ dnl Numeric variable, no label or missing values.
 dnl Display parameters record.
 7; 11; 4; 2; >>4<<; 0;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2794,6 +3048,9 @@ dnl Numeric variable, no label or missing values.
 dnl Display parameters record.
 7; 11; 4; 2; 1; >>-1<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -2820,6 +3077,9 @@ dnl Numeric variables.
 dnl Long variable names.
 7; 13; 1; COUNT (>>"xyzzy"<<);
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -2850,10 +3110,15 @@ dnl Numeric variables.
 dnl Long variable names.
 7; 13; 1; COUNT (
 "LONGVARI=_Invalid"; i8 9;
+"LONGVARI=$Invalid"; i8 9;
+"LONGVARI=#Invalid"; i8 9;
 "LONGVA_A=LongVariableName"; i8 9;
 "LONGVA_B=LONGVARIABLENAME"; i8 9;
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -2865,6 +3130,10 @@ GET FILE='sys-file.sav'.
   AT_CHECK([pspp -O format=csv sys-file.sps], [0], [dnl
 warning: `sys-file.sav' near offset 0x138: Long variable mapping from LONGVARI to invalid variable name `_Invalid'.
 
+warning: `sys-file.sav' near offset 0x138: Long variable mapping from LONGVARI to invalid variable name `$Invalid'.
+
+warning: `sys-file.sav' near offset 0x138: Long variable mapping from LONGVARI to invalid variable name `#Invalid'.
+
 warning: `sys-file.sav' near offset 0x138: Duplicate long variable name `LONGVARIABLENAME'.
 ])
 done
@@ -2887,6 +3156,9 @@ dnl Very long string map.
 "NUM1=00256"; i8 0; i8 9;
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -2923,6 +3195,9 @@ dnl Very long string map.
 "STR1=00256"; i8 0; i8 9;
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -2938,9 +3213,6 @@ done
 AT_CLEANUP
 
 AT_SETUP([too many value labels])
-dnl Skip the test if multiplying a small number by INT32_MAX would not
-dnl cause an overflow in size_t.
-AT_SKIP_IF([test $SIZEOF_SIZE_T -gt 4])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
 dnl File header.
@@ -2975,6 +3247,9 @@ dnl Numeric variable.
 dnl Value label with missing type 4 record.
 3; 1; 1.0; i8 3; s7 "one";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 >>999; 0<<;
 ])
@@ -3027,6 +3302,9 @@ dnl Long string variable.
 dnl Value label that names long string variable.
 3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 1; >>1<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -3055,6 +3333,9 @@ dnl Variables.
 dnl Value label that names numeric and string variables.
 3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>1; 2<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -3084,6 +3365,9 @@ dnl Duplicate value labels.
 3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>1; 1<<;
 3; 1; 1.0; i8 3; s7 "one"; 4; 2; >>2; 2<<;
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl End of dictionary.
 999; 0;
 ])
@@ -3121,6 +3405,9 @@ dnl Variable attributes record.
   "fred('23'"; i8 10
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -3159,6 +3446,9 @@ dnl Variable attributes record.
   "fred(23"; i8 10; ")"
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -3210,6 +3500,9 @@ COUNT("abcdefghijklmn"); COUNT("value label for `abcdefghijklmn'");
 >>COUNT("abcdefghijklmn"); COUNT("another value label for `abcdefghijklmn'")<<;
 );
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 ])
@@ -3242,6 +3535,9 @@ dnl Numeric variables.
 2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
 2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Data.
 999; 0;
 1.0; 2.0;
@@ -3279,6 +3575,9 @@ dnl Numeric variables.
 2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
 2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Data.
 999; 0;
 1.0; 2.0;
@@ -3290,7 +3589,7 @@ for variant in be le; do
 LIST.
 ])
   AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0x110: File ends in partial case.
+   [error: `sys-file.sav' near offset 0x12c: File ends in partial case.
 
 Table: Data List
 num1,num2
@@ -3310,6 +3609,9 @@ dnl Numeric variables.
 2; 14; 0; 0; 0x010e00 *2; s8 "STR14";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Data.
 999; 0;
 s14 "one data item";
@@ -3321,7 +3623,7 @@ for variant in be le; do
 LIST.
 ])
   AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0x10e: Unexpected end of file.
+   [error: `sys-file.sav' near offset 0x12a: Unexpected end of file.
 
 Table: Data List
 str14
@@ -3354,6 +3656,9 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
@@ -3366,7 +3671,7 @@ for variant in be le; do
 LIST.
 ])
   AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0x190: File ends in partial case.
+   [error: `sys-file.sav' near offset 0x1ac: File ends in partial case.
 
 Table: Data List
 num1,num2,str4,str8,str15
@@ -3382,7 +3687,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x178: Wrong ZLIB data header offset 0 (expected 0x178).
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x194: Wrong ZLIB data header offset 0 (expected 0x194).
 ])
 done
 AT_CLEANUP
@@ -3394,7 +3699,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x178: Impossible ZLIB trailer offset 0x0.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x194: Impossible ZLIB trailer offset 0x0.
 ])
 done
 AT_CLEANUP
@@ -3408,7 +3713,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x178: Invalid ZLIB trailer length 12.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x194: Invalid ZLIB trailer length 12.
 ])
 done
 AT_CLEANUP
@@ -3421,8 +3726,8 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [warning: `sys-file.sav' near offset 0x190: End of ZLIB trailer (0x231) is not file size (0x219).
-error: `sys-file.sav' near offset 0x201: 72-byte ZLIB trailer specifies 1 data blocks (expected 2).
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [warning: `sys-file.sav' near offset 0x1ac: End of ZLIB trailer (0x24d) is not file size (0x235).
+error: `sys-file.sav' near offset 0x21d: 72-byte ZLIB trailer specifies 1 data blocks (expected 2).
 ])
 done
 AT_CLEANUP
@@ -3434,7 +3739,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x1f1: ZLIB trailer bias (0) differs from file header bias (100.00).
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x20d: ZLIB trailer bias (0) differs from file header bias (100.00).
 ])
 done
 AT_CLEANUP
@@ -3446,7 +3751,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x1f9: ZLIB trailer "zero" field has nonzero value 100.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x215: ZLIB trailer "zero" field has nonzero value 100.
 ])
 done
 AT_CLEANUP
@@ -3458,7 +3763,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x1fd: ZLIB trailer specifies unexpected 4096-byte block size.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x219: ZLIB trailer specifies unexpected 4096-byte block size.
 ])
 done
 AT_CLEANUP
@@ -3470,7 +3775,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x201: 48-byte ZLIB trailer specifies 2 data blocks (expected 1).
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x21d: 48-byte ZLIB trailer specifies 2 data blocks (expected 1).
 ])
 done
 AT_CLEANUP
@@ -3482,7 +3787,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x201: ZLIB block descriptor 0 reported uncompressed data offset 0x177, when 0x178 was expected.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x21d: ZLIB block descriptor 0 reported uncompressed data offset 0x177, when 0x194 was expected.
 ])
 done
 AT_CLEANUP
@@ -3494,7 +3799,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x201: ZLIB block descriptor 0 reported compressed data offset 0x191, when 0x190 was expected.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x21d: ZLIB block descriptor 0 reported compressed data offset 0x191, when 0x1ac was expected.
 ])
 done
 AT_CLEANUP
@@ -3523,12 +3828,15 @@ dnl String variable.
 2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
 2; -1; 0; 0; 0; 0; s8 "";
 
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
 dnl Dictionary termination record.
 999; 0;
 
 dnl ZLIB data header.
-i64 0x178;    # zheader_ofs
-i64 0x190;    # ztrailer_ofs
+i64 0x194;    # zheader_ofs
+i64 0x1ac;    # ztrailer_ofs
 i64 72;       # ztrailer_len
 
 dnl This is where the ZLIB data blocks would go, but we don't need any to
@@ -3541,14 +3849,14 @@ i64 0;        # ztrailer_zero
 2;            # n_blocks
 
 dnl ZLIB block descriptor 1:
-i64 0x178;    # uncompressed_ofs
-i64 0x190;    # compressed_ofs
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
 0x100000;     # uncompressed_size
 0x12345;      # compressed_size
 
 dnl ZLIB block descriptor 2:
-i64 0x100178; # uncompressed_ofs
-i64 0x12405;  # compressed_ofs
+i64 0x100194; # uncompressed_ofs
+i64 0x12421;  # compressed_ofs
 0x100000;     # uncompressed_size
 0x12345;      # compressed_size
 ])
@@ -3556,8 +3864,8 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [warning: `sys-file.sav' near offset 0x1a8: ZLIB block descriptor 0 reported block size 0x100000, when 0x3ff000 was expected.
-error: `sys-file.sav' near offset 0x1c0: ZLIB block descriptor 1 reported compressed data offset 0x12405, when 0x124d5 was expected.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [warning: `sys-file.sav' near offset 0x1c4: ZLIB block descriptor 0 reported block size 0x100000, when 0x3ff000 was expected.
+error: `sys-file.sav' near offset 0x1dc: ZLIB block descriptor 1 reported compressed data offset 0x12421, when 0x124f1 was expected.
 ])
 done
 AT_CLEANUP
@@ -3569,7 +3877,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x201: ZLIB block descriptor 0 reported block size 0x400000, when at most 0x3ff000 was expected.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], [warning: `sys-file.sav' near offset 0x21d: ZLIB block descriptor 0 reported block size 0x400000, when at most 0x3ff000 was expected.
 ])
 done
 AT_CLEANUP
@@ -3582,7 +3890,7 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x201: ZLIB block descriptor 0 reports compressed size 100 and uncompressed size 50.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x21d: ZLIB block descriptor 0 reports compressed size 100 and uncompressed size 50.
 ])
 done
 AT_CLEANUP
@@ -3594,7 +3902,33 @@ for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x219: ZLIB trailer is at offset 0x1e9 but 0x1e8 would be expected from block descriptors.
+  AT_CHECK([pspp -o pspp.csv sys-file.sps], [1], [error: `sys-file.sav' near offset 0x235: ZLIB trailer is at offset 0x205 but 0x204 would be expected from block descriptors.
 ])
 done
 AT_CLEANUP
+
+# CVE-2017-10791.
+# See also https://bugzilla.redhat.com/show_bug.cgi?id=1467004.
+# See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=866890.
+# See also https://security-tracker.debian.org/tracker/CVE-2017-10791.
+# Found by team OWL337, using the collAFL fuzzer.
+AT_SETUP([integer overflows in long string missing values])
+AT_KEYWORDS([system file negative])
+cp $top_srcdir/tests/data/CVE-2017-10791.sav .
+AT_CHECK([pspp-convert -O csv -e ASCII CVE-2017-10791.sav -], [0], [], [dnl
+`CVE-2017-10791.sav' near offset 0x217: Extension record subtype 21 ends unexpectedly.
+])
+AT_CLEANUP
+
+# CVE-2017-10792.
+# See also https://bugzilla.redhat.com/show_bug.cgi?id=1467005.
+# See also https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=866890.
+# See also https://security-tracker.debian.org/tracker/CVE-2017-10792.
+# Reported by team OWL337, with fuzzer collAFL.
+AT_SETUP([null dereference skipping bad extension record 18])
+AT_KEYWORDS([system file negative])
+cp $top_srcdir/tests/data/CVE-2017-10792.sav .
+AT_CHECK([pspp-convert -O csv -e ASCII CVE-2017-10792.sav -], [0], [], [dnl
+`CVE-2017-10792.sav' near offset 0x1c0: Record type 7, subtype 18 has bad size 4 (expected 1).
+])
+AT_CLEANUP