From 0cecb79ff97c73a24acacf8afdc3edba93507661 Mon Sep 17 00:00:00 2001
From: "Erik M. Bray" <erik.bray@lri.fr>
Date: Thu, 22 Nov 2018 10:53:31 +0100
Subject: [PATCH 2/3] kernel: add helper function for writing error messages to
 the file/stream referenced by the ERROR_OUTPUT global variable

---
 src/error.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/error.h   |  8 ++++++++
 src/scanner.c |  3 ++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/error.c b/src/error.c
index 9bb3be8..d43347d 100644
--- a/src/error.c
+++ b/src/error.c
@@ -33,6 +33,8 @@
 
 
 static Obj ErrorInner;
+static Obj ERROR_OUTPUT = NULL;
+static Obj IsOutputStream;
 
 
 /****************************************************************************
@@ -40,6 +42,44 @@ static Obj ErrorInner;
 *F * * * * * * * * * * * * * * error functions * * * * * * * * * * * * * * *
 */
 
+/****************************************************************************
+**
+*F  OpenErrorOutput()  . . . . . . . open the file or stream assigned to the
+**                                   ERROR_OUTPUT global variable defined in
+**                                   error.g, or "*errout*" otherwise
+*/
+UInt OpenErrorOutput( void )
+{
+    /* Try to print the output to stream. Use *errout* as a fallback. */
+    UInt ret = 0;
+
+    if (ERROR_OUTPUT != NULL) {
+        if (IsStringConv(ERROR_OUTPUT)) {
+            ret = OpenOutput(CSTR_STRING(ERROR_OUTPUT));
+        }
+        else {
+            if (CALL_1ARGS(IsOutputStream, ERROR_OUTPUT) == True) {
+                ret = OpenOutputStream(ERROR_OUTPUT);
+            }
+        }
+    }
+
+    if (!ret) {
+        /* It may be we already tried and failed to open *errout* above but
+         * but this is an extreme case so it can't hurt to try again
+         * anyways */
+        ret = OpenOutput("*errout*");
+        if (ret) {
+            Pr("failed to open error stream\n", 0, 0);
+        }
+        else {
+            Panic("failed to open *errout*");
+        }
+    }
+
+    return ret;
+}
+
 
 /****************************************************************************
 **
@@ -615,6 +655,8 @@ static Int InitKernel(StructInitInfo * module)
     InitHdlrFuncsFromTable(GVarFuncs);
 
     ImportFuncFromLibrary("ErrorInner", &ErrorInner);
+    ImportFuncFromLibrary("IsOutputStream", &IsOutputStream);
+    ImportGVarFromLibrary("ERROR_OUTPUT", &ERROR_OUTPUT);
 
     // return success
     return 0;
diff --git a/src/error.h b/src/error.h
index 31af256..1f5ee5d 100644
--- a/src/error.h
+++ b/src/error.h
@@ -32,6 +32,14 @@ Int RegisterBreakloopObserver(intfunc func);
 
 /****************************************************************************
 **
+*F  OpenErrorOutput()  . . . . . . . open the file or stream assigned to the
+**                                   ERROR_OUTPUT global variable defined in
+**                                   error.g, or "*errout*" otherwise
+*/
+extern UInt OpenErrorOutput();
+
+/****************************************************************************
+**
 *F  ErrorQuit( <msg>, <arg1>, <arg2> )  . . . . . . . . . . .  print and quit
 */
 extern void ErrorQuit(const Char * msg, Int arg1, Int arg2) NORETURN;
diff --git a/src/scanner.c b/src/scanner.c
index 4db17b3..071c0e3 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -16,6 +16,7 @@
 
 #include "scanner.h"
 
+#include "error.h"
 #include "gapstate.h"
 #include "gaputils.h"
 #include "io.h"
@@ -42,7 +43,7 @@ static void SyntaxErrorOrWarning(const Char * msg, UInt error)
     if (STATE(NrErrLine) == 0) {
 
         // open error output
-        OpenOutput("*errout*");
+        OpenErrorOutput();
 
         // print the message ...
         if (error)
-- 
1.9.1

