successfully parse trhough the model on descriptives-only, correlations-only
[pspp] / dump-spo2.c
index 971fbab8eacf1b3390c5c51d6709d45b531396ee..2ed8b7fc24649fc3a0b490f76ff169bd9a9e268f 100644 (file)
@@ -21,6 +21,8 @@ int version;
 
 unsigned int pos;
 
+static int n_dims;
+
 #define XSTR(x) #x
 #define STR(x) XSTR(x)
 #define WHERE __FILE__":" STR(__LINE__)
@@ -465,6 +467,7 @@ parse_heading(const char *name)
   match_u16_assert(0xffff);
   match_u16_assert(0);
   match_string2_assert(name);
+  printf("%#x: %s\n", pos, name);
 }
 
 static void
@@ -502,10 +505,11 @@ put_safe(const char *s)
 
 static void parse_flexible(void);
 
+static int count;
 static void
 parse_DspString(void)
 {
-  printf("%#x: DspString(", pos);
+  printf("%#x: DspString#%d(", pos, count++);
   if (match_byte(2))
     {
       printf("%f, \"", get_double());
@@ -521,6 +525,7 @@ parse_DspString(void)
       put_safe(get_string1());
       printf("\")\n");
     }
+  
 }
 
 static void
@@ -532,10 +537,8 @@ match_DspString(void)
 }
 
 static void
-match_DspSimpleText(void)
-{                               /* 03 80 */
-  match_byte_assert(3);
-  match_byte_assert(0x80);
+parse_DspSimpleText(void)
+{
   match_byte_assert(0);
   if (match_byte(0))
     {
@@ -544,6 +547,15 @@ match_DspSimpleText(void)
         match_byte_assert(0);
       match_zeros_assert(4);
     }
+  /* Followed by DspString or DspNumber. */
+}
+
+static void
+match_DspSimpleText(void)
+{                               /* 03 80 */
+  match_byte_assert(3);
+  match_byte_assert(0x80);
+  parse_DspSimpleText();
 }
 
 static void
@@ -562,12 +574,11 @@ parse_weirdness(void)
 }
 
 static void
-match_NavTreeViewItem(void)
+parse_NavTreeViewItem(void)
 {                               /* 07 80 */
-  match_byte_assert(7);
-  match_byte_assert(0x80);
+  int start_pos = pos;
   match_zeros_assert(1);
-  if (!match_byte(0) && !match_byte(7) && !match_byte(2))
+  if (!match_byte(0) && !match_byte(7) && !match_byte(2) && !match_byte(0xc))
     match_byte_assert(8);
   match_zeros_assert(3);
   pos++;
@@ -630,13 +641,22 @@ match_NavTreeViewItem(void)
         match_zeros_assert(3);
     }
   //fprintf(stderr, "%#x ", pos - 16);
+  hex_dump(stdout, start_pos, pos - start_pos);
+}
+
+static void
+match_NavTreeViewItem(void)
+{
+  match_byte_assert(7);
+  match_byte_assert(0x80);
+  parse_NavTreeViewItem();
 }
 
 static void
 parse_DspNumber(void)
 {
+  printf("%#x: DspNumber#%d(", pos, count++);
   match_byte_assert(1);
-  printf("DspNumber(");
   parse_format();
   match_byte_assert(0x80);
   match_byte(2);
@@ -647,7 +667,8 @@ parse_DspNumber(void)
 static void
 match_DspNumber(void)
 {
-  match_byte_assert(0x2a);
+  if (!match_byte(0x18) && !match_byte(0x19))
+    match_byte_assert(0x2a);
   match_byte_assert(0x80);
   parse_DspNumber();
 }
@@ -656,8 +677,6 @@ static void
 parse_DspCell(void)
 {
   match_byte_assert(0);
-  match_DspSimpleText();
-  parse_flexible();             /* DspString or DspNumber. */
 }
 
 static void
@@ -684,15 +703,78 @@ match_NavLog(void)
 }
 
 static void
