From f8774be92d60bef73a040e5823e87f0dd9dfc70b Mon Sep 17 00:00:00 2001 From: Xavier Delacour Date: Thu, 13 Oct 2011 23:48:28 +0000 Subject: [PATCH] Allow Octave modules to be re-loaded after a "clear all" (thanks to Karl Wette; SF 3418908) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12824 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 ++ Examples/Makefile.in | 2 +- Examples/octave/module_load/runme_args.m | 28 +++++++++++ Examples/octave/module_load/runme_gl_func.m | 46 +++++++++++++++++-- .../octave/module_load/runme_gl_func_base.m | 36 +++++++++++++++ Examples/octave/module_load/runme_nogl_func.m | 42 +++++++++++++++-- .../octave/module_load/runme_nogl_func_base.m | 34 ++++++++++++++ Lib/octave/octruntime.swg | 22 +++++---- 8 files changed, 196 insertions(+), 17 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 9c2cbbc2d..af0053061 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.5 (in progress) =========================== +2011-09-13: xavier98 + [octave] Allow Octave modules to be re-loaded after a "clear all". + 2011-09-19: wsfulton Fix regression introduced in swig-2.0.1 reported by Teemu Ikonone leading to uncompilable code when using typedef and function pointer references, for example: diff --git a/Examples/Makefile.in b/Examples/Makefile.in index b86418c2c..ff5686913 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -333,7 +333,7 @@ python_clean: # Make sure these locate your Octave installation OCTAVE_INCLUDE= $(DEFS) @OCTAVEEXT@ OCTAVE_LIB = -OCTAVE = @OCTAVE@ +OCTAVE = @OCTAVE@ -qf # Extra Octave specific dynamic linking options OCTAVE_DLNK = @OCTAVEDYNAMICLINKING@ diff --git a/Examples/octave/module_load/runme_args.m b/Examples/octave/module_load/runme_args.m index bce3c4492..271cdd289 100644 --- a/Examples/octave/module_load/runme_args.m +++ b/Examples/octave/module_load/runme_args.m @@ -2,6 +2,7 @@ # test module loading with arguments +##### BEGIN TEST ##### # test help example -help assert(!isglobal("example")) @@ -10,3 +11,30 @@ assert(!isglobal("example")) example -globals mycvar assert(!isglobal("cvar")) assert(mycvar.ivar == example.ifunc()) +##### END TEST ##### + +# clearing a module results in a segfault for Octave <= 3.0.* +# (tested on Octave 3.0.5), so skip the following test +try + vers = cellfun("str2num", strsplit(OCTAVE_VERSION, ".")); +catch + vers = cellfun("str2num", cellstr(split(OCTAVE_VERSION, "."))); +end_try_catch +assert(length(vers) >= 2); +if vers(1) < 3 || (vers(1) == 3 && vers(2) == 0) + disp("skipping 'clear all' test"); + return +endif + +clear all; + +##### BEGIN TEST ##### +# test help +example -help +assert(!isglobal("example")) + +# load module with custom cvar +example -globals mycvar +assert(!isglobal("cvar")) +assert(mycvar.ivar == example.ifunc()) +##### END TEST ##### diff --git a/Examples/octave/module_load/runme_gl_func.m b/Examples/octave/module_load/runme_gl_func.m index 15dfc5237..1624cdd9a 100644 --- a/Examples/octave/module_load/runme_gl_func.m +++ b/Examples/octave/module_load/runme_gl_func.m @@ -3,19 +3,57 @@ # test whether module can be loaded # in a function (global cvar) -# test that everything works from the base context -example -global cvar -assert(cvar.ivar == example.ifunc()) +1; +##### BEGIN TEST ##### function func example global cvar assert(cvar.ivar == example.ifunc()) endfunction +# test that everything works from the base context +example +global cvar +assert(cvar.ivar == example.ifunc()) + # test loading in a function func # test a second time to check everything works func +##### END TEST ##### + +# clearing a module results in a segfault for Octave <= 3.0.* +# (tested on Octave 3.0.5), so skip the following test +try + vers = cellfun("str2num", strsplit(OCTAVE_VERSION, ".")); +catch + vers = cellfun("str2num", cellstr(split(OCTAVE_VERSION, "."))); +end_try_catch +assert(length(vers) >= 2); +if vers(1) < 3 || (vers(1) == 3 && vers(2) == 0) + disp("skipping 'clear all' test"); + return +endif + +clear all; + +##### BEGIN TEST ##### +function func + example + global cvar + assert(cvar.ivar == example.ifunc()) +endfunction + +# test that everything works from the base context +example +global cvar +assert(cvar.ivar == example.ifunc()) + +# test loading in a function +func + +# test a second time to check everything works +func +##### END TEST ##### diff --git a/Examples/octave/module_load/runme_gl_func_base.m b/Examples/octave/module_load/runme_gl_func_base.m index 2d312a663..0e3eb6112 100644 --- a/Examples/octave/module_load/runme_gl_func_base.m +++ b/Examples/octave/module_load/runme_gl_func_base.m @@ -5,6 +5,7 @@ 1; +##### BEGIN TEST ##### function func example global cvar @@ -21,3 +22,38 @@ func example global cvar assert(cvar.ivar == example.ifunc()) +##### END TEST ##### + +# clearing a module results in a segfault for Octave <= 3.0.* +# (tested on Octave 3.0.5), so skip the following test +try + vers = cellfun("str2num", strsplit(OCTAVE_VERSION, ".")); +catch + vers = cellfun("str2num", cellstr(split(OCTAVE_VERSION, "."))); +end_try_catch +assert(length(vers) >= 2); +if vers(1) < 3 || (vers(1) == 3 && vers(2) == 0) + disp("skipping 'clear all' test"); + return +endif + +clear all; + +##### BEGIN TEST ##### +function func + example + global cvar + assert(cvar.ivar == example.ifunc()) +endfunction + +# test loading in a function +func + +# test a second time to check everything works +func + +# test that everything works from the base context +example +global cvar +assert(cvar.ivar == example.ifunc()) +##### END TEST ##### diff --git a/Examples/octave/module_load/runme_nogl_func.m b/Examples/octave/module_load/runme_nogl_func.m index 6c549a654..fd8e19f37 100644 --- a/Examples/octave/module_load/runme_nogl_func.m +++ b/Examples/octave/module_load/runme_nogl_func.m @@ -3,17 +3,53 @@ # test whether module can be loaded # in a function (no global cvar) -# test that everything works from the base context -example -noglobal -assert(example.cvar.ivar == example.ifunc()) +1; +##### BEGIN TEST ##### function func example -noglobal assert(example.cvar.ivar == example.ifunc()) endfunction +# test that everything works from the base context +example -noglobal +assert(example.cvar.ivar == example.ifunc()) + # test loading in a function func # test a second time to check everything works func +##### END TEST ##### + +# clearing a module results in a segfault for Octave <= 3.0.* +# (tested on Octave 3.0.5), so skip the following test +try + vers = cellfun("str2num", strsplit(OCTAVE_VERSION, ".")); +catch + vers = cellfun("str2num", cellstr(split(OCTAVE_VERSION, "."))); +end_try_catch +assert(length(vers) >= 2); +if vers(1) < 3 || (vers(1) == 3 && vers(2) == 0) + disp("skipping 'clear all' test"); + return +endif + +clear all; + +##### BEGIN TEST ##### +function func + example -noglobal + assert(example.cvar.ivar == example.ifunc()) +endfunction + +# test that everything works from the base context +example -noglobal +assert(example.cvar.ivar == example.ifunc()) + +# test loading in a function +func + +# test a second time to check everything works +func +##### END TEST ##### diff --git a/Examples/octave/module_load/runme_nogl_func_base.m b/Examples/octave/module_load/runme_nogl_func_base.m index 0716bc223..bb8da9328 100644 --- a/Examples/octave/module_load/runme_nogl_func_base.m +++ b/Examples/octave/module_load/runme_nogl_func_base.m @@ -5,6 +5,7 @@ 1; +##### BEGIN TEST ##### function func example -noglobal assert(example.cvar.ivar == example.ifunc()) @@ -19,3 +20,36 @@ func # test that everything works from the base context example -noglobal assert(example.cvar.ivar == example.ifunc()) +##### END TEST ##### + +# clearing a module results in a segfault for Octave <= 3.0.* +# (tested on Octave 3.0.5), so skip the following test +try + vers = cellfun("str2num", strsplit(OCTAVE_VERSION, ".")); +catch + vers = cellfun("str2num", cellstr(split(OCTAVE_VERSION, "."))); +end_try_catch +assert(length(vers) >= 2); +if vers(1) < 3 || (vers(1) == 3 && vers(2) == 0) + disp("skipping 'clear all' test"); + return +endif + +clear all; + +##### BEGIN TEST ##### +function func + example -noglobal + assert(example.cvar.ivar == example.ifunc()) +endfunction + +# test loading in a function +func + +# test a second time to check everything works +func + +# test that everything works from the base context +example -noglobal +assert(example.cvar.ivar == example.ifunc()) +##### END TEST ##### diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index 0e1434f69..bb173eb22 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -20,11 +20,17 @@ static void SWIG_init_user(octave_swig_type* module_ns); DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { - static bool already_init=false; - static octave_swig_type* module_ns=0; - - // if module not already loaded - if (!already_init) { + // determine if module is already loaded + bool already_load; +#if OCTAVE_API_VERSION_NUMBER<37 + { + symbol_record *rec = curr_sym_tab->lookup(SWIG_name_d); + already_load = (rec && rec->is_linked_to_global()); + } +#else + already_load = symbol_table::is_global(SWIG_name_d); +#endif + if (!already_load) { // parse command line const char* usage="usage: " SWIG_name_d " [-global|-noglobal] [-globals ]"; @@ -64,8 +70,6 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { return octave_value_list(); } - already_init=true; - // load module in base frame #if OCTAVE_API_VERSION_NUMBER<37 symbol_table *prev_sym_tab = curr_sym_tab; @@ -89,7 +93,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { if (swig_globals[j].get_method) cvar_ns->assign(swig_globals[j].name,&swig_globals[j]); - module_ns=new octave_swig_type(0, 0, 0, true); + octave_swig_type* module_ns=new octave_swig_type(0, 0, 0, true); module_ns->assign(global_name,Swig::swig_value_ref(cvar_ns)); for (int j=0;swig_globals[j].name;++j) if (swig_globals[j].method) @@ -130,7 +134,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { mlock(); #endif - } // !already_init + } // !already_load // link variable to module in current context #if OCTAVE_API_VERSION_NUMBER<37