From de7b9b9d6abd28e84a57bdedea78c39ea49b8989 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Thu, 22 Nov 2018 10:53:31 +0100 Subject: [PATCH] Backport PR #3043 (handle ERROR_OUTPUT in kernel) --- 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 6043ba6ff3..d8eed8cbbe 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 31af2564b4..1f5ee5d428 100644 --- a/src/error.h +++ b/src/error.h @@ -30,6 +30,14 @@ typedef void (*intfunc)(Int); 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( , , ) . . . . . . . . . . . print and quit diff --git a/src/scanner.c b/src/scanner.c index 4db17b3f10..071c0e30dd 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)