Massive patch for the first months work adding System FC to GHC #35
[ghc-hetmet.git] / rts / RtsMessages.c
index 1242d88..362b369 100644 (file)
@@ -10,6 +10,8 @@
 #include "Rts.h"
 
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 
 #ifdef HAVE_WINDOWS_H
 #include <windows.h>
 RtsMsgFunction *fatalInternalErrorFn = rtsFatalInternalErrorFn;
 RtsMsgFunction *debugMsgFn           = rtsDebugMsgFn;
 RtsMsgFunction *errorMsgFn           = rtsErrorMsgFn;
+RtsMsgFunction *sysErrorMsgFn        = rtsSysErrorMsgFn;
 
 void
-barf(char *s, ...)
+barf(const char*s, ...)
 {
   va_list ap;
   va_start(ap,s);
@@ -40,20 +43,20 @@ barf(char *s, ...)
 }
 
 void
-vbarf(char *s, va_list ap)
+vbarf(const 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)
+_assertFail(const char*filename, unsigned int linenum)
 {
     barf("ASSERTION FAILED: file %s, line %u\n", filename, linenum);
 }
 
 void
-errorBelch(char *s, ...)
+errorBelch(const char*s, ...)
 {
   va_list ap;
   va_start(ap,s);
@@ -62,13 +65,28 @@ errorBelch(char *s, ...)
 }
 
 void
-verrorBelch(char *s, va_list ap)
+verrorBelch(const char*s, va_list ap)
 {
   (*errorMsgFn)(s,ap);
 }
 
 void
-debugBelch(char *s, ...)
+sysErrorBelch(const char*s, ...)
+{
+  va_list ap;
+  va_start(ap,s);
+  (*sysErrorMsgFn)(s,ap);
+  va_end(ap);
+}
+
+void
+vsysErrorBelch(const char*s, va_list ap)
+{
+  (*sysErrorMsgFn)(s,ap);
+}
+
+void
+debugBelch(const char*s, ...)
 {
   va_list ap;
   va_start(ap,s);
@@ -77,7 +95,7 @@ debugBelch(char *s, ...)
 }
 
 void
-vdebugBelch(char *s, va_list ap)
+vdebugBelch(const char*s, va_list ap)
 {
   (*debugMsgFn)(s,ap);
 }
@@ -88,9 +106,9 @@ vdebugBelch(char *s, va_list ap)
 
 #define BUFSIZE 512
 
-#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
 static int
-isGUIApp()
+isGUIApp(void)
 {
   PIMAGE_DOS_HEADER pDOSHeader;
   PIMAGE_NT_HEADERS pPEHeader;
@@ -111,9 +129,9 @@ isGUIApp()
 #define str(s) #s
 
 void
-rtsFatalInternalErrorFn(char *s, va_list ap)
+rtsFatalInternalErrorFn(const char *s, va_list ap)
 {
-#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
   if (isGUIApp())
   {
      char title[BUFSIZE], message[BUFSIZE];
@@ -148,9 +166,9 @@ rtsFatalInternalErrorFn(char *s, va_list ap)
 }
 
 void
-rtsErrorMsgFn(char *s, va_list ap)
+rtsErrorMsgFn(const char *s, va_list ap)
 {
-#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
   if (isGUIApp())
   {
      char buf[BUFSIZE];
@@ -178,9 +196,64 @@ rtsErrorMsgFn(char *s, va_list ap)
 }
 
 void
-rtsDebugMsgFn(char *s, va_list ap)
+rtsSysErrorMsgFn(const char *s, va_list ap)
+{
+    char *syserr;
+
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
+    FormatMessage( 
+       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+       FORMAT_MESSAGE_FROM_SYSTEM | 
+       FORMAT_MESSAGE_IGNORE_INSERTS,
+       NULL,
+       GetLastError(),
+       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+       (LPTSTR) &syserr,
+       0,
+       NULL );
+
+    if (isGUIApp())
+    {
+       char buf[BUFSIZE];
+       int r;
+       
+       r = vsnprintf(buf, BUFSIZE, s, ap);
+       if (r > 0 && r < BUFSIZE) {
+           r = vsnprintf(buf+r, BUFSIZE-r, ": %s", syserr);
+           MessageBox(NULL /* hWnd */,
+                      buf,
+                      prog_name,
+                      MB_OK | MB_ICONERROR | MB_TASKMODAL
+               );
+       }
+    }
+    else
+#else
+    syserr = strerror(errno);
+    // ToDo: use strerror_r() if available
+#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);
+       if (syserr) {
+           fprintf(stderr, ": %s\n", syserr);
+       } else {
+           fprintf(stderr, "\n");
+       }
+    }
+
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
+    if (syserr) LocalFree(syserr);
+#endif
+}
+
+void
+rtsDebugMsgFn(const char *s, va_list ap)
 {
-#if defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
   if (isGUIApp())
   {
      char buf[BUFSIZE];