Automatically infer variables' measurement level from format and data.
[pspp] / tests / data / sys-file-reader.at
index e9b262e86425d8a23ce7fd5629b5516b6d2d208c..f4466317637a5d2ef5871fce96561e7575d0e987 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])
@@ -131,51 +147,32 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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 (ùúû)
-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: File Label
+Label,PSPP synthetic test file: ôõöø
+
+Table: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
+num1,1,,Unknown,Input,8,Right,F8.0,F8.0,
+num2,2,Numeric variable 2's label (ùúû),Unknown,Input,8,Right,F8.0,F8.0,
+num3,3,,Unknown,Input,8,Right,F8.0,F8.0,1
+num4,4,Another numeric variable label,Unknown,Input,8,Right,F8.0,F8.0,1
+num5,5,,Unknown,Input,8,Right,F8.0,F8.0,1; 2
+num6,6,,Unknown,Input,8,Right,F8.0,F8.0,1; 2; 3
+num7,7,,Unknown,Input,8,Right,F8.0,F8.0,1 THRU 3
+num8,8,,Unknown,Input,8,Right,F8.0,F8.0,1 THRU 3; 5
+num9,9,,Unknown,Input,8,Right,F8.0,F8.0,1 THRU HIGHEST; -5
+numàèìñò,10,,Unknown,Input,8,Right,F8.0,F8.0,LOWEST THRU 1; 5
+str1,11,,Nominal,Input,4,Left,A4,A4,
+str2,12,String variable 2's label,Nominal,Input,4,Left,A4,A4,
+str3,13,,Nominal,Input,4,Left,A4,A4,"""MISS"""
+str4,14,Another string variable label,Nominal,Input,4,Left,A4,A4,"""OTHR"""
+str5,15,,Nominal,Input,4,Left,A4,A4,"""MISS""; ""OTHR"""
+str6,16,,Nominal,Input,4,Left,A4,A4,"""MISS""; ""OTHR""; ""MORE"""
+str7,17,,Nominal,Input,11,Left,A11,A11,"""first8by"""
+str8,18,,Nominal,Input,9,Left,A9,A9,"""abcdefgh"""
+str9,19,,Nominal,Input,10,Left,A10,A10,"""abcdefgh""; ""01234567"""
+str10,20,,Nominal,Input,11,Left,A11,A11,"""abcdefgh""; ""01234567""; ""0       """
+str11,21,25-byte string,Nominal,Input,25,Left,A25,A25,
 
 Table: Data List
 num1,num2,num3,num4,num5,num6,num7,num8,num9,numàèìñò,str1,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11
@@ -192,7 +189,7 @@ dnl File header.
 2; dnl Layout code
 -1; dnl Nominal case size (unspecified)
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 1; dnl 1 case.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -212,7 +209,7 @@ dnl Dictionary termination record.
 999; 0;
 
 dnl Data.
-1.0; 2.0; 
+1.0; 2.0;
 ])
 for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
@@ -223,10 +220,10 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Numeric variable 2's label,Unknown,Input,8,Right,F8.0,F8.0
 
 Table: Data List
 num1,num2
@@ -243,7 +240,7 @@ dnl File header.
 2; dnl Layout code
 -1; dnl Nominal case size (unspecified)
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 1; dnl 1 case.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -266,7 +263,7 @@ dnl Dictionary termination record.
 999; 0;
 
 dnl Data.
-1.0; 2.0; 
+1.0; 2.0;
 ])
 for variant in be le; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
@@ -277,10 +274,10 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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: Variables
+Name,Position,Label,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Numeric variable 2's label,Unknown,Input,8,Right,F8.0,F8.0
 
 Table: Data List
 num1,num2
@@ -297,7 +294,7 @@ dnl File header.
 2; dnl Layout code
 22; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 1; dnl 1 case.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -410,94 +407,64 @@ DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Unknown,Input,8,Right,F8.0,F8.0
