From: Ben Pfaff Date: Sat, 30 Dec 2023 19:16:29 +0000 (-0800) Subject: compiles X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55c50f4539128d520f9517abd3c40d38b3b39519;p=pspp compiles --- diff --git a/rust/src/cooked.rs b/rust/src/cooked.rs index b7802e91cd..3e4677e71c 100644 --- a/rust/src/cooked.rs +++ b/rust/src/cooked.rs @@ -8,7 +8,7 @@ use crate::{ endian::Endian, format::{Error as FormatError, Spec, UncheckedSpec}, identifier::{Error as IdError, Identifier}, - raw::{self, RawDocumentLine, RawStr, RawString, VarDisplayRecord, VarType, ProductInfoRecord}, + raw::{self, ProductInfoRecord, RawDocumentLine, RawStr, RawString, VarDisplayRecord, VarType}, }; use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; use encoding_rs::{DecoderResult, Encoding}; @@ -214,7 +214,7 @@ struct Headers<'a> { float_info: Option<&'a raw::FloatInfoRecord>, variable_sets: Vec<&'a raw::VariableSetRecord>, var_display: Option<&'a raw::VarDisplayRecord>, - multiple_response: Vec<&'a raw::MultipleResponseRecord>, + multiple_response: Vec<&'a raw::MultipleResponseRecord>, long_string_value_labels: Vec<&'a raw::LongStringValueLabelRecord>, long_string_missing_values: Vec<&'a raw::LongStringMissingValueRecord>>, encoding: Option<&'a raw::EncodingRecord>, @@ -271,7 +271,6 @@ impl<'a> Headers<'a> { raw::Record::ZTrailer(_) => (), raw::Record::Cases(record) => set_or_warn(&mut h.cases, record, warn), raw::Record::Text(_) => todo!(), - } } h @@ -339,82 +338,82 @@ pub fn decode( if let Some(raw) = h.number_of_cases { output.push(Record::NumberOfCases(raw.clone())) } -/* - for &raw in &h.file_attributes { - let s = decoder.decode_string_cow(&raw.text.0, warn); - output.push(Record::FileAttributes(FileAttributeRecord::parse( - &decoder, &s, warn, - )?)); - } - for &raw in &h.other_extensions { - output.push(Record::OtherExtension(raw.clone())); - } - // Decode the variable records, which are the basis of almost everything - // else. - for &raw in &h.variables { - if let Some(variable) = VariableRecord::try_decode(&mut decoder, raw, warn)? { - output.push(Record::Variable(variable)); + /* + for &raw in &h.file_attributes { + let s = decoder.decode_string_cow(&raw.text.0, warn); + output.push(Record::FileAttributes(FileAttributeRecord::parse( + &decoder, &s, warn, + )?)); + } + for &raw in &h.other_extensions { + output.push(Record::OtherExtension(raw.clone())); + } + // Decode the variable records, which are the basis of almost everything + // else. + for &raw in &h.variables { + if let Some(variable) = VariableRecord::try_decode(&mut decoder, raw, warn)? { + output.push(Record::Variable(variable)); + } } - } - // Decode value labels and weight variable. These use indexes into the - // variable records, so we need to parse them before those indexes become - // invalidated by very long string variables. - for &raw in &h.value_labels { - if let Some(value_label) = ValueLabelRecord::try_decode(&mut decoder, raw, warn)? { - output.push(Record::ValueLabel(value_label)); + // Decode value labels and weight variable. These use indexes into the + // variable records, so we need to parse them before those indexes become + // invalidated by very long string variables. + for &raw in &h.value_labels { + if let Some(value_label) = ValueLabelRecord::try_decode(&mut decoder, raw, warn)? { + output.push(Record::ValueLabel(value_label)); + } + } + // XXX weight + if let Some(raw) = h.var_display { + output.push(Record::VarDisplay(raw.clone())); } - } - // XXX weight - if let Some(raw) = h.var_display { - output.push(Record::VarDisplay(raw.clone())); - } - // Decode records that use short names. - for &raw in &h.multiple_response { - if let Some(mrr) = MultipleResponseRecord::try_decode(&mut decoder, raw, warn)? { - output.push(Record::MultipleResponse(mrr)) + // Decode records that use short names. + for &raw in &h.multiple_response { + if let Some(mrr) = MultipleResponseRecord::try_decode(&mut decoder, raw, warn)? { + output.push(Record::MultipleResponse(mrr)) + } } + for &raw in &h.very_long_strings { + let s = decoder.decode_string_cow(&raw.text.0, warn); + output.push(Record::VeryLongStrings(VeryLongStringRecord::parse( + &decoder, &s, warn, + )?)); } - for &raw in &h.very_long_strings { - let s = decoder.decode_string_cow(&raw.text.0, warn); - output.push(Record::VeryLongStrings(VeryLongStringRecord::parse( - &decoder, &s, warn, - )?)); - } - // Rename variables to their long names. - for &raw in &h.long_names { - let s = decoder.decode_string_cow(&raw.text.0, warn); - output.push(Record::LongNames(LongNameRecord::parse( - &mut decoder, - &s, - warn, - )?)); - } + // Rename variables to their long names. + for &raw in &h.long_names { + let s = decoder.decode_string_cow(&raw.text.0, warn); + output.push(Record::LongNames(LongNameRecord::parse( + &mut decoder, + &s, + warn, + )?)); + } - // Decode recods that use long names. - for &raw in &h.variable_attributes { - let s = decoder.decode_string_cow(&raw.text.0, warn); - output.push(Record::VariableAttributes(VariableAttributeRecord::parse( - &decoder, &s, warn, - )?)); - } - for &raw in &h.long_string_value_labels { - if let Some(mrr) = LongStringValueLabelRecord::try_decode(&mut decoder, raw, warn)? { - output.push(Record::LongStringValueLabels(mrr)) + // Decode recods that use long names. + for &raw in &h.variable_attributes { + let s = decoder.decode_string_cow(&raw.text.0, warn); + output.push(Record::VariableAttributes(VariableAttributeRecord::parse( + &decoder, &s, warn, + )?)); } - } - for &raw in &h.long_string_missing_values { - if let Some(mrr) = LongStringMissingValuesRecord::try_decode(&mut decoder, raw, warn)? { - output.push(Record::LongStringMissingValues(mrr)) + for &raw in &h.long_string_value_labels { + if let Some(mrr) = LongStringValueLabelRecord::try_decode(&mut decoder, raw, warn)? { + output.push(Record::LongStringValueLabels(mrr)) + } } - } - for &raw in &h.variable_sets { - let s = decoder.decode_string_cow(&raw.text.0, warn); - output.push(Record::VariableSets(VariableSetRecord::parse(&s, warn)?)); - } -*/ + for &raw in &h.long_string_missing_values { + if let Some(mrr) = LongStringMissingValuesRecord::try_decode(&mut decoder, raw, warn)? { + output.push(Record::LongStringMissingValues(mrr)) + } + } + for &raw in &h.variable_sets { + let s = decoder.decode_string_cow(&raw.text.0, warn); + output.push(Record::VariableSets(VariableSetRecord::parse(&s, warn)?)); + } + */ Ok(output) } @@ -1218,21 +1217,12 @@ pub struct MultipleResponseSet { impl MultipleResponseSet { fn decode( decoder: &Decoder, - input: &raw::MultipleResponseSet>, + input: &raw::MultipleResponseSet>, warn: &impl Fn(Error), ) -> Result { - let mr_set_name = - Identifier::new(&input.name, decoder.encoding).map_err(Error::InvalidMrSetName)?; - + let mr_set_name = input.name.clone(); let mut dict_indexes = Vec::with_capacity(input.short_names.len()); for short_name in input.short_names.iter() { - let short_name = match Identifier::new(&short_name, decoder.encoding) { - Ok(name) => name, - Err(error) => { - warn(Error::InvalidMrSetName(error)); - continue; - } - }; let Some(&dict_index) = decoder.var_names.get(&short_name) else { warn(Error::UnknownMrSetVariable { mr_set: mr_set_name.clone(), @@ -1276,7 +1266,7 @@ impl MultipleResponseSet { pub struct MultipleResponseRecord(pub Vec); impl TryDecode for MultipleResponseRecord { - type Input<'a> = raw::MultipleResponseRecord>; + type Input<'a> = raw::MultipleResponseRecord>; fn try_decode( decoder: &mut Decoder, diff --git a/rust/src/raw.rs b/rust/src/raw.rs index ba7124a385..544481906f 100644 --- a/rust/src/raw.rs +++ b/rust/src/raw.rs @@ -179,6 +179,12 @@ pub enum Error { #[error("Invalid variable name in variable set record. {0}")] InvalidVariableSetName(IdError), + #[error("Invalid multiple response set name. {0}")] + InvalidMrSetName(IdError), + + #[error("Invalid multiple response set variable name. {0}")] + InvalidMrSetVariableName(IdError), + #[error("Details TBD")] TBD, } @@ -193,7 +199,7 @@ pub enum Record { FloatInfo(FloatInfoRecord), VariableSets(VariableSetRecord), VarDisplay(VarDisplayRecord), - MultipleResponse(MultipleResponseRecord), + MultipleResponse(MultipleResponseRecord), LongStringValueLabels(LongStringValueLabelRecord), LongStringMissingValues(LongStringMissingValueRecord>), Encoding(EncodingRecord), @@ -1643,17 +1649,18 @@ impl MultipleResponseType { } #[derive(Clone, Debug)] -pub struct MultipleResponseSet +pub struct MultipleResponseSet where + I: Debug, S: Debug, { - pub name: S, + pub name: I, pub label: S, pub mr_type: MultipleResponseType, - pub short_names: Vec, + pub short_names: Vec, } -impl MultipleResponseSet { +impl MultipleResponseSet { fn parse(input: &[u8]) -> Result<(Self, &[u8]), Error> { let Some(equals) = input.iter().position(|&b| b == b'=') else { return Err(Error::TBD); @@ -1694,22 +1701,38 @@ impl MultipleResponseSet { )) } - fn decode<'a>(&'a self, decoder: &Decoder) -> MultipleResponseSet> { - MultipleResponseSet { - name: decoder.decode(&self.name), + fn decode<'a>( + &'a self, + decoder: &Decoder, + ) -> Result>, Error> { + let mut short_names = Vec::with_capacity(self.short_names.len()); + for short_name in self.short_names.iter() { + if let Some(short_name) = decoder + .decode_identifier(short_name) + .map_err(|err| Error::InvalidMrSetName(err)) + .warn_on_error(&decoder.warn) + { + short_names.push(short_name); + } + } + Ok(MultipleResponseSet { + name: decoder + .decode_identifier(&self.name) + .map_err(|err| Error::InvalidMrSetVariableName(err))?, label: decoder.decode(&self.label), mr_type: self.mr_type.clone(), - short_names: self.short_names.iter().map(|s| decoder.decode(s)).collect(), - } + short_names: short_names, + }) } } #[derive(Clone, Debug)] -pub struct MultipleResponseRecord(pub Vec>) +pub struct MultipleResponseRecord(pub Vec>) where + I: Debug, S: Debug; -impl ExtensionRecord for MultipleResponseRecord { +impl ExtensionRecord for MultipleResponseRecord { const SUBTYPE: u32 = 7; const SIZE: Option = Some(1); const COUNT: Option = None; @@ -1729,9 +1752,15 @@ impl ExtensionRecord for MultipleResponseRecord { } } -impl MultipleResponseRecord { - fn decode<'a>(&'a self, decoder: &Decoder) -> MultipleResponseRecord> { - MultipleResponseRecord(self.0.iter().map(|set| set.decode(decoder)).collect()) +impl MultipleResponseRecord { + fn decode<'a>(&'a self, decoder: &Decoder) -> MultipleResponseRecord> { + let mut sets = Vec::new(); + for set in self.0.iter() { + if let Some(set) = set.decode(decoder).warn_on_error(&decoder.warn) { + sets.push(set); + } + } + MultipleResponseRecord(sets) } }