From 376567e0c68e8a5fafb12376358da11e5a445b39 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 24 Sep 2025 08:56:09 -0700 Subject: [PATCH] work on reading spv files --- rust/Cargo.lock | 200 +- rust/doc/src/SUMMARY.md | 5 +- rust/doc/src/commands/set.md | 127 +- rust/doc/src/invoking/output.md | 273 ++ rust/doc/src/invoking/pspp-convert.md | 137 +- rust/doc/src/invoking/pspp-identify.md | 26 + rust/doc/src/invoking/pspp-show-pc.md | 31 +- rust/doc/src/invoking/pspp-show-por.md | 31 +- rust/doc/src/invoking/pspp-show-spv.md | 140 + rust/doc/src/invoking/pspp-show.md | 31 +- rust/doc/src/spv/index.md | 24 +- rust/doc/src/spv/legacy-detail-binary.md | 64 +- rust/doc/src/spv/legacy-detail-xml.md | 33 +- rust/doc/src/spv/light-detail.md | 385 ++- rust/doc/src/spv/structure.md | 479 ++- rust/doc/src/tablelook.md | 26 +- rust/pspp/Cargo.toml | 10 +- rust/pspp/src/calendar.rs | 4 + rust/pspp/src/cli.rs | 80 + rust/pspp/src/cli/convert.rs | 165 + rust/pspp/src/{ => cli}/decrypt.rs | 0 rust/pspp/src/cli/identify.rs | 46 + rust/pspp/src/cli/show.rs | 250 ++ rust/pspp/src/cli/show_pc.rs | 179 ++ rust/pspp/src/cli/show_por.rs | 207 ++ rust/pspp/src/cli/show_spv.rs | 155 + rust/pspp/src/command.rs | 35 +- rust/pspp/src/command/crosstabs.rs | 4 +- rust/pspp/src/command/ctables.rs | 4 +- rust/pspp/src/command/data_list.rs | 4 +- rust/pspp/src/command/descriptives.rs | 4 +- rust/pspp/src/convert.rs | 402 --- rust/pspp/src/data.rs | 44 + rust/pspp/src/file.rs | 19 +- rust/pspp/src/format.rs | 98 +- rust/pspp/src/format/display.rs | 22 +- rust/pspp/src/lex/segment.rs | 115 +- rust/pspp/src/main.rs | 93 +- rust/pspp/src/message.rs | 6 +- rust/pspp/src/output.rs | 1058 ++++++- rust/pspp/src/output/cairo/pager.rs | 237 -- rust/pspp/src/output/csv.rs | 230 -- .../pspp/src/output/{driver.rs => drivers.rs} | 159 +- rust/pspp/src/output/{ => drivers}/cairo.rs | 14 +- .../src/output/{ => drivers}/cairo/driver.rs | 88 +- .../src/output/{ => drivers}/cairo/fsm.rs | 182 +- rust/pspp/src/output/drivers/cairo/pager.rs | 222 ++ rust/pspp/src/output/drivers/csv.rs | 430 +++ rust/pspp/src/output/{ => drivers}/html.rs | 41 +- rust/pspp/src/output/drivers/json.rs | 108 + rust/pspp/src/output/drivers/por.rs | 78 + rust/pspp/src/output/drivers/sav.rs | 83 + rust/pspp/src/output/drivers/spv.rs | 1413 +++++++++ rust/pspp/src/output/{ => drivers}/text.rs | 34 +- .../output/{ => drivers/text}/text_line.rs | 0 rust/pspp/src/output/json.rs | 58 - rust/pspp/src/output/page.rs | 218 +- rust/pspp/src/output/pivot.rs | 1094 +++++-- rust/pspp/src/output/pivot/look_xml.rs | 567 +++- rust/pspp/src/output/pivot/output.rs | 136 +- .../output/pivot/testdata/caption.expected | 8 + .../category_and_dimension_borders_1.expected | 24 + .../category_and_dimension_borders_2.expected | 21 + .../category_and_dimension_borders_3.expected | 25 + .../testdata/category_borders_1.expected | 24 + .../testdata/category_borders_2.expected | 21 + .../src/output/pivot/testdata/d1_c.expected | 8 + .../src/output/pivot/testdata/d1_r.expected | 8 + .../src/output/pivot/testdata/d2_cc.expected | 8 + .../testdata/d2_cc_with_dim_labels.expected | 12 + .../pivot/testdata/d2_cl-all_layers.expected | 23 + .../pivot/testdata/d2_cl-layer0.expected | 7 + .../pivot/testdata/d2_cl-layer1.expected | 7 + .../src/output/pivot/testdata/d2_cr.expected | 8 + .../d2_cr_with_corner_dim_labels.expected | 10 + .../d2_cr_with_nested_dim_labels.expected | 10 + .../src/output/pivot/testdata/d2_rc.expected | 8 + .../d2_rc_with_corner_dim_labels.expected | 10 + .../d2_rc_with_nested_dim_labels.expected | 10 + .../pivot/testdata/d2_rl-all_layers.expected | 23 + .../pivot/testdata/d2_rl-layer0.expected | 7 + .../pivot/testdata/d2_rl-layer1.expected | 7 + .../src/output/pivot/testdata/d2_rr.expected | 14 + .../d2_rr_with_corner_dim_labels.expected | 16 + .../d2_rr_with_nested_dim_labels.expected | 14 + .../src/output/pivot/testdata/d2m_cc.expected | 12 + .../src/output/pivot/testdata/d2m_cr.expected | 14 + .../src/output/pivot/testdata/d2m_rc.expected | 12 + .../src/output/pivot/testdata/d2m_rr.expected | 22 + .../pivot/testdata/d3-layer0_0.expected | 8 + .../pivot/testdata/d3-layer0_1.expected | 8 + .../pivot/testdata/d3-layer1_2.expected | 8 + .../testdata/dimension_borders_1.expected | 21 + .../testdata/dimension_borders_2.expected | 17 + .../pivot/testdata/empty_groups.expected | 7 + .../footnote_alphabetic_subscript.expected | 12 + .../footnote_alphabetic_superscript.expected | 12 + .../pivot/testdata/footnote_hidden.expected | 11 + .../footnote_numeric_subscript.expected | 12 + .../footnote_numeric_superscript.expected | 12 + .../pivot/testdata/metadata_entry.expected | 9 + .../pivot/testdata/no_dimension.expected | 3 + .../testdata/no_title_or_caption.expected | 7 + .../testdata/one_empty_dimension.expected | 1 + .../pivot/testdata/small_numbers.expected | 21 + .../three_dimensions_two_empty.expected | 1 + .../pivot/testdata/title_and_caption.expected | 9 + .../testdata/two_empty_dimensions.expected | 1 + rust/pspp/src/output/pivot/tests.rs | 869 +----- rust/pspp/src/output/pivot/tlo.rs | 46 +- rust/pspp/src/output/render.rs | 21 +- rust/pspp/src/output/spv.rs | 1857 ++++-------- rust/pspp/src/output/spv/css.rs | 377 +++ rust/pspp/src/output/spv/html.rs | 917 ++++++ rust/pspp/src/output/spv/legacy_bin.rs | 280 ++ rust/pspp/src/output/spv/legacy_xml.rs | 2694 +++++++++++++++++ rust/pspp/src/output/spv/light.rs | 1681 ++++++++++ rust/pspp/src/output/table.rs | 59 +- rust/pspp/src/pc.rs | 4 +- rust/pspp/src/pc/tests.rs | 6 +- rust/pspp/src/por/read.rs | 6 +- rust/pspp/src/settings.rs | 4 +- rust/pspp/src/show.rs | 383 --- rust/pspp/src/show_pc.rs | 300 -- rust/pspp/src/show_por.rs | 327 -- rust/pspp/src/sys/cooked.rs | 2 +- rust/pspp/src/sys/raw/records.rs | 7 +- .../pspp/src/sys/testdata/attributes.expected | 19 +- .../bad_machine_float_info_size.expected | 17 +- .../bad_machine_integer_info_count.expected | 17 +- ...d_machine_integer_info_endianness.expected | 19 +- ...machine_integer_info_float_format.expected | 19 +- ...e_name_in_long_string_value_label.expected | 17 +- ...iable_name_in_variable_value_pair.expected | 17 +- .../bad_very_long_string_length.expected | 17 +- ...ad_very_long_string_segment_width.expected | 17 +- .../src/sys/testdata/compressed_data.expected | 17 +- .../compressed_data_other_bias.expected | 17 +- .../compressed_data_zero_bias.expected | 17 +- rust/pspp/src/sys/testdata/documents.expected | 19 +- .../duplicate_attribute_name.expected | 17 +- .../duplicate_long_variable_name.expected | 17 +- .../duplicate_value_labels_type.expected | 17 +- .../testdata/duplicate_variable_name.expected | 17 +- .../testdata/empty_document_record.expected | 19 +- .../sys/testdata/extra_product_info.expected | 23 +- ...rds_than_indicated_by_file_header.expected | 17 +- ...ows_in_long_string_missing_values.expected | 19 +- ...nvalid_long_string_missing_values.expected | 19 +- .../testdata/invalid_variable_format.expected | 17 +- .../testdata/invalid_variable_name.expected | 17 +- .../sys/testdata/long_variable_names.expected | 19 +- .../testdata/missing_attribute_value.expected | 17 +- ...ine_after_variable_name_in_mrsets.expected | 17 +- .../missing_string_continuation.expected | 17 +- .../mixed_variable_types_in_mrsets.expected | 17 +- ...rds_than_indicated_by_file_header.expected | 17 +- .../multiple_documents_records.expected | 17 +- .../testdata/multiple_response_sets.expected | 19 +- ..._response_sets_bad_counted_string.expected | 17 +- .../multiple_response_sets_bad_name.expected | 19 +- ...se_sets_counted_string_bad_length.expected | 17 +- ...sets_counted_string_missing_space.expected | 17 +- ...onse_sets_duplicate_variable_name.expected | 17 +- ...esponse_sets_missing_label_source.expected | 17 +- ...ssing_newline_after_variable_name.expected | 17 +- ...sponse_sets_missing_space_after_c.expected | 17 +- ...issing_space_after_counted_string.expected | 17 +- ...sponse_sets_missing_space_after_e.expected | 17 +- ...onse_sets_unexpected_label_source.expected | 17 +- .../src/sys/testdata/no_variables.expected | 17 +- ..._skipping_bad_extension_record_18.expected | 17 +- .../partial_compressed_data_record.expected | 17 +- ...ial_data_record_between_variables.expected | 17 +- ...al_data_record_within_long_string.expected | 17 +- .../src/sys/testdata/test-encrypted.expected | 19 +- ...record_names_long_string_variable.expected | 17 +- .../sys/testdata/unknown_encoding.expected | 17 +- .../unknown_extension_record.expected | 17 +- .../unquoted_attribute_value.expected | 17 +- ...fied_number_of_variable_positions.expected | 17 +- ..._indexes_must_be_in_correct_range.expected | 17 +- ...t_not_be_long_string_continuation.expected | 17 +- ...abel_with_no_associated_variables.expected | 17 +- .../src/sys/testdata/value_labels.expected | 19 +- .../variable_display_with_width.expected | 17 +- .../variable_display_without_width.expected | 17 +- ...ariable_labels_and_missing_values.expected | 19 +- .../src/sys/testdata/variable_roles.expected | 19 +- .../src/sys/testdata/variable_sets.expected | 19 +- .../variable_sets_unknown_variable.expected | 19 +- ...value_label_must_all_be_same_type.expected | 17 +- .../sys/testdata/very_long_strings.expected | 19 +- .../testdata/weight_must_be_numeric.expected | 17 +- .../weight_variable_bad_index.expected | 17 +- .../weight_variable_continuation.expected | 17 +- .../testdata/write-numeric-simple.expected | 19 +- .../write-numeric-uncompressed.expected | 19 +- .../sys/testdata/write-numeric-zlib.expected | 19 +- .../sys/testdata/write-string-simple.expected | 19 +- .../write-string-uncompressed.expected | 19 +- .../sys/testdata/write-string-zlib.expected | 19 +- .../testdata/wrong_display_alignment.expected | 17 +- .../wrong_display_measurement_level.expected | 17 +- .../wrong_display_parameter_count.expected | 17 +- .../wrong_display_parameter_size.expected | 17 +- .../testdata/wrong_special_floats.expected | 17 +- .../wrong_variable_positions.expected | 17 +- .../wrong_variable_positions_but_v13.expected | 19 +- .../sys/testdata/zcompressed_data.expected | 17 +- ...data_uncompressed_size_block_size.expected | 17 +- .../zero_or_one_variable_in_mrset.expected | 17 +- rust/pspp/src/sys/tests.rs | 7 +- rust/pspp/src/sys/write.rs | 2 +- rust/pspp/src/variable.rs | 12 +- rust/rustfmt.toml | 2 + src/output/spv/spv-legacy-data.h | 2 +- 217 files changed, 16278 insertions(+), 6067 deletions(-) create mode 100644 rust/doc/src/invoking/output.md create mode 100644 rust/doc/src/invoking/pspp-identify.md create mode 100644 rust/doc/src/invoking/pspp-show-spv.md create mode 100644 rust/pspp/src/cli.rs create mode 100644 rust/pspp/src/cli/convert.rs rename rust/pspp/src/{ => cli}/decrypt.rs (100%) create mode 100644 rust/pspp/src/cli/identify.rs create mode 100644 rust/pspp/src/cli/show.rs create mode 100644 rust/pspp/src/cli/show_pc.rs create mode 100644 rust/pspp/src/cli/show_por.rs create mode 100644 rust/pspp/src/cli/show_spv.rs delete mode 100644 rust/pspp/src/convert.rs delete mode 100644 rust/pspp/src/output/cairo/pager.rs delete mode 100644 rust/pspp/src/output/csv.rs rename rust/pspp/src/output/{driver.rs => drivers.rs} (52%) rename rust/pspp/src/output/{ => drivers}/cairo.rs (75%) rename rust/pspp/src/output/{ => drivers}/cairo/driver.rs (59%) rename rust/pspp/src/output/{ => drivers}/cairo/fsm.rs (87%) create mode 100644 rust/pspp/src/output/drivers/cairo/pager.rs create mode 100644 rust/pspp/src/output/drivers/csv.rs rename rust/pspp/src/output/{ => drivers}/html.rs (92%) create mode 100644 rust/pspp/src/output/drivers/json.rs create mode 100644 rust/pspp/src/output/drivers/por.rs create mode 100644 rust/pspp/src/output/drivers/sav.rs create mode 100644 rust/pspp/src/output/drivers/spv.rs rename rust/pspp/src/output/{ => drivers}/text.rs (96%) rename rust/pspp/src/output/{ => drivers/text}/text_line.rs (100%) delete mode 100644 rust/pspp/src/output/json.rs create mode 100644 rust/pspp/src/output/pivot/testdata/caption.expected create mode 100644 rust/pspp/src/output/pivot/testdata/category_and_dimension_borders_1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/category_and_dimension_borders_2.expected create mode 100644 rust/pspp/src/output/pivot/testdata/category_and_dimension_borders_3.expected create mode 100644 rust/pspp/src/output/pivot/testdata/category_borders_1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/category_borders_2.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d1_c.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d1_r.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cc.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cc_with_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cl-all_layers.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cl-layer0.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cl-layer1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cr.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cr_with_corner_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_cr_with_nested_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rc.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rc_with_corner_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rc_with_nested_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rl-all_layers.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rl-layer0.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rl-layer1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rr.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rr_with_corner_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2_rr_with_nested_dim_labels.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2m_cc.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2m_cr.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2m_rc.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d2m_rr.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d3-layer0_0.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d3-layer0_1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/d3-layer1_2.expected create mode 100644 rust/pspp/src/output/pivot/testdata/dimension_borders_1.expected create mode 100644 rust/pspp/src/output/pivot/testdata/dimension_borders_2.expected create mode 100644 rust/pspp/src/output/pivot/testdata/empty_groups.expected create mode 100644 rust/pspp/src/output/pivot/testdata/footnote_alphabetic_subscript.expected create mode 100644 rust/pspp/src/output/pivot/testdata/footnote_alphabetic_superscript.expected create mode 100644 rust/pspp/src/output/pivot/testdata/footnote_hidden.expected create mode 100644 rust/pspp/src/output/pivot/testdata/footnote_numeric_subscript.expected create mode 100644 rust/pspp/src/output/pivot/testdata/footnote_numeric_superscript.expected create mode 100644 rust/pspp/src/output/pivot/testdata/metadata_entry.expected create mode 100644 rust/pspp/src/output/pivot/testdata/no_dimension.expected create mode 100644 rust/pspp/src/output/pivot/testdata/no_title_or_caption.expected create mode 100644 rust/pspp/src/output/pivot/testdata/one_empty_dimension.expected create mode 100644 rust/pspp/src/output/pivot/testdata/small_numbers.expected create mode 100644 rust/pspp/src/output/pivot/testdata/three_dimensions_two_empty.expected create mode 100644 rust/pspp/src/output/pivot/testdata/title_and_caption.expected create mode 100644 rust/pspp/src/output/pivot/testdata/two_empty_dimensions.expected create mode 100644 rust/pspp/src/output/spv/css.rs create mode 100644 rust/pspp/src/output/spv/html.rs create mode 100644 rust/pspp/src/output/spv/legacy_bin.rs create mode 100644 rust/pspp/src/output/spv/legacy_xml.rs create mode 100644 rust/pspp/src/output/spv/light.rs delete mode 100644 rust/pspp/src/show.rs delete mode 100644 rust/pspp/src/show_pc.rs delete mode 100644 rust/pspp/src/show_por.rs create mode 100644 rust/rustfmt.toml diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 74ed653cff..2a7afa6850 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -227,6 +227,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -528,6 +534,40 @@ dependencies = [ "memchr", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.101", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -625,6 +665,12 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "either" version = "1.15.0" @@ -682,6 +728,27 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "enumset" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -711,6 +778,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "erased-serde" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + [[package]] name = "errno" version = "0.3.12" @@ -721,12 +799,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "flagset" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" - [[package]] name = "flate2" version = "1.1.1" @@ -738,6 +810,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foldhash" version = "0.1.5" @@ -1014,6 +1092,21 @@ dependencies = [ "digest", ] +[[package]] +name = "html_parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f56db07b6612644f6f7719f8ef944f75fff9d6378fdf3d316fd32194184abd" +dependencies = [ + "doc-comment", + "pest", + "pest_derive", + "serde", + "serde_derive", + "serde_json", + "thiserror", +] + [[package]] name = "httparse" version = "1.10.1" @@ -1130,6 +1223,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -1619,6 +1718,49 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "pest_meta" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" +dependencies = [ + "pest", + "sha2", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -1731,7 +1873,7 @@ dependencies = [ "aes", "anyhow", "binrw", - "bitflags 2.9.1", + "bit-vec", "cairo-rs", "chardetng", "chrono", @@ -1747,10 +1889,12 @@ dependencies = [ "encoding_rs", "enum-iterator", "enum-map", - "flagset", + "enumset", + "erased-serde", "flate2", "hashbrown 0.15.5", "hexplay", + "html_parser", "indexmap", "itertools 0.14.0", "libc", @@ -1760,12 +1904,14 @@ dependencies = [ "ordered-float", "pango", "pangocairo", + "paper-sizes", "pspp-derive", "quick-xml", "rand", "readpass", "serde", "serde_json", + "serde_path_to_error", "smallstr", "smallvec", "thiserror", @@ -1803,9 +1949,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.5" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" dependencies = [ "memchr", "serde", @@ -1996,6 +2142,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + [[package]] name = "serde_repr" version = "0.1.20" @@ -2036,6 +2193,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2435,12 +2603,24 @@ dependencies = [ "once_cell", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unicase" version = "2.8.1" diff --git a/rust/doc/src/SUMMARY.md b/rust/doc/src/SUMMARY.md index 4c10ae8220..b35c29d723 100644 --- a/rust/doc/src/SUMMARY.md +++ b/rust/doc/src/SUMMARY.md @@ -4,11 +4,14 @@ [License](license.md) - [Running PSPP](invoking/index.md) - - [Converting Data](invoking/pspp-convert.md) + - [Converting Files](invoking/pspp-convert.md) - [Inspecting System Files](invoking/pspp-show.md) - [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) # Language Overview diff --git a/rust/doc/src/commands/set.md b/rust/doc/src/commands/set.md index 0814ba8942..774f57e197 100644 --- a/rust/doc/src/commands/set.md +++ b/rust/doc/src/commands/set.md @@ -24,7 +24,7 @@ SET /SCALEMIN=COUNT (data output) - /CC{A,B,C,D,E}={'NPRE,PRE,SUF,NSUF','NPRE.PRE.SUF.NSUF'} + /CC{A,B,C,D,E}='STRING' /DECIMAL={DOT,COMMA} /FORMAT=FMT_SPEC /LEADZERO={ON,OFF} @@ -46,13 +46,13 @@ SET /TVARS={NAMES,LABELS,BOTH} /TLOOK={NONE,FILE} -(logging) +(journal) /JOURNAL={ON,OFF} ['FILE_NAME'] (system files) /SCOMPRESSION={ON,OFF} -(miscellaneous) +(security) /SAFER=ON /LOCALE='STRING' @@ -62,7 +62,7 @@ SET /MITERATE=NUMBER /MNEST=NUMBER -(settings not yet implemented, but accepted and ignored) +(not yet implemented) /BASETEXTDIRECTION={AUTOMATIC,RIGHTTOLEFT,LEFTTORIGHT} /BLOCK='C' /BOX={'XXX','XXXXXXXXXXX'} @@ -80,8 +80,21 @@ 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. + + +# Data Input + +``` +SET + /BLANKS={SYSMIS,'.',number} + /DECIMAL={DOT,COMMA} + /FORMAT=FMT_SPEC + /EPOCH={AUTOMATIC,YEAR} + /RIB={NATIVE,MSBFIRST,LSBFIRST} +``` + 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 +135,15 @@ files. The data input subcommands are default, is equivalent to `MSBFIRST` or `LSBFIRST` depending on the native format of the machine running PSPP. +# Interaction + +``` +SET + /MXERRS=MAX_ERRS + /MXWARNS=MAX_WARNINGS + /WORKSPACE=WORKSPACE_SIZE +``` + Interaction subcommands affect the way that PSPP interacts with an online user. The interaction subcommands are @@ -136,6 +158,18 @@ online user. The interaction subcommands are are issued, except a single initial warning advising you that warnings will not be given. The default value is 100. +# Syntax Execution + +``` +SET + /LOCALE='LOCALE' + /MXLOOPS=MAX_LOOPS + /SEED={RANDOM,SEED_VALUE} + /UNDEFINED={WARN,NOWARN} + /FUZZBITS=FUZZBITS + /SCALEMIN=COUNT +``` + Syntax execution subcommands control the way that PSPP commands execute. The syntax execution subcommands are @@ -184,6 +218,19 @@ execute. The syntax execution subcommands are virtual memory management, setting a very large workspace may cause PSPP to abort. +# Data Output + +``` +SET + /CC{A,B,C,D,E}='STRING' + /DECIMAL={DOT,COMMA} + /FORMAT=FMT_SPEC + /LEADZERO={ON,OFF} + /MDISPLAY={TEXT,TABLES} + /SMALL=NUMBER + /WIB={NATIVE,MSBFIRST,LSBFIRST} +``` + Data output subcommands affect the format of output data. These subcommands are @@ -236,6 +283,16 @@ subcommands are default, is equivalent to `MSBFIRST` or `LSBFIRST` depending on the native format of the machine running PSPP. +# Output Routing + +``` +SET + /ERRORS={ON,OFF,TERMINAL,LISTING,BOTH,NONE} + /MESSAGES={ON,OFF,TERMINAL,LISTING,BOTH,NONE} + /PRINTBACK={ON,OFF,TERMINAL,LISTING,BOTH,NONE} + /RESULTS={ON,OFF,TERMINAL,LISTING,BOTH,NONE} +``` + 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 +332,18 @@ These output routing subcommands are: These subcommands have no effect on output in the PSPP GUI environment. +# Output Driver + +``` +SET + /HEADERS={NO,YES,BLANK} + /LENGTH={NONE,N_LINES} + /WIDTH={NARROW,WIDTH,N_CHARACTERS} + /TNUMBERS={VALUES,LABELS,BOTH} + /TVARS={NAMES,LABELS,BOTH} + /TLOOK={NONE,FILE} +``` + Output driver option subcommands affect output drivers' settings. These subcommands are: @@ -313,7 +382,14 @@ 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 + +``` +SET + /JOURNAL={ON,OFF} ['FILE_NAME'] +``` + +Journal subcommands affect logging of commands executed to external files. These subcommands are * `JOURNAL` @@ -328,6 +404,13 @@ files. These subcommands are The journal is named `pspp.jnl` by default. A different name may be specified. +# System Files + +``` +SET + /SCOMPRESSION={ON,OFF} +``` + System file subcommands affect the default format of system files produced by PSPP. These subcommands are @@ -335,6 +418,14 @@ produced by PSPP. These subcommands are Whether system files created by `SAVE` or `XSAVE` are compressed by default. The default is `ON`. +# Security + +``` +SET + /SAFER=ON + /LOCALE='STRING' +``` + Security subcommands affect the operations that commands are allowed to perform. The security subcommands are @@ -377,6 +468,16 @@ to perform. The security subcommands are Contrary to intuition, this command does not affect any aspect of the system's locale. +# Macros + +``` +SET + /MEXPAND={ON,OFF} + /MPRINT={ON,OFF} + /MITERATE=NUMBER + /MNEST=NUMBER +``` + The following subcommands affect the interpretation of macros. For more information, see [Macro Settings](define.md#macro-settings). @@ -399,6 +500,20 @@ 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 + +``` +SET + /BASETEXTDIRECTION={AUTOMATIC,RIGHTTOLEFT,LEFTTORIGHT} + /BLOCK='C' + /BOX={'XXX','XXXXXXXXXXX'} + /CACHE={ON,OFF} + /CELLSBREAK=NUMBER + /COMPRESSION={ON,OFF} + /CMPTRANS={ON,OFF} + /HEADER={NO,YES,BLANK} +``` + The following subcommands are not yet implemented, but PSPP accepts them and ignores the settings: diff --git a/rust/doc/src/invoking/output.md b/rust/doc/src/invoking/output.md new file mode 100644 index 0000000000..920ffec573 --- /dev/null +++ b/rust/doc/src/invoking/output.md @@ -0,0 +1,273 @@ +# Output Drivers + +PSPP has output drivers for several formats. This section documents +the supported formats and how they can be configured: + + + +# Text Output (`.txt` and `.text`) + +PSPP can produce plain text output, drawing boxes using ASCII or +Unicode line drawing characters. + +Plain text output is encoded in UTF-8. + +This driver has the following options: + +* `width = ` + Sets the maximum page width to the specified number of columns. To + fit in the given width, output table columns will be word-wrapped + or, if necessary, tables will be broken into multiple chunks. The + default is no maximum width. + +* `boxes = "unicode"` + `boxes = "ascii"` + Sets the style used for boxes in the output. The following shows an + example of each style: + + ``` + unicode ascii + ┌────┬────┐ +----+----+ + │ │ │ | | | + ├────┼────┤ +----+----+ + │ │ │ | | | + └────┴────┘ +----+----+ + ``` + + Unicode boxes are generally more attractive but they can be harder + to work with in some environments. The default is `unicode`. + +* `emphasis = ` + If this is set to true, then the output includes bold and underline + emphasis with overstriking. This is supported by only some + software, mainly on Unix. The default is `false`. + +# PDF Output (`.pdf`) + +This driver has the following options: + +* `page_setup = ` + Sets the page size, margins, and other parameters. The following + sub-options are available: + + - `initial_page_number = ` + The page number to use for the first page of output. The default + is 1. + + - `paper = ""` + Sets the page size. `` takes the form `x`, + e.g. `8.5x11in` or `210x297mm`, or the name of a standard paper + size, such as `letter` or `a4`. The default is system- and + user-dependent. + + - `margins = ""` + `margins = ["", ""]` + `margins = ["", "", ""]` + `margins = ["", "", "", ""]` + Sets the margins. Each variable is a quoted string with a length + and a unit, e.g. `10mm`. The one-value form sets all margins to + the same length; the two-value form sets the top and bottom + margins separately from left and right; and so on. The default is + `0.5in`. + + - `orientation = "portrait"` + `orientation = "landscape"` + Controls the output page orientation. The default is `"portrait"`. + + - `object_spacing = ""` + Sets the vertical spacing between output objects, such as tables + or text. `` includes a length and a unit, e.g. `10mm`. + The default is `12pt`, or 1/6 of an inch. + + - `chart_spacing = "as_is"` + `chart_spacing = "full_height"` + `chart_spacing = "half_height"` + `chart_spacing = "quarter_height"` + Sets the size of charts and graphs in the output. The default, + `"as_is"`, uses the size specified in the charts themselves. The + other possibilities set chart size in terms of the height of the + page. + + - `header = ""` + `footer = ""` + Sets the header, output at the top of each page, and the footer, + output at the bottom of each page. Both header and footer are + expressed in HTML. Only simple HTML features are supported, + including the following HTML elements: + + * ``, optionally, as a top-level element. + + * ``, optionally, as a first element enclosing a `