diff options
author | Xavier Delacour <xavier.delacour@gmail.com> | 2011-05-17 02:02:15 +0000 |
---|---|---|
committer | Xavier Delacour <xavier.delacour@gmail.com> | 2011-05-17 02:02:15 +0000 |
commit | 06221dacaef9d5708532ed7cca0077cba4efc77d (patch) | |
tree | d0cfa008840b402156ef990516854e2ea44e2230 | |
parent | 2d5c4302b0f27e7e23145b2eaa937cd0c2b73845 (diff) | |
download | swig-06221dacaef9d5708532ed7cca0077cba4efc77d.tar.gz |
Allow global operators to be SWIG-wrapped functions (by Karl Wette)
The Octave run-time allows global operators to be implemented,
e.g. op_scalar_add_X for adding a scalar and a wrapped struct X.
However it doesn't currently seem possible for these operators to
map to SWIG-wrapped functions. This is because dispatch_global_op()
looks for the operators to be installed as global variables, whereas
install_global() installs SWIG-wrapped functions as builtin functions;
the two appear to be separate symbol tables in Octave.
This patch modifies install_global() to install global operator functions
as both builtin functions and as global variables, where the value of the
global variable is a function handle to the operator function. It decides
if a function is a global operator if it begins with the prefix "op_"; this
prefix can be modified through a new command-line variable. It also always
installs the operators globally, regardless of whether the rest of the module
is being loaded globally. To accomplish this, install_global() is now always
called, but takes a bool argument specifying whether it should load symbols
globally. If a function is not a global operator, install_global() should
behave as before.
Tested that this compiles and works on Octave 3.2.4 and 3.4.0.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12675 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | Lib/octave/octrun.swg | 26 | ||||
-rw-r--r-- | Lib/octave/octruntime.swg | 3 | ||||
-rw-r--r-- | Source/Modules/octave.cxx | 14 |
3 files changed, 30 insertions, 13 deletions
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index c4c01ed82..49b032fc9 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -457,22 +457,26 @@ namespace Swig { rhs.members.clear(); } - void install_global() { + void install_global(bool global_load) { for (member_map::const_iterator it = members.begin(); it != members.end(); ++it) { - if (it->second.first && it->second.first->method) + bool is_global_op = (it->first.substr(0, strlen(SWIG_op_prefix)) == SWIG_op_prefix); + bool is_func_defined = (it->second.first && it->second.first->method); + if (is_func_defined && (is_global_op || global_load)) { install_builtin_function(it->second.first->method, it->first, - it->second.first->doc?it->second.first->doc:std::string()); - else if (it->second.second.is_defined()) { + it->second.first->doc ? it->second.first->doc : std::string()); + } + octave_value global_val = is_global_op ? make_fcn_handle(it->first) : it->second.second; + if (global_val.is_defined() && (is_global_op || global_load)) { #if OCTAVE_API_VERSION_NUMBER<37 link_to_global_variable(curr_sym_tab->lookup(it->first, true)); #else symbol_table::varref(it->first); symbol_table::mark_global(it->first); #endif - set_global_value(it->first, it->second.second); + set_global_value(it->first, global_val); #if OCTAVE_API_VERSION_NUMBER<37 - octave_swig_type *ost = Swig::swig_value_deref(it->second.second); + octave_swig_type *ost = Swig::swig_value_deref(global_val); if (ost) { const char* h = ost->help_text(); if (h) { @@ -775,7 +779,7 @@ namespace Swig { } static bool dispatch_global_op(const std::string &symbol, const octave_value_list &args, octave_value &ret) { - // we assume that "op_"-prefixed functions are installed in global namespace + // we assume that SWIG_op_prefix-prefixed functions are installed in global namespace // (rather than any module namespace). octave_value fcn = get_global_value(symbol, true); @@ -792,7 +796,7 @@ namespace Swig { octave_value ret; if (ost->dispatch_unary_op(std::string("__") + op_name + std::string("__"), ret)) return ret; - std::string symbol = "op_" + ost->swig_type_name() + "_" + op_name; + std::string symbol = SWIG_op_prefix + ost->swig_type_name() + "_" + op_name; octave_value_list args; args.append(make_value_hack(x)); if (dispatch_global_op(symbol, args, ret)) @@ -825,7 +829,7 @@ namespace Swig { args.append(make_value_hack(lhs)); args.append(make_value_hack(rhs)); - symbol = "op_"; + symbol = SWIG_op_prefix; symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name(); symbol += "_"; symbol += op_name; @@ -834,7 +838,7 @@ namespace Swig { if (dispatch_global_op(symbol, args, ret)) return ret; - symbol = "op_"; + symbol = SWIG_op_prefix; symbol += lhs_ost ? lhs_ost->swig_type_name() : lhs.type_name(); symbol += "_"; symbol += op_name; @@ -843,7 +847,7 @@ namespace Swig { if (dispatch_global_op(symbol, args, ret)) return ret; - symbol = "op_"; + symbol = SWIG_op_prefix; symbol += "any"; symbol += "_"; symbol += op_name; diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index 48da0cf48..da5b9c512 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -101,8 +101,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { // the incref is necessary so install_global doesn't destroy module_ns, // as it would if it installed something with the same name as the module. module_ns->incref(); - if (global_load) - module_ns->install_global(); + module_ns->install_global(global_load); module_ns->decref(); #if OCTAVE_API_VERSION_NUMBER<37 diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index dcd690844..b46214463 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -17,12 +17,14 @@ char cvsroot_octave_cxx[] = "$Id$"; static bool global_load = true; static String *global_name = 0; +static String *op_prefix = 0; static const char *usage = (char *) "\ Octave Options (available with -octave)\n\ -global - Load all symbols into the global namespace [default]\n\ -globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\ -noglobal - Do not load all symbols into the global namespace\n\ + -opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\ \n"; @@ -85,12 +87,23 @@ public: } else { Swig_arg_error(); } + } else if (strcmp(argv[i], "-opprefix") == 0) { + if (argv[i + 1]) { + op_prefix = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } } } } if (!global_name) global_name = NewString("cvar"); + if (!op_prefix) + op_prefix = NewString("op_"); SWIG_library_directory("octave"); Preprocessor_define("SWIGOCTAVE 1", 0); @@ -157,6 +170,7 @@ public: Printf(f_runtime, "\n"); Printf(f_runtime, "#define SWIG_global_load %s\n", global_load ? "true" : "false"); Printf(f_runtime, "#define SWIG_global_name \"%s\"\n", global_name); + Printf(f_runtime, "#define SWIG_op_prefix \"%s\"\n", op_prefix); if (directorsEnabled()) { Printf(f_runtime, "#define SWIG_DIRECTORS\n"); |