From dc5b9bd64d1c1f544e4813dc946b5a83ad304cee Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 18 Feb 2010 17:09:31 +0000 Subject: [PATCH] Refactor gcc.c, pulling out the reusable code --- configure.ac | 2 +- driver/gcc/gcc.c | 89 ++++------------------------------------- driver/utils/cwrapper.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ driver/utils/cwrapper.h | 5 +++ 4 files changed, 114 insertions(+), 82 deletions(-) create mode 100644 driver/utils/cwrapper.c create mode 100644 driver/utils/cwrapper.h diff --git a/configure.ac b/configure.ac index 19cb391..4d83dbc 100644 --- a/configure.ac +++ b/configure.ac @@ -444,7 +444,7 @@ then tar -zxf ../../ghc-tarballs/mingw/w32api*.tar.gz && mv bin/gcc.exe bin/realgcc.exe ) - inplace/mingw/bin/realgcc.exe driver/gcc/gcc.c driver/utils/getLocation.c -Idriver/utils -o inplace/mingw/bin/gcc.exe + inplace/mingw/bin/realgcc.exe driver/gcc/gcc.c driver/utils/cwrapper.c driver/utils/getLocation.c -Idriver/utils -o inplace/mingw/bin/gcc.exe AC_MSG_NOTICE([In-tree mingw tree created]) fi if ! test -d inplace/perl || diff --git a/driver/gcc/gcc.c b/driver/gcc/gcc.c index c086f74..4efd559 100644 --- a/driver/gcc/gcc.c +++ b/driver/gcc/gcc.c @@ -5,6 +5,7 @@ therefore need to add various -B flags to the gcc commandline, so that it uses our in-tree mingw. Hence this wrapper. */ +#include "cwrapper.h" #include "getLocation.h" #include #include @@ -13,74 +14,10 @@ #include #include -static void die(const char *fmt, ...) { - va_list argp; - - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - exit(1); -} - -static char *mkString(const char *fmt, ...) { - char *p; - int i, j; - va_list argp; - - va_start(argp, fmt); - i = vsnprintf(NULL, 0, fmt, argp); - va_end(argp); - - if (i < 0) { - die("snprintf 0 failed: errno %d: %s\n", errno, strerror(errno)); - } - - p = malloc(i + 1); - if (p == NULL) { - die("malloc failed: errno %d: %s\n", errno, strerror(errno)); - } - - va_start(argp, fmt); - j = vsnprintf(p, i + 1, fmt, argp); - va_end(argp); - if (i < 0) { - die("snprintf with %d failed: errno %d: %s\n", - i + 1, errno, strerror(errno)); - } - - return p; -} - -char *quote(char *str) { - char *quotedStr; - char *p; - int i; - - quotedStr = malloc(2 * strlen(str) + 2 + 1); - if (quotedStr == NULL) { - die("malloc failed: errno %d: %s\n", errno, strerror(errno)); - } - p = quotedStr; - *p++ = '"'; - while (*str) { - if (*str == '"') { - *p++ = '\\'; - } - *p++ = *str++; - } - *p++ = '"'; - *p = '\0'; - - return quotedStr; -} - int main(int argc, char** argv) { - char *p; char *binDir; char *exePath; - char *bArg; - char **newArgv; - int i, j, ret; + char *preArgv[4]; binDir = getExecutablePath(); exePath = mkString("%s/realgcc.exe", binDir); @@ -88,21 +25,11 @@ int main(int argc, char** argv) { /* Without these -B args, gcc will still work. However, if you have a mingw installation in c:/mingw then it will use files from that in preference to the in-tree files. */ + preArgv[0] = mkString("-B%s", binDir); + preArgv[1] = mkString("-B%s/../lib", binDir); + preArgv[2] = mkString("-B%s/../lib/gcc/mingw32/3.4.5", binDir); + preArgv[3] = mkString("-B%s/../libexec/gcc/mingw32/3.4.5", binDir); - newArgv = malloc(sizeof(char *) * (argc + 4 + 1)); - newArgv[0] = quote(exePath); - newArgv[1] = quote(mkString("-B%s", binDir)); - newArgv[2] = quote(mkString("-B%s/../lib", binDir)); - newArgv[3] = quote(mkString("-B%s/../lib/gcc/mingw32/3.4.5", binDir)); - newArgv[4] = quote(mkString("-B%s/../libexec/gcc/mingw32/3.4.5", binDir)); - for (i = 1; i < argc; i++) { - newArgv[4 + i] = quote(argv[i]); - } - newArgv[4 + argc] = NULL; - // execv(exePath, argv); - ret = spawnv(_P_WAIT, exePath, (const char* const*)newArgv); - if (errno) { - die("spawnv failed: errno %d: %s\n", errno, strerror(errno)); - } - exit(ret); + run(exePath, 4, preArgv, argc - 1, argv + 1); } + diff --git a/driver/utils/cwrapper.c b/driver/utils/cwrapper.c new file mode 100644 index 0000000..6a58114 --- /dev/null +++ b/driver/utils/cwrapper.c @@ -0,0 +1,100 @@ + +/* gcc on mingw is hardcoded to use /mingw (which is c:/mingw) to + find various files. If this is a different version of mingw to the + one that we have in the GHC tree then things can go wrong. We + therefore need to add various -B flags to the gcc commandline, + so that it uses our in-tree mingw. Hence this wrapper. */ + +#include "cwrapper.h" +#include +#include +#include +#include +#include +#include + +void die(const char *fmt, ...) { + va_list argp; + + va_start(argp, fmt); + vfprintf(stderr, fmt, argp); + va_end(argp); + exit(1); +} + +char *mkString(const char *fmt, ...) { + char *p; + int i, j; + va_list argp; + + va_start(argp, fmt); + i = vsnprintf(NULL, 0, fmt, argp); + va_end(argp); + + if (i < 0) { + die("snprintf 0 failed: errno %d: %s\n", errno, strerror(errno)); + } + + p = malloc(i + 1); + if (p == NULL) { + die("malloc failed: errno %d: %s\n", errno, strerror(errno)); + } + + va_start(argp, fmt); + j = vsnprintf(p, i + 1, fmt, argp); + va_end(argp); + if (i < 0) { + die("snprintf with %d failed: errno %d: %s\n", + i + 1, errno, strerror(errno)); + } + + return p; +} + +char *quote(char *str) { + char *quotedStr; + char *p; + int i; + + quotedStr = malloc(2 * strlen(str) + 2 + 1); + if (quotedStr == NULL) { + die("malloc failed: errno %d: %s\n", errno, strerror(errno)); + } + p = quotedStr; + *p++ = '"'; + while (*str) { + if (*str == '"') { + *p++ = '\\'; + } + *p++ = *str++; + } + *p++ = '"'; + *p = '\0'; + + return quotedStr; +} + +int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2) { + char **p; + char **newArgv; + int i, ret; + + newArgv = malloc(sizeof(char *) * (1 + numArgs1 + numArgs2 + 1)); + if (newArgv == NULL) { + die("malloc failed: errno %d: %s\n", errno, strerror(errno)); + } + p = newArgv; + *p++ = quote(exePath); + for (i = 0; i < numArgs1; i++) { + *p++ = quote(args1[i]); + } + for (i = 0; i < numArgs2; i++) { + *p++ = quote(args2[i]); + } + *p = NULL; + ret = spawnv(_P_WAIT, exePath, (const char* const*)newArgv); + if (errno) { + die("spawnv failed: errno %d: %s\n", errno, strerror(errno)); + } + exit(ret); +} diff --git a/driver/utils/cwrapper.h b/driver/utils/cwrapper.h new file mode 100644 index 0000000..53cf652 --- /dev/null +++ b/driver/utils/cwrapper.h @@ -0,0 +1,5 @@ + +void die(const char *fmt, ...); +char *mkString(const char *fmt, ...); +int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2); + -- 1.7.10.4