From d1b918591893aec26c8b686cb6786e2824d5b136 Mon Sep 17 00:00:00 2001 From: Alex Cunningham Date: Tue, 27 Nov 2012 19:03:19 +0000 Subject: [PATCH] Trying more variations. Fixed small valgrind issue that didn't actually have an effect --- wrap/Method.cpp | 1 + wrap/Module.cpp | 71 ++++++++++++++++++++++++----------------- wrap/Module.h | 9 +++++- wrap/tests/testWrap.cpp | 63 ++++++++++++++++++++++++++++++++++++ wrap/utilities.cpp | 3 +- 5 files changed, 116 insertions(+), 31 deletions(-) diff --git a/wrap/Method.cpp b/wrap/Method.cpp index 9e959dc9a..b327ac7dc 100644 --- a/wrap/Method.cpp +++ b/wrap/Method.cpp @@ -37,6 +37,7 @@ void Method::addOverload(bool verbose, bool is_const, const std::string& name, this->returnVals.push_back(retVal); } +/* ************************************************************************* */ void Method::proxy_wrapper_fragments(FileWriter& proxyFile, FileWriter& wrapperFile, const string& cppClassName, const std::string& matlabQualName, diff --git a/wrap/Module.cpp b/wrap/Module.cpp index 1c51dbf77..e45c09672 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -68,23 +68,40 @@ void handle_possible_template(vector& classes, const Class& cls, const st } } +/* ************************************************************************* */ +Module::Module(const std::string& moduleName, bool enable_verbose) +: name(moduleName), verbose(enable_verbose) +{ +} + /* ************************************************************************* */ Module::Module(const string& interfacePath, - const string& moduleName, bool enable_verbose) : name(moduleName), verbose(enable_verbose) + const string& moduleName, bool enable_verbose) +: name(moduleName), verbose(enable_verbose) { + // read interface file + string interfaceFile = interfacePath + "/" + moduleName + ".h"; + string contents = file_contents(interfaceFile); + + // execute parsing + parseMarkup(contents); +} + +/* ************************************************************************* */ +void Module::parseMarkup(const std::string& data) { // these variables will be imperatively updated to gradually build [cls] // The one with postfix 0 are used to reset the variables after parse. string methodName, methodName0; bool isConst, isConst0 = false; - ReturnValue retVal0(enable_verbose), retVal; + ReturnValue retVal0(verbose), retVal(verbose); Argument arg0, arg; ArgumentList args0, args; vector arg_dup; ///keep track of duplicates - Constructor constructor0(enable_verbose), constructor(enable_verbose); - Deconstructor deconstructor0(enable_verbose), deconstructor(enable_verbose); - StaticMethod static_method0(enable_verbose), static_method(enable_verbose); - Class cls0(enable_verbose),cls(enable_verbose); - GlobalFunction globalFunc0(enable_verbose), globalFunc(enable_verbose); + Constructor constructor0(verbose), constructor(verbose); + Deconstructor deconstructor0(verbose), deconstructor(verbose); + StaticMethod static_method0(verbose), static_method(verbose); + Class cls0(verbose),cls(verbose); + GlobalFunction globalFunc0(verbose), globalFunc(verbose); ForwardDeclaration fwDec0, fwDec; vector namespaces, /// current namespace tag namespaces_return; /// namespace for current return type @@ -110,7 +127,7 @@ Module::Module(const string& interfacePath, (str_p("string") | "bool" | "size_t" | "int" | "double" | "char" | "unsigned char"); Rule keywords_p = - (str_p("const") | "static" | "namespace" | basisType_p); + (str_p("const") | "static" | "namespace" | "void" | basisType_p); Rule eigenType_p = (str_p("Vector") | "Matrix"); @@ -208,20 +225,21 @@ Module::Module(const string& interfacePath, // (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)]; // FIXME: allows for void in a pair + // current revision + Rule returnType1_p = + basisType_p[assign_a(retVal.category1, ReturnValue::BASIS)][assign_a(retVal.type1)] | + ((*namespace_ret_p)[assign_a(retVal.namespaces1, namespaces_return)][clear_a(namespaces_return)] + >> (className_p[assign_a(retVal.category1, ReturnValue::CLASS)][assign_a(retVal.type1)]) >> + !ch_p('*')[assign_a(retVal.isPtr1,true)]) | + eigenType_p[assign_a(retVal.category1, ReturnValue::EIGEN)][assign_a(retVal.type1)]; + + // Original // Rule returnType1_p = -// (eigenType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::EIGEN)]) | // (basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) | // ((*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)]); - - // Original - Rule returnType1_p = - (basisType_p[assign_a(retVal.type1)][assign_a(retVal.category1, ReturnValue::BASIS)]) | - ((*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)]); +// !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)]) | @@ -355,16 +373,12 @@ Module::Module(const string& interfacePath, # endif //---------------------------------------------------------------------------- - // read interface file - string interfaceFile = interfacePath + "/" + moduleName + ".h"; - string contents = file_contents(interfaceFile); - - // and parse contents - parse_info info = parse(contents.c_str(), module_p, space_p); - if(!info.full) { - printf("parsing stopped at \n%.20s\n",info.stop); - throw ParseFailed((int)info.length); - } + // and parse contents + parse_info info = parse(data.c_str(), module_p, space_p); + if(!info.full) { + printf("parsing stopped at \n%.20s\n",info.stop); + throw ParseFailed((int)info.length); + } //Explicitly add methods to the classes from parents so it shows in documentation BOOST_FOREACH(Class& cls, classes) @@ -373,7 +387,6 @@ Module::Module(const string& interfacePath, cls.methods.insert(inhereted.begin(), inhereted.end()); } - } /* ************************************************************************* */ diff --git a/wrap/Module.h b/wrap/Module.h index b8b84a5fa..27d67f8ea 100644 --- a/wrap/Module.h +++ b/wrap/Module.h @@ -38,9 +38,9 @@ struct Module { typedef std::map Methods; std::string name; ///< module name + bool verbose; ///< verbose flag std::vector classes; ///< list of classes std::vector templateInstantiationTypedefs; ///< list of template instantiations - bool verbose; ///< verbose flag std::vector forward_declarations; std::vector includes; ///< Include statements GlobalFunctions global_functions; @@ -50,6 +50,9 @@ struct Module { const std::string& moduleName, bool enable_verbose=true); + /// Dummy constructor that does no parsing - use only for testing + Module(const std::string& moduleName, bool enable_verbose=true); + //Recursive method to append all methods inhereted from parent classes std::map appendInheretedMethods(const Class& cls, const std::vector& classes); @@ -62,6 +65,10 @@ struct Module { void generateIncludes(FileWriter& file) const; + /// non-const function that performs parsing - typically called by constructor + /// Throws exception on failure + void parseMarkup(const std::string& data); + private: static std::vector ExpandTypedefInstantiations(const std::vector& classes, const std::vector instantiations); static std::vector GenerateValidTypes(const std::vector& classes, const std::vector forwardDeclarations); diff --git a/wrap/tests/testWrap.cpp b/wrap/tests/testWrap.cpp index f6b32aedb..efb3912c9 100644 --- a/wrap/tests/testWrap.cpp +++ b/wrap/tests/testWrap.cpp @@ -70,6 +70,69 @@ TEST_UNSAFE( wrap, check_exception ) { CHECK_EXCEPTION(module.matlab_code("actual_deps", headerPath), DependencyMissing); } +/* ************************************************************************* */ +TEST( wrap, small_parse ) { + string moduleName("gtsam"); + Module module(moduleName, true); + + string markup( + string("class Point2 { \n") + + string(" double x() const; \n") + // Method 1 + string(" Matrix returnChar() const; \n") + // Method 2 + string(" Point2 returnPoint2() const; \n") + // Method 3 + string("};\n")); + module.parseMarkup(markup); + + // check return types + LONGS_EQUAL(1, module.classes.size()); + Class cls = module.classes.front(); + EXPECT(assert_equal("Point2", cls.name)); + EXPECT(!cls.isVirtual); + EXPECT(cls.namespaces.empty()); + EXPECT(cls.static_methods.empty()); + LONGS_EQUAL(3, cls.methods.size()); + + // Method 1 + Method m1 = cls.methods.at("x"); + EXPECT(assert_equal("x", m1.name)); + EXPECT(m1.is_const_); + LONGS_EQUAL(1, m1.argLists.size()); + LONGS_EQUAL(1, m1.returnVals.size()); + + ReturnValue rv1 = m1.returnVals.front(); + EXPECT(!rv1.isPair); + EXPECT(!rv1.isPtr1); + EXPECT(assert_equal("double", rv1.type1)); + EXPECT_LONGS_EQUAL(ReturnValue::BASIS, rv1.category1); + + // Method 2 + Method m2 = cls.methods.at("returnChar"); + EXPECT(assert_equal("returnChar", m2.name)); + EXPECT(m2.is_const_); + LONGS_EQUAL(1, m2.argLists.size()); + LONGS_EQUAL(1, m2.returnVals.size()); + + ReturnValue rv2 = m2.returnVals.front(); + EXPECT(!rv2.isPair); + EXPECT(!rv2.isPtr1); + EXPECT(assert_equal("Matrix", rv2.type1)); + EXPECT_LONGS_EQUAL(ReturnValue::EIGEN, rv2.category1); + + // Method 3 + Method m3 = cls.methods.at("returnPoint2"); + EXPECT(assert_equal("returnPoint2", m3.name)); + EXPECT(m3.is_const_); + LONGS_EQUAL(1, m3.argLists.size()); + LONGS_EQUAL(1, m3.returnVals.size()); + + ReturnValue rv3 = m3.returnVals.front(); + EXPECT(!rv3.isPair); + EXPECT(!rv3.isPtr1); + EXPECT(assert_equal("Point2", rv3.type1)); + EXPECT_LONGS_EQUAL(ReturnValue::CLASS, rv3.category1); + +} + /* ************************************************************************* */ TEST( wrap, parse_geometry ) { string markup_header_path = topdir + "/wrap/tests"; diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp index b36f2f70b..1acc50db1 100644 --- a/wrap/utilities.cpp +++ b/wrap/utilities.cpp @@ -136,7 +136,8 @@ void createNamespaceStructure(const std::vector& namespaces, const using namespace boost::filesystem; path curPath = toolboxPath; BOOST_FOREACH(const string& subdir, namespaces) { - curPath /= "+" + subdir; +// curPath /= "+" + subdir; // original - resulted in valgrind error + curPath = curPath / string(string("+") + subdir); if(!is_directory(curPath)) { if(exists("+" + subdir)) throw OutputError("Need to write files to directory " + curPath.string() + ", which already exists as a file but is not a directory");