+num3,3,Unknown,Input,8,Right,F8.0,F8.0
+num4,4,Unknown,Input,8,Right,F8.0,F8.0
+num5,5,Unknown,Input,8,Right,F8.0,F8.0
+str1,6,Nominal,Input,1,Left,A1,A1
+str2,7,Nominal,Input,2,Left,A2,A2
+str3,8,Nominal,Input,3,Left,A3,A3
+str4,9,Nominal,Input,4,Left,A4,A4
+str5,10,Nominal,Input,4,Left,A4,A4
+str6,11,Nominal,Input,6,Left,A6,A6
+str7,12,Nominal,Input,7,Left,A7,A7
+str8,13,Nominal,Input,8,Left,A8,A8
+str9ж,14,Nominal,Input,9,Left,A9,A9
+str12,15,Nominal,Input,12,Left,A12,A12
+str16,16,Nominal,Input,16,Left,A16,A16
+str17,17,Nominal,Input,17,Left,A17,A17
+
+Table: Value Labels
+Variable Value,,Label
+num1,1,один (in Russian)
+num2,1,one
+,2,two
+num3,3,three
+,4,four
+num4,5,five
+,7,seven
+,8,eight
+,9,nine
+num5,6,six
+,7,seven
+,8,eight
+,10,ten
+str1,a,value label for `a'
+str2,bc,value label for `bc'
+,de,value label for `de'
+str3,fgh,value label for `fgh'
+,ijk,value label for `ijk'
+str4,BCDE,value label for `BCDE'
+,lmno,value label for `lmno'
+,tuvw,value label for `tuvw'
+,xyzA,value label for `xyzA'
+str5,FGHI,value label for `FGHI'
+,pqrs,value label for `pqrs'
+,tuvw,value label for `tuvw'
+,xyzA,value label for `xyzA'
+str6,JKLMNO,value label for `JKLMNO'
+str7,JKLMNOP,value label for `JKLMNOP'
+str8,JKLMNOPQ,value label for `JKLMNOPQ'
+str9ж,RSTUVWXYZ,value label for `RSTUVWXYZ'
+str12,0123456789ab,value label for `0123456789ab'
+,cdefghijklmn,value label for `cdefghijklmn'
+str16,EFGHIJKLMNOPQRST,value label for `EFGHIJKLMNOPQRST'
+,UVWXYZ0123456789,value label for `UVWXYZ0123456789' with Cyrillic letters: `фхц'
+,opqrstuvwxyzABCD,value label for `opqrstuvwxyzABCD'
+str17,abcdefghijklmnopq,value label for `abcdefghijklmnopq'
 ])
 done
 AT_CLEANUP
@@ -510,7 +477,7 @@ dnl File header.
 2; dnl Layout code
 1; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 1; dnl 1 case.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -549,18 +516,60 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0], [dnl
-Documents in the active dataset:
+Table: Documents
+"First line of documents
+Second line of documents
+abbé appliqué attaché blasé café canapé cliché consommé
 
-First line of documents
+Last line of documents"
 
-Second line of documents
+Table: Data List
+num1
+1
+])
+done
+AT_CLEANUP
 
-abbé appliqué attaché blasé café canapé cliché consommé
+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";
 
-Last line of documents
+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
@@ -576,7 +585,7 @@ dnl File header.
 2; dnl Layout code
 16; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 0; dnl No cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -638,47 +647,23 @@ MRSETS /DISPLAY NAME=ALL.
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0], [dnl
 Table: Multiple Response Sets
-Name,Variables,Details
-$a,"あ
+Name,Label,Encoding,Counted Value,Member Variables
+$a,my mcgroup,Categories,,"あ
 b
-c
-","Multiple category set
-Label: my mcgroup
-"
-$b,"g
+c"
+$b,,Dichotomies,55,"g
 e
 f
-d
-","Multiple dichotomy set
-Counted value: 55
-Category label source: Variable labels
-"
-$c,"h
+d"
+$c,mdgroup #2,Dichotomies,はい,"h
 i
-j
-","Multiple dichotomy set
-Label: mdgroup #2
-Label source: Provided by user
-Counted value: `はい'
-Category label source: Variable labels
-"
-$d,"k
+j"
+$d,third mdgroup,Dichotomies,34,"k
 l
-m
-","Multiple dichotomy set
-Label: third mdgroup
-Label source: Provided by user
-Counted value: 34
-Category label source: Value labels of counted value
-"
-$e,"n
+m"
+$e,,Dichotomies,choice,"n
 o
-p
-","Multiple dichotomy set
-Label source: First variable label among variables
-Counted value: `choice'
-Category label source: Value labels of counted value
-"
+p"
 ])
 done
 AT_CLEANUP
