X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tests%2Fdissect-sysfile.c;h=d5994b3b845f484aa6f6d6e1371488056137304e;hb=51c3424bf88d0fa110683fbcdd208d0fa5c98179;hp=ecb8d59b77ac11d9d5f415a2886adf23234e0fba;hpb=c5ad65b0351ab1d897eb072eeaec06fb37802b01;p=pspp diff --git a/tests/dissect-sysfile.c b/tests/dissect-sysfile.c index ecb8d59b77..d5994b3b84 100644 --- a/tests/dissect-sysfile.c +++ b/tests/dissect-sysfile.c @@ -102,6 +102,7 @@ static void sys_error (struct sfm_reader *, const char *, ...) NO_RETURN; static void read_bytes (struct sfm_reader *, void *, size_t); +static bool try_read_bytes (struct sfm_reader *, void *, size_t); static int read_int (struct sfm_reader *); static int64_t read_int64 (struct sfm_reader *); static double read_float (struct sfm_reader *); @@ -126,7 +127,7 @@ main (int argc, char *argv[]) r.file_name = argv[i]; r.file = fopen (r.file_name, "rb"); if (r.file == NULL) - error (EXIT_FAILURE, errno, "error opening \"%s\"", r.file_name); + error (EXIT_FAILURE, errno, "error opening `%s'", r.file_name); r.n_variable_records = 0; r.n_variables = 0; r.n_var_widths = 0; @@ -165,9 +166,10 @@ main (int argc, char *argv[]) sys_error (&r, _("Unrecognized record type %d."), rec_type); } } - printf ("%08lx: end-of-dictionary record " - "(first byte of data at %08lx)\n", - ftell (r.file), ftell (r.file) + 4); + printf ("%08llx: end-of-dictionary record " + "(first byte of data at %08llx)\n", + (long long int) ftello (r.file), + (long long int) ftello (r.file) + 4); if (r.compressed) read_compressed_data (&r); @@ -309,8 +311,8 @@ read_variable_record (struct sfm_reader *r) int write_format; char name[9]; - printf ("%08lx: variable record #%d\n", - ftell (r->file), r->n_variable_records++); + printf ("%08llx: variable record #%d\n", + (long long int) ftello (r->file), r->n_variable_records++); width = read_int (r); has_variable_label = read_int (r); @@ -355,17 +357,21 @@ read_variable_record (struct sfm_reader *r) sys_error (r, _("Variable label indicator field is not 0 or 1.")); if (has_variable_label == 1) { - long int offset = ftell (r->file); - size_t len; + long long int offset = ftello (r->file); + size_t len, read_len; char label[255 + 1]; len = read_int (r); - if (len >= sizeof label) - sys_error (r, _("Variable %s has label of invalid length %zu."), - name, len); - read_string (r, label, len + 1); - printf("\t%08lx Variable label: \"%s\"\n", offset, label); + /* Read up to 255 bytes of label. */ + read_len = MIN (sizeof label - 1, len); + read_string (r, label, read_len + 1); + printf("\t%08llx Variable label: \"%s\"\n", offset, label); + + /* Skip unread label bytes. */ + skip_bytes (r, len - read_len); + + /* Skip label padding up to multiple of 4 bytes. */ skip_bytes (r, ROUND_UP (len, 4) - len); } @@ -374,7 +380,7 @@ read_variable_record (struct sfm_reader *r) { int i; - printf ("\t%08lx Missing values:", ftell (r->file)); + printf ("\t%08llx Missing values:", (long long int) ftello (r->file)); if (!width) { if (missing_value_code < -3 || missing_value_code > 3 @@ -429,7 +435,7 @@ read_value_label_record (struct sfm_reader *r) int label_cnt, var_cnt; int i; - printf ("%08lx: value labels record\n", ftell (r->file)); + printf ("%08llx: value labels record\n", (long long int) ftello (r->file)); /* Read number of labels. */ label_cnt = read_int (r); @@ -465,7 +471,7 @@ read_value_label_record (struct sfm_reader *r) /* Read number of variables associated with value label from type 4 record. */ - printf ("\t%08lx: apply to variables", ftell (r->file)); + printf ("\t%08llx: apply to variables", (long long int) ftello (r->file)); var_cnt = read_int (r); for (i = 0; i < var_cnt; i++) printf (" #%d", read_int (r)); @@ -478,14 +484,14 @@ read_document_record (struct sfm_reader *r) int n_lines; int i; - printf ("%08lx: document record\n", ftell (r->file)); + printf ("%08llx: document record\n", (long long int) ftello (r->file)); n_lines = read_int (r); printf ("\t%d lines of documents\n", n_lines); for (i = 0; i < n_lines; i++) { char line[81]; - printf ("\t%08lx: ", ftell (r->file)); + printf ("\t%08llx: ", (long long int) ftello (r->file)); read_string (r, line, sizeof line); trim_spaces (line); printf ("line %d: \"%s\"\n", i, line); @@ -495,13 +501,13 @@ read_document_record (struct sfm_reader *r) static void read_extension_record (struct sfm_reader *r) { - long int offset = ftell (r->file); + long long int offset = ftello (r->file); int subtype = read_int (r); size_t size = read_int (r); size_t count = read_int (r); size_t bytes = size * count; - printf ("%08lx: Record 7, subtype %d, size=%zu, count=%zu\n", + printf ("%08llx: Record 7, subtype %d, size=%zu, count=%zu\n", offset, subtype, size, count); switch (subtype) @@ -574,7 +580,7 @@ read_extension_record (struct sfm_reader *r) static void read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count) { - long int offset = ftell (r->file); + long long int offset = ftello (r->file); int version_major = read_int (r); int version_minor = read_int (r); int version_revision = read_int (r); @@ -584,7 +590,7 @@ read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count) int integer_representation = read_int (r); int character_code = read_int (r); - printf ("%08lx: machine integer info\n", offset); + 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."), @@ -610,12 +616,12 @@ read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count) static void read_machine_float_info (struct sfm_reader *r, size_t size, size_t count) { - long int offset = ftell (r->file); + long long int offset = ftello (r->file); double sysmis = read_float (r); double highest = read_float (r); double lowest = read_float (r); - printf ("%08lx: machine float info\n", offset); + printf ("%08llx: machine float info\n", offset); if (size != 8 || count != 3) sys_error (r, _("Bad size (%zu) or count (%zu) on extension 4."), size, count); @@ -642,7 +648,8 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count) { struct text_record *text; - printf ("%08lx: multiple response sets\n", ftell (r->file)); + printf ("%08llx: multiple response sets\n", + (long long int) ftello (r->file)); text = open_text_record (r, size * count); for (;;) { @@ -682,7 +689,7 @@ read_mrsets (struct sfm_reader *r, size_t size, size_t count) if (!text_match (text, ' ')) { - sys_warn (r, _("Missing space following 'E' at offset %zu " + sys_warn (r, _("Missing space following `E' at offset %zu " "in MRSETS record"), text_pos (text)); break; } @@ -691,14 +698,14 @@ 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)); } else { - sys_warn (r, "missing 'C', 'D', or 'E' at offset %zu " + sys_warn (r, "missing `C', `D', or `E' at offset %zu " "in mrsets record", text_pos (text)); break; } @@ -745,7 +752,8 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count) bool includes_width; size_t i; - printf ("%08lx: variable display parameters\n", ftell (r->file)); + printf ("%08llx: variable display parameters\n", + (long long int) ftello (r->file)); if (size != 4) { sys_warn (r, _("Bad size %zu on extension 11."), size); @@ -796,7 +804,8 @@ read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count) char *var; char *long_name; - printf ("%08lx: long variable names (short => long)\n", ftell (r->file)); + printf ("%08llx: long variable names (short => long)\n", + (long long int) ftello (r->file)); text = open_text_record (r, size * count); while (read_variable_to_value_pair (text, &var, &long_name)) printf ("\t%s => %s\n", var, long_name); @@ -812,7 +821,8 @@ read_long_string_map (struct sfm_reader *r, size_t size, size_t count) char *var; char *length_s; - printf ("%08lx: very long strings (variable => length)\n", ftell (r->file)); + printf ("%08llx: very long strings (variable => length)\n", + (long long int) ftello (r->file)); text = open_text_record (r, size * count); while (read_variable_to_value_pair (text, &var, &length_s)) printf ("\t%s => %d\n", var, atoi (length_s)); @@ -880,9 +890,9 @@ read_ncases64 (struct sfm_reader *r, size_t size, size_t count) } unknown = read_int64 (r); ncases64 = read_int64 (r); - printf ("%08lx: extended number of cases: " + printf ("%08llx: extended number of cases: " "unknown=%"PRId64", ncases64=%"PRId64"\n", - ftell (r->file), unknown, ncases64); + (long long int) ftello (r->file), unknown, ncases64); } static void @@ -890,7 +900,7 @@ read_datafile_attributes (struct sfm_reader *r, size_t size, size_t count) { struct text_record *text; - printf ("%08lx: datafile attributes\n", ftell (r->file)); + printf ("%08llx: datafile attributes\n", (long long int) ftello (r->file)); text = open_text_record (r, size * count); read_attributes (r, text, "datafile"); close_text_record (text); @@ -899,22 +909,22 @@ read_datafile_attributes (struct sfm_reader *r, size_t size, size_t count) static void read_character_encoding (struct sfm_reader *r, size_t size, size_t count) { - const unsigned long int posn = ftell (r->file); + long long int posn = ftello (r->file); char *encoding = xcalloc (size, count + 1); read_string (r, encoding, count + 1); - printf ("%08lx: Character Encoding: %s\n", posn, encoding); + printf ("%08llx: Character Encoding: %s\n", posn, encoding); } static void read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count) { - const long start = ftell (r->file); + long long int start = ftello (r->file); - printf ("%08lx: long string value labels\n", start); - while (ftell (r->file) - start < size * count) + printf ("%08llx: long string value labels\n", start); + while (ftello (r->file) - start < size * count) { - long posn = ftell (r->file); + long long posn = ftello (r->file); char var_name[VAR_NAME_LEN + 1]; int var_name_len; int n_values; @@ -933,7 +943,7 @@ read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count) width = read_int (r); n_values = read_int (r); - printf ("\t%08lx: %s, width %d, %d values\n", + printf ("\t%08llx: %s, width %d, %d values\n", posn, var_name, width, n_values); /* Read values. */ @@ -945,7 +955,7 @@ read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count) char *label; int label_length; - posn = ftell (r->file); + posn = ftello (r->file); /* Read value. */ value_length = read_int (r); @@ -957,7 +967,7 @@ read_long_string_value_labels (struct sfm_reader *r, size_t size, size_t count) label = xmalloc (label_length + 1); read_string (r, label, label_length + 1); - printf ("\t\t%08lx: \"%s\" (%d bytes) => \"%s\" (%d bytes)\n", + printf ("\t\t%08llx: \"%s\" (%d bytes) => \"%s\" (%d bytes)\n", posn, value, value_length, label, label_length); free (value); @@ -1045,7 +1055,7 @@ read_variable_attributes (struct sfm_reader *r, size_t size, size_t count) { struct text_record *text; - printf ("%08lx: variable attributes\n", ftell (r->file)); + printf ("%08llx: variable attributes\n", (long long int) ftello (r->file)); text = open_text_record (r, size * count); for (;;) { @@ -1061,21 +1071,22 @@ read_compressed_data (struct sfm_reader *r) { enum { N_OPCODES = 8 }; uint8_t opcodes[N_OPCODES]; - long int opcode_ofs; + long long int opcode_ofs; int opcode_idx; int case_num; int i; read_int (r); - printf ("\n%08lx: compressed data:\n", ftell (r->file)); + printf ("\n%08llx: compressed data:\n", (long long int) ftello (r->file)); opcode_idx = N_OPCODES; + opcode_ofs = 0; case_num = 0; for (case_num = 0; ; case_num++) { - printf ("%08lx: case %d's uncompressible data begins\n", - ftell (r->file), case_num); - for (i = 0; i < r->n_var_widths; i++) + printf ("%08llx: case %d's uncompressible data begins\n", + (long long int) ftello (r->file), case_num); + for (i = 0; i < r->n_var_widths; ) { int width = r->var_widths[i]; char raw_value[8]; @@ -1083,12 +1094,18 @@ read_compressed_data (struct sfm_reader *r) if (opcode_idx >= N_OPCODES) { - opcode_ofs = ftell (r->file); - read_bytes (r, opcodes, 8); + opcode_ofs = ftello (r->file); + if (i == 0) + { + if (!try_read_bytes (r, opcodes, 8)) + return; + } + else + read_bytes (r, opcodes, 8); opcode_idx = 0; } opcode = opcodes[opcode_idx]; - printf ("%08lx: variable %d: opcode %d: ", + printf ("%08llx: variable %d: opcode %d: ", opcode_ofs + opcode_idx, i, opcode); switch (opcode) @@ -1098,6 +1115,11 @@ read_compressed_data (struct sfm_reader *r) if (width != 0) printf (", but this is a string variable (width=%d)", width); printf ("\n"); + i++; + break; + + case 0: + printf ("ignored padding\n"); break; case 252: @@ -1109,6 +1131,7 @@ read_compressed_data (struct sfm_reader *r) printf ("uncompressible data: "); print_untyped_value (r, raw_value); printf ("\n"); + i++; break; case 254: @@ -1116,14 +1139,15 @@ read_compressed_data (struct sfm_reader *r) if (width == 0) printf (", but this is a numeric variable"); printf ("\n"); + i++; break; case 255: printf ("SYSMIS"); if (width != 0) printf (", but this is a string variable (width=%d)", width); - printf ("\n"); + i++; break; } @@ -1283,8 +1307,8 @@ usage (int exit_code) static void sys_msg (struct sfm_reader *r, const char *format, va_list args) { - printf ("\"%s\" near offset 0x%lx: ", - r->file_name, (unsigned long) ftell (r->file)); + printf ("\"%s\" near offset 0x%llx: ", + r->file_name, (long long int) ftello (r->file)); vprintf (format, args); putchar ('\n'); } @@ -1344,6 +1368,16 @@ read_bytes (struct sfm_reader *r, void *buf, size_t byte_cnt) read_bytes_internal (r, false, buf, byte_cnt); } +/* Reads BYTE_CNT bytes into BUF. + Returns true if exactly BYTE_CNT bytes are successfully read. + Returns false if an immediate end-of-file is encountered. + Aborts if an I/O error or a partial read occurs. */ +static bool +try_read_bytes (struct sfm_reader *r, void *buf, size_t byte_cnt) +{ + return read_bytes_internal (r, true, buf, byte_cnt); +} + /* Reads a 32-bit signed integer from R and returns its value in host format. */ static int