Adding tests and notes to investigate errors parsing return types

release/4.3a0
Alex Cunningham 2012-11-27 19:03:16 +00:00
parent 07aef470a0
commit 16ad77cb53
4 changed files with 88 additions and 32 deletions

View File

@ -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<string> 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;

View File

@ -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";
}
/* ************************************************************************* */

View File

@ -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;

View File

@ -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