X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=dump.c;h=f478131555e2ef126837096f65f4a292b2d02741;hb=815d7313445b7bf351178ecb5171ad5f46a4e83f;hp=bf6003e9b1255079f73f9ebfdec6dd51dad8a4eb;hpb=18baf335922219e337202001c3875e72fc5545e2;p=pspp diff --git a/dump.c b/dump.c index bf6003e9b1..f478131555 100644 --- a/dump.c +++ b/dump.c @@ -204,24 +204,17 @@ dump_value_31(void) match_byte_assert (0x58); } -static void dump_value(int level, bool match1); -static void dump_substs(void (*dump)(int level), int level); -static void dump_value__(int level, bool match1); - static void -dump_value__with_preskip(int level) +dump_value__(int level, bool match1) { + for (int i = 0; i <= level; i++) + printf (" "); + match_byte(0); match_byte(0); match_byte(0); match_byte(0); - dump_value__ (level, false); - putchar('\n'); -} -static void -dump_value__(int level, bool match1) -{ if (match_byte (3)) { char *s1 = get_string(); @@ -289,42 +282,63 @@ dump_value__(int level, bool match1) match_byte (1); } else - dump_substs(dump_value__with_preskip, level + 1); + { + dump_value_31(); + + char *base = get_string(); + int x = get_u32(); + printf ("\"%s\" with %d variables:\n", base, x); + for (int i = 0; i < x; i++) + { + int y = get_u32(); + if (!y) + y = 1; + else + match_u32_assert(0); + for (int j = 0; j <= level; j++) + printf (" "); + printf("variable %d has %d values:\n", i, y); + for (int j = 0; j < y; j++) + { + dump_value__ (level + 1, false); + putchar('\n'); + } + } + } } -static void -dump_value(int level, bool match1) +static int +compare_int(const void *a_, const void *b_) { - for (int i = 0; i <= level; i++) - printf (" "); - - match_byte (0); - match_byte (0); - match_byte (0); - match_byte (0); - dump_value__(level, match1); - match_byte(0); - match_byte(0); - match_byte(0); + const int *a = a_; + const int *b = b_; + return *a < *b ? -1 : *a > *b; } static void -dump_dim_value(int level) +check_permutation(int *a, int n, const char *name) { - for (int i = 0; i <= level; i++) - printf (" "); - - match_byte(0); - match_byte(0); - match_byte(0); - match_byte(0); - dump_value__(level, true); + int b[n]; + memcpy(b, a, n * sizeof *a); + qsort(b, n, sizeof *b, compare_int); + for (int i = 0; i < n; i++) + if (b[i] != i) + { + fprintf(stderr, "bad %s permutation:", name); + for (int i = 0; i < n; i++) + fprintf(stderr, " %d", a[i]); + putc('\n', stderr); + exit(1); + } } static void -dump_category(int level) +dump_category(int level, int *indexes, int *n_indexes) { - dump_value (level, true); + dump_value__ (level, true); + match_byte(0); + match_byte(0); + match_byte(0); if (match_u32 (1)) match_byte (0); @@ -338,14 +352,24 @@ dump_category(int level) else if (!match_u32(2)) match_u32_assert (0); - get_u32 (); - + int indx = get_u32(); int n_categories = get_u32(); + if (indx != -1) + { + if (n_categories != 0) + { + fprintf(stderr, "index not -1 but subcategories\n"); + exit(1); + } + indexes[(*n_indexes)++] = indx; + } if (n_categories > 0) printf (", %d subcategories:", n_categories); + else + printf (", index %d", indx); printf("\n"); for (int i = 0; i < n_categories; i++) - dump_category (level + 1); + dump_category (level + 1, indexes, n_indexes); } static void @@ -353,7 +377,7 @@ dump_dim(void) { int n_categories; printf("next dim\n"); - dump_dim_value(0); + dump_value__ (0, false); /* This byte is usually 0x02 but 0x00 and 0x75 (!) have also been spotted. */ pos++; @@ -364,13 +388,19 @@ dump_dim(void) match_u32_assert(2); if (!match_byte(0)) match_byte_assert(1); - get_u32(); - match_byte(0); - match_byte(0); + if (!match_byte(0)) + match_byte_assert(1); + match_byte_assert(1); + static int dim_indx = 0; + match_u32_assert(dim_indx++); n_categories = get_u32(); printf("%d nested categories\n", n_categories); + + int indexes[1024]; + int n_indexes = 0; for (int i = 0; i < n_categories; i++) - dump_category (0); + dump_category (0, indexes, &n_indexes); + check_permutation(indexes, n_indexes, "categories"); } int n_dims; @@ -386,121 +416,44 @@ dump_dims(void) } } -static void -dump_substs(void (*dump)(int level), int level) -{ - dump_value_31(); - - char *base = get_string(); - int x = get_u32(); - printf ("\"%s\" with %d variables:\n", base, x); - for (int i = 0; i < x; i++) - { - int y = get_u32(); - if (!y) - y = 1; - else - match_u32_assert(0); - for (int j = 0; j <= level; j++) - printf (" "); - printf("variable %d has %d values:\n", i, y); - for (int j = 0; j < y; j++) - { - dump (level+1); - putchar('\n'); - } - } -} - -static void -dump_data_value(int level) -{ - for (int i = 0; i <= level; i++) - printf (" "); - - match_byte(0); - match_byte(0); - match_byte(0); - match_byte(0); - if (data[pos] <= 5) - dump_value__(0, false); - else - dump_substs (dump_data_value, level + 1); -} - static void dump_data(void) { -#if 1 - int a[16]; - for (int i = 0; i < 3 + n_dims; i++) + /* The first three numbers add to the number of dimensions. */ + int t = get_u32(); + t += get_u32(); + match_u32_assert(n_dims - t); + + /* The next n_dims numbers are a permutation of the dimension numbers. */ + int a[n_dims]; + for (int i = 0; i < n_dims; i++) a[i] = get_u32(); - printf ("data intro:"); - for (int i = 0; i < 3 + n_dims; i++) - printf(" %d", a[i]); - printf("\n"); -#else - fprintf (stderr,"data intro (%d dims):", n_dims); - for (int i = 0; i < 3+n_dims; i++) - fprintf (stderr," %d", get_u32()); - fprintf(stderr,"\n"); -#endif + check_permutation(a, n_dims, "dimensions"); + int x = get_u32(); printf ("%d data values, starting at %08x\n", x, pos); for (int i = 0; i < x; i++) { printf("%08x, index %d:\n", pos, get_u32()); match_u32_assert(0); - dump_data_value(0); + dump_value__(0, false); putchar('\n'); } } -static void -dump_title_value(int level) -{ - for (int i = 0; i <= level; i++) - printf (" "); - - match_byte (0); - match_byte (0); - match_byte (0); - match_byte (0); - if (data[pos] <= 5) - dump_value__(level, true); - else - dump_substs(dump_title_value, level + 1); -} - -static void -dump_footnote_value(int level) -{ - for (int i = 0; i <= level; i++) - printf (" "); - - match_byte (0); - match_byte (0); - match_byte (0); - match_byte (0); - if (data[pos] <= 5) - dump_value__(level, false); - else - dump_substs(dump_footnote_value, level + 1); -} - static void dump_title(void) { pos = 0x27; - dump_title_value(0); putchar('\n'); - dump_title_value(0); putchar('\n'); + dump_value__(0, true); putchar('\n'); + dump_value__(0, true); putchar('\n'); match_byte_assert(0x31); - dump_title_value(0); putchar('\n'); + dump_value__(0, true); putchar('\n'); match_byte(0); match_byte_assert(0x58); if (match_byte(0x31)) { - dump_footnote_value(0); putchar('\n'); + dump_value__(0, false); putchar('\n'); } else match_byte_assert(0x58); @@ -519,7 +472,7 @@ dump_title(void) for (int i = 0; i < n_footnotes; i++) { printf("footnote %d:\n", i); - dump_footnote_value(0); + dump_value__(0, false); if (match_byte (0x31)) { /* Custom footnote marker string. */