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)
{
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);
}
}
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);
}
}
{
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);
}
}
}
static char *
-get_string2(void)
+pull_string(int len, const char *where)
{
- int len = data[pos] + data[pos + 1] * 256;
- char *s = xmemdup0(&data[pos + 2], len);
- pos += 2 + len;
+ 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_string1(void)
+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++];
- if (len == 0xff)
- return get_string2();
- else
- {
- char *s = xmemdup0(&data[pos], len);
- pos += len;
- return s;
- }
+ 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",
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",
static char *
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);
-
- 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);
- }
+ assert(data[pos + 3] == 0);
+ return pull_string(get_u32(), where);
}
#define get_string4() get_string4(WHERE)
match_u16_assert(0xffff);
match_u16_assert(0);
match_string2_assert(name);
+ printf("%#x: %s\n", pos, name);
}
static void
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;
}
}
+static void parse_flexible(void);
+
+static int count;
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(\"");
- put_safe(get_string1());
- printf("\")\n");
+ 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
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);
- if (!match_byte(0x10))
- match_byte_assert(0);
- match_zeros_assert(4);
+ pos++;
+ match_zeros_assert(3);
+ puts(get_padded_string(32));
}
static void
-match_NavTreeViewItem(void)
+parse_NavTreeViewItem(void)
{ /* 07 80 */
- match_byte_assert(7);
- match_byte_assert(0x80);
+ int start_pos = pos;
match_zeros_assert(1);
- if (!match_byte(0) && !match_byte(7))
+ 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_zeros_assert(3);
- if (!match_byte(0))
- match_byte_assert(1);
- match_zeros_assert(5);
- match_byte_assert(1);
- match_zeros_assert(5);
+ 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);
+}
- put_safe(get_string1());
- putc('\n', stdout);
+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);
- printf("DspNumber(");
parse_format();
match_byte_assert(0x80);
match_byte(2);
static void
match_DspNumber(void)
{
- match_byte_assert(0x2a);
+ if (!match_byte(0x18) && !match_byte(0x19))
+ 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
}
static void
-parse_PMModelItemInfo(void)
-{ /* 54 80 */
+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 if (!match_u16(0))
+ match_u16_assert(0x0e74);
match_byte_assert(0);
- pos += 1; /* Counter */
- match_zeros_assert(7);
- pos += 3;
- if (!match_byte(0))
- match_byte_assert(0xe);
+ match_DspSimpleText();
+ if (match_u16(0x8018))
+ {
+ printf("18 80(%02x %02x %02x) ",
+ data[pos], data[pos + 1], data[pos + 2]);
+ pos += 3;
+ }
+ if (match_u16(0x8011))
+ {
+ printf("11 80(");
+ pos += 2;
+ for (size_t i = 0; i < 16; i++)
+ printf("%s%02x", i > 0 ? " " : "", data[pos++]);
+ printf(") ");
+ }
+ 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);
+ }
+ 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);
+ }
+
+ if (!match_u32(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 skip_item(const char *name);
+
+static void
+parse_PMModelItemInfo(void)
+{
+ for (int i = 0; i < n_dims; i++)
+ parse_dimension(i);
+ printf("%#x: end of model\n", pos);
+
+ int n_units16 = get_u32();
+ match_u16_assert(0);
+ for (int j = 0; j < n_units16; j++)
+ get_u16();
+
+ 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++)
+ match_u32_assert(j);
+
+ skip_item("end of PMModelItemInfo");
}
static void
match_byte_assert(0x54);
match_byte_assert(0x80);
parse_PMModelItemInfo();
- match_DspSimpleText();
- match_DspString();
+ /* DspSimpleText */
+ /* DspString */
}
static void
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;
+ if (!match_u32(1))
+ 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(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);
+ 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 (pos < n
+ && data[pos + 1] != 0x80
+ && !(data[pos] == 0xff && data[pos + 1] == 0xff
+ && data[pos + 2] == 0 && data[pos + 3] == 0))
+ {
+ pos++;
+ }
+ printf("until %#x:", pos);
+ hex_dump(stdout, start_pos, pos - start_pos);
+}
+
+static void
+parse_DspAnnotation(void)
+{
+ match_zeros_assert(10);
+ match_u32_assert(1);
+}
+
+static void
+parse_DspTextComponentHandle(void)
+{
+ match_byte_assert(0);
+ match_DspString();
+ printf("after DspTextComponentHandle: ");
+ for (int i = 0; ; i++)
+ if (!memcmp(&data[pos + 6 + i], "PVView", 6))
+ {
+ hex_dump(stdout, pos, i);
+ exit(0);
+ }
+}
+
static void
parse_flexible(void)
{
- if (data[pos] == 0xff && data[pos + 1] == 0xff)
+ int start = pos;
+ if (match_u16(0xffff))
{
- match_u16_assert(0xffff);
match_u16_assert(0);
char *heading = get_string2();
- if (!strcmp(heading, "DspCell"))
+ 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 if (!strcmp(heading, "DspAnnotation"))
+ parse_DspAnnotation();
+ else if (!strcmp(heading, "DspTextComponentHandle"))
+ parse_DspTextComponentHandle();
+ 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)
+ {
+ if (0)
+ match_NavTreeViewItem();
+ else
+ {
+ pos += 2;
+ skip_item("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 || data[pos] == 0x25)
+ {
+ 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
- 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();
+ {
+ 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
- assert(0);
+ {
+ //fprintf (stderr, "bad record start at offset %x: ", pos);
+ hex_dump (stderr, pos, 64);
+ assert(0);
+ }
+#endif
}
+
+
int
main(int argc, char *argv[])
{
exit(1);
}
n = s.st_size;
- data = malloc(n);
+ data = malloc(n + 256);
if (!data)
{
perror("malloc");
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);
match_u32_assert(1);
match_byte_assert(0x63);
+ while (pos < n)
+ {
+ if (data[pos] == 0)
+ {
+ //printf("zero\n");
+ pos++;
+ }
+ else
+ parse_flexible();
+ }
+ exit(0);
+
parse_heading("NavRoot");
match_byte_assert(2);
match_zeros_assert(32);
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();
+ 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");
- 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);
match_zeros_assert(3);
match_byte_assert(1);
match_byte_assert(0);
+ match_zeros_assert(7);
- while (data[pos] != 1)
+ while (pos < n)
{
if (data[pos] == 0)
- pos++;
+ {
+ printf("zero\n");
+ pos++;
+ }
else
parse_flexible();
}