tcc-stupidos/tests/misc/c2str.c

159 lines
4.3 KiB
C
Raw Normal View History

#include <stdio.h>
#include <string.h>
/* 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)
{
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)");
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;
}