3 * $Id: ghci.c,v 1.6 2003/06/02 16:24:07 sof Exp $
5 * ghci wrapper - invokes ghc.exe with the added command-line
6 * option "--interactive".
8 * (c) The GHC Team 2001
10 * ghc.exe is searched for using the 'normal' search rules
11 * for DLLs / EXEs (i.e., first in the same dir as this wrapper,
12 * then system dirs, then PATH).
16 * MSVC: cl /o ghci.exe /c ghciwrap.c
17 * mingw: gcc -mno-cygwin -o ghci.exe ghciwrap.c
19 * If you want to associate your own icon with the wrapper,
20 * here's how to do it:
22 * * Create a one-line .rc file, ghci.rc (say), containing
24 * (subst the string literal for the name of your icon file).
25 * * Compile it up (assuming the .ico file is in the same dir
28 * MSVC: rc /i. /fo ghci.res ghci.rc
29 * mingw: windres -o ghci.res -i ghci.rc -O coff
31 * * Add the resulting .res file to the link line of the wrapper:
33 * MSVC: cl /o ghci.exe /c ghciwrap.c ghci.res
34 * mingw: gcc -mno-cygwin -o ghci.exe ghciwrap.c ghci.res
44 #define BINARY_NAME "ghc.exe"
45 #define IACTIVE_OPTION "--interactive"
47 #define errmsg(msg) fprintf(stderr, msg "\n"); fflush(stderr)
50 main(int argc, char** argv)
52 TCHAR binPath[FILENAME_MAX+1];
53 TCHAR binPathShort[MAX_PATH+1];
54 DWORD dwSize = FILENAME_MAX;
60 /* Locate the binary we want to start up */
70 errmsg("Unable to locate ghc.exe");
75 /* Turn the path into short form - LFN form causes problems
76 when passed in argv[0]. */
77 if ( !(GetShortPathName(binPath, binPathShort, dwSize)) ) {
78 errmsg("Unable to locate ghc.exe");
82 new_argv = (char**)malloc(sizeof(char*) * (argc + 1 + 1));
83 if (new_argv == NULL) {
84 errmsg("failed to start up ghc.exe");
87 new_argv[0] = binPathShort;
89 new_argv[1] = (char*)malloc(sizeof(char) * (strlen(IACTIVE_OPTION) + 1));
91 strcpy(new_argv[1], IACTIVE_OPTION);
93 errmsg("failed to start up ghc.exe");
97 for ( i=1; i < argc; i++ ) {
98 int len = strlen(argv[i]);
99 /* to avoid quoting issues, surround each option in double quotes */
100 new_argv[i+1] = (char*)malloc(sizeof(char) * (len + 3));
101 if (new_argv[i+1] == NULL) {
102 errmsg("failed to start up ghc.exe");
105 new_argv[i+1][0] = '"';
106 strcpy(1 + new_argv[i+1], argv[i]);
107 new_argv[i+1][len+1] = '"';
108 new_argv[i+1][len+2] = '\0';
111 new_argv[i+1] = NULL;
113 /* I was hoping to be able to use execv() here, but
114 the MS implementation of said function doesn't appear to
115 be quite right (the 'parent' app seems to exit without
116 waiting, which is not a spec-fulfilling thing to do).
118 Cygwin gives me the right behaviour, but does it by
119 implementing it in terms of spawnv(), so you pay
120 the cost of having to create an extra process.
122 ==> Just use spawnv().
125 fprintf(stderr, "Invoking ghc: ");
127 while (new_argv[i] != NULL) {
128 fprintf(stderr, "%s ", new_argv[i++]);
130 fprintf(stderr, "\n"); fflush(stderr);
132 return _spawnv(_P_WAIT, binPath, new_argv);