Re-factored matlab_code only emits code: it does not post-process the classes anymore. That is now done in parse_Markup, i.e., the constructor....
parent
7a4748d3dc
commit
e07402a58a
|
@ -394,51 +394,35 @@ void Module::parseMarkup(const std::string& data) {
|
||||||
// Explicitly add methods to the classes from parents so it shows in documentation
|
// Explicitly add methods to the classes from parents so it shows in documentation
|
||||||
BOOST_FOREACH(Class& cls, classes)
|
BOOST_FOREACH(Class& cls, classes)
|
||||||
cls.appendInheritedMethods(cls, classes);
|
cls.appendInheritedMethods(cls, classes);
|
||||||
}
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
void Module::generateIncludes(FileWriter& file) const {
|
|
||||||
|
|
||||||
// collect includes
|
|
||||||
vector<string> all_includes(includes);
|
|
||||||
|
|
||||||
// sort and remove duplicates
|
|
||||||
sort(all_includes.begin(), all_includes.end());
|
|
||||||
vector<string>::const_iterator last_include = unique(all_includes.begin(), all_includes.end());
|
|
||||||
vector<string>::const_iterator it = all_includes.begin();
|
|
||||||
// add includes to file
|
|
||||||
for (; it != last_include; ++it)
|
|
||||||
file.oss << "#include <" << *it << ">" << endl;
|
|
||||||
file.oss << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************* */
|
|
||||||
void Module::matlab_code(const string& toolboxPath, const string& headerPath) const {
|
|
||||||
|
|
||||||
fs::create_directories(toolboxPath);
|
|
||||||
|
|
||||||
// Expand templates - This is done first so that template instantiations are
|
// Expand templates - This is done first so that template instantiations are
|
||||||
// counted in the list of valid types, have their attributes and dependencies
|
// counted in the list of valid types, have their attributes and dependencies
|
||||||
// checked, etc.
|
// checked, etc.
|
||||||
vector<Class> expandedClasses = ExpandTypedefInstantiations(classes, templateInstantiationTypedefs);
|
expandedClasses = ExpandTypedefInstantiations(classes,
|
||||||
|
templateInstantiationTypedefs);
|
||||||
|
|
||||||
// Dependency check list
|
// Dependency check list
|
||||||
vector<string> validTypes = GenerateValidTypes(expandedClasses, forward_declarations);
|
vector<string> validTypes = GenerateValidTypes(expandedClasses,
|
||||||
|
forward_declarations);
|
||||||
|
|
||||||
// Check that all classes have been defined somewhere
|
// Check that all classes have been defined somewhere
|
||||||
verifyArguments<GlobalFunction>(validTypes, global_functions);
|
verifyArguments<GlobalFunction>(validTypes, global_functions);
|
||||||
verifyReturnTypes<GlobalFunction>(validTypes, global_functions);
|
verifyReturnTypes<GlobalFunction>(validTypes, global_functions);
|
||||||
|
|
||||||
bool hasSerialiable = false;
|
hasSerialiable = false;
|
||||||
BOOST_FOREACH(const Class& cls, expandedClasses)
|
BOOST_FOREACH(const Class& cls, expandedClasses)
|
||||||
cls.verifyAll(validTypes,hasSerialiable);
|
cls.verifyAll(validTypes,hasSerialiable);
|
||||||
|
|
||||||
// Create type attributes table and check validity
|
// Create type attributes table and check validity
|
||||||
TypeAttributesTable typeAttributes;
|
|
||||||
typeAttributes.addClasses(expandedClasses);
|
typeAttributes.addClasses(expandedClasses);
|
||||||
typeAttributes.addForwardDeclarations(forward_declarations);
|
typeAttributes.addForwardDeclarations(forward_declarations);
|
||||||
typeAttributes.checkValidity(expandedClasses);
|
typeAttributes.checkValidity(expandedClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
void Module::matlab_code(const string& toolboxPath) const {
|
||||||
|
|
||||||
|
fs::create_directories(toolboxPath);
|
||||||
|
|
||||||
// create the unified .cpp switch file
|
// create the unified .cpp switch file
|
||||||
const string wrapperName = name + "_wrapper";
|
const string wrapperName = name + "_wrapper";
|
||||||
|
@ -459,19 +443,18 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co
|
||||||
// Generate includes while avoiding redundant includes
|
// Generate includes while avoiding redundant includes
|
||||||
generateIncludes(wrapperFile);
|
generateIncludes(wrapperFile);
|
||||||
|
|
||||||
// create typedef classes - we put this at the top of the wrap file so that collectors and method arguments can use these typedefs
|
// create typedef classes - we put this at the top of the wrap file so that
|
||||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
// collectors and method arguments can use these typedefs
|
||||||
|
BOOST_FOREACH(const Class& cls, expandedClasses)
|
||||||
if(!cls.typedefName.empty())
|
if(!cls.typedefName.empty())
|
||||||
wrapperFile.oss << cls.getTypedef() << "\n";
|
wrapperFile.oss << cls.getTypedef() << "\n";
|
||||||
}
|
|
||||||
wrapperFile.oss << "\n";
|
wrapperFile.oss << "\n";
|
||||||
|
|
||||||
// Generate boost.serialization export flags (needs typedefs from above)
|
// Generate boost.serialization export flags (needs typedefs from above)
|
||||||
if (hasSerialiable) {
|
if (hasSerialiable) {
|
||||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
BOOST_FOREACH(const Class& cls, expandedClasses)
|
||||||
if(cls.isSerializable)
|
if(cls.isSerializable)
|
||||||
wrapperFile.oss << cls.getSerializationExport() << "\n";
|
wrapperFile.oss << cls.getSerializationExport() << "\n";
|
||||||
}
|
|
||||||
wrapperFile.oss << "\n";
|
wrapperFile.oss << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,14 +467,12 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co
|
||||||
vector<string> functionNames; // Function names stored by index for switch
|
vector<string> functionNames; // Function names stored by index for switch
|
||||||
|
|
||||||
// create proxy class and wrapper code
|
// create proxy class and wrapper code
|
||||||
BOOST_FOREACH(const Class& cls, expandedClasses) {
|
BOOST_FOREACH(const Class& cls, expandedClasses)
|
||||||
cls.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames);
|
cls.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames);
|
||||||
}
|
|
||||||
|
|
||||||
// create matlab files and wrapper code for global functions
|
// create matlab files and wrapper code for global functions
|
||||||
BOOST_FOREACH(const GlobalFunctions::value_type& p, global_functions) {
|
BOOST_FOREACH(const GlobalFunctions::value_type& p, global_functions)
|
||||||
p.second.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames);
|
p.second.matlab_proxy(toolboxPath, wrapperName, typeAttributes, wrapperFile, functionNames);
|
||||||
}
|
|
||||||
|
|
||||||
// finish wrapper file
|
// finish wrapper file
|
||||||
wrapperFile.oss << "\n";
|
wrapperFile.oss << "\n";
|
||||||
|
@ -501,6 +482,23 @@ void Module::matlab_code(const string& toolboxPath, const string& headerPath) co
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
void Module::generateIncludes(FileWriter& file) const {
|
||||||
|
|
||||||
|
// collect includes
|
||||||
|
vector<string> all_includes(includes);
|
||||||
|
|
||||||
|
// sort and remove duplicates
|
||||||
|
sort(all_includes.begin(), all_includes.end());
|
||||||
|
vector<string>::const_iterator last_include = unique(all_includes.begin(), all_includes.end());
|
||||||
|
vector<string>::const_iterator it = all_includes.begin();
|
||||||
|
// add includes to file
|
||||||
|
for (; it != last_include; ++it)
|
||||||
|
file.oss << "#include <" << *it << ">" << endl;
|
||||||
|
file.oss << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
void Module::finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const {
|
void Module::finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const {
|
||||||
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
file.oss << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n";
|
||||||
file.oss << "{\n";
|
file.oss << "{\n";
|
||||||
|
|
|
@ -37,40 +37,50 @@ struct Module {
|
||||||
typedef std::map<std::string, GlobalFunction> GlobalFunctions;
|
typedef std::map<std::string, GlobalFunction> GlobalFunctions;
|
||||||
typedef std::map<std::string, Method> Methods;
|
typedef std::map<std::string, Method> Methods;
|
||||||
|
|
||||||
std::string name; ///< module name
|
// Filled during parsing:
|
||||||
bool verbose; ///< verbose flag
|
std::string name; ///< module name
|
||||||
|
bool verbose; ///< verbose flag
|
||||||
std::vector<Class> classes; ///< list of classes
|
std::vector<Class> classes; ///< list of classes
|
||||||
std::vector<TemplateInstantiationTypedef> templateInstantiationTypedefs; ///< list of template instantiations
|
std::vector<TemplateInstantiationTypedef> templateInstantiationTypedefs; ///< list of template instantiations
|
||||||
std::vector<ForwardDeclaration> forward_declarations;
|
std::vector<ForwardDeclaration> forward_declarations;
|
||||||
std::vector<std::string> includes; ///< Include statements
|
std::vector<std::string> includes; ///< Include statements
|
||||||
GlobalFunctions global_functions;
|
GlobalFunctions global_functions;
|
||||||
|
|
||||||
|
// After parsing:
|
||||||
|
std::vector<Class> expandedClasses;
|
||||||
|
bool hasSerialiable;
|
||||||
|
TypeAttributesTable typeAttributes;
|
||||||
|
|
||||||
/// constructor that parses interface file
|
/// constructor that parses interface file
|
||||||
Module(const std::string& interfacePath,
|
Module(const std::string& interfacePath, const std::string& moduleName,
|
||||||
const std::string& moduleName,
|
bool enable_verbose = true);
|
||||||
bool enable_verbose=true);
|
|
||||||
|
|
||||||
/// Dummy constructor that does no parsing - use only for testing
|
/// Dummy constructor that does no parsing - use only for testing
|
||||||
Module(const std::string& moduleName, bool enable_verbose=true);
|
Module(const std::string& moduleName, bool enable_verbose = true);
|
||||||
|
|
||||||
/// MATLAB code generation:
|
|
||||||
void matlab_code(
|
|
||||||
const std::string& path,
|
|
||||||
const std::string& headerPath) const; // FIXME: headerPath not actually used?
|
|
||||||
|
|
||||||
void finish_wrapper(FileWriter& file, const std::vector<std::string>& functionNames) const;
|
|
||||||
|
|
||||||
void generateIncludes(FileWriter& file) const;
|
|
||||||
|
|
||||||
/// non-const function that performs parsing - typically called by constructor
|
/// non-const function that performs parsing - typically called by constructor
|
||||||
/// Throws exception on failure
|
/// Throws exception on failure
|
||||||
void parseMarkup(const std::string& data);
|
void parseMarkup(const std::string& data);
|
||||||
|
|
||||||
|
/// MATLAB code generation:
|
||||||
|
void matlab_code(const std::string& path) const;
|
||||||
|
|
||||||
|
void generateIncludes(FileWriter& file) const;
|
||||||
|
|
||||||
|
void finish_wrapper(FileWriter& file,
|
||||||
|
const std::vector<std::string>& functionNames) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::vector<Class> ExpandTypedefInstantiations(const std::vector<Class>& classes, const std::vector<TemplateInstantiationTypedef> instantiations);
|
static std::vector<Class> ExpandTypedefInstantiations(
|
||||||
static std::vector<std::string> GenerateValidTypes(const std::vector<Class>& classes, const std::vector<ForwardDeclaration> forwardDeclarations);
|
const std::vector<Class>& classes,
|
||||||
static void WriteCollectorsAndCleanupFcn(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes);
|
const std::vector<TemplateInstantiationTypedef> instantiations);
|
||||||
static void WriteRTTIRegistry(FileWriter& wrapperFile, const std::string& moduleName, const std::vector<Class>& classes);
|
static std::vector<std::string> GenerateValidTypes(
|
||||||
|
const std::vector<Class>& classes,
|
||||||
|
const std::vector<ForwardDeclaration> forwardDeclarations);
|
||||||
|
static void WriteCollectorsAndCleanupFcn(FileWriter& wrapperFile,
|
||||||
|
const std::string& moduleName, const std::vector<Class>& classes);
|
||||||
|
static void WriteRTTIRegistry(FileWriter& wrapperFile,
|
||||||
|
const std::string& moduleName, const std::vector<Class>& classes);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // \namespace wrap
|
} // \namespace wrap
|
||||||
|
|
|
@ -64,12 +64,11 @@ TEST( wrap, check_exception ) {
|
||||||
THROWS_EXCEPTION(Module("/notarealpath", "geometry",enable_verbose));
|
THROWS_EXCEPTION(Module("/notarealpath", "geometry",enable_verbose));
|
||||||
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile);
|
CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",enable_verbose), CantOpenFile);
|
||||||
|
|
||||||
// clean out previous generated code
|
// // TODO: matlab_code does not throw this anymore, so check constructor
|
||||||
fs::remove_all("actual_deps");
|
// fs::remove_all("actual_deps"); // clean out previous generated code
|
||||||
|
// string path = topdir + "/wrap/tests";
|
||||||
string path = topdir + "/wrap/tests";
|
// Module module(path.c_str(), "testDependencies",enable_verbose);
|
||||||
Module module(path.c_str(), "testDependencies",enable_verbose);
|
// CHECK_EXCEPTION(module.matlab_code("actual_deps"), DependencyMissing);
|
||||||
CHECK_EXCEPTION(module.matlab_code("actual_deps", headerPath), DependencyMissing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
@ -413,7 +412,7 @@ TEST( wrap, matlab_code_namespaces ) {
|
||||||
// emit MATLAB code
|
// emit MATLAB code
|
||||||
string exp_path = path + "/tests/expected_namespaces/";
|
string exp_path = path + "/tests/expected_namespaces/";
|
||||||
string act_path = "actual_namespaces/";
|
string act_path = "actual_namespaces/";
|
||||||
module.matlab_code("actual_namespaces", headerPath);
|
module.matlab_code("actual_namespaces");
|
||||||
|
|
||||||
|
|
||||||
EXPECT(files_equal(exp_path + "ClassD.m", act_path + "ClassD.m" ));
|
EXPECT(files_equal(exp_path + "ClassD.m", act_path + "ClassD.m" ));
|
||||||
|
@ -441,7 +440,7 @@ TEST( wrap, matlab_code_geometry ) {
|
||||||
|
|
||||||
// emit MATLAB code
|
// emit MATLAB code
|
||||||
// make_geometry will not compile, use make testwrap to generate real make
|
// make_geometry will not compile, use make testwrap to generate real make
|
||||||
module.matlab_code("actual", headerPath);
|
module.matlab_code("actual");
|
||||||
#ifndef WRAP_DISABLE_SERIALIZE
|
#ifndef WRAP_DISABLE_SERIALIZE
|
||||||
string epath = path + "/tests/expected/";
|
string epath = path + "/tests/expected/";
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue