#include #include /* replace native host macros by compile-time versions */ const char *platform_macros[] = { "__i386__", "TCC_TARGET_I386", "__x86_64__", "TCC_TARGET_X86_64", "_WIN32", "TCC_TARGET_PE", "__arm__", "TCC_TARGET_ARM", "__ARM_EABI__", "TCC_ARM_EABI", "__aarch64__", "TCC_TARGET_ARM64", "__riscv", "TCC_TARGET_RISCV64", "__APPLE__", "TCC_TARGET_MACHO", "__FreeBSD__", "TARGETOS_FreeBSD", "__FreeBSD_kernel__", "TARGETOS_FreeBSD_kernel", "__OpenBSD__", "TARGETOS_OpenBSD", "__NetBSD__", "TARGETOS_NetBSD", "__linux__", "TARGETOS_Linux", "__SIZEOF_POINTER__", "PTR_SIZE", "__SIZEOF_LONG__", "LONG_SIZE", 0 }; int isid(int c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } int isspc(int c) { return c == ' ' || c == '\t'; } int main(int argc, char **argv) { unsigned char l[1000], l2[1000], *p, *q, *p0; FILE *fp, *op; int c, e, f, cmt, cmt_n; const char *r; if (argc < 3) return 1; fp = fopen(argv[1], "rb"); op = fopen(argv[2], "wb"); if (!fp || !op) { fprintf(stderr, "c2str: file error\n"); return 1; } cmt = cmt_n = 0; for (;;) { p = l; append: if (fgets(p, sizeof l - (p - l), fp)) { p = strchr(p, 0); while (p > l && p[-1] <= ' ') --p; *p = 0; } else if (p == l) break; /* check for continuation */ if (p > l && p[-1] == '\\') { p[-1] = ' '; goto append; } p = l, q = l2, f = 0; /* count & skip leading spaces */ while (*p && isspc(*p)) ++p, ++f; /* handle comments */ if (p[0] == '/' && cmt == 0) { if (p[1] == '*') cmt = 2; if (p[1] == '/') cmt = 1; } if (cmt) { fprintf(op, "%s", l); if (++cmt_n == 1) fprintf(op, " (converted, do not edit this file)", l); fprintf(op, "\n"); if (cmt == 1) cmt = 0; if (cmt == 2) { p = strchr(l, 0); if (p >= l + 2 && p[-1] == '/' && p[-2] == '*') cmt = 0; } continue; } if (f < 4) { /* less than 4 leading spaces : no quotes but replace macros by compile-time versions */ do { for (f = 0; (r = platform_macros[f]); f += 2) { c = strlen(r); e = 0; /*if (memcmp(p, "defined ", 8)) e = 8;*/ if (0 == memcmp(p + e, r, c)) { p += e + c; q = strchr(strcpy(q, platform_macros[f + 1]), 0); break; } } if (r) continue; } while (!!(*q++ = *p++)); fprintf(op, "%s\n", l2); continue; } else { /* output line as C string */ e = f = 0, p0 = p; for (;;) { c = *p++; if (c == '/' && (p[0] == '/' || p[0] == '*')) c = 0; /* trailing comment detected */ if (isspc(c)) { /* remove spaces if possible */ if (q == l2 || isspc(q[-1])) continue; /* keep space after macro identifier */ if ((f >= 2 || e) && (!isid(q[-1]) || !isid(*p))) continue; if (f == 1) f = 2; } if (c == '(') ++e; if (c == ')') --e, f += e == 0; if (c == '\\' || c == '\"') *q++ = '\\'; *q++ = c; if (c == 0) break; p0 = p; } fprintf(op, " \"%s\\n\"%s\n", l2, p0); } } fclose(fp); fclose(op); return 0; }