X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump.c;h=faea74221ccc7b2d660829b9cf6c2c952d9ce5b0;hb=73745ab54190d58ead4fdf3de6a5142d92d4de80;hp=9a44b0346ca3d73ea724455c3000bd19efaf8d18;hpb=a4d9d8bbad937207bdbc70596b71d25335d0faa3;p=pspp diff --git a/dump.c b/dump.c index 9a44b0346c..faea74221c 100644 --- a/dump.c +++ b/dump.c @@ -19,15 +19,41 @@ all_ascii(const uint8_t *p, size_t n) } static size_t -find(const char *target, size_t target_len) +try_find(const char *target, size_t target_len) { const uint8_t *pos = (const uint8_t *) memmem (data, n, target, target_len); + return pos ? pos - data : 0; +} + +static size_t +try_find_tail(const char *target, size_t target_len) +{ + size_t pos = try_find(target, target_len); + return pos ? pos + target_len : 0; +} + +static size_t +find(const char *target, size_t target_len) +{ + size_t pos = try_find(target, target_len); + if (!pos) + { + fprintf (stderr, "not found\n"); + exit(1); + } + return pos; +} + +static size_t +find_tail(const char *target, size_t target_len) +{ + size_t pos = try_find_tail(target, target_len); if (!pos) { fprintf (stderr, "not found\n"); exit(1); } - return pos - data; + return pos; } size_t pos; @@ -99,10 +125,10 @@ match_byte_assert(uint8_t b, const char *where) #define match_byte_assert(b) match_byte_assert(b, WHERE) static char * -get_string(void) +get_string(const char *where) { if (data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0 - && all_ascii(&data[pos + 4], data[pos])) + /*&& all_ascii(&data[pos + 4], data[pos])*/) { int len = data[pos]; char *s = malloc(len + 1); @@ -114,25 +140,73 @@ get_string(void) } else { - fprintf(stderr, "0x%x: expected string\n", pos); + fprintf(stderr, "%s: 0x%x: expected string\n", where, pos); exit(1); } } +#define get_string() get_string(WHERE) static void -dump_category(int level) +dump_value(int level) { for (int i = 0; i <= level; i++) printf (" "); + match_byte (0); + match_byte (0); + match_byte (0); match_byte (0); if (match_byte (3)) { get_string(); - match_byte_assert (0x58); + if (match_byte (0x31)) + { + if (match_u32 (1)) + { + printf("(footnote %d) ", get_u32()); + match_byte_assert (0); + match_byte_assert (0); + int subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + } + else if (match_u32 (2)) + { + printf("(special 2)"); + match_byte_assert(0); + match_byte_assert(0); + match_u32_assert(1); + match_byte_assert(0); + match_byte_assert(0); + int subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + } + else + { + match_u32_assert(3); + printf("(special 3)"); + match_byte_assert(0); + match_byte_assert(0); + match_byte_assert(1); + match_byte_assert(0); + int subn = get_u32 (); + printf ("nested %d bytes, ", subn); + pos += subn; + subn = get_u32 (); + printf ("nested %d bytes, ", subn); + pos += subn; + } + } + else + match_byte_assert (0x58); get_string(); printf("string \"%s\"", get_string()); - match_byte_assert (1); + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (1); + match_byte (1); match_byte (0); match_byte (0); match_byte (0); @@ -143,7 +217,9 @@ dump_category(int level) match_byte_assert (0x58); printf ("variable \"%s\"", get_string()); get_string(); - match_byte_assert (3); + if (!match_byte(1) && !match_byte(2)) + match_byte_assert(3); + match_byte (0); match_byte (0); match_byte (0); match_byte (0); @@ -151,42 +227,237 @@ dump_category(int level) else if (match_byte (2)) { unsigned int format; + char *var, *vallab; double value; - char *var; match_byte_assert (0x58); format = get_u32 (); value = get_double (); var = get_string (); - get_string (); - printf ("value %g format %d(%d.%d) var \"%s\"", value, format >> 16, (format >> 8) & 0xff, format & 0xff, var); - match_u32_assert (3); + vallab = get_string (); + printf ("value %g format %d(%d.%d) var \"%s\" vallab \"%s\"", + value, format >> 16, (format >> 8) & 0xff, format & 0xff, var, vallab); + if (!match_u32 (1) && !match_u32(2)) + match_u32_assert (3); + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (0); } - else + else if (match_byte (4)) + { + unsigned int format; + char *var, *vallab, *value; + + match_byte_assert (0x58); + format = get_u32 (); + vallab = get_string (); + var = get_string (); + if (!match_byte(1) && !match_byte(2)) + match_byte_assert (3); + value = get_string (); + printf ("value \"%s\" format %d(%d.%d) var \"%s\" vallab \"%s\"", + value, format >> 16, (format >> 8) & 0xff, format & 0xff, var, vallab); + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (0); + } + else if (match_byte (1)) { unsigned int format; double value; + match_byte_assert (0x58); + format = get_u32 (); + value = get_double (); + printf ("value %g format %d(%d.%d)", value, format >> 16, (format >> 8) & 0xff, format & 0xff); + match_byte (1); + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (1); + } + else if (match_byte (0x31)) + { + int subn; + int total_subs = 1; + + match_u32_assert (0); + match_u32_assert (0); + subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + printf ("; \"%s\", substitutions:", get_string()); + for (;;) + { + int n_subst = get_u32(); + if (!n_subst) + break; + printf (" %d", n_subst); + total_subs *= n_subst; + } + + for (int i = 0; i < total_subs; i++) + { + putc ('\n', stdout); + dump_value (level + 1); + } + } + else + { + int total_subs = 1; + + match_byte_assert (0x58); + printf ("\"%s\" with substitutions:", get_string()); + for (;;) + { + int n_subst = get_u32(); + if (!n_subst) + break; + printf (" %d", n_subst); + total_subs *= n_subst; + } + + for (int i = 0; i < total_subs; i++) + { + putc ('\n', stdout); + dump_value (level + 1); + } + } +} + +static void +dump_dim_value(int level) +{ + for (int i = 0; i <= level; i++) + printf (" "); + + if (match_byte (3)) + { + get_string(); + if (match_byte (0x31)) + { + match_u32 (1); + printf("(footnote %d) ", get_u32()); + match_byte_assert (0); + match_byte_assert (0); + int subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + } + else + match_byte_assert (0x58); + get_string(); + printf("string \"%s\"", get_string()); + match_byte (0); match_byte_assert (1); + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (1); + } + else if (match_byte (5)) + { + match_byte_assert (0x58); + printf ("variable \"%s\"", get_string()); + get_string(); + match_byte_assert (2); + } + else if (match_byte (2)) + { + unsigned int format; + char *var, *vallab; + double value; + + match_byte_assert (0x58); + format = get_u32 (); + value = get_double (); + var = get_string (); + vallab = get_string (); + printf ("value %g format %d(%d.%d) var \"%s\" vallab \"%s\"", + value, format >> 16, (format >> 8) & 0xff, format & 0xff, var, vallab); + if (!match_u32 (3)) + match_u32_assert (2); + match_byte (0); + } + else if (match_byte (1)) + { + unsigned int format; + double value; + match_byte_assert (0x58); format = get_u32 (); value = get_double (); printf ("value %g format %d(%d.%d)", value, format >> 16, (format >> 8) & 0xff, format & 0xff); + match_byte (1); match_byte (0); match_byte (0); match_byte (0); + match_byte (1); + } + else + { + int subn; + int total_subs = 1; + + match_byte (0); + match_byte_assert (0x31); + match_u32_assert (0); + match_u32_assert (0); + subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + printf ("; \"%s\", substitutions:", get_string()); + for (;;) + { + int n_subst = get_u32(); + if (!n_subst) + break; + printf (" %d", n_subst); + total_subs *= n_subst; + } + + for (int i = 0; i < total_subs; i++) + { + putc ('\n', stdout); + dump_value (level + 1); + } } +} + +static void +dump_category(int level) +{ + match_byte (0); + match_byte (0); + match_byte (0); + match_byte (0); + dump_value (level); if (match_u32 (2)) get_u32 (); - else + else if (match_u32 (1)) { - match_u32_assert (1); match_byte (0); match_byte (0); match_byte (0); get_u32 (); } + else if (match_byte (1)) + { + match_byte (0); + if (!match_u32 (2)) + match_u32_assert (1); + match_byte (0); + get_u32(); + } + else + { + match_u32_assert (0); + get_u32 (); + } + int n_categories = get_u32(); if (n_categories > 0) printf (", %d subcategories:", n_categories); @@ -199,15 +470,17 @@ static void dump_dim(void) { int n_categories; + printf("next dim\n"); + match_byte(0); if (match_byte(3)) { get_string(); match_byte_assert(0x58); get_string(); printf("string \"%s\": ", get_string()); - match_byte_assert(1); + match_byte(1) || match_byte(0); } - else if (match_byte(5)) + else if (match_byte(5)) { match_byte_assert(0x58); printf("variable \"%s\": ", get_string()); @@ -215,16 +488,61 @@ dump_dim(void) if (!match_byte(2)) match_byte_assert(3); } + else if (match_byte(0x31)) + { + int subn; + int total_subs = 1; + + match_u32_assert (0); + match_u32_assert (0); + subn = get_u32 (); + printf ("nested %d bytes", subn); + pos += subn; + printf ("; \"%s\", substitutions:", get_string()); + for (;;) + { + int n_subst = get_u32(); + if (!n_subst) + break; + printf (" %d", n_subst); + total_subs *= n_subst; + } + + for (int i = 0; i < total_subs; i++) + { + putc ('\n', stdout); + dump_dim_value (0); + } + } else { - fprintf(stderr, "%08x: unexpected byte\n", pos); - exit(1); + int total_subs = 1; + + match_byte_assert (0x58); + printf ("\"%s\" with substitutions:", get_string()); + for (;;) + { + int n_subst = get_u32(); + if (!n_subst) + break; + printf (" %d", n_subst); + total_subs *= n_subst; + } + + for (int i = 0; i < total_subs; i++) + { + putc ('\n', stdout); + dump_dim_value (0); + } } - match_byte_assert(0); + /* This byte is usually 0x02 but 0x00 and 0x75 (!) have also been spotted. */ + pos++; + if (!match_byte(0) && !match_byte(1)) match_byte_assert(2); - match_u32_assert(2); + if (!match_u32(0)) + match_u32_assert(2); if (!match_byte(0)) match_byte_assert(1); match_byte(0); @@ -286,6 +604,16 @@ main(int argc, char *argv[]) if (argc > 1) { + if (!strcmp(argv[1], "title0")) + { + pos = 0x27; + if (match_byte (0x03) + || (match_byte (0x05) && match_byte (0x58))) + printf ("%s\n", get_string()); + else + printf ("\n"); + return 0; + } if (!strcmp(argv[1], "title")) { const char fonts[] = "\x01\x31\x09\0\0\0SansSerif"; @@ -308,8 +636,17 @@ main(int argc, char *argv[]) } else if (!strcmp(argv[1], "dimensions")) { - const char dimensions[] = "-,,,.\0"; - start = find(dimensions, sizeof dimensions - 1) + sizeof dimensions - 1; + { + const char dimensions[] = "-,,,.\0"; + start = try_find_tail(dimensions, sizeof dimensions - 1); + } + + if (!start) + { + const char dimensions[] = "-,,, .\0"; + start = find_tail(dimensions, sizeof dimensions - 1); + } + pos = start; dump_dims (); return 0;