Added codegen for namespace handling, examples exercising namespaces

release/4.3a0
Alex Cunningham 2011-12-08 20:51:13 +00:00
parent aa2eccbcb4
commit 48a2056020
36 changed files with 453 additions and 126 deletions

View File

@ -33,16 +33,19 @@ void Class::matlab_proxy(const string& classFile) {
if(!ofs) throw CantOpenFile(classFile);
if(verbose_) cerr << "generating " << classFile << endl;
// get the name of actual matlab object
string matlabName = qualifiedName();
// emit class proxy code
ofs << "classdef " << name << endl;
ofs << "classdef " << matlabName << endl;
ofs << " properties" << endl;
ofs << " self = 0" << endl;
ofs << " end" << endl;
ofs << " methods" << endl;
ofs << " function obj = " << name << "(varargin)" << endl;
ofs << " function obj = " << matlabName << "(varargin)" << endl;
BOOST_FOREACH(Constructor c, constructors)
c.matlab_proxy_fragment(ofs,name);
ofs << " if nargin ~= 13 && obj.self == 0, error('" << name << " constructor failed'); end" << endl;
c.matlab_proxy_fragment(ofs,matlabName);
ofs << " if nargin ~= 13 && obj.self == 0, error('" << matlabName << " constructor failed'); end" << endl;
ofs << " end" << endl;
ofs << " function display(obj), obj.print(''); end" << endl;
ofs << " function disp(obj), obj.display; end" << endl;
@ -56,24 +59,26 @@ void Class::matlab_proxy(const string& classFile) {
/* ************************************************************************* */
void Class::matlab_constructors(const string& toolboxPath,const string& nameSpace) {
BOOST_FOREACH(Constructor c, constructors) {
c.matlab_mfile (toolboxPath, name);
c.matlab_wrapper(toolboxPath, name, nameSpace);
c.matlab_mfile (toolboxPath, qualifiedName());
c.matlab_wrapper(toolboxPath, qualifiedName("::"), qualifiedName(), nameSpace);
}
}
/* ************************************************************************* */
void Class::matlab_methods(const string& classPath, const string& nameSpace) {
string matlabName = qualifiedName(), cppName = qualifiedName("::");
BOOST_FOREACH(Method m, methods) {
m.matlab_mfile (classPath);
m.matlab_wrapper(classPath, name, nameSpace);
m.matlab_wrapper(classPath, name, cppName, matlabName, nameSpace);
}
}
/* ************************************************************************* */
void Class::matlab_static_methods(const string& toolboxPath, const string& nameSpace) {
string matlabName = qualifiedName(), cppName = qualifiedName("::");
BOOST_FOREACH(StaticMethod& m, static_methods) {
m.matlab_mfile (toolboxPath, name);
m.matlab_wrapper(toolboxPath, name, nameSpace);
m.matlab_mfile (toolboxPath, qualifiedName());
m.matlab_wrapper(toolboxPath, name, matlabName, cppName, nameSpace);
}
}
@ -83,13 +88,14 @@ void Class::matlab_make_fragment(ofstream& ofs,
const string& mexFlags)
{
string mex = "mex " + mexFlags + " ";
string matlabClassName = qualifiedName();
BOOST_FOREACH(Constructor c, constructors)
ofs << mex << c.matlab_wrapper_name(name) << ".cpp" << endl;
ofs << mex << c.matlab_wrapper_name(matlabClassName) << ".cpp" << endl;
BOOST_FOREACH(StaticMethod sm, static_methods)
ofs << mex << name + "_" + sm.name << ".cpp" << endl;
ofs << endl << "cd @" << name << endl;
ofs << mex << matlabClassName + "_" + sm.name << ".cpp" << endl;
ofs << endl << "cd @" << matlabClassName << endl;
BOOST_FOREACH(Method m, methods)
ofs << mex << m.name_ << ".cpp" << endl;
ofs << mex << m.name << ".cpp" << endl;
ofs << endl;
}
@ -108,18 +114,20 @@ void Class::makefile_fragment(ofstream& ofs) {
//
// Point2: new_Point2_.$(MEXENDING) new_Point2_dd.$(MEXENDING) @Point2/x.$(MEXENDING) @Point2/y.$(MEXENDING) @Point2/dim.$(MEXENDING)
string matlabName = qualifiedName();
// collect names
vector<string> file_names;
BOOST_FOREACH(Constructor c, constructors) {
string file_base = c.matlab_wrapper_name(name);
string file_base = c.matlab_wrapper_name(matlabName);
file_names.push_back(file_base);
}
BOOST_FOREACH(StaticMethod c, static_methods) {
string file_base = name + "_" + c.name;
string file_base = matlabName + "_" + c.name;
file_names.push_back(file_base);
}
BOOST_FOREACH(Method c, methods) {
string file_base = "@" + name + "/" + c.name_;
string file_base = "@" + matlabName + "/" + c.name;
file_names.push_back(file_base);
}
@ -129,7 +137,7 @@ void Class::makefile_fragment(ofstream& ofs) {
}
// class target
ofs << "\n" << name << ": ";
ofs << "\n" << matlabName << ": ";
BOOST_FOREACH(const string& file_base, file_names) {
ofs << file_base << ".$(MEXENDING) ";
}
@ -137,3 +145,11 @@ void Class::makefile_fragment(ofstream& ofs) {
}
/* ************************************************************************* */
string Class::qualifiedName(const string& delim) const {
string result;
BOOST_FOREACH(const string& ns, namespaces)
result += ns + delim;
return result + name;
}
/* ************************************************************************* */

View File

@ -18,7 +18,6 @@
#pragma once
#include <string>
#include <list>
#include "Constructor.h"
#include "Method.h"
@ -33,9 +32,9 @@ struct Class {
// Then the instance variables are set directly by the Module constructor
std::string name; ///< Class name
std::list<Constructor> constructors; ///< Class constructors
std::list<Method> methods; ///< Class methods
std::list<StaticMethod> static_methods; ///< Static methods
std::vector<Constructor> constructors; ///< Class constructors
std::vector<Method> methods; ///< Class methods
std::vector<StaticMethod> static_methods; ///< Static methods
std::vector<std::string> namespaces; ///< Stack of namespaces
bool verbose_; ///< verbose flag
@ -51,6 +50,7 @@ struct Class {
const std::string& toolboxPath,
const std::string& mexFlags); ///< emit make fragment for global make script
void makefile_fragment(std::ofstream& ofs); ///< emit makefile fragment
std::string qualifiedName(const std::string& delim = "") const; ///< creates a namespace-qualified name, optional delimiter
};
} // \namespace wrap

View File

@ -45,22 +45,22 @@ void Constructor::matlab_proxy_fragment(ofstream& ofs, const string& className)
}
/* ************************************************************************* */
void Constructor::matlab_mfile(const string& toolboxPath, const string& className) {
void Constructor::matlab_mfile(const string& toolboxPath, const string& qualifiedMatlabName) {
string name = matlab_wrapper_name(className);
string matlabName = matlab_wrapper_name(qualifiedMatlabName);
// open destination m-file
string wrapperFile = toolboxPath + "/" + name + ".m";
string wrapperFile = toolboxPath + "/" + matlabName + ".m";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
if(verbose_) cerr << "generating " << wrapperFile << endl;
// generate code
wrap::emit_header_comment(ofs, "%");
ofs << "function result = " << name << "(obj";
ofs << "function result = " << matlabName << "(obj";
if (args.size()) ofs << "," << args.names();
ofs << ")" << endl;
ofs << " error('need to compile " << name << ".cpp');" << endl;
ofs << " error('need to compile " << matlabName << ".cpp');" << endl;
ofs << "end" << endl;
// close file
@ -69,14 +69,15 @@ void Constructor::matlab_mfile(const string& toolboxPath, const string& classNam
/* ************************************************************************* */
void Constructor::matlab_wrapper(const string& toolboxPath,
const string& className,
const string& cppClassName,
const string& matlabClassName,
const string& nameSpace)
{
string name = matlab_wrapper_name(className);
string matlabName = matlab_wrapper_name(matlabClassName);
// open destination wrapperFile
string wrapperFile = toolboxPath + "/" + name + ".cpp";
string wrapperFile = toolboxPath + "/" + matlabName + ".cpp";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
if(verbose_) cerr << "generating " << wrapperFile << endl;
@ -84,14 +85,14 @@ void Constructor::matlab_wrapper(const string& toolboxPath,
// generate code
wrap::emit_header_comment(ofs, "//");
ofs << "#include <wrap/matlab.h>" << endl;
ofs << "#include <" << className << ".h>" << endl;
ofs << "#include <" << name << ".h>" << endl;
if (!nameSpace.empty()) ofs << "using namespace " << nameSpace << ";" << endl;
ofs << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl;
ofs << "{" << endl;
ofs << " checkArguments(\"" << name << "\",nargout,nargin," << args.size() << ");" << endl;
ofs << " checkArguments(\"" << matlabName << "\",nargout,nargin," << args.size() << ");" << endl;
args.matlab_unwrap(ofs); // unwrap arguments
ofs << " " << className << "* self = new " << className << "(" << args.names() << ");" << endl;
ofs << " out[0] = wrap_constructed(self,\"" << className << "\");" << endl;
ofs << " " << cppClassName << "* self = new " << cppClassName << "(" << args.names() << ");" << endl; // need qualified name, delim: "::"
ofs << " out[0] = wrap_constructed(self,\"" << matlabClassName << "\");" << endl; // need matlab qualified name
ofs << "}" << endl;
// close file

View File

@ -34,6 +34,7 @@ struct Constructor {
// Then the instance variables are set directly by the Module constructor
ArgumentList args;
std::string name;
bool verbose_;
// MATLAB code generation
@ -48,11 +49,13 @@ struct Constructor {
/// m-file
void matlab_mfile(const std::string& toolboxPath,
const std::string& className);
const std::string& qualifiedMatlabName);
/// wrapper
void matlab_wrapper(const std::string& toolboxPath,
const std::string& className, const std::string& nameSpace);
const std::string& cppClassName,
const std::string& matlabClassName,
const std::string& nameSpace);
};
} // \namespace wrap

View File

@ -29,18 +29,18 @@ using namespace wrap;
void Method::matlab_mfile(const string& classPath) {
// open destination m-file
string wrapperFile = classPath + "/" + name_ + ".m";
string wrapperFile = classPath + "/" + name + ".m";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
if(verbose_) cerr << "generating " << wrapperFile << endl;
// generate code
string returnType = returnVal_.matlab_returnType();
ofs << "function " << returnType << " = " << name_ << "(obj";
if (args_.size()) ofs << "," << args_.names();
string returnType = returnVal.matlab_returnType();
ofs << "function " << returnType << " = " << name << "(obj";
if (args.size()) ofs << "," << args.names();
ofs << ")" << endl;
ofs << "% usage: obj." << name_ << "(" << args_.names() << ")" << endl;
ofs << " error('need to compile " << name_ << ".cpp');" << endl;
ofs << "% usage: obj." << name << "(" << args.names() << ")" << endl;
ofs << " error('need to compile " << name << ".cpp');" << endl;
ofs << "end" << endl;
// close file
@ -50,10 +50,12 @@ void Method::matlab_mfile(const string& classPath) {
/* ************************************************************************* */
void Method::matlab_wrapper(const string& classPath,
const string& className,
const string& cppClassName,
const string& matlabClassName,
const string& nameSpace)
{
// open destination wrapperFile
string wrapperFile = classPath + "/" + name_ + ".cpp";
string wrapperFile = classPath + "/" + name + ".cpp";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
if(verbose_) cerr << "generating " << wrapperFile << endl;
@ -74,26 +76,26 @@ void Method::matlab_wrapper(const string& classPath,
// check arguments
// extra argument obj -> nargin-1 is passed !
// example: checkArguments("equals",nargout,nargin-1,2);
ofs << " checkArguments(\"" << name_ << "\",nargout,nargin-1," << args_.size() << ");\n";
ofs << " checkArguments(\"" << name << "\",nargout,nargin-1," << args.size() << ");\n";
// get class pointer
// example: shared_ptr<Test> = unwrap_shared_ptr< Test >(in[0], "Test");
ofs << " shared_ptr<" << className << "> self = unwrap_shared_ptr< " << className
<< " >(in[0],\"" << className << "\");" << endl;
ofs << " shared_ptr<" << cppClassName << "> self = unwrap_shared_ptr< " << cppClassName
<< " >(in[0],\"" << matlabClassName << "\");" << endl;
// unwrap arguments, see Argument.cpp
args_.matlab_unwrap(ofs,1);
args.matlab_unwrap(ofs,1);
// call method
// example: bool result = self->return_field(t);
ofs << " ";
if (returnVal_.type1!="void")
ofs << returnVal_.return_type(true,ReturnValue::pair) << " result = ";
ofs << "self->" << name_ << "(" << args_.names() << ");\n";
if (returnVal.type1!="void")
ofs << returnVal.return_type(true,ReturnValue::pair) << " result = ";
ofs << "self->" << name << "(" << args.names() << ");\n";
// wrap result
// example: out[0]=wrap<bool>(result);
returnVal_.wrap_result(ofs);
returnVal.wrap_result(ofs);
// finish
ofs << "}\n";

View File

@ -35,16 +35,18 @@ struct Method {
// Then the instance variables are set directly by the Module constructor
bool verbose_;
bool is_const_;
std::string name_;
ArgumentList args_;
ReturnValue returnVal_;
std::string name;
ArgumentList args;
ReturnValue returnVal;
// MATLAB code generation
// classPath is class directory, e.g., ../matlab/@Point2
void matlab_mfile(const std::string& classPath); ///< m-file
void matlab_wrapper(const std::string& classPath,
const std::string& className, const std::string& nameSpace); ///< wrapper
const std::string& className,
const std::string& cppClassName,
const std::string& matlabClassname,const std::string& nameSpace); ///< wrapper
};
} // \namespace wrap

View File

@ -104,6 +104,7 @@ Module::Module(const string& interfacePath,
Rule constructor_p =
(className_p >> '(' >> argumentList_p >> ')' >> ';' >> !comments_p)
[assign_a(constructor.args,args)]
[assign_a(constructor.name,cls.name)]
[assign_a(args,args0)]
[push_back_a(cls.constructors, constructor)]
[assign_a(constructor,constructor0)];
@ -131,12 +132,12 @@ Module::Module(const string& interfacePath,
Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')];
Rule method_p =
(returnType_p >> methodName_p[assign_a(method.name_)] >>
(returnType_p >> methodName_p[assign_a(method.name)] >>
'(' >> argumentList_p >> ')' >>
!str_p("const")[assign_a(method.is_const_,true)] >> ';' >> *comments_p)
[assign_a(method.args_,args)]
[assign_a(method.args,args)]
[assign_a(args,args0)]
[assign_a(method.returnVal_,retVal)]
[assign_a(method.returnVal,retVal)]
[assign_a(retVal,retVal0)]
[push_back_a(cls.methods, method)]
[assign_a(method,method0)];
@ -165,7 +166,7 @@ Module::Module(const string& interfacePath,
namespace_name_p[push_back_a(namespaces)]
>> ch_p('{') >>
*(class_p | namespace_p | comments_p) >>
str_p("}///\\namespace") // end namespace, avoid confusion with classes
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 ;
@ -207,6 +208,18 @@ Module::Module(const string& interfacePath,
}
}
template<class T>
void verifyArguments(const vector<string>& validArgs, const vector<T>& vt) {
BOOST_FOREACH(const T& t, vt) {
BOOST_FOREACH(Argument arg, t.args) {
if(std::find(validArgs.begin(), validArgs.end(), arg.type)
== validArgs.end())
throw DependencyMissing(arg.type, t.name);
}
}
}
/* ************************************************************************* */
void Module::matlab_code(const string& toolboxPath,
const string& nameSpace,
@ -254,60 +267,40 @@ void Module::matlab_code(const string& toolboxPath,
// add 'all' to Makefile
make_ofs << "all: ";
BOOST_FOREACH(Class cls, classes) {
make_ofs << cls.name << " ";
make_ofs << cls.qualifiedName() << " ";
//Create a list of parsed classes for dependency checking
validArgs.push_back(cls.name);
}
make_ofs << "\n\n";
// generate proxy classes and wrappers
BOOST_FOREACH(Class cls, classes) {
// create directory if needed
string classPath = toolboxPath + "/@" + cls.name;
string classPath = toolboxPath + "/@" + cls.qualifiedName();
string installCmd = "install -d " + classPath;
system(installCmd.c_str());
// create proxy class
string classFile = classPath + "/" + cls.name + ".m";
string classFile = classPath + "/" + cls.qualifiedName() + ".m";
cls.matlab_proxy(classFile);
// verify all of the function arguments
verifyArguments<Constructor>(validArgs, cls.constructors);
verifyArguments<StaticMethod>(validArgs, cls.static_methods);
verifyArguments<Method>(validArgs, cls.methods);
// create constructor and method wrappers
BOOST_FOREACH(Constructor con, cls.constructors) {
BOOST_FOREACH(Argument arg, con.args) {
if(std::find(validArgs.begin(), validArgs.end(), arg.type)
== validArgs.end())
throw DependencyMissing(arg.type, cls.name);
}
}
cls.matlab_constructors(toolboxPath,nameSpace);
BOOST_FOREACH(StaticMethod stMth, cls.static_methods) {
BOOST_FOREACH(Argument arg, stMth.args) {
if(std::find(validArgs.begin(), validArgs.end(), arg.type)
== validArgs.end())
throw DependencyMissing(arg.type, stMth.name);
}
}
cls.matlab_static_methods(toolboxPath,nameSpace);
BOOST_FOREACH(Method mth, cls.methods) {
BOOST_FOREACH(Argument arg, mth.args_) {
if(std::find(validArgs.begin(), validArgs.end(), arg.type)
== validArgs.end())
throw DependencyMissing(arg.type, mth.name_);
}
}
cls.matlab_methods(classPath,nameSpace);
// add lines to make m-file
ofs << "%% " << cls.name << endl;
ofs << "%% " << cls.qualifiedName() << endl;
ofs << "cd(toolboxpath)" << endl;
cls.matlab_make_fragment(ofs, toolboxPath, mexFlags);
// add section to the (actual) make file
make_ofs << "# " << cls.name << endl;
make_ofs << "# " << cls.qualifiedName() << endl;
cls.makefile_fragment(make_ofs);
}
@ -320,7 +313,7 @@ void Module::matlab_code(const string& toolboxPath,
make_ofs << "\n\nclean: \n";
make_ofs << "\trm -rf *.$(MEXENDING)\n";
BOOST_FOREACH(Class cls, classes)
make_ofs << "\trm -rf @" << cls.name << "/*.$(MEXENDING)\n";
make_ofs << "\trm -rf @" << cls.qualifiedName() << "/*.$(MEXENDING)\n";
// finish Makefile
make_ofs << "\n" << endl;

View File

@ -49,11 +49,11 @@ void StaticMethod::matlab_mfile(const string& toolboxPath, const string& classNa
}
/* ************************************************************************* */
void StaticMethod::matlab_wrapper(const string& toolboxPath,
const string& className, const string& nameSpace)
void StaticMethod::matlab_wrapper(const string& toolboxPath, const string& className,
const string& matlabClassName, const string& cppClassName, const string& nameSpace)
{
// open destination wrapperFile
string full_name = className + "_" + name;
string full_name = matlabClassName + "_" + name;
string wrapperFile = toolboxPath + "/" + full_name + ".cpp";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
@ -84,7 +84,7 @@ void StaticMethod::matlab_wrapper(const string& toolboxPath,
// call method with default type
if (returnVal.type1!="void")
ofs << returnVal.return_type(true,ReturnValue::pair) << " result = ";
ofs << className << "::" << name << "(" << args.names() << ");\n";
ofs << cppClassName << "::" << name << "(" << args.names() << ");\n";
// wrap result
// example: out[0]=wrap<bool>(result);

View File

@ -46,7 +46,8 @@ struct StaticMethod {
void matlab_mfile(const std::string& toolboxPath, const std::string& className); ///< m-file
void matlab_wrapper(const std::string& toolboxPath,
const std::string& className, const std::string& nameSpace); ///< wrapper
const std::string& className, const std::string& matlabClassName,
const std::string& cppClassName, const std::string& nameSpace); ///< cpp wrapper
};
} // \namespace wrap

View File

@ -0,0 +1,13 @@
classdef ClassD
properties
self = 0
end
methods
function obj = ClassD(varargin)
if nargin == 0, obj.self = new_ClassD_(); end
if nargin ~= 13 && obj.self == 0, error('ClassD constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,13 @@
classdef ns1ClassA
properties
self = 0
end
methods
function obj = ns1ClassA(varargin)
if nargin == 0, obj.self = new_ns1ClassA_(); end
if nargin ~= 13 && obj.self == 0, error('ns1ClassA constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,13 @@
classdef ns1ClassB
properties
self = 0
end
methods
function obj = ns1ClassB(varargin)
if nargin == 0, obj.self = new_ns1ClassB_(); end
if nargin ~= 13 && obj.self == 0, error('ns1ClassB constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,10 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassA.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("memberFunction",nargout,nargin-1,0);
shared_ptr<ns2::ClassA> self = unwrap_shared_ptr< ns2::ClassA >(in[0],"ns2ClassA");
double result = self->memberFunction();
out[0] = wrap< double >(result);
}

View File

@ -0,0 +1,4 @@
function result = memberFunction(obj)
% usage: obj.memberFunction()
error('need to compile memberFunction.cpp');
end

View File

@ -0,0 +1,13 @@
classdef ns2ClassA
properties
self = 0
end
methods
function obj = ns2ClassA(varargin)
if nargin == 0, obj.self = new_ns2ClassA_(); end
if nargin ~= 13 && obj.self == 0, error('ns2ClassA constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,13 @@
classdef ns2ClassC
properties
self = 0
end
methods
function obj = ns2ClassC(varargin)
if nargin == 0, obj.self = new_ns2ClassC_(); end
if nargin ~= 13 && obj.self == 0, error('ns2ClassC constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,13 @@
classdef ns2ns3ClassB
properties
self = 0
end
methods
function obj = ns2ns3ClassB(varargin)
if nargin == 0, obj.self = new_ns2ns3ClassB_(); end
if nargin ~= 13 && obj.self == 0, error('ns2ns3ClassB constructor failed'); end
end
function display(obj), obj.print(''); end
function disp(obj), obj.display; end
end
end

View File

@ -0,0 +1,60 @@
# automatically generated by wrap on 2011-Dec-08
MEX = mex
MEXENDING = mexa64
mex_flags = -O5
all: ns1ClassA ns1ClassB ns2ClassA ns2ns3ClassB ns2ClassC ClassD
# ns1ClassA
new_ns1ClassA_.$(MEXENDING): new_ns1ClassA_.cpp
$(MEX) $(mex_flags) new_ns1ClassA_.cpp -output new_ns1ClassA_
ns1ClassA: new_ns1ClassA_.$(MEXENDING)
# ns1ClassB
new_ns1ClassB_.$(MEXENDING): new_ns1ClassB_.cpp
$(MEX) $(mex_flags) new_ns1ClassB_.cpp -output new_ns1ClassB_
ns1ClassB: new_ns1ClassB_.$(MEXENDING)
# ns2ClassA
new_ns2ClassA_.$(MEXENDING): new_ns2ClassA_.cpp
$(MEX) $(mex_flags) new_ns2ClassA_.cpp -output new_ns2ClassA_
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: new_ns2ClassA_.$(MEXENDING) ns2ClassA_afunction.$(MEXENDING) @ns2ClassA/memberFunction.$(MEXENDING)
# ns2ns3ClassB
new_ns2ns3ClassB_.$(MEXENDING): new_ns2ns3ClassB_.cpp
$(MEX) $(mex_flags) new_ns2ns3ClassB_.cpp -output new_ns2ns3ClassB_
ns2ns3ClassB: new_ns2ns3ClassB_.$(MEXENDING)
# ns2ClassC
new_ns2ClassC_.$(MEXENDING): new_ns2ClassC_.cpp
$(MEX) $(mex_flags) new_ns2ClassC_.cpp -output new_ns2ClassC_
ns2ClassC: new_ns2ClassC_.$(MEXENDING)
# ClassD
new_ClassD_.$(MEXENDING): new_ClassD_.cpp
$(MEX) $(mex_flags) new_ClassD_.cpp -output new_ClassD_
ClassD: new_ClassD_.$(MEXENDING)
clean:
rm -rf *.$(MEXENDING)
rm -rf @ns1ClassA/*.$(MEXENDING)
rm -rf @ns1ClassB/*.$(MEXENDING)
rm -rf @ns2ClassA/*.$(MEXENDING)
rm -rf @ns2ns3ClassB/*.$(MEXENDING)
rm -rf @ns2ClassC/*.$(MEXENDING)
rm -rf @ClassD/*.$(MEXENDING)

View File

@ -0,0 +1,50 @@
% automatically generated by wrap on 2011-Dec-08
echo on
toolboxpath = mfilename('fullpath');
delims = find(toolboxpath == '/');
toolboxpath = toolboxpath(1:(delims(end)-1));
clear delims
addpath(toolboxpath);
%% ns1ClassA
cd(toolboxpath)
mex -O5 new_ns1ClassA_.cpp
cd @ns1ClassA
%% ns1ClassB
cd(toolboxpath)
mex -O5 new_ns1ClassB_.cpp
cd @ns1ClassB
%% ns2ClassA
cd(toolboxpath)
mex -O5 new_ns2ClassA_.cpp
mex -O5 ns2ClassA_afunction.cpp
cd @ns2ClassA
mex -O5 memberFunction.cpp
%% ns2ns3ClassB
cd(toolboxpath)
mex -O5 new_ns2ns3ClassB_.cpp
cd @ns2ns3ClassB
%% ns2ClassC
cd(toolboxpath)
mex -O5 new_ns2ClassC_.cpp
cd @ns2ClassC
%% ClassD
cd(toolboxpath)
mex -O5 new_ClassD_.cpp
cd @ClassD
cd(toolboxpath)
echo off

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassD.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ClassD_",nargout,nargin,0);
ClassD* self = new ClassD();
out[0] = wrap_constructed(self,"ClassD");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ClassD_(obj)
error('need to compile new_ClassD_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassA.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ns1ClassA_",nargout,nargin,0);
ns1::ClassA* self = new ns1::ClassA();
out[0] = wrap_constructed(self,"ns1ClassA");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ns1ClassA_(obj)
error('need to compile new_ns1ClassA_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassB.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ns1ClassB_",nargout,nargin,0);
ns1::ClassB* self = new ns1::ClassB();
out[0] = wrap_constructed(self,"ns1ClassB");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ns1ClassB_(obj)
error('need to compile new_ns1ClassB_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassA.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ns2ClassA_",nargout,nargin,0);
ns2::ClassA* self = new ns2::ClassA();
out[0] = wrap_constructed(self,"ns2ClassA");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ns2ClassA_(obj)
error('need to compile new_ns2ClassA_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassC.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ns2ClassC_",nargout,nargin,0);
ns2::ClassC* self = new ns2::ClassC();
out[0] = wrap_constructed(self,"ns2ClassC");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ns2ClassC_(obj)
error('need to compile new_ns2ClassC_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassB.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("new_ns2ns3ClassB_",nargout,nargin,0);
ns2::ns3::ClassB* self = new ns2::ns3::ClassB();
out[0] = wrap_constructed(self,"ns2ns3ClassB");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2011-Dec-08
function result = new_ns2ns3ClassB_(obj)
error('need to compile new_ns2ns3ClassB_.cpp');
end

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2011-Dec-08
#include <wrap/matlab.h>
#include <ClassA.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("ns2ClassA_afunction",nargout,nargin,0);
double result = ns2::ClassA::afunction();
out[0] = wrap< double >(result);
}

View File

@ -0,0 +1,4 @@
function result = ns2ClassA_afunction()
% usage: x = ns2ClassA_afunction()
error('need to compile ns2ClassA_afunction.cpp');
end

View File

@ -9,10 +9,6 @@ class Point2 {
VectorNotEigen vectorConfusion();
};
namespace ns_outer {
namespace ns_inner {
class Point3 {
Point3(double x, double y, double z);
double norm() const;
@ -24,9 +20,6 @@ class Point3 {
// another comment
// NOTE: you *must* end namespaces as follows:
}///\namespace
// another comment
/**
@ -76,8 +69,6 @@ class Test {
// even more comments at the end!
};
}///\namespace
// comments at the end!
// even more comments at the end!

View File

@ -5,33 +5,39 @@
namespace ns1 {
class ClassA {
ClassA();
};
class ClassB {
ClassB();
};
}///\namespace
}///\namespace ns1
namespace ns2 {
class ClassA {
ClassA();
static double afunction();
double memberFunction();
};
namespace ns3 {
class ClassB {
ClassB();
};
}///\namespace
}///\namespace ns3
class ClassC {
ClassC();
};
}///\namespace
}///\namespace ns2
class ClassD {
ClassD();
};

View File

@ -50,6 +50,10 @@ TEST( wrap, check_exception ) {
THROWS_EXCEPTION(Module("/notarealpath", "geometry",enable_verbose));
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile);
// clean out previous generated code
string cleanCmd = "rm -rf actual";
system(cleanCmd.c_str());
string path = topdir + "/wrap/tests";
Module module(path.c_str(), "testWrap1",enable_verbose);
CHECK_EXCEPTION(module.matlab_code("actual", "", "mexa64", "-O5"), DependencyMissing);
@ -78,9 +82,7 @@ TEST( wrap, parse ) {
EXPECT_LONGS_EQUAL(1, cls.constructors.size());
EXPECT_LONGS_EQUAL(1, cls.methods.size());
EXPECT_LONGS_EQUAL(2, cls.static_methods.size());
EXPECT_LONGS_EQUAL(2, cls.namespaces.size());
EXPECT(assert_equal("ns_outer", cls.namespaces.front()));
EXPECT(assert_equal("ns_inner", cls.namespaces.back()));
EXPECT_LONGS_EQUAL(0, cls.namespaces.size());
// first constructor takes 3 doubles
Constructor c1 = cls.constructors.front();
@ -95,9 +97,9 @@ TEST( wrap, parse ) {
// check method
Method m1 = cls.methods.front();
EXPECT(assert_equal("double", m1.returnVal_.type1));
EXPECT(assert_equal("norm", m1.name_));
EXPECT_LONGS_EQUAL(0, m1.args_.size());
EXPECT(assert_equal("double", m1.returnVal.type1));
EXPECT(assert_equal("norm", m1.name));
EXPECT_LONGS_EQUAL(0, m1.args.size());
EXPECT(m1.is_const_);
}
@ -108,14 +110,13 @@ TEST( wrap, parse ) {
EXPECT_LONGS_EQUAL( 2, testCls.constructors.size());
EXPECT_LONGS_EQUAL(19, testCls.methods.size());
EXPECT_LONGS_EQUAL( 0, testCls.static_methods.size());
EXPECT_LONGS_EQUAL( 1, testCls.namespaces.size());
EXPECT(assert_equal("ns_outer", testCls.namespaces.front()));
EXPECT_LONGS_EQUAL( 0, testCls.namespaces.size());
// function to parse: pair<Vector,Matrix> return_pair (Vector v, Matrix A) const;
Method m2 = testCls.methods.front();
EXPECT(m2.returnVal_.isPair);
EXPECT(m2.returnVal_.category1 == ReturnValue::EIGEN);
EXPECT(m2.returnVal_.category2 == ReturnValue::EIGEN);
EXPECT(m2.returnVal.isPair);
EXPECT(m2.returnVal.category1 == ReturnValue::EIGEN);
EXPECT(m2.returnVal.category2 == ReturnValue::EIGEN);
}
}
@ -154,8 +155,26 @@ TEST( wrap, parse_namespaces ) {
Class cls6 = module.classes.at(5);
EXPECT(assert_equal("ClassD", cls6.name));
EXPECT_LONGS_EQUAL(0, cls6.namespaces.size());
if (!cls6.namespaces.empty())
cout << "Extraneous namespace: " << cls6.namespaces.front() << endl;
}
/* ************************************************************************* */
TEST( wrap, matlab_code_namespaces ) {
string header_path = topdir + "/wrap/tests";
Module module(header_path.c_str(), "testNamespaces",enable_verbose);
EXPECT_LONGS_EQUAL(6, module.classes.size());
string path = topdir + "/wrap";
// clean out previous generated code
string cleanCmd = "rm -rf actual_namespaces";
system(cleanCmd.c_str());
// emit MATLAB code
string exp_path = path + "/tests/expected_namespaces/";
string act_path = "actual_namespaces/";
module.matlab_code("actual_namespaces", "", "mexa64", "-O5");
EXPECT(files_equal(exp_path + "make_testNamespaces.m", act_path + "make_testNamespaces.m"));
EXPECT(files_equal(exp_path + "Makefile" , act_path + "Makefile" ));
}
/* ************************************************************************* */