diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html index afa4a8c83..1e965102a 100644 --- a/Doc/Manual/Octave.html +++ b/Doc/Manual/Octave.html @@ -77,22 +77,18 @@ The current SWIG implemention is based on Octave 2.9.12. Support for other versi Let's start with a very simple SWIG interface file:

-

%module example
 %{
 #include "example.h"
 %}
 int gcd(int x, int y);
 extern double Foo; 
-

To build an Octave module, run SWIG using the -octave option. The -c++ option is required (for now) as Octave itself is written in C++ and thus the wrapper code must also be.

-

$ swig -octave -c++ example.i 
-

This creates a C/C++ source file example_wrap.cxx. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module. @@ -110,12 +106,10 @@ Octave modules are DLLs/shared objects having the ".oct" suffix. Building an oct file is usually done with the mkoctfile command (either within Octave itself, or from the shell). For example,

-

 $ swig -octave -c++ example.i -o example_wrap.cxx
 $ mkoctfile example_wrap.cxx example.c
 
-

where example.c is the file containing the gcd() implementation. @@ -129,22 +123,16 @@ $ mkoctfile example_wrap.cxx example.c mkoctfile will produce example.oct, which contains the compiled extension module. Loading it into Octave is then a matter of invoking

-

octave:1> example
-

-

26.2.2 Using your module

-

-

Assuming all goes well, you will be able to do this:

-

$ octave -q
 octave:1> example
 octave:2> example.gcd(4,6)
@@ -154,7 +142,6 @@ ans =  3
 octave:4> example.cvar.Foo=4;
 octave:5> example.cvar.Foo
 ans =  4 
-

26.3 A tour of basic C/C++ wrapping

@@ -174,7 +161,6 @@ When Octave is asked to invoke example, it will try to find the .m or . Giving this function a parameter "global" will cause it to load all symbols into the global namespace in addition to the example namespace. For example:

-

$ octave -q
 octave:1> example("global")
 octave:2> gcd(4,6)
@@ -185,15 +171,12 @@ octave:4> cvar.Foo=4;
 octave:5> cvar.Foo
 ans =  4 
 
-

It is also possible to rename the module namespace with an assignment, as in:
-

octave:1> example;
 octave:2> c=example;
 octave:3> c.gcd(10,4)
 ans =  2 
-

All global variables are put into the cvar namespace object. This is accessible either as my_module.cvar, or just cvar (if the module is imported into the global namespace). @@ -201,11 +184,9 @@ All global variables are put into the cvar namespace object. This is accessible

One can also rename it by simple assignment, e.g.,

-

 octave:1> some_vars = cvar;
-
-

+

26.3.2 Functions

@@ -214,21 +195,16 @@ octave:1> some_vars = cvar; Global functions are wrapped as new Octave built-in functions. For example,

-

%module example
 int fact(int n); 
-

creates a built-in function example.fact(n) that works exactly like you think it does:

-

octave:1> example.fact(4)
 24 
-

-

26.3.3 Global variables

@@ -236,17 +212,14 @@ int fact(int n); Global variables are a little special in Octave. Given a global variable:

-

%module example
 extern double Foo;
       
-

To expose variables, SWIG actually generates two functions, to get and set the value. In this case, Foo_set and Foo_set would be generated. SWIG then automatically calls these functions when you get and set the variable-- in the former case creating a local copy in the interpreter of the C variables, and in the latter case copying an interpreter variables onto the C variable.

-

octave:1> example;
 octave:2> c=example.cvar.Foo
 c =  3
@@ -255,42 +228,35 @@ octave:4> c
 c =  3
 octave:5> example.cvar.Foo
 ans =  4
-

If a variable is marked with the %immutable directive then any attempts to set this variable will cause an Octave error. Given a global variable:

-

%module example
 %immutable;
 extern double Foo;
 %mutable;
 
-

SWIG will allow the the reading of Foo but when a set attempt is made, an error function will be called.

-

