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
This commit is contained in:
parent
2d5c4302b0
commit
06221dacae
3 changed files with 30 additions and 13 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue