X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump-spo2.c;h=a7100e60689792445d0af54aa6dcbde8b0765390;hb=75a05a0a68046957d9801db0bfc02b0108736e36;hp=d50d861fa428260e4d99bdde812da3517da056c7;hpb=6fbf3ec9ce0176ef805a18086b4cfe66df9cfbba;p=pspp diff --git a/dump-spo2.c b/dump-spo2.c index d50d861fa4..a7100e6068 100644 --- a/dump-spo2.c +++ b/dump-spo2.c @@ -21,10 +21,15 @@ int version; unsigned int pos; +static int n_dims; + #define XSTR(x) #x #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 +114,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); } } @@ -121,7 +127,8 @@ match_u16_assert(uint16_t x, const char *where) unsigned int y = get_u16(); if (x != y) { - fprintf(stderr, "%s: 0x%x: expected u16:%u, got u16:%u\n", where, pos - 2, x, y); + fprintf(stderr, "%s: 0x%x: expected u16:%u, got u16:%u: ", where, pos - 2, x, y); + hex_dump(stderr, pos - 2, 64); exit(1); } } @@ -186,7 +193,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); } } @@ -250,19 +258,43 @@ all_utf8(const char *p_, size_t len) } static char * -get_string1(void) +pull_string(int len, const char *where) { - int len = data[pos++]; + assert (len >= 0); + for (int i = 0; i < len - 1; i++) + if (!data[pos + i]) + { + fprintf(stderr, "%s: %d-byte string starting at 0x%x has null byte " + "at offset %d: ", where, len, pos, i); + hex_dump(stderr, pos, len + 64); + exit(1); + } + char *s = xmemdup0(&data[pos], len); pos += len; return s; } +static char * +get_string2(const char *where) +{ + return pull_string(get_u16(), where); +} +#define get_string2() get_string2(WHERE) + +static char * +get_string1(const char *where) +{ + int len = data[pos++]; + return len == 0xff ? (get_string2)(where) : pull_string(len, where); +} +#define get_string1() get_string1(WHERE) + static void match_string1_assert(const char *exp, const char *where) { int start = pos; - char *act = get_string1(); + char *act = (get_string1)(where); if (strcmp(act, exp)) { fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n", @@ -272,20 +304,11 @@ 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) { int start = pos; - char *act = get_string2(); + char *act = (get_string2)(where); if (strcmp(act, exp)) { fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n", @@ -296,27 +319,20 @@ match_string2_assert(const char *exp, const char *where) #define match_string2_assert(x) match_string2_assert(x, WHERE) static char * -get_string(const char *where) +get_string4(const char *where) { - if (1 - /*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; - char *s = malloc(len + 1); + assert(data[pos + 3] == 0); + return pull_string(get_u32(), where); +} +#define get_string4() get_string4(WHERE) - memcpy(s, &data[pos + 4], len); - s[len] = 0; - pos += 4 + len; - return s; - } - else - { - fprintf(stderr, "%s: 0x%x: expected string\n", where, pos); - exit(1); - } +static char * +get_padded_string(int len) +{ + char *s = xmemdup0(&data[pos], len); + pos += len; + return s; } -#define get_string() get_string(WHERE) static char * get_string_be(const char *where) @@ -435,41 +451,922 @@ 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); + printf("%#x: %s\n", pos, name); } static void -match_zeros_assert(int count) +match_zeros_assert(int count, const char *where) { for (int i = 0; i < count; i++) if (data[pos + i]) { fprintf (stderr, - "%#x: expected %d zeros here but offset %d is %#"PRIx8"\n", - pos, count, i, data[pos + i]); + "%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 int count; static void parse_DspString(void) { + printf("%#x: DspString#%d(", pos, count++); + 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 +match_DspString(void) +{ /* 05 80 */ + match_byte_assert(5); + match_byte_assert(0x80); + parse_DspString(); +} + +static void +parse_DspSimpleText(void) +{ + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(3); + if (!match_byte(0x10)) + match_byte_assert(0); + match_zeros_assert(4); + } + /* Followed by DspString or DspNumber. */ +} + +static void +match_DspSimpleText(void) +{ /* 03 80 */ + match_byte_assert(3); + match_byte_assert(0x80); + parse_DspSimpleText(); +} + +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 +parse_NavTreeViewItem(void) +{ /* 07 80 */ + int start_pos = pos; + match_zeros_assert(1); + if (!match_byte(0) && !match_byte(7) && !match_byte(2) && !match_byte(0xc)) + match_byte_assert(8); + match_zeros_assert(3); + pos++; + match_byte_assert(0); + match_byte_assert(1); + match_byte_assert(0); + if (match_byte(0)) + { + match_byte_assert(0); + if (!match_byte(1)) + match_byte_assert(0); + match_zeros_assert(5); + if (!match_byte(0)) + match_byte_assert(1); + match_zeros_assert(5); + get_string1(); + if (match_byte(1)) + { + if (data[pos] == 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); + hex_dump(stdout, start_pos, pos - start_pos); +} + +static void +match_NavTreeViewItem(void) +{ + match_byte_assert(7); + match_byte_assert(0x80); + parse_NavTreeViewItem(); +} + +static void +parse_DspNumber(void) +{ + printf("%#x: DspNumber#%d(", pos, count++); + match_byte_assert(1); + parse_format(); + match_byte_assert(0x80); + match_byte(2); + printf (" %f", get_double()); + printf (" \"%s\")\n", get_string1()); +} + +static void +match_DspNumber(void) +{ + if (!match_byte(0x18) && !match_byte(0x19)) + match_byte_assert(0x2a); + match_byte_assert(0x80); + parse_DspNumber(); +} + +static void +parse_DspCell(void) +{ + match_byte_assert(0); +} + +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_category(int level, int j, int *n_leaves) +{ + for (size_t k = 0; k < level; k++) + putchar('\t'); + get_u16(); match_byte_assert(0); + get_u16(); match_byte_assert(0); + int leaf_idx = get_u32(); + printf("%d ", leaf_idx); + match_u32_assert(0); + if (get_u16() == 0xffff) + match_u16_assert(0xffff); + else + match_u16_assert(0x0e74); + match_byte_assert(0); + match_DspSimpleText(); + match_DspString(); + + int n_subcategories = get_u32(); + if (n_subcategories) + assert (leaf_idx == 0); + else + { + assert (leaf_idx == *n_leaves); + ++*n_leaves; + } + for (int k = 0; k < n_subcategories; k++) + parse_category(level + 1, k, n_leaves); +} + +static void +parse_dimension(int i) +{ + printf ("%#x: dimension %d\n", pos, i); + if (i == 0) + { + match_zeros_assert(5); + match_u32_assert(1); + } + else + { + match_zeros_assert(6); + + int n_units16 = get_u32(); + match_u16_assert(1); + for (int j = 0; j < n_units16; j++) + get_u16(); + + match_byte_assert(0); + + int n_units32 = get_u32(); + match_u16_assert(0); + for (int j = 0; j < n_units32; j++) + get_u32(); + + get_u16(); match_byte_assert(0); + + get_u16(); match_byte_assert(0); + get_u16(); match_byte_assert(0); + match_u32_assert(0); + match_u32_assert(1); + } + + get_u16(); + if (!match_u16(0xffff)) + match_u16_assert(0x0e74); + match_byte_assert(0); + match_DspSimpleText(); + match_DspString(); + + int n_leaves = 0; + int n_categories = get_u32(); + for (int j = 0; j < n_categories; j++) + parse_category(1, j, &n_leaves); +} + +static void +parse_PMModelItemInfo(void) +{ + for (int i = 0; i < n_dims; i++) + parse_dimension(i); + printf("%#x: end of model\n", pos); + exit(0); +} + +static void +match_PMModelItemInfo(void) +{ /* 54 80 */ + match_byte_assert(0x54); + match_byte_assert(0x80); + parse_PMModelItemInfo(); + /* DspSimpleText */ + /* 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); + /* DspSimpleText */ +} + +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); + 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 or 12 80*/ + if (!match_byte(0x12)) + 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(0xffffff4b)) + match_u32_assert(-40); + pos += 8; + match_u32_assert(2); + if (!match_u32(2)) + match_u32_assert(1); +} + +static void +parse_PTPivotController(void) +{ + match_byte_assert(2); + pos += 8; + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); + match_u32_assert(100); +} + +static void +parse_PVPivotView(void) +{ + match_byte_assert(5); + printf ("PVPivotView(%d)\n", get_u32()); +} + +static void +parse_NDimensional__DspCell(void) +{ + match_byte_assert(0); + n_dims = get_u32(); + printf ("NDimensional__DspCell(n_dims=%d)\n", n_dims); +} + +static void +parse_IndexedCollection(void) +{ + printf("IndexedCollection"); + for (size_t i = 0; ; i++) + { + match_byte_assert(0); + printf("%c%d", i ? 'x' : '(', get_u32()); + match_u16_assert(1); + if (!match_u16(0x8011)) + break; + } + printf(")\n"); +} + +static void +parse_PTTableLook(void) +{ match_byte_assert(2); - match_byte_assert(40); - if (!match_byte(0)) - match_byte_assert(5); + match_byte_assert(2); + match_zeros_assert(7); + match_u32_assert(0x36); + match_u32_assert(0x12); +} + +static void +parse_PVViewDimension(void) +{ + while (data[pos + 1] != 0x80 + && (data[pos] != 0xff || data[pos + 1] != 0xff)) + { + assert(pos < n); + pos++; + } +} + +static void +parse_PVSeparatorStyle(void) +{ match_byte_assert(0); match_byte_assert(1); - printf ("DspString(\"%s\")\n", get_string1()); + match_zeros_assert(15); + pos++; + match_byte_assert(0x80); + match_byte_assert(0); + + match_byte_assert(1); + match_zeros_assert(9); + while (data[pos + 1] != 0x80 + && (data[pos] != 0xff || data[pos + 1] != 0xff)) + { + assert(pos < n); + pos++; + } +} + +static void +parse_PVCellStyle(void) +{ + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(5); + match_u32_assert(0xffffff); + match_zeros_assert(2); +} + +static void +skip_item(const char *name) +{ + int start_pos = pos; + printf("%#x: skipping %s bytes...", pos, name); + while (data[pos + 1] != 0x80 + && !(data[pos] == 0xff && data[pos + 1] == 0xff + && data[pos + 2] == 0 && data[pos + 3] == 0)) + { + assert(pos < n); + pos++; + } + printf("until %#x:", pos); + hex_dump(stdout, start_pos, pos - start_pos); +} + +static void +parse_flexible(void) +{ + int start = pos; + if (match_u16(0xffff)) + { + match_u16_assert(0); + char *heading = get_string2(); + printf("%#x: %s\n", pos, heading); + if (!strcmp(heading, "NavRoot")) + { + match_byte_assert(2); + match_zeros_assert(32); + } + else if (!strcmp(heading, "NavPivot")) + { + hex_dump(stdout, pos, 021); + pos += 0x21; + } + else if (!strcmp(heading, "DspCell")) + parse_DspCell(); + else if (!strcmp(heading, "DspSimpleText")) + parse_DspSimpleText(); + 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, "NavTreeViewItem")) + { + if (0) + parse_NavTreeViewItem(); + else + skip_item(heading); + } + else if (!strcmp(heading, "IndexedCollection")) + parse_IndexedCollection(); + else if (!strcmp(heading, "NavOleItem")) + parse_NavOleItem(); + else if (!strcmp(heading, "NavTitle")) + parse_NavTitle(); + else if (!strcmp(heading, "NavNote")) + parse_NavNote(); + else if (!strcmp(heading, "PTPivotController")) + parse_PTPivotController(); + else if (!strcmp(heading, "PVPivotView")) + parse_PVPivotView(); + else if (!strcmp(heading, "PMPivotModel")) + match_byte_assert(3); + else if (!strcmp(heading, "NDimensional__DspCell")) + parse_NDimensional__DspCell(); + else if (!strcmp(heading, "PMPivotItemTree")) + match_byte_assert(0); + else if (!strcmp(heading, "PMModelItemInfo")) + parse_PMModelItemInfo(); + else if (!strcmp(heading, "AbstractTreeBranch")) + match_byte_assert(0); + else if (!strcmp(heading, "PTTableLook")) + parse_PTTableLook(); + else if (!strcmp(heading, "PVViewDimension")) + parse_PVViewDimension(); + else if (!strcmp(heading, "PVSeparatorStyle")) + parse_PVSeparatorStyle(); + else if (!strcmp(heading, "PVCellStyle")) + parse_PVCellStyle(); + else if (!strcmp(heading, "PVTextStyle")) + exit(0); + else + { + fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start); + hex_dump(stderr, pos, 128); + assert(0); + } + } + else if (data[pos + 1] == 0x80) + { + if ((data[pos] == 0x2a || data[pos] == 0x18 || data[pos] == 0x19) && 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 */ + printf("%#x: %02x %02x ", pos, data[pos], data[pos + 1]); + pos += 2; + parse_format(); + printf ("\n"); +/* match_byte_assert(0x01); + match_byte_assert(0x02); + match_byte_assert(0x0d); */ + } + else if ((data[pos] == 0x15 || data[pos] == 0x14) + && data[pos + 1] == 0x80) + { + /* 14 80 */ + /* 15 80 */ + pos += 2; + if (match_byte(2)) + { + printf ("%02x 80(%f", data[pos - 2], get_double()); + printf (" \"%s\")\n", get_string1()); + if (match_byte(1)) + { + match_byte_assert(0); + get_string1(); + if (!match_byte(2) && !match_byte(3)) + match_byte_assert(0); + match_zeros_assert(3); + get_string1(); + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(3); + match_byte_assert(1); + match_byte_assert(0); + } + } + else + { + match_byte_assert(0); + } + } + else if (data[pos] == 0x17) + { + printf("%02x %02x(%02x %02x %02x)\n", + data[pos], data[pos + 1], + data[pos + 2], data[pos + 3], data[pos + 4]); + pos += 5; + } + else if (data[pos] == 0x9 && data[pos + 1] == 0x80) + { + match_NavLog(); + } + else if (data[pos] == 0xe || data[pos] == 0x12) + match_NavOleItem(); + else if (data[pos] == 0x11 || data[pos] == 0x13) + { + int type = data[pos]; + pos += 2; + match_byte_assert(0); + if (data[pos] != 0) + { + int x = get_u32(); + int y = get_u16(); + if (y == 0) + { + int index = get_u32(); + printf("%02x 80(footnote %d)\n", type, index); + } + else + printf("%02x 80(%d %d)\n", type, x, y); + } + else + match_zeros_assert(13); + } + else if (data[pos] == 0x29 || + data[pos] == 0x2b || + data[pos] == 0x2d || + data[pos] == 0x31 || + data[pos] == 0x32 || + data[pos] == 0x4a || + data[pos] == 0x4c || + data[pos] == 0x4f || + data[pos] == 0x4d || + data[pos] == 0x50 || + data[pos] == 0x36 || + data[pos] == 0x52 || + data[pos] == 0x53 || + data[pos] == 0x54 || + data[pos] == 0x55 || + data[pos] == 0x57 || + data[pos] == 0x56 || + data[pos] == 0x58 || + data[pos] == 0x5c || + data[pos] == 0x5b || + data[pos] == 0x5e || + data[pos] == 0x62 || + data[pos] == 0x64 || + data[pos] == 0x4e || + data[pos] == 0x51 || + data[pos] == 0x59 || + data[pos] == 0x5a || + data[pos] == 0x5d || + data[pos] == 0x66 || + data[pos] == 0x60 || + data[pos] == 0x68 || + data[pos] == 0x48 || + data[pos] == 0x6a || + data[pos] == 0x37) + { + pos += 2; + match_byte_assert(0); + } + else if (data[pos] == 0x2c || + data[pos] == 0x2e || + data[pos] == 0x30 || + data[pos] == 0x34 || + data[pos] == 0x3d || + data[pos] == 0x40 || + data[pos] == 0x3f || + data[pos] == 0x42 || + data[pos] == 0x43 || + data[pos] == 0x44 || + data[pos] == 0x49 || + data[pos] == 0x3e || + data[pos] == 0x46) + { + printf ("%#x: %02x %02x(%02x %02x %02x)\n", + pos, data[pos], data[pos + 1], + data[pos + 2], data[pos + 3], data[pos + 4]); + pos += 2; + pos += 3; + } + else + { + fprintf (stderr, "%#x: unknown record", pos); + hex_dump (stderr, pos, 64); + exit(1); + } + } + else if (match_byte(0xa)) + { + if (!match_byte(7)) + match_byte_assert(0); + if (match_u16(0x0e74)) + match_byte_assert(0); + else + { + match_zeros_assert(4); + if (pos == n) + exit (0); + match_zeros_assert (2); + } + } +#if 0 + else if (match_byte(1)) + { + match_byte_assert(0); + get_string1(); + if (!match_byte(2)) + match_byte_assert(0); + if (match_byte(0)) + { + match_zeros_assert(2); + get_string1(); + if (match_byte(0x08)) + { + match_byte_assert(0); + match_u16_assert(0x0e74); + match_byte_assert(0); + } + else if (match_byte(3)) + { + match_byte_assert(0); + if (match_u16(0x0e74)) + match_byte_assert(0); + else + { + match_zeros_assert(6); + if (!match_byte(0xe) && !match_byte(0x11)) + match_byte_assert(0); + match_byte_assert(0); + if (!match_u16(0x0e74)) + match_u16_assert(0); + match_byte_assert(0); + } + } + else + { + match_byte_assert(0); + match_byte_assert(1); + match_zeros_assert(3); + match_byte_assert(1); + match_byte_assert(0); + } + } + } +#endif + else if (match_u16(1)) + { + int start_pos = pos; + char *title = get_string1(); + printf("%#x: title(\"%s\", ", start_pos, title); + if (!match_u32(2)) + match_u32_assert(0); + char *id = get_string1(); + printf("\"%s\")\n", id); + match_byte_assert(0); + if (!match_u32(2)) + match_u32_assert(3); + match_u16_assert(1); + } + else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9)) + skip_item("unknown"); +#if 0 + else if (match_byte(7) || match_byte(4) || match_byte(5) || match_byte(6) || match_byte(8) || match_byte(9) || match_byte(0xb) || match_byte(0xc) || match_byte(0x15) || match_byte(0x16) || match_byte(0x17) || match_byte(0x18) || match_byte(0x1e) || match_byte(0x1a)) + { + if (!match_byte(7)) + match_byte_assert(0); + if (!match_u16(0x0e74)) + match_byte_assert(0); + match_byte_assert(0); + } + else if (match_byte(2) || match_byte(3)) + { + match_byte_assert(0); + if (!match_u16(0x0e74)) + { + match_zeros_assert(2); + if (match_byte(0)) + { + match_zeros_assert(3); + if (match_byte(0)) + match_zeros_assert(4); + else + { + pos++; + match_byte(0); + match_u16_assert(0x0e74); + } + } + } + //match_byte_assert(0); + } + else if (match_byte(0xd) || match_byte(0xe) || match_byte(0xf) + || match_byte(0x11) || match_byte(0x12) || match_byte(0x13) + || match_byte(0x14) || match_byte(0x1b)) + { + if (!match_byte(0x07)) + match_byte_assert(0); + if (!match_u16(0x0e74)) + match_zeros_assert(11); + else + match_byte_assert(0); + } + else if (match_byte(0xe3) || match_byte(0xdb) || match_byte(0xd8) || match_byte(0xe9) || match_byte(0xf3)) + { + match_byte_assert(0x0e); + match_byte_assert(0x74); + match_byte_assert(0x0e); + match_byte_assert(0); + } + else if (match_byte(0x9d) || match_byte(0x9e) || match_byte(0x9c)) + match_u32_assert(0x000e741a); + else if (match_byte(0x10)) + { + match_byte_assert(0); + if (match_byte(0)) + match_zeros_assert(10); + else + { + match_u16_assert(0x0e74); + match_byte_assert(0); + } + } + else if (match_byte(0x39) || match_byte(0x3a) || match_byte(0x3b)) + match_u32_assert(0x000e7409); + else + { + //fprintf (stderr, "bad record start at offset %x: ", pos); + hex_dump (stderr, pos, 64); + assert(0); + } +#endif } + + int main(int argc, char *argv[]) { @@ -511,7 +1408,7 @@ main(int argc, char *argv[]) exit(1); } n = s.st_size; - data = malloc(n); + data = malloc(n + 256); if (!data) { perror("malloc"); @@ -522,9 +1419,11 @@ 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); + setvbuf (stdout, NULL, _IONBF, 0); match_byte_assert(4); match_u32_assert(0); @@ -532,6 +1431,18 @@ main(int argc, char *argv[]) match_u32_assert(1); match_byte_assert(0x63); + for (;;) + { + if (data[pos] == 0) + { + //printf("zero\n"); + pos++; + } + else + parse_flexible(); + } + exit(0); + parse_heading("NavRoot"); match_byte_assert(2); match_zeros_assert(32); @@ -543,7 +1454,248 @@ main(int argc, char *argv[]) parse_DspString(); parse_heading("NavTreeViewItem"); - + match_byte_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); + + 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_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); + } + + if (data[pos + 9] != 'L') + exit(0); + parse_heading("NavLog"); + parse_NavLog(); + for (;;) + { + if (data[pos] == 0) + { + //printf("zero\n"); + pos++; + } + else + 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"); + parse_NavHead(); + 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); + match_zeros_assert(7); + + while (data[pos] != 1) + { + if (data[pos] == 0) + { + printf("zero\n"); + 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);