#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)
{
{
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);
}
}
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 void
parse_DspString(void)
{
+ printf("%#x: DspString(", pos);
if (match_byte(2))
{
- printf("DspString(%f, \"", get_double());
+ printf("%f, \"", get_double());
printf("%s\")\n", get_string1());
}
else
{
match_byte_assert(1);
- printf ("DspString(");
parse_format();
printf(" \"");
match_byte_assert(0);
{ /* 03 80 */
match_byte_assert(3);
match_byte_assert(0x80);
+ 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);
+ match_byte_assert(0x90);
+ 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_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);
- 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);
+ 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();
}
-static void parse_flexible(void);
-
static void
parse_DspCell(void)
{
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_PMModelItemInfo();
}
+static void
+parse_NavHead(void)
+{
+ match_byte_assert(2);
+ match_zeros_assert(24);
+ match_byte_assert(1);
+ match_zeros_assert(7);
+ 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(6);
+ 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
parse_flexible(void)
{
+ int start = pos;
if (data[pos] == 0xff && data[pos + 1] == 0xff)
{
match_u16_assert(0xffff);
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
- 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();
+ {
+ 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); */
+ 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
+ {
+ fprintf (stderr, "bad record 0x%02x at offset %x\n",
+ data[pos], pos);
+ hex_dump (stderr, pos, 64);
+ assert(0);
+ }
}
- else if (data[pos] == 0x15 && data[pos + 1] == 0x80)
+ else if (match_byte(0xa))
{
- /* 15 80 */
- data += 2;
- match_byte_assert(2);
- printf ("15 80(%f", get_double());
- printf (" %s)\n", get_string1());
+ match_zeros_assert(5);
+ assert(pos == n);
+ exit (0);
}
else
{
- fprintf (stderr, "bad data cell 0x%02x at offset %x\n",
- data[pos], pos);
+ fprintf (stderr, "bad record start at offset %x: ", pos);
hex_dump (stderr, pos, 64);
assert(0);
}
}
+
+
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);
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();
+ exit(0);
puts(get_padded_string(32));
if (!match_u32(80))
match_u32_assert(132);
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)
{