From 8251cd2dc1e55919381fc9468b36659338ac433d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 25 Mar 2025 15:15:13 -0700 Subject: [PATCH] Add PIBHEX, PIB, RB tests. --- rust/pspp/src/endian.rs | 11 +- rust/pspp/src/format/display.rs | 79 ++- rust/pspp/src/format/testdata/pibhex.txt | 544 +++++++++--------- rust/pspp/src/format/testdata/rb.txt | 136 +++++ .../testdata/split-binhex-out.expected.py | 8 +- rust/pspp/src/settings.rs | 15 +- 6 files changed, 494 insertions(+), 299 deletions(-) create mode 100644 rust/pspp/src/format/testdata/rb.txt diff --git a/rust/pspp/src/endian.rs b/rust/pspp/src/endian.rs index ae3cd99c14..d35b7daead 100644 --- a/rust/pspp/src/endian.rs +++ b/rust/pspp/src/endian.rs @@ -5,21 +5,18 @@ use smallvec::SmallVec; /// SPSS system files can declare IBM 370 and DEC VAX floating-point /// representations, but no file that uses either of these has ever been found /// in the wild, so this code does not handle them. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] pub enum Endian { /// Big-endian: MSB at lowest address. + #[cfg_attr(target_endian = "big", default)] Big, /// Little-endian: LSB at lowest address. + #[cfg_attr(target_endian = "little", default)] Little, } impl Endian { - #[cfg(target_endian = "big")] - pub const NATIVE: Endian = Endian::Big; - #[cfg(target_endian = "little")] - pub const NATIVE: Endian = Endian::Little; - pub fn identify_u32(expected_value: u32, bytes: [u8; 4]) -> Option { let as_big: u32 = Endian::Big.parse(bytes); let as_little: u32 = Endian::Little.parse(bytes); @@ -40,7 +37,7 @@ impl Endian { } } - pub fn to_smallvec(self, mut value: u64, n: usize) -> SmallVec<[u8; 16]> { + pub fn to_smallvec(self, mut value: u64, n: usize) -> SmallVec<[u8; N]> { debug_assert!(n <= 8); let mut vec = SmallVec::new(); value <<= 8 * (8 - n); diff --git a/rust/pspp/src/format/display.rs b/rust/pspp/src/format/display.rs index ca1545240a..647e258daf 100644 --- a/rust/pspp/src/format/display.rs +++ b/rust/pspp/src/format/display.rs @@ -14,13 +14,15 @@ use smallvec::{Array, SmallVec}; use crate::{ calendar::{calendar_offset_to_gregorian, day_of_year, month_name, short_month_name}, dictionary::Value, + endian::ToBytes, format::{Category, Decimal, Format, NumberStyle, Settings, Type}, - settings::Settings as PsppSettings, + settings::{EndianSettings, Settings as PsppSettings}, }; pub struct DisplayValue<'a, 'b> { format: Format, settings: &'b Settings, + endian: EndianSettings, value: &'a Value, encoding: &'static Encoding, } @@ -82,16 +84,21 @@ impl<'a, 'b> Display for DisplayValue<'a, 'b> { impl<'a, 'b> DisplayValue<'a, 'b> { pub fn new(format: Format, value: &'a Value, encoding: &'static Encoding) -> Self { + let settings = PsppSettings::global(); Self { format, value, encoding, - settings: &PsppSettings::global().formats, + settings: &settings.formats, + endian: settings.endian, } } pub fn with_settings(self, settings: &'b Settings) -> Self { Self { settings, ..self } } + pub fn with_endian(self, endian: EndianSettings) -> Self { + Self { endian, ..self } + } fn fmt_binary(&self, f: &mut Formatter) -> FmtResult { let output = self.to_binary().unwrap(); for b in output { @@ -561,6 +568,8 @@ impl<'a, 'b> DisplayValue<'a, 'b> { Type::P => Some(self.p(number)), Type::PK => Some(self.pk(number)), Type::IB => Some(self.ib(number)), + Type::PIB => Some(self.pib(number)), + Type::RB => Some(self.rb(number)), _ => None, } } @@ -630,10 +639,32 @@ impl<'a, 'b> DisplayValue<'a, 'b> { } else { integer }; - PsppSettings::global() + self.endian + .output_integer_format + .to_smallvec(integer, self.format.w()) + } + + fn pib(&self, number: Option) -> SmallVec<[u8; 16]> { + let number = number.map_or(0.0, |number| (number * power10(self.format.d())).round()); + let number = if number >= power256(self.format.w) || number < 0.0 { + 0.0 + } else { + number + }; + let integer = number.abs() as u64; + self.endian .output_integer_format .to_smallvec(integer, self.format.w()) } + + fn rb(&self, number: Option) -> SmallVec<[u8; 16]> { + let number = number.unwrap_or(-f64::MAX); + let bytes: [u8; 8] = self.endian.output_float_format.to_bytes(number); + let mut vec = SmallVec::new(); + vec.extend_from_slice(&bytes); + vec.resize(self.format.w(), 0); + vec + } } struct LegacyFormat { @@ -1023,13 +1054,14 @@ mod test { use crate::{ dictionary::Value, + endian::Endian, format::{AbstractFormat, Format, Settings, Type, UncheckedFormat, CC}, lex::{ scan::StringScanner, segment::Syntax, token::{Punct, Token}, }, - settings::Settings as PsppSettings, + settings::EndianSettings, }; fn test(name: &str) { @@ -1043,7 +1075,7 @@ mod test { .with_cc(CC::C, "((,[,],))".parse().unwrap()) .with_cc(CC::D, ",XXX,,-".parse().unwrap()) .with_cc(CC::E, ",,YYY,-".parse().unwrap()); - let mut value = 0.0; + let mut value = Some(0.0); let mut value_name = String::new(); for (line_number, line) in input.lines().map(|r| r.unwrap()).enumerate() { let line = line.trim(); @@ -1056,13 +1088,17 @@ mod test { value = if let Some(Token::Punct(Punct::Exp)) = tokens.get(1) { assert_eq!(tokens.len(), 3); let exponent = tokens[2].as_number().unwrap(); - number.powf(exponent) + Some(number.powf(exponent)) } else { assert_eq!(tokens.len(), 1); - *number + Some(*number) }; value_name = String::from(line); } + Token::End => { + value = None; + value_name = String::from(line); + } Token::Id(id) => { let format: UncheckedFormat = id.0.as_str() @@ -1073,7 +1109,7 @@ mod test { let format: Format = format.try_into().unwrap(); assert_eq!(tokens.get(1), Some(&Token::Punct(Punct::Colon))); let expected = tokens[2].as_string().unwrap(); - let actual = Value::Number(Some(value)) + let actual = Value::Number(value) .display(format, UTF_8) .with_settings(&settings) .to_string(); @@ -1154,6 +1190,11 @@ mod test { test("cce.txt"); } + #[test] + fn pibhex() { + test("pibhex.txt"); + } + #[test] fn leading_zeros() { struct Test { @@ -1227,6 +1268,11 @@ mod test { let mut value = None; let mut value_name = String::new(); + let endian = EndianSettings { + output_integer_format: Endian::Big, + output_float_format: Endian::Big, + ..EndianSettings::default() + }; for (line_number, line) in input.lines().map(|r| r.unwrap()).enumerate() { let line = line.trim(); let line_number = line_number + 1; @@ -1255,6 +1301,7 @@ mod test { let mut actual = SmallVec::<[u8; 16]>::new(); Value::Number(value) .display(format, UTF_8) + .with_endian(endian) .write(&mut actual, UTF_8) .unwrap(); let mut actual_s = SmallString::<[u8; 32]>::new(); @@ -1274,17 +1321,27 @@ mod test { } #[test] - fn test_p() { + fn p() { test_binhex("p.txt"); } #[test] - fn test_pk() { + fn pk() { test_binhex("pk.txt"); } #[test] - fn test_ib() { + fn ib() { test_binhex("ib.txt"); } + + #[test] + fn pib() { + test_binhex("pib.txt"); + } + + #[test] + fn rb() { + test_binhex("rb.txt"); + } } diff --git a/rust/pspp/src/format/testdata/pibhex.txt b/rust/pspp/src/format/testdata/pibhex.txt index 4c6a9ded68..23c50a803c 100644 --- a/rust/pspp/src/format/testdata/pibhex.txt +++ b/rust/pspp/src/format/testdata/pibhex.txt @@ -1,340 +1,340 @@ . -PIBHEX2: "b' '" -PIBHEX4: "b' '" -PIBHEX6: "b' '" -PIBHEX8: "b' '" +PIBHEX2: " ." +PIBHEX4: " ." +PIBHEX6: " ." +PIBHEX8: " ." 2 -PIBHEX2: "b'02'" -PIBHEX4: "b'0002'" -PIBHEX6: "b'000002'" -PIBHEX8: "b'00000002'" +PIBHEX2: "02" +PIBHEX4: "0002" +PIBHEX6: "000002" +PIBHEX8: "00000002" 11 -PIBHEX2: "b'0B'" -PIBHEX4: "b'000B'" -PIBHEX6: "b'00000B'" -PIBHEX8: "b'0000000B'" +PIBHEX2: "0B" +PIBHEX4: "000B" +PIBHEX6: "00000B" +PIBHEX8: "0000000B" 123 -PIBHEX2: "b'7B'" -PIBHEX4: "b'007B'" -PIBHEX6: "b'00007B'" -PIBHEX8: "b'0000007B'" +PIBHEX2: "7B" +PIBHEX4: "007B" +PIBHEX6: "00007B" +PIBHEX8: "0000007B" 1234 -PIBHEX2: "b'**'" -PIBHEX4: "b'04D2'" -PIBHEX6: "b'0004D2'" -PIBHEX8: "b'000004D2'" +PIBHEX2: "**" +PIBHEX4: "04D2" +PIBHEX6: "0004D2" +PIBHEX8: "000004D2" 913 -PIBHEX2: "b'**'" -PIBHEX4: "b'0391'" -PIBHEX6: "b'000391'" -PIBHEX8: "b'00000391'" +PIBHEX2: "**" +PIBHEX4: "0391" +PIBHEX6: "000391" +PIBHEX8: "00000391" 3.14159 -PIBHEX2: "b'03'" -PIBHEX4: "b'0003'" -PIBHEX6: "b'000003'" -PIBHEX8: "b'00000003'" +PIBHEX2: "03" +PIBHEX4: "0003" +PIBHEX6: "000003" +PIBHEX8: "00000003" 777 -PIBHEX2: "b'**'" -PIBHEX4: "b'0309'" -PIBHEX6: "b'000309'" -PIBHEX8: "b'00000309'" +PIBHEX2: "**" +PIBHEX4: "0309" +PIBHEX6: "000309" +PIBHEX8: "00000309" 82 -PIBHEX2: "b'52'" -PIBHEX4: "b'0052'" -PIBHEX6: "b'000052'" -PIBHEX8: "b'00000052'" +PIBHEX2: "52" +PIBHEX4: "0052" +PIBHEX6: "000052" +PIBHEX8: "00000052" 690 -PIBHEX2: "b'**'" -PIBHEX4: "b'02B2'" -PIBHEX6: "b'0002B2'" -PIBHEX8: "b'000002B2'" +PIBHEX2: "**" +PIBHEX4: "02B2" +PIBHEX6: "0002B2" +PIBHEX8: "000002B2" -2 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -11 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -123 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -1234 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -913 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -3.14159 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -777 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -82 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -690 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 9999.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'270F'" -PIBHEX6: "b'00270F'" -PIBHEX8: "b'0000270F'" +PIBHEX2: "**" +PIBHEX4: "270F" +PIBHEX6: "00270F" +PIBHEX8: "0000270F" 9999.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'2710'" -PIBHEX6: "b'002710'" -PIBHEX8: "b'00002710'" +PIBHEX2: "**" +PIBHEX4: "2710" +PIBHEX6: "002710" +PIBHEX8: "00002710" 9999.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'2710'" -PIBHEX6: "b'002710'" -PIBHEX8: "b'00002710'" +PIBHEX2: "**" +PIBHEX4: "2710" +PIBHEX6: "002710" +PIBHEX8: "00002710" 10000 -PIBHEX2: "b'**'" -PIBHEX4: "b'2710'" -PIBHEX6: "b'002710'" -PIBHEX8: "b'00002710'" +PIBHEX2: "**" +PIBHEX4: "2710" +PIBHEX6: "002710" +PIBHEX8: "00002710" 18231237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'01162FC5'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "01162FC5" -9999.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -9999.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -9999.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -10000 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -8231237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 999.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'03E7'" -PIBHEX6: "b'0003E7'" -PIBHEX8: "b'000003E7'" +PIBHEX2: "**" +PIBHEX4: "03E7" +PIBHEX6: "0003E7" +PIBHEX8: "000003E7" 999.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'03E8'" -PIBHEX6: "b'0003E8'" -PIBHEX8: "b'000003E8'" +PIBHEX2: "**" +PIBHEX4: "03E8" +PIBHEX6: "0003E8" +PIBHEX8: "000003E8" 999.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'03E8'" -PIBHEX6: "b'0003E8'" -PIBHEX8: "b'000003E8'" +PIBHEX2: "**" +PIBHEX4: "03E8" +PIBHEX6: "0003E8" +PIBHEX8: "000003E8" 1000 -PIBHEX2: "b'**'" -PIBHEX4: "b'03E8'" -PIBHEX6: "b'0003E8'" -PIBHEX8: "b'000003E8'" +PIBHEX2: "**" +PIBHEX4: "03E8" +PIBHEX6: "0003E8" +PIBHEX8: "000003E8" 8231237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'7D9945'" -PIBHEX8: "b'007D9945'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "7D9945" +PIBHEX8: "007D9945" -999.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -999.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -999.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -1000 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -8231237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 99.1 -PIBHEX2: "b'63'" -PIBHEX4: "b'0063'" -PIBHEX6: "b'000063'" -PIBHEX8: "b'00000063'" +PIBHEX2: "63" +PIBHEX4: "0063" +PIBHEX6: "000063" +PIBHEX8: "00000063" 99.5 -PIBHEX2: "b'64'" -PIBHEX4: "b'0064'" -PIBHEX6: "b'000064'" -PIBHEX8: "b'00000064'" +PIBHEX2: "64" +PIBHEX4: "0064" +PIBHEX6: "000064" +PIBHEX8: "00000064" 99.9 -PIBHEX2: "b'64'" -PIBHEX4: "b'0064'" -PIBHEX6: "b'000064'" -PIBHEX8: "b'00000064'" +PIBHEX2: "64" +PIBHEX4: "0064" +PIBHEX6: "000064" +PIBHEX8: "00000064" 100 -PIBHEX2: "b'64'" -PIBHEX4: "b'0064'" -PIBHEX6: "b'000064'" -PIBHEX8: "b'00000064'" +PIBHEX2: "64" +PIBHEX4: "0064" +PIBHEX6: "000064" +PIBHEX8: "00000064" 821237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'0C87F5'" -PIBHEX8: "b'000C87F5'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "0C87F5" +PIBHEX8: "000C87F5" -99.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -99.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -99.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -100 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -831237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 9.1 -PIBHEX2: "b'09'" -PIBHEX4: "b'0009'" -PIBHEX6: "b'000009'" -PIBHEX8: "b'00000009'" +PIBHEX2: "09" +PIBHEX4: "0009" +PIBHEX6: "000009" +PIBHEX8: "00000009" 9.5 -PIBHEX2: "b'0A'" -PIBHEX4: "b'000A'" -PIBHEX6: "b'00000A'" -PIBHEX8: "b'0000000A'" +PIBHEX2: "0A" +PIBHEX4: "000A" +PIBHEX6: "00000A" +PIBHEX8: "0000000A" 9.9 -PIBHEX2: "b'0A'" -PIBHEX4: "b'000A'" -PIBHEX6: "b'00000A'" -PIBHEX8: "b'0000000A'" +PIBHEX2: "0A" +PIBHEX4: "000A" +PIBHEX6: "00000A" +PIBHEX8: "0000000A" 10 -PIBHEX2: "b'0A'" -PIBHEX4: "b'000A'" -PIBHEX6: "b'00000A'" -PIBHEX8: "b'0000000A'" +PIBHEX2: "0A" +PIBHEX4: "000A" +PIBHEX6: "00000A" +PIBHEX8: "0000000A" 81237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'013D55'" -PIBHEX8: "b'00013D55'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "013D55" +PIBHEX8: "00013D55" -9.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -9.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -9.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -10 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" -81237 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 1.1 -PIBHEX2: "b'01'" -PIBHEX4: "b'0001'" -PIBHEX6: "b'000001'" -PIBHEX8: "b'00000001'" +PIBHEX2: "01" +PIBHEX4: "0001" +PIBHEX6: "000001" +PIBHEX8: "00000001" -1.1 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 1.5 -PIBHEX2: "b'02'" -PIBHEX4: "b'0002'" -PIBHEX6: "b'000002'" -PIBHEX8: "b'00000002'" +PIBHEX2: "02" +PIBHEX4: "0002" +PIBHEX6: "000002" +PIBHEX8: "00000002" -1.5 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" 1.9 -PIBHEX2: "b'02'" -PIBHEX4: "b'0002'" -PIBHEX6: "b'000002'" -PIBHEX8: "b'00000002'" +PIBHEX2: "02" +PIBHEX4: "0002" +PIBHEX6: "000002" +PIBHEX8: "00000002" -1.9 -PIBHEX2: "b'**'" -PIBHEX4: "b'****'" -PIBHEX6: "b'******'" -PIBHEX8: "b'********'" +PIBHEX2: "**" +PIBHEX4: "****" +PIBHEX6: "******" +PIBHEX8: "********" diff --git a/rust/pspp/src/format/testdata/rb.txt b/rust/pspp/src/format/testdata/rb.txt new file mode 100644 index 0000000000..d3fad7a579 --- /dev/null +++ b/rust/pspp/src/format/testdata/rb.txt @@ -0,0 +1,136 @@ +. +RB8: "ffefffffffffffff" +2 +RB8: "4000000000000000" +11 +RB8: "4026000000000000" +123 +RB8: "405ec00000000000" +1234 +RB8: "4093480000000000" +913 +RB8: "408c880000000000" +3.14159 +RB8: "400921f9f01b866e" +777 +RB8: "4088480000000000" +82 +RB8: "4054800000000000" +690 +RB8: "4085900000000000" +-2 +RB8: "c000000000000000" +-11 +RB8: "c026000000000000" +-123 +RB8: "c05ec00000000000" +-1234 +RB8: "c093480000000000" +-913 +RB8: "c08c880000000000" +-3.14159 +RB8: "c00921f9f01b866e" +-777 +RB8: "c088480000000000" +-82 +RB8: "c054800000000000" +-690 +RB8: "c085900000000000" +-.1 +RB8: "bfb999999999999a" +-.5 +RB8: "bfe0000000000000" +-.9 +RB8: "bfeccccccccccccd" +9999.1 +RB8: "40c3878ccccccccd" +9999.5 +RB8: "40c387c000000000" +9999.9 +RB8: "40c387f333333333" +10000 +RB8: "40c3880000000000" +18231237 +RB8: "417162fc50000000" +-9999.1 +RB8: "c0c3878ccccccccd" +-9999.5 +RB8: "c0c387c000000000" +-9999.9 +RB8: "c0c387f333333333" +-10000 +RB8: "c0c3880000000000" +-8231237 +RB8: "c15f665140000000" +999.1 +RB8: "408f38cccccccccd" +999.5 +RB8: "408f3c0000000000" +999.9 +RB8: "408f3f3333333333" +1000 +RB8: "408f400000000000" +8231237 +RB8: "415f665140000000" +-999.1 +RB8: "c08f38cccccccccd" +-999.5 +RB8: "c08f3c0000000000" +-999.9 +RB8: "c08f3f3333333333" +-1000 +RB8: "c08f400000000000" +-8231237 +RB8: "c15f665140000000" +99.1 +RB8: "4058c66666666666" +99.5 +RB8: "4058e00000000000" +99.9 +RB8: "4058f9999999999a" +100 +RB8: "4059000000000000" +821237 +RB8: "41290fea00000000" +-99.1 +RB8: "c058c66666666666" +-99.5 +RB8: "c058e00000000000" +-99.9 +RB8: "c058f9999999999a" +-100 +RB8: "c059000000000000" +-831237 +RB8: "c1295e0a00000000" +9.1 +RB8: "4022333333333333" +9.5 +RB8: "4023000000000000" +9.9 +RB8: "4023cccccccccccd" +10 +RB8: "4024000000000000" +81237 +RB8: "40f3d55000000000" +-9.1 +RB8: "c022333333333333" +-9.5 +RB8: "c023000000000000" +-9.9 +RB8: "c023cccccccccccd" +-10 +RB8: "c024000000000000" +-81237 +RB8: "c0f3d55000000000" +1.1 +RB8: "3ff199999999999a" +-1.1 +RB8: "bff199999999999a" +1.5 +RB8: "3ff8000000000000" +-1.5 +RB8: "bff8000000000000" +1.9 +RB8: "3ffe666666666666" +-1.9 +RB8: "bffe666666666666" diff --git a/rust/pspp/src/format/testdata/split-binhex-out.expected.py b/rust/pspp/src/format/testdata/split-binhex-out.expected.py index c7d5e87060..e57accaf0b 100644 --- a/rust/pspp/src/format/testdata/split-binhex-out.expected.py +++ b/rust/pspp/src/format/testdata/split-binhex-out.expected.py @@ -2,9 +2,10 @@ import sys import pathlib +import struct outputs = {} -for format in ["P", "PK", "IB", "PIB", "PIBHEX"]: +for format in ["P", "PK", "IB", "PIB", "PIBHEX", "RB"]: outputs[format] = open(format.lower() + '.txt', 'w') values = [ @@ -101,7 +102,10 @@ for value in values: outputs["PIB"].write(f"PIB{w}.{d}: \"{b[x:x + w].hex()}\"\n") x += w for w in [2,4,6,8]: - outputs["PIBHEX"].write(f"PIBHEX{w}: \"{b[x:x + w]}\"\n") + outputs["PIBHEX"].write(f"PIBHEX{w}: \"{b[x:x + w].decode('UTF-8')}\"\n") x += w + value = -sys.float_info.max if value == '.' else float(value) + outputs["RB"].write(f"RB8: \"{struct.pack('>d', value).hex()}\"\n") + ofs += 256 diff --git a/rust/pspp/src/settings.rs b/rust/pspp/src/settings.rs index ac41b22e64..966f26bd5b 100644 --- a/rust/pspp/src/settings.rs +++ b/rust/pspp/src/settings.rs @@ -38,9 +38,8 @@ impl Show { } } -pub struct Settings { - pub look: Arc, - +#[derive(Copy, Clone, Default, PartialEq, Eq)] +pub struct EndianSettings { /// Endianness for reading IB and PIB formats. pub input_integer_format: Endian, @@ -52,6 +51,10 @@ pub struct Settings { /// Endianness for writing RB and RBHEX formats. pub output_float_format: Endian, +} + +pub struct Settings { + pub look: Arc, /// `MDISPLAY`: how to display matrices in `MATRIX`...`END MATRIX`. pub matrix_display: MatrixDisplay, @@ -78,6 +81,7 @@ pub struct Settings { pub global: Compatibility, pub syntax: Compatibility, pub formats: FormatSettings, + pub endian: EndianSettings, pub small: f64, pub show_values: Show, pub show_variables: Show, @@ -87,10 +91,6 @@ impl Default for Settings { fn default() -> Self { Self { look: Arc::new(Look::default()), - input_integer_format: Endian::NATIVE, - input_float_format: Endian::NATIVE, - output_integer_format: Endian::NATIVE, - output_float_format: Endian::NATIVE, matrix_display: MatrixDisplay::default(), view_length: 24, view_width: 79, @@ -114,6 +114,7 @@ impl Default for Settings { global: Compatibility::default(), syntax: Compatibility::default(), formats: FormatSettings::default(), + endian: EndianSettings::default(), small: 0.0001, show_values: Show::default(), show_variables: Show::default(), -- 2.30.2