From f3d96136f292dea83fd760098d189a6884f59eb0 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sat, 15 Aug 2020 22:30:28 +0900 Subject: [PATCH] Split cc1 from compiler driver --- chibicc.h | 3 +++ main.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- self.py | 10 ++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/chibicc.h b/chibicc.h index 88beb88..ae71b4a 100644 --- a/chibicc.h +++ b/chibicc.h @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) diff --git a/main.c b/main.c index d0eb21f..02e8fcf 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,7 @@ #include "chibicc.h" +static bool opt_cc1; +static bool opt_hash_hash_hash; static char *opt_o; static char *input_path; @@ -11,6 +13,16 @@ static void usage(int status) { static void parse_args(int argc, char **argv) { for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-###")) { + opt_hash_hash_hash = true; + continue; + } + + if (!strcmp(argv[i], "-cc1")) { + opt_cc1 = true; + continue; + } + if (!strcmp(argv[i], "--help")) usage(0); @@ -46,9 +58,37 @@ static FILE *open_file(char *path) { return out; } -int main(int argc, char **argv) { - parse_args(argc, argv); +static void run_subprocess(char **argv) { + // If -### is given, dump the subprocess's command line. + if (opt_hash_hash_hash) { + fprintf(stderr, "%s", argv[0]); + for (int i = 1; argv[i]; i++) + fprintf(stderr, " %s", argv[i]); + fprintf(stderr, "\n"); + } + if (fork() == 0) { + // Child process. Run a new command. + execvp(argv[0], argv); + fprintf(stderr, "exec failed: %s: %s\n", argv[0], strerror(errno)); + _exit(1); + } + + // Wait for the child process to finish. + int status; + while (wait(&status) > 0); + if (status != 0) + exit(1); +} + +static void run_cc1(int argc, char **argv) { + char **args = calloc(argc + 10, sizeof(char *)); + memcpy(args, argv, argc * sizeof(char *)); + args[argc++] = "-cc1"; + run_subprocess(args); +} + +static void cc1(void) { // Tokenize and parse. Token *tok = tokenize_file(input_path); Obj *prog = parse(tok); @@ -57,5 +97,16 @@ int main(int argc, char **argv) { FILE *out = open_file(opt_o); fprintf(out, ".file 1 \"%s\"\n", input_path); codegen(prog, out); +} + +int main(int argc, char **argv) { + parse_args(argc, argv); + + if (opt_cc1) { + cc1(); + return 0; + } + + run_cc1(argc, argv); return 0; } diff --git a/self.py b/self.py index 5007dbd..10b8f72 100755 --- a/self.py +++ b/self.py @@ -68,6 +68,16 @@ double strtod(char *nptr, char **endptr); static void va_end(va_list ap) {} long strtoul(char *nptr, char **endptr, int base); void exit(int code); +char *basename(char *path); +char *strrchr(char *s, int c); +int unlink(char *pathname); +int mkstemp(char *template); +int close(int fd); +int fork(void); +int execvp(char *file, char **argv); +void _exit(int code); +int wait(int *wstatus); +int atexit(void (*)(void)); """) for path in sys.argv[1:]: