aboutsummaryrefslogtreecommitdiff
path: root/tcctools.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcctools.c')
-rw-r--r--tcctools.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/tcctools.c b/tcctools.c
index 53d88be..0e2755b 100644
--- a/tcctools.c
+++ b/tcctools.c
@@ -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);
+}
+
+/* -------------------------------------------------------------- */