char buf[1024];
+/* 0 = in statement, first word wasn't typedef */
+/* 1 = beginning of statement, look for typedef */
+/* 2 = in statement, first word was typedef */
+/* 3 = in statement, first word was typedef, got potential name */
+/* 4-7 = in preprocessor line, subtract 4 when newline seen */
+int typedef_state = 1;
+/* "typedef struct { something; } typename;" or "typedef int jmp_buf[7];" */
+/* ignore what's in brackets, counter is only active in typedef_state 2-3 */
+int typedef_count;
+int typedef_str_len;
+char typedef_str_data[1024];
+
int main(argc, argv) int argc; char **argv; {
+ FILE *fin, *fout;
char *p, *q, *r;
int l, m, n;
int e, i;
- while (fgets(buf, sizeof(buf), stdin)) {
+ if (argc < 2 || strcmp(argv[1], "-") == 0)
+ fin = stdin;
+ else if ((fin = fopen(argv[1], "r")) == 0)
+ abort();
+
+ if (argc < 3 || strcmp(argv[2], "-") == 0)
+ fout = stdout;
+ else if ((fout = fopen(argv[2], "w")) == 0)
+ abort();
+
+ fputs("#include <stdint.h>\n\
+typedef int16_t x_short;\n\
+typedef int32_t x_int;\n\
+typedef int32_t x_long;\n\
+typedef uint16_t x_unsigned_short;\n\
+typedef uint32_t x_unsigned_int;\n\
+typedef uint32_t x_unsigned_long;\n\
+#define _va_arg_short(argp) va_arg(argp, int)\n\
+#define _va_arg_int(argp) va_arg(argp, int)\n\
+#define _va_arg_long(argp) va_arg(argp, int)\n\
+#define _va_arg_unsigned_short(argp) va_arg(argp, unsigned int)\n\
+#define _va_arg_unsigned_int(argp) va_arg(argp, unsigned int)\n\
+#define _va_arg_unsigned_long(argp) va_arg(argp, unsigned int)\n", fout);
+
+ while (fgets(buf, sizeof(buf), fin)) {
p = buf;
l = 0;
if (p[l] == '#') {
+ typedef_state |= 4;
++l;
while (isblank(p[l]))
++l;
else if (p[l] == '"') {
e = '"';
include:
- fwrite(p, ++l, 1, stdout);
+ fwrite(p, ++l, 1, fout);
p += l;
for (m = 0; p[m] && p[m] != e; ++m)
;
q = p + l;
m -= l;
if (m >= 4 && memcmp(q, "nox_", 4) == 0) {
- fwrite(p, l, 1, stdout);
+ fwrite(p, l, 1, fout);
p = q + 4;
l = m - 4;
}
else if (
(l != 0 || m != 8 || memcmp(p, "setjmp.h", 8) != 0) &&
(l != 0 || m != 8 || memcmp(p, "stdarg.h", 8) != 0) &&
- (l != 0 || m != 8 || memcmp(p, "stdint.h", 8) != 0) &&
+ (l != 0 || m != 8 || memcmp(p, "fint.h", 8) != 0) &&
(l != 0 || m != 9 || memcmp(p, "varargs.h", 9) != 0)
) {
#if 1
- fwrite(p, l, 1, stdout);
+ fwrite(p, l, 1, fout);
#else
fwrite(p - 1, l + m + 2, 1, stderr); /* include <> or "" */
- fputc('\n', stderr);
+ putc('\n', stderr);
if (l) {
- fwrite("../", 3, 1, stdout);
- fwrite(p, l, 1, stdout);
- fwrite(".xify/", 6, 1, stdout);
+ fwrite("../", 3, 1, fout);
+ fwrite(p, l, 1, fout);
+ fwrite(".xify/", 6, 1, fout);
}
#endif
- fwrite("x_", 2, 1, stdout);
+ fwrite("x_", 2, 1, fout);
p = q;
l = m;
}
continue;
}
}
- fwrite(p, l, 1, stdout);
- fputs(p + l + m, stdout);
+ fwrite(p, l, 1, fout);
+ fputs(p + l + m, fout);
continue;
}
else
l += m;
- fwrite(p, l, 1, stdout);
+ fwrite(p, l, 1, fout);
p += l;
l = 0;
}
}
+ else
+ typedef_state &= 3;
while (p[l]) {
+ if (isspace(p[l]) || p[l] == '\n') {
+ ++l;
+ while (isspace(p[l]) || p[l] == '\n')
+ ++l;
+ goto flush;
+ }
if (isalpha(p[l]) || p[l] == '_') {
++l;
while (isalnum(p[l]) || p[l] == '_')
++l;
+ switch (typedef_state) {
+ case 1:
+ if (l == 7 && memcmp(p, "typedef", 7) == 0)
+ typedef_state = 2;
+ else
+ typedef_state = 0;
+ break;
+ case 2:
+ case 3:
+ if (typedef_count == 0) {
+ typedef_str_len = l;
+ memcpy(typedef_str_data, p, l);
+ typedef_state = 3;
+ }
+ break;
+ }
if (
(l == 6 && memcmp(p, "extern", 6) == 0) ||
(l == 8 && memcmp(p, "register", 8) == 0) ||
(l == 6 && memcmp(p, "static", 6) == 0)
) {
- fwrite(p, l, 1, stdout);
+ fwrite(p, l, 1, fout);
p += l;
l = 0;
while (isblank(p[l]))
while (isblank(q[m]))
++m;
if (q[m] != '*') /* avoid something like: register FILE *fp; */
- fwrite(" x_int", 6, 1, stdout);
+ fwrite(" x_int", 6, 1, fout);
found_typedef:
;
}
else /* maybe something like: register *p; */
- fwrite(" x_int", 6, 1, stdout);
+ fwrite(" x_int", 6, 1, fout);
}
else if (l == 3 && memcmp(p, "int", 3) == 0) {
- fwrite("x_int", 5, 1, stdout);
+ fwrite("x_int", 5, 1, fout);
p += l;
l = 0;
}
(l == 5 && memcmp(p, "short", 5) == 0) ||
(l == 4 && memcmp(p, "long", 4) == 0)
) {
- fwrite("x_", 2, 1, stdout);
- fwrite(p, l, 1, stdout);
+ fwrite("x_", 2, 1, fout);
+ fwrite(p, l, 1, fout);
p += l;
l = 0;
while (isblank(p[l]))
while (isalnum(q[m]) || q[m] == '_')
++m;
if (m == 3 && memcmp(q, "int", 3) == 0) {
- fwrite("x_unsigned_int", 14, 1, stdout);
+ fwrite("x_unsigned_int", 14, 1, fout);
p += l + m;
l = 0;
}
(m == 5 && memcmp(q, "short", 5) == 0) ||
(m == 4 && memcmp(q, "long", 4) == 0)
) {
- fwrite("x_unsigned_", 11, 1, stdout);
- fwrite(q, m, 1, stdout);
+ fwrite("x_unsigned_", 11, 1, fout);
+ fwrite(q, m, 1, fout);
p += l + m;
l = 0;
while (isblank(p[l]))
}
}
else if (m != 4 || memcmp(q, "char", 4) != 0) {
- fwrite("x_unsigned_int", 14, 1, stdout);
+ fwrite("x_unsigned_int", 14, 1, fout);
p += 8;
l -= 8;
}
memcmp(p, keywords[i].str_data, l) == 0
)
goto found_keyword;
- fwrite("x_", 2, 1, stdout);
+ fwrite("x_", 2, 1, fout);
found_keyword:
;
}
+ goto flush;
+ }
+ switch (typedef_state) {
+ case 2:
+ case 3:
+ if (p[l] == '{' || p[l] == '[') {
+ ++l;
+ ++typedef_count;
+ goto flush;
+ }
+ if (p[l] == '}' || p[l] == ']' && typedef_count > 0) {
+ ++l;
+ --typedef_count;
+ goto flush;
+ }
+ /* fallthru */
+ case 0:
+ case 1:
+ if (typedef_count == 0) {
+ if (p[l] == ';') {
+ ++l;
+ if (typedef_state == 3) {
+ fwrite("typedef: ", 9, 1, stderr);
+ fwrite(typedef_str_data, typedef_str_len, 1, stderr);
+ putc('\n', stderr);
+ if ((q = malloc(typedef_str_len)) == 0)
+ abort();
+ memcpy(q, typedef_str_data, typedef_str_len);
+ if (n_typedefs >= sizeof(typedefs) / sizeof(struct str))
+ abort();
+ typedefs[n_typedefs].str_len = typedef_str_len;
+ typedefs[n_typedefs].str_data = q;
+ ++n_typedefs;
+ }
+ typedef_state = 1;
+ goto flush;
+ }
+ typedef_state &= ~1;
+ }
+ break;
}
- else if (p[l] == '.' && isdigit(p[l + 1])) {
+ if (p[l] == '.' && isdigit(p[l + 1])) {
l += 2;
goto decimal;
}
if (p[l] == '\\')
++l;
if (p[l] == 0) {
- fwrite(p, l, 1, stdout);
- if (fgets(buf, sizeof(buf), stdin) == 0)
+ fwrite(p, l, 1, fout);
+ if (fgets(buf, sizeof(buf), fin) == 0)
return 0;
p = buf;
l = 0;
l += 2;
while (p[l] != '*' || p[l + 1] != '/')
if (p[l] == 0) {
- fwrite(p, l, 1, stdout);
- if (fgets(buf, sizeof(buf), stdin) == 0)
+ fwrite(p, l, 1, fout);
+ if (fgets(buf, sizeof(buf), fin) == 0)
return 0;
p = buf;
l = 0;
}
else
++l;
- fwrite(p, l, 1, stdout);
+ flush:
+ fwrite(p, l, 1, fout);
p += l;
l = 0;
}