work on spo files
[pspp] / dump-spo.c
index 1ca9f0a03f3fda520956e510c9db883a84767d9c..fe35a0bb4f851b3b4d3c6ae36a75910bf203c554 100644 (file)
@@ -576,7 +576,7 @@ dump_cell(void)
 }
 
 static void
-dump_category (int level, uint8_t *catstart, bool *have_catstart)
+dump_category (int level, uint8_t *delim, int *delim_len)
 {
   int cat_index = get_u32();
   assert (cat_index < 256);
@@ -619,25 +619,30 @@ dump_category (int level, uint8_t *catstart, bool *have_catstart)
     printf (" (group with %d children)", n_children);
   else
     printf (" (category #%d)", cat_index);
+  printf ("\n");
 
-  printf (" %02x %02x %02x %02x %02x %02x\n",
-          data[pos], data[pos + 1], data[pos + 2],
-          data[pos + 3], data[pos + 4], data[pos + 5]);
-  if (!*have_catstart)
+  int dlen = 0;
+  for (int i = 0; i < 2; i++)
     {
-      *have_catstart = true;
-      memcpy(catstart, &data[pos], 6);
+      if (data[pos + dlen] == 0xff)
+        dlen += 7;
+      else
+        dlen += 3;
+    }
+  if (!*delim_len)
+    {
+      *delim_len = dlen;
+      memcpy(delim, &data[pos], dlen);
     }
-  pos += 6;
+  pos += dlen;
 
   for (int i = 0; i < n_children; i++)
-    dump_category (level + 1, catstart, have_catstart);
+    dump_category (level + 1, delim, delim_len);
 }
 
 static void
 dump_PMModelItemInfo(int ndims)
 {
-  return;
 #if 0
   if (data[pos + 9] && data[pos + 9] != 0xff)//count_zeros (&data[pos + 9]) < 4)
     return;
@@ -645,22 +650,22 @@ dump_PMModelItemInfo(int ndims)
   
   match_byte_assert (0);
 
-  uint8_t catstart[6];
-  bool have_catstart = false;
-  dump_category (0, catstart, &have_catstart);
-  assert(have_catstart);
+  uint8_t delim[14];
+  int delim_len = 0;
+  dump_category (0, delim, &delim_len);
+  assert(delim_len);
 
   for (int i = 1; i < ndims; i++)
     {
       for (int j = 0; ; j++, pos++)
         {
-          assert (j <= 1000);
-          if (!memcmp(&data[pos], catstart, 6))
+          assert (pos + j + delim_len < n);
+          if (!memcmp(&data[pos], delim, delim_len))
             break;
         }
-      pos += 6;
+      pos += delim_len;
 
-      dump_category (0, catstart, &have_catstart);
+      dump_category (0, delim, &delim_len);
     }
 }
 
@@ -720,6 +725,44 @@ main(int argc, char *argv[])
 
   setvbuf (stdout, NULL, _IOLBF, 0);
 
+  pos = 0x39b;
+  unsigned int rtflen = get_u32();
+  pos += rtflen - 1;            /* Almost past SPSS syntax */
+  assert(pos < n);
+  pos += 0x45 + data[pos + 0x44]; /* Just past the string */
+  pos += 0x1a + data[pos + 0x19]; /* Just past the string again */
+  pos += 0x66 + data[pos + 0x65]; /* Just past the third string */
+  pos += 0x4e;
+  rtflen = get_u32();
+  pos += rtflen - 1;            /* Almost past 2nd RTF */
+  pos += 0x64 + data[pos + 0x63]; /* Just past the fourth string */
+  /* as-number: */
+  if (data[pos + 0x114] == 0xff)
+    pos += 0x117 + data[pos + 0x115] + 256 * data[pos + 0x116];
+  else
+    pos += 0x115 + data[pos + 0x114];
+  pos += 0x18 + data[pos + 0x17]; /* Just past "<none>" or dataset name. */
+  pos += 0x18 + data[pos + 0x17]; /* Just past "<none>" or dataset name. */
+  pos += count_zeros(&data[pos]); /* Skip optional zeros. */
+  pos += 0x18 + data[pos + 0x17]; /* Just past "<none>" or dataset name. */
+  pos += 0x3e + data[pos + 0x3d]; /* Skip past "100" etc. */
+  pos += count_zeros(&data[pos]); /* Skip optional zeros. */
+  pos += 0x18 + data[pos + 0x17]; /* Just past "User-defined...". */
+  pos += 0x18 + data[pos + 0x17]; /* Just past "Statistics are based... */
+  if (data[pos + 0x19] == 0xff)
+    pos += 0x1c + data[pos + 0x1a] + 256 * data[pos + 0x1b];
+  else
+    pos += 0x1a + data[pos + 0x19];
+  pos += 0x61 + data[pos + 0x60]; /* Just past "Cluster_Notes". */
+  pos += 0x992 + data[pos + 0x991]; /* Just past "Cluster". */
+  pos += 0x4e;
+  rtflen = get_u32();
+  pos += rtflen - 1;            /* Almost past RTF with filesystem path */
+  pos += 0x45 + data[pos + 0x44]; /* Just past "Statistics" */
+  pos += 0x1a + data[pos + 0x19]; /* Just past "Cluster". */
+  fwrite (&data[pos], 1, n - pos, stdout);
+  exit (0);
+
   int sum = 0;
   
 #if 0
@@ -1048,7 +1091,20 @@ main(int argc, char *argv[])
           continue;
         }
 
-      
+      if (data[pos] == 0 && data[pos + 1] == 0xff
+          && (!data[pos + 2] || data[pos + 2] == 0xff) && data[pos + 3] == 0xff
+          && data[pos + 4] == 0)
+        {
+          pos++;
+          if (prev_end != pos)
+            {
+              if (print_offsets)
+                printf ("%04x ", prev_end);
+              hex_dump (stdout, prev_end, pos - prev_end);
+            }
+          prev_end = pos;
+          continue;
+        }
 
 
       if (!is_ascii(data[pos]))