X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump-spo.c;h=2a75bef6a928fd81d55b6fc2f948eb45b404e1ec;hb=ffcf1cd46432799392194fb6058bc52833acad3f;hp=f2d33a1449c3475250df54c3c02819aab338e149;hpb=2370ccebe0ceaa372e2c861d0c4425464d25f365;p=pspp diff --git a/dump-spo.c b/dump-spo.c index f2d33a1449..2a75bef6a9 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) { @@ -265,16 +274,21 @@ get_end(void) static void __attribute__((unused)) hex_dump(FILE *stream, int ofs, int n) { + int n_ascii = 0; for (int i = 0; i < n; i++) { int c = data[ofs + i]; + n_ascii += is_ascii(c); fprintf(stream, " %02x", c); } - putc(' ', stream); - for (int i = 0; i < n; i++) + if (n_ascii >= 3) { - int c = data[ofs + i]; - putc(c >= 32 && c < 127 ? c : '.', stream); + putc(' ', stream); + for (int i = 0; i < n; i++) + { + int c = data[ofs + i]; + putc(c >= 32 && c < 127 ? c : '.', stream); + } } putc('\n', stream); } @@ -511,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; } @@ -1258,16 +1272,79 @@ dump_fonts(void) } } +static const char * +format_name (int format, char *buf) +{ + switch (format) + { + case 1: return "A"; + case 2: return "AHEX"; + case 3: return "COMMA"; + case 4: return "DOLLAR"; + case 5: return "F"; + case 6: return "IB"; + case 7: return "PIBHEX"; + case 8: return "P"; + case 9: return "PIB"; + case 10: return "PK"; + case 11: return "RB"; + case 12: return "RBHEX"; + case 15: return "Z"; + case 16: return "N"; + case 17: return "E"; + case 20: return "DATE"; + case 21: return "TIME"; + case 22: return "DATETIME"; + case 23: return "ADATE"; + case 24: return "JDATE"; + case 25: return "DTIME"; + case 26: return "WKDAY"; + case 27: return "MONTH"; + case 28: return "MOYR"; + case 29: return "QYR"; + case 30: return "WKYR"; + case 31: return "PCT"; + case 32: return "DOT"; + case 33: return "CCA"; + case 34: return "CCB"; + case 35: return "CCC"; + case 36: return "CCD"; + case 37: return "CCE"; + case 38: return "EDATE"; + case 39: return "SDATE"; + case 40: return "MTIME"; + case 41: return "YMDHMS"; + default: sprintf(buf, "(%d)", format); return 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) { @@ -1295,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++) @@ -1324,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--; @@ -1333,34 +1415,51 @@ 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, 0x01, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0x00, 0x03, + 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 (match_bytes(pos, cell_prefix, cell_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); + + 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; + } } - printf ("cell %04x %d %d %d %d %d %d ", pos, - data[pos + 13], data[pos + 16], data[pos + 17], - data[pos + 18], data[pos + 19], data[pos + 20]); + char buf[64]; + printf ("cell %s%d.%d ", + format_name (data[pos + 18], buf), + data[pos + 17], + data[pos + 16]); int len = cell_prefix_len; if (data[pos + 19] == 0) { + assert (data[pos + 13] == 5); if (data[pos + 20] == 0) { int count = (data[pos + 22]); - printf ("/ %d %d %d \"%.*s\"\n", - data[pos + 20], data[pos + 21], data[pos + 22], + printf ("%d %d \"%.*s\"\n", + data[pos + 21], data[pos + 22], count, &data[pos + 23]); len = 23 + count; } @@ -1369,23 +1468,27 @@ main(int argc, char *argv[]) && data[pos + 22] == 0xff) { int count = 255; - printf ("/ \"%.*s\"\n", count, &data[pos + 24]); + printf ("%d \"%.*s\"\n", count, data[pos + 23], + &data[pos + 24]); len = 23 + count; } - else if (data[pos + 20] == 1 ) + else if (data[pos + 20] == 1) { int count = (data[pos + 21]); - printf ("/ %d %d %d \"%.*s\"\n", - data[pos + 20], data[pos + 21], data[pos + 22], + printf ("\"%.*s\"\n", count, &data[pos + 22]); len = 22 + count; } else - abort (); + assert (false); } - else if (data[pos + 19] == 128) + else if (data[pos + 19] == 128 && data[pos + 20] == 2) { - double d = *(double *) &data[pos + cell_prefix_len - 8]; + /* 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 { uint8_t b[8]; @@ -1393,150 +1496,204 @@ 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\n", d); + 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 + 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; } - static const int col_prefix[] = { - 0x11, 0x80, 0x00, -1, 0x00, 0x00, 0x00, 0x01, 0x00 + static const int record_prefix[] = { + 0xff, 0xff, 0x00, 0x00, }; - size_t col_prefix_len = sizeof col_prefix / sizeof *col_prefix; - if (match_bytes(pos, col_prefix, col_prefix_len)) + size_t record_prefix_len = sizeof record_prefix / sizeof *record_prefix; + if (match_bytes(pos, record_prefix, record_prefix_len)) { - if (prev_end != pos) + 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)) { - printf ("%04x ", prev_end); - hex_dump (stdout, prev_end, pos - prev_end); - } + if (prev_end != pos) + { + if (print_offsets) + printf ("%04x ", prev_end); + hex_dump (stdout, prev_end, pos - prev_end); + } - printf ("col %d\n", data[pos + 3]); - pos += col_prefix_len - 1; - prev_end = pos + 1; - continue; + putchar ('\n'); + + printf ("rec:%-20.*s ", slen, &data[pos + 6]); + len = slen + 6; + 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; + } } - 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 + static const int number_prefix[] = { + 0x80, 0x02 }; - size_t heading_prefix_len = sizeof heading_prefix / sizeof *heading_prefix; - if (match_bytes(pos, heading_prefix, heading_prefix_len)) + size_t number_prefix_len = sizeof number_prefix / sizeof *number_prefix; + if (match_bytes(pos, number_prefix, number_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 ("heading %d %d\n", data[pos],data[pos + 10]); - pos += heading_prefix_len - 1; + double d = *(double *) &data[pos + number_prefix_len]; + printf ("float %f\n", d); + + pos += 10 - 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 */, - }; - size_t font_prefix_len = sizeof font_prefix / sizeof *font_prefix; - if (match_bytes(pos, font_prefix, font_prefix_len)) + 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; + } + } + + 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); } - - 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; + + 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 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, - }; - size_t table_prefix_len = sizeof table_prefix / sizeof *table_prefix; - if (match_bytes(pos, table_prefix, table_prefix_len)) + 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 ("table %d\n", data[pos + 72]); - pos += table_prefix_len - 1; + printf ("font\n"); + + pos += font_prefix_len - 1; prev_end = pos + 1; continue; } - 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 */, + static const int string_prefix[] = { + 0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01 }; - size_t dim_prefix_len = sizeof dim_prefix / sizeof *dim_prefix; - if (match_bytes(pos, dim_prefix, dim_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 ("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 + 7]; + printf ("string %.*s\n", len, &data[pos + 8]); + pos += 8 + 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 (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; - 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; + 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; } + + + if (!is_ascii(data[pos])) continue; @@ -1571,10 +1728,13 @@ 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 \"%.*s\"\n", real_start, + if (print_offsets) + printf ("%04x ", real_start); + printf ("\"%.*s\"\n", (int) end - start, (char *) &data[start]); prev_end = end; pos = end - 1;