work
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 12 Oct 2025 17:09:51 +0000 (10:09 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 12 Oct 2025 17:09:51 +0000 (10:09 -0700)
rust/doc/src/invoking/pspp-show-spv.md
rust/pspp/src/output.rs

index 386f2c32b7b31f427800e38b2a6689fe287bb701..a31ff548c3a8ec216b1972ca66978ae9a75e36f5 100644 (file)
@@ -39,11 +39,11 @@ The following `<MODE>`s are accepted:
 
 ## Input Selection Options
 
-The `dir` and `convert` commands, by default, operate on all of the
-objects in the source SPV file, except for objects that are not visible
-in the output viewer window.  The user may specify these options to
-select a subset of the input objects.  When multiple options are used,
-only objects that satisfy all of them are selected:
+Commands that read an SPV file operate, by default, on all of the
+objects in the file, except for objects that are not visible in the
+output viewer window.  The user may specify these options to select a
+subset of the input objects.  When multiple options are used, only
+objects that satisfy all of them are selected:
 
 * `--select=[^]CLASS...`  
   Include only objects of the given `CLASS`; with leading `^`, include
index 544f2353a3ec9cb77bc0537c970d76d78e92fe0a..8c307a6c4811264aadd9218b3984aace921c7f2f 100644 (file)
@@ -846,38 +846,25 @@ impl Criteria {
         }
         fn unflatten_items(
             items: Vec<Arc<Item>>,
-            mut index: usize,
-            include: &BitVec,
+            include: &mut bit_vec::Iter,
             out: &mut Vec<Arc<Item>>,
         ) {
             for item in items {
-                unflatten_item(Arc::unwrap_or_clone(item), index, include, out);
-                index += 1;
+                unflatten_item(Arc::unwrap_or_clone(item), include, out);
             }
         }
-        fn unflatten_item(
-            mut item: Item,
-            mut index: usize,
-            include: &BitVec,
-            out: &mut Vec<Arc<Item>>,
-        ) {
-            let include_item = include[index];
-            index += 1;
-            match item.details {
-                Details::Group(ref mut children) => {
-                    let in_children = take(children);
-                    if !include_item {
-                        unflatten_items(in_children, index, include, out);
-                        return;
-                    }
-                    unflatten_items(in_children, index, include, children);
+        fn unflatten_item(mut item: Item, include: &mut bit_vec::Iter, out: &mut Vec<Arc<Item>>) {
+            let include_item = include.next().unwrap();
+            if let Some(children) = item.details.as_mut_group() {
+                if !include_item {
+                    unflatten_items(take(children), include, out);
+                    return;
                 }
-                _ => {}
+                unflatten_items(take(children), include, children);
             }
             if include_item {
                 out.push(Arc::new(item));
             }
-            todo!()
         }
 
         let mut items = Vec::new();
@@ -885,13 +872,22 @@ impl Criteria {
         flatten_children(take_children(&item), 0, &mut items, &mut depths);
 
         let mut include = BitVec::from_elem(items.len(), false);
-        for selection in &self.0 {
+        let selections = if self.0.is_empty() {
+            &[Selection::default()]
+        } else {
+            self.0.as_slice()
+        };
+        for selection in selections {
             select_matches(&items, &depths, selection, &mut include);
         }
 
         let mut output = Item::new_root();
-        unflatten_item(item, 0, &include, output.details.as_mut_group().unwrap());
-        todo!()
+        unflatten_item(
+            item,
+            &mut include.iter(),
+            output.details.as_mut_group().unwrap(),
+        );
+        output
     }
 }
 
@@ -961,25 +957,25 @@ impl FromArgMatches for Criteria {
             }
         }
 
-        if values.is_empty() {
-            return Ok(());
-        }
-
-        let mut selection = Selection::default();
-        for value in values.into_values() {
-            match value {
-                Value::Or => self.0.push(take(&mut selection)),
-                Value::Classes(classes) => selection.classes = classes,
-                Value::Commands(commands) => selection.commands = commands,
-                Value::Subtypes(subtypes) => selection.subtypes = subtypes,
-                Value::Labels(labels) => selection.labels = labels,
-                Value::NthCommands(nth_commands) => selection.nth_commands = nth_commands,
-                Value::Instances(instances) => selection.instances = instances,
-                Value::ShowHidden(show) => selection.visible = if show { None } else { Some(true) },
-                Value::Errors(only) => selection.error = if only { Some(true) } else { None },
+        if !self.0.is_empty() {
+            let mut selection = Selection::default();
+            for value in values.into_values() {
+                match value {
+                    Value::Or => self.0.push(take(&mut selection)),
+                    Value::Classes(classes) => selection.classes = classes,
+                    Value::Commands(commands) => selection.commands = commands,
+                    Value::Subtypes(subtypes) => selection.subtypes = subtypes,
+                    Value::Labels(labels) => selection.labels = labels,
+                    Value::NthCommands(nth_commands) => selection.nth_commands = nth_commands,
+                    Value::Instances(instances) => selection.instances = instances,
+                    Value::ShowHidden(show) => {
+                        selection.visible = if show { None } else { Some(true) }
+                    }
+                    Value::Errors(only) => selection.error = if only { Some(true) } else { None },
+                }
             }
+            self.0.push(selection);
         }
-        self.0.push(selection);
         Ok(())
     }
 }