|
degate 0.1.1
|
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 <GateLibraryImporter.h> 00024 #include <ImageHelper.h> 00025 00026 #include <sys/types.h> 00027 #include <sys/stat.h> 00028 #include <unistd.h> 00029 #include <errno.h> 00030 00031 #include <string> 00032 #include <iostream> 00033 #include <fstream> 00034 #include <sstream> 00035 #include <stdexcept> 00036 #include <list> 00037 #include <tr1/memory> 00038 00039 using namespace std; 00040 using namespace degate; 00041 00042 GateLibrary_shptr GateLibraryImporter::import(std::string const& filename) { 00043 00044 if(RET_IS_NOT_OK(check_file(filename))) { 00045 debug(TM, "Problem: file %s not found.", filename.c_str()); 00046 throw InvalidPathException("Can't load gate library from file."); 00047 } 00048 00049 std::string directory = get_basedir(filename); 00050 00051 try { 00052 //debug(TM, "try to parse file %s", filename.c_str()); 00053 00054 xmlpp::DomParser parser; 00055 parser.set_substitute_entities(); // We just want the text to be resolved/unescaped automatically. 00056 00057 parser.parse_file(filename); 00058 assert(parser == true); 00059 00060 const xmlpp::Document * doc = parser.get_document(); 00061 assert(doc != NULL); 00062 00063 const xmlpp::Element * root_elem = doc->get_root_node(); // deleted by DomParser 00064 assert(root_elem != NULL); 00065 00066 return parse_gate_library_element(root_elem, directory); 00067 00068 } 00069 catch(const std::exception& ex) { 00070 std::cout << "Exception caught: " << ex.what() << std::endl; 00071 throw; 00072 } 00073 00074 00075 00076 } 00077 00078 GateLibrary_shptr GateLibraryImporter::parse_gate_library_element(const xmlpp::Element * const gt_elem, 00079 std::string const& directory) { 00080 00081 // parse width and height 00082 GateLibrary_shptr gate_lib(new GateLibrary()); 00083 assert(gate_lib != NULL); 00084 00085 const xmlpp::Element * e = get_dom_twig(gt_elem, "gate-templates"); 00086 if(e != NULL) parse_gate_templates_element(e, gate_lib, directory); 00087 00088 return gate_lib; 00089 } 00090 00091 void GateLibraryImporter::parse_gate_templates_element(const xmlpp::Element * const gate_template_element, 00092 GateLibrary_shptr gate_lib, 00093 std::string const& directory) { 00094 00095 if(gate_template_element == NULL || gate_lib == NULL) throw(InvalidPointerException("Invalid pointer")); 00096 00097 const xmlpp::Node::NodeList gate_list = gate_template_element->get_children("gate"); 00098 for(xmlpp::Node::NodeList::const_iterator iter = gate_list.begin(); 00099 iter != gate_list.end(); 00100 ++iter) { 00101 00102 if(const xmlpp::Element* gate_elem = dynamic_cast<const xmlpp::Element*>(*iter)) { 00103 00104 object_id_t object_id = parse_number<object_id_t>(gate_elem, "type-id"); 00105 int min_x = parse_number<int>(gate_elem, "min-x", 0); 00106 int min_y = parse_number<int>(gate_elem, "min-y", 0); 00107 int max_x = parse_number<int>(gate_elem, "max-x", 0); 00108 int max_y = parse_number<int>(gate_elem, "max-y", 0); 00109 00110 int width = parse_number<int>(gate_elem, "width", 0); 00111 int height = parse_number<int>(gate_elem, "height", 0); 00112 00113 const Glib::ustring name(gate_elem->get_attribute_value("name")); 00114 const Glib::ustring description(gate_elem->get_attribute_value("description")); 00115 const Glib::ustring logic_class(gate_elem->get_attribute_value("logic-class")); 00116 const Glib::ustring frame_color_str(gate_elem->get_attribute_value("frame-color")); 00117 const Glib::ustring fill_color_str(gate_elem->get_attribute_value("fill-color")); 00118 00119 GateTemplate_shptr gate_template; 00120 00121 if(min_x == 0 && min_y == 0 && max_x == 0 && max_y == 0) { 00122 gate_template = GateTemplate_shptr(new GateTemplate(width, height)); 00123 } 00124 else { 00125 gate_template = GateTemplate_shptr(new GateTemplate(min_x, max_x, min_y, max_y)); 00126 } 00127 00128 gate_template->set_name(string(name.c_str())); 00129 gate_template->set_description(string(description.c_str())); 00130 gate_template->set_logic_class(string(logic_class.c_str())); 00131 gate_template->set_object_id(object_id); 00132 gate_template->set_fill_color(parse_color_string(fill_color_str)); 00133 gate_template->set_frame_color(parse_color_string(frame_color_str)); 00134 00135 00136 const xmlpp::Element * images = get_dom_twig(gate_elem, "images"); 00137 if(images != NULL) parse_template_images_element(images, gate_template, directory); 00138 00139 00140 const xmlpp::Element * ports = get_dom_twig(gate_elem, "ports"); 00141 if(ports != NULL) parse_template_ports_element(ports, gate_template, gate_lib); 00142 00143 const xmlpp::Element * implementations = get_dom_twig(gate_elem, "implementations"); 00144 if(implementations != NULL) 00145 parse_template_implementations_element(implementations, gate_template, directory); 00146 00147 gate_lib->add_template(gate_template); 00148 } 00149 } 00150 00151 } 00152 00153 void GateLibraryImporter::parse_template_images_element(const xmlpp::Element * const template_images_element, 00154 GateTemplate_shptr gate_tmpl, 00155 std::string const& directory) { 00156 00157 if(template_images_element == NULL || 00158 gate_tmpl == NULL) throw InvalidPointerException("Invalid pointer"); 00159 00160 const xmlpp::Node::NodeList image_list = template_images_element->get_children("image"); 00161 for(xmlpp::Node::NodeList::const_iterator iter = image_list.begin(); 00162 iter != image_list.end(); ++iter) { 00163 00164 if(const xmlpp::Element* image_elem = dynamic_cast<const xmlpp::Element*>(*iter)) { 00165 const std::string layer_type_str(image_elem->get_attribute_value("layer-type")); 00166 const std::string image_file(image_elem->get_attribute_value("image")); 00167 00168 Layer::LAYER_TYPE layer_type = Layer::get_layer_type_from_string(layer_type_str); 00169 GateTemplateImage_shptr img = load_image<GateTemplateImage>(join_pathes(directory, image_file)); 00170 00171 assert(img != NULL); 00172 gate_tmpl->set_image(layer_type, img); 00173 } 00174 } 00175 00176 } 00177 00178 void GateLibraryImporter::parse_template_implementations_element(const xmlpp::Element * const implementations_element, 00179 GateTemplate_shptr gate_tmpl, 00180 std::string const& directory) { 00181 00182 if(implementations_element == NULL || 00183 gate_tmpl == NULL) throw InvalidPointerException("Invalid pointer"); 00184 00185 const xmlpp::Node::NodeList impl_list = implementations_element->get_children("implementation"); 00186 for(xmlpp::Node::NodeList::const_iterator iter = impl_list.begin(); 00187 iter != impl_list.end(); ++iter) { 00188 00189 if(const xmlpp::Element* impl_elem = dynamic_cast<const xmlpp::Element*>(*iter)) { 00190 const std::string impl_type_str(impl_elem->get_attribute_value("type")); 00191 const std::string impl_file_attr(impl_elem->get_attribute_value("file")); 00192 const std::string impl_file(join_pathes(directory, impl_file_attr)); 00193 00194 if(!impl_file_attr.empty()) { 00195 GateTemplate::IMPLEMENTATION_TYPE impl_type; 00196 try { 00197 impl_type = GateTemplate::get_impl_type_from_string(impl_type_str); 00198 } 00199 catch(DegateRuntimeException const &ex) { 00200 boost::format f("Can't interprete attribute %1% while reading gate library (%2%)"); 00201 f % impl_type_str % ex.what(); 00202 throw XMLAttributeParseException(f.str()); 00203 } 00204 00205 debug(TM, "Parsing file '%s'", impl_file.c_str()); 00206 std::ifstream myfile(impl_file.c_str()); 00207 std::string line, code; 00208 if(myfile.is_open()) { 00209 while (!myfile.eof()) { 00210 getline(myfile, line); 00211 code.append(line); 00212 code.append("\n"); 00213 } 00214 myfile.close(); 00215 gate_tmpl->set_implementation(impl_type, code); 00216 gate_tmpl->get_implementation(impl_type); 00217 } 00218 else { 00219 boost::format f("Can't open file %1%"); 00220 f % impl_file; 00221 throw FileSystemException(f.str()); 00222 } 00223 00224 } 00225 } 00226 } 00227 00228 } 00229 00230 00231 void GateLibraryImporter::parse_template_ports_element(const xmlpp::Element * const template_ports_element, 00232 GateTemplate_shptr gate_tmpl, 00233 GateLibrary_shptr gate_lib) { 00234 00235 if(template_ports_element == NULL || 00236 gate_tmpl == NULL) throw InvalidPointerException("Invalid pointer"); 00237 00238 const xmlpp::Node::NodeList port_list = template_ports_element->get_children("port"); 00239 for(xmlpp::Node::NodeList::const_iterator iter = port_list.begin(); 00240 iter != port_list.end(); 00241 ++iter) { 00242 00243 if(const xmlpp::Element* port_elem = dynamic_cast<const xmlpp::Element*>(*iter)) { 00244 00245 object_id_t object_id = parse_number<object_id_t>(port_elem, "id"); 00246 00247 // we check if the object id is somehow present in the logic model 00248 if(gate_lib->exists_template_port(object_id) || gate_lib->exists_template(object_id)) { 00249 boost::format f("Error: The object ID %1% is used twice in the gate library."); 00250 f % object_id; 00251 std::cout << f.str() << "\n"; 00252 throw DegateInconsistencyException(f.str()); 00253 } 00254 00255 00256 const std::string name(port_elem->get_attribute_value("name")); 00257 const std::string description(port_elem->get_attribute_value("description")); 00258 const std::string type_str(port_elem->get_attribute_value("type").lowercase()); 00259 00260 GateTemplatePort::PORT_TYPE port_type = GateTemplatePort::get_port_type_from_string(type_str); 00261 00262 GateTemplatePort_shptr tmpl_port; 00263 00264 int pos_x, pos_y; 00265 try { 00266 pos_x = parse_number<int>(port_elem, "x"); 00267 pos_y = parse_number<int>(port_elem, "y"); 00268 00269 tmpl_port = GateTemplatePort_shptr(new GateTemplatePort(pos_x, pos_y, port_type)); 00270 } 00271 catch(XMLAttributeMissingException const & ex) { 00272 tmpl_port = GateTemplatePort_shptr(new GateTemplatePort(port_type)); 00273 } 00274 assert(tmpl_port != NULL); 00275 00276 00277 tmpl_port->set_name(string(name.c_str())); 00278 tmpl_port->set_description(string(description.c_str())); 00279 tmpl_port->set_object_id(object_id); 00280 00281 // add port to the gate template 00282 gate_tmpl->add_template_port(tmpl_port); 00283 } 00284 00285 00286 } 00287 }
1.7.4