+static char *
+get_string_be(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 + 2] * 256 + data[pos + 3];
+ 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);
+ }
+}
+#define get_string_be() get_string_be(WHERE)
+
+static int
+get_end(void)
+{
+ int len = get_u32();
+ return pos + len;
+}
+
+static void __attribute__((unused))
+hex_dump(int ofs, int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ int c = data[ofs + i];
+#if 1
+ if (i && !(i % 16))
+ printf("-");
+ else
+ printf(" ");
+#endif
+ printf("%02x", c);
+ }
+ for (int i = 0; i < n; i++)
+ {
+ int c = data[ofs + i];
+ printf("%c", c >= 32 && c < 127 ? c : '.');
+ }
+}
+
+static char *
+dump_counted_string(void)
+{
+ char *s = NULL;
+ int inner_end = get_end();
+ if (pos != inner_end)
+ {
+ if (match_u32(5))
+ {
+ match_u32_assert(0);
+ match_byte_assert(0x58);
+ }
+ else
+ match_u32_assert(0);
+ if (match_byte(0x31))
+ s = get_string();
+ else
+ match_byte_assert(0x58);
+ if (pos != inner_end)
+ {
+ fprintf(stderr, "inner end discrepancy\n");
+ exit(1);
+ }
+ }
+ return s;
+}
+
+static void
+dump_style(FILE *stream)
+{
+ match_byte(1);
+ match_byte(0);
+ match_byte(0);
+ match_byte(0);
+ match_byte_assert(1);
+ char *fg = get_string(); /* foreground */
+ char *bg = get_string(); /* background */
+ char *font = get_string(); /* font */
+ int size = data[pos];
+ if (!match_byte(14))
+ match_byte_assert(12); /* size? */
+ fprintf(stream, " fgcolor=\"%s\" bgcolor=\"%s\" font=\"%s\" size=\"%d\"",
+ fg, bg, font, size);
+}
+
+static char *
+dump_nested_string(FILE *stream)
+{
+ char *s = NULL;
+
+ match_byte_assert (0);
+ match_byte_assert (0);
+ int outer_end = get_end();
+ s = dump_counted_string();
+ if (s)
+ fprintf(stream, " \"%s\"", s);
+ if (match_byte(0x31))
+ dump_style(stream);
+ else
+ match_byte_assert(0x58);
+ match_byte_assert(0x58);
+ if (pos != outer_end)
+ {
+ fprintf(stderr, "outer end discrepancy\n");
+ exit(1);
+ }
+
+ return s;
+}
+