From 5bfdb2977435344fd22cd5efd41a45ac6318213b Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 5 Dec 2014 21:59:33 +0000 Subject: Support writing to a FILE * directly Support writing to a NULL FILE * Return number of processed things Covering tests --- slicer/slicer/parser.cpp | 61 +++++++++++++++++++++++++++++++++++++------- slicer/slicer/parser.h | 5 +++- slicer/test/preprocessor.cpp | 25 ++++++++++++++++++ 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index 998a0cb..299b178 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -14,6 +14,7 @@ namespace fs = boost::filesystem; namespace Slicer { Slicer::Slicer(FILE * c) : + components(0), cpp(c), classNo(0) { @@ -22,6 +23,8 @@ namespace Slicer { void Slicer::defineConversions(Slice::DataMemberPtr dm) const { + if (!cpp) return; + auto type = dm->type(); auto c = Slice::ContainedPtr::dynamicCast(dm->container()); auto conversions = getConversions(dm); @@ -79,6 +82,7 @@ namespace Slicer { Slicer::visitUnitStart(const Slice::UnitPtr & u) { fs::path topLevelFile(u->topLevelFile()); + if (!cpp) return true; fprintf(cpp, "// Begin Slicer code\n\n"); fprintf(cpp, "#include <%s>\n\n", fs::change_extension(topLevelFile.filename(), ".h").string().c_str()); @@ -90,6 +94,8 @@ namespace Slicer { void Slicer::visitUnitEnd(const Slice::UnitPtr&) { + if (!cpp) return; + fprintf(cpp, "}\n\n"); fprintf(cpp, "// End Slicer code\n\n"); } @@ -97,8 +103,11 @@ namespace Slicer { bool Slicer::visitModuleStart(const Slice::ModulePtr & m) { - fprintf(cpp, "// Begin module %s\n\n", m->name().c_str()); modules.push_back(m); + + if (!cpp) return true; + + fprintf(cpp, "// Begin module %s\n\n", m->name().c_str()); BOOST_FOREACH(const auto & c, m->structs()) { BOOST_FOREACH(const auto & dm, c->dataMembers()) { defineConversions(dm); @@ -118,6 +127,10 @@ namespace Slicer { if (c->isInterface()) { return false; } if (c->hasMetaData("slicer:ignore")) { return false; } + components += 1; + + if (!cpp) return true; + auto decl = c->declaration(); fprintf(cpp, "// Class %s\n", c->name().c_str()); visitComplexDataMembers(decl, c->allDataMembers()); @@ -177,6 +190,10 @@ namespace Slicer { { if (c->hasMetaData("slicer:ignore")) { return false; } + components += 1; + + if (!cpp) return true; + fprintf(cpp, "// Struct %s\n", c->name().c_str()); visitComplexDataMembers(c, c->dataMembers()); @@ -190,6 +207,8 @@ namespace Slicer { void Slicer::visitComplexDataMembers(Slice::ConstructedPtr it, const Slice::DataMemberList & dataMembers) const { + if (!cpp) return; + fprintf(cpp, "template<>\n"); fprintf(cpp, "ModelPartForComplex< %s::%s >::Hooks ", modulePath().c_str(), it->name().c_str()); @@ -258,6 +277,10 @@ namespace Slicer { { if (s->hasMetaData("slicer:ignore")) { return; } + components += 1; + + if (!cpp) return; + fprintf(cpp, "// Sequence %s\n", s->name().c_str()); fprintf(cpp, "template<>\n"); fprintf(cpp, "ModelPartPtr ModelPartForSequence< %s::%s >::GetChild(const std::string & name)\n{\n", @@ -299,6 +322,10 @@ namespace Slicer { { if (d->hasMetaData("slicer:ignore")) { return; } + components += 1; + + if (!cpp) return; + fprintf(cpp, "// Dictionary %s\n", d->name().c_str()); auto iname = metaDataValue("slicer:item:", d->getMetaData()); fprintf(cpp, "template<>\n"); @@ -360,7 +387,9 @@ namespace Slicer { void Slicer::visitModuleEnd(const Slice::ModulePtr & m) { - fprintf(cpp, "// End module %s\n\n", m->name().c_str()); + if (cpp) { + fprintf(cpp, "// End module %s\n\n", m->name().c_str()); + } modules.pop_back(); } @@ -456,8 +485,25 @@ namespace Slicer { return rtn; } - void + unsigned int + Slicer::Components() const + { + return components; + } + + unsigned int Slicer::Apply(const boost::filesystem::path & ice, const boost::filesystem::path & cpp) + { + FilePtr cppfile(fopen(cpp.string().c_str(), "a"), fclose); + if (!cppfile) { + throw std::runtime_error("failed to open code file"); + } + + return Apply(ice, cppfile.get()); + } + + unsigned int + Slicer::Apply(const boost::filesystem::path & ice, FILE * cpp) { std::vector cppArgs; Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("slicer", ice.string(), cppArgs); @@ -479,15 +525,12 @@ namespace Slicer { throw std::runtime_error("unit parse failed"); } - FilePtr cppfile(fopen(cpp.string().c_str(), "a"), fclose); - if (!cppfile) { - throw std::runtime_error("failed to open code file"); - } - - Slicer s(cppfile.get()); + Slicer s(cpp); u->visit(&s, false); u->destroy(); + + return s.Components(); } }; diff --git a/slicer/slicer/parser.h b/slicer/slicer/parser.h index 8aef56f..12193cb 100644 --- a/slicer/slicer/parser.h +++ b/slicer/slicer/parser.h @@ -19,7 +19,8 @@ namespace Slicer { Slicer(FILE * c); - static void Apply(const boost::filesystem::path & ice, const boost::filesystem::path & cpp); + static unsigned int Apply(const boost::filesystem::path & ice, const boost::filesystem::path & cpp); + static unsigned int Apply(const boost::filesystem::path & ice, FILE *); virtual bool visitUnitStart(const Slice::UnitPtr&) override; @@ -37,6 +38,7 @@ namespace Slicer { virtual void visitModuleEnd(const Slice::ModulePtr & m) override; + unsigned int Components() const; private: void createNewModelPartPtrFor(const Slice::TypePtr & type) const; @@ -53,6 +55,7 @@ namespace Slicer { static std::vector metaDataSplit(const std::string & metadata); static std::vector getConversions(Slice::DataMemberPtr); + unsigned int components; FILE * cpp; std::vector modules; unsigned int classNo; diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp index f4c75fc..430efd9 100644 --- a/slicer/test/preprocessor.cpp +++ b/slicer/test/preprocessor.cpp @@ -13,8 +13,33 @@ namespace fs = boost::filesystem; +const unsigned int COMPONENTS_IN_TEST_ICE = 24; + BOOST_FIXTURE_TEST_SUITE ( preprocessor, FileStructure ); +BOOST_AUTO_TEST_CASE( slicer_test_counts_path ) +{ + auto count = Slicer::Slicer::Apply(slice, boost::filesystem::path("/dev/null")); + BOOST_REQUIRE_EQUAL(COMPONENTS_IN_TEST_ICE, count); +} + +BOOST_AUTO_TEST_CASE( slicer_test_counts_filestar ) +{ + FILE * file = fopen("/dev/null", "a"); + BOOST_REQUIRE(file); + + auto count = Slicer::Slicer::Apply(slice, file); + BOOST_REQUIRE_EQUAL(COMPONENTS_IN_TEST_ICE, count); + + fclose(file); +} + +BOOST_AUTO_TEST_CASE( slicer_test_counts_nullfilestar ) +{ + auto count = Slicer::Slicer::Apply(slice, NULL); + BOOST_REQUIRE_EQUAL(COMPONENTS_IN_TEST_ICE, count); +} + BOOST_AUTO_TEST_CASE( slicer_test_ice ) { const fs::path cpp = fs::change_extension(tmp / base, ".cpp"); -- cgit v1.2.3