X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump.c;h=be5139c6045a5eb2620242d9b2ca4212243e724d;hb=7802d3315464f29b075f69253162405e4d52fd27;hp=c247c4af661be8c50ef6312aa18f05c524088b68;hpb=38a126b38f4963ba033120754e7a4f026e9fa01e;p=pspp diff --git a/dump.c b/dump.c index c247c4af66..be5139c604 100644 --- a/dump.c +++ b/dump.c @@ -218,11 +218,18 @@ get_string(const char *where) } #define get_string() get_string(WHERE) +static int +get_end(void) +{ + int len = get_u32(); + return pos + len; +} + static char * dump_counted_string(void) { char *s = NULL; - int inner_end = pos + get_u32(); + int inner_end = get_end(); if (pos != inner_end) { match_u32_assert(0); @@ -239,6 +246,39 @@ dump_counted_string(void) return s; } +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)) + fprintf(stderr, "-"); + else + fprintf(stderr, " "); +#endif + fprintf(stderr, "%02x", c); + //fprintf(stderr, "%c", c >= 32 && c < 127 ? c : '.'); + } + fprintf(stderr, "\n"); +} + +static void +dump_style(void) +{ + match_byte(1); + match_byte(0); + match_byte(0); + match_byte(0); + match_byte_assert(1); + get_string(); /* foreground */ + get_string(); /* background */ + get_string(); /* font */ + if (!match_byte(14)) + match_byte_assert(12); /* size? */ +} + static char * dump_nested_string(void) { @@ -246,9 +286,12 @@ dump_nested_string(void) match_byte_assert (0); match_byte_assert (0); - int outer_end = pos + get_u32(); + int outer_end = get_end(); s = dump_counted_string(); - match_byte_assert(0x58); + if (match_byte(0x31)) + dump_style(); + else + match_byte_assert(0x58); match_byte_assert(0x58); if (pos != outer_end) { @@ -294,26 +337,14 @@ dump_optional_value(FILE *stream) return; } - int outer_end = pos + get_u32(); - + int outer_end = get_end(); + /* This counted-string appears to be a template string, e.g. "Design\: [:^1:]1 Within Subjects Design\: [:^1:]2". */ dump_counted_string(); if (match_byte(0x31)) - { - /* Only one example in the corpus. */ - match_byte(1); - match_byte(0); - match_byte(0); - match_byte(0); - match_byte_assert(1); - get_string(); /* foreground */ - get_string(); /* background */ - get_string(); /* font */ - if (!match_byte(14)) - match_byte_assert(12); /* size? */ - } + dump_style(); else match_byte_assert(0x58); if (match_byte(0x31)) @@ -350,7 +381,7 @@ dump_optional_value(FILE *stream) else if (match_u32 (2)) { fprintf(stream, "(special 2)"); - if (!match_byte(0)) + if (!match_byte(0) && !match_byte(1)) match_byte_assert(2); match_byte_assert(0); if (!match_u32 (2) && !match_u32(1)) @@ -829,8 +860,8 @@ dump_fonts(void) match_u32_assert(5); if (!match_u32(10) && !match_u32(11) && !match_u32(5)) match_u32_assert(9); - if (!match_u32(0)) - match_u32_assert(1); + if (!match_u32(0) && !match_u32(1)) + match_u32_assert(2); } else { @@ -854,25 +885,21 @@ dump_fonts(void) match_u32_assert(18); pos += 18; - if (match_u32(117)) - pos += 117; - else if (match_u32(142)) - pos += 142; - else if (match_u32(143)) - pos += 143; - else if (match_u32(150)) - pos += 150; - else + int x3 = get_u32(); + if (version == 3) { - match_u32_assert(16); - pos += 16; + assert(x3 >= 117); + int len = data[pos + 0x34]; + if (len) + printf("%.*s\n", len, &data[pos + 0x35]); } + pos += x3; int count = get_u32(); pos += 4 * count; - const char *encoding = get_string(); - printf ("%s\n", encoding); + const char *locale = get_string(); + printf ("%s\n", locale); if (!match_u32(0)) match_u32_assert(UINT32_MAX); @@ -883,8 +910,9 @@ dump_fonts(void) match_byte_assert(1); if (version > 1) { - if (!match_byte(0x97) && !match_byte(0x98) && !match_byte(0x99)) - match_byte_assert(0x9a); + if (!match_byte(0x97) && !match_byte(0x98) + && !match_byte(0x99) && !match_byte(0x9a)) + match_byte_assert(0x9b); match_byte_assert(7); match_byte_assert(0); match_byte_assert(0); @@ -916,8 +944,111 @@ dump_fonts(void) } else match_u32_assert(0); - int skip = get_u32(); - pos += skip; + + /* The last chunk is an outer envelope that contains two inner envelopes. + The second inner envelope has some interesting data like the encoding and + the locale. */ + if (version == 3) + { + int outer_end = get_end(); + + /* First inner envelope: byte*33 int[n] int*[n]. */ + pos = get_end(); + + /* Second inner envelope. */ + assert(get_end() == outer_end); + + match_byte_assert(1); + match_byte_assert(0); + if (!match_byte(3) && !match_byte(4)) + match_byte_assert(5); + match_byte_assert(0); + match_byte_assert(0); + match_byte_assert(0); + + printf("%s\n", get_string()); + printf("%s\n", get_string()); + printf("%s\n", get_string()); + printf("%s\n", get_string()); + printf("%s\n", get_string()); + + if (!match_byte(0)) + match_byte_assert(1); + match_byte_assert(0); + if (!match_byte(0)) + match_byte_assert(1); + if (!match_byte(0)) + match_byte_assert(1); + + if (!match_byte(0x97) && !match_byte(0x98) + && !match_byte(0x99) && !match_byte(0x9a)) + match_byte_assert(0x9b); + match_byte_assert(7); + match_byte_assert(0); + match_byte_assert(0); + + if (match_byte('.')) + { + if (!match_byte(',') && !match_byte('\'')) + match_byte_assert(' '); + } + else + { + match_byte_assert(','); + if (!match_byte('.') && !match_byte(' ')) + match_byte_assert(0); + } + + pos += 8; + match_byte_assert(1); + + if (outer_end - pos > 6) + { + /* There might be a pair of strings representing a dataset and + datafile name, or there might be a set of custom currency strings. + The custom currency strings start with a pair of integers, so we + can distinguish these from a string by checking for a null byte; a + small 32-bit integer will always contain a null and a text string + never will. */ + int save_pos = pos; + int len = get_u32(); + bool has_dataset = !memchr(&data[pos], '\0', len); + pos = save_pos; + + if (has_dataset) + { + printf("%s\n", get_string()); + printf("%s\n", get_string()); + + match_u32_assert(0); + get_u32(); + match_u32_assert(0); + } + } + + if (match_u32(5)) + { + for (int i = 0; i < 5; i++) + printf("%s\n", 'A' + i, get_string(), 'A' + i); + } + else + match_u32_assert(0); + + match_byte_assert(0x2e); + if (!match_byte(0)) + match_byte_assert(1); + + if (pos < outer_end) + { + match_u32_assert(2000000); + match_u32_assert(0); + } + assert(pos == outer_end); + + pos = outer_end; + } + else + match_u32_assert(0); } int