From: Ben Pfaff Date: Thu, 16 Oct 2025 14:18:54 +0000 (-0700) Subject: work X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=266bedbf429381e9bc3e467e05016e35ead89b8a;p=pspp work --- diff --git a/rust/doc/src/SUMMARY.md b/rust/doc/src/SUMMARY.md index 456092cf62..1810af5d4e 100644 --- a/rust/doc/src/SUMMARY.md +++ b/rust/doc/src/SUMMARY.md @@ -9,6 +9,7 @@ - [Inspecting Portable Files](invoking/pspp-show-por.md) - [Inspecting SPSS/PC+ Files](invoking/pspp-show-pc.md) - [Inspecting SPSS Viewer Files](invoking/pspp-show-spv.md) + - [Identifying Files](invoking/pspp-identify.md) - [Decrypting Files](invoking/pspp-decrypt.md) - [Output Driver Configuration](invoking/output.md) diff --git a/rust/doc/src/invoking/pspp-identify.md b/rust/doc/src/invoking/pspp-identify.md new file mode 100644 index 0000000000..4d4546a0e3 --- /dev/null +++ b/rust/doc/src/invoking/pspp-identify.md @@ -0,0 +1,26 @@ +# Identifying Files + +The `pspp identify` command identifies file types. The syntax is: + +``` +pspp identify +``` + +which reads `` and identifies it based on its contents. The +command prints one of the following on the terminal: + +* `sav`, for an SPSS system file, `sav (encrypted)` if the file is + encrypted. + +* `por`, for an SPSS portable file. + +* `pc+`, for an SPSS/PC+ data file. + +* `spv`, for an SPSS Viewer file, or `spv (encrypted)` if the file is + encrypted. + +* `sps`, for an SPSS syntax file, `sps (encrypted)` if the file is + encrypted, or `sps (low confidence)` if the file could be a syntax + file or another kind of text file. + +* `unknown`, for other kinds of files. diff --git a/rust/doc/src/spv/structure.md b/rust/doc/src/spv/structure.md index 1241c61ce7..4e34d7344f 100644 --- a/rust/doc/src/spv/structure.md +++ b/rust/doc/src/spv/structure.md @@ -40,7 +40,7 @@ element: ``` container - :visibility=(visible | hidden) + :visibility=(visible | hidden)? :page-break-before=(always)? :text-align=(left | center)? :width=dimension @@ -305,7 +305,7 @@ anyway. The user cannot edit it. ``` container - :visibility=(visible | hidden) + :visibility=(visible | hidden)? :page-break-before=(always | auto | avoid | left | right | inherit)? :text-align=(left | center)? :width=dimension @@ -319,7 +319,8 @@ This element has the following attributes. * `visibility` Whether the container's content is displayed. "Notes" tables are - often hidden; other data is usually visible. + often hidden; other data is usually visible. The default is + `visible`. * `page-break-before` Whether to start the element at the beginning of a new page. This diff --git a/rust/pspp/src/file.rs b/rust/pspp/src/file.rs index bc9bb85ec4..1baa00e7a9 100644 --- a/rust/pspp/src/file.rs +++ b/rust/pspp/src/file.rs @@ -170,6 +170,21 @@ impl FileType { Ok(None) } + + /// Returns a string for the typical extension associated with this kind of + /// file, without the leading `.`. + /// + /// Returns `pc+` for [FileType::Pc] files, even though that is not typical, + /// since these files are so unusual. + pub fn as_extension(&self) -> &'static str { + match self { + FileType::System { .. } => "sav", + FileType::Portable => "por", + FileType::Pc => "pc+", + FileType::Viewer { .. } => "spv", + FileType::Syntax { .. } => "sps", + } + } } #[cfg(test)] diff --git a/rust/pspp/src/identify.rs b/rust/pspp/src/identify.rs new file mode 100644 index 0000000000..917e86370b --- /dev/null +++ b/rust/pspp/src/identify.rs @@ -0,0 +1,46 @@ +// PSPP - a program for statistical analysis. +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +use anyhow::Result; +use clap::Args; +use pspp::file::FileType; +use std::path::PathBuf; + +/// Identify the type of a file. +#[derive(Args, Clone, Debug)] +pub struct Identify { + /// File to identify. + file: PathBuf, +} + +impl Identify { + pub fn run(self) -> Result<()> { + match FileType::from_file(&self.file)? { + None => println!("unknown"), + Some(file_type) => { + print!("{}", file_type.as_extension()); + if file_type.is_encrypted() { + print!(" (encrypted)"); + } + if !file_type.is_confident() { + print!(" (low confidence)"); + } + println!(); + } + } + Ok(()) + } +} diff --git a/rust/pspp/src/main.rs b/rust/pspp/src/main.rs index de9293200f..df4d3715b3 100644 --- a/rust/pspp/src/main.rs +++ b/rust/pspp/src/main.rs @@ -1,18 +1,18 @@ -/* PSPP - a program for statistical analysis. - * Copyright (C) 2023 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . */ +// PSPP - a program for statistical analysis. +// Copyright (C) 2025 Free Software Foundation, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . use anyhow::Result; use clap::{Parser, Subcommand}; @@ -20,12 +20,13 @@ use encoding_rs::Encoding; use thiserror::Error as ThisError; use crate::{ - convert::Convert, decrypt::Decrypt, show::Show, show_pc::ShowPc, show_por::ShowPor, - show_spv::ShowSpv, + convert::Convert, decrypt::Decrypt, identify::Identify, show::Show, show_pc::ShowPc, + show_por::ShowPor, show_spv::ShowSpv, }; mod convert; mod decrypt; +mod identify; mod show; mod show_pc; mod show_por; @@ -43,6 +44,7 @@ struct Cli { enum Command { Convert(Convert), Decrypt(Decrypt), + Identify(Identify), Show(Show), ShowPor(ShowPor), ShowPc(ShowPc), @@ -54,6 +56,7 @@ impl Command { match self { Command::Convert(convert) => convert.run(), Command::Decrypt(decrypt) => decrypt.run(), + Command::Identify(identify) => identify.run(), Command::Show(show) => show.run(), Command::ShowPor(show_por) => show_por.run(), Command::ShowPc(show_pc) => show_pc.run(), diff --git a/rust/pspp/src/output/spv.rs b/rust/pspp/src/output/spv.rs index d1cdc1a695..aab671e2b3 100644 --- a/rust/pspp/src/output/spv.rs +++ b/rust/pspp/src/output/spv.rs @@ -183,6 +183,10 @@ impl Heading { .into_item() .with_command_name(container_text.command_name) .with_spv_info(SpvInfo::new(structure_member)), + ContainerContent::Model => new_error_item("models not yet implemented") + .with_spv_info(SpvInfo::new(structure_member).with_error()), + ContainerContent::Object => new_error_item("objects not yet implemented") + .with_spv_info(SpvInfo::new(structure_member).with_error()), ContainerContent::Tree => new_error_item("trees not yet implemented") .with_spv_info(SpvInfo::new(structure_member).with_error()), }; @@ -219,14 +223,14 @@ enum HeadingContent { #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] struct Label { - #[serde(rename = "$text")] + #[serde(default, rename = "$text")] text: String, } #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] struct Container { - #[serde(rename = "@visibility")] + #[serde(default, rename = "@visibility")] visibility: Visibility, #[serde(rename = "@page-break-before")] #[serde(default)] @@ -253,9 +257,10 @@ enum PageBreakBefore { Inherit, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Default)] #[serde(rename_all = "camelCase")] enum Visibility { + #[default] Visible, Hidden, } @@ -274,10 +279,9 @@ enum ContainerContent { Table(Table), Text(ContainerText), Graph(Graph), - /* - Model(Model), - Object(Object), - Image(Image),*/ + Model, + Object, + //Image(Image), Tree, }