@@ -714,18 +699,19 @@ dnl Character encoding record.
 dnl Dictionary termination record.
 999; 0;
 ])
-for variant in be le; do
+for variant in be; do
   AT_CHECK([sack --$variant sys-file.sack > sys-file.sav])
   AT_DATA([sys-file.sps], [dnl
 SYSFILE INFO FILE='sys-file.sav'.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
-  AT_CHECK([sed 7q pspp.csv], [0], [dnl
-File:,sys-file.sav
-Label:,"PSPP synthetic
+  AT_CHECK([sed 8q pspp.csv], [0], [dnl
+Table: File Information
+File,sys-file.sav
+Label,"PSPP synthetic
 test file"
-Created:,01 Jan 11 20:53:52 by $(@%:@) SPSS DATA FILE PSPP synthetic test file
-Product:,"Extra product info
+Created,01 Jan 11 20:53:52 by $(@%:@) SPSS DATA FILE PSPP synthetic test file
+Product,"Extra product info
 another line
 blah"
 ])
@@ -740,7 +726,7 @@ dnl File header.
 2; dnl Layout code
 19; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 0; dnl No cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -797,43 +783,20 @@ 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
-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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+a,1,Nominal,Input,8,Left,F8.0,F8.0
+b,2,Ordinal,Input,8,Left,F8.0,F8.0
+c,3,Scale,Input,8,Left,F8.0,F8.0
+d,4,Nominal,Input,8,Right,F8.0,F8.0
+h,5,Ordinal,Input,3,Right,A3,A3
+i,6,Scale,Input,3,Right,A3,A3
+j,7,Nominal,Input,3,Center,A3,A3
+k,8,Ordinal,Input,3,Center,A3,A3
+l,9,Scale,Input,9,Center,A9,A9
+m,10,Nominal,Input,10,Left,A10,A10
+n,11,Nominal,Input,17,Right,A17,A17
+o,12,Nominal,Input,25,Center,A25,A25
 ])
 done
 AT_CLEANUP
@@ -846,7 +809,7 @@ dnl File header.
 2; dnl Layout code
 19; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 0; dnl No cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -903,55 +866,20 @@ 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
-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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+a,1,Nominal,Input,1,Left,F8.0,F8.0
+b,2,Ordinal,Input,2,Left,F8.0,F8.0
+c,3,Scale,Input,3,Left,F8.0,F8.0
+d,4,Nominal,Input,4,Right,F8.0,F8.0
+h,5,Ordinal,Input,5,Right,A3,A3
+i,6,Scale,Input,6,Right,A3,A3
+j,7,Nominal,Input,7,Center,A3,A3
+k,8,Ordinal,Input,8,Center,A3,A3
+l,9,Scale,Input,9,Center,A9,A9
+m,10,Nominal,Input,10,Left,A10,A10
+n,11,Nominal,Input,11,Right,A17,A17
+o,12,Nominal,Input,12,Center,A25,A25
 ])
 done
 AT_CLEANUP
@@ -964,7 +892,7 @@ dnl File header.
 2; dnl Layout code
 7; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 0; dnl No cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1010,14 +938,15 @@ DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+LongVariableName1,1,Unknown,Input,8,Right,F8.0,F8.0
