6a58114bcf5f1042a8a7982806c9ba72fb1b91b4
[ghc-hetmet.git] / driver / utils / cwrapper.c
1
2 /* gcc on mingw is hardcoded to use /mingw (which is c:/mingw) to
3    find various files. If this is a different version of mingw to the
4    one that we have in the GHC tree then things can go wrong. We
5    therefore need to add various -B flags to the gcc commandline,
6    so that it uses our in-tree mingw. Hence this wrapper. */
7
8 #include "cwrapper.h"
9 #include <errno.h>
10 #include <process.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14 #include <string.h>
15
16 void die(const char *fmt, ...) {
17     va_list argp;
18
19     va_start(argp, fmt);
20     vfprintf(stderr, fmt, argp);
21     va_end(argp);
22     exit(1);
23 }
24
25 char *mkString(const char *fmt, ...) {
26     char *p;
27     int i, j;
28     va_list argp;
29
30     va_start(argp, fmt);
31     i = vsnprintf(NULL, 0, fmt, argp);
32     va_end(argp);
33
34     if (i < 0) {
35         die("snprintf 0 failed: errno %d: %s\n", errno, strerror(errno));
36     }
37
38     p = malloc(i + 1);
39     if (p == NULL) {
40         die("malloc failed: errno %d: %s\n", errno, strerror(errno));
41     }
42
43     va_start(argp, fmt);
44     j = vsnprintf(p, i + 1, fmt, argp);
45     va_end(argp);
46     if (i < 0) {
47         die("snprintf with %d failed: errno %d: %s\n",
48             i + 1, errno, strerror(errno));
49     }
50
51     return p;
52 }
53
54 char *quote(char *str) {
55     char *quotedStr;
56     char *p;
57     int i;
58
59     quotedStr = malloc(2 * strlen(str) + 2 + 1);
60     if (quotedStr == NULL) {
61         die("malloc failed: errno %d: %s\n", errno, strerror(errno));
62     }
63     p = quotedStr;
64     *p++ = '"';
65     while (*str) {
66         if (*str == '"') {
67             *p++ = '\\';
68         }
69         *p++ = *str++;
70     }
71     *p++ = '"';
72     *p = '\0';
73
74     return quotedStr;
75 }
76
77 int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2) {
78     char **p;
79     char **newArgv;
80     int i, ret;
81
82     newArgv = malloc(sizeof(char *) * (1 + numArgs1 + numArgs2 + 1));
83     if (newArgv == NULL) {
84         die("malloc failed: errno %d: %s\n", errno, strerror(errno));
85     }
86     p = newArgv;
87     *p++ = quote(exePath);
88     for (i = 0; i < numArgs1; i++) {
89         *p++ = quote(args1[i]);
90     }
91     for (i = 0; i < numArgs2; i++) {
92         *p++ = quote(args2[i]);
93     }
94     *p = NULL;
95     ret = spawnv(_P_WAIT, exePath, (const char* const*)newArgv);
96     if (errno) {
97         die("spawnv failed: errno %d: %s\n", errno, strerror(errno));
98     }
99     exit(ret);
100 }