-parse_PMModelItemInfo(void)
-{                               /* 54 80 */
-  match_byte_assert(0);
-  pos += 1;                     /* Counter */
-  match_zeros_assert(7);
-  pos += 3;
-  if (!match_byte(0))
-    match_byte_assert(0xe);
+parse_category(int j)
+{
+  get_u16(); match_byte_assert(0);
+  get_u16(); match_byte_assert(0);
+  match_u32_assert(j);
+  match_u32_assert(0);
+  if (get_u16() == 0xffff)
+    match_u16_assert(0xffff);
+  else
+    match_u16_assert(0x0e74);
   match_byte_assert(0);
+  match_DspSimpleText();
+  match_DspString();
+  match_u32_assert(0);
+}
+
+static void
+parse_dimension(int i)
+{
+  printf ("%#x: dimension %d\n", pos, i);
+  if (i == 0)
+    {
+      match_zeros_assert(5);
+      match_u32_assert(1);
+      get_u16(); match_u16_assert(0x0e74); match_byte_assert(0);
+      match_DspSimpleText();
+      match_DspString();
+
+      int n_categories = get_u32();
+      for (int j = 0; j < n_categories; j++)
+        parse_category(j);
+    }
+  else
+    {
+      match_zeros_assert(6);
+
+      int n_units16 = get_u32();
+      match_u16_assert(1);
+      for (int j = 0; j < n_units16; j++)
+        get_u16();
+
+      match_byte_assert(0);
+
+      int n_units32 = get_u32();
+      match_u16_assert(0);
+      for (int j = 0; j < n_units32; j++)
+        get_u32();
+
+      get_u16(); match_byte_assert(0);
+
+      get_u16(); match_byte_assert(0);
+      get_u16(); match_byte_assert(0);
+      match_u32_assert(0);
+      match_u32_assert(1);
+
+      get_u16(); match_u16_assert(0x0e74); match_byte_assert(0);
+      match_DspSimpleText();
+      match_DspString();
+
+      int n_categories = get_u32();
+      for (int j = 0; j < n_categories; j++)
+        parse_category(j);
+    }
+}
+
+static void
+parse_PMModelItemInfo(void)
+{
+  for (int i = 0; i < n_dims; i++)
+    parse_dimension(i);
+  printf("%#x: end of model\n", pos);
+  exit(0);
 }
 
 static void
@@ -701,8 +783,8 @@ match_PMModelItemInfo(void)
   match_byte_assert(0x54);
   match_byte_assert(0x80);
   parse_PMModelItemInfo();
-  match_DspSimpleText();
-  match_DspString();
+  /* DspSimpleText */
+  /* DspString */
 }
 
 static void
@@ -724,8 +806,7 @@ parse_NavHead(void)
   if (!match_byte(1))
     match_byte_assert(0);
   match_zeros_assert(3);
-  match_DspSimpleText();
-  parse_flexible();
+  /* DspSimpleText */
 }
 
 static void
@@ -807,29 +888,30 @@ static void
 parse_PVPivotView(void)
 {
   match_byte_assert(5);
-  match_zeros_assert(4);
+  printf ("PVPivotView(%d)\n", get_u32());
 }
 
 static void
 parse_NDimensional__DspCell(void)
 {
   match_byte_assert(0);
-  match_u32_assert(1);
+  n_dims = get_u32();
+  printf ("NDimensional__DspCell(n_dims=%d)\n", n_dims);
 }
 
 static void
 parse_IndexedCollection(void)
 {
-  match_byte_assert(0);
-  if (match_byte(0))
+  printf("IndexedCollection");
+  for (size_t i = 0; ; i++)
     {
-      match_zeros_assert(12);
-    }
-  else
-    {
-      get_u32();
+      match_byte_assert(0);
+      printf("%c%d", i ? 'x' : '(', get_u32());
       match_u16_assert(1);
+      if (!match_u16(0x8011))
+        break;
     }
+  printf(")\n");
 }
 
 static void
@@ -883,6 +965,22 @@ parse_PVCellStyle(void)
   match_zeros_assert(2);
 }
 
