diff options
author | Simon Marlow <simonmar@microsoft.com> | 2006-04-07 02:05:11 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2006-04-07 02:05:11 +0000 |
commit | 0065d5ab628975892cea1ec7303f968c3338cbe1 (patch) | |
tree | 8e2afe0ab48ee33cf95009809d67c9649573ef92 /rts/RtsMessages.c | |
parent | 28a464a75e14cece5db40f2765a29348273ff2d2 (diff) | |
download | haskell-0065d5ab628975892cea1ec7303f968c3338cbe1.tar.gz |
Reorganisation of the source tree
Most of the other users of the fptools build system have migrated to
Cabal, and with the move to darcs we can now flatten the source tree
without losing history, so here goes.
The main change is that the ghc/ subdir is gone, and most of what it
contained is now at the top level. The build system now makes no
pretense at being multi-project, it is just the GHC build system.
No doubt this will break many things, and there will be a period of
instability while we fix the dependencies. A straightforward build
should work, but I haven't yet fixed binary/source distributions.
Changes to the Building Guide will follow, too.
Diffstat (limited to 'rts/RtsMessages.c')
-rw-r--r-- | rts/RtsMessages.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/rts/RtsMessages.c b/rts/RtsMessages.c new file mode 100644 index 0000000000..1242d886eb --- /dev/null +++ b/rts/RtsMessages.c @@ -0,0 +1,201 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 1998-2004 + * + * General utility functions used in the RTS. + * + * ---------------------------------------------------------------------------*/ + +#include "PosixSource.h" +#include "Rts.h" + +#include <stdio.h> + +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif + +/* ----------------------------------------------------------------------------- + General message generation functions + + All messages should go through here. We can't guarantee that + stdout/stderr will be available - e.g. in a Windows program there + is no console for generating messages, so they have to either go to + to the debug console, or pop up message boxes. + -------------------------------------------------------------------------- */ + +// Default to the stdio implementation of these hooks. +RtsMsgFunction *fatalInternalErrorFn = rtsFatalInternalErrorFn; +RtsMsgFunction *debugMsgFn = rtsDebugMsgFn; +RtsMsgFunction *errorMsgFn = rtsErrorMsgFn; + +void +barf(char *s, ...) +{ + va_list ap; + va_start(ap,s); + (*fatalInternalErrorFn)(s,ap); + stg_exit(EXIT_INTERNAL_ERROR); // just in case fatalInternalErrorFn() returns + va_end(ap); +} + +void +vbarf(char *s, va_list ap) +{ + (*fatalInternalErrorFn)(s,ap); + stg_exit(EXIT_INTERNAL_ERROR); // just in case fatalInternalErrorFn() returns +} + +void +_assertFail(char *filename, unsigned int linenum) +{ + barf("ASSERTION FAILED: file %s, line %u\n", filename, linenum); +} + +void +errorBelch(char *s, ...) +{ + va_list ap; + va_start(ap,s); + (*errorMsgFn)(s,ap); + va_end(ap); +} + +void +verrorBelch(char *s, va_list ap) +{ + (*errorMsgFn)(s,ap); +} + +void +debugBelch(char *s, ...) +{ + va_list ap; + va_start(ap,s); + (*debugMsgFn)(s,ap); + va_end(ap); +} + +void +vdebugBelch(char *s, va_list ap) +{ + (*debugMsgFn)(s,ap); +} + +/* ----------------------------------------------------------------------------- + stdio versions of the message functions + -------------------------------------------------------------------------- */ + +#define BUFSIZE 512 + +#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS) +static int +isGUIApp() +{ + PIMAGE_DOS_HEADER pDOSHeader; + PIMAGE_NT_HEADERS pPEHeader; + + pDOSHeader = (PIMAGE_DOS_HEADER) GetModuleHandleA(NULL); + if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) + return 0; + + pPEHeader = (PIMAGE_NT_HEADERS) ((char *)pDOSHeader + pDOSHeader->e_lfanew); + if (pPEHeader->Signature != IMAGE_NT_SIGNATURE) + return 0; + + return (pPEHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI); +} +#endif + +#define xstr(s) str(s) +#define str(s) #s + +void +rtsFatalInternalErrorFn(char *s, va_list ap) +{ +#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS) + if (isGUIApp()) + { + char title[BUFSIZE], message[BUFSIZE]; + + snprintf(title, BUFSIZE, "%s: internal error", prog_name); + vsnprintf(message, BUFSIZE, s, ap); + + MessageBox(NULL /* hWnd */, + message, + title, + MB_OK | MB_ICONERROR | MB_TASKMODAL + ); + } + else +#endif + { + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + if (prog_argv != NULL && prog_name != NULL) { + fprintf(stderr, "%s: internal error: ", prog_name); + } else { + fprintf(stderr, "internal error: "); + } + vfprintf(stderr, s, ap); + fprintf(stderr, "\n"); + fprintf(stderr, " (GHC version %s for %s)\n", ProjectVersion, xstr(HostPlatform_TYPE)); + fprintf(stderr, " Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug\n"); + fflush(stderr); + } + + abort(); + // stg_exit(EXIT_INTERNAL_ERROR); +} + +void +rtsErrorMsgFn(char *s, va_list ap) +{ +#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS) + if (isGUIApp()) + { + char buf[BUFSIZE]; + int r; + + r = vsnprintf(buf, BUFSIZE, s, ap); + if (r > 0 && r < BUFSIZE) { + MessageBox(NULL /* hWnd */, + buf, + prog_name, + MB_OK | MB_ICONERROR | MB_TASKMODAL + ); + } + } + else +#endif + { + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + if (prog_argv != NULL && prog_name != NULL) { + fprintf(stderr, "%s: ", prog_name); + } + vfprintf(stderr, s, ap); + fprintf(stderr, "\n"); + } +} + +void +rtsDebugMsgFn(char *s, va_list ap) +{ +#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS) + if (isGUIApp()) + { + char buf[BUFSIZE]; + int r; + + r = vsnprintf(buf, BUFSIZE, s, ap); + if (r > 0 && r < BUFSIZE) { + OutputDebugString(buf); + } + } + else +#endif + { + /* don't fflush(stdout); WORKAROUND bug in Linux glibc */ + vfprintf(stderr, s, ap); + fflush(stderr); + } +} |