diff --git a/wrap/Module.cpp b/wrap/Module.cpp index b54a05e9d..3b4586e8d 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -76,7 +76,7 @@ Module::Module(const string& interfacePath, // The one with postfix 0 are used to reset the variables after parse. string methodName, methodName0; bool isConst, isConst0 = false; - ReturnValue retVal0, retVal; + ReturnValue retVal0(enable_verbose), retVal; Argument arg0, arg; ArgumentList args0, args; vector arg_dup; ///keep track of duplicates @@ -205,7 +205,8 @@ Module::Module(const string& interfacePath, ((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)] >> (className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >> !ch_p('*')[assign_a(retVal.isPtr1,true)]) | - (eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]); + (eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]); +// | str_p("void")[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::VOID)]; Rule returnType2_p = (basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) | @@ -218,7 +219,7 @@ Module::Module(const string& interfacePath, (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>') [assign_a(retVal.isPair,true)]; - Rule void_p = str_p("void")[assign_a(retVal.type1)]; + Rule void_p = str_p("void")[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::VOID)]; Rule returnType_p = void_p | returnType1_p | pair_p; diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index ab05762ae..c7902e60f 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -55,6 +55,12 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type // For a pair, store the returned pair so we do not evaluate the function twice file.oss << " " << return_type(false, pair) << " pairResult = " << result << ";\n"; + // sanity check values + if ((category1 != ReturnValue::CLASS) || (category1 != ReturnValue::EIGEN) || (category1 != ReturnValue::BASIS)) + throw invalid_argument("ReturnValue::wrap_result() FAILURE: invalid first member of pair "); + if ((category2 != ReturnValue::CLASS) || (category2 != ReturnValue::EIGEN) || (category2 != ReturnValue::BASIS)) + throw invalid_argument("ReturnValue::wrap_result() FAILURE: invalid second member of pair "); + // first return value in pair if (category1 == ReturnValue::CLASS) { // if we are going to make one string objCopy, ptrType; @@ -100,28 +106,33 @@ void ReturnValue::wrap_result(const string& result, FileWriter& file, const Type file.oss << " out[1] = wrap_shared_ptr(ret,\"" << matlabType2 << "\");\n"; } else file.oss << " out[1] = wrap< " << return_type(true,arg2) << " >(pairResult.second);\n"; + } else { // Not a pair + // sanity check values + if ((category1 != ReturnValue::CLASS) || (category1 != ReturnValue::EIGEN) || (category1 != ReturnValue::BASIS)) + throw invalid_argument("ReturnValue::wrap_result() FAILURE: return non-void flag "); + + if (category1 == ReturnValue::CLASS) { + string objCopy, ptrType; + ptrType = "Shared" + type1; + const bool isVirtual = typeAttributes.at(cppType1).isVirtual; + if(isVirtual) { + if(isPtr1) + objCopy = result; + else + objCopy = result + ".clone()"; + } else { + if(isPtr1) + objCopy = result; + else + objCopy = ptrType + "(new " + cppType1 + "(" + result + "))"; + } + file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n"; + } else if(isPtr1) { + file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(" << result << ");" << endl; + file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\");\n"; + } else if (matlabType1!="void") + file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n"; } - else if (category1 == ReturnValue::CLASS){ - string objCopy, ptrType; - ptrType = "Shared" + type1; - const bool isVirtual = typeAttributes.at(cppType1).isVirtual; - if(isVirtual) { - if(isPtr1) - objCopy = result; - else - objCopy = result + ".clone()"; - } else { - if(isPtr1) - objCopy = result; - else - objCopy = ptrType + "(new " + cppType1 + "(" + result + "))"; - } - file.oss << " out[0] = wrap_shared_ptr(" << objCopy << ",\"" << matlabType1 << "\", " << (isVirtual ? "true" : "false") << ");\n"; - } else if(isPtr1) { - file.oss << " Shared" << type1 <<"* ret = new Shared" << type1 << "(" << result << ");" << endl; - file.oss << " out[0] = wrap_shared_ptr(ret,\"" << matlabType1 << "\");\n"; - } else if (matlabType1!="void") - file.oss << " out[0] = wrap< " << return_type(true,arg1) << " >(" << result << ");\n"; } /* ************************************************************************* */ diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index 01949e323..ee681800b 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -21,15 +21,15 @@ namespace wrap { struct ReturnValue { typedef enum { - CLASS, - EIGEN, - BASIS, - VOID + CLASS = 0, + EIGEN = 1, + BASIS = 2, + VOID = 3 } return_category; ReturnValue(bool enable_verbosity = true) : verbose(enable_verbosity), isPtr1(false), isPtr2(false), - isPair(false), category1(VOID), category2(VOID) + isPair(false), category1(CLASS), category2(CLASS) {} bool verbose; diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index d9b0f9ea9..6c5469fac 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -87,12 +87,53 @@ TEST( wrap, parse_geometry ) { LONGS_EQUAL(3, module.classes.size()); - // check first class, Point2 { + // check first class + // class Point2 { + // Point2(); + // Point2(double x, double y); + // double x() const; + // double y() const; + // int dim() const; + // char returnChar() const; + // void argChar(char a) const; + // void argUChar(unsigned char a) const; + // VectorNotEigen vectorConfusion(); + // }; + Class cls = module.classes.at(0); EXPECT(assert_equal("Point2", cls.name)); EXPECT_LONGS_EQUAL(2, cls.constructor.args_list.size()); EXPECT_LONGS_EQUAL(7, cls.methods.size()); + + { + // char returnChar() const; + CHECK(cls.methods.find("returnChar") != cls.methods.end()); + Method m1 = cls.methods.find("returnChar")->second; + LONGS_EQUAL(1, m1.returnVals.size()); + EXPECT(assert_equal("char", m1.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1); // FAIL: gets 0 instead of 2 + EXPECT(!m1.returnVals.front().isPair); + EXPECT(assert_equal("returnChar", m1.name)); + LONGS_EQUAL(1, m1.argLists.size()); + EXPECT_LONGS_EQUAL(0, m1.argLists.front().size()); + EXPECT(m1.is_const_); + } + + { + // VectorNotEigen vectorConfusion(); + CHECK(cls.methods.find("vectorConfusion") != cls.methods.end()); + Method m1 = cls.methods.find("vectorConfusion")->second; + LONGS_EQUAL(1, m1.returnVals.size()); + EXPECT(assert_equal("VectorNotEigen", m1.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(ReturnValue::CLASS, m1.returnVals.front().category1); // FAIL: gets 1 instead of 0 + EXPECT(!m1.returnVals.front().isPair); + EXPECT(assert_equal("vectorConfusion", m1.name)); + LONGS_EQUAL(1, m1.argLists.size()); + EXPECT_LONGS_EQUAL(0, m1.argLists.front().size()); + EXPECT(!m1.is_const_); + } + EXPECT_LONGS_EQUAL(0, cls.static_methods.size()); EXPECT_LONGS_EQUAL(0, cls.namespaces.size()); } @@ -122,6 +163,7 @@ TEST( wrap, parse_geometry ) { Method m1 = cls.methods.find("norm")->second; LONGS_EQUAL(1, m1.returnVals.size()); EXPECT(assert_equal("double", m1.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(ReturnValue::BASIS, m1.returnVals.front().category1); // FAIL: gets 0 instead of 2 - defaulting to CLASS EXPECT(assert_equal("norm", m1.name)); LONGS_EQUAL(1, m1.argLists.size()); EXPECT_LONGS_EQUAL(0, m1.argLists.front().size()); @@ -141,8 +183,10 @@ TEST( wrap, parse_geometry ) { Method m2 = testCls.methods.find("return_pair")->second; LONGS_EQUAL(1, m2.returnVals.size()); EXPECT(m2.returnVals.front().isPair); - EXPECT(m2.returnVals.front().category1 == ReturnValue::EIGEN); - EXPECT(m2.returnVals.front().category2 == ReturnValue::EIGEN); + EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, m2.returnVals.front().category1); // FIXME: gets different large numbers - latest: 6152961 + EXPECT(assert_equal("Vector", m2.returnVals.front().type1)); + EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, m2.returnVals.front().category2); // FIXME: see above + EXPECT(assert_equal("Matrix", m2.returnVals.front().type2)); } // evaluate global functions