Simplify type of ms_srcimps and ms_textual_imps.
[ghc.git] / rts / RtsMessages.c
index 73af839..b3d8f94 100644 (file)
@@ -9,7 +9,11 @@
 #include "PosixSource.h"
 #include "Rts.h"
 
+#include "eventlog/EventLog.h"
+
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 
 #ifdef HAVE_WINDOWS_H
 #include <windows.h>
@@ -28,6 +32,7 @@
 RtsMsgFunction *fatalInternalErrorFn = rtsFatalInternalErrorFn;
 RtsMsgFunction *debugMsgFn           = rtsDebugMsgFn;
 RtsMsgFunction *errorMsgFn           = rtsErrorMsgFn;
+RtsMsgFunction *sysErrorMsgFn        = rtsSysErrorMsgFn;
 
 void
 barf(const char*s, ...)
@@ -46,7 +51,7 @@ vbarf(const char*s, va_list ap)
   stg_exit(EXIT_INTERNAL_ERROR); // just in case fatalInternalErrorFn() returns
 }
 
-void 
+void
 _assertFail(const char*filename, unsigned int linenum)
 {
     barf("ASSERTION FAILED: file %s, line %u\n", filename, linenum);
@@ -68,6 +73,21 @@ verrorBelch(const char*s, va_list ap)
 }
 
 void
+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;
@@ -90,7 +110,7 @@ vdebugBelch(const char*s, va_list ap)
 
 #if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
 static int
-isGUIApp()
+isGUIApp(void)
 {
   PIMAGE_DOS_HEADER pDOSHeader;
   PIMAGE_NT_HEADERS pPEHeader;
@@ -110,7 +130,7 @@ isGUIApp()
 #define xstr(s) str(s)
 #define str(s) #s
 
-void
+void GNU_ATTRIBUTE(__noreturn__)
 rtsFatalInternalErrorFn(const char *s, va_list ap)
 {
 #if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
@@ -122,10 +142,10 @@ rtsFatalInternalErrorFn(const char *s, va_list ap)
      vsnprintf(message, BUFSIZE, s, ap);
 
      MessageBox(NULL /* hWnd */,
-               message,
-               title,
-               MB_OK | MB_ICONERROR | MB_TASKMODAL
-              );
+                message,
+                title,
+                MB_OK | MB_ICONERROR | MB_TASKMODAL
+               );
   }
   else
 #endif
@@ -143,6 +163,10 @@ rtsFatalInternalErrorFn(const char *s, va_list ap)
      fflush(stderr);
   }
 
+#ifdef TRACING
+  if (RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG) endEventLogging();
+#endif
+
   abort();
   // stg_exit(EXIT_INTERNAL_ERROR);
 }
@@ -156,9 +180,9 @@ rtsErrorMsgFn(const char *s, va_list ap)
      char buf[BUFSIZE];
      int r;
 
-        r = vsnprintf(buf, BUFSIZE, s, ap);
-        if (r > 0 && r < BUFSIZE) {
-               MessageBox(NULL /* hWnd */,
+         r = vsnprintf(buf, BUFSIZE, s, ap);
+         if (r > 0 && r < BUFSIZE) {
+                MessageBox(NULL /* hWnd */,
               buf,
               prog_name,
               MB_OK | MB_ICONERROR | MB_TASKMODAL
@@ -169,7 +193,7 @@ rtsErrorMsgFn(const char *s, va_list ap)
 #endif
   {
      /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
-     if (prog_argv != NULL && prog_name != NULL) {
+     if (prog_name != NULL) {
        fprintf(stderr, "%s: ", prog_name);
      }
      vfprintf(stderr, s, ap);
@@ -178,16 +202,76 @@ rtsErrorMsgFn(const char *s, va_list ap)
 }
 
 void
+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) {
+#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
+            // Win32 error messages have a terminating \n
+            fprintf(stderr, ": %s", syserr);
+#else
+            fprintf(stderr, ": %s\n", syserr);
+#endif
+        } 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_HOST_OS) || defined (mingw32_HOST_OS)
   if (isGUIApp())
   {
      char buf[BUFSIZE];
-        int r;
+         int r;
 
-        r = vsnprintf(buf, BUFSIZE, s, ap);
-        if (r > 0 && r < BUFSIZE) {
+         r = vsnprintf(buf, BUFSIZE, s, ap);
+         if (r > 0 && r < BUFSIZE) {
        OutputDebugString(buf);
      }
   }