+LongVariableName2,2,Unknown,Input,8,Right,F8.0,F8.0
+LongVariableName3,3,Unknown,Input,8,Right,F8.0,F8.0
+LongVariableName4,4,Unknown,Input,8,Right,F8.0,F8.0
+Coördinate_X,5,Unknown,Input,8,Right,F8.0,F8.0
+Coördinate_Y,6,Unknown,Input,8,Right,F8.0,F8.0
+Coördinate_Z,7,Unknown,Input,8,Right,F8.0,F8.0
 ])
 done
 AT_CLEANUP
@@ -1030,7 +959,7 @@ dnl File header.
 2; dnl Layout code
 109; dnl Nominal case size
 0; dnl Not compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 1; dnl No cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1079,9 +1008,10 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0], [dnl
-Variable,Description,Position
-séq256,Format: A256,1
-str600,Format: A600,2
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+séq256,1,Nominal,Input,32,Left,A256,A256
+str600,2,Nominal,Input,32,Left,A600,A600
 
 Table: Data List
 séq256,str600
@@ -1096,9 +1026,9 @@ 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 Not weighted
 0; dnl 1 case.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1107,6 +1037,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;
@@ -1115,6 +1046,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.
@@ -1133,6 +1065,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";
@@ -1148,21 +1084,18 @@ DISPLAY @ATTRIBUTES.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   AT_CHECK([cat pspp.csv], [0],
-[[Variable,Description
-FirstVariable,"Attribute,Value
-$@Role,1
-adèle[1],23
-adèle[2],34
-bert,123"
-SécondVariable,"Attribute,Value
-xyzzy,quux"
-
-Table: Custom data file attributes.
-Attribute,Value
-Attr1[1],Value1
-Attr1[2],'déclaration'
-SécondAttr[1],123
-SécondAttr[2],456
+[[Table: Variable and Dataset Attributes
+Variable and Name,,Value
+(dataset),Attr1[1],Value1
+,Attr1[2],'déclaration'
+,SécondAttr[1],123
+,SécondAttr[2],456
+FirstVariable,$@Role,1
+,adèle[1],23
+,adèle[2],34
+,bert,123
+SécondVariable,xyzzy,quux
+ThirdVariable,fizz,buzz
 ]])
   AT_DATA([sys-file.sps], [dnl
 GET FILE='sys-file.sav'.
@@ -1170,26 +1103,11 @@ DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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
-
-Table: Custom data file attributes.
-Attribute,Value
-Attr1[1],Value1
-Attr1[2],'déclaration'
-SécondAttr[1],123
-SécondAttr[2],456
+[[Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+FirstVariable,1,Unknown,Output,8,Right,F8.0,F8.0
+SécondVariable,2,Unknown,Input,8,Right,F8.0,F8.0
+ThirdVariable,3,Unknown,Input,8,Right,F8.0,F8.0
 ]])
 done
 AT_CLEANUP
@@ -1249,21 +1167,15 @@ warning: `sys-file.sav': Invalid role for variable x.
   AT_CHECK([cat pspp.csv], [0], [dnl
 warning: `sys-file.sav': Invalid role for variable x.
 
-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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+i,1,Unknown,Input,8,Right,F8.0,F8.0
+o,2,Unknown,Output,8,Right,F8.0,F8.0
+b,3,Unknown,Both,8,Right,F8.0,F8.0
+n,4,Unknown,None,8,Right,F8.0,F8.0
+p,5,Unknown,Partition,8,Right,F8.0,F8.0
+s,6,Unknown,Split,8,Right,F8.0,F8.0
+x,7,Unknown,Input,8,Right,F8.0,F8.0
 ])
 done
 AT_CLEANUP
@@ -1276,7 +1188,7 @@ dnl File header.
 2; dnl Layout code
 6; dnl Nominal case size
 1; dnl Simple compression
-0; dnl Not weighted 
+0; dnl Not weighted
 -1; dnl Unspecified number of cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1314,17 +1226,18 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Unknown,Input,8,Right,F8.0,F8.0
+str4,3,Nominal,Input,4,Left,A4,A4
+str8,4,Nominal,Input,8,Left,A8,A8
+str15,5,Nominal,Input,15,Left,A15,A15
 
 Table: Data List
 num1,num2,str4,str8,str15
--99,0,,abcdefgh,0123   @&t@
-.,151,jklm,nopqrstu,vwxyzABC       @&t@
+-99,0,,abcdefgh,0123
+.,151,jklm,nopqrstu,vwxyzABC
 1,2,DEFG,HIJKLMNO,PQRSTUV
 ])
 done
