X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump-spo2.c;h=847dcac45c96ebb568ad515d3429edce9f2c018d;hb=96c7d3dc94c2e3f2d587e42382b541c5ec70ec9a;hp=33671632755321814dcae1ac86a1d78983fbf1cb;hpb=6ca1cdb717c55f8a4b4567285e9b44a8822504c9;p=pspp diff --git a/dump-spo2.c b/dump-spo2.c index 3367163275..847dcac45c 100644 --- a/dump-spo2.c +++ b/dump-spo2.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -248,15 +249,6 @@ all_utf8(const char *p_, size_t len) return true; } -static char * -get_string1(void) -{ - int len = data[pos++]; - char *s = xmemdup0(&data[pos], len); - pos += len; - return s; -} - static char * get_string2(void) { @@ -267,7 +259,49 @@ get_string2(void) } static char * -get_string(const char *where) +get_string1(void) +{ + int len = data[pos++]; + if (len == 0xff) + return get_string2(); + else + { + char *s = xmemdup0(&data[pos], len); + pos += len; + return s; + } +} + +static void +match_string1_assert(const char *exp, const char *where) +{ + int start = pos; + char *act = get_string1(); + if (strcmp(act, exp)) + { + fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n", + where, start, exp, act); + exit(1); + } +} +#define match_string1_assert(x) match_string1_assert(x, WHERE) + +static void +match_string2_assert(const char *exp, const char *where) +{ + int start = pos; + char *act = get_string2(); + if (strcmp(act, exp)) + { + fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n", + where, start, exp, act); + exit(1); + } +} +#define match_string2_assert(x) match_string2_assert(x, WHERE) + +static char * +get_string4(const char *where) { if (1 /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/ @@ -287,7 +321,15 @@ get_string(const char *where) exit(1); } } -#define get_string() get_string(WHERE) +#define get_string4() get_string4(WHERE) + +static char * +get_padded_string(int len) +{ + char *s = xmemdup0(&data[pos], len); + pos += len; + return s; +} static char * get_string_be(const char *where) @@ -406,6 +448,238 @@ format_name (int format, char *buf) } } +static void +parse_format(void) +{ + int d = data[pos++]; + int w = data[pos++]; + int fmt = data[pos++]; + char buf[32]; + printf ("%s%d.%d", format_name(fmt, buf), w, d); +} + +static void +parse_heading(const char *name) +{ + match_u16_assert(0xffff); + match_u16_assert(0); + match_string2_assert(name); +} + +static void +match_zeros_assert(int count, const char *where) +{ + for (int i = 0; i < count; i++) + if (data[pos + i]) + { + fprintf (stderr, + "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8"\n", + where, pos, count, i, data[pos + i]); + exit (1); + } + pos += count; +} +#define match_zeros_assert(count) match_zeros_assert(count, WHERE) + +static void +put_safe(const char *s) +{ + while (*s) + { + if (*s == '\n') + printf ("\\n"); + else if (*s == '\r') + printf ("\\r"); + else if (*s < 0x20 || *s > 0x7e) + printf ("\\x%02"PRIx8, (uint8_t) *s); + else + putchar (*s); + s++; + } +} + +static void +parse_DspString(void) +{ + if (match_byte(2)) + { + printf("DspString(%f, \"", get_double()); + printf("%s\")\n", get_string1()); + } + else + { + match_byte_assert(1); + printf ("DspString("); + parse_format(); + printf(" \""); + match_byte_assert(0); + match_byte_assert(1); + put_safe(get_string1()); + printf("\")\n"); + } +} + +static void +match_DspString(void) +{ /* 05 80 */ + match_byte_assert(5); + match_byte_assert(0x80); + parse_DspString(); +} + +static void +match_DspSimpleText(void) +{ /* 03 80 */ + match_byte_assert(3); + match_byte_assert(0x80); + match_zeros_assert(5); + if (!match_byte(0x10)) + match_byte_assert(0); + match_zeros_assert(4); +} + +static void +match_NavTreeViewItem(void) +{ /* 07 80 */ + match_byte_assert(7); + match_byte_assert(0x80); + match_zeros_assert(1); + if (!match_byte(0) && !match_byte(7)) + match_byte_assert(8); + match_zeros_assert(3); + pos++; + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(3); + if (!match_byte(0)) + match_byte_assert(1); + match_zeros_assert(5); + match_byte_assert(1); + match_zeros_assert(5); + + put_safe(get_string1()); + putc('\n', stdout); +} + +static void +parse_DspNumber(void) +{ + match_byte_assert(1); + printf("DspNumber("); + parse_format(); + match_byte_assert(0x80); + match_byte(2); + printf (" %f", get_double()); + printf (" \"%s\")\n", get_string1()); +} + +static void +match_DspNumber(void) +{ + match_byte_assert(0x2a); + match_byte_assert(0x80); + parse_DspNumber(); +} + +static void parse_flexible(void); + +static void +parse_DspCell(void) +{ + match_byte_assert(0); + match_DspSimpleText(); + parse_flexible(); /* DspString or DspNumber. */ +} + +static void +match_DspCell(void) +{ /* 27 80 */ + match_byte_assert(0x27); + match_byte_assert(0x80); + parse_DspCell(); +} + +static void +parse_PMModelItemInfo(void) +{ /* 54 80 */ + match_byte_assert(0); + pos += 1; /* Counter */ + match_zeros_assert(7); + pos += 3; + if (!match_byte(0)) + match_byte_assert(0xe); + match_byte_assert(0); +} + +static void +match_PMModelItemInfo(void) +{ /* 54 80 */ + match_byte_assert(0x54); + match_byte_assert(0x80); + parse_PMModelItemInfo(); + match_DspSimpleText(); + match_DspString(); +} + +static void +match_PMPivotItemTree(void) +{ /* 52 80 */ + match_byte_assert(0x52); + match_byte_assert(0x80); + match_byte_assert(0); + match_PMModelItemInfo(); +} + +static void +parse_flexible(void) +{ + if (data[pos] == 0xff && data[pos + 1] == 0xff) + { + match_u16_assert(0xffff); + match_u16_assert(0); + char *heading = get_string2(); + if (!strcmp(heading, "DspCell")) + parse_DspCell(); + else if (!strcmp(heading, "DspNumber")) + parse_DspNumber(); + else if (!strcmp(heading, "DspString")) + parse_DspString(); + else + assert(0); + } + else if (data[pos] == 0x2a && data[pos + 1] == 0x80) + match_DspNumber(); + else if (data[pos] == 0x27 && data[pos + 1] == 0x80) + match_DspCell(); + else if (data[pos] == 0x5 && data[pos + 1] == 0x80) + match_DspString(); + else if ((data[pos] == 0x3c || data[pos] == 0x39) + && data[pos + 1] == 0x80) + { + /* 3c 80 */ + /* 39 80 */ + pos += 2; + parse_format(); +/* match_byte_assert(0x01); + match_byte_assert(0x02); + match_byte_assert(0x0d); */ + } + else if (data[pos] == 0x15 && data[pos + 1] == 0x80) + { + /* 15 80 */ + data += 2; + match_byte_assert(2); + printf ("15 80(%f", get_double()); + printf (" %s)\n", get_string1()); + } + else + { + fprintf (stderr, "bad data cell 0x%02x at offset %x\n", + data[pos], pos); + hex_dump (stderr, pos, 64); + assert(0); + } +} int main(int argc, char *argv[]) @@ -463,5 +737,237 @@ main(int argc, char *argv[]) setvbuf (stdout, NULL, _IOLBF, 0); + match_byte_assert(4); + match_u32_assert(0); + match_string1_assert("SPSS Output Document"); + match_u32_assert(1); + match_byte_assert(0x63); + + parse_heading("NavRoot"); + match_byte_assert(2); + match_zeros_assert(32); + + parse_heading("DspSimpleText"); + match_zeros_assert(10); + + parse_heading("DspString"); + parse_DspString(); + + parse_heading("NavTreeViewItem"); + match_byte_assert(0); + match_u32_assert(0); + match_byte_assert(2); + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(9); + match_u32_assert(1); + assert (pos == 0xb0); + + pos += 0x28; + match_zeros_assert(5); + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos = 0x105; + match_string1_assert("(Continued)"); + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page title */ + match_byte_assert(1); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); /* page number */ + match_byte_assert(0); + pos += 2; + match_u16_assert(2); + + parse_heading("NavLog"); + pos = 0x36b; + puts(get_padded_string(32)); + if (!match_u32(80)) + match_u32_assert(132); + match_zeros_assert(8); + match_u32_assert(1); + get_string4(); + match_byte_assert(0); + + parse_heading("NavHead"); + match_byte_assert(2); + match_zeros_assert(24); + match_u32_assert(1); + match_u32_assert(0); + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + match_zeros_assert(3); + + parse_heading("NavTitle"); + pos += 33; + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + + match_byte_assert(1); + match_byte_assert(1); + match_u32_assert(-19); + match_zeros_assert(12); + match_byte_assert(0xbc); + match_byte_assert(2); + match_zeros_assert(9); + match_byte_assert(0x22); + puts(get_padded_string(32)); + match_u32_assert(80); + match_zeros_assert(8); + match_u32_assert(1); + get_string4(); + match_byte_assert(0); + + parse_heading("NavNote"); + match_byte_assert(2); + match_zeros_assert(8); + match_u32_assert(24); + if (!match_u32(0)) + match_u32_assert(-40); + pos += 8; + match_u32_assert(2); + match_u32_assert(1); + match_DspSimpleText(); + match_DspString(); + match_NavTreeViewItem(); + match_byte_assert(1); + + parse_heading("PTPivotController"); + match_byte_assert(2); + pos += 8; + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); + + parse_heading("PVPivotView"); + match_u32_assert(5); + match_byte_assert(0); + + parse_heading("PMPivotModel"); + match_byte_assert(3); + + parse_heading("NDimensional__DspCell"); + match_byte_assert(0); + match_u32_assert(1); + + parse_heading("IndexedCollection"); + match_byte_assert(0); + pos++; + match_zeros_assert(3); + match_byte_assert(1); + match_byte_assert(0); + + while (data[pos] != 1) + { + if (data[pos] == 0) + pos++; + else + parse_flexible(); + } + + match_byte_assert(1); + match_byte_assert(0); + puts(get_string1()); + if (!match_u32(0)) + match_u32_assert(2); + puts(get_string1()); + + match_byte_assert(0); + match_byte_assert(1); + match_byte_assert(0); + match_byte_assert(0); + match_byte_assert(0); + match_byte_assert(1); + match_byte_assert(0); + + exit (0); + + parse_heading("PMPivotItemTree"); + match_byte_assert(0); + + parse_heading("AbstractTreeBranch"); + match_byte_assert(0); + + parse_heading("PMModelItemInfo"); + parse_PMModelItemInfo(); + match_DspSimpleText(); + match_DspString(); + + match_u32_assert(7); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(6); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(2); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(2); + match_PMPivotItemTree(); + + match_u32_assert(0); + match_PMPivotItemTree(); + + match_u32_assert(0); + + /* ...unknown... */ + + while (data[pos] != 0xff || data[pos + 1] != 0xff) + pos++; + parse_heading("PVViewDimension"); + + int i; + for (i = 0; data[pos + i] != 0xff || data[pos + i + 1] != 0xff; i++) + ; + hex_dump(stdout, pos, i); + + printf ("%#x: end of successful parse\n", pos); + return 0; }