+#include <assert.h>
#include <float.h>
#include <stdbool.h>
#include <stdint.h>
}
#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)
{
}
}
-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);
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;
}