+ printf ("%d: \"%s\" (%d)\n", i, s, frequency);
+ strings[i] = s;
+ }
+ printf ("\n");
+
+ assert (pos == end);
+ pos = ofs;
+ printf("Strings:\n");
+ for (int i = 0; i < n_more_series; i++)
+ {
+ printf (" \"%s\"\n", get_string());
+ int n_pairs = get_u32();
+ for (int j = 0; j < n_pairs; j++)
+ {
+ int x = get_u32();
+ //assert (x == j);
+ int y = get_u32();
+ printf (" %d: \"%s\"\n", x, strings[y]);
+ }
+ printf ("\n");
+ }
+ pos = end;
+}
+
+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);
+ int version = data[pos];
+ 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);
+
+ struct source
+ {
+ int offset, count, n_series;
+ char *name;
+ }
+ sources[n_sources];
+ for (int i = 0; i < n_sources; i++)
+ {
+ int count = get_u32();
+ int n_series = get_u32();
+ int offset = get_u32();
+ char *name = get_fixed_string(version == 0xb0 ? 64 : 28);
+ int dunno = version == 0xb0 ? get_u32() : 0;
+ printf ("source %d: %d series, %d observations per series, offset %08x, \"%s\", %x\n",
+ i, n_series, count, offset, name, dunno);
+ sources[i].offset = offset;
+ sources[i].count = count;
+ sources[i].n_series = n_series;
+ sources[i].name = name;
+ }
+
+ for (int i = 0; i < n_sources; i++)
+ {
+ if (pos != sources[i].offset)
+ {
+ fprintf (stderr, "pos=0x%x expected=0x%x reading source %d\n", pos, sources[i].offset, i);
+ exit(1);
+ }
+ dump_source(i + 1 >= n_sources ? n : sources[i + 1].offset, sources[i].count, sources[i].n_series, sources[i].name);