fix honor_small
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 7 Jan 2026 20:00:45 +0000 (12:00 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 7 Jan 2026 20:00:45 +0000 (12:00 -0800)
rust/pspp/src/spv/read/legacy_xml.rs
rust/pspp/src/spv/read/light.rs
rust/pspp/src/spv/testdata/light4.expected [new file with mode: 0644]
rust/pspp/src/spv/testdata/light4.spv [new file with mode: 0644]

index 7843d01aa60c4f14e03d153fbdfaa81571b664b3..47c2ca09deb8df714bed4e5a278f05a153b89531 100644 (file)
@@ -54,7 +54,7 @@ pub fn datum_as_format(datum: &Datum<String>) -> crate::format::Format {
         Datum::Number(None) => 0,
         Datum::String(s) => s.parse().unwrap_or_default(),
     };
-    decode_format(f as u32, &mut |_| () /*XXX*/)
+    decode_format(f as u32, &mut |_| () /*XXX*/).0
 }
 
 /// Returns this data value interpreted using `format`.
index a3c685432ca466f3815847f18b1fd59f6001fdb0..1b1aca730cc775fc62b252c63845c54d207d29e7 100644 (file)
@@ -1140,15 +1140,28 @@ struct ValueNumber {
 
 #[binread]
 #[br(little)]
-#[derive(Debug)]
 struct Format(u32);
 
 impl Format {
-    pub fn decode(&self, warn: &mut dyn FnMut(LightWarning)) -> format::Format {
+    pub fn decode(&self, warn: &mut dyn FnMut(LightWarning)) -> (format::Format, bool) {
         decode_format(self.0, warn)
     }
 }
 
+impl Debug for Format {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let mut warning = false;
+        let (format, _honor_small) = self.decode(&mut |_| {
+            warning = true;
+        });
+        if warning {
+            write!(f, "InvalidFormat({:#x})", self.0)
+        } else {
+            write!(f, "{format}")
+        }
+    }
+}
+
 #[binread]
 #[br(little, import(context: &Context))]
 #[derive(Debug)]
@@ -1274,24 +1287,27 @@ impl BinRead for Value {
     }
 }
 
