Commit aed804ef authored by Tarun Prabhu's avatar Tarun Prabhu
Browse files

Fixed some bugs in the parsers. A full features and desires test now works....

Fixed some bugs in the parsers. A full features and desires test now works. There are stil some extension support which needs to be added to ptopgen.
parent 308589d5
...@@ -36,34 +36,34 @@ class annotate_rspec : public annotate ...@@ -36,34 +36,34 @@ class annotate_rspec : public annotate
~annotate_rspec () { ; } ~annotate_rspec () { ; }
// Annotates nodes and direct links in the rspec // Annotates nodes and direct links in the rspec
void annotate_element(const char* v_name, const char* p_name); virtual void annotate_element(const char* v_name, const char* p_name);
// Annotates intraswitch and interswitch links in the rspec // Annotates intraswitch and interswitch links in the rspec
void annotate_element(const char* v_name, virtual void annotate_element(const char* v_name,
std::list<const char*>* links); std::list<const char*>* links);
// Annotate a trivial link // Annotate a trivial link
void annotate_element(const char* v_name); virtual void annotate_element(const char* v_name);
// Annotates an interface element on a link // Annotates an interface element on a link
void annotate_interface (const xercesc::DOMElement* plink, virtual void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink, const xercesc::DOMElement* vlink,
int interface_number, int interface_number,
bool is_trivial_link); bool is_trivial_link);
// Annotates an interface element on a non-trivial link // Annotates an interface element on a non-trivial link
void annotate_interface (const xercesc::DOMElement* plink, virtual void annotate_interface (const xercesc::DOMElement* plink,
const xercesc::DOMElement* vlink, const xercesc::DOMElement* vlink,
int interface_number); int interface_number);
// Annotates an interface element on a trivial link // Annotates an interface element on a trivial link
void annotate_interface (const xercesc::DOMElement* vlink, virtual void annotate_interface (const xercesc::DOMElement* vlink,
int interface_number); int interface_number);
// Creates a hop from a switch till the next end point. // Creates a hop from a switch till the next end point.
// Adds the hop to the vlink // Adds the hop to the vlink
// Returns the hop element that was created // Returns the hop element that was created
xercesc::DOMElement* virtual xercesc::DOMElement*
create_component_hop (const xercesc::DOMElement* plink, create_component_hop (const xercesc::DOMElement* plink,
xercesc::DOMElement* vlink, xercesc::DOMElement* vlink,
int endpoint_interface, int endpoint_interface,
...@@ -72,40 +72,40 @@ class annotate_rspec : public annotate ...@@ -72,40 +72,40 @@ class annotate_rspec : public annotate
// Creates a component_hop for a trivial link // Creates a component_hop for a trivial link
// Adds the hop to the vlink // Adds the hop to the vlink
// Returns the hop element that was created // Returns the hop element that was created
xercesc::DOMElement* create_component_hop (xercesc::DOMElement* vlink); virtual xercesc::DOMElement* create_component_hop (xercesc::DOMElement* vlink);
// If the interface is the end point of a link/path, // If the interface is the end point of a link/path,
// add two additional attributes to it // add two additional attributes to it
void set_interface_as_link_endpoint (xercesc::DOMElement* interface, virtual void set_interface_as_link_endpoint (xercesc::DOMElement* interface,
const char* virtual_node_id, const char* virtual_node_id,
const char* virtual_interface_id); const char* virtual_interface_id);
// Finds the next link in the path returned by assign // Finds the next link in the path returned by assign
xercesc::DOMElement* find_next_link_in_path virtual xercesc::DOMElement* find_next_link_in_path
(xercesc::DOMElement *prev, (xercesc::DOMElement *prev,
std::list<const char*>* links); std::list<const char*>* links);
// Copies the component spec from the source to the destination // Copies the component spec from the source to the destination
void copy_component_spec(const xercesc::DOMElement* src, virtual void copy_component_spec(const xercesc::DOMElement* src,
xercesc::DOMElement* dst); xercesc::DOMElement* dst);
// Copies the component hop from the auto-generated link // Copies the component hop from the auto-generated link
// to the requested link // to the requested link
void copy_component_hop(xercesc::DOMElement* requested_link, virtual void copy_component_hop(xercesc::DOMElement* requested_link,
xercesc::DOMElement* component_hop); xercesc::DOMElement* component_hop);
// Checks if the link contains an interface with // Checks if the link contains an interface with
// virtual_interface_id = id // virtual_interface_id = id
bool has_interface_with_id (std::string link_id, std::string id); virtual bool has_interface_with_id (std::string link_id, std::string id);
// Removes all extra tags and generated elements from the XML document // Removes all extra tags and generated elements from the XML document
void cleanup (); virtual void cleanup ();
// Checks whether an element of type tag // Checks whether an element of type tag
// with attr_name = attr_value is a generated element // with attr_name = attr_value is a generated element
bool is_generated_element (const char* tag, virtual bool is_generated_element (const char* tag,
const char* attr_name, const char* attr_name,
const char* attr_value); const char* attr_value);
}; };
#endif //for __ANNOTATE_RSPEC_H #endif //for __ANNOTATE_RSPEC_H
......
...@@ -30,7 +30,6 @@ extern DOMElement* request_root; ...@@ -30,7 +30,6 @@ extern DOMElement* request_root;
extern map<string, DOMElement*>* advertisement_elements; extern map<string, DOMElement*>* advertisement_elements;
XERCES_CPP_NAMESPACE_USE XERCES_CPP_NAMESPACE_USE
using namespace std; using namespace std;
annotate_rspec_v2 :: annotate_rspec_v2 () annotate_rspec_v2 :: annotate_rspec_v2 ()
...@@ -86,7 +85,10 @@ void annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name ...@@ -86,7 +85,10 @@ void annotate_rspec_v2::annotate_element (const char* v_name, const char* p_name
if (vnode != NULL) { if (vnode != NULL) {
if (!vnode->hasAttribute(XStr("generated_by_assign").x())) { if (!vnode->hasAttribute(XStr("generated_by_assign").x())) {
DOMElement* pnode = (this->physical_elements->find(p_name))->second; DOMElement* pnode = (this->physical_elements->find(p_name))->second;
copy_component_spec(pnode, vnode); vnode->setAttribute(XStr("component_id").x(),
pnode->getAttribute(XStr("component_id").x()));
vnode->setAttribute(XStr("component_manager_id").x(),
pnode->getAttribute(XStr("component_manager_id").x()));
} }
} }
else { else {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define __ANNOTATE_RSPEC_V2_H #define __ANNOTATE_RSPEC_V2_H
#include "annotate.h" #include "annotate.h"
#include "annotate_rspec.h"
#include <list> #include <list>
#include <map> #include <map>
...@@ -23,7 +24,7 @@ ...@@ -23,7 +24,7 @@
#include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM.hpp>
class annotate_rspec_v2 : public annotate class annotate_rspec_v2 : public annotate_rspec
{ {
private: private:
// Enumeration of which interface in a hop // Enumeration of which interface in a hop
......
...@@ -17,7 +17,7 @@ XERCES_CPP_NAMESPACE_USE ...@@ -17,7 +17,7 @@ XERCES_CPP_NAMESPACE_USE
using namespace std; using namespace std;
using namespace rspec_emulab_extension; using namespace rspec_emulab_extension;
emulab_operator emulab_extensions_parser::readOperator(DOMElement* tag) emulab_operator emulab_extensions_parser::readOperator(const DOMElement* tag)
{ {
struct emulab_operator op = { "", NORMAL_OPERATOR }; struct emulab_operator op = { "", NORMAL_OPERATOR };
if (this->hasAttribute(tag, "global_operator")) { if (this->hasAttribute(tag, "global_operator")) {
...@@ -32,10 +32,11 @@ emulab_operator emulab_extensions_parser::readOperator(DOMElement* tag) ...@@ -32,10 +32,11 @@ emulab_operator emulab_extensions_parser::readOperator(DOMElement* tag)
} }
vector<struct fd> vector<struct fd>
emulab_extensions_parser::readAllFeaturesDesires (DOMElement* elem) emulab_extensions_parser::readFeaturesDesires (const DOMElement* ele, int& count)
{ {
DOMNodeList* fdNodes = elem->getElementsByTagName(XStr("emulab:fd").x());
vector<struct fd> fds; vector<struct fd> fds;
DOMNodeList* fdNodes = ele->getElementsByTagName(XStr("emulab:fd").x());
count = fdNodes->getLength();
for (int i = 0; i < fdNodes->getLength(); i++) { for (int i = 0; i < fdNodes->getLength(); i++) {
fds.push_back(this->readFeatureDesire fds.push_back(this->readFeatureDesire
(dynamic_cast<DOMElement*>(fdNodes->item(i)))); (dynamic_cast<DOMElement*>(fdNodes->item(i))));
...@@ -43,7 +44,7 @@ emulab_extensions_parser::readAllFeaturesDesires (DOMElement* elem) ...@@ -43,7 +44,7 @@ emulab_extensions_parser::readAllFeaturesDesires (DOMElement* elem)
return fds; return fds;
} }
struct fd emulab_extensions_parser::readFeatureDesire (DOMElement* tag) struct fd emulab_extensions_parser::readFeatureDesire (const DOMElement* tag)
{ {
struct fd fdObject = { struct fd fdObject = {
this->getAttribute(tag, "name"), this->getAttribute(tag, "name"),
...@@ -55,8 +56,8 @@ struct fd emulab_extensions_parser::readFeatureDesire (DOMElement* tag) ...@@ -55,8 +56,8 @@ struct fd emulab_extensions_parser::readFeatureDesire (DOMElement* tag)
return fdObject; return fdObject;
} }
vector<struct property> emulab_extensions_parser::readAllProperties vector<struct property> emulab_extensions_parser::readProperties
(DOMElement* elem) (const DOMElement* elem)
{ {
DOMNodeList* propNodes = elem->getElementsByTagName(XStr("property").x()); DOMNodeList* propNodes = elem->getElementsByTagName(XStr("property").x());
vector<struct property> properties; vector<struct property> properties;
...@@ -67,7 +68,7 @@ vector<struct property> emulab_extensions_parser::readAllProperties ...@@ -67,7 +68,7 @@ vector<struct property> emulab_extensions_parser::readAllProperties
return properties; return properties;
} }
struct property emulab_extensions_parser::readProperty (DOMElement* tag) struct property emulab_extensions_parser::readProperty (const DOMElement* tag)
{ {
struct property propertyObject = { struct property propertyObject = {
this->getAttribute(tag, "property_name"), this->getAttribute(tag, "property_name"),
...@@ -80,7 +81,7 @@ struct property emulab_extensions_parser::readProperty (DOMElement* tag) ...@@ -80,7 +81,7 @@ struct property emulab_extensions_parser::readProperty (DOMElement* tag)
return propertyObject; return propertyObject;
} }
struct hardness emulab_extensions_parser::readHardness (DOMElement* tag) struct hardness emulab_extensions_parser::readHardness (const DOMElement* tag)
{ {
struct hardness hardnessObject; struct hardness hardnessObject;
if (this->hasChild(tag, "hard")) { if (this->hasChild(tag, "hard")) {
...@@ -97,7 +98,7 @@ struct hardness emulab_extensions_parser::readHardness (DOMElement* tag) ...@@ -97,7 +98,7 @@ struct hardness emulab_extensions_parser::readHardness (DOMElement* tag)
} }
vector<struct vclass> vector<struct vclass>
emulab_extensions_parser::readAllVClasses (DOMElement* elem) emulab_extensions_parser::readAllVClasses (const DOMElement* elem)
{ {
DOMNodeList* vclassNodes DOMNodeList* vclassNodes
= elem->getElementsByTagName(XStr("emulab:vclass").x()); = elem->getElementsByTagName(XStr("emulab:vclass").x());
...@@ -110,7 +111,7 @@ emulab_extensions_parser::readAllVClasses (DOMElement* elem) ...@@ -110,7 +111,7 @@ emulab_extensions_parser::readAllVClasses (DOMElement* elem)
return vclasses; return vclasses;
} }
struct vclass emulab_extensions_parser::readVClass (DOMElement* tag) struct vclass emulab_extensions_parser::readVClass (const DOMElement* tag)
{ {
struct vclass vclassObject = { struct vclass vclassObject = {
this->getAttribute(tag, "name"), this->getAttribute(tag, "name"),
...@@ -120,7 +121,7 @@ struct vclass emulab_extensions_parser::readVClass (DOMElement* tag) ...@@ -120,7 +121,7 @@ struct vclass emulab_extensions_parser::readVClass (DOMElement* tag)
return vclassObject; return vclassObject;
} }
string emulab_extensions_parser::readTypeSlots (DOMElement* tag) string emulab_extensions_parser::readTypeSlots (const DOMElement* tag)
{ {
DOMNodeList* typeSlotsNodes DOMNodeList* typeSlotsNodes
= tag->getElementsByTagName(XStr("emulab:node_type").x()); = tag->getElementsByTagName(XStr("emulab:node_type").x());
...@@ -131,7 +132,7 @@ string emulab_extensions_parser::readTypeSlots (DOMElement* tag) ...@@ -131,7 +132,7 @@ string emulab_extensions_parser::readTypeSlots (DOMElement* tag)
return (this->getAttribute(typeSlotsNode, "type_slots")); return (this->getAttribute(typeSlotsNode, "type_slots"));
} }
bool emulab_extensions_parser::readStaticType (DOMElement* tag) bool emulab_extensions_parser::readStaticType (const DOMElement* tag)
{ {
DOMNodeList* typeSlotsNodes DOMNodeList* typeSlotsNodes
= tag->getElementsByTagName(XStr("emulab:node_type").x()); = tag->getElementsByTagName(XStr("emulab:node_type").x());
......
...@@ -80,28 +80,28 @@ namespace rspec_emulab_extension { ...@@ -80,28 +80,28 @@ namespace rspec_emulab_extension {
class emulab_extensions_parser : public rspec_parser_helper { class emulab_extensions_parser : public rspec_parser_helper {
private: private:
int type; int type;
struct emulab_operator readOperator(xercesc::DOMElement* tag); struct emulab_operator readOperator(const xercesc::DOMElement* tag);
struct hardness readHardness (xercesc::DOMElement* tag); struct hardness readHardness (const xercesc::DOMElement* tag);
public: public:
// Constructor // Constructor
emulab_extensions_parser(int type) { this->type = type; } emulab_extensions_parser(int type) { this->type = type; }
// Functions // Functions
std::vector<struct fd> readAllFeaturesDesires std::vector<struct fd> readFeaturesDesires (const xercesc::DOMElement*,
(xercesc::DOMElement* ele); int&);
struct fd readFeatureDesire (xercesc::DOMElement* tag); struct fd readFeatureDesire (const xercesc::DOMElement* tag);
struct node_flags readNodeFlag (xercesc::DOMElement* tag); struct node_flags readNodeFlag (const xercesc::DOMElement* tag);
struct link_flags readLinkFlag (xercesc::DOMElement* tag); struct link_flags readLinkFlag (const xercesc::DOMElement* tag);
std::vector<struct property> readAllProperties std::vector<struct property> readProperties
(xercesc::DOMElement* elem); (const xercesc::DOMElement* elem);
struct property readProperty (xercesc::DOMElement* tag); struct property readProperty (const xercesc::DOMElement* tag);
std::vector<struct vclass> readAllVClasses (xercesc::DOMElement*); std::vector<struct vclass> readAllVClasses (const xercesc::DOMElement*);
struct vclass readVClass (xercesc::DOMElement* tag); struct vclass readVClass (const xercesc::DOMElement* tag);
std::string readAssignedTo (xercesc::DOMElement* tag); std::string readAssignedTo (const xercesc::DOMElement* tag);
std::string readHintTo (xercesc::DOMElement* tag); std::string readHintTo (const xercesc::DOMElement* tag);
std::string readTypeSlots (xercesc::DOMElement* tag); std::string readTypeSlots (const xercesc::DOMElement* tag);
bool readStaticType (xercesc::DOMElement* tag); bool readStaticType (const xercesc::DOMElement* tag);
std::vector<struct type_limit> readTypeLimits(const xercesc::DOMElement* tag, std::vector<struct type_limit> readTypeLimits(const xercesc::DOMElement* tag,
int& count); int& count);
}; };
......
...@@ -225,15 +225,7 @@ bool populate_nodes(DOMElement *root, ...@@ -225,15 +225,7 @@ bool populate_nodes(DOMElement *root,
continue; continue;
} }
bool isAvailable; // Maintain a list of componentId's seen so far to ensure no duplicates
string available = rspecParser->readAvailable(elt, isAvailable);
if (available == "false") {
unavailable.insert(componentId);
continue;
}
++availableCount;
// Maintain a list of componentId's seen so far to ensure no duplicates
insert_ret = advertisement_elements->insert insert_ret = advertisement_elements->insert
(pair<string, DOMElement*>(componentId, elt)); (pair<string, DOMElement*>(componentId, elt));
if (insert_ret.second == false) if (insert_ret.second == false)
...@@ -283,8 +275,6 @@ bool populate_nodes(DOMElement *root, ...@@ -283,8 +275,6 @@ bool populate_nodes(DOMElement *root,
int typeSlots = type.typeSlots; int typeSlots = type.typeSlots;
bool isStatic = type.isStatic; bool isStatic = type.isStatic;
cout << typeName << " " << typeSlots << " " << isStatic << endl;
// Add the type into assign's data structures // Add the type into assign's data structures
if (ptypes.find(typeName) == ptypes.end()) { if (ptypes.find(typeName) == ptypes.end()) {
ptypes[typeName] = new tb_ptype(typeName); ptypes[typeName] = new tb_ptype(typeName);
...@@ -347,6 +337,45 @@ bool populate_nodes(DOMElement *root, ...@@ -347,6 +337,45 @@ bool populate_nodes(DOMElement *root,
p->subnode_of_name = XStr(subnodeOf.c_str()).f(); p->subnode_of_name = XStr(subnodeOf.c_str()).f();
} }
} }
// This has to be at the end becuase if we don't populate
// at least the interfaces, we get all kinds of crappy errors
bool isAvailable;
string available = rspecParser->readAvailable(elt, isAvailable);
if (available == "false") {
unavailable.insert(componentId);
continue;
}
++availableCount;
// Deal with features
int fdsCount;
vector<struct fd> fds = rspecParser->readFeaturesDesires(elt, fdsCount);
for (int i = 0; i < fdsCount; i++) {
struct fd feature = fds[i];
featuredesire::fd_type fd_type;
switch(feature.op.type) {
case LOCAL_OPERATOR:
fd_type = featuredesire::FD_TYPE_LOCAL_ADDITIVE;
break;
case GLOBAL_OPERATOR:
if (feature.op.op == "OnceOnly") {
fd_type = featuredesire::FD_TYPE_GLOBAL_ONE_IS_OKAY;
}
else {
fd_type = featuredesire::FD_TYPE_GLOBAL_MORE_THAN_ONE;
}
break;
default:
fd_type = featuredesire::FD_TYPE_NORMAL;
break;
}
tb_node_featuredesire node_fd (XStr(feature.fd_name.c_str()).f(),
feature.fd_weight,
feature.violatable,
fd_type);
(p->features).push_front(node_fd);
}
/* /*
* XXX: Is this really necessary? * XXX: Is this really necessary?
......
...@@ -274,4 +274,11 @@ rspec_parser::readTypeLimits (const DOMElement* tag, int& count) ...@@ -274,4 +274,11 @@ rspec_parser::readTypeLimits (const DOMElement* tag, int& count)
return vector<struct type_limit>(); return vector<struct type_limit>();
} }
vector<struct fd>
rspec_parser::readFeaturesDesires (const DOMElement* tag, int& count)
{
count = 0;
return vector<struct fd>();
}
#endif #endif
...@@ -130,6 +130,9 @@ class rspec_parser : public rspec_parser_helper ...@@ -130,6 +130,9 @@ class rspec_parser : public rspec_parser_helper
virtual std::vector<struct rspec_emulab_extension::type_limit> virtual std::vector<struct rspec_emulab_extension::type_limit>
readTypeLimits (const xercesc::DOMElement*, int&); readTypeLimits (const xercesc::DOMElement*, int&);
virtual std::vector<struct rspec_emulab_extension::fd>
readFeaturesDesires(const xercesc::DOMElement*, int&);
}; };
......
...@@ -48,6 +48,7 @@ rspec_parser_v2::readLinkInterface (const DOMElement* link, int& ifaceCount) ...@@ -48,6 +48,7 @@ rspec_parser_v2::readLinkInterface (const DOMElement* link, int& ifaceCount)
return vector<struct link_interface>(); return vector<struct link_interface>();
} }
if ((this->ifacesSeen).find(destId) == (this->ifacesSeen).end()) { if ((this->ifacesSeen).find(destId) == (this->ifacesSeen).end()) {
cerr << "Could not find " << destId << endl;
ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_DST; ifaceCount = RSPEC_ERROR_UNSEEN_NODEIFACE_DST;
return vector<struct link_interface>(); return vector<struct link_interface>();
} }
...@@ -244,4 +245,10 @@ rspec_parser_v2::readTypeLimits (const DOMElement* tag, int& count) ...@@ -244,4 +245,10 @@ rspec_parser_v2::readTypeLimits (const DOMElement* tag, int& count)
return ((this->emulabExtensions)->readTypeLimits(tag, count)); return ((this->emulabExtensions)->readTypeLimits(tag, count));
} }
vector<struct fd>
rspec_parser_v2::readFeaturesDesires (const DOMElement* tag, int& count)
{
return ((this->emulabExtensions)->readFeaturesDesires(tag, count));
}
#endif // #ifdef WITH_XML #endif // #ifdef WITH_XML
...@@ -51,6 +51,9 @@ class rspec_parser_v2 : public rspec_parser ...@@ -51,6 +51,9 @@ class rspec_parser_v2 : public rspec_parser
std::vector<struct rspec_emulab_extension::type_limit> std::vector<struct rspec_emulab_extension::type_limit>
readTypeLimits(const xercesc::DOMElement* tag, int& count); readTypeLimits(const xercesc::DOMElement* tag, int& count);
std::vector<struct rspec_emulab_extension::fd>
readFeaturesDesires(const xercesc::DOMElement* tag, int& count);
}; };
......
...@@ -14,9 +14,10 @@ static const char rcsid[] = "$Id: solution.cc,v 1.15 2009-10-21 20:49:26 tarunp ...@@ -14,9 +14,10 @@ static const char rcsid[] = "$Id: solution.cc,v 1.15 2009-10-21 20:49:26 tarunp
#include <utility> #include <utility>
#ifdef WITH_XML #ifdef WITH_XML
#include "annotate_rspec.h" #include "annotate_rspec.h"
#include "annotate_vtop.h" #include "annotate_rspec_v2.h"
#include "xstr.h" #include "annotate_vtop.h"
#include "xstr.h"
#endif #endif
extern bool ptop_xml_input; extern bool ptop_xml_input;
...@@ -25,6 +26,8 @@ extern bool ptop_rspec_input; ...@@ -25,6 +26,8 @@ extern bool ptop_rspec_input;
extern bool vtop_xml_input; extern bool vtop_xml_input;
extern bool vtop_rspec_input; extern bool vtop_rspec_input;
extern int rspec_version;
bool both_inputs_rspec = false; bool both_inputs_rspec = false;
bool both_inputs_xml = false; bool both_inputs_xml = false;
...@@ -51,14 +54,22 @@ void print_solution(const solution &s) { ...@@ -51,14 +54,22 @@ void print_solution(const solution &s) {
tb_vnode *vn; tb_vnode *vn;
#ifdef WITH_XML #ifdef WITH_XML
bool is_generated = false; bool is_generated = false;
both_inputs_xml = ptop_xml_input && vtop_xml_input; both_inputs_xml = ptop_xml_input && vtop_xml_input;
both_inputs_rspec = ptop_rspec_input && vtop_rspec_input; both_inputs_rspec = ptop_rspec_input && vtop_rspec_input;
if (both_inputs_rspec == true) if (both_inputs_rspec == true) {
rspec_annotater = new annotate_rspec (); switch (rspec_version) {
else if (both_inputs_xml == true) case 2:
vtop_annotater = new annotate_vtop(); rspec_annotater = new annotate_rspec_v2();
break;
default:
rspec_annotater = new annotate_rspec ();
break;
}
}
else if (both_inputs_xml == true)
vtop_annotater = new annotate_vtop();
#endif #endif