14 #define STR(x) XSTR(x)
15 #define WHERE __FILE__":" STR(__LINE__)
21 memcpy(&x, &data[pos], 4);
30 memcpy(&x, &data[pos], 8);
45 match_u32_assert(uint32_t x, const char *where)
47 unsigned int y = get_u32();
50 fprintf(stderr, "%s: 0x%x: expected i%u, got i%u\n", where, pos - 4, x, y);
54 #define match_u32_assert(x) match_u32_assert(x, WHERE)
57 all_ascii(const uint8_t *p)
60 if (*p < 32 || *p > 126)
66 get_fixed_string(int len, const char *where)
68 if (pos + len > n || !memchr(&data[pos], 0, len) || !all_ascii(&data[pos]))
70 fprintf(stderr, "%s: 0x%x: bad fixed-width string\n", where, pos);
73 char *s = (char *) &data[pos];
77 #define get_fixed_string(len) get_fixed_string(len, WHERE)
80 all_ascii2(const uint8_t *p, size_t n)
82 for (size_t i = 0; i < n; i++)
83 if (p[i] < 32 || p[i] > 126)
89 get_string(const char *where)
92 /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/
93 /*&& all_ascii(&data[pos + 4], data[pos])*/)
95 int len = data[pos] + data[pos + 1] * 256;
96 char *s = malloc(len + 1);
98 memcpy(s, &data[pos + 4], len);
105 fprintf(stderr, "%s: 0x%x: expected string\n", where, pos);
109 #define get_string() get_string(WHERE)
112 dump_raw(FILE *stream, int start, int end, const char *separator)
114 for (size_t i = start; i < end; )
121 && i + 4 + data[i] + data[i + 1] * 256 <= end
122 && all_ascii2(&data[i + 4], data[i] + data[i + 1] * 256))
124 fprintf(stream, "%s\"", separator);
125 fwrite(&data[i + 4], 1, data[i] + data[i + 1] * 256, stream);
126 fputs("\" ", stream);
128 i += 4 + data[i] + data[i + 1] * 256;
130 else if (i + 12 <= end
137 memcpy (&d, &data[i + 4], 8);
138 fprintf (stream, "F40.%d(%.*f)%s", data[i], data[i], d, separator);
141 else if (i + 12 <= end
148 memcpy (&d, &data[i + 4], 8);
149 fprintf (stream, "PCT40.%d(%.*f)%s", data[i], data[i], d, separator);
152 else if (i + 4 <= end
157 fprintf (stream, "i%d ", data[i]);
162 fprintf(stream, "%02x ", data[i]);
169 main(int argc, char **argv)
174 if (isatty(STDIN_FILENO))
176 fprintf(stderr, "redirect stdin from a .bin file\n");
179 if (fstat(STDIN_FILENO, &s))
191 if (read(STDIN_FILENO, data, n) != n)
198 match_u32_assert(0x1b000);
199 match_u32_assert(s.st_size);
201 printf ("%08x:", pos);
202 int count = get_u32(), n_series = get_u32();
203 printf (" %d series, %d observations per series\n", n_series, count);
204 printf ("%08x\n\n", pos);
211 sysmis = {.b = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff}};
213 for (int i = 0; i < n_series; i++)
215 printf ("%08x:", pos);
216 printf (" %s\n", get_fixed_string(288));
217 printf ("%08x:", pos);
218 for (int i = 0; i < count; i++)
220 double d = get_double();
224 printf (" %.*g", DBL_DIG, d);
229 printf ("%08x:", pos);
230 printf (" %d", get_u32());
231 printf (", \"%s\"\n", get_string());
233 printf ("\n%08x:", pos);
234 int n_more_series = get_u32();
235 printf (" %d series to come\n", n_more_series);
237 for (int i = 0; i < n_more_series; i++)
239 printf ("%08x:", pos);
240 printf (" \"%s\"", get_string());
241 int n_pairs = get_u32();
242 for (int j = 0; j < n_pairs; j++)
246 printf (" (%d,%d)", x, y);
251 printf ("\n%08x:", pos);
252 int n_strings = get_u32();
253 printf (" %d strings\n", n_strings);
254 for (int i = 0; i < n_strings; i++)
257 char *s = get_string();
258 printf ("%d: \"%s\" (%d)\n", i, s, x);
261 dump_raw (stdout, pos, n, "\n");