work
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 13 Oct 2025 15:46:42 +0000 (08:46 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 13 Oct 2025 15:46:42 +0000 (08:46 -0700)
rust/doc/src/commands/set.md
rust/pspp/src/output/spv.rs
rust/pspp/src/output/spv/light.rs

index 0814ba8942d598e47843d85c99cf8f90c6dab1fd..a7a48a9b59f5191a4fe6104506b729cf42bee13c 100644 (file)
@@ -80,8 +80,12 @@ subcommands are examined in groups.
 For subcommands that take boolean values, `ON` and `YES` are
 synonymous, as are `OFF` and `NO`, when used as subcommand values.
 
+<!-- toc -->
+
+# Data Input
+
 The data input subcommands affect the way that data is read from data
-files.  The data input subcommands are
+files.  The data input subcommands are:
 
 * `BLANKS`  
   This is the value assigned to an item data item that is empty or
@@ -122,6 +126,8 @@ files.  The data input subcommands are
   default, is equivalent to `MSBFIRST` or `LSBFIRST` depending on the
   native format of the machine running PSPP.
 
+# Interaction
+
 Interaction subcommands affect the way that PSPP interacts with an
 online user.  The interaction subcommands are
 
@@ -184,6 +190,8 @@ execute.  The syntax execution subcommands are
   virtual memory management, setting a very large workspace may cause
   PSPP to abort.
 
+# Data Output
+
 Data output subcommands affect the format of output data.  These
 subcommands are
 
@@ -236,6 +244,8 @@ subcommands are
   default, is equivalent to `MSBFIRST` or `LSBFIRST` depending on the
   native format of the machine running PSPP.
 
+# Output Routing
+
 In the PSPP text-based interface, the output routing subcommands
 affect where output is sent.  The following values are allowed for each
 of these subcommands:
@@ -275,6 +285,8 @@ These output routing subcommands are:
 These subcommands have no effect on output in the PSPP GUI
 environment.
 
+# Output Driver
+
 Output driver option subcommands affect output drivers' settings.
 These subcommands are:
 
@@ -313,7 +325,9 @@ These subcommands are:
   `.tlo` file in the same way as specifying `--table-look=FILE` the
   PSPP command line (*note Main Options::).
 
-Logging subcommands affect logging of commands executed to external
+# Journal
+
+Journal subcommands affect logging of commands executed to external
 files.  These subcommands are
 
 * `JOURNAL`  
@@ -335,6 +349,8 @@ produced by PSPP.  These subcommands are
   Whether system files created by `SAVE` or `XSAVE` are compressed by
   default.  The default is `ON`.
 
+# Security
+
 Security subcommands affect the operations that commands are allowed
 to perform.  The security subcommands are
 
@@ -377,6 +393,8 @@ to perform.  The security subcommands are
   Contrary to intuition, this command does not affect any aspect of
   the system's locale.
 
+# Macros
+
 The following subcommands affect the interpretation of macros.  For
 more information, see [Macro Settings](define.md#macro-settings).
 
@@ -399,6 +417,8 @@ more information, see [Macro Settings](define.md#macro-settings).
   Limits the number of levels of nested macro expansions.  This must
   be set to a positive integer.  The default is 50.
 
+# Not Yet Implemented
+
 The following subcommands are not yet implemented, but PSPP accepts
 them and ignores the settings:
 
index a212bde8f6946ba2e26456181ed85b0a7f27957b..073b94291efe9ecb688eacbead4a852de84d5256 100644 (file)
@@ -20,7 +20,7 @@ use std::{
     path::Path,
 };
 
-use binrw::BinRead;
+use binrw::{BinRead, error::ContextExt};
 use displaydoc::Display;
 use serde::Deserialize;
 use zip::{ZipArchive, result::ZipError};
@@ -287,10 +287,16 @@ impl Table {
         R: Read + Seek,
     {
         if self.table_structure.path.is_none() {
-            let mut light = archive.by_name(&self.table_structure.data_path)?;
+            let member_name = &self.table_structure.data_path;
+            let mut light = archive.by_name(member_name)?;
             let mut data = Vec::with_capacity(light.size() as usize);
             light.read_to_end(&mut data)?;
-            let table = LightTable::read(&mut Cursor::new(data))?;
+            let mut cursor = Cursor::new(data);
+            let table = LightTable::read(&mut cursor).map_err(|e| {
+                e.with_message(format!(
+                    "While parsing {member_name:?} as light binary SPV member"
+                ))
+            })?;
             let pivot_table = table.decode()?;
             Ok(pivot_table.into_item().with_spv_info(
                 SpvInfo::new(structure_member)
index 89c0b289865176a1715c53b043625d4140d78ef1..c7be973dad4c7bcbb709a4d2c26b2611c662d169 100644 (file)
@@ -1,4 +1,5 @@
 use std::{
+    any::type_name,
     fmt::Debug,
     io::{Cursor, Read, Seek},
     ops::Deref,
@@ -47,6 +48,7 @@ pub enum LightError {
 #[br(little)]
 #[derive(Debug)]
 pub struct LightTable {
+    #[br(dbg)]
     header: Header,
     #[br(args(header.version))]
     titles: Titles,
@@ -56,7 +58,7 @@ pub struct LightTable {
     areas: Areas,
     borders: Counted<Borders>,
     print_settings: Counted<PrintSettings>,
-    #[br(if(header.version == Version::V3))]
+    #[br(dbg, if(header.version == Version::V3))]
     table_settings: Counted<TableSettings>,
     #[br(if(header.version == Version::V1), temp)]
     _ts: Option<Counted<Sponge>>,
@@ -784,6 +786,7 @@ where
         let start = reader.stream_position()?;
         let result = <T>::read_options(reader, endian, args).ok();
         if result.is_none() {
+            dbg!((start, type_name::<T>()));
             reader.seek(std::io::SeekFrom::Start(start))?;
         }
         Ok(Self(result))
@@ -805,7 +808,9 @@ struct Formats {
     _x8: bool,
     #[br(temp, parse_with(parse_bool))]
     _x9: bool,
+    #[br(dbg)]
     y0: Y0,
+    #[br(dbg)]
     custom_currency: CustomCurrency,
     #[br(if(version == Version::V1))]
     v1: Optional<Counted<X0>>,
@@ -858,6 +863,7 @@ impl Formats {
 #[br(little)]
 #[derive(Debug)]
 struct FormatsV3 {
+    #[br(dbg)]
     x1_x2: Counted<X1X2>,
     x3: Counted<X3>,
 }
@@ -876,6 +882,7 @@ struct X1X2 {
 struct X0 {
     #[br(temp)]
     _bytes: [u8; 14],
+    #[br(dbg)]
     y1: Y1,
     y2: Y2,
 }
@@ -904,6 +911,7 @@ struct Y1 {
 #[br(little)]
 #[derive(Debug)]
 struct Y2 {
+    #[br(dbg)]
     custom_currency: CustomCurrency,
     missing: u8,
     #[br(temp, parse_with(parse_bool))]
@@ -966,11 +974,13 @@ struct X2 {
 #[br(little)]
 #[derive(Debug)]
 struct X3 {
-    #[br(temp, magic = b"\x01\0")]
+    #[br(dbg, temp, magic = b"\x01\0")]
     _x21: u8,
-    #[br(magic = b"\0\0\0")]
+    #[br(dbg, magic = b"\0\0\0")]
     y1: Y1,
+    #[br(dbg)]
     small: f64,
+    #[br(dbg)]
     inner: Optional<X3Inner>,
     y2: Y2,
     #[br(temp)]