diff options
| -rw-r--r-- | src/openscad.cc | 47 | 
1 files changed, 32 insertions, 15 deletions
| diff --git a/src/openscad.cc b/src/openscad.cc index d190cc0..36ba68c 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -217,7 +217,7 @@ static bool assert_root_2d(CGAL_Nef_polyhedron &nef) {  	return true;  }; -int cmdline(const char *deps_output_file, const string &filename, Camera &camera, const char *output_file, const fs::path &original_path, Render::type renderer, string application_name) +int cmdline(const char *deps_output_file, const string &filename, Camera &camera, const string output_file, const fs::path &original_path, Render::type renderer, string application_name)  {  	CGAL_Nef_polyhedron root_N;  	Tree tree; @@ -239,13 +239,11 @@ int cmdline(const char *deps_output_file, const string &filename, Camera &camera  			root_N = cgalevaluator->evaluateCGALMesh(*tree.root());  			if (!assert_root_3d_simple(root_N)) return 1;  			export_off(&root_N, fstream); -			fstream.close();  			return 0; }},  		{"dxf", [&] {  			root_N = cgalevaluator->evaluateCGALMesh(*tree.root());  			if (!assert_root_2d(root_N)) return 1;  			export_dxf(&root_N, fstream); -			fstream.close();  			return 0; }},  		{"png", [&] {  			switch (renderer) { @@ -267,11 +265,9 @@ int cmdline(const char *deps_output_file, const string &filename, Camera &camera  			return 0; }},  		{"term", [&] {  			// TODO: check wether CWD is correct at this point -			vector<shared_ptr<CSGTerm> > highlight_terms; -			vector<shared_ptr<CSGTerm> > background_terms; -  			PolySetCGALEvaluator psevaluator(*cgalevaluator);  			CSGTermEvaluator csgRenderer(tree, &psevaluator); +			vector<shared_ptr<CSGTerm> > highlight_terms, background_terms;  			shared_ptr<CSGTerm> root_raw_term = csgRenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms);  			if (!root_raw_term) { @@ -301,12 +297,11 @@ int cmdline(const char *deps_output_file, const string &filename, Camera &camera  		return 1;  	} -	// Open the output file -	fstream.open(output_file, (suffix == "png") ? std::ios::binary : std::ios::out); -	if (!fstream.is_open()) { -	  PRINTB("Can't open file \"%s\" for export", output_file); -	} - +	// Open the output file early if it is an echo stream +	unique_ptr<Echostream> echostream; +	string temp_output_file = output_file + "~"; +	if (suffix == "echo") +		echostream.reset(new Echostream(temp_output_file.c_str()));  	// Init parser, top_con  	const string application_path = boosty::stringy(boosty::absolute(boost::filesystem::path(application_name).parent_path())); @@ -321,9 +316,6 @@ int cmdline(const char *deps_output_file, const string &filename, Camera &camera  #if 0 && DEBUG  	top_ctx.dump(NULL, NULL);  #endif -	unique_ptr<Echostream> echostream; -	if (suffix == "echo") -		echostream.reset( new Echostream( output_file ) );  	ModuleInstantiation root_inst("group");  	AbstractNode *absolute_root_node; @@ -383,9 +375,34 @@ int cmdline(const char *deps_output_file, const string &filename, Camera &camera  		}  	} +	// Open output file late to catch errors before writing anything to disk +	if (suffix != "echo") { +		fstream.open(temp_output_file, (suffix == "png") ? std::ios::binary : std::ios::out); +		if (!fstream.is_open()) { +			PRINTB("Can't open file \"%s\" for export", temp_output_file); +			return 1; +		} +	} +  	// Call the intended action  	auto ret = actions[suffix](); +	// Commit the file if succesfull, delete it otherwise. +	if (!ret) { +		// Success +		if (rename(temp_output_file.c_str(), output_file.c_str())) { +			PRINTB("Can't rename \"%s\" to \"%s\"", temp_output_file % output_file); +			return 1; +		} +	}else{ +		// Failure +		if (remove(temp_output_file.c_str())) { +			PRINTB("Can't remove \"%s\"", temp_output_file); +			return 1; +		} +		fstream.close(); +	} +  	// Clean up  	delete root_node;  	fstream.close(); | 
