scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 6436f30f804ab7221e12510431c1c779785eee08
parent 392865a83653ffd582efd2c855cab9ac853cadc2
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 20 Jun 2016 14:01:45 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
Mcc1/error.c | 4+---
Mcc1/main.c | 51+++++++++++++++++++++++++++------------------------
Mdriver/posix/scc.c | 114+++++++++++++++++++++++++++++++------------------------------------------------
Minc/cc.h | 8++++++++
Mlib/Makefile | 2+-
Alib/newitem.c | 12++++++++++++
6 files changed, 94 insertions(+), 97 deletions(-)

diff --git a/cc1/error.c b/cc1/error.c @@ -24,10 +24,8 @@ warn_error(int flag, char *fmt, va_list va) putc('\n', stderr); if (flag < 0) { - if (!failure) { - failure = 1; + if (!failure) fclose(stdout); - } failure = 1; if (++nerrors == MAXERRNUM) { fputs("too many errors\n", stderr); diff --git a/cc1/main.c b/cc1/main.c @@ -15,7 +15,8 @@ char *argv0; int warnings; jmp_buf recover; -static char *output; +static char *base, *output; +static struct items uflags; int onlycpp; extern int failure; @@ -30,63 +31,65 @@ clean(void) static void usage(void) { - die("usage: %s [-E] [-D macro[=value]] ... [-I dir] [-w] [-d]" - "[-o output] [input]", argv0); + die(!strcmp(base, "cpp") ? + "usage: cpp [-wd] [-D def[=val]]... [-U def]... [-I dir]... " + "[input]" : + "usage: cc1 [-Ewd] [-D def[=val]]... [-U def]... [-I dir]... " + "[-o output] [input]"); } int main(int argc, char *argv[]) { char *base; - static char *uvec[NR_USWITCHES], **umacro = uvec; + int i; atexit(clean); icpp(); + /* if run as cpp, only run the preprocessor */ + if ((base = strrchr(argv0, '/'))) + ++base; + else + base = argv0; + ARGBEGIN { - case 'w': - warnings = 1; + case 'D': + defmacro(EARGF(usage())); break; case 'E': onlycpp = 1; break; - case 'D': - defmacro(EARGF(usage())); + case 'I': + incdir(EARGF(usage())); break; case 'U': - if (umacro == &uvec[NR_USWITCHES]) - die("too many -U switches"); - *umacro++ = EARGF(usage()); + uflags.s = newitem(uflags.s, uflags.n++, EARGF(usage())); break; case 'd': DBGON(); break; - case 'I': - incdir(EARGF(usage())); - break; case 'o': output = EARGF(usage()); break; + case 'w': + warnings = 1; + break; default: usage(); } ARGEND - for (umacro = uvec; *umacro; umacro++) - undefmacro(*umacro); - if (argc > 1) usage(); - /* if run as cpp, only run the preprocessor */ - if ((base = strrchr(argv0, '/'))) - ++base; - else - base = argv0; + if (output && !freopen(output, "w", stdout)) + die("error opening output: %s", strerror(errno)); + if (!strcmp(base, "cpp")) onlycpp = 1; - if (output && !freopen(output, "w", stdout)) - die("error opening output: %s", strerror(errno)); + for (i = 0; i < uflags.n; ++i) + undefmacro(uflags.s[i]); ilex(*argv); if (onlycpp) { diff --git a/driver/posix/scc.c b/driver/posix/scc.c @@ -32,7 +32,7 @@ static struct tool { char **args; char bin[16]; char *outfile; - int nparams, nargs, in, out, init, error; + int nparams, nargs, in, out, init; pid_t pid; } tools[] = { [CC1] = { .bin = "cc1", .cmd = PREFIX "/libexec/scc/", }, @@ -46,53 +46,24 @@ static struct tool { [STRIP] = { .bin = "strip", .cmd = "strip", }, }; -struct objects { - char **f; - int n; -}; - char *argv0; -static char *arch; -static struct objects objtmp, objout; +static char *arch, *outfile; +static struct items objtmp, objout; static int Eflag, Sflag, cflag, kflag, sflag; -static void -cleanobjects(void) -{ - int i; - - for (i = 0; i < objtmp.n; ++i) - unlink(objtmp.f[i]); -} +extern int failure; static void terminate(void) { - struct tool *t; - int tool, failed = -1; + int i; - for (tool = 0; tool < LAST_TOOL; ++tool) { - t = &tools[tool]; - if (t->pid) { - kill(t->pid, SIGTERM); - if (t->error) - failed = tool; - if (tool >= failed && t->outfile) - unlink(t->outfile); - } + if (!kflag) { + for (i = 0; i < objtmp.n; ++i) + unlink(objtmp.s[i]); } } -static char ** -newitem(char **array, int num, char *item) -{ - char **ar = xrealloc(array, (num + 1) * sizeof(char **)); - - ar[num] = item; - - return ar; -} - static void addarg(int tool, char *arg) { @@ -144,8 +115,7 @@ inittool(int tool) break; case LD: addarg(tool, "-o"); - if (!t->outfile) - t->outfile = xstrdup("a.out"); + t->outfile = outfile ? outfile : xstrdup("a.out"); addarg(tool, t->outfile); break; case AS: @@ -212,19 +182,19 @@ settool(int tool, char *infile, int nexttool) addarg(tool, t->outfile); break; case AS: - t->outfile = outfilename(infile, "o"); + t->outfile = outfile ? outfile : outfilename(infile, "o"); addarg(tool, t->outfile); break; case LD: for (i = 0; i < objtmp.n; ++i) - addarg(tool, xstrdup(objtmp.f[i])); + addarg(tool, xstrdup(objtmp.s[i])); for (i = 0; i < objout.n; ++i) - addarg(tool, xstrdup(objout.f[i])); + addarg(tool, xstrdup(objout.s[i])); break; case STRIP: if (cflag || kflag) { for (i = 0; i < objout.n; ++i) - addarg(tool, xstrdup(objout.f[i])); + addarg(tool, xstrdup(objout.s[i])); } if (!cflag && tools[LD].outfile) addarg(tool, tools[LD].outfile); @@ -236,8 +206,10 @@ settool(int tool, char *infile, int nexttool) if (fdin > -1) { t->in = fdin; fdin = -1; - } else if (infile) { - addarg(tool, xstrdup(infile)); + } else { + t->in = -1; + if (infile) + addarg(tool, xstrdup(infile)); } if (nexttool < LAST_TOOL) { @@ -245,6 +217,8 @@ settool(int tool, char *infile, int nexttool) die("scc: pipe: %s", strerror(errno)); t->out = fds[1]; fdin = fds[0]; + } else { + t->out = -1; } addarg(tool, NULL); @@ -299,35 +273,37 @@ toolfor(char *file) die("scc: do not recognize filetype of %s", file); } -static void +static int validatetools(void) { struct tool *t; - int i, tool, st; + int i, tool, st, failed = LAST_TOOL; + for (tool = 0; tool < LAST_TOOL; ++tool) { t = &tools[tool]; if (t->pid) { if (waitpid(t->pid, &st, 0) < 0 || !WIFEXITED(st) || WEXITSTATUS(st) != 0) { - t->error = 1; - exit(-1); + failure = 1; + failed = tool; } + if (tool >= failed && t->outfile) + unlink(t->outfile); for (i = t->nparams; i < t->nargs; ++i) free(t->args[i]); t->nargs = t->nparams; t->pid = 0; - t->error = 0; - t->in = -1; - t->out = -1; } } + + return failed == LAST_TOOL; } static void build(char *file) { int tool = toolfor(file), nexttool; - struct objects *objs = (tool == LD || cflag || kflag) ? + struct items *objs = (tool == LD || cflag || kflag) ? &objout : &objtmp; for (; tool < LAST_TOOL; tool = nexttool) { @@ -367,16 +343,22 @@ build(char *file) spawn(settool(inittool(tool), file, nexttool)); } - validatetools(); - - objs->f = newitem(objs->f, objs->n++, outfilename(file, "o")); + if (validatetools()) + objs->s = newitem(objs->s, objs->n++, outfilename(file, "o")); } static void usage(void) { - die("usage: %s [-E|-kS] [-w] [-m arch] [-c] [-o binout] [-s]\n" - " [-D macro[=val]]... [-I dir]... file...", argv0); + die("usage: scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-ksw] [-m arch] [-E|-S] [-o outfile] file...\n" + " scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-ksw] [-m arch] [-E|-S] -c file...\n" + " scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-ksw] [-m arch] -c -o outfile file"); } int @@ -424,7 +406,7 @@ main(int argc, char *argv[]) arch = EARGF(usage()); break; case 'o': - tools[LD].outfile = xstrdup(EARGF(usage())); + outfile = xstrdup(EARGF(usage())); break; case 's': sflag = 1; @@ -440,19 +422,16 @@ main(int argc, char *argv[]) usage(); } ARGEND - if (Eflag && (Sflag || kflag)) + if (Eflag && (Sflag || kflag) || argc > 1 && cflag && outfile || !argc) usage(); - if (!argc) - die("scc: fatal error: no input file"); - for (; *argv; ++argv) build(*argv); if (Eflag || Sflag) - return 0; + return failure; - if (!cflag) { + if (!cflag && !failure) { spawn(settool(inittool(LD), NULL, LAST_TOOL)); validatetools(); } @@ -462,8 +441,5 @@ main(int argc, char *argv[]) validatetools(); } - if (!kflag) - cleanobjects(); - - return 0; + return failure; } diff --git a/inc/cc.h b/inc/cc.h @@ -1,4 +1,6 @@ /* See LICENSE file for copyright and license details. */ +#include <sys/types.h> + #ifndef NDEBUG extern int debug; #define DBG(fmt, ...) dbg(fmt, __VA_ARGS__) @@ -12,8 +14,14 @@ extern int debug; #define PREFIX "/usr/local/" #endif +struct items { + char **s; + int n; +}; + extern void die(const char *fmt, ...); extern void dbg(const char *fmt, ...); +extern char **newitem(char **array, int num, char *item); extern void *xmalloc(size_t size); extern void *xcalloc(size_t nmemb, size_t size); extern char *xstrdup(const char *s); diff --git a/lib/Makefile b/lib/Makefile @@ -2,7 +2,7 @@ .POSIX: include ../config.mk -OBJS = die.o xcalloc.o xmalloc.o xrealloc.o xstrdup.o debug.o +OBJS = debug.o die.o newitem.o xcalloc.o xmalloc.o xrealloc.o xstrdup.o all: libcc.a diff --git a/lib/newitem.c b/lib/newitem.c @@ -0,0 +1,12 @@ +#include "../inc/cc.h" + +char ** +newitem(char **array, int num, char *item) +{ + char **ar = xrealloc(array, (num + 1) * sizeof(char **)); + + ar[num] = item; + + return ar; +} +