@@ -1338,7 +1251,7 @@ dnl File header.
 2; dnl Layout code
 6; dnl Nominal case size
 1; dnl Simple compression.
-0; dnl Not weighted 
+0; dnl Not weighted
 -1; dnl Unspecified number of cases.
 0.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1376,17 +1289,18 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps], [0])
   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: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Unknown,Input,8,Right,F8.0,F8.0
+str4,3,Nominal,Input,4,Left,A4,A4
+str8,4,Nominal,Input,8,Left,A8,A8
+str15,5,Nominal,Input,15,Left,A15,A15
 
 Table: Data List
 num1,num2,str4,str8,str15
-1,100,,abcdefgh,0123   @&t@
-.,251,jklm,nopqrstu,vwxyzABC       @&t@
+1,100,,abcdefgh,0123
+.,251,jklm,nopqrstu,vwxyzABC
 101,102,DEFG,HIJKLMNO,PQRSTUV
 ])
 done
@@ -1400,7 +1314,7 @@ dnl File header.
 2; dnl Layout code
 6; dnl Nominal case size
 1; dnl Simple compression.
-0; dnl Not weighted 
+0; dnl Not weighted
 -1; dnl Unspecified number of cases.
 50.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -1436,23 +1350,24 @@ GET FILE='sys-file.sav'.
 DISPLAY DICTIONARY.
 LIST.
 ])
-  AT_CHECK([pspp -o pspp.csv sys-file.sps], [0], 
+  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([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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Unknown,Input,8,Right,F8.0,F8.0
+str4,3,Nominal,Input,4,Left,A4,A4
+str8,4,Nominal,Input,8,Left,A8,A8
+str15,5,Nominal,Input,15,Left,A15,A15
 
 Table: Data List
 num1,num2,str4,str8,str15
--49,50,,abcdefgh,0123   @&t@
-.,201,jklm,nopqrstu,vwxyzABC       @&t@
+-49,50,,abcdefgh,0123
+.,201,jklm,nopqrstu,vwxyzABC
 51,52,DEFG,HIJKLMNO,PQRSTUV
 ])
 done
@@ -1539,17 +1454,18 @@ LIST.
 ])
   AT_CHECK([pspp -o pspp.csv sys-file.sps])
   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: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+num2,2,Unknown,Input,8,Right,F8.0,F8.0
+str4,3,Nominal,Input,4,Left,A4,A4
+str8,4,Nominal,Input,8,Left,A8,A8
+str15,5,Nominal,Input,15,Left,A15,A15
 
 Table: Data List
 num1,num2,str4,str8,str15
--99,0,,abcdefgh,0123   @&t@
-.,151,jklm,nopqrstu,vwxyzABC       @&t@
+-99,0,,abcdefgh,0123
+.,151,jklm,nopqrstu,vwxyzABC
 1,2,DEFG,HIJKLMNO,PQRSTUV
 ])
 done
@@ -1557,6 +1473,43 @@ 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
@@ -1610,7 +1563,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0xd4: Misplaced type 4 record.
 ])
 done
@@ -1633,7 +1586,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0xd4: Unrecognized record type 8.
 ])
 done
