diff --git a/wrap/Argument.cpp b/wrap/Argument.cpp index c196212ef..e01da3db3 100644 --- a/wrap/Argument.cpp +++ b/wrap/Argument.cpp @@ -30,25 +30,35 @@ void Argument::matlab_unwrap(ofstream& ofs, { ofs << " "; + string cppType = qualifiedType("::"); + string matlabType = qualifiedType(); + if (is_ptr) // A pointer: emit an "unwrap_shared_ptr" call which returns a pointer - ofs << "shared_ptr<" << type << "> " << name << " = unwrap_shared_ptr< "; + ofs << "shared_ptr<" << cppType << "> " << name << " = unwrap_shared_ptr< "; else if (is_ref) // A reference: emit an "unwrap_shared_ptr" call and de-reference the pointer - ofs << type << "& " << name << " = *unwrap_shared_ptr< "; + ofs << cppType << "& " << name << " = *unwrap_shared_ptr< "; else // Not a pointer or a reference: emit an "unwrap" call // unwrap is specified in matlab.h as a series of template specializations // that know how to unpack the expected MATLAB object // example: double tol = unwrap< double >(in[2]); // example: Vector v = unwrap< Vector >(in[1]); - ofs << type << " " << name << " = unwrap< "; + ofs << cppType << " " << name << " = unwrap< "; - ofs << type << " >(" << matlabName; - if (is_ptr || is_ref) ofs << ", \"" << type << "\""; + ofs << cppType << " >(" << matlabName; + if (is_ptr || is_ref) ofs << ", \"" << matlabType << "\""; ofs << ");" << endl; } +/* ************************************************************************* */ +string Argument::qualifiedType(const string& delim) { + string result; + BOOST_FOREACH(const string& ns, namespaces) result += ns + delim; + return result + type; +} + /* ************************************************************************* */ string ArgumentList::types() { string str; diff --git a/wrap/Argument.h b/wrap/Argument.h index 3ebfa505e..07c11a5cc 100644 --- a/wrap/Argument.h +++ b/wrap/Argument.h @@ -18,7 +18,7 @@ #pragma once #include -#include +#include namespace wrap { @@ -27,17 +27,20 @@ struct Argument { bool is_const, is_ref, is_ptr; std::string type; std::string name; + std::vector namespaces; Argument() : is_const(false), is_ref(false), is_ptr(false) { } + std::string qualifiedType(const std::string& delim = ""); // adds namespaces to type + /// MATLAB code generation, MATLAB to C++ void matlab_unwrap(std::ofstream& ofs, const std::string& matlabName); }; /// Argument list -struct ArgumentList: public std::list { - std::list args; +struct ArgumentList: public std::vector { + std::vector args; // why does it contain this? std::string types(); std::string signature(); std::string names(); diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 998f1992d..fdd550f5a 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -74,12 +74,18 @@ Module::Module(const string& interfacePath, Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')] - eigenType_p - basisType_p; + Rule namespace_name_p = lexeme_d[lower_p >> *(alnum_p | '_')]; + + Rule namespace_arg_p = namespace_name_p[push_back_a(arg.namespaces)] >> str_p("::"); + Rule classPtr_p = + *namespace_arg_p >> className_p [assign_a(arg.type)] >> ch_p('*') [assign_a(arg.is_ptr,true)]; Rule classRef_p = !str_p("const") [assign_a(arg.is_const,true)] >> + *namespace_arg_p >> className_p [assign_a(arg.type)] >> ch_p('&') [assign_a(arg.is_ref,true)]; @@ -95,7 +101,8 @@ Module::Module(const string& interfacePath, Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')]; Rule argument_p = - ((basisType_p[assign_a(arg.type)] | argEigenType_p | classRef_p | eigenRef_p | classPtr_p) >> name_p[assign_a(arg.name)]) + ((basisType_p[assign_a(arg.type)] | argEigenType_p | classRef_p | eigenRef_p | classPtr_p) + >> name_p[assign_a(arg.name)]) [push_back_a(args, arg)] [assign_a(arg,arg0)]; @@ -160,16 +167,14 @@ Module::Module(const string& interfacePath, *(functions_p | comments_p) >> str_p("};"))[assign_a(cls.namespaces, namespaces)][push_back_a(classes,cls)][assign_a(cls,cls0)]; - Rule namespace_name_p = lexeme_d[(upper_p | lower_p) >> *(alnum_p | '_')]; - - Rule namespace_p = str_p("namespace") >> + Rule namespace_def_p = str_p("namespace") >> namespace_name_p[push_back_a(namespaces)] >> ch_p('{') >> - *(class_p | namespace_p | comments_p) >> + *(class_p | namespace_def_p | comments_p) >> str_p("}///\\namespace") >> !namespace_name_p // end namespace, avoid confusion with classes [pop_a(namespaces)]; - Rule module_content_p = comments_p | class_p | namespace_p ; + Rule module_content_p = comments_p | class_p | namespace_def_p ; Rule module_p = *module_content_p >> !end_p; @@ -208,18 +213,19 @@ Module::Module(const string& interfacePath, } } +/* ************************************************************************* */ template void verifyArguments(const vector& validArgs, const vector& vt) { BOOST_FOREACH(const T& t, vt) { BOOST_FOREACH(Argument arg, t.args) { - if(std::find(validArgs.begin(), validArgs.end(), arg.type) + string fullType = arg.qualifiedType("::"); + if(std::find(validArgs.begin(), validArgs.end(), fullType) == validArgs.end()) - throw DependencyMissing(arg.type, t.name); + throw DependencyMissing(fullType, t.name); } } } - /* ************************************************************************* */ void Module::matlab_code(const string& toolboxPath, const string& nameSpace, @@ -269,7 +275,7 @@ void Module::matlab_code(const string& toolboxPath, BOOST_FOREACH(Class cls, classes) { make_ofs << cls.qualifiedName() << " "; //Create a list of parsed classes for dependency checking - validArgs.push_back(cls.name); + validArgs.push_back(cls.qualifiedName("::")); } make_ofs << "\n\n"; diff --git a/wrap/tests/expected_namespaces/Makefile b/wrap/tests/expected_namespaces/Makefile index 844bf9692..d15278938 100644 --- a/wrap/tests/expected_namespaces/Makefile +++ b/wrap/tests/expected_namespaces/Makefile @@ -25,8 +25,10 @@ ns2ClassA_afunction.$(MEXENDING): ns2ClassA_afunction.cpp $(MEX) $(mex_flags) ns2ClassA_afunction.cpp -output ns2ClassA_afunction @ns2ClassA/memberFunction.$(MEXENDING): @ns2ClassA/memberFunction.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: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) +ns2ClassA: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING) @ns2ClassA/nsArg.$(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 76cb43fbb..95b4633de 100644 --- a/wrap/tests/expected_namespaces/make_testNamespaces.m +++ b/wrap/tests/expected_namespaces/make_testNamespaces.m @@ -26,6 +26,7 @@ mex -O5 ns2ClassA_afunction.cpp cd @ns2ClassA mex -O5 memberFunction.cpp +mex -O5 nsArg.cpp %% ns2ns3ClassB cd(toolboxpath) diff --git a/wrap/tests/testNamespaces.h b/wrap/tests/testNamespaces.h index 5b46f99ac..f6b4efa95 100644 --- a/wrap/tests/testNamespaces.h +++ b/wrap/tests/testNamespaces.h @@ -20,6 +20,7 @@ class ClassA { ClassA(); static double afunction(); double memberFunction(); + int nsArg(const ns1::ClassB& arg); }; namespace ns3 {