15 #define STR(x) XSTR(x)
16 #define WHERE __FILE__":" STR(__LINE__)
22 memcpy(&x, &data[pos], 4);
31 memcpy(&x, &data[pos], 8);
46 match_u32_assert(uint32_t x, const char *where)
48 unsigned int y = get_u32();
51 fprintf(stderr, "%s: 0x%x: expected i%u, got i%u\n", where, pos - 4, x, y);
55 #define match_u32_assert(x) match_u32_assert(x, WHERE)
60 if (pos < n && data[pos] == b)
70 match_byte_assert(uint8_t b, const char *where)
74 fprintf(stderr, "%s: 0x%x: expected %02x, got %02x\n", where, pos, b, data[pos]);
78 #define match_byte_assert(b) match_byte_assert(b, WHERE)
81 all_ascii(const uint8_t *p)
84 if (*p < 32 || *p > 126)
90 get_fixed_string(int len, const char *where)
92 if (pos + len > n || !memchr(&data[pos], 0, len) || !all_ascii(&data[pos]))
94 fprintf(stderr, "%s: 0x%x: bad fixed-width string\n", where, pos);
97 char *s = (char *) &data[pos];
101 #define get_fixed_string(len) get_fixed_string(len, WHERE)
104 all_ascii2(const uint8_t *p, size_t n)
106 for (size_t i = 0; i < n; i++)
107 if (p[i] < 32 || p[i] > 126)
113 get_string(const char *where)
116 /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/
117 /*&& all_ascii(&data[pos + 4], data[pos])*/)
119 int len = data[pos] + data[pos + 1] * 256;
120 char *s = malloc(len + 1);
122 memcpy(s, &data[pos + 4], len);
129 fprintf(stderr, "%s: 0x%x: expected string\n", where, pos);
133 #define get_string() get_string(WHERE)
136 dump_raw(FILE *stream, int start, int end, const char *separator)
138 for (size_t i = start; i < end; )
145 && i + 4 + data[i] + data[i + 1] * 256 <= end
146 && all_ascii2(&data[i + 4], data[i] + data[i + 1] * 256))
148 fprintf(stream, "%s\"", separator);
149 fwrite(&data[i + 4], 1, data[i] + data[i + 1] * 256, stream);
150 fputs("\" ", stream);
152 i += 4 + data[i] + data[i + 1] * 256;
154 else if (i + 12 <= end
161 memcpy (&d, &data[i + 4], 8);
162 fprintf (stream, "F40.%d(%.*f)%s", data[i], data[i], d, separator);
165 else if (i + 12 <= end
172 memcpy (&d, &data[i + 4], 8);
173 fprintf (stream, "PCT40.%d(%.*f)%s", data[i], data[i], d, separator);
176 else if (i + 4 <= end
181 fprintf (stream, "i%d ", data[i]);
186 fprintf(stream, "%02x ", data[i]);
193 dump_source(int count, int n_series)
200 sysmis = {.b = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff}};
202 for (int i = 0; i < n_series; i++)
204 printf (" series %d: \"%s\"\n ", i, get_fixed_string(288));
205 for (int i = 0; i < count; i++)
207 double d = get_double();
214 printf (" %.*g", DBL_DIG, d);
222 printf ("\n %08x:", pos);
223 printf (" %d", get_u32());
224 printf (", \"%s\"\n", get_string());
226 printf ("\n %08x:", pos);
227 int n_more_series = get_u32();
228 printf (" %d series to come\n", n_more_series);
230 for (int i = 0; i < n_more_series; i++)
232 printf ("%08x:", pos);
233 printf (" \"%s\"", get_string());
234 int n_pairs = get_u32();
235 for (int j = 0; j < n_pairs; j++)
239 printf (" (%d,%d)", x, y);
244 printf ("\n%08x:", pos);
245 int n_strings = get_u32();
246 printf (" %d strings\n", n_strings);
247 for (int i = 0; i < n_strings; i++)
250 char *s = get_string();
251 printf ("%d: \"%s\" (%d)\n", i, s, x);
257 main(int argc, char **argv)
262 if (isatty(STDIN_FILENO))
264 fprintf(stderr, "redirect stdin from a .bin file\n");
267 if (fstat(STDIN_FILENO, &s))
279 if (read(STDIN_FILENO, data, n) != n)
286 match_byte_assert(0);
287 if (!match_byte(0xaf))
288 match_byte_assert(0xb0);
289 int n_sources = data[pos++];
290 match_byte_assert(0);
292 match_u32_assert(s.st_size);
293 printf ("%d sources\n", n_sources);
294 for (int i = 0; i < n_sources; i++)
297 int count = get_u32();
298 int n_series = get_u32();
299 int offset = get_u32();
300 char *name = get_fixed_string(64);
301 int dunno = get_u32();
302 printf ("source %d: %d series, %d observations per series, offset %08x, \"%s\", %x\n",
303 i, n_series, count, offset, name, dunno);
305 dump_source(count, n_series);