X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump-spo.c;h=35cd8b5dcc072e837b32ce051198419e99870bd5;hb=2618ed943daf22c2b46f6dd76b7700739c5afb84;hp=ac53ece628894626236a24d2c2d9a91537d33b12;hpb=55083a4e71e2027e4ddea318f2128ba9a7636c10;p=pspp diff --git a/dump-spo.c b/dump-spo.c index ac53ece628..35cd8b5dcc 100644 --- a/dump-spo.c +++ b/dump-spo.c @@ -179,6 +179,15 @@ match_bytes(int start, const int *bytes, size_t n_bytes) 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) { @@ -516,7 +525,7 @@ format_to_string (int type) case 38: return "EDATE"; case 39: return "SDATE"; default: - abort(); + assert(false); sprintf(tmp, "<%d>", type); return tmp; } @@ -1312,13 +1321,30 @@ format_name (int format, char *buf) 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) { @@ -1346,6 +1372,10 @@ main(int argc, char *argv[]) } close(fd); + setvbuf (stdout, NULL, _IOLBF, 0); + + int sum = 0; + #if 0 unsigned int prev_end = 0; for (pos = 0; pos + 50 < n; pos++) @@ -1375,7 +1405,8 @@ main(int argc, char *argv[]) !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--; @@ -1384,11 +1415,14 @@ main(int argc, char *argv[]) } #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; @@ -1396,8 +1430,19 @@ main(int argc, char *argv[]) { 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]; @@ -1435,13 +1480,13 @@ main(int argc, char *argv[]) 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 @@ -1451,17 +1496,48 @@ main(int argc, char *argv[]) } 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 - printf ("%f\n", d); + 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 + assert (false); } else - abort (); + { + printf ("xxx%d %d %d %d\n", + data[pos + 19], data[pos + 20], + data[pos + 21], data[pos + 22]); + assert(false); + } pos += len - 1; prev_end = pos + 1; continue; } +#if 0 static const int col_prefix[] = { 0x11, 0x80, 0x00, -1, 0x00, 0x00, 0x00, 0x01, 0x00 }; @@ -1470,7 +1546,8 @@ main(int argc, char *argv[]) { if (prev_end != pos) { - //printf ("%04x ", prev_end); + if (print_offsets) + printf ("%04x ", prev_end); hex_dump (stdout, prev_end, pos - prev_end); } @@ -1479,35 +1556,37 @@ main(int argc, char *argv[]) prev_end = pos + 1; continue; } - +#endif + static const int record_prefix[] = { 0xff, 0xff, 0x00, 0x00, }; 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[] = { @@ -1518,18 +1597,41 @@ main(int argc, char *argv[]) { 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; } + if (!memcmp (&data[pos + 4], "{\\rtf", 5)) + { + int len = data[pos] + (data[pos + 1] << 8) + (data[pos + 2] << 16) + + (data[pos + 3] << 24); + if (len < n - pos - 4) + { + if (prev_end != pos) + { + if (print_offsets) + printf ("%04x ", prev_end); + hex_dump (stdout, prev_end, pos - prev_end); + } + prev_end = pos; + + printf ("rtf\n"); + pos += 4 + len - 1; + prev_end = pos + 1; + continue; + } + } + static const int string_prefix[] = { 0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01 }; @@ -1538,24 +1640,33 @@ main(int argc, char *argv[]) { 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 ("\nstring %.*s\n", (int) data[pos + 7], &data[pos + 8]); + int len = data[pos + 7]; + printf ("string %.*s\n", len, &data[pos + 8]); + pos += 8 + len - 1; + prev_end = pos + 1; + continue; } 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; 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; } @@ -1572,7 +1683,8 @@ main(int argc, char *argv[]) { if (prev_end != pos) { - //printf ("%04x ", prev_end); + if (print_offsets) + printf ("%04x ", prev_end); hex_dump (stdout, prev_end, pos - prev_end); } @@ -1582,6 +1694,7 @@ main(int argc, char *argv[]) continue; } +#if 0 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, @@ -1596,7 +1709,8 @@ main(int argc, char *argv[]) { if (prev_end != pos) { - //printf ("%04x", prev_end); + if (print_offsets) + printf ("%04x", prev_end); hex_dump (stdout, prev_end, pos - prev_end); } @@ -1609,7 +1723,8 @@ main(int argc, char *argv[]) prev_end = pos + 1; continue; } - +#endif + 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, @@ -1624,7 +1739,8 @@ main(int argc, char *argv[]) { if (prev_end != pos) { - //printf ("%04x", prev_end); + if (print_offsets) + printf ("%04x", prev_end); hex_dump (stdout, prev_end, pos - prev_end); } @@ -1633,49 +1749,28 @@ main(int argc, char *argv[]) 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 */, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x01, 0x02, 0x28, + 0x05, 0x00, }; size_t dim_prefix_len = sizeof dim_prefix / sizeof *dim_prefix; if (match_bytes(pos, dim_prefix, dim_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); } - printf ("dim %d %d %d %d %d\n", data[pos + 8], data[pos + 13], - data[pos + 17], data[pos + 18], data[pos + 19]); + printf ("dim %d\n", data[pos + 8]); pos += dim_prefix_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; - } +#endif if (!is_ascii(data[pos])) continue; @@ -1711,10 +1806,12 @@ main(int argc, char *argv[]) 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;