diff --git a/wrap/Module.cpp b/wrap/Module.cpp index fdd550f5a..24257c96b 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -21,6 +21,7 @@ //#define BOOST_SPIRIT_DEBUG #include #include +#include #include #include @@ -52,7 +53,7 @@ Module::Module(const string& interfacePath, Method method0(enable_verbose), method(enable_verbose); StaticMethod static_method0(enable_verbose), static_method(enable_verbose); Class cls0(enable_verbose),cls(enable_verbose); - vector namespaces, namespaces_parent, namespaces_temp; + vector namespaces, namespaces_return; //---------------------------------------------------------------------------- // Grammar with actions that build the Class object. Actions are @@ -69,12 +70,15 @@ Module::Module(const string& interfacePath, Rule basisType_p = (str_p("string") | "bool" | "size_t" | "int" | "double"); + Rule keywords_p = + (str_p("const") | "static" | "namespace" | basisType_p); + Rule eigenType_p = (str_p("Vector") | "Matrix"); - Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - basisType_p; + Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - keywords_p; - Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')]; + Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')] - keywords_p; Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::"); @@ -116,15 +120,19 @@ Module::Module(const string& interfacePath, [push_back_a(cls.constructors, constructor)] [assign_a(constructor,constructor0)]; + Rule namespace_ret_p = namespace_name_p[push_back_a(namespaces_return)] >> str_p("::"); + Rule returnType1_p = (basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) | - ((className_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::CLASS)]) >> + ((*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)]); Rule returnType2_p = (basisType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::BASIS)]) | - ((className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >> + ((*namespace_ret_p)[assign_a(retVal.namespaces2, namespaces_return)][clear_a(namespaces_return)] + >> (className_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::CLASS)]) >> !ch_p('*') [assign_a(retVal.isPtr2,true)]) | (eigenType_p[assign_a(retVal.type2)][assign_a(retVal.category2, ReturnValue::EIGEN)]); diff --git a/wrap/ReturnValue.cpp b/wrap/ReturnValue.cpp index 9d8606c5b..c10c173d7 100644 --- a/wrap/ReturnValue.cpp +++ b/wrap/ReturnValue.cpp @@ -5,6 +5,8 @@ * @author Alex Cunningham */ +#include + #include "ReturnValue.h" #include "utilities.h" @@ -15,21 +17,43 @@ using namespace wrap; string ReturnValue::return_type(bool add_ptr, pairing p) { if (p==pair && isPair) { string str = "pair< " + - wrap::maybe_shared_ptr(add_ptr && isPtr1, type1) + ", " + - wrap::maybe_shared_ptr(add_ptr && isPtr2, type2) + " >"; + maybe_shared_ptr(add_ptr && isPtr1, qualifiedType1("::")) + ", " + + maybe_shared_ptr(add_ptr && isPtr2, qualifiedType2("::")) + " >"; return str; } else - return wrap::maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? type2 : type1); + return maybe_shared_ptr(add_ptr && isPtr1, (p==arg2)? qualifiedType2("::") : qualifiedType1("::")); +} + +/* ************************************************************************* */ +string ReturnValue::matlab_returnType() const { + return isPair? "[first,second]" : "result"; +} + +/* ************************************************************************* */ +string ReturnValue::qualifiedType1(const string& delim) { + string result; + BOOST_FOREACH(const string& ns, namespaces1) result += ns + delim; + return result + type1; +} + +/* ************************************************************************* */ +string ReturnValue::qualifiedType2(const string& delim) { + string result; + BOOST_FOREACH(const string& ns, namespaces2) result += ns + delim; + return result + type2; } /* ************************************************************************* */ void ReturnValue::wrap_result(std::ostream& ofs) { + string cppType1 = qualifiedType1("::"), matlabType1 = qualifiedType1(); + string cppType2 = qualifiedType2("::"), matlabType2 = qualifiedType2(); + if (isPair) { // first return value in pair if (isPtr1) // if we already have a pointer - ofs << " out[0] = wrap_shared_ptr(result.first,\"" << type1 << "\");\n"; + ofs << " out[0] = wrap_shared_ptr(result.first,\"" << matlabType1 << "\");\n"; else if (category1 == ReturnValue::CLASS) // if we are going to make one - ofs << " out[0] = wrap_shared_ptr(make_shared< " << type1 << " >(result.first),\"" << type1 << "\");\n"; + ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result.first),\"" << matlabType1 << "\");\n"; else // if basis type ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; @@ -37,14 +61,14 @@ void ReturnValue::wrap_result(std::ostream& ofs) { if (isPtr2) // if we already have a pointer ofs << " out[1] = wrap_shared_ptr(result.second,\"" << type2 << "\");\n"; else if (category2 == ReturnValue::CLASS) // if we are going to make one - ofs << " out[1] = wrap_shared_ptr(make_shared< " << type2 << " >(result.second),\"" << type2 << "\");\n"; + ofs << " out[1] = wrap_shared_ptr(make_shared< " << cppType2 << " >(result.second),\"" << matlabType2 << "\");\n"; else ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; } else if (isPtr1) ofs << " out[0] = wrap_shared_ptr(result,\"" << type1 << "\");\n"; else if (category1 == ReturnValue::CLASS) - ofs << " out[0] = wrap_shared_ptr(make_shared< " << type1 << " >(result),\"" << type1 << "\");\n"; + ofs << " out[0] = wrap_shared_ptr(make_shared< " << cppType1 << " >(result),\"" << matlabType1 << "\");\n"; else if (type1!="void") ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; } diff --git a/wrap/ReturnValue.h b/wrap/ReturnValue.h index c6d7864d3..ba606ad9c 100644 --- a/wrap/ReturnValue.h +++ b/wrap/ReturnValue.h @@ -7,6 +7,7 @@ * @author Alex Cunningham */ +#include #include #pragma once @@ -30,6 +31,7 @@ struct ReturnValue { bool verbose; std::string type1, type2; bool isPtr1, isPtr2, isPair; + std::vector namespaces1, namespaces2; return_category category1, category2; @@ -39,7 +41,10 @@ struct ReturnValue { std::string return_type(bool add_ptr, pairing p); - std::string matlab_returnType() const { return isPair? "[first,second]" : "result"; } + std::string qualifiedType1(const std::string& delim = ""); + std::string qualifiedType2(const std::string& delim = ""); + + std::string matlab_returnType() const; void wrap_result(std::ostream& ofs); diff --git a/wrap/tests/expected_namespaces/Makefile b/wrap/tests/expected_namespaces/Makefile index d15278938..4fe9b0655 100644 --- a/wrap/tests/expected_namespaces/Makefile +++ b/wrap/tests/expected_namespaces/Makefile @@ -27,8 +27,10 @@ ns2ClassA_afunction.$(MEXENDING): ns2ClassA_afunction.cpp $(MEX) $(mex_flags) @ns2ClassA/memberFunction.cpp -output @ns2ClassA/memberFunction @ns2ClassA/nsArg.$(MEXENDING): @ns2ClassA/nsArg.cpp $(MEX) $(mex_flags) @ns2ClassA/nsArg.cpp -output @ns2ClassA/nsArg +@ns2ClassA/nsReturn.$(MEXENDING): @ns2ClassA/nsReturn.cpp + $(MEX) $(mex_flags) @ns2ClassA/nsReturn.cpp -output @ns2ClassA/nsReturn -ns2ClassA: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) @ns2ClassA/nsArg.$(MEXENDING) +ns2ClassA: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) @ns2ClassA/nsArg.$(MEXENDING) @ns2ClassA/nsReturn.$(MEXENDING) # ns2ns3ClassB new_ns2ns3ClassB_.$(MEXENDING): new_ns2ns3ClassB_.cpp diff --git a/wrap/tests/expected_namespaces/make_testNamespaces.m b/wrap/tests/expected_namespaces/make_testNamespaces.m index 95b4633de..59d850c42 100644 --- a/wrap/tests/expected_namespaces/make_testNamespaces.m +++ b/wrap/tests/expected_namespaces/make_testNamespaces.m @@ -27,6 +27,7 @@ mex -O5 ns2ClassA_afunction.cpp cd @ns2ClassA mex -O5 memberFunction.cpp mex -O5 nsArg.cpp +mex -O5 nsReturn.cpp %% ns2ns3ClassB cd(toolboxpath) diff --git a/wrap/tests/testNamespaces.h b/wrap/tests/testNamespaces.h index f6b4efa95..f27a518c6 100644 --- a/wrap/tests/testNamespaces.h +++ b/wrap/tests/testNamespaces.h @@ -21,6 +21,7 @@ class ClassA { static double afunction(); double memberFunction(); int nsArg(const ns1::ClassB& arg); + ns2::ns3::ClassB nsReturn(double q); }; namespace ns3 {