Better dumping of multiple series.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 13 Nov 2014 05:54:03 +0000 (21:54 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 13 Nov 2014 05:54:03 +0000 (21:54 -0800)
dump2.c

diff --git a/dump2.c b/dump2.c
index 56d8163ebbf12ab0102339967786a148fe9cd883..4fd7531ab530df5860a01cb27195008f47aef06d 100644 (file)
--- a/dump2.c
+++ b/dump2.c
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <float.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -53,6 +54,29 @@ match_u32_assert(uint32_t x, const char *where)
 }
 #define match_u32_assert(x) match_u32_assert(x, WHERE)
 
+static bool
+match_byte(uint8_t b)
+{
+  if (pos < n && data[pos] == b)
+    {
+      pos++;
+      return true;
+    }
+  else
+    return false;
+}
+
+static void
+match_byte_assert(uint8_t b, const char *where)
+{
+  if (!match_byte(b))
+    {
+      fprintf(stderr, "%s: 0x%x: expected %02x, got %02x\n", where, pos, b, data[pos]);
+      exit(1);
+    }
+}
+#define match_byte_assert(b) match_byte_assert(b, WHERE)
+
 static bool
 all_ascii(const uint8_t *p)
 {
@@ -165,72 +189,41 @@ dump_raw(FILE *stream, int start, int end, const char *separator)
     }
 }
 
-int
-main(int argc, char **argv)
+static void
+dump_source(int count, int n_series)
 {
-  size_t start;
-  struct stat s;
-
-  if (isatty(STDIN_FILENO))
-    {
-      fprintf(stderr, "redirect stdin from a .bin file\n");
-      exit(1);
-    }
-  if (fstat(STDIN_FILENO, &s))
-    {
-      perror("fstat");
-      exit(1);
-    }
-  n = s.st_size;
-  data = malloc(n);
-  if (!data)
-    {
-      perror("malloc");
-      exit(1);
-    }
-  if (read(STDIN_FILENO, data, n) != n)
-    {
-      perror("read");
-      exit(1);
-    }
-
-  pos = 0;
-  match_u32_assert(0x1b000);
-  match_u32_assert(s.st_size);
-
-  printf ("%08x:", pos);
-  int count = get_u32(), n_series = get_u32();
-  printf (" %d series, %d observations per series\n", n_series, count);
-  printf ("%08x\n\n", pos);
-
   const union
     {
       uint8_t b[8];
       double d;
     }
   sysmis = {.b = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff}};
-  pos = 0x58;
+  int n_sysmis = 0;
   for (int i = 0; i < n_series; i++)
     {
-      printf ("%08x:", pos);
-      printf (" %s\n", get_fixed_string(288));
-      printf ("%08x:", pos);
+      printf ("    series %d: \"%s\"\n        ", i, get_fixed_string(288));
       for (int i = 0; i < count; i++)
         {
           double d = get_double();
           if (d == sysmis.d)
-            printf (" .");
+            {
+              printf (" .");
+              n_sysmis++;
+            }
           else
             printf (" %.*g", DBL_DIG, d);
         }
       printf ("\n");
     }
 
-  printf ("%08x:", pos);
+  if (!n_sysmis)
+    return;
+
+  printf ("\n    %08x:", pos);
   printf (" %d", get_u32());
   printf (", \"%s\"\n", get_string());
 
-  printf ("\n%08x:", pos);
+  printf ("\n    %08x:", pos);
   int n_more_series = get_u32();
   printf (" %d series to come\n", n_more_series);
 
@@ -257,8 +250,60 @@ main(int argc, char **argv)
       char *s = get_string();
       printf ("%d: \"%s\" (%d)\n", i, s, x);
     }
+  printf ("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+  size_t start;
+  struct stat s;
+
+  if (isatty(STDIN_FILENO))
+    {
+      fprintf(stderr, "redirect stdin from a .bin file\n");
+      exit(1);
+    }
+  if (fstat(STDIN_FILENO, &s))
+    {
+      perror("fstat");
+      exit(1);
+    }
+  n = s.st_size;
+  data = malloc(n);
+  if (!data)
+    {
+      perror("malloc");
+      exit(1);
+    }
+  if (read(STDIN_FILENO, data, n) != n)
+    {
+      perror("read");
+      exit(1);
+    }
+
+  pos = 0;
+  match_byte_assert(0);
+  if (!match_byte(0xaf))
+    match_byte_assert(0xb0);
+  int n_sources = data[pos++];
+  match_byte_assert(0);
+
+  match_u32_assert(s.st_size);
+  printf ("%d sources\n", n_sources);
+  for (int i = 0; i < n_sources; i++)
+    {
+      pos = 8 + 80 * i;
+      int count = get_u32();
+      int n_series = get_u32();
+      int offset = get_u32();
+      char *name = get_fixed_string(64);
+      int dunno = get_u32();
+      printf ("source %d: %d series, %d observations per series, offset %08x, \"%s\", %x\n",
+              i, n_series, count, offset, name, dunno);
+      pos = offset;
+      dump_source(count, n_series);
+    }
 
-  dump_raw (stdout, pos, n, "\n");
-  putchar('\n');
   return 0;
 }