Skip to content

Commit

Permalink
Refactor initialization of GAP error handling
Browse files Browse the repository at this point in the history
This way, we don't need to call "high-level" functions like evalstr
from inside __init__, which otherwise complicates certain code refactoring.

Also improve type inference for `disable_error_handler` by turning it into a `Ref`
  • Loading branch information
fingolfin committed Sep 15, 2021
1 parent b28d96d commit 91cc38a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 22 deletions.
10 changes: 10 additions & 0 deletions pkg/JuliaInterface/src/JuliaInterface.c
Expand Up @@ -326,6 +326,16 @@ static void MarkJuliaObject(Bag bag)
#endif
}

//
extern Obj setup_ERROR_OUTPUT(void)
{
Obj buf = MakeString("");
Obj stream = CALL_2ARGS(ValGVar(GVarName("OutputTextString")), buf, True);
CALL_2ARGS(ValGVar(GVarName("SetPrintFormattingStatus")), stream, False);
AssGVarWithoutReadOnlyCheck(GVarName("ERROR_OUTPUT"), stream);
return buf;
}

// Table of functions to export
static StructGVarFunc GVarFuncs[] = {
GVAR_FUNC(_JuliaFunction, 1, "string"),
Expand Down
27 changes: 9 additions & 18 deletions src/GAP.jl
Expand Up @@ -22,34 +22,24 @@ include("types.jl")
const sysinfo = Setup.read_sysinfo_gap(GAPROOT)
const GAP_VERSION = VersionNumber(sysinfo["GAP_VERSION"])

function reset_GAP_ERROR_OUTPUT()
# Note: strictly speaking we should close the stream here; but since it is
# a string stream, this does nothing. So we don't do it, which saves us
# some hassle when calling reset_GAP_ERROR_OUTPUT from `initialize`
#Globals.CloseStream(Globals.ERROR_OUTPUT)
evalstr("_JULIAINTERFACE_ERROR_OUTPUT:= \"\";")
Globals.MakeReadWriteGlobal(julia_to_gap("ERROR_OUTPUT"))
evalstr("ERROR_OUTPUT:= OutputTextString( _JULIAINTERFACE_ERROR_OUTPUT, true );")
evalstr("SetPrintFormattingStatus( ERROR_OUTPUT, false )")
Globals.MakeReadOnlyGlobal(julia_to_gap("ERROR_OUTPUT"))
end

const last_error_gap = Ref{GapObj}()
const last_error = Ref{String}("")

disable_error_handler = false
const disable_error_handler = Ref{Bool}(false)


function error_handler()
global disable_error_handler
if disable_error_handler
if disable_error_handler[]
return
end
last_error[] = String(Globals._JULIAINTERFACE_ERROR_OUTPUT)
ccall((:SET_LEN_STRING, libgap), Cvoid, (GapObj, Cuint), Globals._JULIAINTERFACE_ERROR_OUTPUT, 0)
last_error[] = String(last_error_gap[])
ccall((:SET_LEN_STRING, libgap), Cvoid, (GapObj, Cuint), last_error_gap[], 0)
end

function ThrowObserver(depth::Cint)
global disable_error_handler
if disable_error_handler
if disable_error_handler[]
return
end

Expand Down Expand Up @@ -165,7 +155,8 @@ function initialize(argv::Vector{String})
end

# Redirect error messages, in order not to print them to the screen.
Base.invokelatest(reset_GAP_ERROR_OUTPUT)
global last_error_gap
last_error_gap[] = ccall((:setup_ERROR_OUTPUT, JuliaInterface_path), GapObj, ())
end

function finalize()
Expand Down
4 changes: 2 additions & 2 deletions src/ccalls.jl
Expand Up @@ -70,10 +70,10 @@ function evalstr(cmd::String)
res = evalstr_ex(cmd * ";")
if any(x->x[1] == false, res)
# error
global last_error
global last_error, last_error_gap
# HACK HACK HACK: if there is an error string on the GAP side, call
# error_handler to copy it into `last_error`
if !GAP.Globals.IsEmpty(GAP.Globals._JULIAINTERFACE_ERROR_OUTPUT)
if !GAP.Globals.IsEmpty(last_error_gap[])
error_handler()
end
error("Error thrown by GAP: $(last_error[])")
Expand Down
4 changes: 2 additions & 2 deletions src/prompt.jl
Expand Up @@ -27,7 +27,7 @@ function prompt()
ccall((:SyInstallAnswerIntr, libgap), Cvoid, ())

# restore GAP's error output
disable_error_handler = true
disable_error_handler[] = true
Globals.MakeReadWriteGlobal(GapObj("ERROR_OUTPUT"))
evalstr("""ERROR_OUTPUT:= "*errout*";""")
Globals.MakeReadOnlyGlobal(GapObj("ERROR_OUTPUT"))
Expand All @@ -45,6 +45,6 @@ function prompt()
ccall(:signal, Ptr{Cvoid}, (Cint, Ptr{Cvoid}), Base.SIGINT, old_sigint)

# restore GAP.jl error handler
disable_error_handler = false
disable_error_handler[] = false
reset_GAP_ERROR_OUTPUT()
end

0 comments on commit 91cc38a

Please sign in to comment.