degate  0.1.2
GateLibraryExporter.cc
Go to the documentation of this file.
00001 /*
00002 
00003   This file is part of the IC reverse engineering tool degate.
00004 
00005   Copyright 2008, 2009, 2010 by Martin Schobert
00006 
00007   Degate is free software: you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation, either version 3 of the License, or
00010   any later version.
00011 
00012   Degate is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015   GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with degate. If not, see <http://www.gnu.org/licenses/>.
00019 
00020 */
00021 
00022 #include <degate.h>
00023 #include <GateLibraryExporter.h>
00024 #include <FileSystem.h>
00025 #include <ImageHelper.h>
00026 #include <DegateHelper.h>
00027 
00028 #include <sys/types.h>
00029 #include <sys/stat.h>
00030 #include <unistd.h>
00031 #include <errno.h>
00032 
00033 #include <string>
00034 #include <iostream>
00035 #include <sstream>
00036 #include <fstream>
00037 #include <stdexcept>
00038 #include <list>
00039 #include <memory>
00040 
00041 
00042 using namespace std;
00043 using namespace degate;
00044 
00045 void GateLibraryExporter::export_data(std::string const& filename, GateLibrary_shptr gate_lib) {
00046 
00047   if(gate_lib == NULL) throw InvalidPointerException("Gate library pointer is NULL.");
00048 
00049   std::string directory = get_basedir(filename);
00050 
00051   try {
00052 
00053     xmlpp::Document doc;
00054 
00055     xmlpp::Element * root_elem = doc.create_root_node("gate-library");
00056     assert(root_elem != NULL);
00057 
00058     xmlpp::Element* templates_elem = root_elem->add_child("gate-templates");
00059     if(templates_elem == NULL) throw(std::runtime_error("Failed to create node."));
00060 
00061     add_gates(templates_elem, gate_lib, directory);
00062 
00063     doc.write_to_file_formatted(filename, "ISO-8859-1");
00064 
00065   }
00066   catch(const std::exception& ex) {
00067     std::cout << "Exception caught: " << ex.what() << std::endl;
00068     throw;
00069   }
00070 
00071 }
00072 
00073 void GateLibraryExporter::add_gates(xmlpp::Element* templates_elem,
00074                                     GateLibrary_shptr gate_lib,
00075                                     std::string const& directory) {
00076 
00077   for(GateLibrary::template_iterator iter = gate_lib->begin();
00078       iter != gate_lib->end(); ++iter) {
00079 
00080     GateTemplate_shptr gate_tmpl((*iter).second);
00081 
00082     xmlpp::Element* gate_elem = templates_elem->add_child("gate");
00083     if(gate_elem == NULL) throw(std::runtime_error("Failed to create node."));
00084 
00085     object_id_t new_oid = oid_rewriter->get_new_object_id(gate_tmpl->get_object_id());
00086     gate_elem->set_attribute("type-id", number_to_string<object_id_t>(new_oid));
00087     gate_elem->set_attribute("name", gate_tmpl->get_name());
00088     gate_elem->set_attribute("description", gate_tmpl->get_description());
00089     gate_elem->set_attribute("logic-class", gate_tmpl->get_logic_class());
00090 
00091     gate_elem->set_attribute("fill-color", to_color_string(gate_tmpl->get_fill_color()));
00092     gate_elem->set_attribute("frame-color", to_color_string(gate_tmpl->get_frame_color()));
00093 
00094     gate_elem->set_attribute("width", number_to_string<unsigned int>(gate_tmpl->get_width()));
00095     gate_elem->set_attribute("height", number_to_string<unsigned int>(gate_tmpl->get_height()));
00096 
00097     add_images(gate_elem, gate_tmpl, directory);
00098     add_ports(gate_elem, gate_tmpl);
00099     add_implementations(gate_elem, gate_tmpl, directory);
00100   }
00101 }
00102 
00103 
00104 void GateLibraryExporter::add_images(xmlpp::Element* gate_elem,
00105                                      GateTemplate_shptr gate_tmpl,
00106                                      std::string const& directory) {
00107 
00108   // export images
00109 
00110   xmlpp::Element* images_elem = gate_elem->add_child("images");
00111   if(images_elem == NULL) throw(std::runtime_error("Failed to create node."));
00112 
00113   for(GateTemplate::image_iterator img_iter = gate_tmpl->images_begin();
00114       img_iter != gate_tmpl->images_end(); ++img_iter) {
00115 
00116     Layer::LAYER_TYPE layer_type = (*img_iter).first;
00117     GateTemplateImage_shptr img = (*img_iter).second;
00118     assert(img != NULL);
00119 
00120     xmlpp::Element* img_elem = images_elem->add_child("image");
00121     if(img_elem == NULL) throw(std::runtime_error("Failed to create node."));
00122 
00123     img_elem->set_attribute("layer-type", Layer::get_layer_type_as_string(layer_type));
00124 
00125     // export the image
00126     object_id_t new_oid = oid_rewriter->get_new_object_id(gate_tmpl->get_object_id());
00127     boost::format fmter("%1%_%2%.tif");
00128     fmter % new_oid % Layer::get_layer_type_as_string(layer_type);
00129     std::string filename(fmter.str());
00130 
00131     img_elem->set_attribute("image", filename);
00132 
00133     save_image<GateTemplateImage>(join_pathes(directory, filename), img);
00134   }
00135 
00136 }
00137 
00138 void GateLibraryExporter::add_ports(xmlpp::Element* gate_elem,
00139                                     GateTemplate_shptr gate_tmpl) {
00140 
00141   xmlpp::Element* ports_elem = gate_elem->add_child("ports");
00142   if(ports_elem == NULL) throw(std::runtime_error("Failed to create node."));
00143 
00144   for(GateTemplate::port_iterator piter = gate_tmpl->ports_begin();
00145       piter != gate_tmpl->ports_end(); ++piter) {
00146 
00147     xmlpp::Element* port_elem = ports_elem->add_child("port");
00148     if(port_elem == NULL) throw(std::runtime_error("Failed to create node."));
00149 
00150     GateTemplatePort_shptr tmpl_port((*piter));
00151 
00152     object_id_t new_port_id = oid_rewriter->get_new_object_id(tmpl_port->get_object_id());
00153     port_elem->set_attribute("id", number_to_string<object_id_t>(new_port_id));
00154     port_elem->set_attribute("name", tmpl_port->get_name());
00155     port_elem->set_attribute("description", tmpl_port->get_description());
00156 
00157     port_elem->set_attribute("type", tmpl_port->get_port_type_as_string());
00158 
00159     if(tmpl_port->is_position_defined()) {
00160       Point const & point = tmpl_port->get_point();
00161       port_elem->set_attribute("x", number_to_string<int>(point.get_x()));
00162       port_elem->set_attribute("y", number_to_string<int>(point.get_y()));
00163     }
00164 
00165   }
00166 }
00167 
00168 void GateLibraryExporter::add_implementations(xmlpp::Element* gate_elem,
00169                                               GateTemplate_shptr gate_tmpl,
00170                                               std::string const& directory) {
00171 
00172   xmlpp::Element* implementations_elem = gate_elem->add_child("implementations");
00173   if(implementations_elem == NULL) throw(std::runtime_error("Failed to create node."));
00174 
00175   for(GateTemplate::implementation_iter iter = gate_tmpl->implementations_begin();
00176       iter != gate_tmpl->implementations_end(); ++iter) {
00177 
00178     GateTemplate::IMPLEMENTATION_TYPE t = iter->first;
00179     std::string const& code = iter->second;
00180 
00181     //std::cout << "Code: " << code;
00182     if(t != GateTemplate::UNDEFINED && !code.empty()) {
00183 
00184       xmlpp::Element* impl_elem = implementations_elem->add_child("implementation");
00185       if(impl_elem == NULL) throw(std::runtime_error("Failed to create node."));
00186 
00187       object_id_t new_oid = oid_rewriter->get_new_object_id(gate_tmpl->get_object_id());
00188       boost::format fmter("%1%%2%.%3%");
00189       switch(t) {
00190       case GateTemplate::TEXT: fmter % "" % new_oid % "txt"; break;
00191       case GateTemplate::VHDL: fmter % "" % new_oid % "vhdl"; break;
00192       case GateTemplate::VHDL_TESTBENCH: fmter % "test_" % new_oid % "vhdl"; break;
00193       case GateTemplate::VERILOG: fmter % "" % new_oid % "v"; break;
00194       case GateTemplate::VERILOG_TESTBENCH: fmter % "test_" % new_oid % "v"; break;
00195       default: assert(1==0); // already handled. just to get rid of a compiler warning.
00196       }
00197       std::string filename(fmter.str());
00198 
00199       write_string_to_file(join_pathes(directory, filename), code);
00200 
00201       impl_elem->set_attribute("type", GateTemplate::get_impl_type_as_string(t));
00202       impl_elem->set_attribute("file", filename);
00203     }
00204   }
00205 }
00206