diff --git a/deps/src/singular.cpp b/deps/src/singular.cpp index 0208693dc..f75dc65e7 100644 --- a/deps/src/singular.cpp +++ b/deps/src/singular.cpp @@ -5,6 +5,27 @@ #include "ideals.h" #include "matrices.h" +static std::string singular_return; +static std::string singular_error; +static std::string singular_warning; + +// Internal singular interpreter variable +extern int inerror; + +static void WerrorS_for_julia(const char * s) +{ + singular_error += s; +} + +static void PrintS_for_julia(const char * s) +{ + singular_return += s; +} + +static void WarningS_for_julia(const char * s) +{ + singular_warning += s; +} JLCXX_MODULE define_julia_module(jlcxx::Module & Singular) { @@ -53,6 +74,54 @@ JLCXX_MODULE define_julia_module(jlcxx::Module & Singular) singular_define_ideals(Singular); singular_define_matrices(Singular); + + // Calls the Singular interpreter with `input`. + // `input` needs to be valid Singular input. + // Returns a 4-tuple: + // 1. entry is a bool, indicated if an error has happened + // 2. entry is the output as a string + // 3. entry is the error output as a string + // 4. entry is the warning output as a string + Singular.method("call_interpreter", [](std::string input) { + // save callbacks + auto default_print = PrintS_callback; + auto default_error = WerrorS_callback; + auto default_warning = WarnS_callback; + + // set temporary new callbacks + PrintS_callback = PrintS_for_julia; + WerrorS_callback = WerrorS_for_julia; + WarnS_callback = WarningS_for_julia; + + // cleanup return strings + singular_return.clear(); + singular_error.clear(); + singular_warning.clear(); + + // call interpreter + std::string input_str = input + "\nreturn();"; + char * ost = (char *)omalloc0(input_str.length() + 1); + memcpy(ost, input_str.c_str(), input_str.length() + 1); + bool err = iiAllStart(NULL, ost, BT_proc, 0); + inerror = 0; + errorreported = 0; + omFree(ost); + + // Get output + jl_array_t * result = jl_alloc_array_1d(jl_array_any_type, 4); + jl_arrayset(result, err ? jl_true : jl_false, 0); + jl_arrayset(result, jl_cstr_to_string(singular_return.c_str()), 1); + jl_arrayset(result, jl_cstr_to_string(singular_error.c_str()), 2); + jl_arrayset(result, jl_cstr_to_string(singular_warning.c_str()), 3); + + // restore old callbacks + PrintS_callback = default_print; + WerrorS_callback = default_error; + WarnS_callback = default_warning; + + return reinterpret_cast(result); + }); + /**************************** ** from resolutions.jl ***************************/ diff --git a/test/call_interpreter-test.jl b/test/call_interpreter-test.jl new file mode 100644 index 000000000..2f08a9bd2 --- /dev/null +++ b/test/call_interpreter-test.jl @@ -0,0 +1,14 @@ +function test_call_interpreter() + print("call_interpreter...") + Singular.libSingular.call_interpreter("ring r;") + result = Singular.libSingular.call_interpreter("r;") + @test result[1] == false + Singular.libSingular.call_interpreter("poly f = x;") + result = Singular.libSingular.call_interpreter("f;") + @test result[1] == false + @test result[2] == "x\n" + @test result[3] == "" + @test result[4] == "" + @test length(result) == 4 + println("PASS") +end diff --git a/test/runtests.jl b/test/runtests.jl index ae9488f5a..7d7e40063 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,6 +15,7 @@ include("../test/ideal-test.jl") include("../test/matrix-test.jl") include("../test/resolution-test.jl") include("../test/module-test.jl") +include("../test/call_interpreter-test.jl") # include("../test/libsingular-test.jl") test_number() @@ -23,5 +24,6 @@ test_ideal() test_matrix() test_resolution() test_module() +test_call_interpreter() # test_libsingular()