25#include "exceptions.h"
27#include <interface/interface.h>
28#include <interface/message.h>
29#include <libxml++/libxml++.h>
30#include <utils/misc/string_conversions.h>
48 dom =
new DomParser();
50 dom->set_substitute_entities();
51 dom->parse_file(config_filename);
52 root = dom->get_document()->get_root_node();
70std::vector<InterfaceField>
73 vector<InterfaceField> result;
74 NodeSet set = node->find(
"field");
75 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
78 const Element *el =
dynamic_cast<const Element *
>(*i);
81 const Element::AttributeList &attrs = el->get_attributes();
82 for (Element::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end();
84 const Attribute *attr = *iter;
93 NodeSet nameset = (*i)->find(
"text()");
94 if (nameset.size() == 0) {
98 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(nameset[0]);
105 f.
valid(reserved_names);
108 for (vector<InterfaceField>::iterator i = result.begin(); i != result.end(); ++i) {
109 for (vector<InterfaceField>::iterator j = i + 1; j != result.end(); ++j) {
110 if ((*i).getName() == (*j).getName()) {
125std::vector<InterfacePseudoMap>
128 vector<InterfacePseudoMap> result;
129 NodeSet set = node->find(
"pseudomap");
130 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
131 const Element *el =
dynamic_cast<const Element *
>(*i);
132 std::string pm_name, pm_type, pm_keytype;
136 attr = el->get_attribute(
"name");
139 pm_name = attr->get_value();
141 attr = el->get_attribute(
"type");
144 pm_type = attr->get_value();
146 attr = el->get_attribute(
"keytype");
149 pm_keytype = attr->get_value();
154 NodeSet comment_set = (*i)->find(
"text()");
155 if (comment_set.size() == 0) {
158 std::string pm_comment =
"";
159 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
161 pm_comment = comment_node->get_content();
168 NodeSet ref_nodes = (*i)->find(
"mapref");
169 for (NodeSet::iterator r = ref_nodes.begin(); r != ref_nodes.end(); ++r) {
170 NodeSet ref_set = (*r)->find(
"text()");
171 if (ref_set.size() == 0) {
175 const Element *el =
dynamic_cast<const Element *
>(*r);
177 attr = el->get_attribute(
"key");
180 std::string mapref_key = attr->get_value();
182 const TextNode *text_node =
dynamic_cast<const TextNode *
>(ref_set[0]);
186 for (vector<InterfaceField>::iterator j = fields.begin(); j != fields.end(); ++j) {
187 if ((*j).getName() == text_node->get_content()) {
189 if (j->getLengthValue() > 0) {
191 "pseudomap references may only point to non-map types");
193 pm.
addRef(text_node->get_content(), mapref_key);
209 result.push_back(pm);
214 for (vector<InterfacePseudoMap>::iterator i = result.begin(); i != result.end(); ++i) {
215 for (vector<InterfacePseudoMap>::iterator j = i + 1; j != result.end(); ++j) {
216 if ((*i).getName() == (*j).getName()) {
220 for (vector<InterfaceField>::iterator f = fields.begin(); f != fields.end(); ++f) {
221 if (i->getName() == f->getName()) {
237 for (vector<InterfaceField>::iterator i = fields.begin(); i != fields.end(); ++i) {
238 cout <<
" Field: name=" << (*i).getName() <<
" type=" << (*i).getType();
239 if ((*i).getLength() !=
"") {
240 cout <<
" length=" << (*i).getLength();
242 if ((*i).getValidFor() !=
"") {
243 cout <<
" validfor=" << (*i).getValidFor();
245 if ((*i).getDefaultValue() !=
"") {
246 cout <<
" default=" << (*i).getDefaultValue();
248 vector<string> flags = (*i).getFlags();
249 if (flags.size() > 0) {
251 vector<string>::iterator j = flags.begin();
252 while (j != flags.end()) {
255 if (j != flags.end()) {
270 for (vector<InterfacePseudoMap>::iterator i = pseudo_maps.begin(); i != pseudo_maps.end(); ++i) {
271 cout <<
" PseudoMap: name=" << i->getName() <<
" type=" << i->getType()
272 <<
" keytype=" << i->getKeyType() << endl;
275 InterfacePseudoMap::RefList::iterator j;
276 for (j = reflist.begin(); j != reflist.end(); ++j) {
277 cout <<
" Ref: field=" << j->first <<
" key=" << j->second << endl;
293 vector<InterfaceEnumConstant> &enum_constants,
294 vector<InterfaceField> & data_fields,
295 vector<InterfacePseudoMap> & pseudo_maps,
296 vector<InterfaceMessage> & messages)
298 cout <<
"Constants" << endl;
299 for (vector<InterfaceConstant>::iterator i = constants.begin(); i != constants.end(); ++i) {
300 cout <<
" Constant: name=" << (*i).getName() <<
" type=" << (*i).getType()
301 <<
" value=" << (*i).getValue() << endl;
304 cout <<
"EnumConstants" << endl;
305 for (vector<InterfaceEnumConstant>::iterator i = enum_constants.begin();
306 i != enum_constants.end();
308 cout <<
" EnumConstant: name=" << (*i).get_name() << endl;
309 vector<InterfaceEnumConstant::EnumItem> items = (*i).get_items();
310 vector<InterfaceEnumConstant::EnumItem>::iterator j;
311 for (j = items.begin(); j != items.end(); ++j) {
312 cout <<
" Item: " << j->name <<
"(" << j->comment <<
")" << endl;
316 cout <<
"Data block" << endl;
319 for (vector<InterfaceMessage>::iterator i = messages.begin(); i != messages.end(); ++i) {
320 cout <<
"Message: name=" << (*i).getName() << endl;
321 vector<InterfaceField> msg_fields = (*i).getFields();
330 printParsed(constants, enum_constants, data_fields, pseudo_maps, messages);
340 enum_constants.clear();
348 const Element *el =
dynamic_cast<const Element *
>(root);
352 attr = el->get_attribute(
"name");
356 name = attr->get_value();
357 if (name.length() > INTERFACE_TYPE_SIZE_) {
359 INTERFACE_TYPE_SIZE_);
362 attr = el->get_attribute(
"author");
364 author = attr->get_value();
366 attr = el->get_attribute(
"year");
368 year = attr->get_value();
370 attr = el->get_attribute(
"created");
372 creation_date = attr->get_value();
382 NodeSet constants_set = root->find(
"/interface/constants");
383 if (constants_set.size() > 1) {
386 if (constants_set.size() == 1) {
388 set = constants_set[0]->find(
"constant");
389 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
391 NodeSet nameset = (*i)->find(
"text()");
392 if (nameset.size() == 0) {
395 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(nameset[0]);
399 std::string const_comment = comment_node->get_content();
405 std::string const_name;
407 el =
dynamic_cast<const Element *
>(*i);
411 attr = el->get_attribute(
"type");
415 type = attr->get_value();
417 attr = el->get_attribute(
"name");
421 const_name = attr->get_value();
423 attr = el->get_attribute(
"value");
427 value = attr->get_value();
435 constants.push_back(constant);
442 for (vector<InterfaceConstant>::iterator i = constants.begin(); i != constants.end(); ++i) {
443 for (vector<InterfaceConstant>::iterator j = i + 1; j != constants.end(); ++j) {
444 if ((*i).getName() == (*j).getName()) {
454 set = constants_set[0]->find(
"enum");
455 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
456 std::string enum_comment;
457 NodeSet comment_set = (*i)->find(
"comment/text()");
458 if (comment_set.size() == 0) {
461 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
463 enum_comment = comment_node->get_content();
470 el =
dynamic_cast<const Element *
>(*i);
474 attr = el->get_attribute(
"name");
478 enum_name = attr->get_value();
487 NodeSet items = (*i)->find(
"item");
488 if (items.size() == 0) {
492 for (NodeSet::iterator j = items.begin(); j != items.end(); ++j) {
493 std::string item_name;
494 std::string item_value;
495 el =
dynamic_cast<const Element *
>(*j);
499 attr = el->get_attribute(
"name");
503 item_name = attr->get_value();
506 val_attr = el->get_attribute(
"value");
508 item_value = val_attr->get_value();
515 comment_set = (*j)->find(
"text()");
516 if (comment_set.size() == 0) {
519 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
521 if (item_value !=
"") {
523 comment_node->get_content(),
526 enum_constant.
add_item(item_name, comment_node->get_content());
533 enum_constants.push_back(enum_constant);
535 vector<InterfaceEnumConstant>::iterator i;
536 for (i = enum_constants.begin(); i != enum_constants.end(); ++i) {
537 vector<InterfaceEnumConstant>::iterator j;
538 for (j = i + 1; j != enum_constants.end(); ++j) {
539 if (i->get_name() == j->get_name()) {
550 set = root->find(
"/interface/data");
551 if (set.size() > 1) {
553 }
else if (set.size() == 0) {
557 data_fields =
getFields(set[0], reserved_names_interface());
558 if (data_fields.size() == 0) {
564 NodeSet comment_set = root->find(
"/interface/data/comment/text()");
565 if (comment_set.size() == 0) {
568 const TextNode *comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
570 data_comment = comment_node->get_content();
579 set = root->find(
"/interface/message");
580 for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
581 std::string msg_name;
582 std::string msg_comment;
584 el =
dynamic_cast<const Element *
>(*i);
587 attr = el->get_attribute(
"name");
591 msg_name = attr->get_value();
592 if (msg_name.length() + std::string(
"Message").length() > INTERFACE_MESSAGE_TYPE_SIZE_ - 1) {
594 "Interface message name '%s' too long, max length is %u",
596 INTERFACE_MESSAGE_TYPE_SIZE_ - 1 - std::string(
"Message").length());
602 comment_set = (*i)->find(
"text()");
603 if (comment_set.size() == 0) {
606 comment_node =
dynamic_cast<const TextNode *
>(comment_set[0]);
608 msg_comment = comment_node->get_content();
613 vector<InterfaceField> msg_fields =
getFields(*i, reserved_names_message());
615 NodeSet ref_nodes = (*i)->find(
"ref/text()");
616 for (NodeSet::iterator r = ref_nodes.begin(); r != ref_nodes.end(); ++r) {
617 const TextNode *text_node =
dynamic_cast<const TextNode *
>(*r);
621 for (vector<InterfaceField>::iterator j = data_fields.begin(); j != data_fields.end();
623 if ((*j).getName() == text_node->get_content()) {
625 msg_fields.push_back(*j);
637 for (vector<InterfaceField>::iterator k = msg_fields.begin(); k != msg_fields.end(); ++k) {
638 for (vector<InterfaceField>::iterator j = k + 1; j != msg_fields.end(); ++j) {
639 if ((*k).getName() == (*j).getName()) {
648 messages.push_back(msg);
650 bool duplicateExists =
false;
651 for (
auto msg1 = messages.begin(); msg1 != messages.end(); ++msg1) {
652 for (
auto msg2 = msg1 + 1; msg2 != messages.end(); ++msg2) {
653 if (strncmp(msg1->getName().c_str(),
654 msg2->getName().c_str(),
655 INTERFACE_MESSAGE_TYPE_SIZE_ - 1)
657 cout <<
"Possible duplicate at message network syncing detected:" << endl;
658 cout << msg1->getName() <<
" and " << msg2->getName() << endl << endl;
659 duplicateExists =
true;
665 "Duplicates after serializing by BB network handler exist!");
705 return creation_date;
712std::vector<InterfaceConstant>
722std::vector<InterfaceEnumConstant>
725 return enum_constants;
732std::vector<InterfaceField>
742std::vector<InterfacePseudoMap>
762std::vector<InterfaceMessage>
Interface generator internal representation of a constant as parsed from the XML template file.
Interface generator internal representation of a enum constant as parsed from the XML template file.
void add_item(std::string name, std::string comment)
Add an item without custom value.
Interface generator internal representation of a field as parsed from the XML template file.
void setAttribute(const std::string &attr_name, const std::string &attr_value)
Set attribute.
std::string getName() const
Get name of field.
void valid(const std::set< std::string > &reserved_names)
Assert validity.
void setComment(const std::string &comment)
Set comment of field.
Thrown if name is ambiguous.
Thrown if document contains illegal content.
Thrown if document was invalid.
Thrown if illegal type is supplied.
Thrown if illegal value is supplied.
Interface generator internal representation of a message as parsed from the XML template file.
void setFields(const std::vector< InterfaceField > &fields)
Set fields of message.
std::vector< InterfaceField > getDataFields()
Get data fields.
void print()
Print parsed data.
~InterfaceParser()
Destructor.
std::vector< InterfaceField > getFields(xmlpp::Node *node, const std::set< std::string > &reserved_names)
Get parsed fields.
std::vector< InterfaceEnumConstant > getEnumConstants()
Get enum constants.
InterfaceParser(std::string config_filename)
Constructor.
std::vector< InterfacePseudoMap > getPseudoMaps()
Get data pseudo maps.
std::vector< InterfaceConstant > getConstants()
Get constants.
std::string getInterfaceCreationDate()
Get interface creation date as string Only valid after parse().
std::string getInterfaceAuthor()
Get interface author.
void printPseudoMaps(std::vector< InterfacePseudoMap > &pseudo_maps)
Print pseudo maps.
void printFields(std::vector< InterfaceField > &fields)
Print fields.
void printParsed(std::vector< InterfaceConstant > &constants, std::vector< InterfaceEnumConstant > &enum_constants, std::vector< InterfaceField > &data_fields, std::vector< InterfacePseudoMap > &pseudo_maps, std::vector< InterfaceMessage > &messages)
Print parsed config.
std::string getInterfaceYear()
Get interface copyright year.
void parse()
Parse config.
std::string getDataComment()
Get data comment.
std::string getInterfaceName()
Get interface name.
std::vector< InterfaceMessage > getMessages()
Get messages.
Interface generator internal representation of a pseudo map as parsed from the XML template file.
std::list< std::pair< std::string, std::string > > RefList
Reference list.
void addRef(std::string fieldname, std::string key)
Add reference.
void valid()
Assert validity.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
static int to_int(std::string s)
Convert string to an int value.