#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);
}
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);
}
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);
}
void
-vdebugBelch(char *s, va_list ap)
+vdebugBelch(const char*s, va_list ap)
{
(*debugMsgFn)(s,ap);
}
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
static int
-isGUIApp()
+isGUIApp(void)
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pPEHeader;
#define str(s) #s
void
-rtsFatalInternalErrorFn(char *s, va_list ap)
+rtsFatalInternalErrorFn(const char *s, va_list ap)
{
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
if (isGUIApp())
}
void
-rtsErrorMsgFn(char *s, va_list ap)
+rtsErrorMsgFn(const char *s, va_list ap)
{
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
if (isGUIApp())
}
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_HOST_OS) || defined (mingw32_HOST_OS)
if (isGUIApp())