return true;
}
+static char *
+xmemdup0(const void *p, size_t n)
+{
+ char *s = malloc(n + 1);
+ memcpy(s, p, n);
+ s[n] = 0;
+ return s;
+}
+
static bool
get_bool(void)
{
case 38: return "EDATE";
case 39: return "SDATE";
default:
- abort();
+ assert(false);
sprintf(tmp, "<%d>", type);
return tmp;
}
int
main(int argc, char *argv[])
{
- if (argc != 2)
+ bool print_offsets = false;
+ for (;;)
+ {
+ int c = getopt (argc, argv, "o");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 'o':
+ print_offsets = true;
+ break;
+
+ case '?':
+ exit (-1);
+ }
+ }
+ if (argc - optind != 1)
{
fprintf (stderr, "usage: %s FILE.bin", argv[0]);
exit (1);
}
- filename = argv[1];
+ const char *filename = argv[optind];
int fd = open(filename, O_RDONLY);
if (fd < 0)
{
}
close(fd);
+ setvbuf (stdout, NULL, _IOLBF, 0);
+
+ int sum = 0;
+
#if 0
unsigned int prev_end = 0;
for (pos = 0; pos + 50 < n; pos++)
!all_utf8((char *) &data[pos + 3], 1) &&
data[pos - 1] != 'v')
{
- //printf ("%04x: ", pos);
+ if (print_offsets)
+ printf ("%04x: ", pos);
unsigned int p = pos;
while (all_utf8 ((char *) &data[p], 1))
p--;
}
#endif
unsigned int prev_end = 0;
+ char *title = "";
for (pos = 2; pos + 50 < n; pos++)
{
static const int cell_prefix[] = {
0x00, 0x03,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -1 /* 00 or 10 */, 0x00, 0x00, 0x00, 0x00, -1,
+
+ /*14 15 16 17 18 19 */
0x80, 0x01, -1, -1, -1, -1,
};
size_t cell_prefix_len = sizeof cell_prefix / sizeof *cell_prefix;
{
if (prev_end != pos)
{
- //printf ("%04x ", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
+
+ if (!strcmp (title, "DspNumber")
+ && pos - prev_end == 2
+ && data[prev_end + 1] == 0x80)
+ {
+ static int already = false;
+ if (!already)
+ fprintf (stderr, " sum=%d %02x\n", sum, data[prev_end]);
+ already = true;
+ }
}
char buf[64];
len = 22 + count;
}
else
- abort ();
+ assert (false);
}
- else if (data[pos + 19] == 128)
+ else if (data[pos + 19] == 128 && data[pos + 20] == 2)
{
- /* pos + 13 is usually 22...53 but also 5 or 69 */
- /* pos + 20 is 2 most of the time, occasionally 1 */
- printf ("%d %d ", data[pos + 13], data[pos + 20]);
+ /* pos + 13 is usually 22...53, and it's 3 more than the
+ " xx 80" separator between cells */
+ printf ("xxx%x ", data[pos + 13]);
double d = *(double *) &data[pos + 21];
len = 29;
const union
}
sysmis = {.b = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff}};
if (d == sysmis.d)
- printf ("sysmis\n");
+ printf ("sysmis");
+ else
+ printf ("%f", d);
+
+ if (data[pos + 29] < 0xff
+ && all_utf8((char *) &data[pos + 30], data[pos + 29]))
+ {
+ printf (" \"%.*s\"", (int) data[pos + 29],
+ &data[pos + 30]);
+ len += data[pos + 29] + 1;
+ }
+ else
+ assert (false);
+
+ putchar ('\n');
+ }
+ else if (data[pos + 19] == 128 && data[pos + 20] == 1 &&
+ data[pos + 21] == 0)
+ {
+ if (data[pos + 23] < 0xff
+ && all_utf8((char *) &data[pos + 24], data[pos + 23]))
+ {
+ printf (" \"%.*s\"\n", (int) data[pos + 23],
+ &data[pos + 24]);
+ len = 24 + data[pos + 23];
+ }
else
- printf ("%f\n", d);
+ assert (false);
}
else
- abort ();
- pos += len - 1;
- prev_end = pos + 1;
- continue;
- }
-
- static const int col_prefix[] = {
- 0x11, 0x80, 0x00, -1, 0x00, 0x00, 0x00, 0x01, 0x00
- };
- size_t col_prefix_len = sizeof col_prefix / sizeof *col_prefix;
- if (match_bytes(pos, col_prefix, col_prefix_len))
- {
- if (prev_end != pos)
{
- //printf ("%04x ", prev_end);
- hex_dump (stdout, prev_end, pos - prev_end);
+ printf ("xxx%d %d %d %d\n",
+ data[pos + 19], data[pos + 20],
+ data[pos + 21], data[pos + 22]);
+ assert(false);
}
-
- printf ("col %d\n", data[pos + 3]);
- pos += col_prefix_len - 1;
+ pos += len - 1;
prev_end = pos + 1;
continue;
}
size_t record_prefix_len = sizeof record_prefix / sizeof *record_prefix;
if (match_bytes(pos, record_prefix, record_prefix_len))
{
- if (prev_end != pos)
- {
- //printf ("%04x ", prev_end);
- hex_dump (stdout, prev_end, pos - prev_end);
- }
-
- putchar ('\n');
-
- //printf ("%d ", pos % 4);
int len = record_prefix_len;
int slen = data[pos + 4] + (data[pos + 5] << 8);
- if (slen > 2 && slen < 256 && all_utf8((char *) &data[pos + 6], slen))
+ if (slen >= 2 && slen < 256 && all_utf8((char *) &data[pos + 6], slen))
{
- printf ("%.*s ", slen, &data[pos + 6]);
+ if (prev_end != pos)
+ {
+ if (print_offsets)
+ printf ("%04x ", prev_end);
+ hex_dump (stdout, prev_end, pos - prev_end);
+ }
+
+ putchar ('\n');
+
+ printf ("rec:%-20.*s ", slen, &data[pos + 6]);
len = slen + 6;
- }
- else
- printf ("notitle ");
+ title = xmemdup0(&data[pos + 6], slen);
+ fprintf (stderr, "%s%d ", title, data[pos + len]);
+ sum += data[pos+len];
- pos += len - 1;
- prev_end = pos + 1;
- continue;
+ pos += len - 1;
+ prev_end = pos + 1;
+ continue;
+ }
}
static const int number_prefix[] = {
{
if (prev_end != pos)
{
- //printf ("%04x ", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
}
prev_end = pos;
double d = *(double *) &data[pos + number_prefix_len];
- printf ("float%f ", d);
- pos += 10 - 9;
+ printf ("float %f\n", d);
+
+ pos += 10 - 1;
prev_end = pos + 1;
continue;
}
- static const int string_prefix[] = {
- 0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01
- };
- size_t string_prefix_len = sizeof string_prefix / sizeof *string_prefix;
- if (match_bytes(pos, string_prefix, string_prefix_len) && data[pos + string_prefix_len] != 255)
+ if (!memcmp (&data[pos + 4], "{\\rtf", 5))
{
- if (prev_end != pos)
+ int len = data[pos] + (data[pos + 1] << 8) + (data[pos + 2] << 16)
+ + (data[pos + 3] << 24);
+ if (len < n - pos - 4)
{
- //printf ("%04x ", prev_end);
- hex_dump (stdout, prev_end, pos - prev_end);
- }
- prev_end = pos;
+ if (prev_end != pos)
+ {
+ if (print_offsets)
+ printf ("%04x ", prev_end);
+ hex_dump (stdout, prev_end, pos - prev_end);
+ }
+ prev_end = pos;
- printf ("\nstring %.*s\n", (int) data[pos + 7], &data[pos + 8]);
- }
- if (match_bytes(pos, string_prefix, string_prefix_len) && data[pos + string_prefix_len] == 255)
- {
- if (prev_end != pos)
- {
- //printf ("%04x ", prev_end);
- hex_dump (stdout, prev_end, pos - prev_end);
+ printf ("rtf\n");
+ pos += 4 + len - 1;
+ prev_end = pos + 1;
+ continue;
}
- prev_end = pos;
-
- int len = data[pos + 8] + (data[pos + 9] << 8);
- printf ("\nlongstring %.*s\n", len, &data[pos + 10]);
}
-
-
-#if 0
- static const int heading_prefix[] = {
- -1, 0x00, 0x00, 0x00, 0x50, 0x80, 0x00, 0x52, 0x80, 0x00, -1, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
- 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x00, 0x05, 0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01
- };
- size_t heading_prefix_len = sizeof heading_prefix / sizeof *heading_prefix;
- if (match_bytes(pos, heading_prefix, heading_prefix_len))
+ if (data[pos] && data[pos + 1] && data[pos + 2] >= 0xfe
+ && data[pos + 3] == 0xff && data[pos + 4] && data[pos + 4] != 0xff)
{
if (prev_end != pos)
{
- //printf ("%04x ", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
}
+ prev_end = pos;
- printf ("heading %d %d\n", data[pos],data[pos + 10]);
- pos += heading_prefix_len - 1;
+ static int prev_num;
+ int32_t num = data[pos] + (data[pos + 1] << 8)
+ + (data[pos + 2] << 16) + (data[pos + 3] << 24);
+ printf ("%d (%+d) ", num, num - prev_num);
+ prev_num = num;
+ pos += 4 - 1;
prev_end = pos + 1;
continue;
}
- static const int font_prefix[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x80, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, -1,
- 0x80, 0x00, -1, 0x00, -1, 0x00, 0xc8, 0x00, -1, -1, -1, -1, -1,
- 0x00, -1, 0x00, 0x00, 0x00, 0x01, 0x00, -1,
- 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, -1 /* 12 or 22 */,
- };
+ static const int font_prefix[] =
+ {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x41, 0x72, 0x69, 0x61, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ };
size_t font_prefix_len = sizeof font_prefix / sizeof *font_prefix;
if (match_bytes(pos, font_prefix, font_prefix_len))
{
if (prev_end != pos)
{
- //printf ("%04x", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
}
+ prev_end = pos;
+
+ printf ("font\n");
- printf ("font %d %d %d %d %d %d %d %d %d %d\n",
- data[pos + 24], data[pos + 26],
- data[pos + 30], data[pos + 31], data[pos + 32],
- data[pos + 33], data[pos + 34], data[pos + 36],
- data[pos + 58], data[pos + 59]);
pos += font_prefix_len - 1;
prev_end = pos + 1;
continue;
}
- static const int table_prefix[] = {
- -1 /* ed or e9 */, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x41, 0x72, 0x69,
- 0x61, 0x6c, 0x00, -1, 0x00, -1, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, -1, 0x00, 0x00, 0x00, -1,
+ static const int string_prefix[] = {
+ 0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01
};
- size_t table_prefix_len = sizeof table_prefix / sizeof *table_prefix;
- if (match_bytes(pos, table_prefix, table_prefix_len))
+ size_t string_prefix_len = sizeof string_prefix / sizeof *string_prefix;
+ if (match_bytes(pos, string_prefix, string_prefix_len) && data[pos + string_prefix_len] != 255)
{
if (prev_end != pos)
{
- //printf ("%04x", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
}
+ prev_end = pos;
- printf ("table %d\n", data[pos + 72]);
- pos += table_prefix_len - 1;
+ int len = data[pos + 7];
+ printf ("string %.*s\n", len, &data[pos + 8]);
+ pos += 8 + len - 1;
prev_end = pos + 1;
continue;
}
-#endif
-
- static const int dim_prefix[] = {
- 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -1,
- 0x00, 0x00, 0x00, 0x00, -1, 0x80, 0x01, 0x02, -1,
- -1, -1, -1 /* 00 or 01 */,
- };
- size_t dim_prefix_len = sizeof dim_prefix / sizeof *dim_prefix;
- if (match_bytes(pos, dim_prefix, dim_prefix_len))
+ if (match_bytes(pos, string_prefix, string_prefix_len) && data[pos + string_prefix_len] == 255)
{
if (prev_end != pos)
{
- //printf ("%04x", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, pos - prev_end);
}
+ prev_end = pos;
- printf ("dim %d %d %d %d %d\n", data[pos + 8], data[pos + 13],
- data[pos + 17], data[pos + 18], data[pos + 19]);
- pos += dim_prefix_len - 1;
+ int len = data[pos + 8] + (data[pos + 9] << 8);
+ printf ("\nlongstring %.*s\n", len, &data[pos + 10]);
+ pos += 10 + len - 1;
prev_end = pos + 1;
continue;
}
- static const int dim2_prefix[] = {
- 0x50, 0x80, 0x00, 0x52, 0x80, 0x00, -1, 0x00, 0x00, 0x00, -1, 0, 0, 0,
- -1, -1, -1, -1
- };
- size_t dim2_prefix_len = sizeof dim2_prefix / sizeof *dim2_prefix;
- if (match_bytes(pos, dim2_prefix, dim2_prefix_len))
- {
- if (prev_end != pos)
- {
- //printf ("%04x", prev_end);
- hex_dump (stdout, prev_end, pos - prev_end);
- }
+
- int16_t x = *(int16_t *) &data[pos + 14];
- int16_t y = *(int16_t *) &data[pos + 16];
- printf ("dim2 %d %d %d %d\n", data[pos + 6], data[pos + 10], x, y);
- pos += dim2_prefix_len - 1;
- prev_end = pos + 1;
- continue;
- }
if (!is_ascii(data[pos]))
continue;
unsigned real_start = start - length_bytes;
if (prev_end != real_start)
{
- //printf ("%04x ", prev_end);
+ if (print_offsets)
+ printf ("%04x ", prev_end);
hex_dump (stdout, prev_end, real_start - prev_end);
}
- //printf ("%04x ", real_start);
+ if (print_offsets)
+ printf ("%04x ", real_start);
printf ("\"%.*s\"\n",
(int) end - start, (char *) &data[start]);
prev_end = end;