Add lots of tests (most of them fail so far)
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 25 Jun 2025 21:48:54 +0000 (14:48 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 25 Jun 2025 21:48:54 +0000 (14:48 -0700)
90 files changed:
rust/pspp/src/dictionary.rs
rust/pspp/src/sys/cooked.rs
rust/pspp/src/sys/raw.rs
rust/pspp/src/sys/test.rs
rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_very_long_string_length.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_very_long_string_length.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_attribute_name.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_attribute_name.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_long_variable_name.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_long_variable_name.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_value_labels_type.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/duplicate_value_labels_type.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_attribute_value.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_attribute_value.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_type_4_record.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/missing_type_4_record.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_compressed_data_record.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_compressed_data_record.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_data_record_between_variables.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_data_record_between_variables.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_data_record_within_long_string.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/partial_data_record_within_long_string.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/too_many_value_labels.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/too_many_value_labels.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/unquoted_attribute_value.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/unquoted_attribute_value.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_alignment.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_alignment.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_measurement_level.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_measurement_level.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_parameter_count.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_parameter_count.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_parameter_size.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/wrong_display_parameter_size.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.sack [new file with mode: 0644]
rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.expected [new file with mode: 0644]
rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.sack [new file with mode: 0644]

index 876284d6b061d843530b46be62cadbeed38f3d60..55a795fd1ac97934e29b2ed7088f9ed41e9114c1 100644 (file)
@@ -574,18 +574,22 @@ impl Dictionary {
     }
 
     /// Attempts to change the name of the variable with the given `index` to
-    /// `new_name`.  Returns true if successful, false if `new_name` would
-    /// duplicate the name of some other variable.
-    pub fn try_rename_var(&mut self, index: usize, new_name: Identifier) -> bool {
+    /// `new_name`.  Returns `Ok(())` if successful; otherwise, if `new_name`
+    /// would duplicate the name of some other variable, returns `new_name` as
+    /// an error.
+    pub fn try_rename_var(&mut self, index: usize, new_name: Identifier) -> Result<(), Identifier> {
         let mut variable = self.variables.swap_remove_index(index).unwrap();
         let may_rename = !self.variables.contains(&new_name.0);
-        if may_rename {
+        let retval = if may_rename {
             variable.name = new_name;
             variable.short_names = Vec::new();
+            Ok(())
+        } else {
+            Err(new_name)
         };
         assert!(self.variables.insert(variable));
         self.variables.swap_indices(self.variables.len() - 1, index);
-        may_rename
+        retval
     }
 
     /// Changes the name of the variable with given `index` to `new_name`.
@@ -594,7 +598,7 @@ impl Dictionary {
     ///
     /// Panics if the new name duplicates the name of some existing variable.
     pub fn rename_var(&mut self, index: usize, new_name: Identifier) {
-        assert!(self.try_rename_var(index, new_name));
+        assert!(self.try_rename_var(index, new_name).is_ok());
     }
 
     pub fn output_variables(&self) -> OutputVariables {
index e74b7334dadd537e39bf037c64f2a2f617e230e6..d864504bd5396ae90a70a60582dce55ba06f57fa 100644 (file)
@@ -169,9 +169,24 @@ pub enum Error {
     #[error("Invalid name in long variable name record.  {0}")]
     InvalidLongName(IdError),
 
+    #[error("Duplicate long variable name {0}.")]
+    DuplicateLongName(Identifier),
+
     #[error("Invalid variable name in very long string record.  {0}")]
     InvalidLongStringName(IdError),
 
+    #[error("Variable with short name {short_name} listed in very long string record with width {width}, which requires only one segment.")]
+    ShortVeryLongString { short_name: Identifier, width: u16 },
+
+    #[error("Variable with short name {short_name} listed in very long string record with width {width} requires string segments for {n_segments} dictionary indexes starting at index {index}, but the dictionary only contains {len} indexes.")]
+    VeryLongStringOverflow {
+        short_name: Identifier,
+        width: u16,
+        index: usize,
+        n_segments: usize,
+        len: usize,
+    },
+
     #[error("Invalid variable name in long string value label record.  {0}")]
     InvalidLongStringValueLabelName(IdError),
 
@@ -824,11 +839,20 @@ pub fn decode(
         let width = VarWidth::String(record.length);
         let n_segments = width.n_segments();
         if n_segments == 1 {
-            warn(dbg!(Error::TBD));
+            warn(dbg!(Error::ShortVeryLongString {
+                short_name: record.short_name.clone(),
+                width: record.length
+            }));
             continue;
         }
         if index + n_segments > dictionary.variables.len() {
-            warn(dbg!(Error::TBD));
+            warn(dbg!(Error::VeryLongStringOverflow {
+                short_name: record.short_name.clone(),
+                width: record.length,
+                index,
+                n_segments,
+                len: dictionary.variables.len()
+            }));
             continue;
         }
         let mut short_names = Vec::with_capacity(n_segments);
@@ -854,7 +878,7 @@ pub fn decode(
         for index in 0..dictionary.variables.len() {
             let lower = dictionary.variables[index].name.0.as_ref().to_lowercase();
             if let Ok(new_name) = Identifier::from_encoding(lower, dictionary.encoding) {
-                dictionary.try_rename_var(index, new_name);
+                let _ = dictionary.try_rename_var(index, new_name);
             }
         }
     } else {
@@ -868,12 +892,15 @@ pub fn decode(
             .iter()
             .flat_map(|record| record.0.iter().cloned())
         {
+            dbg!(&renaming);
             let LongName {
                 short_name,
                 long_name,
             } = renaming;
             if let Some(index) = dictionary.variables.get_index_of(&short_name.0) {
-                dictionary.try_rename_var(index, long_name);
+                if let Err(long_name) = dictionary.try_rename_var(index, long_name) {
+                    warn(Error::DuplicateLongName(long_name));
+                }
                 dictionary
                     .variables
                     .get_index_mut2(index)
@@ -968,7 +995,7 @@ pub fn decode(
             .collect::<Vec<_>>();
         match MissingValues::new(values, None) {
             Ok(missing_values) => variable.missing_values = missing_values,
-            Err(MissingValuesError::TooWide) => warn(Error::TBD),
+            Err(MissingValuesError::TooWide) => warn(dbg!(Error::TBD)),
             Err(MissingValuesError::TooMany) | Err(MissingValuesError::MixedTypes) => {
                 unreachable!()
             }
index de528388b6d0191175308d93e116cb824a819798..4fcd05562a76cbc4c42ce8c012a5d330d8169f45 100644 (file)
@@ -181,6 +181,9 @@ pub enum Warning {
     #[error("Invalid variable name in attribute record.  {0}")]
     InvalidAttributeVariableName(IdError),
 
+    #[error("Missing `=` separator in long variable name record.")]
+    LongNameMissingEquals,
+
     #[error("Invalid short name in long variable name record.  {0}")]
     InvalidShortName(IdError),
 
@@ -2853,7 +2856,7 @@ impl RawFileAttributesRecord {
         match Attributes::parse(decoder, &input, None).issue_warning(&mut decoder.warn) {
             Some((set, rest)) => {
                 if !rest.is_empty() {
-                    decoder.warn(Warning::TBD);
+                    decoder.warn(dbg!(Warning::TBD));
                 }
                 FileAttributesRecord(set)
             }
@@ -2874,7 +2877,7 @@ impl VarAttributes {
         input: &'a str,
     ) -> Result<(VarAttributes, &'a str), Warning> {
         let Some((long_var_name, rest)) = input.split_once(':') else {
-            return Err(Warning::TBD);
+            return Err(dbg!(Warning::TBD));
         };
         let long_var_name = decoder
             .new_identifier(long_var_name)
@@ -2928,7 +2931,7 @@ pub struct LongName {
 impl LongName {
     fn parse(input: &str, decoder: &Decoder) -> Result<Self, Warning> {
         let Some((short_name, long_name)) = input.split_once('=') else {
-            return Err(Warning::TBD);
+            return Err(dbg!(Warning::LongNameMissingEquals));
         };
         let short_name = decoder
             .new_identifier(short_name)
index f6dd0cd10abefffeacad2224ca72c3f377facb79..f0846a160f101aebaaa6a478f7f58bd8904c1635 100644 (file)
@@ -287,6 +287,221 @@ fn multiple_response_sets_duplicate_variable_name() {
     test_sysfile("multiple_response_sets_duplicate_variable_name");
 }
 
+#[test]
+fn mixed_variable_types_in_mrsets() {
+    test_sysfile("mixed_variable_types_in_mrsets");
+}
+
+#[test]
+fn missing_newline_after_variable_name_in_mrsets() {
+    test_sysfile("missing_newline_after_variable_name_in_mrsets");
+}
+
+#[test]
+fn zero_or_one_variable_in_mrset() {
+    test_sysfile("zero_or_one_variable_in_mrset");
+}
+
+#[test]
+fn wrong_display_parameter_size() {
+    test_sysfile("wrong_display_parameter_size");
+}
+
+#[test]
+fn wrong_display_parameter_count() {
+    test_sysfile("wrong_display_parameter_count");
+}
+
+#[test]
+fn wrong_display_measurement_level() {
+    test_sysfile("wrong_display_measurement_level");
+}
+
+#[test]
+fn wrong_display_alignment() {
+    test_sysfile("wrong_display_alignment");
+}
+
+#[test]
+fn bad_variable_name_in_variable_value_pair() {
+    test_sysfile("bad_variable_name_in_variable_value_pair");
+}
+
+#[test]
+fn duplicate_long_variable_name() {
+    test_sysfile("duplicate_long_variable_name");
+}
+
+#[test]
+fn bad_very_long_string_length() {
+    test_sysfile("bad_very_long_string_length");
+}
+
+#[test]
+fn bad_very_long_string_segment_width() {
+    test_sysfile("bad_very_long_string_segment_width");
+}
+
+#[test]
+fn too_many_value_labels() {
+    test_sysfile("too_many_value_labels");
+}
+
+#[test]
+fn missing_type_4_record() {
+    test_sysfile("missing_type_4_record");
+}
+
+#[test]
+fn value_label_with_no_associated_variables() {
+    test_sysfile("value_label_with_no_associated_variables");
+}
+
+#[test]
+fn type_4_record_names_long_string_variable() {
+    test_sysfile("type_4_record_names_long_string_variable");
+}
+
+#[test]
+fn value_label_variable_indexes_must_be_in_correct_range() {
+    test_sysfile("value_label_variable_indexes_must_be_in_correct_range");
+}
+
+#[test]
+fn value_label_variable_indexes_must_not_be_long_string_continuation() {
+    test_sysfile("value_label_variable_indexes_must_not_be_long_string_continuation");
+}
+
+#[test]
+fn variables_for_value_label_must_all_be_same_type() {
+    test_sysfile("variables_for_value_label_must_all_be_same_type");
+}
+
+#[test]
+fn duplicate_value_labels_type() {
+    test_sysfile("duplicate_value_labels_type");
+}
+
+#[test]
+fn missing_attribute_value() {
+    test_sysfile("missing_attribute_value");
+}
+
+#[test]
+fn unquoted_attribute_value() {
+    test_sysfile("unquoted_attribute_value");
+}
+
+#[test]
+fn duplicate_attribute_name() {
+    test_sysfile("duplicate_attribute_name");
+}
+
+#[test]
+fn bad_variable_name_in_long_string_value_label() {
+    test_sysfile("bad_variable_name_in_long_string_value_label");
+}
+
+#[test]
+fn fewer_data_records_than_indicated_by_file_header() {
+    test_sysfile("fewer_data_records_than_indicated_by_file_header");
+}
+
+#[test]
+fn partial_data_record_between_variables() {
+    test_sysfile("partial_data_record_between_variables");
+}
+
+#[test]
+fn partial_data_record_within_long_string() {
+    test_sysfile("partial_data_record_within_long_string");
+}
+
+#[test]
+fn partial_compressed_data_record() {
+    test_sysfile("partial_compressed_data_record");
+}
+
+#[test]
+fn zcompressed_data_bad_zheader_ofs() {
+    test_sysfile("zcompressed_data_bad_zheader_ofs");
+}
+
+#[test]
+fn zcompressed_data_bad_ztrailer_ofs() {
+    test_sysfile("zcompressed_data_bad_ztrailer_ofs");
+}
+
+#[test]
+fn zcompressed_data_invalid_ztrailer_len() {
+    test_sysfile("zcompressed_data_invalid_ztrailer_len");
+}
+
+#[test]
+fn zcompressed_data_wrong_ztrailer_len() {
+    test_sysfile("zcompressed_data_wrong_ztrailer_len");
+}
+
+#[test]
+fn zcompressed_data_wrong_ztrailer_bias() {
+    test_sysfile("zcompressed_data_wrong_ztrailer_bias");
+}
+
+#[test]
+fn zcompressed_data_wrong_ztrailer_zero() {
+    test_sysfile("zcompressed_data_wrong_ztrailer_zero");
+}
+
+#[test]
+fn zcompressed_data_wrong_block_size() {
+    test_sysfile("zcompressed_data_wrong_block_size");
+}
+
+#[test]
+fn zcompressed_data_wrong_n_blocks() {
+    test_sysfile("zcompressed_data_wrong_n_blocks");
+}
+
+#[test]
+fn zcompressed_data_wrong_uncompressed_ofs() {
+    test_sysfile("zcompressed_data_wrong_uncompressed_ofs");
+}
+
+#[test]
+fn zcompressed_data_wrong_compressed_ofs() {
+    test_sysfile("zcompressed_data_wrong_compressed_ofs");
+}
+
+#[test]
+fn zcompressed_data_compressed_sizes_dont_add_up() {
+    test_sysfile("zcompressed_data_compressed_sizes_dont_add_up");
+}
+
+#[test]
+fn zcompressed_data_uncompressed_size_block_size() {
+    test_sysfile("zcompressed_data_uncompressed_size_block_size");
+}
+
+#[test]
+fn zcompressed_data_compression_expands_data_too_much() {
+    test_sysfile("zcompressed_data_compression_expands_data_too_much");
+}
+
+#[test]
+fn zcompressed_data_compressed_sizes_don_t_add_up() {
+    test_sysfile("zcompressed_data_compressed_sizes_don_t_add_up");
+}
+
+#[test]
+fn integer_overflows_in_long_string_missing_values() {
+    test_sysfile("integer_overflows_in_long_string_missing_values");
+}
+
+#[test]
+fn null_dereference_skipping_bad_extension_record_18() {
+    test_sysfile("null_dereference_skipping_bad_extension_record_18");
+}
+
 /// Duplicate variable name handling negative test.
 ///
 /// SPSS-generated system file can contain duplicate variable names (see bug
diff --git a/rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.expected b/rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.sack b/rust/pspp/src/sys/testdata/bad_variable_name_in_long_string_value_label.sack
new file mode 100644 (file)
index 0000000..57f7ef2
--- /dev/null
@@ -0,0 +1,37 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 3; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 14; 0; 0; 0x010e00 *2; s8 "STR14";
+2; -1; 0; 0; 0; 0; s8 "";
+
+7; 21; 1; COUNT (
+# No variable named STR9.
+COUNT(>>"STR9"<<); 9;
+1; COUNT("RSTUVWXYZ"); COUNT("value label for `RSTUVWXYZ'");
+
+# NUM1 is numeric.
+COUNT(>>"NUM1"<<); 0;
+1; COUNT("xyz"); COUNT("value label for 1.0");
+
+# Wrong width for STR14.
+COUNT("STR14"); >>9<<;
+1; COUNT("RSTUVWXYZ"); COUNT("value label for `RSTUVWXYZ'");
+
+# Wrong width for value.
+COUNT("STR14"); 14;
+1; COUNT(>>"RSTUVWXYZ"<<); COUNT("value label for `RSTUVWXYZ'");
+
+# Duplicate value label.
+COUNT("STR14"); 14; 2;
+COUNT("abcdefghijklmn"); COUNT("value label for `abcdefghijklmn'");
+>>COUNT("abcdefghijklmn"); COUNT("another value label for `abcdefghijklmn'")<<;
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.expected b/rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.expected
new file mode 100644 (file)
index 0000000..2c10b1c
--- /dev/null
@@ -0,0 +1,20 @@
+Missing `=` separator in long variable name record.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│        │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│LONGVARI│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.sack b/rust/pspp/src/sys/testdata/bad_variable_name_in_variable_value_pair.sack
new file mode 100644 (file)
index 0000000..840690c
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "LONGVARI";
+
+# Long variable names.
+7; 13; 1; COUNT (>>"xyzzy"<<);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/bad_very_long_string_length.expected b/rust/pspp/src/sys/testdata/bad_very_long_string_length.expected
new file mode 100644 (file)
index 0000000..31dafee
--- /dev/null
@@ -0,0 +1,24 @@
+Variable with short name NUM1 listed in very long string record with width 0, which requires only one segment.
+
+Variable with short name NUM1 listed in very long string record with width 255, which requires only one segment.
+
+Variable with short name NUM1 listed in very long string record with width 256 requires string segments for 2 dictionary indexes starting at index 0, but the dictionary only contains 1 indexes.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/bad_very_long_string_length.sack b/rust/pspp/src/sys/testdata/bad_very_long_string_length.sack
new file mode 100644 (file)
index 0000000..7a6008f
--- /dev/null
@@ -0,0 +1,19 @@
+# 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;
+
+# Numeric variable.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Very long string map.
+7; 14; 1; COUNT (
+"NUM1=00000"; i8 0; i8 9;
+"NUM1=00255"; i8 0; i8 9;
+"NUM1=00256"; i8 0; i8 9;
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.expected b/rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.sack b/rust/pspp/src/sys/testdata/bad_very_long_string_segment_width.sack
new file mode 100644 (file)
index 0000000..1141dc8
--- /dev/null
@@ -0,0 +1,20 @@
+# 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;
+
+# Variables.
+2; 255; 0; 0; 0x01ff00 *2; s8 "STR1";
+(2; -1; 0; 0; 0; 0; s8 "") * 31;
+2; >>9<<; 0; 0; 0x010900 *2; s8 "STR1_A";
+>>2; -1; 0; 0; 0; 0; s8 "";<<
+
+# Very long string map.
+7; 14; 1; COUNT (
+"STR1=00256"; i8 0; i8 9;
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/duplicate_attribute_name.expected b/rust/pspp/src/sys/testdata/duplicate_attribute_name.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/duplicate_attribute_name.sack b/rust/pspp/src/sys/testdata/duplicate_attribute_name.sack
new file mode 100644 (file)
index 0000000..2febfc6
--- /dev/null
@@ -0,0 +1,25 @@
+# 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;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
+
+# Data file attributes record.
+7; 17; 1; COUNT (
+"Attr1('value'"; i8 10; ")";
+"Attr1('value'"; i8 10; ")";
+);
+
+# Variable attributes record.
+7; 18; 1; COUNT (
+"FIRSTVAR:";
+  "fred('23'"; i8 10; ")";
+  "fred('23'"; i8 10; ")";
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/duplicate_long_variable_name.expected b/rust/pspp/src/sys/testdata/duplicate_long_variable_name.expected
new file mode 100644 (file)
index 0000000..de5196b
--- /dev/null
@@ -0,0 +1,29 @@
+Invalid name in long variable name record.  "_Invalid" may not be used as an identifier because it begins with disallowed character "_".
+
+Invalid name in long variable name record.  "$Invalid" may not be used as an identifier because it begins with disallowed character "$".
+
+Invalid name in long variable name record.  "#Invalid" may not be used as an identifier because it begins with disallowed character "#".
+
+Duplicate long variable name LONGVARIABLENAME.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│4│
+╰─────────┴─╯
+
+╭────────────────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│                │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────────────────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│LONGVARI        │       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+│LongVariableName│       2│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+│LONGVA_B        │       3│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+│LONGVA_C        │       4│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────────────────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/duplicate_long_variable_name.sack b/rust/pspp/src/sys/testdata/duplicate_long_variable_name.sack
new file mode 100644 (file)
index 0000000..cf1762e
--- /dev/null
@@ -0,0 +1,24 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 4; 1; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "LONGVARI";
+2; 0; 0; 0; 0x050800 *2; s8 "LONGVA_A";
+2; 0; 0; 0; 0x050800 *2; s8 "LONGVA_B";
+2; 0; 0; 0; 0x050800 *2; s8 "LONGVA_C";
+
+# 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;
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/duplicate_value_labels_type.expected b/rust/pspp/src/sys/testdata/duplicate_value_labels_type.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/duplicate_value_labels_type.sack b/rust/pspp/src/sys/testdata/duplicate_value_labels_type.sack
new file mode 100644 (file)
index 0000000..e98c2ec
--- /dev/null
@@ -0,0 +1,17 @@
+# 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;
+
+# Variables.
+2; 6; 0; 0; 0x010600 *2; s8 "STR1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# 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<<;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.expected b/rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.sack b/rust/pspp/src/sys/testdata/fewer_data_records_than_indicated_by_file_header.sack
new file mode 100644 (file)
index 0000000..e3ccb62
--- /dev/null
@@ -0,0 +1,18 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 2; 0; 0; >>5<<; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Data.
+999; 0;
+1.0; 2.0;
+3.0; 4.0;
+5.0; 6.0;
+7.0; 8.0;
+# Missing record here.
diff --git a/rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.expected b/rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.sack b/rust/pspp/src/sys/testdata/integer_overflows_in_long_string_missing_values.sack
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/missing_attribute_value.expected b/rust/pspp/src/sys/testdata/missing_attribute_value.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/missing_attribute_value.sack b/rust/pspp/src/sys/testdata/missing_attribute_value.sack
new file mode 100644 (file)
index 0000000..50d6eb7
--- /dev/null
@@ -0,0 +1,23 @@
+# 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;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
+
+# Data file attributes record.
+7; 17; 1; COUNT (
+"Attr1("
+);
+
+# Variable attributes record.
+7; 18; 1; COUNT (
+"FIRSTVAR:";
+  "fred('23'"; i8 10
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.expected b/rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.expected
new file mode 100644 (file)
index 0000000..ca11450
--- /dev/null
@@ -0,0 +1,20 @@
+Multiple response set $a has only one variable.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.sack b/rust/pspp/src/sys/testdata/missing_newline_after_variable_name_in_mrsets.sack
new file mode 100644 (file)
index 0000000..4c0ef69
--- /dev/null
@@ -0,0 +1,14 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Multiple response sets.
+7; 7; 1; COUNT("$a=C 0  NUM1"; i8 10);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/missing_type_4_record.expected b/rust/pspp/src/sys/testdata/missing_type_4_record.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/missing_type_4_record.sack b/rust/pspp/src/sys/testdata/missing_type_4_record.sack
new file mode 100644 (file)
index 0000000..f3f8204
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variable.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Value label with missing type 4 record.
+3; 1; 1.0; i8 3; s7 "one";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+>>999; 0<<;
diff --git a/rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.expected b/rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.expected
new file mode 100644 (file)
index 0000000..b9a1e3a
--- /dev/null
@@ -0,0 +1,21 @@
+Multiple response set $a contains both string and numeric variables.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│2│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+│str1│       2│     │Nominal          │Input│    8│Left     │A8          │A8          │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.sack b/rust/pspp/src/sys/testdata/mixed_variable_types_in_mrsets.sack
new file mode 100644 (file)
index 0000000..42981c0
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 8; 0; 0; 0x010800 *2; s8 "STR1";
+
+# Multiple response sets.
+7; 7; 1; COUNT("$a=C 0  NUM1 STR1"; i8 10);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.expected b/rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.sack b/rust/pspp/src/sys/testdata/null_dereference_skipping_bad_extension_record_18.sack
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/partial_compressed_data_record.expected b/rust/pspp/src/sys/testdata/partial_compressed_data_record.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/partial_compressed_data_record.sack b/rust/pspp/src/sys/testdata/partial_compressed_data_record.sack
new file mode 100644 (file)
index 0000000..a05dd8b
--- /dev/null
@@ -0,0 +1,29 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+1; # Compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# Compressed data.
+i8 1 100 254 253 254 253; i8 255 251; "abcdefgh"; s8 "0123";
diff --git a/rust/pspp/src/sys/testdata/partial_data_record_between_variables.expected b/rust/pspp/src/sys/testdata/partial_data_record_between_variables.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/partial_data_record_between_variables.sack b/rust/pspp/src/sys/testdata/partial_data_record_between_variables.sack
new file mode 100644 (file)
index 0000000..cebd9a9
--- /dev/null
@@ -0,0 +1,15 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 2; 0; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Data.
+999; 0;
+1.0; 2.0;
+3.0;
diff --git a/rust/pspp/src/sys/testdata/partial_data_record_within_long_string.expected b/rust/pspp/src/sys/testdata/partial_data_record_within_long_string.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/partial_data_record_within_long_string.sack b/rust/pspp/src/sys/testdata/partial_data_record_within_long_string.sack
new file mode 100644 (file)
index 0000000..d69a9cb
--- /dev/null
@@ -0,0 +1,15 @@
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; 2; 0; 0; -1; 100.0; "01 Jan 11"; "20:53:52"; s64 ""; i8 0 *3;
+
+# Numeric variables.
+2; 14; 0; 0; 0x010e00 *2; s8 "STR14";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Data.
+999; 0;
+s14 "one data item";
+s8 "partial";
diff --git a/rust/pspp/src/sys/testdata/too_many_value_labels.expected b/rust/pspp/src/sys/testdata/too_many_value_labels.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/too_many_value_labels.sack b/rust/pspp/src/sys/testdata/too_many_value_labels.sack
new file mode 100644 (file)
index 0000000..190abcc
--- /dev/null
@@ -0,0 +1,7 @@
+# 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;
+
+# Numeric variable.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+3; >>0x7fffffff<<;
diff --git a/rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.expected b/rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.sack b/rust/pspp/src/sys/testdata/type_4_record_names_long_string_variable.sack
new file mode 100644 (file)
index 0000000..01463d4
--- /dev/null
@@ -0,0 +1,16 @@
+# 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;
+
+# Long string variable.
+2; 9; 0; 0; 0x010900 *2; s8 "STR1";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Value label that names long string variable.
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 1; >>1<<;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/unquoted_attribute_value.expected b/rust/pspp/src/sys/testdata/unquoted_attribute_value.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/unquoted_attribute_value.sack b/rust/pspp/src/sys/testdata/unquoted_attribute_value.sack
new file mode 100644 (file)
index 0000000..ac0274b
--- /dev/null
@@ -0,0 +1,24 @@
+# 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;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "FIRSTVAR";
+
+# Data file attributes record.
+7; 17; 1; COUNT (
+"Attr1(value"; i8 10;
+")"
+);
+
+# Variable attributes record.
+7; 18; 1; COUNT (
+"FIRSTVAR:";
+  "fred(23"; i8 10; ")"
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.expected b/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.sack b/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_be_in_correct_range.sack
new file mode 100644 (file)
index 0000000..537f511
--- /dev/null
@@ -0,0 +1,18 @@
+# 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;
+
+# Variables.
+2; 6; 0; 0; 0x010600 *2; s8 "STR1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# 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;<<
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.expected b/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.sack b/rust/pspp/src/sys/testdata/value_label_variable_indexes_must_not_be_long_string_continuation.sack
new file mode 100644 (file)
index 0000000..eb9c088
--- /dev/null
@@ -0,0 +1,16 @@
+# 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;
+
+# Long string variable.
+2; 9; 0; 0; 0x010900 *2; s8 "STR1";
+(2; -1; 0; 0; 0; 0; s8 "");
+
+# Value label with long string indexes.
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 1; >>2;<<
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.expected b/rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.sack b/rust/pspp/src/sys/testdata/value_label_with_no_associated_variables.sack
new file mode 100644 (file)
index 0000000..c0bf70b
--- /dev/null
@@ -0,0 +1,9 @@
+# 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;
+
+# Numeric variable.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Value label with no variables.
+3; 1; 1.0; i8 3; s7 "one"; 4; >>0<<;
diff --git a/rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.expected b/rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.sack b/rust/pspp/src/sys/testdata/variables_for_value_label_must_all_be_same_type.sack
new file mode 100644 (file)
index 0000000..ff505af
--- /dev/null
@@ -0,0 +1,16 @@
+# 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;
+
+# Variables.
+2; 6; 0; 0; 0x010600 *2; s8 "STR1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Value label that names numeric and string variables.
+3; 1; s8 "xyzzy"; i8 3; s7 "one"; 4; 2; >>1; 2<<;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/wrong_display_alignment.expected b/rust/pspp/src/sys/testdata/wrong_display_alignment.expected
new file mode 100644 (file)
index 0000000..5a47058
--- /dev/null
@@ -0,0 +1,20 @@
+Invalid variable display alignment value 4294967295
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │Nominal          │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/wrong_display_alignment.sack b/rust/pspp/src/sys/testdata/wrong_display_alignment.sack
new file mode 100644 (file)
index 0000000..3aa887a
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Display parameters record.
+7; 11; 4; 2; 1; >>-1<<;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/wrong_display_measurement_level.expected b/rust/pspp/src/sys/testdata/wrong_display_measurement_level.expected
new file mode 100644 (file)
index 0000000..4dc2ab1
--- /dev/null
@@ -0,0 +1,20 @@
+Invalid variable measurement level value 4
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Left     │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/wrong_display_measurement_level.sack b/rust/pspp/src/sys/testdata/wrong_display_measurement_level.sack
new file mode 100644 (file)
index 0000000..1334ac7
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Display parameters record.
+7; 11; 4; 2; >>4<<; 0;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/wrong_display_parameter_count.expected b/rust/pspp/src/sys/testdata/wrong_display_parameter_count.expected
new file mode 100644 (file)
index 0000000..99a2db9
--- /dev/null
@@ -0,0 +1,20 @@
+Variable display record contains 4 items but should contain either 2 or 3.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/wrong_display_parameter_count.sack b/rust/pspp/src/sys/testdata/wrong_display_parameter_count.sack
new file mode 100644 (file)
index 0000000..6a5f007
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Display parameters record.
+7; 11; 4; >>4<<; 1; 1; 2; 2;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/wrong_display_parameter_size.expected b/rust/pspp/src/sys/testdata/wrong_display_parameter_size.expected
new file mode 100644 (file)
index 0000000..1fc8ac5
--- /dev/null
@@ -0,0 +1,20 @@
+At offset 0xe0, variable display record has bad size 8 bytes instead of the expected 4.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/wrong_display_parameter_size.sack b/rust/pspp/src/sys/testdata/wrong_display_parameter_size.sack
new file mode 100644 (file)
index 0000000..dcec8c4
--- /dev/null
@@ -0,0 +1,15 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Display parameters record.
+7; 11; >>8<<; 2; 1.0; 1.0;
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# End of dictionary.
+999; 0;
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.expected b/rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.sack b/rust/pspp/src/sys/testdata/zcompressed_data_bad_zheader_ofs.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.expected b/rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.sack b/rust/pspp/src/sys/testdata/zcompressed_data_bad_ztrailer_ofs.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.expected b/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.sack b/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_don_t_add_up.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.expected b/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.sack b/rust/pspp/src/sys/testdata/zcompressed_data_compressed_sizes_dont_add_up.sack
new file mode 100644 (file)
index 0000000..f74d0e8
--- /dev/null
@@ -0,0 +1,52 @@
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x1ac;    # ztrailer_ofs
+i64 72;       # ztrailer_len
+
+# This is where the ZLIB data blocks would go, but we don't need any to
+# provoke this message so we omit them.
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+2;            # n_blocks
+
+# ZLIB block descriptor 1:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+0x100000;     # uncompressed_size
+0x12345;      # compressed_size
+
+# ZLIB block descriptor 2:
+i64 0x100194; # uncompressed_ofs
+i64 0x12421;  # compressed_ofs
+0x100000;     # uncompressed_size
+0x12345;      # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.expected b/rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.sack b/rust/pspp/src/sys/testdata/zcompressed_data_compression_expands_data_too_much.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.expected b/rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.sack b/rust/pspp/src/sys/testdata/zcompressed_data_invalid_ztrailer_len.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.expected b/rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.sack b/rust/pspp/src/sys/testdata/zcompressed_data_uncompressed_size_block_size.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_block_size.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_compressed_ofs.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_n_blocks.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_uncompressed_ofs.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_bias.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_len.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.expected b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.sack b/rust/pspp/src/sys/testdata/zcompressed_data_wrong_ztrailer_zero.sack
new file mode 100644 (file)
index 0000000..bbe7020
--- /dev/null
@@ -0,0 +1,63 @@
+
+# File header.
+"$FL3"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+2; # zlib compressed
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# ZLIB data header.
+i64 0x194;    # zheader_ofs
+i64 0x205;    # ztrailer_ofs
+i64 48;       # ztrailer_len
+
+# ZLIB data block.
+#
+# This is the compressed form of:
+#
+# 01 64 fe fd fe fd ff fb  61 62 63 64 65 66 67 68  |.d......abcdefgh|
+# 30 31 32 33 20 20 20 20  fd fd fd fe 65 66 fd fd  |0123    ....ef..|
+# 6a 6b 6c 6d 20 20 20 20  6e 6f 70 71 72 73 74 75  |jklm    nopqrstu|
+# 76 77 78 79 7a 41 42 43  44 45 46 47 20 20 20 20  |vwxyzABCDEFG    |
+# 48 49 4a 4b 4c 4d 4e 4f  fe fd fc 00 00 00 00 00  |HIJKLMNO........|
+# 50 51 52 53 54 55 56 57                           |PQRSTUVW|
+#
+# which is the data from the "compressed data" test.
+hex "78 01 63 4c f9 f7 f7 df  df ff bf 13 93 92 53 52";
+hex "d3 d2 33 0c 0c 8d 8c 15  80 e0 ef df bf ff 52 d3";
+hex "fe fe cd ca ce c9 05 f1  f3 f2 0b 0a 8b 8a 4b 4a";
+hex "cb ca 2b 2a ab 1c 9d 9c  5d 5c dd dc 41 e2 1e 9e";
+hex "5e de 3e be 7e fe ff fe  fe 61 00 81 80 c0 a0 e0";
+hex "90 d0 b0 70 00 0f 3f 23  d7";
+
+# ZLIB data trailer fixed header:
+i64 -100;     # ztrailer_bias
+i64 0;        # ztrailer_zero
+0x3ff000;     # block_size
+1;            # n_blocks
+
+# ZLIB block descriptor:
+i64 0x194;    # uncompressed_ofs
+i64 0x1ac;    # compressed_ofs
+88;           # uncompressed_size
+89;           # compressed_size
diff --git a/rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.expected b/rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.expected
new file mode 100644 (file)
index 0000000..098e534
--- /dev/null
@@ -0,0 +1,22 @@
+Multiple response set $a has only one variable.
+
+Multiple response set $b has no variables.
+
+╭──────────────────────┬────────────────────────╮
+│       Created        │    01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product        │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│       Compression    │SAV                     │
+│       Number of Cases│Unknown                 │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬─╮
+│Variables│1│
+╰─────────┴─╯
+
+╭────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│    │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1│       1│     │                 │Input│    8│Right    │F8.0        │F8.0        │              │
+╰────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
diff --git a/rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.sack b/rust/pspp/src/sys/testdata/zero_or_one_variable_in_mrset.sack
new file mode 100644 (file)
index 0000000..4f74156
--- /dev/null
@@ -0,0 +1,14 @@
+# 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;
+
+# Numeric variable, no label or missing values.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+
+# Multiple response sets.
+7; 7; 1; COUNT("$a=C 0  NUM1"; i8 10; "$b=C 0  "; i8 10);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+999; 0;