From 2623b3404c32136e76757a2029192333bdc3e8a8 Mon Sep 17 00:00:00 2001 From: rrt Date: Mon, 30 Jul 2001 10:40:36 +0000 Subject: [PATCH] [project @ 2001-07-30 10:40:36 by rrt] Add Sigbjorn's wrapper for ghci on Windows. ghci.exe will work from cmd.exe, bash, the Explorer &c. &c., i.e. it's a one-size fits all solution. Thanks, Sigbjorn! --- ghc/driver/ghci/Makefile | 9 +++- ghc/driver/ghci/ghci.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 ghc/driver/ghci/ghci.c diff --git a/ghc/driver/ghci/Makefile b/ghc/driver/ghci/Makefile index eb74961..99b5843 100644 --- a/ghc/driver/ghci/Makefile +++ b/ghc/driver/ghci/Makefile @@ -1,5 +1,5 @@ #----------------------------------------------------------------------------- -# $Id: Makefile,v 1.6 2001/06/27 15:26:56 chak Exp $ +# $Id: Makefile,v 1.7 2001/07/30 10:40:36 rrt Exp $ # TOP=../.. @@ -27,6 +27,10 @@ endif INSTALLED_SCRIPT_PROG = ghci-$(ProjectVersion) INPLACE_SCRIPT_PROG = ghci-inplace +ifeq "$(TARGETPLATFORM)" "i386-unknown-mingw32" +C_PROG = ghci +endif + SCRIPT_OBJS = ghci.sh INTERP = $(SHELL) SCRIPT_SUBST_VARS = GHCBIN TOPDIROPT @@ -35,7 +39,9 @@ TOPDIROPT = -B$(GHCLIB) ifeq "$(INSTALLING)" "1" SCRIPT_PROG = $(INSTALLED_SCRIPT_PROG) +ifneq "$(TARGETPLATFORM)" "i386-unknown-mingw32" LINK = ghci +endif else SCRIPT_PROG = $(INPLACE_SCRIPT_PROG) endif @@ -48,4 +54,3 @@ all clean distclean maintainer-clean :: endif include $(TOP)/mk/target.mk - diff --git a/ghc/driver/ghci/ghci.c b/ghc/driver/ghci/ghci.c new file mode 100644 index 0000000..bd75ac3 --- /dev/null +++ b/ghc/driver/ghci/ghci.c @@ -0,0 +1,110 @@ +/* + * + * $Id: ghci.c,v 1.1 2001/07/30 10:40:36 rrt Exp $ + * + * ghci wrapper - invokes ghc.exe with the added command-line + * option "--interactive". + * + * (c) The GHC Team 2001 + * + * ghc.exe is searched for using the 'normal' search rules + * for DLLs / EXEs (i.e., first in the same dir as this wrapper, + * then system dirs, then PATH). + * + * To compile: + * + * MSVC: cl /o ghci.exe /c ghciwrap.c + * mingw: gcc -mno-cygwin -o ghci.exe ghciwrap.c + * + * If you want to associate your own icon with the wrapper, + * here's how to do it: + * + * * Create a one-line .rc file, ghci.rc (say), containing + * 0 ICON "hsicon.ico" + * (subst the string literal for the name of your icon file). + * * Compile it up (assuming the .ico file is in the same dir + * as the .rc file): + * + * MSVC: rc /I. ghci.rc /o ghci.res + * mingw: windres -o ghci.res -o ghci.rc -O coff + * + * * Add the resulting .res file to the link line of the wrapper: + * + * MSVC: cl /o ghci.exe /c ghciwrap.c ghci.res + * mingw: gcc -mno-cygwin -o ghci.exe ghciwrap.c ghci.res + * + */ + +#include +#include +#include +#include + +#define BINARY_NAME "ghc.exe" +#define IACTIVE_OPTION "--interactive" + +#define errmsg(msg) fprintf(stderr, msg "\n"); fflush(stderr) + +int +main(int argc, char** argv) +{ + TCHAR binPath[FILENAME_MAX+1]; + DWORD dwSize = FILENAME_MAX; + DWORD dwRes; + TCHAR* szEnd; + char** new_argv; + int i; + + /* Locate the binary we want to start up */ + dwRes = + SearchPath(NULL, + BINARY_NAME, + NULL, + dwSize, + binPath, + &szEnd); + + if (dwRes == 0) { + errmsg("Unable to locate ghc.exe"); + return 1; + } + + new_argv = (char**)malloc(sizeof(char) * (argc + 1 + 1)); + if (new_argv == NULL) { + errmsg("failed to start up ghc.exe"); + return 1; + } + new_argv[0] = binPath; + + new_argv[1] = (char*)malloc(sizeof(char) * (strlen(IACTIVE_OPTION) + 1)); + if (new_argv[1]) { + strcpy(new_argv[1], IACTIVE_OPTION); + } else { + errmsg("failed to start up ghc.exe"); + return 1; + } + + for ( i=1; i < argc; i++ ) { + new_argv[i+1] = (char*)malloc(sizeof(char) * (strlen(argv[i] + 1))); + if (new_argv[i+1] == NULL) { + errmsg("failed to start up ghc.exe"); + return 1; + } else { + strcpy(new_argv[i+1], argv[i]); + } + } + new_argv[i+1] = NULL; + + /* I was hoping to be able to use execv() here, but + the MS implementation of said function doesn't appear to + be quite right (the 'parent' app seems to exit without + waiting, which is not a spec-fulfilling thing to do). + + Cygwin gives me the right behaviour, but does it by + implementing it in terms of spawnv(), so you pay + the cost of having to create an extra process. + + ==> Just use spawnv(). + */ + return _spawnv(_P_WAIT, binPath, new_argv); +} -- 1.7.10.4