-pub(super) fn decode_format(raw: u32, warn: &mut dyn FnMut(LightWarning)) -> format::Format {
+pub(super) fn decode_format(
+    raw: u32,
+    warn: &mut dyn FnMut(LightWarning),
+) -> (format::Format, bool) {
     if raw == 0 || raw == 0x10000 || raw == 1 {
-        return F40_2;
+        return (F40_2, false);
     }
 
     let raw_type = (raw >> 16) as u16;
-    let type_ = if raw_type >= 40 {
-        Type::F
+    let (type_, honor_small) = if raw_type >= 40 {
+        (Type::F, true)
     } else if let Ok(type_) = Type::try_from(raw_type) {
-        type_
+        (type_, false)
     } else {
         warn(LightWarning::InvalidFormat(raw_type));
-        Type::F
+        (Type::F, false)
     };
     let w = ((raw >> 8) & 0xff) as Width;
     let d = raw as Decimals;
 
-    UncheckedFormat::new(type_, w, d).fix()
+    (UncheckedFormat::new(type_, w, d).fix(), honor_small)
 }
 
 impl ValueNumber {
@@ -1301,8 +1317,10 @@ impl ValueNumber {
         footnotes: &pivot::Footnotes,
         warn: &mut dyn FnMut(LightWarning),
     ) -> value::Value {
+        let (format, honor_small) = dbg!(self.format.decode(warn));
         value::Value::new_number((self.x != -f64::MAX).then_some(self.x))
-            .with_format(self.format.decode(warn))
+            .with_format(format)
+            .with_honor_small(honor_small)
             .with_styling(ValueMods::decode_optional(&self.mods, encoding, footnotes))
     }
 }
@@ -1314,8 +1332,10 @@ impl ValueVarNumber {
         footnotes: &pivot::Footnotes,
         warn: &mut dyn FnMut(LightWarning),
     ) -> value::Value {
+        let (format, honor_small) = self.format.decode(warn);
         value::Value::new_number((self.x != -f64::MAX).then_some(self.x))
-            .with_format(self.format.decode(warn))
+            .with_format(format)
+            .with_honor_small(honor_small)
             .with_styling(ValueMods::decode_optional(&self.mods, encoding, footnotes))
             .with_value_label(self.value_label.decode_optional(encoding))
             .with_variable_name(Some(self.var_name.decode(encoding)))
@@ -1342,11 +1362,12 @@ impl ValueString {
         footnotes: &pivot::Footnotes,
         warn: &mut dyn FnMut(LightWarning),
     ) -> value::Value {
+        let (format, honor_small) = self.format.decode(warn);
         value::Value::new(pivot::value::ValueInner::Datum(DatumValue {
             datum: Datum::new_utf8(self.s.decode(encoding)),
-            format: self.format.decode(warn),
+            format,
+            honor_small,
             show: self.show.decode(warn),
-            honor_small: false,
             variable: self.var_name.decode_optional(encoding),
             value_label: self.value_label.decode_optional(encoding),
         }))
diff --git a/rust/pspp/src/spv/testdata/light4.expected b/rust/pspp/src/spv/testdata/light4.expected
new file mode 100644 (file)
index 0000000..21ddf26
--- /dev/null
@@ -0,0 +1,44 @@
+                               Correlation Matrix[a]
+                      xxxx1│ xxx2│xxxx3│  x4 │  x5 │  x6 │  x7 │  x8 │  x9 │  x0
+───────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+Correlation     xxxx1 1.000│2.000│3.000│4.000│5.000│6.000│7.000│8.000│9.000│10.000
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                xxx2  -.962│1.000│ .969│ .252│ .738│ .038│ .242│-.103│-.091│  .194
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                xxxx3 -.984│ .969│1.000│ .291│ .836│-.047│ .324│ .010│-.103│  .190
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x4    -.187│ .252│ .291│1.000│ .545│ .128│ .344│ .575│-.283│  .178
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x5    -.754│ .738│ .836│ .545│1.000│ .043│ .513│ .333│ .018│  .215
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x6    -.001│ .038│-.047│ .128│ .043│1.000│-.412│-.536│ .018│ -.357
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x7    -.245│ .242│ .324│ .344│ .513│-.412│1.000│ .560│ .086│  .862
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x8     .117│-.103│ .010│ .575│ .333│-.536│ .560│1.000│-.227│  .241
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x9     .147│-.091│-.103│-.283│ .018│ .018│ .086│-.227│1.000│  .190
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x0    -.138│ .194│ .190│ .178│ .215│-.357│ .862│ .241│ .190│ 1.000
+───────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+Sig. (1-tailed) xxxx1      │ .000│ .000│ .291│ .004│ .499│ .234│ .366│ .333│  .343
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                xxx2   .000│     │ .000│ .227│ .005│ .455│ .237│ .381│ .395│  .284
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                xxxx3  .000│ .000│     │ .193│ .001│ .445│ .166│ .488│ .381│  .288
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x4     .291│ .227│ .193│     │ .041│ .353│ .150│ .032│ .200│  .301
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x5     .004│ .005│ .001│ .041│     │ .450│ .053│ .159│ .479│  .263
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x6     .499│ .455│ .445│ .353│ .450│     │ .104│ .045│ .480│  .141
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x7     .234│ .237│ .166│ .150│ .053│ .104│     │ .037│ .401│  .000
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x8     .366│ .381│ .488│ .032│ .159│ .045│ .037│     │ .251│  .237
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x9     .333│ .395│ .381│ .200│ .479│ .480│ .401│ .251│     │  .288
+               ╶───────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼──────
+                x0     .343│ .284│ .288│ .301│ .263│ .141│ .000│ .237│ .288│
+───────────────────────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴──────
+a. Determinant = 1.479E-009
diff --git a/rust/pspp/src/spv/testdata/light4.spv b/rust/pspp/src/spv/testdata/light4.spv
new file mode 100644 (file)
index 0000000..717602a
Binary files /dev/null and b/rust/pspp/src/spv/testdata/light4.spv differ