X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=utilities%2Fpspp-dump-sav.c;h=98cb6f3b22ed7ae6673081365fce531c52984069;hb=c1708f027dfb623031bcccf2cee84aa4511fb824;hp=a23ce6b42087d1cb5286d96024b5f8c790c6ab09;hpb=c6a0811bac0249e4f0d60ad979d37c2719c6a020;p=pspp diff --git a/utilities/pspp-dump-sav.c b/utilities/pspp-dump-sav.c index a23ce6b420..98cb6f3b22 100644 --- a/utilities/pspp-dump-sav.c +++ b/utilities/pspp-dump-sav.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 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 @@ -18,11 +18,14 @@ #include #include +#include #include +#include #include #include #include "data/val-type.h" +#include "libpspp/cast.h" #include "libpspp/compiler.h" #include "libpspp/float-format.h" #include "libpspp/integer-format.h" @@ -31,11 +34,9 @@ #include "gl/error.h" #include "gl/minmax.h" #include "gl/progname.h" +#include "gl/version-etc.h" #include "gl/xalloc.h" -#include "gettext.h" -#define _(msgid) gettext (msgid) - #define ID_MAX_LEN 64 struct sfm_reader @@ -82,7 +83,7 @@ static void read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count); static void read_unknown_extension (struct sfm_reader *, size_t size, size_t count); -static void read_compressed_data (struct sfm_reader *); +static void read_compressed_data (struct sfm_reader *, int max_cases); static struct text_record *open_text_record ( struct sfm_reader *, size_t size); @@ -94,7 +95,7 @@ static bool text_match (struct text_record *text, int c); static const char *text_parse_counted_string (struct text_record *); static size_t text_pos (const struct text_record *); -static void usage (int exit_code); +static void usage (void); static void sys_warn (struct sfm_reader *, const char *, ...) PRINTF_FORMAT (2, 3); static void sys_error (struct sfm_reader *, const char *, ...) @@ -113,14 +114,53 @@ static void trim_spaces (char *); int main (int argc, char *argv[]) { + int max_cases = 0; struct sfm_reader r; int i; set_program_name (argv[0]); - if (argc < 2) - usage (EXIT_FAILURE); - for (i = 1; i < argc; i++) + for (;;) + { + static const struct option long_options[] = + { + { "data", optional_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 }, + }; + + int c; + + c = getopt_long (argc, argv, "d::hv", long_options, NULL); + if (c == -1) + break; + + switch (c) + { + case 'd': + max_cases = optarg ? atoi (optarg) : INT_MAX; + break; + + case 'v': + version_etc (stdout, "pspp-dump-sav", PACKAGE_NAME, PACKAGE_VERSION, + "Ben Pfaff", "John Darrington", NULL_SENTINEL); + exit (EXIT_SUCCESS); + + case 'h': + usage (); + exit (EXIT_SUCCESS); + + default: + exit (EXIT_FAILURE); + } + } + + if (optind == argc) + error (1, 0, "at least one non-option argument is required; " + "use --help for help"); + + for (i = optind; i < argc; i++) { int rec_type; @@ -135,7 +175,7 @@ main (int argc, char *argv[]) r.var_widths = 0; r.compressed = false; - if (argc > 2) + if (argc - optind > 1) printf ("Reading \"%s\":\n", r.file_name); read_header (&r); @@ -152,7 +192,7 @@ main (int argc, char *argv[]) break; case 4: - sys_error (&r, _("Misplaced type 4 record.")); + sys_error (&r, "Misplaced type 4 record."); case 6: read_document_record (&r); @@ -163,7 +203,7 @@ main (int argc, char *argv[]) break; default: - sys_error (&r, _("Unrecognized record type %d."), rec_type); + sys_error (&r, "Unrecognized record type %d.", rec_type); } } printf ("%08llx: end-of-dictionary record " @@ -171,8 +211,8 @@ main (int argc, char *argv[]) (long long int) ftello (r.file), (long long int) ftello (r.file) + 4); - if (r.compressed) - read_compressed_data (&r); + if (r.compressed && max_cases > 0) + read_compressed_data (&r, max_cases); fclose (r.file); } @@ -187,7 +227,6 @@ read_header (struct sfm_reader *r) char eye_catcher[61]; uint8_t raw_layout_code[4]; int32_t layout_code; - int32_t nominal_case_size; int32_t compressed; int32_t weight_index; int32_t ncases; @@ -200,7 +239,7 @@ read_header (struct sfm_reader *r) read_string (r, eye_catcher, sizeof eye_catcher); if (strcmp ("$FL2", rec_type) != 0) - sys_error (r, _("This is not an SPSS system file.")); + sys_error (r, "This is not an SPSS system file."); /* Identify integer format. */ read_bytes (r, raw_layout_code, sizeof raw_layout_code); @@ -210,11 +249,11 @@ read_header (struct sfm_reader *r) &r->integer_format)) || (r->integer_format != INTEGER_MSB_FIRST && r->integer_format != INTEGER_LSB_FIRST)) - sys_error (r, _("This is not an SPSS system file.")); + sys_error (r, "This is not an SPSS system file."); layout_code = integer_get (r->integer_format, raw_layout_code, sizeof raw_layout_code); - nominal_case_size = read_int (r); + read_int (r); /* Nominal case size (not actually useful). */ compressed = read_int (r); weight_index = read_int (r); ncases = read_int (r); @@ -225,9 +264,8 @@ read_header (struct sfm_reader *r) read_bytes (r, raw_bias, sizeof raw_bias); if (float_identify (100.0, raw_bias, sizeof raw_bias, &r->float_format) == 0) { - sys_warn (r, _("Compression bias is not the usual " - "value of 100, or system file uses unrecognized " - "floating-point format.")); + sys_warn (r, "Compression bias is not the usual value of 100, or system " + "file uses unrecognized floating-point format."); if (r->integer_format == INTEGER_MSB_FIRST) r->float_format = FLOAT_IEEE_DOUBLE_BE; else @@ -354,7 +392,7 @@ read_variable_record (struct sfm_reader *r) /* Get variable label, if any. */ if (has_variable_label != 0 && has_variable_label != 1) - sys_error (r, _("Variable label indicator field is not 0 or 1.")); + sys_error (r, "Variable label indicator field is not 0 or 1."); if (has_variable_label == 1) { long long int offset = ftello (r->file); @@ -385,8 +423,8 @@ read_variable_record (struct sfm_reader *r) { if (missing_value_code < -3 || missing_value_code > 3 || missing_value_code == -1) - sys_error (r, _("Numeric missing value indicator field is not " - "-3, -2, 0, 1, 2, or 3.")); + sys_error (r, "Numeric missing value indicator field is not " + "-3, -2, 0, 1, 2, or 3."); if (missing_value_code < 0) { double low = read_float (r); @@ -400,8 +438,8 @@ read_variable_record (struct sfm_reader *r) else if (width > 0) { if (missing_value_code < 1 || missing_value_code > 3) - sys_error (r, _("String missing value indicator field is not " - "0, 1, 2, or 3.")); + sys_error (r, "String missing value indicator field is not " + "0, 1, 2, or 3."); for (i = 0; i < missing_value_code; i++) { char string[9]; @@ -420,7 +458,7 @@ print_untyped_value (struct sfm_reader *r, char raw_value[8]) double value; value = float_get_double (r->float_format, raw_value); - for (n_printable = 0; n_printable < sizeof raw_value; n_printable++) + for (n_printable = 0; n_printable < 8; n_printable++) if (!isprint (raw_value[n_printable])) break; @@ -466,8 +504,8 @@ read_value_label_record (struct sfm_reader *r) /* Read record type of type 4 record. */ if (read_int (r) != 4) - sys_error (r, _("Variable index record (type 4) does not immediately " - "follow value label record (type 3) as it should.")); + sys_error (r, "Variable index record (type 4) does not immediately " + "follow value label record (type 3) as it should."); /* Read number of variables associated with value label from type 4 record. */ @@ -569,7 +607,7 @@ read_extension_record (struct sfm_reader *r) return; default: - sys_warn (r, _("Unrecognized record type 7, subtype %d."), subtype); + sys_warn (r, "Unrecognized record type 7, subtype %d.", subtype); read_unknown_extension (r, size, count); return; } @@ -592,9 +630,8 @@ read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count) printf ("%08llx: machine integer info\n", offset); if (size != 4 || count != 8) - sys_error (r, _("Bad size (%zu) or count (%zu) field on record type 7, " - "subtype 3."), - size, count); + sys_error (r, "Bad size (%zu) or count (%zu) field on record type 7, " + "subtype 3.", size, count); printf ("\tVersion: %d.%d.%d\n", version_major, version_minor, version_revision); @@ -623,22 +660,22 @@ read_machine_float_info (struct sfm_reader *r, size_t size, size_t count) printf ("%08llx: machine float info\n", offset); if (size != 8 || count != 3) - sys_error (r, _("Bad size (%zu) or count (%zu) on extension 4."), + sys_error (r, "Bad size (%zu) or count (%zu) on extension 4.", size, count); printf ("\tsysmis: %g\n", sysmis); if (sysmis != SYSMIS) - sys_warn (r, _("File specifies unexpected value %g as %s."), + sys_warn (r, "File specifies unexpected value %g as %s.", sysmis, "SYSMIS"); printf ("\thighest: %g\n", highest); if (highest != HIGHEST) - sys_warn (r, _("File specifies unexpected value %g as %s."), + sys_warn (r, "File specifies unexpected value %g as %s.", highest, "HIGHEST"); printf ("\tlowest: %g\n", lowest); if (lowest != LOWEST) - sys_warn (r, _("File specifies unexpected value %g as %s."), + sys_warn (r, "File specifies unexpected value %g as %s.", lowest, "LOWEST"); } @@ -689,8 +726,8 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count) if (!text_match (text, ' ')) { - sys_warn (r, _("Missing space following `%c' at offset %zu " - "in MRSETS record"), 'E', text_pos (text)); + sys_warn (r, "Missing space following `%c' at offset %zu " + "in MRSETS record", 'E', text_pos (text)); break; } @@ -698,8 +735,8 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count) if (!strcmp (number, "11")) label_from_var_label = true; else if (strcmp (number, "1")) - sys_warn (r, _("Unexpected label source value `%s' " - "following `E' at offset %zu in MRSETS record"), + sys_warn (r, "Unexpected label source value `%s' " + "following `E' at offset %zu in MRSETS record", number, text_pos (text)); } @@ -756,7 +793,7 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count) (long long int) ftello (r->file)); if (size != 4) { - sys_warn (r, _("Bad size %zu on extension 11."), size); + sys_warn (r, "Bad size %zu on extension 11.", size); skip_bytes (r, size * count); return; } @@ -768,7 +805,7 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count) includes_width = false; else { - sys_warn (r, _("Extension 11 has bad count %zu (for %zu variables)."), + sys_warn (r, "Extension 11 has bad count %zu (for %zu variables.", count, n_vars); skip_bytes (r, size * count); return; @@ -848,13 +885,13 @@ read_attributes (struct sfm_reader *r, struct text_record *text, const char *value = text_tokenize (text, '\n'); if (value == NULL) { - sys_warn (r, _("%s: Error parsing attribute value %s[%d]"), + sys_warn (r, "%s: Error parsing attribute value %s[%d]", variable, key, index); return false; } if (strlen (value) < 2 || value[0] != '\'' || value[strlen (value) - 1] != '\'') - sys_warn (r, _("%s: Attribute value %s[%d] is not quoted: %s"), + sys_warn (r, "%s: Attribute value %s[%d] is not quoted: %s", variable, key, index, value); else printf ("\t%s: %s[%d] = \"%.*s\"\n", @@ -878,13 +915,13 @@ read_ncases64 (struct sfm_reader *r, size_t size, size_t count) if (size != 8) { - sys_warn (r, _("Bad size %zu for extended number of cases."), size); + sys_warn (r, "Bad size %zu for extended number of cases.", size); skip_bytes (r, size * count); return; } if (count != 2) { - sys_warn (r, _("Bad count %zu for extended number of cases."), size); + sys_warn (r, "Bad count %zu for extended number of cases.", size); skip_bytes (r, size * count); return; } @@ -934,8 +971,8 @@ read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count) /* Read variable name. */ var_name_len = read_int (r); if (var_name_len > ID_MAX_LEN) - sys_error (r, _("Variable name length in long string value label " - "record (%d) exceeds %d-byte limit."), + sys_error (r, "Variable name length in long string value label " + "record (%d) exceeds %d-byte limit.", var_name_len, ID_MAX_LEN); read_string (r, var_name, var_name_len + 1); @@ -1033,17 +1070,20 @@ read_unknown_extension (struct sfm_reader *r, size_t size, size_t count) buffer = xmalloc (count); read_bytes (r, buffer, count); if (memchr (buffer, 0, count) == 0) - for (i = 0; i < count; i++) - { - unsigned char c = buffer[i]; - - if (c == '\\') - printf ("\\\\"); - else if (c == '\n' || isprint (c)) - putchar (c); - else - printf ("\\%02x", c); - } + { + for (i = 0; i < count; i++) + { + unsigned char c = buffer[i]; + + if (c == '\\') + printf ("\\\\"); + else if (c == '\n' || isprint (c)) + putchar (c); + else + printf ("\\%02x", c); + } + putchar ('\n'); + } else hex_dump (0, buffer, count); free (buffer); @@ -1067,7 +1107,7 @@ read_variable_attributes (struct sfm_reader *r, size_t size, size_t count) } static void -read_compressed_data (struct sfm_reader *r) +read_compressed_data (struct sfm_reader *r, int max_cases) { enum { N_OPCODES = 8 }; uint8_t opcodes[N_OPCODES]; @@ -1082,7 +1122,7 @@ read_compressed_data (struct sfm_reader *r) opcode_idx = N_OPCODES; opcode_ofs = 0; case_num = 0; - for (case_num = 0; ; case_num++) + for (case_num = 0; case_num < max_cases; case_num++) { printf ("%08llx: case %d's uncompressible data begins\n", (long long int) ftello (r->file), case_num); @@ -1295,12 +1335,18 @@ text_pos (const struct text_record *text) } static void -usage (int exit_code) +usage (void) { - printf ("usage: %s SYSFILE...\n" - "where each SYSFILE is the name of a system file\n", - program_name); - exit (exit_code); + printf ("\ +%s, a utility for dissecting system files.\n\ +Usage: %s [OPTION]... SYSFILE...\n\ +where each SYSFILE is the name of a system file.\n\ +\n\ +Options:\n\ + --data[=MAXCASES] print (up to MAXCASES cases of) compressed data\n\ + --help display this help and exit\n\ + --version output version information and exit\n", + program_name, program_name); } /* Displays a corruption message. */ @@ -1353,9 +1399,9 @@ read_bytes_internal (struct sfm_reader *r, bool eof_is_ok, if (bytes_read == byte_cnt) return true; else if (ferror (r->file)) - sys_error (r, _("System error: %s."), strerror (errno)); + sys_error (r, "System error: %s.", strerror (errno)); else if (!eof_is_ok || bytes_read != 0) - sys_error (r, _("Unexpected end of file.")); + sys_error (r, "Unexpected end of file."); else return false; }