Refine understanding of minor points.
[pspp] / dump.c
diff --git a/dump.c b/dump.c
index 9b90fe651d62db98b82be547cb8618e99abeb384..7665a4ccd0898cde3972beec00f7b6eb5efcd50f 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <float.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -234,7 +235,7 @@ dump_nested_string(void)
 }
 
 static void
-dump_value_31(FILE *stream)
+dump_optional_value(FILE *stream)
 {
   if (match_byte (0x31))
     {
@@ -420,7 +421,7 @@ dump_value(FILE *stream, int level)
   if (match_byte (3))
     {
       char *text = get_string();
-      dump_value_31(stream);
+      dump_optional_value(stream);
       char *identifier = get_string();
       char *text_eng = get_string();
       fprintf (stream, "<string c=\"%s\"", text_eng);
@@ -434,7 +435,7 @@ dump_value(FILE *stream, int level)
     }
   else if (match_byte (5))
     {
-      dump_value_31(stream);
+      dump_optional_value(stream);
       char *name = get_string ();
       char *label = get_string ();
       fprintf (stream, "<variable name=\"%s\"", name);
@@ -450,7 +451,7 @@ dump_value(FILE *stream, int level)
       char *var, *vallab;
       double value;
 
-      dump_value_31 (stream);
+      dump_optional_value (stream);
       format = get_u32 ();
       value = get_double ();
       var = get_string ();
@@ -490,7 +491,7 @@ dump_value(FILE *stream, int level)
       unsigned int format;
       double value;
 
-      dump_value_31(stream);
+      dump_optional_value(stream);
       format = get_u32 ();
       value = get_double ();
       fprintf (stream, "<number value=\"%.*g\" format=\"%s%d.%d\"/>\n",
@@ -498,7 +499,7 @@ dump_value(FILE *stream, int level)
     }
   else
     {
-      dump_value_31(stream);
+      dump_optional_value(stream);
 
       char *base = get_string();
       int x = get_u32();
@@ -676,7 +677,6 @@ dump_data(void)
 static void
 dump_title(void)
 {
-  pos = 0x27;
   printf ("<title-local>\n");
   dump_value(stdout, 0);
   match_byte(1);
@@ -705,24 +705,17 @@ dump_title(void)
   else
     match_byte_assert(0x58);
 
-
   int n_footnotes = get_u32();
   for (int i = 0; i < n_footnotes; i++)
     {
       printf ("<footnote index=\"%d\">\n", i);
       dump_value(stdout, 0);
+      /* Custom footnote marker string. */
       if (match_byte (0x31))
-        {
-          /* Custom footnote marker string. */
-          match_byte_assert(3);
-          get_string();
-          match_byte_assert(0x58);
-          match_u32_assert(0);
-          get_string();
-        }
+        dump_value(stdout, 0);
       else
         match_byte_assert (0x58);
-      printf("(%d)\n", get_u32());
+      get_u32 ();
       printf ("</footnote>\n");
     }
 }
@@ -810,7 +803,8 @@ dump_fonts(void)
   int count = get_u32();
   pos += 4 * count;
 
-  printf ("<encoding>%s</encoding>\n", get_string ());
+  const char *encoding = get_string();
+  printf ("<encoding>%s</encoding>\n", encoding);
 
   if (!match_u32(0))
     match_u32_assert(UINT32_MAX);
@@ -829,6 +823,9 @@ dump_fonts(void)
     }
   else
     match_u32_assert(UINT32_MAX);
+
+  int decimal = data[pos];
+  int grouping = data[pos + 1];
   if (match_byte('.'))
     {
       if (!match_byte(',') && !match_byte('\''))
@@ -840,10 +837,14 @@ dump_fonts(void)
       if (!match_byte('.') && !match_byte(' '))
         match_byte_assert(0);
     }
+  printf("<format decimal=\"%c\" grouping=\"", decimal);
+  if (grouping)
+    putchar(grouping);
+  printf("\"/>\n");
   if (match_u32(5))
     {
       for (int i = 0; i < 5; i++)
-        get_string();
+        printf("<CC%c>%s</CC%c>\n", 'A' + i, get_string(), 'A' + i);
     }
   else
     match_u32_assert(0);
@@ -898,6 +899,7 @@ main(int argc, char *argv[])
     }
   else if (!strcmp(argv[1], "title"))
     {
+      pos = 0x27;
       dump_title();
       exit(0);
     }
@@ -929,23 +931,64 @@ main(int argc, char *argv[])
 
       /* This might be a version number of some kind, because value 1 seems
          to only appear in an SPV file that also required its own weird
-         special cases in dump_value_31(). */
+         special cases in dump_optional_value(). */
       version = get_u32();
       pos -= 4;
       if (!match_u32(1))
         match_u32_assert(3);
 
       match_byte_assert(1);
+      if (!match_byte(0))
+        match_byte_assert(1);
+
+      /* Offset 8. */
+      match_byte_assert(0);
+      match_byte_assert(0);
+      if (!match_byte(0))
+        match_byte_assert(1);
+
+      /* Offset 11. */
+      pos++;
+      match_byte_assert(0);
+      match_byte_assert(0);
+      match_byte_assert(0);
+
+      /* Offset 15. */
+      pos++;
       if (!match_byte(0))
         match_byte_assert(1);
       match_byte_assert(0);
       match_byte_assert(0);
+
+      /* Offset 19. */
+      pos++;
       if (!match_byte(0))
         match_byte_assert(1);
+      match_byte_assert(0);
+      match_byte_assert(0);
+
+      /* Offset 23. */
       pos++;
+      if (!match_byte(0))
+        match_byte_assert(1);
       match_byte_assert(0);
       match_byte_assert(0);
+
+      /* Offset 27. */
+      pos++;
+      pos++;
+      match_byte_assert(0);
       match_byte_assert(0);
+
+      /* Offset 31.
+
+         This is the tableId, e.g. -4154297861994971133 would be 0xdca00003.
+         We don't have enough context to validate it. */
+      pos += 4;
+
+      /* Offset 35. */
+      pos += 4;
+
       dump_title ();
       dump_fonts();
       dump_dims ();