tccgen: nodata_wanted

The existing variable 'nocode_wanted' is now used to control
output of static data too. So...

(nocode_wanted == 0)
    code and data (normal within functions)
(nocode_wanted < 0)
    means: no code, but data (global or static data)
(nocode_wanted > 0)
    means: no code and no data (code and data suppressed)
(nocode_wanted & 0xC0000000)
    means:  we're in declaration of static data

Also: new option '-dT' to be used with -run
    tcc -dT -run file.c
This will look in file.c for certain comment-boundaries:
    /*-* test-xxx: ...some description */
and then for each test below run it from memory.  This way
various features and error messages can be tested with one
single file.  See 96_nodata_wanted.c for an example.

Also: tccgen.c: one more bitfield fix
This commit is contained in:
grischka
2017-07-16 12:10:00 +02:00
parent 69a137ff88
commit 7f1ab9b1e1
10 changed files with 330 additions and 86 deletions

View File

@@ -544,3 +544,108 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
}
/* -------------------------------------------------------------- */
/* run test snippets from file */
static char *readfile(const char *fname)
{
char *buf;
int fsize;
FILE *fi;
fi = fopen(fname, "rb");
if (!fi)
return NULL;
fseek(fi, 0, SEEK_END);
fsize = ftell(fi);
fseek(fi, 0, SEEK_SET);
buf = tcc_malloc(fsize + 1);
fread(buf, fsize, 1, fi);
fclose(fi);
buf[fsize] = 0;
return buf;
}
static int run_prog(const char *prog, int ac, char **av)
{
TCCState *s;
int (*func)(int, char**);
int ret = -10000;
s = tcc_new();
tcc_parse_args(s, &ac, &av, 1);
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if (tcc_compile_string(s, prog) == -1)
goto done;
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
goto done;
func = tcc_get_symbol(s, "main");
if (!func)
goto done;
ret = func(ac, av);
done:
tcc_delete(s);
return ret;
}
static char *trimback(char *a, char *e)
{
while (e > a && (unsigned char)e[-1] <= ' ')
--e;
*e = 0;;
return a;
}
ST_FUNC int tcc_tool_test(TCCState *s, int argc, char **argv)
{
const char *fname;
char *buf, *p, *a, *b, *e, tmp[100];
int r = 0, c, n;
const char sep[] = "/*-* test";
n = s->do_test - argc;
if (!n)
return 0;
fname = argv[0], argv -= n, argc += n;
buf = readfile(fname);
if (NULL == buf)
return -1;
p = strstr(buf, sep);
if (!p) {
tcc_free(buf);
return -1;
}
while (*p) {
a = p, p = strchr(p, '\n');
if (NULL == p)
break;
*p++ = 0;
b = p, p = strstr(p, sep);
if (NULL == p)
p = strchr(b, 0);
c = *p, *p = 0;
trimback(a, b);
if (r)
printf("\n");
printf("%s\n", a);
fflush(stdout);
e = a += sizeof sep - 5;
while (*e && *e != ':')
++e;
if (!*e || e - a > 32)
e = a + 4;
n = snprintf(tmp, sizeof tmp, "#line 1 \"%.*s\"\n", (int)(e - a), a);
if (b - buf >= n)
b = memcpy(b - n, tmp, n);
n = run_prog(b, argc, argv);
if (n != -10000)
printf("returns %d\n", n);
*p = c, ++r;
}
tcc_free(buf);
exit(0);
}
/* -------------------------------------------------------------- */