+static void
+skip_item(const char *name)
+{
+  int start_pos = pos;
+  printf("%#x: skipping %s bytes...", pos, name);
+  while (data[pos + 1] != 0x80
+         && !(data[pos] == 0xff && data[pos + 1] == 0xff
+              && data[pos + 2] == 0 && data[pos + 3] == 0))
+    {
+      assert(pos < n);
+      pos++;
+    }
+  printf("until %#x:", pos);
+  hex_dump(stdout, start_pos, pos - start_pos);
+}
+
 static void
 parse_flexible(void)
 {
@@ -891,14 +989,34 @@ parse_flexible(void)
     {
       match_u16_assert(0);
       char *heading = get_string2();
-      if (!strcmp(heading, "DspCell"))
+      printf("%#x: %s\n", pos, heading);
+      if (!strcmp(heading, "NavRoot"))
+        {
+          match_byte_assert(2);
+          match_zeros_assert(32);
+        }
+      else if (!strcmp(heading, "NavPivot"))
+        {
+          hex_dump(stdout, pos, 021);
+          pos += 0x21;
+        }
+      else if (!strcmp(heading, "DspCell"))
         parse_DspCell();
+      else if (!strcmp(heading, "DspSimpleText"))
+        parse_DspSimpleText();
       else if (!strcmp(heading, "DspNumber"))
         parse_DspNumber();
       else if (!strcmp(heading, "DspString"))
         parse_DspString();
       else if (!strcmp(heading, "NavHead"))
         parse_NavHead();
+      else if (!strcmp(heading, "NavTreeViewItem"))
+        {
+          if (0)
+            parse_NavTreeViewItem();
+          else
+            skip_item(heading);
+        }
       else if (!strcmp(heading, "IndexedCollection"))
         parse_IndexedCollection();
       else if (!strcmp(heading, "NavOleItem"))
@@ -929,6 +1047,8 @@ parse_flexible(void)
         parse_PVSeparatorStyle();
       else if (!strcmp(heading, "PVCellStyle"))
         parse_PVCellStyle();
+      else if (!strcmp(heading, "PVTextStyle"))
+        exit(0);
       else
         {
           fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start);
@@ -938,7 +1058,7 @@ parse_flexible(void)
     }
   else if (data[pos + 1] == 0x80)
     {
-      if (data[pos] == 0x2a && data[pos + 1] == 0x80)
+      if ((data[pos] == 0x2a || data[pos] == 0x18 || data[pos] == 0x19) && data[pos + 1] == 0x80)
         match_DspNumber();
       else if (data[pos] == 0x27 && data[pos + 1] == 0x80)
         match_DspCell();
@@ -953,8 +1073,10 @@ parse_flexible(void)
         {
           /* 3c 80 */
           /* 39 80 */
+          printf("%#x: %02x %02x ", pos, data[pos], data[pos + 1]);
           pos += 2;
           parse_format();
+          printf ("\n");
 /*      match_byte_assert(0x01);
         match_byte_assert(0x02);
         match_byte_assert(0x0d); */
@@ -966,7 +1088,7 @@ parse_flexible(void)
           if (match_byte(2))
             {
               printf ("15 80(%f", get_double());
-              printf (" %s)\n", get_string1());
+              printf (" \"%s\")\n", get_string1());
               if (match_byte(1))
                 {
                   match_byte_assert(0);
@@ -987,8 +1109,6 @@ parse_flexible(void)
               match_byte_assert(0);
               if (match_u32(0xc))
                 match_u16_assert(1);
-              else
-                match_zeros_assert(13);
             }
         }
       else if (data[pos] == 0x9 && data[pos + 1] == 0x80)
@@ -999,10 +1119,21 @@ parse_flexible(void)
         match_NavOleItem();
       else if (data[pos] == 0x11 || data[pos] == 0x13)
         {
+          int type = data[pos];
           pos += 2;
           match_byte_assert(0);
-          if (match_u32(0xc) || match_u32(0xd))
-            match_u16_assert(1);
+          if (data[pos] != 0)
+            {
+              int x = get_u32();
+              int y = get_u16();
+              if (y == 0)
+                {
+                  int index = get_u32();
+                  printf("%02x 80(footnote %d)\n", type, index);
+                }
+              else
+                printf("%02x 80(%d %d)\n", type, x, y);
+            }
           else
             match_zeros_assert(13);
         }
@@ -1058,8 +1189,11 @@ parse_flexible(void)
                data[pos] == 0x3e ||
                data[pos] == 0x46)
         {
+          printf ("%#x: %02x %02x(%02x %02x %02x)\n",
+                  pos, data[pos], data[pos + 1],
+                  data[pos + 2], data[pos + 3], data[pos + 4]);
           pos += 2;
-          parse_format();
+          pos += 3;
         }
       else
         {
@@ -1129,15 +1263,20 @@ parse_flexible(void)
         }
     }
 #endif
-  else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9))
+  else if (match_u16(1))
     {
-      while (data[pos + 1] != 0x80
-             && (data[pos] != 0xff || data[pos + 1] != 0xff))
-        {
-          assert(pos < n);
-          pos++;
-        }
+      int start_pos = pos;
+      char *title = get_string1();
+      printf("%#x: title(\"%s\", ", start_pos, title);
+      match_u32_assert(0);
+      char *id = get_string1();
+      printf("\"%s\")\n", id);
+      match_byte_assert(0);
+      match_u32_assert(3);
+      match_u16_assert(1);
     }
+  else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9))
+    skip_item("unknown");
 #if 0
   else if (match_byte(7) || match_byte(4) || match_byte(5) || match_byte(6) || match_byte(8) || match_byte(9) || match_byte(0xb) || match_byte(0xc) || match_byte(0x15) || match_byte(0x16) || match_byte(0x17) || match_byte(0x18) || match_byte(0x1e)  || match_byte(0x1a))
     {
@@ -1268,7 +1407,7 @@ main(int argc, char *argv[])
     data[n + i] = i % 2 ? 0xaa : 0x55;
   close(fd);
 
-  setvbuf (stdout, NULL, _IOLBF, 0);
+  setvbuf (stdout, NULL, _IONBF, 0);
 
   match_byte_assert(4);
   match_u32_assert(0);
@@ -1276,6 +1415,18 @@ main(int argc, char *argv[])
   match_u32_assert(1);
   match_byte_assert(0x63);
 
+  for (;;)
+    {
+      if (data[pos] == 0)
+        {
+          //printf("zero\n");
+          pos++;
+        }
+      else
+        parse_flexible();
+    }
+  exit(0);
+
   parse_heading("NavRoot");
   match_byte_assert(2);
   match_zeros_assert(32);
@@ -1343,7 +1494,10 @@ main(int argc, char *argv[])
   for (;;)
     {
       if (data[pos] == 0)
-        pos++;
+        {
+          //printf("zero\n");
+          pos++;
+        }
       else
         parse_flexible();
     }
@@ -1427,7 +1581,10 @@ main(int argc, char *argv[])
   while (data[pos] != 1)
     {
       if (data[pos] == 0)
-        pos++;
+        {
+          printf("zero\n");
+          pos++;
+        }
       else
         parse_flexible();
     }