Fix build on Windows
[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
58     quotedStr = malloc(2 * strlen(str) + 2 + 1);
59     if (quotedStr == NULL) {
60         die("malloc failed: errno %d: %s\n", errno, strerror(errno));
61     }
62     p = quotedStr;
63     *p++ = '"';
64     while (*str) {
65         if (*str == '"') {
66             *p++ = '\\';
67         }
68         *p++ = *str++;
69     }
70     *p++ = '"';
71     *p = '\0';
72
73     return quotedStr;
74 }
75
76 __attribute__((noreturn)) int run(char *exePath, int numArgs1, char **args1, int numArgs2, char **args2) {
77     char **p;
78     char **newArgv;
79     int i, ret;
80
81     newArgv = malloc(sizeof(char *) * (1 + numArgs1 + numArgs2 + 1));
82     if (newArgv == NULL) {
83         die("malloc failed: errno %d: %s\n", errno, strerror(errno));
84     }
85     p = newArgv;
86     *p++ = quote(exePath);
87     for (i = 0; i < numArgs1; i++) {
88         *p++ = quote(args1[i]);
89     }
90     for (i = 0; i < numArgs2; i++) {
91         *p++ = quote(args2[i]);
92     }
93     *p = NULL;
94     ret = spawnv(_P_WAIT, exePath, (const char* const*)newArgv);
95     if (errno) {
96         die("spawnv failed: errno %d: %s\n", errno, strerror(errno));
97     }
98     exit(ret);
99 }