/* PSPP - a program for statistical analysis.
- Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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
size_t size, size_t count);
static void read_machine_float_info (struct sfm_reader *,
size_t size, size_t count);
+static void read_extra_product_info (struct sfm_reader *,
+ size_t size, size_t count);
static void read_mrsets (struct sfm_reader *, size_t size, size_t count);
static void read_display_parameters (struct sfm_reader *,
size_t size, size_t count);
size_t size, size_t count);
static void read_long_string_value_labels (struct sfm_reader *r,
size_t size, size_t count);
+static void read_long_string_missing_values (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 *, int max_cases);
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 const char *text_get_all (const struct text_record *);
static void usage (void);
static void sys_warn (struct sfm_reader *, const char *, ...)
static void skip_bytes (struct sfm_reader *, size_t);
static void trim_spaces (char *);
+static void print_string (const char *s, size_t len);
+
int
main (int argc, char *argv[])
{
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;
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);
read_mrsets (r, size, count);
return;
+ case 10:
+ read_extra_product_info (r, size, count);
+ return;
+
case 11:
read_display_parameters (r, size, count);
return;
read_long_string_value_labels (r, size, count);
return;
+ case 22:
+ read_long_string_missing_values (r, size, count);
+ return;
+
default:
sys_warn (r, "Unrecognized record type 7, subtype %d.", subtype);
read_unknown_extension (r, size, count);
sys_error (r, "Bad size (%zu) or count (%zu) on extension 4.",
size, count);
- printf ("\tsysmis: %g\n", sysmis);
+ printf ("\tsysmis: %g (%a)\n", sysmis, sysmis);
if (sysmis != SYSMIS)
- sys_warn (r, "File specifies unexpected value %g as %s.",
- sysmis, "SYSMIS");
+ sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
+ sysmis, sysmis, "SYSMIS");
- printf ("\thighest: %g\n", highest);
+ printf ("\thighest: %g (%a)\n", highest, highest);
if (highest != HIGHEST)
- sys_warn (r, "File specifies unexpected value %g as %s.",
- highest, "HIGHEST");
+ sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
+ highest, highest, "HIGHEST");
+
+ printf ("\tlowest: %g (%a)\n", lowest, lowest);
+ if (lowest != LOWEST && lowest != SYSMIS)
+ sys_warn (r, "File specifies unexpected value %g (%a) as %s.",
+ lowest, lowest, "LOWEST");
+}
+
+static void
+read_extra_product_info (struct sfm_reader *r,
+ size_t size, size_t count)
+{
+ struct text_record *text;
+ const char *s;
- printf ("\tlowest: %g\n", lowest);
- if (lowest != LOWEST)
- sys_warn (r, "File specifies unexpected value %g as %s.",
- lowest, "LOWEST");
+ printf ("%08llx: extra product info\n", (long long int) ftello (r->file));
+ text = open_text_record (r, size * count);
+ s = text_get_all (text);
+ print_string (s, strlen (s));
+ close_text_record (text);
}
/* Read record type 7, subtype 7. */
}
}
+static void
+read_long_string_missing_values (struct sfm_reader *r,
+ size_t size, size_t count)
+{
+ long long int start = ftello (r->file);
+
+ printf ("%08llx: long string missing values\n", start);
+ while (ftello (r->file) - start < size * count)
+ {
+ long long posn = ftello (r->file);
+ char var_name[ID_MAX_LEN + 1];
+ uint8_t n_missing_values;
+ int var_name_len;
+ int i;
+
+ /* 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.",
+ var_name_len, ID_MAX_LEN);
+ read_string (r, var_name, var_name_len + 1);
+
+ /* Read number of values. */
+ read_bytes (r, &n_missing_values, 1);
+
+ printf ("\t%08llx: %s, %d missing values:",
+ posn, var_name, n_missing_values);
+
+ /* Read values. */
+ for (i = 0; i < n_missing_values; i++)
+ {
+ char *value;
+ int value_length;
+
+ posn = ftello (r->file);
+
+ /* Read value. */
+ value_length = read_int (r);
+ value = xmalloc (value_length + 1);
+ read_string (r, value, value_length + 1);
+
+ printf (" \"%s\"", value);
+
+ free (value);
+ }
+ printf ("\n");
+ }
+}
+
static void
hex_dump (size_t offset, const void *buffer_, size_t buffer_size)
{
{
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);
- }
- else
- hex_dump (0, buffer, count);
+ print_string (CHAR_CAST (char *, buffer), count);
free (buffer);
}
}
{
return text->pos;
}
+
+static const char *
+text_get_all (const struct text_record *text)
+{
+ return text->buffer;
+}
\f
static void
usage (void)
end--;
*end = '\0';
}
+
+static void
+print_string (const char *s, size_t len)
+{
+ if (memchr (s, 0, len) == 0)
+ {
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ {
+ unsigned char c = s[i];
+
+ if (c == '\\')
+ printf ("\\\\");
+ else if (c == '\n' || isprint (c))
+ putchar (c);
+ else
+ printf ("\\%02x", c);
+ }
+ putchar ('\n');
+ }
+ else
+ hex_dump (0, s, len);
+}