* 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
#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 */
#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;
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 */
* 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 */
}
#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;
* 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,
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) {
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);
}
}
+/* 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;
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();
Printf("%d}}",recovered);
FlushStdout();
}
-#if HUGS_FOR_WINDOWS
- SetCursor(SaveCursor);
-#endif
}
Cell *CStackBase; /* Retain start of C control stack */
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 */
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
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
* 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
#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;
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;
}
}