diff options
| author | Dan Goodliffe <randomdan@akira.random.lan> | 2014-12-05 21:59:33 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <randomdan@akira.random.lan> | 2014-12-05 21:59:33 +0000 | 
| commit | 5bfdb2977435344fd22cd5efd41a45ac6318213b (patch) | |
| tree | f443b13c8be47a26c699d0431800c203d8639860 | |
| parent | Support for automatically determining a model part implementation (diff) | |
| download | slicer-5bfdb2977435344fd22cd5efd41a45ac6318213b.tar.bz2 slicer-5bfdb2977435344fd22cd5efd41a45ac6318213b.tar.xz slicer-5bfdb2977435344fd22cd5efd41a45ac6318213b.zip | |
Support writing to a FILE * directlyslicer-0.8.4
Support writing to a NULL FILE *
Return number of processed things
Covering tests
| -rw-r--r-- | slicer/slicer/parser.cpp | 61 | ||||
| -rw-r--r-- | slicer/slicer/parser.h | 5 | ||||
| -rw-r--r-- | 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,9 +485,26 @@ 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<std::string> cppArgs;  		Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("slicer", ice.string(), cppArgs);  		FILE * cppHandle = icecpp->preprocess(false); @@ -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<std::string> metaDataSplit(const std::string & metadata);  			static std::vector<ConversionSpec> getConversions(Slice::DataMemberPtr); +			unsigned int components;  			FILE * cpp;  			std::vector<Slice::ModulePtr> 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"); | 
