X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump-spo2.c;h=d59ab7ba63c04de8d7dfb1fee05e34bbef9df99b;hb=3de0178afea2e6f4efd708b5a41db865955ac8ef;hp=a76aff97621ba9a17efa4d7299a662a4eeee1ad7;hpb=044a792171add4cdec5f5ee1e2d4d47059665232;p=pspp diff --git a/dump-spo2.c b/dump-spo2.c index a76aff9762..d59ab7ba63 100644 --- a/dump-spo2.c +++ b/dump-spo2.c @@ -25,6 +25,9 @@ unsigned int pos; #define STR(x) XSTR(x) #define WHERE __FILE__":" STR(__LINE__) +static void __attribute__((unused)) +hex_dump(FILE *stream, int ofs, int n); + static uint8_t get_byte(void) { @@ -109,7 +112,8 @@ match_u32_assert(uint32_t x, const char *where) unsigned int y = get_u32(); if (x != y) { - fprintf(stderr, "%s: 0x%x: expected i%u, got i%u\n", where, pos - 4, x, y); + fprintf(stderr, "%s: 0x%x: expected i%u, got i%u: ", where, pos - 4, x, y); + hex_dump(stderr, pos - 4, 64); exit(1); } } @@ -186,7 +190,8 @@ match_byte_assert(uint8_t b, const char *where) { if (!match_byte(b)) { - fprintf(stderr, "%s: 0x%x: expected %02x, got %02x\n", where, pos, b, data[pos]); + fprintf(stderr, "%s: 0x%x: expected %02x, got %02x: ", where, pos, b, data[pos]); + hex_dump(stderr, pos, 64); exit(1); } } @@ -249,13 +254,27 @@ all_utf8(const char *p_, size_t len) return true; } +static char * +get_string2(void) +{ + int len = data[pos] + data[pos + 1] * 256; + char *s = xmemdup0(&data[pos + 2], len); + pos += 2 + len; + return s; +} + static char * get_string1(void) { int len = data[pos++]; - char *s = xmemdup0(&data[pos], len); - pos += len; - return s; + if (len == 0xff) + return get_string2(); + else + { + char *s = xmemdup0(&data[pos], len); + pos += len; + return s; + } } static void @@ -272,15 +291,6 @@ match_string1_assert(const char *exp, const char *where) } #define match_string1_assert(x) match_string1_assert(x, WHERE) -static char * -get_string2(void) -{ - int len = data[pos] + data[pos + 1] * 256; - char *s = xmemdup0(&data[pos + 2], len); - pos += 2 + len; - return s; -} - static void match_string2_assert(const char *exp, const char *where) { @@ -302,7 +312,8 @@ get_string4(const char *where) /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/ /*&& all_ascii(&data[pos + 4], data[pos])*/) { - int len = data[pos] + data[pos + 1] * 256; + assert(data[pos + 3] == 0); + int len = data[pos] + data[pos + 1] * 256 + data[pos + 2] * 65536; char *s = malloc(len + 1); memcpy(s, &data[pos + 4], len); @@ -468,25 +479,53 @@ match_zeros_assert(int count, const char *where) if (data[pos + i]) { fprintf (stderr, - "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8"\n", + "%s: %#x: expected %d zeros here but offset %d is %#"PRIx8": ", where, pos, count, i, data[pos + i]); + hex_dump (stderr, pos, 64); 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_flexible(void); + static void parse_DspString(void) { - match_byte_assert(1); - match_byte_assert(2); - match_byte_assert(40); - if (!match_byte(0)) - match_byte_assert(5); - match_byte_assert(0); - match_byte_assert(1); - printf ("DspString(\"%s\")\n", get_string1()); + printf("%#x: DspString(", pos); + if (match_byte(2)) + { + printf("%f, \"", get_double()); + printf("%s\")\n", get_string1()); + } + else + { + match_byte_assert(1); + parse_format(); + printf(" \""); + match_byte_assert(0); + match_byte_assert(1); + put_safe(get_string1()); + printf("\")\n"); + } } static void @@ -502,7 +541,29 @@ match_DspSimpleText(void) { /* 03 80 */ match_byte_assert(3); match_byte_assert(0x80); - match_zeros_assert(10); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(3); + if (!match_byte(0x10)) + match_byte_assert(0); + match_zeros_assert(4); + } +} + +static void +parse_weirdness(void) +{ + match_byte_assert(1); + get_u32(); + match_zeros_assert(12); + pos++; /* 90 or BC */ + if (!match_byte(2)) + match_byte_assert(1); + match_zeros_assert(5); + pos++; + match_zeros_assert(3); + puts(get_padded_string(32)); } static void @@ -511,21 +572,316 @@ match_NavTreeViewItem(void) match_byte_assert(7); match_byte_assert(0x80); match_zeros_assert(1); - if (!match_byte(0) && !match_byte(7)) + if (!match_byte(0) && !match_byte(7) && !match_byte(2)) match_byte_assert(8); match_zeros_assert(3); pos++; match_byte_assert(0); match_byte_assert(1); - match_zeros_assert(3); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(7); + if (!match_byte(0)) + match_byte_assert(1); + match_zeros_assert(5); + get_string1(); + if (match_byte(1)) + { + parse_weirdness(); + match_byte_assert(0); + pos++; + match_zeros_assert(11); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(2); + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos += 32; + get_string1(); + if (!match_byte(0)) + match_byte_assert(1); + pos++; + pos++; + pos++; + pos++; + 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_flexible(); + } + else + match_zeros_assert(3); + } + //fprintf(stderr, "%#x ", pos - 16); +} + +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_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_NavLog(void) +{ + match_byte_assert(2); + pos += 32; +} + +static void +match_NavLog(void) +{ /* 09 80 */ + match_byte_assert(9); + match_byte_assert(0x80); + parse_NavLog(); +} + +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(1); - match_zeros_assert(5); + 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_NavHead(void) +{ + match_byte_assert(2); + match_zeros_assert(24); + match_byte_assert(1); + match_zeros_assert(3); + if (!match_byte(1)) + match_byte_assert(0); + match_zeros_assert(3); + match_DspSimpleText(); + parse_flexible(); +} + +static void +parse_NavOleItem(void) +{ + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(2); + pos++; + match_zeros_assert(9); + match_byte_assert(1); + match_zeros_assert(10); match_byte_assert(1); match_zeros_assert(5); - puts(get_string1()); + get_string1(); + match_byte_assert(1); + parse_weirdness(); + match_byte_assert(0); + pos++; + match_zeros_assert(11); + match_byte_assert(1); + match_zeros_assert(3); + get_string4(); + match_byte_assert(0); +} + +static void +match_NavOleItem(void) +{ /* 0e 80 */ + match_byte_assert(0x0e); + match_byte_assert(0x80); + parse_NavOleItem(); +} + +static void +parse_NavTitle(void) +{ + match_byte_assert(2); + match_zeros_assert(8); + match_u32_assert(24); + get_u32(); + pos++; + if (!match_byte(3)) + match_byte_assert(4); + match_zeros_assert(2); + get_u32(); + match_u32_assert(2); + if (!match_u32(2)) + match_u32_assert(1); +} + +static void +parse_NavNote(void) +{ + 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); +} + +static void +parse_flexible(void) +{ + int start = pos; + 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 if (!strcmp(heading, "NavHead")) + parse_NavHead(); + else if (!strcmp(heading, "IndexedCollection")) + match_zeros_assert(14); + else if (!strcmp(heading, "NavOleItem")) + parse_NavOleItem(); + else if (!strcmp(heading, "NavTitle")) + parse_NavTitle(); + else if (!strcmp(heading, "NavNote")) + parse_NavNote(); + else + { + fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start); + hex_dump(stderr, pos, 64); + assert(0); + } + } + else if (data[pos + 1] == 0x80) + { + 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] == 0x7 && data[pos + 1] == 0x80) + match_NavTreeViewItem(); + else if (data[pos] == 0x3 && data[pos + 1] == 0x80) + match_DspSimpleText(); + 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 if (data[pos] == 0x9 && data[pos + 1] == 0x80) + { + match_NavLog(); + } + else if (data[pos] == 0xe) + match_NavOleItem(); + else + { + fprintf (stderr, "bad record 0x%02x at offset %x: ", + data[pos], pos); + hex_dump (stderr, pos, 64); + assert(0); + } + } + else if (match_byte(0xa)) + { + match_zeros_assert(5); + assert(pos == n); + exit (0); + } + else + { + fprintf (stderr, "bad record start at offset %x: ", pos); + hex_dump (stderr, pos, 64); + assert(0); + } } + + int main(int argc, char *argv[]) { @@ -567,7 +923,7 @@ main(int argc, char *argv[]) exit(1); } n = s.st_size; - data = malloc(n); + data = malloc(n + 256); if (!data) { perror("malloc"); @@ -578,6 +934,8 @@ main(int argc, char *argv[]) perror("read"); exit(1); } + for (int i = 0; i < 256; i++) + data[n + i] = i % 2 ? 0xaa : 0x55; close(fd); setvbuf (stdout, NULL, _IOLBF, 0); @@ -600,54 +958,80 @@ main(int argc, char *argv[]) parse_heading("NavTreeViewItem"); match_byte_assert(0); - match_u32_assert(0); + if (!match_u32(1)) + 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(0); + match_u32_assert(0x18); + if (!match_u32(0)) + match_u32_assert(0xffffffd8); + match_u32_assert(0xffffffde); + match_u32_assert(0x18); + if (!match_u32(0)) + match_u32_assert(0xffffffd8); + match_u32_assert(0x28); + match_u32_assert(0x28); + pos += 8; + if (data[pos] == 0) { - match_u32_assert(11000); - match_u32_assert(8500); + match_zeros_assert(5); + + if (match_u32(8500)) + match_u32_assert(11000); + else + { + match_u32_assert(11000); + match_u32_assert(8500); + } + pos += 32; + get_string1(); + if (!match_byte(0)) + match_byte_assert(1); + pos++; + pos++; + pos++; + pos++; + 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); } - 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); + if (data[pos + 9] != 'L') + exit(0); parse_heading("NavLog"); - pos = 0x36b; + parse_NavLog(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + parse_flexible(); + exit(0); puts(get_padded_string(32)); if (!match_u32(80)) match_u32_assert(132); match_zeros_assert(8); match_u32_assert(1); + printf ("0x%x\n", pos); 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(); + parse_NavHead(); match_NavTreeViewItem(); match_zeros_assert(3); @@ -711,18 +1095,107 @@ main(int argc, char *argv[]) match_zeros_assert(3); match_byte_assert(1); match_byte_assert(0); + match_zeros_assert(7); - parse_heading("DspCell"); + while (data[pos] != 1) + { + if (data[pos] == 0) + pos++; + else + parse_flexible(); + } + + match_byte_assert(1); match_byte_assert(0); - match_DspSimpleText(); + puts(get_string1()); + if (!match_u32(0)) + match_u32_assert(2); + puts(get_string1()); - parse_heading("DspNumber"); + match_byte_assert(0); match_byte_assert(1); - parse_format(); - match_byte_assert(0x80); - match_byte(2); - printf (" %f", get_double()); - printf (" \"%s\"\n", get_string1()); + 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);