coriolis/chamsin/src/technology/ATechnologyXmlParser.cpp

123 lines
4.7 KiB
C++

#include <libxml/parser.h>
#include <libxml/tree.h>
#include "hurricane/Technology.h"
#include "ATechnology.h"
#include "ATechnologyXmlParser.h"
using namespace Hurricane;
namespace {
void syntaxError(const string& reason) {
throw Error(reason);
}
DbU::Unit getUnitValue(double physicalValue) {
return DbU::grid(DbU::physicalToGrid(physicalValue, DbU::Micro));
}
void readPhysicalRules(xmlNode* node, ATechnology* aTechnology) {
if (node->type == XML_ELEMENT_NODE && node->children) {
for (xmlNode* ruleNode = node->children;
ruleNode;
ruleNode = ruleNode->next) {
if (ruleNode->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(ruleNode->name, (xmlChar*)"arule")) {
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
xmlChar* layer1C = xmlGetProp(ruleNode, (xmlChar*)"layer1");
xmlChar* layer2C = xmlGetProp(ruleNode, (xmlChar*)"layer2");
if (ruleNameC && valueC && refC && layer1C && layer2C) {
string ruleName((const char*)ruleNameC);
double value = atof((const char*)valueC);
DbU::Unit unitValue = getUnitValue(value);
cerr << value << ", " << unitValue << endl;
string reference((const char*)refC);
Name layer1Name((const char*)layer1C);
Name layer2Name((const char*)layer2C);
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, false, unitValue, reference);
}
} else if (xmlStrEqual(ruleNode->name, (xmlChar*)"rule")) {
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
xmlChar* layerC = xmlGetProp(ruleNode, (xmlChar*)"layer");
xmlChar* layer1C = xmlGetProp(ruleNode, (xmlChar*)"layer1");
xmlChar* layer2C = xmlGetProp(ruleNode, (xmlChar*)"layer2");
if (ruleNameC && valueC && refC) {
string ruleName((const char*)ruleNameC);
double value = atof((const char*)valueC);
DbU::Unit unitValue = getUnitValue(value);
string reference((const char*)refC);
if (layerC) {
Name layerName((const char*)layerC);
aTechnology->addPhysicalRule(ruleName, layerName, unitValue, reference);
} else if (layer1C && layer2C) {
Name layer1Name((const char*)layer1C);
Name layer2Name((const char*)layer2C);
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, true, unitValue, reference);
} else {
aTechnology->addPhysicalRule(ruleName, unitValue, reference);
}
} else {
syntaxError("");
}
}
}
}
}
}
ATechnology* parseFileAsTechnology(const char* filePath, Technology* technology) {
ATechnology* aTechnology = ATechnology::create(technology);
xmlDocPtr doc; /* the resulting document tree */
doc = xmlReadFile(filePath, NULL, 0);
if (doc == NULL) {
fprintf(stderr, "Failed to parse %s\n", filePath);
exit(5);
}
/*Get the design element node */
xmlNode* rootElement = xmlDocGetRootElement(doc);
if (rootElement->type == XML_ELEMENT_NODE &&
xmlStrEqual(rootElement->name, (xmlChar*)"technology")) {
xmlNode* child = rootElement->children;
for (xmlNode* node = child; node; node = node->next) {
if (node->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(node->name, (xmlChar*)"physical_rules")) {
readPhysicalRules(node, aTechnology);
} else {
syntaxError("unknown tag");
}
}
}
}
}
}
ATechnology* ATechnologyXmlParser::parse(const char* filePath, Technology* technology) {
LIBXML_TEST_VERSION
ATechnology* aTechnology = parseFileAsTechnology(filePath, technology);
xmlCleanupParser();
/*
* this is to debug memory for regression tests
*/
xmlMemoryDump();
return NULL;
}