[project @ 2000-04-03 17:27:10 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / machdep.c
index f1fa49f..19db383 100644 (file)
@@ -13,8 +13,8 @@
  * included in the distribution.
  *
  * $RCSfile: machdep.c,v $
- * $Revision: 1.13 $
- * $Date: 1999/11/24 17:32:41 $
+ * $Revision: 1.25 $
+ * $Date: 2000/04/03 17:27:10 $
  * ------------------------------------------------------------------------*/
 
 #ifdef HAVE_SIGNAL_H
@@ -45,7 +45,7 @@
 #ifdef HAVE_DOS_H
 # include <dos.h>
 #endif
-#if defined HAVE_CONIO_H && ! HUGS_FOR_WINDOWS
+#if defined HAVE_CONIO_H
 # include <conio.h>
 #endif
 #ifdef HAVE_IO_H
 # include <windows.h>
 #endif
 
-#if HUGS_FOR_WINDOWS
-#include <dir.h>
-#include <mem.h>
-
-extern HCURSOR HandCursor;            /* Forward references to cursors   */
-extern HCURSOR GarbageCursor;
-extern HCURSOR SaveCursor;
-static void    local DrawStatusLine     Args((HWND));
-#endif
-
 #if DOS
 #include <mem.h>
 extern unsigned _stklen = 8000;         /* Allocate an 8k stack segment    */
@@ -118,35 +108,25 @@ int allow_break_count = 0;
 #define HugsRoot ("SOFTWARE\\Haskell\\Hugs\\" HUGS_VERSION "\\")
 #define ProjectRoot ("SOFTWARE\\Haskell\\Projects\\")
 
-static Bool   local createKey      Args((HKEY, String, PHKEY, REGSAM));
-static Bool   local queryValue     Args((HKEY, String, String, LPDWORD, LPBYTE, DWORD));
-static Bool   local setValue       Args((HKEY, String, String, DWORD, LPBYTE, DWORD));
-static String local readRegString  Args((HKEY, String, String, String));
-static Int    local readRegInt     Args((String,Int));
-static Bool   local writeRegString Args((String,String));
-static Bool   local writeRegInt    Args((String,Int));
+static Bool   local createKey      ( HKEY, String, PHKEY, REGSAM );
+static Bool   local queryValue     ( HKEY, String, String, LPDWORD, LPBYTE, DWORD );
+static Bool   local setValue       ( HKEY, String, String, DWORD, LPBYTE, DWORD );
+static String local readRegString  ( HKEY, String, String, String );
+static Int    local readRegInt     ( String,Int );
+static Bool   local writeRegString ( String,String );
+static Bool   local writeRegInt    ( String,Int );
 
-static String local readRegChildStrings Args((HKEY, String, String, Char, String));
+static String local readRegChildStrings ( HKEY, String, String, Char, String );
 #endif /* USE_REGISTRY */
 
 /* --------------------------------------------------------------------------
  * Find information about a file:
  * ------------------------------------------------------------------------*/
 
-#if RISCOS
-typedef struct { unsigned hi, lo; } Time;
-#define timeChanged(now,thn)    (now.hi!=thn.hi || now.lo!=thn.lo)
-#define timeSet(var,tm)         var.hi = tm.hi; var.lo = tm.lo
-error  timeEarlier not defined
-#else
-typedef time_t Time;
-#define timeChanged(now,thn)      (now!=thn)
-#define timeSet(var,tm)           var = tm
-#define timeEarlier(earlier,now)  (earlier < now)
-#endif
+#include "machdep_time.h"
 
-static Bool local readable      Args((String));
-static Void local getFileInfo   Args((String, Time *, Long *));
+static Bool local readable      ( String );
+static Void local getFileInfo   ( String, Time *, Long * );
 
 static Void local getFileInfo(f,tm,sz)  /* find time stamp and size of file*/
 String f;
@@ -221,7 +201,7 @@ String f; {
     return (0 == access(f,4));
 #elif defined HAVE_SYS_STAT_H || defined HAVE_STAT_H
     struct stat scbuf;
-    //fprintf(stderr, "readable: %s\n", f );
+    /* fprintf(stderr, "readable: %s\n", f ); */
     return (  !stat(f,&scbuf) 
            && (scbuf.st_mode & S_IREAD) /* readable     */
            && (scbuf.st_mode & S_IFREG) /* regular file */
@@ -241,33 +221,35 @@ String f; {
  * Search for script files on the HUGS path:
  * ------------------------------------------------------------------------*/
 
-static String local hugsdir       Args((Void));
+static String local hugsdir       ( Void );
 #if HSCRIPT
-static String local hscriptDir    Args((Void));
+static String local hscriptDir    ( Void );
 #endif
-//static String local RealPath      Args((String));
-static int    local pathCmp       Args((String, String));
-static String local normPath      Args((String));
-static Void   local searchChr     Args((Int));
-static Void   local searchStr     Args((String));
-static Bool   local tryEndings    Args((String));
-
-#if DOS_FILENAMES
+static int    local pathCmp       ( String, String );
+static String local normPath      ( String );
+static Void   local searchChr     ( Int );
+static Void   local searchStr     ( String );
+static Bool   local tryEndings    ( String );
+
+#if (DOS_FILENAMES || __CYGWIN32__) 
 # define SLASH                   '\\'
 # define isSLASH(c)              ((c)=='\\' || (c)=='/')
 # define PATHSEP                 ';'
+# define PATHSEP_STR             ";"
 # define DLL_ENDING              ".dll"
 #elif MAC_FILENAMES
 # define SLASH                   ':'
 # define isSLASH(c)              ((c)==SLASH)
 # define PATHSEP                 ';'
+# define PATHSEP_STR             ";"
 /* Mac PEF (Preferred Executable Format) file */
 # define DLL_ENDING              ".pef" 
 #else
 # define SLASH                   '/'
 # define isSLASH(c)              ((c)==SLASH)
 # define PATHSEP                 ':'
-# define DLL_ENDING              ".o"
+# define PATHSEP_STR             ":"
+# define DLL_ENDING              ".u_o"
 #endif
 
 static String local hugsdir() {     /* directory containing lib/Prelude.hs */
@@ -380,9 +362,9 @@ String s; {                     /* a pathname in some appropriate manner.  */
 }
 
 #if HSCRIPT
-static String endings[] = { "", ".hi", ".hs", ".lhs", ".hsx", ".hash", 0 };
+static String endings[] = { "", ".u_hi", ".hs", ".lhs", ".hsx", ".hash", 0 };
 #else
-static String endings[] = { "", ".hi", ".hs", ".lhs", 0 };
+static String endings[] = { "", ".u_hi", ".hs", ".lhs", 0 };
 #endif
 static char   searchBuf[FILENAME_MAX+1];
 static Int    searchPos;
@@ -604,33 +586,40 @@ String path; {
  * New path handling stuff for the Combined System (tm)
  * ------------------------------------------------------------------------*/
 
-#define N_DEFAULT_LIBDIR 1000
-char defaultLibDir[N_DEFAULT_LIBDIR];
+char installDir[N_INSTALLDIR];
 
-/* Assumes that getcwd()++argv[0] is the absolute path to the
-   executable.  Basically wrong.
+/* Sets installDir to $STGHUGSDIR, and ensures there is a trailing
+   slash at the end.
 */
-void setDefaultLibDir ( String argv_0 )
+void setInstallDir ( String argv_0 )
 {
-   int i;
-   if (argv_0[0] != SLASH) {
-      if (!getcwd(defaultLibDir,N_DEFAULT_LIBDIR-strlen(argv_0)-10)) {
-         ERRMSG(0) "Can't get current working directory"
-         EEND;
-      }
-      i = strlen(defaultLibDir);
-      if (defaultLibDir[i-1] != SLASH) defaultLibDir[i++] = SLASH;
-   } else {
-      i = 0;
+   int   i;
+   char* r = getenv("STGHUGSDIR");
+   if (!r) {
+      fprintf(stderr, 
+          "%s: installation error: environment variable STGHUGSDIR is not set.\n",
+          argv_0 );
+      fprintf(stderr, 
+          "%s: pls set it to be the directory where STGHugs98 is installed.\n\n",
+          argv_0 );
+      exit(2);
+
    }
-   strcpy(&defaultLibDir[i],argv_0);
-   i += strlen(argv_0);
-   while (defaultLibDir[i] != SLASH) i--;
-   i++;
-   strcpy(&defaultLibDir[i], "lib");
-   /* fprintf ( stderr, "default lib dir = %s\n", defaultLibDir );  */
+
+   if (strlen(r) > N_INSTALLDIR-30 ) {
+      fprintf(stderr, 
+          "%s: environment variable STGHUGSDIR is suspiciously long; pls remedy\n\n",
+          argv_0 );
+      exit(2);
+   }
+
+   strcpy ( installDir, r );
+   i = strlen(installDir);
+   if (installDir[i-1] != SLASH) installDir[i++] = SLASH;
+   installDir[i] = 0;
 }
 
+
 Bool findFilesForModule ( 
         String  modName,
         String* path,
@@ -653,22 +642,35 @@ Bool findFilesForModule (
    Int    nPath;
    Bool   literate;
    String peStart, peEnd;
-   String augdPath;       /* .:hugsPath:defaultLibDir */
+   String augdPath;       /* .:hugsPath:installDir/GhcPrel:installDir/lib */
 
    *path = *sExt = NULL;
    *sAvail = *iAvail = *oAvail = FALSE;
    *sSize  = *iSize  = *oSize  = 0;
 
-   augdPath = malloc(4+strlen(defaultLibDir)+strlen(hugsPath));
+   augdPath = malloc( 2*(10+3+strlen(installDir)) 
+                      +strlen(hugsPath) +10/*paranoia*/);
    if (!augdPath)
       internal("moduleNameToFileNames: malloc failed(2)");
-   augdPath[0] = '.';
-   augdPath[1] = PATHSEP;
-   augdPath[2] = 0;
-   strcat ( augdPath, hugsPath );
-   augdPath[2+strlen(hugsPath)] = PATHSEP;
-   augdPath[3+strlen(hugsPath)] = 0;
-   strcat(augdPath,defaultLibDir);
+
+   augdPath[0] = 0;
+   strcat(augdPath, ".");
+   strcat(augdPath, PATHSEP_STR);
+
+   strcat(augdPath, hugsPath);
+   strcat(augdPath, PATHSEP_STR);
+
+   if (combined) {
+      strcat(augdPath, installDir);
+      strcat(augdPath, "GhcPrel");
+      strcat(augdPath, PATHSEP_STR);
+   }
+
+   strcat(augdPath, installDir);
+   strcat(augdPath, "lib");
+   strcat(augdPath, PATHSEP_STR);
+
+   /*   fprintf ( stderr, "augdpath = `%s'\n", augdPath ); */
 
    peEnd = augdPath-1;
    while (1) {
@@ -709,9 +711,10 @@ Bool findFilesForModule (
          getFileInfo(searchBuf, oTime, oSize);
       }
 
-      strcpy(searchBuf+nPath, ".hi");
+      strcpy(searchBuf+nPath, ".u_hi");
       if (readable(searchBuf)) {
          *iAvail = TRUE;
+         *sExt = ".u_hi";
          getFileInfo(searchBuf, iTime, iSize);
       }
 
@@ -748,12 +751,49 @@ Bool findFilesForModule (
 }
 
 
+/* If the primaryObjectName is (eg)
+     /foo/bar/PrelSwamp.o
+   and the extraFileName is (eg)
+     swampy_cbits
+   and DLL_ENDING is set to .o
+   return
+     /foo/bar/swampy_cbits.o
+     and set *extraFileSize to its size, or -1 if not avail
+*/
+String getExtraObjectInfo ( String primaryObjectName,
+                            String extraFileName,
+                            Int*   extraFileSize )
+{
+   Time   xTime;
+   Long   xSize;
+   String xtra;
+
+   Int i = strlen(primaryObjectName)-1;
+   while (i >= 0 && primaryObjectName[i] != SLASH) i--;
+   if (i == -1) return extraFileName;
+   i++;
+   xtra = malloc ( i+3+strlen(extraFileName)+strlen(DLL_ENDING) );
+   if (!xtra) internal("deriveExtraObjectName: malloc failed");
+   strncpy ( xtra, primaryObjectName, i );
+   xtra[i] = 0;
+   strcat ( xtra, extraFileName );
+   strcat ( xtra, DLL_ENDING );
+
+   *extraFileSize = -1;
+   if (readable(xtra)) {
+      getFileInfo ( xtra, &xTime, &xSize );
+      *extraFileSize = xSize;
+   }
+   return xtra;
+}
+
+
 /* --------------------------------------------------------------------------
  * Substitute old value of path into empty entries in new path
  * eg substPath("a:b:c::d:e","x:y:z") = "a:b:c:x:y:z:d:e"
  * ------------------------------------------------------------------------*/
 
-static String local substPath Args((String,String));
+static String local substPath ( String,String );
 
 static String local substPath(new,sub) /* substitute sub path into new path*/
 String new;
@@ -791,9 +831,6 @@ String sub; {
 Bool gcMessages = FALSE;                /* TRUE => print GC messages       */
 
 Void gcStarted() {                      /* Notify garbage collector start  */
-#if HUGS_FOR_WINDOWS
-    SaveCursor = SetCursor(GarbageCursor);
-#endif
     if (gcMessages) {
         Printf("{{Gc");
         FlushStdout();
@@ -813,9 +850,6 @@ Int recovered; {
         Printf("%d}}",recovered);
         FlushStdout();
     }
-#if HUGS_FOR_WINDOWS
-    SetCursor(SaveCursor);
-#endif
 }
 
 Cell *CStackBase;                       /* Retain start of C control stack */
@@ -882,7 +916,7 @@ void gcCStack() {
 Void gcCStack() {                       /* Garbage collect elements off    */
     Cell stackTop = NIL;                /* C stack                         */
     Cell *ptr = &stackTop;
-#if SIZEOF_INTP == 2
+#if SIZEOF_VOID_P == 2
     if (((long)(ptr) - (long)(CStackBase))&1)
         fatal("gcCStack");
 #elif STACK_ALIGNMENT == 2 /* eg Macintosh 68000 */
@@ -912,7 +946,7 @@ Void gcCStack() {                       /* Garbage collect elements off    */
     GuessDirection;
 #endif
 
-#if SIZEOF_INTP==4 && STACK_ALIGNMENT == 2 /* eg Macintosh 68000 */
+#if SIZEOF_VOID_P==4 && STACK_ALIGNMENT == 2 /* eg Macintosh 68000 */
     ptr = (Cell *)((long)(&stackTop) + 2);
     StackGrowsDown;
 #endif
@@ -1068,7 +1102,7 @@ Int readTerminalChar() {                /* read character from terminal    */
     if (terminalEchoReqd) {
         return getchar();
     } else {
-#if IS_WIN32 && !HUGS_FOR_WINDOWS && !__BORLANDC__
+#if IS_WIN32 && !__BORLANDC__
        /* When reading a character from the console/terminal, we want
         * to operate in 'raw' mode (to use old UNIX tty parlance) and have
         * it return when a character is available and _not_ wait until
@@ -1133,66 +1167,10 @@ Int readTerminalChar() {                /* read character from terminal    */
  * Interrupt handling:
  * ------------------------------------------------------------------------*/
 
-Bool    broken         = FALSE;
-static  Bool breakReqd = FALSE;
-static  sigProto(ignoreBreak);
-static  Void local installHandlers Args((Void));
-
-Bool breakOn(reqd)                      /* set break trapping on if reqd,  */
-Bool reqd; {                            /* or off otherwise, returning old */
-    Bool old  = breakReqd;
-
-    breakReqd = reqd;
-    if (reqd) {
-        if (broken) {                   /* repond to break signal received */
-            broken = FALSE;             /* whilst break trap disabled      */
-            sigRaise(breakHandler);
-            /* not reached */
-        }
-#if HANDLERS_CANT_LONGJMP
-        ctrlbrk(ignoreBreak);
-#else
-        ctrlbrk(breakHandler);
-#endif
-    } else {
-        ctrlbrk(ignoreBreak);
-    }
-    return old;
-}
-
-static sigHandler(ignoreBreak) {        /* record but don't respond to break*/
-    ctrlbrk(ignoreBreak);         /* reinstall signal handler               */
-                                  /* redundant on BSD systems but essential */
-                                  /* on POSIX and other systems             */
-    broken = TRUE;
-    interruptStgRts();
-    sigResume;
-}
-
-#if !DONT_PANIC
-static sigProto(panic);
-static sigHandler(panic) {              /* exit in a panic, on receipt of  */
-    everybody(EXIT);                    /* an unexpected signal            */
-    fprintf(stderr,"\nUnexpected signal\n");
-    exit(1);
-    sigResume;/*NOTREACHED*/
-}
-#endif /* !DONT_PANIC */
-
-#if IS_WIN32
-BOOL WINAPI consoleHandler(DWORD dwCtrlType) {
-    switch (dwCtrlType) {              /* Allows Hugs to be terminated    */
-       case CTRL_CLOSE_EVENT :         /* from the window's close menu.   */
-           ExitProcess(0);
-    }
-    return FALSE;
-}
-#endif
-static Void local installHandlers() { /* Install handlers for all fatal    */ 
+static Void installHandlers ( void ) { /* Install handlers for all fatal   */ 
                                       /* signals except SIGINT and SIGBREAK*/
 #if IS_WIN32
-    SetConsoleCtrlHandler(consoleHandler,TRUE);
+    /* SetConsoleCtrlHandler(consoleHandler,TRUE); */
 #endif
 #if !DONT_PANIC && !DOS
 # ifdef SIGABRT
@@ -1394,9 +1372,9 @@ int snprintf(char* buffer, int count, const char* fmt, ...) {
 
 #define HugsRoot ("SOFTWARE\\Haskell\\Hugs\\" HUGS_VERSION "\\")
 
-static Bool   local createKey      Args((HKEY, PHKEY, REGSAM));
-static Bool   local queryValue     Args((HKEY, String, LPDWORD, LPBYTE, DWORD));
-static Bool   local setValue       Args((HKEY, String, DWORD, LPBYTE, DWORD));
+static Bool   local createKey      ( HKEY, PHKEY, REGSAM );
+static Bool   local queryValue     ( HKEY, String, LPDWORD, LPBYTE, DWORD );
+static Bool   local setValue       ( HKEY, String, DWORD, LPBYTE, DWORD );
 
 static Bool local createKey(hKey, phRootKey, samDesired)
 HKEY    hKey;
@@ -1520,17 +1498,12 @@ Void machdep(what)                      /* Handle machine specific         */
 Int what; {                             /* initialisation etc..            */
     switch (what) {
         case MARK    : break;
-        case INSTALL : installHandlers();
+        case POSTPREL: break;
+        case PREPREL : installHandlers();
                        break;
         case RESET   :
         case BREAK   :
         case EXIT    : normalTerminal();
-#if HUGS_FOR_WINDOWS
-                       if (what==EXIT)
-                           DestroyWindow(hWndMain);
-                       else
-                           SetCursor(LoadCursor(NULL,IDC_ARROW));
-#endif
                        break;
     }
 }