int octave_call(const char *string) { int parse_status; octave_save_signal_mask (); if (octave_set_current_context) { #if defined (USE_EXCEPTIONS_FOR_INTERRUPTS) panic_impossible (); #else unwind_protect::run_all (); raw_mode (0); std::cout << "\n"; octave_restore_signal_mask (); #endif } can_interrupt = true; octave_catch_interrupts (); octave_initialized = true; // XXX FIXME XXX need to give caller an opaque pointer // so that they can define and use separate namespaces // when calling octave, with a shared global namespace. // Something like: // int call_octave (const char *string, void *psymtab = NULL) { // ... // curr_sym_tab = psymtab == NULL ? top_level_sym_tab : symbol_table; // I suppose to be safe from callbacks (surely we have to // provide some way to call back from embedded octave into // the user's application), we should push and pop the current // symbol table. // Note that I'm trying to distinguish exception from // failure in the return codes. I believe failure is // indicated by -1. I have execution exception (including // user interrupt and more dramatic failures) returning -2 // and memory failure returning -3. We should formalize // this with error codes defined in embed_octave.h. Maybe // a more fine-grained approach could be used within octave // proper. try { curr_sym_tab = top_level_sym_tab; reset_error_handler (); eval_string(string, false, parse_status); } catch (octave_interrupt_exception) { recover_from_exception (); std::cout << "\n"; error_state = -2; } catch (std::bad_alloc) { recover_from_exception (); std::cout << "\n"; error_state = -3; } octave_restore_signal_mask(); octave_initialized = false; // XXX FIXME XXX callbacks calling embed_octave // may or may not want error_state reset. return error_state; }
bool COctaveInterface::run_octave_helper(CSGInterface* from_if) { from_if->SG_DEBUG("Entering Octave\n"); octave_save_signal_mask (); if (octave_set_current_context) { #if defined (USE_EXCEPTIONS_FOR_INTERRUPTS) panic_impossible (); #else unwind_protect::run_all (); raw_mode (0); octave_restore_signal_mask (); #endif } can_interrupt = true; octave_catch_interrupts (); octave_initialized = true; try { int parse_status; char* octave_code=NULL; clear_octave_globals(); for (int i=0; i<from_if->get_nrhs(); i++) { int len=0; char* var_name = from_if->get_string(len); from_if->SG_DEBUG("var_name = '%s'\n", var_name); if (strmatch(var_name, "octavecode")) { len=0; octave_code=from_if->get_string(len); from_if->SG_DEBUG("octave_code = '%s'\n", octave_code); break; } else { octave_value_list args; COctaveInterface* in = new COctaveInterface(args, 1, false); in->create_return_values(1); from_if->translate_arg(from_if, in); #if OCTAVE_APIVERSION >= 37 symbol_table::varref (var_name) = in->get_return_values()(0); #else set_global_value(var_name, in->get_return_values()(0)); #endif delete[] var_name; SG_UNREF(in); } } #if OCTAVE_APIVERSION >= 37 #else symbol_table* old=curr_sym_tab; curr_sym_tab = global_sym_tab; #endif reset_error_handler (); eval_string(octave_code, false, parse_status); delete[] octave_code; int32_t sz=0; octave_value_list results; #if OCTAVE_APIVERSION >= 37 if (symbol_table::is_variable("results")) { results = symbol_table::varval("results"); //results = get_global_value("results", false); sz=results.length(); } #else if (curr_sym_tab->lookup("results")) { results = get_global_value("results", false); sz=results.length(); } #endif if (sz>0) { if (results(0).is_list()) { from_if->SG_DEBUG("Found return list of length %d\n", results(0).length()); results=results(0).list_value(); sz=results.length(); } } if (sz>0 && from_if->create_return_values(sz)) { from_if->SG_DEBUG("Found %d args\n", sz); COctaveInterface* out = new COctaveInterface(results, sz, false); //process d for (int32_t i=0; i<sz; i++) from_if->translate_arg(out, from_if); SG_UNREF(out); } else { if (sz!=from_if->get_nlhs()) { from_if->SG_ERROR("Number of return values (%d) does not match number of expected" " return values (%d).\n", sz, from_if->get_nlhs()); } } #if OCTAVE_APIVERSION >= 37 #else curr_sym_tab=old; #endif } catch (octave_interrupt_exception) { recover_from_exception (); SG_SPRINT("%\n"); } catch (std::bad_alloc) { recover_from_exception (); SG_SPRINT("%\n"); } octave_restore_signal_mask(); octave_initialized = false; from_if->SG_DEBUG("Leaving Octave.\n"); return true; }