Commit dc5b9bd6 authored by Ian Lynagh's avatar Ian Lynagh
Browse files

Refactor gcc.c, pulling out the reusable code

parent f3e08050
......@@ -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 ||
......
......@@ -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 <errno.h>
#include <process.h>
......@@ -13,74 +14,10 @@
#include <stdarg.h>
#include <string.h>
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);
}
/* 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 <errno.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
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);
}
void die(const char *fmt, ...);
char *mkString(const char *fmt, ...);
int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment