diff --git a/wrap/Module.cpp b/wrap/Module.cpp index da481b9d5..efc45f187 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -82,14 +82,17 @@ Module::Module(const string& interfacePath, Rule basisType_p = (str_p("string") | "bool" | "size_t" | "int" | "double"); - Rule eigenType = - (str_p("Vector") | "Matrix")[assign_a(arg.type)] >> - !ch_p('*')[assign_a(arg.is_ptr,true)]; + Rule eigenType_p = + (str_p("Vector") | "Matrix"); + + Rule argEigenType = + eigenType_p[assign_a(arg.type)] >> + !ch_p('*')[assign_a(arg.is_ptr,true)]; Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')]; Rule argument_p = - ((basisType_p[assign_a(arg.type)] | eigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)]) + ((basisType_p[assign_a(arg.type)] | argEigenType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)]) [push_back_a(args, arg)] [assign_a(arg,arg0)]; @@ -102,19 +105,17 @@ Module::Module(const string& interfacePath, [push_back_a(cls.constructors, constructor)] [assign_a(constructor,constructor0)]; - Rule returnClass1_p = className_p [assign_a(retVal.returns_class_, true)]; - - Rule returnClass2_p = className_p [assign_a(retVal.returns_class2_, true)]; - Rule returnType1_p = - basisType_p[assign_a(retVal.returns_)] | - ((returnClass1_p | "Vector" | "Matrix")[assign_a(retVal.returns_)] >> - !ch_p('*') [assign_a(retVal.returns_ptr_,true)]); + (basisType_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::BASIS)]) | + (eigenType_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::EIGEN)]) | + (className_p[assign_a(retVal.returns_)][assign_a(retVal.return1, ReturnValue::CLASS)]) >> + !ch_p('*') [assign_a(retVal.returns_ptr_,true)]; Rule returnType2_p = - basisType_p[assign_a(retVal.returns2_)] | - ((returnClass2_p | "Vector" | "Matrix")[assign_a(retVal.returns2_)] >> - !ch_p('*') [assign_a(retVal.returns_ptr2_,true)]); + (basisType_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::BASIS)]) | + (eigenType_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::EIGEN)]) | + (className_p[assign_a(retVal.returns2_)][assign_a(retVal.return2, ReturnValue::CLASS)]) >> + !ch_p('*') [assign_a(retVal.returns_ptr2_,true)]; Rule pair_p = (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>') diff --git a/wrap/Module.h b/wrap/Module.h index e47057a63..a5aaad191 100644 --- a/wrap/Module.h +++ b/wrap/Module.h @@ -18,7 +18,7 @@ #pragma once #include -#include +#include #include "Class.h" @@ -29,7 +29,7 @@ namespace wrap { */ struct Module { std::string name; ///< module name - std::list classes; ///< list of classes + std::vector classes; ///< list of classes bool verbose_; ///< verbose flag /// constructor that parses interface file diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index 005cfea40..e7b87e0fa 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -16,7 +16,7 @@ string ReturnValue::return_type(bool add_ptr, pairing p) { if (p==pair && returns_pair_) { string str = "pair< " + wrap::maybe_shared_ptr(add_ptr && returns_ptr_, returns_) + ", " + - wrap::maybe_shared_ptr(add_ptr && returns_ptr_, returns2_) + " >"; + wrap::maybe_shared_ptr(add_ptr && returns_ptr2_, returns2_) + " >"; return str; } else return wrap::maybe_shared_ptr(add_ptr && returns_ptr_, (p==arg2)? returns2_ : returns_); @@ -26,20 +26,24 @@ string ReturnValue::return_type(bool add_ptr, pairing p) { void ReturnValue::wrap_result(std::ostream& ofs) { if (returns_pair_) { // first return value in pair - if (returns_ptr_) + if (returns_ptr_) // if we already have a pointer ofs << " out[0] = wrap_shared_ptr(result.first,\"" << returns_ << "\");\n"; - else + else if (return1 == ReturnValue::CLASS) // if we are going to make one + ofs << " out[0] = wrap_shared_ptr(make_shared< " << returns_ << " >(result.first),\"" << returns_ << "\");\n"; + else // if basis type ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; // second return value in pair - if (returns_ptr2_) + if (returns_ptr2_) // if we already have a pointer ofs << " out[1] = wrap_shared_ptr(result.second,\"" << returns2_ << "\");\n"; + else if (return2 == ReturnValue::CLASS) // if we are going to make one + ofs << " out[1] = wrap_shared_ptr(make_shared< " << returns2_ << " >(result.second),\"" << returns2_ << "\");\n"; else ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; } else if (returns_ptr_) ofs << " out[0] = wrap_shared_ptr(result,\"" << returns_ << "\");\n"; - else if (returns_class_) + else if (return1 == ReturnValue::CLASS) ofs << " out[0] = wrap_shared_ptr(make_shared< " << returns_ << " >(result),\"" << returns_ << "\");\n"; else if (returns_!="void") ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index 68c0fb6da..a7137054f 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -15,14 +15,23 @@ namespace wrap { struct ReturnValue { + typedef enum { + CLASS, + EIGEN, + BASIS, + VOID + } return_category; + ReturnValue(bool verbose = true) : verbose_(verbose), returns_ptr_(false), returns_ptr2_(false), - returns_pair_(false), returns_class_(false) + returns_pair_(false), return1(VOID), return2(VOID) {} bool verbose_; std::string returns_, returns2_; - bool returns_ptr_, returns_ptr2_, returns_pair_, returns_class_, returns_class2_; + bool returns_ptr_, returns_ptr2_, returns_pair_; + + return_category return1, return2; typedef enum { arg1, arg2, pair diff --git a/wrap/geometry.h b/wrap/geometry.h index f89b7f132..2faa21504 100644 --- a/wrap/geometry.h +++ b/wrap/geometry.h @@ -24,6 +24,8 @@ class Test { // another comment Test(); + pair return_pair (Vector v, Matrix A) const; // intentionally the first method + bool return_bool (bool value) const; // comment after a line! size_t return_size_t (size_t value) const; int return_int (int value) const; @@ -39,15 +41,15 @@ class Test { Vector return_vector2(Vector value) const; Matrix return_matrix2(Matrix value) const; - pair return_pair (Vector v, Matrix A) const; - bool return_field(const Test& t) const; Test* return_TestPtr(Test* value) const; + Test return_Test(Test* value) const; Point2* return_Point2Ptr(bool value) const; pair create_ptrs () const; + pair create_MixedPtrs () const; pair return_ptrs (Test* p1, Test* p2) const; void print() const; diff --git a/wrap/tests/expected/@Test/create_MixedPtrs.cpp b/wrap/tests/expected/@Test/create_MixedPtrs.cpp new file mode 100644 index 000000000..6e271486b --- /dev/null +++ b/wrap/tests/expected/@Test/create_MixedPtrs.cpp @@ -0,0 +1,11 @@ +// automatically generated by wrap on 2011-Dec-06 +#include +#include +void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("create_MixedPtrs",nargout,nargin-1,0); + shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); + pair< Test, shared_ptr > result = self->create_MixedPtrs(); + out[0] = wrap_shared_ptr(make_shared< Test >(result.first),"Test"); + out[1] = wrap_shared_ptr(result.second,"Test"); +} diff --git a/wrap/tests/expected/@Test/create_MixedPtrs.m b/wrap/tests/expected/@Test/create_MixedPtrs.m new file mode 100644 index 000000000..9062cabcb --- /dev/null +++ b/wrap/tests/expected/@Test/create_MixedPtrs.m @@ -0,0 +1,4 @@ +function [first,second] = create_MixedPtrs(obj) +% usage: obj.create_MixedPtrs() + error('need to compile create_MixedPtrs.cpp'); +end diff --git a/wrap/tests/expected/@Test/return_Test.cpp b/wrap/tests/expected/@Test/return_Test.cpp new file mode 100644 index 000000000..e14aecb89 --- /dev/null +++ b/wrap/tests/expected/@Test/return_Test.cpp @@ -0,0 +1,11 @@ +// automatically generated by wrap on 2011-Dec-06 +#include +#include +void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) +{ + checkArguments("return_Test",nargout,nargin-1,1); + shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); + shared_ptr value = unwrap_shared_ptr< Test >(in[1], "Test"); + Test result = self->return_Test(value); + out[0] = wrap_shared_ptr(make_shared< Test >(result),"Test"); +} diff --git a/wrap/tests/expected/@Test/return_Test.m b/wrap/tests/expected/@Test/return_Test.m new file mode 100644 index 000000000..01f4ec61b --- /dev/null +++ b/wrap/tests/expected/@Test/return_Test.m @@ -0,0 +1,4 @@ +function result = return_Test(obj,value) +% usage: obj.return_Test(value) + error('need to compile return_Test.cpp'); +end diff --git a/wrap/tests/expected/Makefile b/wrap/tests/expected/Makefile index 7249daaba..f839827e3 100644 --- a/wrap/tests/expected/Makefile +++ b/wrap/tests/expected/Makefile @@ -35,6 +35,8 @@ Point3: new_Point3_ddd.$(MEXENDING) Point3_staticFunction.$(MEXENDING) Point3_St # Test new_Test_.$(MEXENDING): new_Test_.cpp $(MEX) $(mex_flags) new_Test_.cpp -output new_Test_ +@Test/return_pair.$(MEXENDING): @Test/return_pair.cpp + $(MEX) $(mex_flags) @Test/return_pair.cpp -output @Test/return_pair @Test/return_bool.$(MEXENDING): @Test/return_bool.cpp $(MEX) $(mex_flags) @Test/return_bool.cpp -output @Test/return_bool @Test/return_size_t.$(MEXENDING): @Test/return_size_t.cpp @@ -53,22 +55,24 @@ new_Test_.$(MEXENDING): new_Test_.cpp $(MEX) $(mex_flags) @Test/return_vector2.cpp -output @Test/return_vector2 @Test/return_matrix2.$(MEXENDING): @Test/return_matrix2.cpp $(MEX) $(mex_flags) @Test/return_matrix2.cpp -output @Test/return_matrix2 -@Test/return_pair.$(MEXENDING): @Test/return_pair.cpp - $(MEX) $(mex_flags) @Test/return_pair.cpp -output @Test/return_pair @Test/return_field.$(MEXENDING): @Test/return_field.cpp $(MEX) $(mex_flags) @Test/return_field.cpp -output @Test/return_field @Test/return_TestPtr.$(MEXENDING): @Test/return_TestPtr.cpp $(MEX) $(mex_flags) @Test/return_TestPtr.cpp -output @Test/return_TestPtr +@Test/return_Test.$(MEXENDING): @Test/return_Test.cpp + $(MEX) $(mex_flags) @Test/return_Test.cpp -output @Test/return_Test @Test/return_Point2Ptr.$(MEXENDING): @Test/return_Point2Ptr.cpp $(MEX) $(mex_flags) @Test/return_Point2Ptr.cpp -output @Test/return_Point2Ptr @Test/create_ptrs.$(MEXENDING): @Test/create_ptrs.cpp $(MEX) $(mex_flags) @Test/create_ptrs.cpp -output @Test/create_ptrs +@Test/create_MixedPtrs.$(MEXENDING): @Test/create_MixedPtrs.cpp + $(MEX) $(mex_flags) @Test/create_MixedPtrs.cpp -output @Test/create_MixedPtrs @Test/return_ptrs.$(MEXENDING): @Test/return_ptrs.cpp $(MEX) $(mex_flags) @Test/return_ptrs.cpp -output @Test/return_ptrs @Test/print.$(MEXENDING): @Test/print.cpp $(MEX) $(mex_flags) @Test/print.cpp -output @Test/print -Test: new_Test_.$(MEXENDING) @Test/return_bool.$(MEXENDING) @Test/return_size_t.$(MEXENDING) @Test/return_int.$(MEXENDING) @Test/return_double.$(MEXENDING) @Test/return_string.$(MEXENDING) @Test/return_vector1.$(MEXENDING) @Test/return_matrix1.$(MEXENDING) @Test/return_vector2.$(MEXENDING) @Test/return_matrix2.$(MEXENDING) @Test/return_pair.$(MEXENDING) @Test/return_field.$(MEXENDING) @Test/return_TestPtr.$(MEXENDING) @Test/return_Point2Ptr.$(MEXENDING) @Test/create_ptrs.$(MEXENDING) @Test/return_ptrs.$(MEXENDING) @Test/print.$(MEXENDING) +Test: new_Test_.$(MEXENDING) @Test/return_pair.$(MEXENDING) @Test/return_bool.$(MEXENDING) @Test/return_size_t.$(MEXENDING) @Test/return_int.$(MEXENDING) @Test/return_double.$(MEXENDING) @Test/return_string.$(MEXENDING) @Test/return_vector1.$(MEXENDING) @Test/return_matrix1.$(MEXENDING) @Test/return_vector2.$(MEXENDING) @Test/return_matrix2.$(MEXENDING) @Test/return_field.$(MEXENDING) @Test/return_TestPtr.$(MEXENDING) @Test/return_Test.$(MEXENDING) @Test/return_Point2Ptr.$(MEXENDING) @Test/create_ptrs.$(MEXENDING) @Test/create_MixedPtrs.$(MEXENDING) @Test/return_ptrs.$(MEXENDING) @Test/print.$(MEXENDING) diff --git a/wrap/tests/expected/make_geometry.m b/wrap/tests/expected/make_geometry.m index 732f40fc9..d73022bab 100644 --- a/wrap/tests/expected/make_geometry.m +++ b/wrap/tests/expected/make_geometry.m @@ -31,6 +31,7 @@ cd(toolboxpath) mex -O5 new_Test_.cpp cd @Test +mex -O5 return_pair.cpp mex -O5 return_bool.cpp mex -O5 return_size_t.cpp mex -O5 return_int.cpp @@ -40,11 +41,12 @@ mex -O5 return_vector1.cpp mex -O5 return_matrix1.cpp mex -O5 return_vector2.cpp mex -O5 return_matrix2.cpp -mex -O5 return_pair.cpp mex -O5 return_field.cpp mex -O5 return_TestPtr.cpp +mex -O5 return_Test.cpp mex -O5 return_Point2Ptr.cpp mex -O5 create_ptrs.cpp +mex -O5 create_MixedPtrs.cpp mex -O5 return_ptrs.cpp mex -O5 print.cpp diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index 2040254ed..b80412891 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -55,7 +55,7 @@ TEST( wrap, parse ) { string path = topdir + "/wrap"; Module module(path.c_str(), "geometry",verbose); - EXPECT(module.classes.size()==3); + CHECK(module.classes.size()==3); // check second class, Point3 Class cls = *(++module.classes.begin()); @@ -81,6 +81,18 @@ TEST( wrap, parse ) { EXPECT(m1.name_=="norm"); EXPECT(m1.args_.size()==0); EXPECT(m1.is_const_); + + // Test class is the third one + Class testCls = module.classes.at(2); + EXPECT_LONGS_EQUAL( 1, testCls.constructors.size()); + EXPECT_LONGS_EQUAL(18, testCls.methods.size()); + EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size()); + +// pair return_pair (Vector v, Matrix A) const; + Method m2 = testCls.methods.front(); + EXPECT(m2.returnVal_.returns_pair_); + EXPECT(m2.returnVal_.return1 == ReturnValue::EIGEN); + EXPECT(m2.returnVal_.return2 == ReturnValue::EIGEN); } /* ************************************************************************* */ @@ -107,8 +119,10 @@ TEST( wrap, matlab_code ) { EXPECT(files_equal(path + "/tests/expected/@Test/Test.m" , "actual/@Test/Test.m" )); EXPECT(files_equal(path + "/tests/expected/@Test/return_string.cpp" , "actual/@Test/return_string.cpp" )); EXPECT(files_equal(path + "/tests/expected/@Test/return_pair.cpp" , "actual/@Test/return_pair.cpp" )); + EXPECT(files_equal(path + "/tests/expected/@Test/create_MixedPtrs.cpp", "actual/@Test/create_MixedPtrs.cpp")); EXPECT(files_equal(path + "/tests/expected/@Test/return_field.cpp" , "actual/@Test/return_field.cpp" )); EXPECT(files_equal(path + "/tests/expected/@Test/return_TestPtr.cpp", "actual/@Test/return_TestPtr.cpp")); + EXPECT(files_equal(path + "/tests/expected/@Test/return_Test.cpp" , "actual/@Test/return_Test.cpp" )); EXPECT(files_equal(path + "/tests/expected/@Test/return_Point2Ptr.cpp", "actual/@Test/return_Point2Ptr.cpp")); EXPECT(files_equal(path + "/tests/expected/@Test/return_ptrs.cpp" , "actual/@Test/return_ptrs.cpp" )); EXPECT(files_equal(path + "/tests/expected/@Test/print.m" , "actual/@Test/print.m" ));