octave:1> example
 octave:2> example.Foo=4
 error: attempt to set immutable member variable
 error: assignment failed, or no method for `swig_type = scalar'
 error: evaluating assignment expression near line 2, column 12 
-

It is possible to add new functions or variables to the module. This also allows the user to rename/remove existing functions and constants (but not linked variables, mutable or immutable). Therefore users are recommended to be careful when doing so.

-

octave:1> example;
 octave:2> example.PI=3.142;
 octave:3> example.PI
 ans =  3.1420 
-

26.3.4 Constants and enums

@@ -299,62 +265,50 @@ ans = 3.1420 Because Octave doesn't really have the concept of constants, C/C++ constants are not really constant in Octave. They are actually just a copy of the value into the Octave interpreter. Therefore they can be changed just as any other value. For example given some constants:

-

%module example
 %constant int ICONST=42;
 #define    SCONST      "Hello World"
 enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
 
-

This is 'effectively' converted into the following Octave code:

-

example.ICONST=42
 example.SCONST="Hello World"
 example.SUNDAY=0
 .... 
-

-

26.3.5 Pointers

-

-

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface: C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface:

-

%module example
 FILE *fopen(const char *filename, const char *mode);
 int fputs(const char *, FILE *);
 int fclose(FILE *);
 
-

When wrapped, you will be able to use the functions in a natural way from Octave. For example:

-

 octave:1> example;
 octave:2> f=example.fopen("w","junk");
 octave:3> example.fputs("Hello world",f);
 octave:4> example.fclose(f);
 
-

Simply printing the value of a wrapped C++ type will print it's typename. E.g.,

-

octave:1> example;
 octave:2> f=example.fopen("junk","w");
 octave:3> f
@@ -363,18 +317,15 @@ f =
 {
   _p_FILE, ptr = 0x9b0cd00
 } 
-

As the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes and structs (see below).

-

octave:1> example;
 octave:2> f=example.fopen("not there","r");
 error: value on right hand side of assignment is undefined
 error: evaluating assignment expression near line 2, column 2 
-

26.3.6 Structures

@@ -383,18 +334,15 @@ error: evaluating assignment expression near line 2, column 2 SWIG wraps C structures and C++ classes by creating type objects. When invoked as a function, they create a new object of their type. The structures/classes themselves are mapped to a native Octave type. This provides a very natural interface. For example,

-

struct Point{
   int x,y;
 };
 
-

is used as follows:

-

octave:1> example;
 octave:2> p=example.Point();
@@ -404,7 +352,6 @@ octave:5> p.x, p.y
 ans =  3
 ans =  5 
 
-

26.3.7 C++ classes

@@ -459,26 +406,22 @@ For example, the following: struct A { int value; A(int _value) : value(_value) {} - A operator+ (const A& x) { + A operator+ (const A& x) { return A(value+x.value); } }; } -

may be used naturally from Octave:

-

 a=A(2), b=A(3), c=a+b
 assert(c.value==5);
 
-

Octave operators are mapped in the following way:

-

 __brace      a{args}
 __brace_asgn a{args} = rhs
@@ -510,14 +453,12 @@ __el_mul     a .* b
 __el_div     a ./ b
 __el_pow     a .^ b
 __el_ldiv    a .\ b
-__el_and     a & b
+__el_and     a & b
 __el_or      a | b
 
-

On the C++ side, the default mappings are as follows:

-

 %rename(__add)       *::operator+;
 %rename(__add)       *::operator+();
@@ -530,7 +471,7 @@ On the C++ side, the default mappings are as follows:
 %rename(__mod)       *::operator%;
 %rename(__lshift)    *::operator<<;
 %rename(__rshift)    *::operator>>;
-%rename(__el_and)    *::operator&&;
+%rename(__el_and)    *::operator&&;
 %rename(__el_or)     *::operator||;
 %rename(__xor)       *::operator^;
 %rename(__invert)    *::operator~;
@@ -556,7 +497,6 @@ The %extend directive works the same as in other modules.
 

You can use it to define special behavior, like for example defining Octave operators not mapped to C++ operators, or defining certain Octave mechanisms such as how an object prints. For example, the octave_value::{is_string,string_value,print} functions are routed to a special method __str that can be defined inside an %extend.

-

 %extend A {
 string __str() {
@@ -566,11 +506,9 @@ string __str() {
 }
 }
 
-

Then in Octave one gets,

-

 octave:1> a=A(4);
 octave:2> a
@@ -580,7 +518,6 @@ octave:3> printf("%s\n",a);
 octave:4> a.__str()
 4
 
-

26.3.13 C++ templates

@@ -607,19 +544,16 @@ Octave has no direct support for object oriented programming, however the sw

For example,

-

 octave:1> a=subclass();
 octave:2> a.my_var = 4;
 octave:3> a.my_method = @(self) printf("my_var = ",self.my_var);
 octave:4> a.my_method();
 my_var = 4
-
-

+

subclass() can also be used to subclass one or more C++ types. Suppose you have an interface defined by

-

 %inline {
 class A {
@@ -628,16 +562,14 @@ public:
     printf("c-side routine called\n");
   }
 };
-void call_your_method(A& a) {
+void call_your_method(A& a) {
   a.my_method();
 }
 }
 
-

Then from Octave you can say:

-

 octave:1> B=@() subclass(A(),@my_method);
 octave:2> function my_method(self)
@@ -646,35 +578,29 @@ octave:4> end
 octave:5> call_your_method(B());
 octave-side routine called
 
-

or more concisely,

-

 octave:1> B=@() subclass(A(),'my_method',@(self) printf("octave-side routine called\n"));
 octave:2> call_your_method(B());
 octave-side routine called
 
-

Note that you have to enable directors via the %feature directive (see other modules for this).

subclass() will accept any number of C++ bases or other subclass()'ed objects, (string,octave_value) pairs, and function_handles. In the first case, these are taken as base classes; in the second case, as named members (either variables or functions, depending on whether the given value is a function handle); in the third case, as member functions whose name is taken from the given function handle. E.g.,

-

 octave:1> B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',@(self) do_stuff())
 
-

You can also assign non-C++ member variables and functions after construct time. There is no support for non-C++ static members.

There is limited support for explicitly referencing C++ bases. So, in the example above, we could have

-

 octave:1> B=@() subclass(A(),@my_method);
 octave:2> function my_method(self)
@@ -685,7 +611,6 @@ octave:6> call_your_method(B());
 c-side routine called
 octave-side routine called
 
-

26.3.16 Threads

@@ -711,11 +636,9 @@ public: }; } -

Would produce this behavior in Octave:

-

 octave:1> a=A();
 A constructing
@@ -724,7 +647,6 @@ octave:3> clear a;
 octave:4> b=4;
 A destructing
 
-

In the case where one wishes for the C++ side to own an object that was created in Octave (especially a Director object), one can use the __disown() method to invert this logic. Then letting the Octave reference count go to zero will not destroy the object, but destroying the object will invalidate the Octave-side object if it still exists (and call destructors of other C++ bases in the case of multiple inheritance/subclass()'ing).

@@ -742,20 +664,16 @@ This is some skeleton support for various STL containers, but this work is not f

Octave provides a rich set of classes for dealing with matrices etc. Currently there are no typemaps to deal with those, though such support will be added soon. However, these are relatively straight forward for users to add themselves (see the docs on typemaps). Without much work (a single typemap decl-- say, 5 lines of code in the interface file), it would be possible to have a function

-

 double my_det(const double* mat,int m,int n);
-
-

+

that is accessed from Octave as,

-

 octave:1> my_det(rand(4));
 ans = -0.18388
-
-

+
diff --git a/Examples/test-suite/namespace_typemap.i b/Examples/test-suite/namespace_typemap.i index 93cc5c400..e4e0af905 100644 --- a/Examples/test-suite/namespace_typemap.i +++ b/Examples/test-suite/namespace_typemap.i @@ -22,12 +22,12 @@ namespace test { } }; - /* A minimalistic complex class */ - class complex { + /* A minimalistic test_complex class */ + class test_complex { double re; double im; public: - complex(double r = 0, double i = 0) { + test_complex(double r = 0, double i = 0) { re = r; im = i; } @@ -44,16 +44,29 @@ namespace test { /* SWIG interface tests */ #ifdef SWIGPYTHON -%typemap(in) test::complex * { +%typemap(in) test::test_complex * { if (PyComplex_Check($input)) { - $1 = new complex(PyComplex_RealAsDouble($input), + $1 = new test_complex(PyComplex_RealAsDouble($input), PyComplex_ImagAsDouble($input)); } else { - PyErr_SetString(PyExc_TypeError,"Expected complex.\n"); + PyErr_SetString(PyExc_TypeError,"Expected test_complex.\n"); return NULL; } } -%typemap(freearg) test::complex * { +%typemap(freearg) test::test_complex * { + delete $1; +} +#endif +#ifdef SWIGOCTAVE +%typemap(in) test::test_complex * { + if ($input.is_complex_scalar()) { + $1 = new test_complex($input.complex_value().real(), + $input.complex_value().imag()); + } else { + error("Expected test_complex."); + } +} +%typemap(freearg) test::test_complex * { delete $1; } #endif @@ -68,6 +81,14 @@ namespace test { delete $1; } #endif +#ifdef SWIGOCTAVE + %typemap(in) string_class * { + $1 = new string_class($input.string_value().c_str()); + } + %typemap(freearg) string_class * { + delete $1; + } +#endif #ifdef SWIGRUBY %typemap(in) string_class * { $1 = new string_class(STR2CSTR($input)); @@ -81,26 +102,26 @@ namespace test { %inline %{ namespace test { class string_class; - class complex; + class test_complex; /* Functions in the namespace itself */ char *stest1(string_class *s) { return s->c_str(); } - double ctest1(complex *c) { + double ctest1(test_complex *c) { return c->real(); } } namespace test2 { using test::string_class; - using test::complex; + using test::test_complex; /* Functions in another namespace */ char *stest2(string_class *s) { return s->c_str(); } - double ctest2(complex *c) { + double ctest2(test_complex *c) { return c->real(); } } @@ -111,7 +132,7 @@ namespace test { char *stest3(string_class *s) { return s->c_str(); } - double ctest3(complex *c) { + double ctest3(test_complex *c) { return c->real(); } } @@ -122,7 +143,7 @@ namespace test { char *stest4(string_class *s) { return s->c_str(); } - double ctest4(complex *c) { + double ctest4(test_complex *c) { return c->real(); } } @@ -133,7 +154,7 @@ namespace test { char *stest5(string_class *s) { return s->c_str(); } - double ctest5(complex *c) { + double ctest5(test_complex *c) { return c->real(); } } @@ -141,35 +162,35 @@ namespace test { char *stest6(test::string_class *s) { return s->c_str(); } - double ctest6(test::complex *c) { + double ctest6(test::test_complex *c) { return c->real(); } char *stest7(test2::string_class *s) { return s->c_str(); } - double ctest7(test2::complex *c) { + double ctest7(test2::test_complex *c) { return c->real(); } char *stest8(test3::string_class *s) { return s->c_str(); } - double ctest8(test3::complex *c) { + double ctest8(test3::test_complex *c) { return c->real(); } char *stest9(test4::string_class *s) { return s->c_str(); } - double ctest9(test4::complex *c) { + double ctest9(test4::test_complex *c) { return c->real(); } char *stest10(test5::string_class *s) { return s->c_str(); } - double ctest10(test5::complex *c) { + double ctest10(test5::test_complex *c) { return c->real(); } @@ -178,17 +199,17 @@ namespace test { char *stest11(test11::string_class *s) { return s->c_str(); } - double ctest11(test11::complex *c) { + double ctest11(test11::test_complex *c) { return c->real(); } using namespace test2; - using test::complex; + using test::test_complex; char *stest12(string_class *s) { return s->c_str(); } - double ctest12(complex *c) { + double ctest12(test_complex *c) { return c->real(); } %} @@ -203,6 +224,14 @@ namespace Split { } } #endif +#ifdef SWIGOCTAVE + %typemap(in) PosInteger { + $1 = $input.long_value(); + if ($1 < 0) { + error("domain error"); + } + } +#endif #ifdef SWIGRUBY %typemap(in) PosInteger { $1 = NUM2INT($input); diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index 4feca8cd6..eff9c0c57 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -13,8 +13,14 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -#CPP_TEST_CASES += +# CPP_TEST_CASES += +CPP_TEST_BROKEN += \ + implicittest \ + li_implicit \ + li_std_map \ + li_std_set \ + li_std_stream #C_TEST_CASES += diff --git a/Examples/test-suite/octave/arrays_global_runme.m b/Examples/test-suite/octave/arrays_global_runme.m index 95a49088c..619d381b0 100644 --- a/Examples/test-suite/octave/arrays_global_runme.m +++ b/Examples/test-suite/octave/arrays_global_runme.m @@ -1,18 +1,19 @@ arrays_global -arrays_global.array_i = arrays_global.array_const_i; +arrays_global.cvar.array_i = arrays_global.cvar.array_const_i; -BeginString_FIX44a; -BeginString_FIX44b; -BeginString_FIX44c; -BeginString_FIX44d; -BeginString_FIX44d; -BeginString_FIX44b ="12"'\0'"45"; -BeginString_FIX44b; -BeginString_FIX44d; -BeginString_FIX44e; -BeginString_FIX44f; +cvar.BeginString_FIX44a; +cvar.BeginString_FIX44b; +cvar.BeginString_FIX44c; +cvar.BeginString_FIX44d; +cvar.BeginString_FIX44d; +cvar.BeginString_FIX44b = strcat("12","\0","45"); +cvar.BeginString_FIX44b; +cvar.BeginString_FIX44d; +cvar.BeginString_FIX44e; +cvar.BeginString_FIX44f; test_a("hello","hi","chello","chi"); test_b("1234567","hi"); + diff --git a/Examples/test-suite/octave/constover_runme.m b/Examples/test-suite/octave/constover_runme.m index b6822fc84..febcdae69 100644 --- a/Examples/test-suite/octave/constover_runme.m +++ b/Examples/test-suite/octave/constover_runme.m @@ -5,28 +5,28 @@ if (!strcmp(p,"test")) error("test failed!") endif -p = constover.test_pconst("test") +p = constover.test_pconst("test"); if (!strcmp(p,"test_pconst")) error("test_pconst failed!") endif -f = constover.Foo() -p = f.test("test") +f = constover.Foo(); +p = f.test("test"); if (!strcmp(p,"test")) error("member-test failed!") endif -p = f.test_pconst("test") +p = f.test_pconst("test"); if (!strcmp(p,"test_pconst")) error("member-test_pconst failed!") endif -p = f.test_constm("test") +p = f.test_constm("test"); if (!strcmp(p,"test_constmethod")) error("member-test_constm failed!") endif -p = f.test_pconstm("test") +p = f.test_pconstm("test"); if (!strcmp(p,"test_pconstmethod")) error("member-test_pconstm failed!") endif diff --git a/Examples/test-suite/octave/implicittest.i b/Examples/test-suite/octave/implicittest.i new file mode 100644 index 000000000..91205aafa --- /dev/null +++ b/Examples/test-suite/octave/implicittest.i @@ -0,0 +1,68 @@ +%module(naturalvar="1") implicittest + +%implicitconv; + +%inline +{ + struct B { }; +} + +%inline +{ + struct A + { + int ii; + A(int i) { ii = 1; } + A(double d) { ii = 2; } + A(const B& b) { ii = 3; } + explicit A(char *s) { ii = 4; } + + int get() const { return ii; } + + }; + + int get(const A& a) { return a.ii; } + + template + struct A_T + { + int ii; + A_T(int i) { ii = 1; } + A_T(double d) { ii = 2; } + A_T(const B& b) { ii = 3; } + explicit A_T(char *s) { ii = 4; } + + int get() const { return ii; } + + }; +} + +%inline +{ + struct Foo + { + int ii; + Foo(){ ii = 0;} + Foo(int){ ii = 1;} + Foo(double){ ii = 2;} + explicit Foo(char *s){ii = 3;} + Foo(const Foo& f){ ii = f.ii;} + + }; + + struct Bar + { + int ii; + Foo f; + Bar() {ii = -1;} + Bar(const Foo& ff){ ii = ff.ii;} + }; + + + int get_b(const Bar&b) { return b.ii; } + + Foo foo; + +} + +%template(A_int) A_T; diff --git a/Examples/test-suite/octave/langobj_runme.m b/Examples/test-suite/octave/langobj_runme.m deleted file mode 100644 index a18905ec0..000000000 --- a/Examples/test-suite/octave/langobj_runme.m +++ /dev/null @@ -1,12 +0,0 @@ -langobj - - -x ="hello" -rx = sys.getrefcount(x) -v = identity(x) -rv = sys.getrefcount(v) -if v != x: - error - -if rv - rx != 1: - error diff --git a/Examples/test-suite/octave/li_attribute_runme.m b/Examples/test-suite/octave/li_attribute_runme.m index 49d488b0a..c66e27c5b 100644 --- a/Examples/test-suite/octave/li_attribute_runme.m +++ b/Examples/test-suite/octave/li_attribute_runme.m @@ -47,9 +47,9 @@ if (b.a.c != 3) endif -myFoo = li_attribute.MyFoo; +myFoo = li_attribute.MyFoo(); myFoo.x = 8; -myClass = li_attribute.MyClass; +myClass = li_attribute.MyClass(); myClass.Foo = myFoo; if (myClass.Foo.x != 8) error diff --git a/Examples/test-suite/octave/li_boost_shared_ptr_runme.m b/Examples/test-suite/octave/li_boost_shared_ptr_runme.m index 358b55d0a..ca09316bc 100644 --- a/Examples/test-suite/octave/li_boost_shared_ptr_runme.m +++ b/Examples/test-suite/octave/li_boost_shared_ptr_runme.m @@ -10,10 +10,10 @@ function main() li_boost_shared_ptr.cvar.debug_shared = debug; # Change loop count to run for a long time to monitor memory - loopCount = 1 #5000 + loopCount = 1; #5000 for i=0:loopCount, self.runtest(); - endif + endfor if (li_boost_shared_ptr.Klass.getTotal_count() != 0) error("Klass.total_count=", li_boost_shared_ptr.Klass.getTotal_count()) @@ -454,10 +454,10 @@ function runtest() # templates pid = li_boost_shared_ptr.PairIntDouble(10, 20.2) - if (pid.baseVal1 != 20 or pid.baseVal2 != 40.4) + if (pid.baseVal1 != 20 || pid.baseVal2 != 40.4) error("Base values wrong") endif - if (pid.val1 != 10 or pid.val2 != 20.2) + if (pid.val1 != 10 || pid.val2 != 20.2) error("Derived Values wrong") endif endfunction diff --git a/Examples/test-suite/octave/li_std_string.i b/Examples/test-suite/octave/li_std_string.i new file mode 100644 index 000000000..822d713c4 --- /dev/null +++ b/Examples/test-suite/octave/li_std_string.i @@ -0,0 +1,55 @@ +%module li_std_string + +%naturalvar A; + + +%include +%include + + +%inline %{ + +struct A : std::string +{ + A(const std::string& s) : std::string(s) + { + } +}; + +struct B +{ + B(const std::string& s) : cname(0), name(s), a(s) + { + } + + char *cname; + std::string name; + A a; + +}; + + +const char* test_ccvalue(const char* x) { + return x; +} + +char* test_cvalue(char* x) { + return x; +} + +std::basic_string test_value_basic1(std::basic_string x) { + return x; +} + +std::basic_string > test_value_basic2(std::basic_string > x) { + return x; +} + +std::basic_string,std::allocator > test_value_basic3(std::basic_string,std::allocator > x) { + return x; +} + +%} + +%include ../li_std_string.i + diff --git a/Examples/test-suite/octave/namespace_typemap_runme.m b/Examples/test-suite/octave/namespace_typemap_runme.m index 2e4990fb9..ca3730773 100644 --- a/Examples/test-suite/octave/namespace_typemap_runme.m +++ b/Examples/test-suite/octave/namespace_typemap_runme.m @@ -48,8 +48,8 @@ if (!strcmp(stest12("hello"),"hello")) error endif -c = complex(2,3) -r = c.real +c = complex(2,3); +r = real(c); if (ctest1(c) != r) error diff --git a/Examples/test-suite/octave/overload_rename_runme.m b/Examples/test-suite/octave/overload_rename_runme.m index c266988c2..4a416cfbc 100644 --- a/Examples/test-suite/octave/overload_rename_runme.m +++ b/Examples/test-suite/octave/overload_rename_runme.m @@ -3,6 +3,6 @@ overload_rename f = overload_rename.Foo(1); f = overload_rename.Foo(1,1); -f = overload_rename.Foo_int(1,1); -f = overload_rename.Foo_int(1,1,1); +f = overload_rename.new_Foo_int(1,1); +f = overload_rename.new_Foo_int(1,1,1); diff --git a/Examples/test-suite/octave/refcount_runme.m b/Examples/test-suite/octave/refcount_runme.m index 2eb8eeed0..3ce5bcda2 100644 --- a/Examples/test-suite/octave/refcount_runme.m +++ b/Examples/test-suite/octave/refcount_runme.m @@ -13,22 +13,3 @@ if (a.ref_count() != 3) endif -rca = b2.get_rca(); -b3 = B.create(rca); - -if (a.ref_count() != 5) - error("This program will crash... now") -endif - - -v = vector_A(2); -v(0) = a; -v(1) = a; - -x = v(0); -clear v; - - - - - diff --git a/Examples/test-suite/octave/template_default_arg_runme.m b/Examples/test-suite/octave/template_default_arg_runme.m index 62219dc77..e50066248 100644 --- a/Examples/test-suite/octave/template_default_arg_runme.m +++ b/Examples/test-suite/octave/template_default_arg_runme.m @@ -2,7 +2,7 @@ template_default_arg helloInt = template_default_arg.Hello_int(); -helloInt.foo(template_default_arg.Hello_int.hi); +helloInt.foo(template_default_arg.Hello_int_hi); x = template_default_arg.X_int(); @@ -18,7 +18,7 @@ endif -y = template_default_arg.Y_unsigned() +y = template_default_arg.Y_unsigned(); if (y.meth(20.0, 200) != 200) error("Y_unsigned test 1 failed") endif @@ -33,7 +33,7 @@ endif x = template_default_arg.X_longlong(); x = template_default_arg.X_longlong(20.0); -x = template_default_arg.X_longlong(20.0, 200L); +x = template_default_arg.X_longlong(20.0, 200); x = template_default_arg.X_int(); @@ -49,7 +49,7 @@ x = template_default_arg.X_hello_unsigned(20.0, template_default_arg.Hello_int() y = template_default_arg.Y_hello_unsigned(); y.meth(20.0, template_default_arg.Hello_int()); y.meth(template_default_arg.Hello_int()); -y.meth() +y.meth(); diff --git a/Examples/test-suite/octave/template_type_namespace_runme.m b/Examples/test-suite/octave/template_type_namespace_runme.m index 1974a3be7..bbdcdef5e 100644 --- a/Examples/test-suite/octave/template_type_namespace_runme.m +++ b/Examples/test-suite/octave/template_type_namespace_runme.m @@ -1,7 +1,5 @@ template_type_namespace -if (!strcmp(typeinfo(foo()(0)),typeinfo(""))) - error -endif +assert(strcmp(foo()(1),"foo")); diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i index 3afbd90c5..164d1a1d1 100644 --- a/Examples/test-suite/preproc.i +++ b/Examples/test-suite/preproc.i @@ -228,6 +228,7 @@ This testcase tests operators for defines +#ifndef SWIGOCTAVE #ifdef __cplusplus #define %mangle(...) #@__VA_ARGS__ @@ -245,6 +246,7 @@ inline const char* mangle ## #@__VA_ARGS__ () { } #endif +#endif #if defined (__cplusplus) \ diff --git a/Examples/test-suite/python/template_typedef_runme.py b/Examples/test-suite/python/template_typedef_runme.py index e2efb7246..4b3970593 100644 --- a/Examples/test-suite/python/template_typedef_runme.py +++ b/Examples/test-suite/python/template_typedef_runme.py @@ -1,7 +1,7 @@ from template_typedef import * d = make_Identity_float() -c = make_Identity_real() +c = make_Identity_reald() try: @@ -18,14 +18,14 @@ except: raise RuntimeError try: - f = make_Multiplies_real_real_real_real(c, c) + f = make_Multiplies_reald_reald_reald_reald(c, c) a = f.this except: print f, "is not an instance" raise RuntimeError try: - g = make_Multiplies_float_float_real_real(d, c) + g = make_Multiplies_float_float_reald_reald(d, c) a = g.this except: print g, "is not an instance" diff --git a/Examples/test-suite/refcount.i b/Examples/test-suite/refcount.i index 5dfd951d3..8352b508a 100644 --- a/Examples/test-suite/refcount.i +++ b/Examples/test-suite/refcount.i @@ -55,7 +55,7 @@ %} -#ifdef SWIGPYTHON +#if defined(SWIGPYTHON) %extend_smart_pointer(RCPtr); %template(RCPtr_A) RCPtr; #endif @@ -96,7 +96,7 @@ %} -#ifdef SWIGPYTHON +#if defined(SWIGPYTHON) || defined(SWIGOCTAVE) %include %template(vector_A) std::vector >; diff --git a/Examples/test-suite/template_arg_replace.i b/Examples/test-suite/template_arg_replace.i index 4e69fa351..25274c9ab 100644 --- a/Examples/test-suite/template_arg_replace.i +++ b/Examples/test-suite/template_arg_replace.i @@ -1,14 +1,14 @@ %module template_arg_replace -%warnfilter(SWIGWARN_RUBY_WRONG_NAME) Matrix; /* Ruby, wrong class name */ +%warnfilter(SWIGWARN_RUBY_WRONG_NAME) test_Matrix; /* Ruby, wrong class name */ %inline %{ -template class Matrix { +template class test_Matrix { public: - void Func(const Matrix &m) { }; + void Func(const test_Matrix &m) { }; }; %} -%template (matrix33f) Matrix; +%template (matrix33f) test_Matrix; diff --git a/Examples/test-suite/template_typedef.i b/Examples/test-suite/template_typedef.i index 8ad5de209..b6128e1fa 100644 --- a/Examples/test-suite/template_typedef.i +++ b/Examples/test-suite/template_typedef.i @@ -8,15 +8,15 @@ // #if 0 -#define real double +#define reald double %{ -#define real double +#define reald double %} #else %inline %{ - typedef double real; + typedef double reald; %} #endif @@ -24,7 +24,7 @@ %inline %{ - // typedef double real; + // typedef double reald; namespace vfncs { @@ -78,29 +78,29 @@ }; template<> - struct arith_traits< real, real > + struct arith_traits< reald, reald > { - typedef real argument_type; - typedef real result_type; + typedef reald argument_type; + typedef reald result_type; static const char* const arg_type; static const char* const res_type; }; template<> - struct arith_traits< real, float > + struct arith_traits< reald, float > { typedef float argument_type; - typedef real result_type; + typedef reald result_type; static const char* const arg_type; static const char* const res_type; }; template<> - struct arith_traits< float, real > + struct arith_traits< float, reald > { typedef float argument_type; - typedef real result_type; + typedef reald result_type; static const char* const arg_type; static const char* const res_type; }; @@ -124,14 +124,14 @@ const char* const arith_traits< float, float >::arg_type = "float"; const char* const arith_traits< float, float >::res_type = "float"; - const char* const arith_traits< real, real >::arg_type = "real"; - const char* const arith_traits< real, real >::res_type = "real"; + const char* const arith_traits< reald, reald >::arg_type = "reald"; + const char* const arith_traits< reald, reald >::res_type = "reald"; - const char* const arith_traits< real, float >::arg_type = "float"; - const char* const arith_traits< real, float >::res_type = "real"; + const char* const arith_traits< reald, float >::arg_type = "float"; + const char* const arith_traits< reald, float >::res_type = "reald"; - const char* const arith_traits< float, real >::arg_type = "float"; - const char* const arith_traits< float, real >::res_type = "real"; + const char* const arith_traits< float, reald >::arg_type = "float"; + const char* const arith_traits< float, reald >::res_type = "reald"; #endif @@ -145,32 +145,32 @@ namespace vfncs { %template() arith_traits; %template(make_Identity_float) make_Identity; - %template(UnaryFunction_real_real) UnaryFunction; - %template(ArithUnaryFunction_real_real) ArithUnaryFunction; + %template(UnaryFunction_reald_reald) UnaryFunction; + %template(ArithUnaryFunction_reald_reald) ArithUnaryFunction; - %template() unary_func_traits; - %template() arith_traits; - %template(make_Identity_real) make_Identity; + %template() unary_func_traits; + %template() arith_traits; + %template(make_Identity_reald) make_Identity; /* [beazley] Added this part */ - %template() unary_func_traits; - %template(UnaryFunction_float_real) UnaryFunction; - %template(ArithUnaryFunction_float_real) ArithUnaryFunction; + %template() unary_func_traits; + %template(UnaryFunction_float_reald) UnaryFunction; + %template(ArithUnaryFunction_float_reald) ArithUnaryFunction; /* */ - %template() arith_traits; - %template() arith_traits; + %template() arith_traits; + %template() arith_traits; %template() arith_traits; - %template(make_Multiplies_float_float_real_real) - make_Multiplies; + %template(make_Multiplies_float_float_reald_reald) + make_Multiplies; %template(make_Multiplies_float_float_float_float) make_Multiplies; - %template(make_Multiplies_real_real_real_real) - make_Multiplies; + %template(make_Multiplies_reald_reald_reald_reald) + make_Multiplies; } diff --git a/Examples/test-suite/template_typedef_rec.i b/Examples/test-suite/template_typedef_rec.i index f630034db..83fe2104a 100644 --- a/Examples/test-suite/template_typedef_rec.i +++ b/Examples/test-suite/template_typedef_rec.i @@ -6,7 +6,7 @@ typedef size_t MY_sizeT; typedef long MY_intT; typedef double MY_floatT; -class Array +class test_Array { public: typedef MY_intT intT; @@ -19,7 +19,7 @@ template class ArrayIterator { public: - typedef Array::intT intT; + typedef test_Array::intT intT; }; @@ -27,13 +27,13 @@ template class ArrayReverseIterator { public: - typedef Array::intT intT; + typedef test_Array::intT intT; }; template class ArrayPrimitiveT - : public Array + : public test_Array { public: typedef T ValueT; diff --git a/Lib/octave/octave.swg b/Lib/octave/octave.swg index 735f3028e..9e5596537 100644 --- a/Lib/octave/octave.swg +++ b/Lib/octave/octave.swg @@ -1,12 +1,6 @@ - - %include %include %include +%include %include %include - - -%typemap(constcode) int double { - SWIG_Octave_SetConstant(module_ns,"$symname",octave_value($value)); -} diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 7c63a4a12..bb1122a7b 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -2,9 +2,9 @@ * See the LICENSE file for information on copyright, usage and redistribution * of SWIG, and the README file for authors - http://www.swig.org/release.html. * - * pycontainer.swg + * octcontainer.swg * - * Octave sequence <-> C++ container wrapper + * Octave cell <-> C++ container wrapper * * This wrapper, and its iterator, allows a general use (and reuse) of * the the mapping between C++ and Octave, thanks to the C++ @@ -52,14 +52,14 @@ namespace swig { template <> struct traits_check { - static bool check(octave_value) { + static bool check(const octave_value&) { return true; } }; template <> struct traits_asval { typedef octave_value value_type; - static int asval(octave_value obj, value_type *val) { + static int asval(const octave_value& obj, value_type *val) { if (val) *val = obj; return SWIG_OK; } @@ -76,16 +76,10 @@ namespace std { struct less : public binary_function { bool - operator()(octave_value v, octave_value w) const + operator()(const octave_value& v, const octave_value& w) const { - /* - bool res; - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - res = PyObject_Compare(v, w) < 0; - SWIG_PYTHON_THREAD_END_BLOCK; - return res; - */ - return false; + octave_value res = do_binary_op(octave_value::op_le,v,w); + return res.is_true(); } }; } @@ -201,9 +195,9 @@ namespace swig { namespace swig { template - struct OctSequence_Ref + struct OctSequence_Ref // * octave can't support these, because of how assignment works { - OctSequence_Ref(octave_value seq, int index) + OctSequence_Ref(const octave_value& seq, int index) : _seq(seq), _index(index) { } @@ -262,7 +256,7 @@ namespace swig { } - OctSequence_InputIterator(octave_value seq, int index) + OctSequence_InputIterator(const octave_value& seq, int index) : _seq(seq), _index(index) { } @@ -279,7 +273,7 @@ namespace swig bool operator==(const self& ri) const { - return (_index == ri._index) && (_seq == ri._seq); + return (_index == ri._index); } bool operator!=(const self& ri) const @@ -355,7 +349,7 @@ namespace swig typedef OctSequence_InputIterator iterator; typedef OctSequence_InputIterator const_iterator; - OctSequence_Cont(octave_value seq) : _seq(seq) + OctSequence_Cont(const octave_value& seq) : _seq(seq) { // * assert that we have map type etc. /* @@ -446,32 +440,28 @@ namespace swig %typemap(out,noblock=1,fragment="OctSequence_Cont") iterator, reverse_iterator, const_iterator, const_reverse_iterator { - /* $result = SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)), swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN); - */ } - %typemap(out,noblock=1,fragment="OctSequence_Cont") + %typemap(out,fragment="OctSequence_Cont") std::pair, std::pair { - /* - $result = PyTuple_New(2); - PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), - swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); - PyTuple_SetItem($result,1,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), - swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); - */ + octave_value_list tmpc; + tmpc.append(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); + tmpc.append(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).second), + swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); + $result = Cell(tmpc); } %fragment("PyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="OctSequence_Cont") {} - %typemap(out,noblock=1,fragment="OctPairBoolOutputIterator") + %typemap(out,fragment="OctPairBoolOutputIterator") std::pair, std::pair { - /* - $result = PyTuple_New(2); - PyTuple_SetItem($result,0,SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), - swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); - PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second)); - */ + octave_value_list tmpc; + tmpc.append(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &).first), + swig::OctSwigIterator::descriptor(),SWIG_POINTER_OWN)); + tmpc.append(SWIG_From(bool)(%static_cast($1,const $type &).second)); + $result = Cell(tmpc); } %typemap(in,noblock=1,fragment="OctSequence_Cont") @@ -479,7 +469,6 @@ namespace swig reverse_iterator(swig::OctSwigIterator *iter = 0, int res), const_iterator(swig::OctSwigIterator *iter = 0, int res), const_reverse_iterator(swig::OctSwigIterator *iter = 0, int res) { - /* res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::OctSwigIterator::descriptor(), 0); if (!SWIG_IsOK(res) || !iter) { %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); @@ -491,16 +480,13 @@ namespace swig %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); } } - */ } %typecheck(%checkcode(ITERATOR),noblock=1,fragment="OctSequence_Cont") iterator, reverse_iterator, const_iterator, const_reverse_iterator { - /* swig::OctSwigIterator *iter = 0; int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::OctSwigIterator::descriptor(), 0); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast *>(iter) != 0)); - */ } %fragment("OctSequence_Cont"); @@ -517,6 +503,29 @@ namespace swig %swig_container_methods(%arg(Sequence)) %fragment("OctSequence_Base"); + + %extend { + value_type pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty container"); + Sequence::value_type x = self->back(); + self->pop_back(); + return x; + } + + value_type __paren(difference_type i) throw (std::out_of_range) { + return *(swig::cgetpos(self, i)); + } + + void __paren_asgn(difference_type i, value_type x) throw (std::out_of_range) { + *(swig::getpos(self,i)) = x; + } + + void append(value_type x) { + self->push_back(x); + } + } + %enddef %define %swig_sequence_methods(Sequence...) @@ -525,19 +534,6 @@ namespace swig %define %swig_sequence_methods_val(Sequence...) %swig_sequence_methods_common(%arg(Sequence)) - %extend { - value_type __getitem__(difference_type i) throw (std::out_of_range) { - return *(swig::cgetpos(self, i)); - } - - void __setitem__(difference_type i, value_type x) throw (std::out_of_range) { - *(swig::getpos(self,i)) = x; - } - - void append(value_type x) { - self->push_back(x); - } - } %enddef // @@ -549,17 +545,17 @@ namespace swig fragment="OctSequence_Cont") { namespace swig { - template + template inline void - assign(const PySeq& pyseq, Seq* seq) { + assign(const OctSeq& octseq, Seq* seq) { %#ifdef SWIG_STD_NOASSIGN_STL - typedef typename PySeq::value_type value_type; - typename PySeq::const_iterator it = pyseq.begin(); - for (;it != pyseq.end(); ++it) { + typedef typename OctSeq::value_type value_type; + typename OctSeq::const_iterator it = octseq.begin(); + for (;it != octseq.end(); ++it) { seq->insert(seq->end(),(value_type)(*it)); } %#else - seq->assign(pyseq.begin(), pyseq.end()); + seq->assign(octseq.begin(), octseq.end()); %#endif } @@ -568,38 +564,32 @@ namespace swig { typedef Seq sequence; typedef T value_type; - static int asptr(octave_value obj, sequence **seq) { - /* - if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) { + static int asptr(const octave_value& obj, sequence **seq) { + if (!obj.is_defined() || Swig::swig_value_deref(obj)) { sequence *p; if (SWIG_ConvertPtr(obj,(void**)&p, swig::type_info(),0) == SWIG_OK) { if (seq) *seq = p; return SWIG_OLDOBJ; } - } else if (OctSequence_Check(obj)) { + } else if (obj.is_cell()) { try { - OctSequence_Cont pyseq(obj); + OctSequence_Cont octseq(obj); if (seq) { sequence *pseq = new sequence(); - assign(pyseq, pseq); + assign(octseq, pseq); *seq = pseq; return SWIG_NEWOBJ; } else { - return pyseq.check() ? SWIG_OK : SWIG_ERROR; + return octseq.check() ? SWIG_OK : SWIG_ERROR; } } catch (std::exception& e) { - if (seq) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, e.what()); - } - } + if (seq&&!error_state) + error("swig type error: %s",e.what()); return SWIG_ERROR; } } return SWIG_ERROR; - */ - return SWIG_ERROR; } }; @@ -611,8 +601,7 @@ namespace swig { typedef typename sequence::const_iterator const_iterator; static octave_value from(const sequence& seq) { - /* -#ifdef SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS +#ifdef SWIG_OCTAVE_EXTRA_NATIVE_CONTAINERS swig_type_info *desc = swig::type_info(); if (desc && desc->clientdata) { return SWIG_NewPointerObj(new sequence(seq), desc, SWIG_POINTER_OWN); @@ -620,18 +609,17 @@ namespace swig { #endif size_type size = seq.size(); if (size <= (size_type)INT_MAX) { - PyObject *obj = PyTuple_New((int)size); + Cell c(size,1); int i = 0; for (const_iterator it = seq.begin(); it != seq.end(); ++it, ++i) { - PyTuple_SetItem(obj,i,swig::from(*it)); + c(i) = swig::from(*it); } - return obj; + return c; } else { - PyErr_SetString(PyExc_OverflowError,"sequence size not valid in python"); - return NULL; + error("swig overflow error: sequence size not valid in octave"); + return octave_value(); } - */ return octave_value(); } }; diff --git a/Lib/octave/octiterators.swg b/Lib/octave/octiterators.swg index 3e589b946..926361e10 100644 --- a/Lib/octave/octiterators.swg +++ b/Lib/octave/octiterators.swg @@ -2,9 +2,7 @@ * See the LICENSE file for information on copyright, usage and redistribution * of SWIG, and the README file for authors - http://www.swig.org/release.html. * - * pyiterators.swg - * - * Implement a python 'output' iterator for Python 2.2 or higher. + * octiterators.swg * * Users can derive form the OctSwigIterator to implemet their * own iterators. As an example (real one since we use it for STL/STD @@ -31,19 +29,15 @@ namespace swig { public: virtual ~OctSwigIterator() {} - // Access iterator method, required by Python virtual octave_value value() const = 0; - // Forward iterator method, required by Python virtual OctSwigIterator *incr(size_t n = 1) = 0; - - // Backward iterator method, very common in C++, but not required in Python + virtual OctSwigIterator *decr(size_t n = 1) { throw stop_iteration(); } - // Random access iterator methods, but not required in Python virtual ptrdiff_t distance(const OctSwigIterator &x) const { throw std::invalid_argument("operation not supported"); @@ -54,7 +48,6 @@ namespace swig { throw std::invalid_argument("operation not supported"); } - // C++ common/needed methods virtual OctSwigIterator *copy() const = 0; octave_value next() @@ -84,15 +77,15 @@ namespace swig { { return ! operator==(x); } - - OctSwigIterator& operator += (ptrdiff_t n) - { - return *advance(n); + + OctSwigIterator* operator ++ () { + incr(); + return this; } - OctSwigIterator& operator -= (ptrdiff_t n) - { - return *advance(-n); + OctSwigIterator* operator -- () { + decr(); + return this; } OctSwigIterator* operator + (ptrdiff_t n) const @@ -306,12 +299,8 @@ namespace swig struct stop_iteration {}; %typemap(throws) stop_iteration { - assert(0); *(int*)0=0; - /* - (void)$1; - SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void()); + error("stop_iteration exception"); SWIG_fail; - */ } // Mark methods that return new objects @@ -343,37 +332,29 @@ namespace swig public: virtual ~OctSwigIterator(); - // Access iterator method, required by Python virtual octave_value value() const = 0; - // Forward iterator method, required by Python virtual OctSwigIterator *incr(size_t n = 1) = 0; - // Backward iterator method, very common in C++, but not required in Python virtual OctSwigIterator *decr(size_t n = 1); - // Random access iterator methods, but not required in Python virtual ptrdiff_t distance(const OctSwigIterator &x) const; virtual bool equal (const OctSwigIterator &x) const; - // C++ common/needed methods virtual OctSwigIterator *copy() const = 0; octave_value next(); octave_value previous(); OctSwigIterator *advance(ptrdiff_t n); - // * todo: need operator support - /* bool operator == (const OctSwigIterator& x) const; bool operator != (const OctSwigIterator& x) const; - OctSwigIterator& operator += (ptrdiff_t n); - OctSwigIterator& operator -= (ptrdiff_t n); + OctSwigIterator* operator ++ (); + OctSwigIterator* operator -- (); OctSwigIterator* operator + (ptrdiff_t n) const; OctSwigIterator* operator - (ptrdiff_t n) const; ptrdiff_t operator - (const OctSwigIterator& x) const; - */ }; } diff --git a/Lib/octave/octprimtypes.swg b/Lib/octave/octprimtypes.swg index 6b388c27e..a5068b5a8 100644 --- a/Lib/octave/octprimtypes.swg +++ b/Lib/octave/octprimtypes.swg @@ -111,8 +111,14 @@ SWIG_AsVal_dec(bool)(const octave_value& ov, bool *val) if (v!=floor(v)) return SWIG_TypeError; } - if (val) - *val = ov.int64_scalar_value().value(); + if (val) { + if (ov.is_int64_type()) + *val = ov.int64_scalar_value().value(); + else if (ov.is_uint64_type()) + *val = ov.uint64_scalar_value().value(); + else + *val = ov.long_value(); + } return SWIG_OK; } } @@ -147,8 +153,14 @@ SWIG_AsVal_dec(bool)(const octave_value& ov, bool *val) if (v<0) return SWIG_OverflowError; } - if (val) - *val = ov.uint64_scalar_value().value(); + if (val) { + if (ov.is_int64_type()) + *val = ov.int64_scalar_value().value(); + else if (ov.is_uint64_type()) + *val = ov.uint64_scalar_value().value(); + else + *val = ov.long_value(); + } return SWIG_OK; } } diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index d338d59e6..7b872af45 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -163,8 +163,10 @@ struct swig_octave_class { // octave_swig_type plays the role of both the shadow class and the class // representation within Octave, since there is no support for classes. -// Ideally these would be separated (with the latter in Octave itself), -// but for brevity/simplicity this is not done here. +// +// These should really be decoupled, with the class support added to Octave +// and the shadow class given by an m-file script. That would dramatically +// reduce the runtime complexity, and be more in line w/ other modules. class octave_swig_type : public octave_base_value { struct cpp_ptr { diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index fb05a3812..7718f7f6e 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -24,7 +24,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { octave_swig_packed::register_type(); SWIG_InitializeModule(0); SWIG_PropagateClientData(); - + install_builtin_function(swig_type,"swig_type",std::string()); install_builtin_function(swig_typequery,"swig_typequery",std::string()); install_builtin_function(swig_this,"swig_this",std::string()); diff --git a/Lib/octave/octstdcommon.swg b/Lib/octave/octstdcommon.swg index 716f46120..e69c7e629 100644 --- a/Lib/octave/octstdcommon.swg +++ b/Lib/octave/octstdcommon.swg @@ -40,7 +40,7 @@ namespace swig { // Traits that provides the asval/as/check method template struct traits_asptr { - static int asptr(octave_value obj, Type **val) { + static int asptr(const octave_value& obj, Type **val) { Type *p; int res = (SWIG_ConvertPtr(obj, (void**)&p, type_info(), 0) == SWIG_OK) ? SWIG_OLDOBJ : 0; if (SWIG_IsOK(res)) { @@ -51,13 +51,13 @@ namespace swig { }; template - inline int asptr(octave_value obj, Type **vptr) { + inline int asptr(const octave_value& obj, Type **vptr) { return traits_asptr::asptr(obj, vptr); } template struct traits_asval { - static int asval(octave_value obj, Type *val) { + static int asval(const octave_value& obj, Type *val) { if (val) { Type *p = 0; int res = traits_asptr::asptr(obj, &p); @@ -80,7 +80,7 @@ namespace swig { }; template struct traits_asval { - static int asval(octave_value obj, Type **val) { + static int asval(const octave_value& obj, Type **val) { if (val) { typedef typename noconst_traits::noconst_type noconst_type; noconst_type *p = 0; @@ -96,13 +96,13 @@ namespace swig { }; template - inline int asval(octave_value obj, Type *val) { + inline int asval(const octave_value& obj, Type *val) { return traits_asval::asval(obj, val); } template struct traits_as { - static Type as(octave_value obj, bool throw_error) { + static Type as(const octave_value& obj, bool throw_error) { Type v; int res = asval(obj, &v); if (!obj.is_defined() || !SWIG_IsOK(res)) { @@ -117,9 +117,9 @@ namespace swig { template struct traits_as { - static Type as(octave_value obj, bool throw_error) { + static Type as(const octave_value& obj, bool throw_error) { Type *v = 0; - int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res) && v) { if (SWIG_IsNewObj(res)) { Type r(*v); @@ -143,9 +143,9 @@ namespace swig { template struct traits_as { - static Type* as(octave_value obj, bool throw_error) { + static Type* as(const octave_value& obj, bool throw_error) { Type *v = 0; - int res = (obj ? traits_asptr::asptr(obj, &v) : SWIG_ERROR); + int res = traits_asptr::asptr(obj, &v); if (SWIG_IsOK(res)) { return v; } else { @@ -159,28 +159,28 @@ namespace swig { }; template - inline Type as(octave_value obj, bool te = false) { + inline Type as(const octave_value& obj, bool te = false) { return traits_as::category>::as(obj, te); } template struct traits_check { - static bool check(octave_value obj) { - int res = obj ? asval(obj, (Type *)(0)) : SWIG_ERROR; + static bool check(const octave_value& obj) { + int res = asval(obj, (Type *)(0)); return SWIG_IsOK(res) ? true : false; } }; template struct traits_check { - static bool check(octave_value obj) { - int res = obj ? asptr(obj, (Type **)(0)) : SWIG_ERROR; + static bool check(const octave_value& obj) { + int res = asptr(obj, (Type **)(0)); return SWIG_IsOK(res) ? true : false; } }; template - inline bool check(octave_value obj) { + inline bool check(const octave_value& obj) { return traits_check::category>::check(obj); } } @@ -191,7 +191,7 @@ namespace swig { namespace swig { template <> struct traits_asval { typedef Type value_type; - static int asval(octave_value obj, value_type *val) { + static int asval(const octave_value& obj, value_type *val) { if (Check(obj)) { if (val) *val = As(obj); return SWIG_OK; @@ -208,7 +208,7 @@ namespace swig { template <> struct traits_check { - static int check(octave_value obj) { + static int check(const octave_value& obj) { int res = Check(obj); return obj && res ? res : 0; } diff --git a/Lib/octave/octtypemaps.swg b/Lib/octave/octtypemaps.swg index 0c1093948..b75e65cde 100644 --- a/Lib/octave/octtypemaps.swg +++ b/Lib/octave/octtypemaps.swg @@ -20,6 +20,10 @@ #define SWIG_Object octave_value #define VOID_Object octave_value() +/* +// Octave allows implicit conversion +#define %implicitconv_flag $implicitconv +*/ // append output #define SWIG_AppendOutput(result, obj) SWIG_Octave_AppendOutput(result, obj) @@ -33,3 +37,28 @@ // Include the unified typemap library %include + + +%typemap(constcode,noblock=1) int double { + SWIG_Octave_SetConstant(module_ns,"$symname",octave_value($value)); +} + +/* +// Smart Pointers +%typemap(out,noblock=1) const SWIGTYPE & SMARTPOINTER { + $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor, SWIG_POINTER_OWN | %newpointer_flags); +} + +%typemap(ret) const SWIGTYPE & SMARTPOINTER, SWIGTYPE SMARTPOINTER { + octave_swig_type* lobj=Swig::swig_value_deref($result); + if (lobj) { + std::list idx; + idx.push_back(octave_value("__deref__")); + idx.push_back(octave_value_list()); + octave_value_list ovl(lobj->subsref(".(",idx)); + octave_swig_type* robj=ovl.length()>=1?Swig::swig_value_deref(ovl(0)):0; + if (robj && !error_state) + lobj->append(robj); + } +} +*/ diff --git a/Lib/octave/octuserdir.swg b/Lib/octave/octuserdir.swg new file mode 100644 index 000000000..ebb11b3a5 --- /dev/null +++ b/Lib/octave/octuserdir.swg @@ -0,0 +1,72 @@ +/* ------------------------------------------------------------------------- + * Special user directives + * ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- */ +/* + Implicit Conversion using the C++ constructor mechanism +*/ + +#define %implicitconv %feature("implicitconv") +#define %noimplicitconv %feature("implicitconv", "0") +#define %clearimplicitconv %feature("implicitconv", "") + + +/* ------------------------------------------------------------------------- */ +/* + %extend_smart_pointer extend the smart pointer support. + + For example, if you have a smart pointer as: + + template class RCPtr { + public: + ... + RCPtr(Type *p); + Type * operator->() const; + ... + }; + + you use the %extend_smart_pointer directive as: + + %extend_smart_pointer(RCPtr); + %template(RCPtr_A) RCPtr; + + then, if you have something like: + + RCPtr make_ptr(); + int foo(A *); + + you can do the following: + + a = make_ptr(); + b = foo(a); + + ie, swig will accept a RCPtr object where a 'A *' is + expected. + + Also, when using vectors + + %extend_smart_pointer(RCPtr); + %template(RCPtr_A) RCPtr; + %template(vector_A) std::vector >; + + you can type + + a = A(); + v = vector_A(2) + v[0] = a + + ie, an 'A *' object is accepted, via implicit conversion, + where a RCPtr object is expected. Additionally + + x = v[0] + + returns (and sets 'x' as) a copy of v[0], making reference + counting possible and consistent. +*/ + +%define %extend_smart_pointer(Type...) +%implicitconv Type; +%apply const SWIGTYPE& SMARTPOINTER { const Type& }; +%apply SWIGTYPE SMARTPOINTER { Type }; +%enddef diff --git a/Lib/octave/std_vector.i b/Lib/octave/std_vector.i index 510528a18..2862b5e77 100644 --- a/Lib/octave/std_vector.i +++ b/Lib/octave/std_vector.i @@ -3,21 +3,19 @@ %fragment("StdVectorTraits","header",fragment="StdSequenceTraits") %{ namespace swig { -/* template struct traits_asptr > { - static int asptr(PyObject *obj, std::vector **vec) { + static int asptr(const octave_value& obj, std::vector **vec) { return traits_asptr_stdseq >::asptr(obj, vec); } }; template struct traits_from > { - static PyObject *from(const std::vector& vec) { + static octave_value from(const std::vector& vec) { return traits_from_stdseq >::from(vec); } }; -*/ } %} diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 1faa64aed..8f05400de 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -37,17 +37,13 @@ private: public: - OCTAVE() : f_runtime(0),f_header(0),f_wrappers(0), - f_init(0),f_initbeforefunc(0), - f_directors(0),f_directors_h(0), - s_global_tab(0), - s_members_tab(0),class_name(0) { + OCTAVE():f_runtime(0), f_header(0), f_wrappers(0), + f_init(0), f_initbeforefunc(0), f_directors(0), f_directors_h(0), + s_global_tab(0), s_members_tab(0), class_name(0) { allow_overloading(); director_multiple_inheritance = 1; director_language = 1; - } - - virtual void main(int argc, char *argv[]) { + } virtual void main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { @@ -85,7 +81,6 @@ public: } } - String *module = Getattr(n, "name"); String *outfile = Getattr(n, "outfile"); f_runtime = NewFile(outfile, "w"); @@ -114,8 +109,8 @@ public: if (directorsEnabled()) { Swig_banner(f_directors_h); if (dirprot_mode()) { - // Printf(f_directors_h, "#include \n"); - // Printf(f_directors_h, "#include \n\n"); + // Printf(f_directors_h, "#include \n"); + // Printf(f_directors_h, "#include \n\n"); } } @@ -130,8 +125,7 @@ public: Printf(f_init, "}\n"); Printf(s_global_tab, "{0,0,0,0,0}\n};\n"); - Printf(s_global_tab, "static swig_octave_class swig_module_globals = {" - "SWIG_name_d,0,0,0,0,swig_globals,0};\n"); + Printf(s_global_tab, "static swig_octave_class swig_module_globals = {" "SWIG_name_d,0,0,0,0,swig_globals,0};\n"); Printv(f_wrappers, s_global_tab, NIL); SwigType_emit_type_table(f_runtime, f_wrappers); @@ -161,6 +155,14 @@ public: return Language::importDirective(n); } + const char *get_implicitconv_flag(Node *n) { + int conv = 0; + if (n && GetFlag(n, "feature:implicitconv")) { + conv = 1; + } + return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0"; + } + virtual int functionWrapper(Node *n) { Wrapper *f = NewWrapper(); Parm *p; @@ -168,27 +170,27 @@ public: int j; String *nodeType = Getattr(n, "nodeType"); - // int constructor = (!Cmp(nodeType, "constructor")); + int constructor = (!Cmp(nodeType, "constructor")); int destructor = (!Cmp(nodeType, "destructor")); + String *storage = Getattr(n, "storage"); - bool overloaded=!!Getattr(n, "sym:overloaded"); - bool last_overload=overloaded&&!Getattr(n, "sym:nextSibling"); + bool overloaded = !!Getattr(n, "sym:overloaded"); + bool last_overload = overloaded && !Getattr(n, "sym:nextSibling"); String *iname = Getattr(n, "sym:name"); String *wname = Swig_name_wrapper(iname); String *overname = Copy(wname); SwigType *d = Getattr(n, "type"); ParmList *l = Getattr(n, "parms"); - if (!overloaded&&!addSymbol(iname, n)) + if (!overloaded && !addSymbol(iname, n)) return SWIG_ERROR; if (overloaded) Append(overname, Getattr(n, "sym:overname")); - Printv(f->def, "static octave_value_list ", overname, - " (const octave_value_list& args, int nargout) {", NIL); - if (!overloaded||last_overload) - Printf(s_global_tab,"{\"%s\",%s,0,0,2},\n",iname,wname); + Printv(f->def, "static octave_value_list ", overname, " (const octave_value_list& args, int nargout) {", NIL); + if (!overloaded || last_overload) + Printf(s_global_tab, "{\"%s\",%s,0,0,2},\n", iname, wname); emit_args(d, l, f); emit_attach_parmmaps(l, f); @@ -196,17 +198,23 @@ public: int num_arguments = emit_num_arguments(l); int num_required = emit_num_required(l); + int varargs = emit_isvarargs(l); char source[64]; - Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i)) " - "{\n return octave_value_list();\n }\n", - iname,num_arguments,num_required); + Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i)) " "{\n return octave_value_list();\n }\n", iname, num_arguments, num_required); - // * typecheck, check, memberin, memberout, freearg typemaps..? + if (constructor && num_arguments == 1 && num_required == 1) { + if (Cmp(storage, "explicit") == 0) { + Node *parent = Swig_methodclass(n); + if (GetFlag(parent, "feature:implicitconv")) { + String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type"))); + Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc); + Delete(desc); + } + } + } - // * varargs? - - for (j=0,p=l;j= num_required) - Printf(getargs,"if (%dcode, getargs, "\n", NIL); Delete(getargs); p = Getattr(p, "tmap:in:next"); continue; } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument.\n", - SwigType_str(pt, 0)); + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); break; } } + // Check for trailing varargs + if (varargs) { + if (p && (tm = Getattr(p, "tmap:in"))) { + Replaceall(tm, "$input", "varargs"); + Printv(f->code, tm, "\n", NIL); + } + } + // Insert constraint checking code + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:check"))) { + Replaceall(tm, "$target", Getattr(p, "lname")); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p, "tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + // Insert cleanup code + String *cleanup = NewString(""); + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:freearg"))) { + if (Getattr(p, "tmap:freearg:implicitconv")) { + const char *convflag = "0"; + if (!Getattr(p, "hidden")) { + SwigType *ptype = Getattr(p, "type"); + convflag = get_implicitconv_flag(classLookup(ptype)); + } + if (strcmp(convflag, "0") == 0) { + tm = 0; + } + } + if (tm && (Len(tm) != 0)) { + Replaceall(tm, "$source", Getattr(p, "lname")); + Printv(cleanup, tm, "\n", NIL); + } + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + // Insert argument output code - String* outarg=NewString(""); + String *outarg = NewString(""); for (p = l; p;) { if ((tm = Getattr(p, "tmap:argout"))) { Replaceall(tm, "$source", Getattr(p, "lname")); @@ -273,7 +331,7 @@ public: Append(f->code, "upcall = !!dynamic_cast(arg1);\n"); } - Setattr(n,"wrap:name",overname); + Setattr(n, "wrap:name", overname); emit_action(n, f); @@ -293,17 +351,30 @@ public: Replaceall(tm, "$owner", "0"); Printf(f->code, "%s\n", tm); - Printf(f->code, "if (_outv.is_defined()) _outp = " - "SWIG_Octave_AppendOutput(_outp, _outv);\n"); + Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n"); Delete(tm); } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, - "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname); + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname); } - Printv(f->code,outarg,NIL); + Printv(f->code, outarg, NIL); + Printv(f->code, cleanup, NIL); - Printf(f->code, "fail:\n"); // we should free locals etc if this happens + if (GetFlag(n, "feature:new")) { + if ((tm = Swig_typemap_lookup_new("newfree", n, "result", 0))) { + Replaceall(tm, "$source", "result"); + Printf(f->code, "%s\n", tm); + } + } + + if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { + Replaceall(tm, "$source", "result"); + Replaceall(tm, "$result", "_outv"); + Printf(f->code, "%s\n", tm); + Delete(tm); + } + + Printf(f->code, "fail:\n"); // we should free locals etc if this happens Printf(f->code, "return _out;\n"); Printf(f->code, "}\n"); @@ -313,6 +384,7 @@ public: DelWrapper(f); Delete(overname); Delete(wname); + Delete(cleanup); Delete(outarg); if (last_overload) @@ -327,17 +399,15 @@ public: String *iname = Getattr(n, "sym:name"); String *wname = Swig_name_wrapper(iname); int maxargs; - String *dispatch = Swig_overload_dispatch - (n, "return %s(args, nargout);", &maxargs); + String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs); String *tmp = NewString(""); - Printv(f->def, "static octave_value_list ", wname, - " (const octave_value_list& args, int nargout) {", NIL); + Printv(f->def, "static octave_value_list ", wname, " (const octave_value_list& args, int nargout) {", NIL); Wrapper_add_local(f, "argc", "int argc = args.length()"); - Printf(tmp,"octave_value_ref argv[%d]={",maxargs); - for (int j=0;jcode, dispatch, "\n", NIL); Printf(f->code, "error(\"No matching function for overload\");\n", iname); @@ -352,26 +422,67 @@ public: } virtual int variableWrapper(Node *n) { - Language::variableWrapper(n); - + String *name = Getattr(n, "name"); String *iname = Getattr(n, "sym:name"); - String *gname = Swig_name_wrapper(Swig_name_get(iname)); + SwigType *t = Getattr(n, "type"); - bool assignable=is_assignable(n) ? true : false; - SwigType *type = Getattr(n, "type"); - String *tm = Swig_typemap_lookup_new("globalin", n, iname, 0); - if (!tm && SwigType_isarray(type)) - assignable=false; - Delete(tm); + if (!addSymbol(iname, n)) + return SWIG_ERROR; - String *sname = assignable ? - Swig_name_wrapper(Swig_name_set(iname)) : - NewString("octave_set_immutable"); + String *tm; + Wrapper *getf = NewWrapper(); + Wrapper *setf = NewWrapper(); - Printf(s_global_tab, "{\"%s\",0,%s,%s,2},\n", iname, gname, sname); + String *getname = Swig_name_get(iname); + String *setname = Swig_name_set(iname); + + Printf(setf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", setname); + Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1)) return octave_value_list();", iname); + if (is_assignable(n)) { + Setattr(n, "wrap:name", setname); + if ((tm = Swig_typemap_lookup_new("varin", n, name, 0))) { + Replaceall(tm, "$source", "args(0)"); + Replaceall(tm, "$target", name); + Replaceall(tm, "$input", "args(0)"); + if (Getattr(n, "tmap:varin:implicitconv")) { + Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); + } + emit_action_code(n, setf, tm); + Delete(tm); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); + } + Append(setf->code, "fail:\n"); + Printf(setf->code, "return octave_value_list();\n"); + } else { + Printf(setf->code, "return octave_set_immutable(args,nargout);"); + } + Append(setf->code, "}\n"); + Wrapper_print(setf, f_wrappers); + + Setattr(n, "wrap:name", getname); + int addfail = 0; + Printf(getf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", getname); + Wrapper_add_local(getf, "obj", "octave_value obj"); + if ((tm = Swig_typemap_lookup_new("varout", n, name, 0))) { + Replaceall(tm, "$source", name); + Replaceall(tm, "$target", "obj"); + Replaceall(tm, "$result", "obj"); + addfail = emit_action_code(n, getf, tm); + Delete(tm); + } else { + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); + } + Append(getf->code, " return obj;\n"); + if (addfail) { + Append(getf->code, "fail:\n"); + Append(getf->code, " return octave_value_list();\n"); + } + Append(getf->code, "}\n"); + Wrapper_print(getf, f_wrappers); + + Printf(s_global_tab, "{\"%s\",0,_wrap_%s,_wrap_%s,2},\n", iname, getname, setname); - Delete(sname); - Delete(gname); return SWIG_OK; } @@ -400,8 +511,7 @@ public: Replaceall(tm, "$nsname", iname); Printf(f_init, "%s\n", tm); } else { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF,input_file,line_number, - "Unsupported constant value.\n"); + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } @@ -425,19 +535,29 @@ public: } virtual int classHandler(Node *n) { - have_constructor=0; - have_destructor=0; - constructor_name=0; + have_constructor = 0; + have_destructor = 0; + constructor_name = 0; class_name = Getattr(n, "sym:name"); if (!addSymbol(class_name, n)) return SWIG_ERROR; + // This is a bug, due to the fact that swig_type -> octave_class mapping + // is not 1-to-1. + static Hash *emitted = NewHash(); + String *mangled_classname = Swig_name_mangle(Getattr(n, "name")); + if (Getattr(emitted, mangled_classname)) { + Delete(mangled_classname); + return SWIG_NOWRAP; + } + Setattr(emitted, mangled_classname, "1"); + Delete(mangled_classname); + assert(!s_members_tab); s_members_tab = NewString(""); - Printv(s_members_tab, "static swig_octave_member swig_", class_name, - "_members[] = {\n", NIL); + Printv(s_members_tab, "static swig_octave_member swig_", class_name, "_members[] = {\n", NIL); Language::classHandler(n); @@ -447,24 +567,20 @@ public: String *wrap_class = NewStringf("&_wrap_class_%s", class_name); SwigType_remember_clientdata(t, wrap_class); - // * this is 1-to-n map : swig_type -> octave_class - int use_director = Swig_directorclass(n); if (use_director) { - String *disown_shadow=NewString(""); - Printf(disown_shadow,"static octave_value_list _wrap_disown_%s_shadow " - "(const octave_value_list& args, int nargout) {\n", class_name); - Printf(disown_shadow," if (args.length()!=1) {\n"); - Printf(disown_shadow," error(\"disown takes no arguments\");\n"); - Printf(disown_shadow," return octave_value_list();\n"); - Printf(disown_shadow," }\n"); - Printf(disown_shadow," _wrap_disown_%s (args, nargout);\n", class_name); - Printf(disown_shadow," return args;\n"); - Printf(disown_shadow,"}\n"); - Printv(f_wrappers,disown_shadow,NIL); + String *disown_shadow = NewString(""); + Printf(disown_shadow, "static octave_value_list _wrap_disown_%s_shadow " "(const octave_value_list& args, int nargout) {\n", class_name); + Printf(disown_shadow, " if (args.length()!=1) {\n"); + Printf(disown_shadow, " error(\"disown takes no arguments\");\n"); + Printf(disown_shadow, " return octave_value_list();\n"); + Printf(disown_shadow, " }\n"); + Printf(disown_shadow, " _wrap_disown_%s (args, nargout);\n", class_name); + Printf(disown_shadow, " return args;\n"); + Printf(disown_shadow, "}\n"); + Printv(f_wrappers, disown_shadow, NIL); Delete(disown_shadow); - Printf(s_members_tab, "{\"__disown\",_wrap_disown_%s_shadow,0,0,0},\n", - class_name); + Printf(s_members_tab, "{\"__disown\",_wrap_disown_%s_shadow,0,0,0},\n", class_name); } Printf(s_members_tab, "{0,0,0,0}\n};\n"); @@ -479,13 +595,12 @@ public: b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "name"); - if ((!bname) || GetFlag(b.item, "feature:ignore") || - (!Getattr(b.item, "module"))) { + if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { b = Next(b); continue; } - String* bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname))); + String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname))); Printf(base_class_names, "\"%s\",", bname_mangled); Printf(base_class, "0,"); b = Next(b); @@ -494,37 +609,30 @@ public: } } - Printv(f_wrappers, "static const char *swig_", class_name, - "_base_names[] = {", base_class_names, "0};\n", NIL); - Printv(f_wrappers, "static const swig_type_info *swig_", class_name, - "_base[] = {", base_class, "0};\n", NIL); - Printv(f_wrappers, "static swig_octave_class _wrap_class_", - class_name, " = {\"", class_name,"\", &SWIGTYPE", - SwigType_manglestr(t), ",", NIL); - Printv(f_wrappers, Swig_directorclass(n)?"1,":"0,", NIL); + Printv(f_wrappers, "static const char *swig_", class_name, "_base_names[] = {", base_class_names, "0};\n", NIL); + Printv(f_wrappers, "static const swig_type_info *swig_", class_name, "_base[] = {", base_class, "0};\n", NIL); + Printv(f_wrappers, "static swig_octave_class _wrap_class_", class_name, " = {\"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL); + Printv(f_wrappers, Swig_directorclass(n) ? "1," : "0,", NIL); if (have_constructor) { - String *cname=Swig_name_construct(constructor_name); - String *wcname=Swig_name_wrapper(cname); - Printf(f_wrappers,"%s,",wcname); + String *cname = Swig_name_construct(constructor_name); + String *wcname = Swig_name_wrapper(cname); + Printf(f_wrappers, "%s,", wcname); Delete(wcname); Delete(cname); - } - else + } else Printv(f_wrappers, "0", ",", NIL); if (have_destructor) Printv(f_wrappers, "_wrap_delete_", class_name, ",", NIL); else Printv(f_wrappers, "0", ",", NIL); - Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", - class_name, class_name, class_name); + Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", class_name, class_name, class_name); Delete(base_class); Delete(base_class_names); - Delete(wrap_class); Delete(t); Delete(s_members_tab); - s_members_tab=0; - class_name=0; + s_members_tab = 0; + class_name = 0; return SWIG_OK; } @@ -539,8 +647,8 @@ public: String *realname = iname ? iname : name; String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); - if (!Getattr(n,"sym:nextSibling")) - Printf(s_members_tab,"{\"%s\",%s,0,0,0},\n",realname,rname); + if (!Getattr(n, "sym:nextSibling")) + Printf(s_members_tab, "{\"%s\",%s,0,0,0},\n", realname, rname); Delete(rname); return SWIG_OK; @@ -552,23 +660,22 @@ public: assert(s_members_tab); assert(class_name); String *symname = Getattr(n, "sym:name"); - String *gname=Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name,symname))); - String *sname=GetFlag(n,"feature:immutable")? - NewString("octave_set_immutable"): - Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name,symname))); + String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + String *setname = GetFlag(n, "feature:immutable") ? + NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname))); assert(s_members_tab); - Printf(s_members_tab,"{\"%s\",0,%s,%s,0},\n",symname,gname,sname); + Printf(s_members_tab, "{\"%s\",0,%s,%s,0},\n", symname, getname, setname); - Delete(gname); - Delete(sname); + Delete(getname); + Delete(setname); return SWIG_OK; } virtual int constructorHandler(Node *n) { - have_constructor=1; + have_constructor = 1; if (!constructor_name) - constructor_name=NewString(Getattr(n,"sym:name")); + constructor_name = NewString(Getattr(n, "sym:name")); int use_director = Swig_directorclass(n); if (use_director) { @@ -593,7 +700,7 @@ public: } virtual int destructorHandler(Node *n) { - have_destructor=1; + have_destructor = 1; return Language::destructorHandler(n);; } @@ -607,8 +714,8 @@ public: String *realname = iname ? iname : name; String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); - if (!Getattr(n,"sym:nextSibling")) - Printf(s_members_tab,"{\"%s\",%s,0,0,1},\n",realname,rname); + if (!Getattr(n, "sym:nextSibling")) + Printf(s_members_tab, "{\"%s\",%s,0,0,1},\n", realname, rname); Delete(rname); return SWIG_OK; @@ -625,16 +732,15 @@ public: assert(s_members_tab); assert(class_name); String *symname = Getattr(n, "sym:name"); - String *gname=Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name,symname))); - String *sname=GetFlag(n,"feature:immutable")? - NewString("octave_set_immutable"): - Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name,symname))); + String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + String *setname = GetFlag(n, "feature:immutable") ? + NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname))); assert(s_members_tab); - Printf(s_members_tab,"{\"%s\",0,%s,%s,1},\n",symname,gname,sname); + Printf(s_members_tab, "{\"%s\",0,%s,%s,1},\n", symname, getname, setname); - Delete(gname); - Delete(sname); + Delete(getname); + Delete(setname); } return SWIG_OK; } @@ -679,9 +785,7 @@ public: String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(0, decl, classname, parms, 0, 0); call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s," - "\nSwig::Director(static_cast<%s*>(this)) { \n", - classname, target, call, basetype); + Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype); Append(w->def, "}\n"); Delete(target); Wrapper_print(w, f_directors); @@ -709,8 +813,7 @@ public: { Wrapper *w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :" - "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", - classname, classname, classname); + "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname); Append(w->def, "}\n"); Wrapper_print(w, f_directors); DelWrapper(w); @@ -907,9 +1010,9 @@ public: Wrapper_add_local(w, "args", "octave_value_list args"); Wrapper_add_local(w, "out", "octave_value_list out"); Wrapper_add_local(w, "idx", "std::list idx"); - Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n",method_name); + Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n", method_name); Printf(w->code, "idx.push_back(args);\n"); - Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n",outputs); + Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n", outputs); String *cleanup = NewString(""); String *outarg = NewString(""); @@ -917,10 +1020,9 @@ public: // marshal return value if (!is_void) { - Printf(w->code, "if (out.length()<%d) {\n",outputs); + Printf(w->code, "if (out.length()<%d) {\n", outputs); Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave " - "method %s.%s failed to return the required number " - "of arguments.\");\n", classname, method_name); + "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name); Printf(w->code, "}\n"); Setattr(n, "type", return_type); @@ -935,17 +1037,18 @@ public: char temp[24]; sprintf(temp, "out(%d)", idx); Replaceall(tm, "$input", temp); - // Replaceall(tm, "$argnum", temp); - Replaceall(tm, "$disown", - Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0"); + // Replaceall(tm, "$argnum", temp); + Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0"); + if (Getattr(n, "tmap:directorout:implicitconv")) { + Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); + } Replaceall(tm, "$result", "c_result"); Printv(w->code, tm, "\n", NIL); Delete(tm); } else { Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", - SwigType_str(return_type, 0), SwigType_namestr(c_classname), - SwigType_namestr(name)); + "Unable to use return type %s in director method %s::%s (skipping method).\n", + SwigType_str(return_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); status = SWIG_ERROR; } } @@ -998,7 +1101,6 @@ public: Delete(methodcall); Delete(extra_method_name); } - // emit the director method if (status == SWIG_OK) { if (!Getattr(n, "defaultargs")) { @@ -1007,7 +1109,6 @@ public: Printv(f_directors_h, inline_extra_method, NIL); } } - // clean up Delete(wrap_args); Delete(return_type); @@ -1036,4 +1137,3 @@ public: extern "C" Language *swig_octave(void) { return new OCTAVE(); } -