@@ -1659,7 +1612,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 format=csv sys-file.sps], [0], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [0],
    [warning: `sys-file.sav': File header claims 2 variable positions but 1 were read from file.
 ])
 done
@@ -1685,8 +1638,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 format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0xb4: Invalid variable name `$UM1'.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0,
+   [warning: `sys-file.sav' near offset 0xb4: Renaming variable with invalid name `$UM1' to `VAR001'.
 ])
 done
 AT_CLEANUP
@@ -1711,8 +1664,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 format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0xb4: Invalid variable name `TO'.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0,
+   [warning: `sys-file.sav' near offset 0xb4: Renaming variable with invalid name `TO' to `VAR001'.
 ])
 done
 AT_CLEANUP
@@ -1737,7 +1690,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0xb4: Bad width 256 for variable VAR1.
 ])
 done
@@ -1770,9 +1723,10 @@ 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
-var001,Format: F8.0,2
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+var1,1,Unknown,Input,8,Right,F8.0,F8.0
+var001,2,Unknown,Input,8,Right,F8.0,F8.0
 ])
 done
 AT_CLEANUP
@@ -1797,7 +1751,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0xb4: Variable label indicator field is not 0 or 1.
 ])
 done
@@ -1823,7 +1777,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    ["error: `sys-file.sav' near offset 0xb4: Numeric missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 ])
 done
@@ -1849,7 +1803,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    ["error: `sys-file.sav' near offset 0xb4: String missing value indicator field is not 0, 1, 2, or 3."
 ])
 done
@@ -1876,7 +1830,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 format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0xb4: Missing string continuation record.
 ])
 done
@@ -2010,12 +1964,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
-str1,Format: A9,2
-str2,"Format: A10
-Missing Values: ""abcdefgh""; ""ijklmnop""; ""qrstuvwx""",3
-str3,Format: A11,4
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format,Missing Values
+num1,1,Unknown,Input,8,Right,F8.0,F8.0,
+str1,2,Nominal,Input,9,Left,A9,A9,
+str2,3,Nominal,Input,10,Left,A10,A10,"""abcdefgh""; ""ijklmnop""; ""qrstuvwx"""
+str3,4,Nominal,Input,11,Left,A11,A11,
 ])
 done
 AT_CLEANUP
@@ -2045,11 +1999,12 @@ for variant in be le; do
 DISPLAY DICTIONARY.
 ])
   AT_CHECK([pspp -O format=csv sys-file.sps], [0],
-   [warning: `sys-file.sav': Ignoring string variable `STR1' set as weighting variable.
+   [warning: `sys-file.sav' near offset 0x4c: Ignoring string variable `STR1' set as weighting variable.
 
-Variable,Description,Position
-num1,Format: F8.0,1
-str1,Format: A4,2
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
+str1,2,Nominal,Input,4,Left,A4,A4
 ])
 done
 AT_CLEANUP
@@ -2077,13 +2032,13 @@ 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 format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0x4c: Variable index 3 not in valid range 1...2.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0,
+   [warning: `sys-file.sav' near offset 0x4c: Weight variable index 3 not in valid range 1...2.  Treating file as unweighted.
 ])
 done
 AT_CLEANUP
 
-AT_SETUP([variable index is long string contination])
+AT_SETUP([variable index is long string continuation])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
 dnl File header.
@@ -2107,8 +2062,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 format=csv sys-file.sps], [1], 
-   [error: `sys-file.sav' near offset 0x4c: Variable index 3 refers to long string continuation.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0,
+   [warning: `sys-file.sav' near offset 0x4c: Weight variable index 3 refers to long string continuation.  Treating file as unweighted.
 ])
 done
 AT_CLEANUP
@@ -2120,46 +2075,16 @@ 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.
+dnl Numeric variables, no label or missing values.
 2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
 
 dnl Two document records.
 (6; 1; s80 "One line of documents") >>* 2<<;
 
-dnl Dictionary termination record.
-999; 0;
-
 dnl Character encoding record.
 7; 20; 1; 12; "windows-1252";
 
-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 0x12c: Duplicate type 6 (document) record.
-])
-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;
 
@@ -2171,12 +2096,13 @@ 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], [1], [dnl
-error: `sys-file.sav' near offset 0xd4: Number of document lines (0) must be greater than 0 and less than 26843545.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0, [dnl
+warning: `sys-file.sav' near offset 0x14c: Duplicate type 6 (document) record.
 ])
 done
 AT_CLEANUP
 
+
 AT_SETUP([extension record too large])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
@@ -2225,8 +2151,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
@@ -2320,8 +2246,9 @@ 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
+Table: Variables
+Name,Position,Measurement Level,Role,Width,Alignment,Print Format,Write Format
+num1,1,Unknown,Input,8,Right,F8.0,F8.0
 ])
 done
 AT_CLEANUP
@@ -2456,36 +2383,21 @@ 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
-$a,"あ
+Name,Label,Encoding,Counted Value,Member Variables
+$a,my mcgroup,Categories,,"あ
 b
-c
-","Multiple category set
-Label: my mcgroup
-"
-$c,"h
+c"
+$c,mdgroup #2,Dichotomies,はい,"h
 i
-j
-","Multiple dichotomy set
-Label: mdgroup #2
-Label source: Provided by user
-Counted value: `はい'
-Category label source: Variable labels
-"
-$d,"k
+j"
+$d,third mdgroup,Dichotomies,34,"k
 l
-m
-","Multiple dichotomy set
-Label: third mdgroup
-Label source: Provided by user
-Counted value: 34
-Category label source: Value labels of counted value
-"
+m"
 ])
 done
 AT_CLEANUP
@@ -2546,6 +2458,36 @@ warning: `sys-file.sav' near offset 0xd8: Missing space following `E' at offset
 done
 AT_CLEANUP
 
+AT_SETUP([missing label source in mrsets])
+AT_KEYWORDS([sack synthetic system file negative multiple response])
+AT_DATA([sys-file.sack], [dnl
+dnl File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 1; 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 Multiple response sets.
+7; 7; 1; COUNT("$a=E ");
+
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+999; 0;
+])
+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 format=csv sys-file.sps], [0], [dnl
+warning: `sys-file.sav' near offset 0xd8: Missing label source value following `E' at offset 5 in MRSETS record.
+
+warning: `sys-file.sav' near offset 0xd8: Expecting digit at offset 5 in MRSETS record.
+])
+done
+AT_CLEANUP
+
 AT_SETUP([unexpected label source in mrsets])
 AT_KEYWORDS([sack synthetic system file negative multiple response])
 AT_DATA([sys-file.sack], [dnl
@@ -3027,6 +2969,8 @@ 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;
 );
@@ -3045,6 +2989,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
@@ -3224,8 +3172,82 @@ 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], [1], [dnl
-error: `sys-file.sav' near offset 0xf4: Value labels may not be added to long string variables (e.g. STR1) using records types 3 and 4.
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0, [dnl
+warning: `sys-file.sav' near offset 0xf4: Value labels may not be added to long string variables (e.g. STR1) using records types 3 and 4.
+])
+done
+AT_CLEANUP
+
+AT_SETUP([value label variable indexes must be in correct range])
+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 Variables.
+2; 6; 0; 0; 0x010600 *2; s8 "STR1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+dnl Value labels with bad variable indexes.
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>3; 4;<<
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>5; 6;<<
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>7; 8;<<
+
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+dnl End of dictionary.
+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], 0, [dnl
+warning: `sys-file.sav' near offset 0xf4: Value label variable index 3 not in valid range 1...2.
+
+warning: `sys-file.sav' near offset 0xf4: Value label variable index 4 not in valid range 1...2.
+
+warning: `sys-file.sav' near offset 0x11c: Value label variable index 5 not in valid range 1...2.
+
+warning: `sys-file.sav' near offset 0x11c: Value label variable index 6 not in valid range 1...2.
+
+warning: `sys-file.sav' near offset 0x144: Value label variable index 7 not in valid range 1...2.
+
+warning: `sys-file.sav': Suppressed 1 additional warnings for value labels.
+])
+done
+AT_CLEANUP
+
+AT_SETUP([value label variable indexes must not be long string continuation])
+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 Long string variable.
+2; 9; 0; 0; 0x010900 *2; s8 "STR1";
+(2; -1; 0; 0; 0; 0; s8 "");
+
+dnl Value label with long string indexes.
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 1; >>2;<<
+
+dnl Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+dnl End of dictionary.
+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], 0, [dnl
+warning: `sys-file.sav' near offset 0xf4: Value label variable index 2 refers to long string continuation.
 ])
 done
 AT_CLEANUP
@@ -3255,8 +3277,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], [1], [dnl
-"error: `sys-file.sav' near offset 0xf4: Variables associated with value label are not all of identical type.  Variable STR1 is string, but variable NUM1 is numeric."
+  AT_CHECK([pspp -O format=csv sys-file.sps], 0, [dnl
+"warning: `sys-file.sav' near offset 0xf4: Variables associated with value label are not all of identical type.  Variable STR1 is string, but variable NUM1 is numeric."
 ])
 done
 AT_CLEANUP
@@ -3376,6 +3398,48 @@ warning: `sys-file.sav' near offset 0x106: Attribute value fred[[1]] is not quot
 done
 AT_CLEANUP
 
+AT_SETUP([duplicate attribute name])
+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; 1; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+dnl Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
+
+dnl Data file attributes record.
+7; 17; 1; COUNT (
+"Attr1('value'"; i8 10; ")";
+"Attr1('value'"; i8 10; ")";
+);
+
+dnl Variable attributes record.
+7; 18; 1; COUNT (
+"FIRSTVAR:";
+  "fred('23'"; i8 10; ")";
+  "fred('23'"; i8 10; ")";
+);
+
+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], [0], [dnl
+warning: `sys-file.sav' near offset 0xf6: Duplicate attribute Attr1.
+
+warning: `sys-file.sav' near offset 0x125: Duplicate attribute fred.
+])
+done
+AT_CLEANUP
+
 AT_SETUP([bad variable name in long string value label])
 AT_KEYWORDS([sack synthetic system file negative])
 AT_DATA([sys-file.sack], [dnl
@@ -3462,7 +3526,7 @@ for variant in be le; do
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 LIST.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: Error reading case from file `sys-file.sav'.
 
 Table: Data List
@@ -3499,7 +3563,7 @@ for variant in be le; do
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 LIST.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0x12c: File ends in partial case.
 
 Table: Data List
@@ -3533,12 +3597,12 @@ for variant in be le; do
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 LIST.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0x12a: Unexpected end of file.
 
 Table: Data List
 str14
-one data item @&t@
+one data item
 ])
 done
 AT_CLEANUP
@@ -3551,7 +3615,7 @@ dnl File header.
 2; dnl Layout code
 6; dnl Nominal case size
 1; dnl Compressed
-0; dnl Not weighted 
+0; dnl Not weighted
 -1; dnl Unspecified number of cases.
 100.0; dnl Bias.
 "01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
@@ -3581,12 +3645,12 @@ for variant in be le; do
   AT_DATA([sys-file.sps], [GET FILE='sys-file.sav'.
 LIST.
 ])
-  AT_CHECK([pspp -O format=csv sys-file.sps], [1], 
+  AT_CHECK([pspp -O format=csv sys-file.sps], [1],
    [error: `sys-file.sav' near offset 0x1ac: File ends in partial case.
 
 Table: Data List
 num1,num2,str4,str8,str15
--99,0,,abcdefgh,0123   @&t@
+-99,0,,abcdefgh,0123
 ])
 done
 AT_CLEANUP
@@ -3817,3 +3881,29 @@ for variant in be le; do
 ])
 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