Fawkes API  Fawkes Development Version
parser.cpp
1 
2 /***************************************************************************
3  * parser.cpp - Interface config parser
4  *
5  * Created: Tue Oct 10 17:41:13 2006
6  * Copyright 2006-2015 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "parser.h"
23 
24 #include "checker.h"
25 #include "exceptions.h"
26 
27 #include <interface/interface.h>
28 #include <interface/message.h>
29 #include <libxml++/libxml++.h>
30 #include <utils/misc/string_conversions.h>
31 
32 #include <iostream>
33 #include <vector>
34 
35 using namespace std;
36 using namespace xmlpp;
37 
38 /** @class InterfaceParser interfaces/generator/parser.h
39  * Parser used to get information out of interface template. Uses
40  * XML parser internally.
41  */
42 
43 /** Constructor
44  * @param config_filename file name of config (interface template)
45  */
46 InterfaceParser::InterfaceParser(std::string config_filename)
47 {
48  dom = new DomParser();
49  //dom->set_validate();
50  dom->set_substitute_entities();
51  dom->parse_file(config_filename);
52  root = dom->get_document()->get_root_node();
53  if (root == NULL) {
54  throw InterfaceGeneratorInvalidDocumentException("root == NULL");
55  }
56 }
57 
58 /** Destructor. */
60 {
61  delete dom;
62 }
63 
64 /** Get parsed fields.
65  * Get fields stored below the given node.
66  * @param node root node where to start searching
67  * @param reserved_names reserved names which may not be used as identifiers
68  * @return vector of field representations.
69  */
70 std::vector<InterfaceField>
71 InterfaceParser::getFields(xmlpp::Node *node, const std::set<std::string> &reserved_names)
72 {
73  vector<InterfaceField> result;
74  NodeSet set = node->find("field");
75  for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
76  InterfaceField f(&enum_constants);
77 
78  const Element *el = dynamic_cast<const Element *>(*i);
79  if (el) {
80  // valid element
81  const Element::AttributeList &attrs = el->get_attributes();
82  for (Element::AttributeList::const_iterator iter = attrs.begin(); iter != attrs.end();
83  ++iter) {
84  const Attribute *attr = *iter;
85  //std::cout << " Attribute " << attr->get_name() << " = " << attr->get_value() << std::endl;
86  f.setAttribute(attr->get_name(), attr->get_value());
87  }
88  } else {
89  throw InterfaceGeneratorInvalidContentException("constant is not an element");
90  }
91 
92  // Get field comment
93  NodeSet nameset = (*i)->find("text()");
94  if (nameset.size() == 0) {
95  throw InterfaceGeneratorInvalidContentException("no comment for field %s",
96  f.getName().c_str());
97  }
98  const TextNode *comment_node = dynamic_cast<const TextNode *>(nameset[0]);
99  if (!comment_node) {
100  throw InterfaceGeneratorInvalidContentException("comment node not text node for constant");
101  }
102  f.setComment(comment_node->get_content());
103 
104  //std::cout << "Field name: " << field_name << std::endl;
105  f.valid(reserved_names);
106  result.push_back(f);
107  }
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()) {
111  throw InterfaceGeneratorAmbiguousNameException((*i).getName().c_str(), "field");
112  }
113  }
114  }
115 
116  return result;
117 }
118 
119 /** Get parsed pseudo maps.
120  * Get pseudo maps stored below the given node.
121  * @param node root node where to start searching
122  * @param fields vector of parsed fields, used to detect name clashes
123  * @return vector of pseudo map representations.
124  */
125 std::vector<InterfacePseudoMap>
126 InterfaceParser::getPseudoMaps(xmlpp::Node *node, std::vector<InterfaceField> &fields)
127 {
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;
133 
134  if (el) {
135  Attribute *attr;
136  attr = el->get_attribute("name");
137  if (!attr)
138  throw InterfaceGeneratorInvalidContentException("no name for pseudo map");
139  pm_name = attr->get_value();
140 
141  attr = el->get_attribute("type");
142  if (!attr)
143  throw InterfaceGeneratorInvalidContentException("no type for pseudo map");
144  pm_type = attr->get_value();
145 
146  attr = el->get_attribute("keytype");
147  if (!attr)
148  throw InterfaceGeneratorInvalidContentException("no key type for pseudo map");
149  pm_keytype = attr->get_value();
150  } else {
151  throw InterfaceGeneratorInvalidContentException("pseudo map is not an element");
152  }
153 
154  NodeSet comment_set = (*i)->find("text()");
155  if (comment_set.size() == 0) {
156  throw InterfaceGeneratorInvalidContentException("pseudo map without comment");
157  }
158  std::string pm_comment = "";
159  const TextNode *comment_node = dynamic_cast<const TextNode *>(comment_set[0]);
160  if (comment_node) {
161  pm_comment = comment_node->get_content();
162  } else {
163  throw InterfaceGeneratorInvalidContentException("pseudo map comment not a text node");
164  }
165 
166  InterfacePseudoMap pm(pm_name, pm_type, pm_keytype, pm_comment);
167 
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) {
172  throw InterfaceGeneratorInvalidContentException("pseudo map without referenced field");
173  }
174 
175  const Element *el = dynamic_cast<const Element *>(*r);
176  Attribute * attr;
177  attr = el->get_attribute("key");
178  if (!attr)
179  throw InterfaceGeneratorInvalidContentException("no key for mapref map");
180  std::string mapref_key = attr->get_value();
181 
182  const TextNode *text_node = dynamic_cast<const TextNode *>(ref_set[0]);
183  if (text_node) {
184  // find field in data fields
185  bool found = false;
186  for (vector<InterfaceField>::iterator j = fields.begin(); j != fields.end(); ++j) {
187  if ((*j).getName() == text_node->get_content()) {
188  // field found
189  if (j->getLengthValue() > 0) {
191  "pseudomap references may only point to non-map types");
192  }
193  pm.addRef(text_node->get_content(), mapref_key);
194  found = true;
195  break;
196  }
197  }
198  if (!found) {
199  throw InterfaceGeneratorInvalidContentException("reference to non-existing data field");
200  }
201 
202  } else {
203  throw InterfaceGeneratorInvalidContentException("message ref not a text node");
204  }
205  }
206 
207  try {
208  pm.valid();
209  result.push_back(pm);
210  } catch (fawkes::Exception &e) {
211  e.print_trace();
212  }
213  }
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()) {
217  throw InterfaceGeneratorAmbiguousNameException((*i).getName().c_str(), "field");
218  }
219  }
220  for (vector<InterfaceField>::iterator f = fields.begin(); f != fields.end(); ++f) {
221  if (i->getName() == f->getName()) {
222  throw InterfaceGeneratorAmbiguousNameException((*i).getName().c_str(), "pseudo map");
223  }
224  }
225  }
226 
227  return result;
228 }
229 
230 /** Print fields.
231  * Print fields to stdout.
232  * @param fields fields to print
233  */
234 void
235 InterfaceParser::printFields(vector<InterfaceField> &fields)
236 {
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();
241  }
242  if ((*i).getValidFor() != "") {
243  cout << " validfor=" << (*i).getValidFor();
244  }
245  if ((*i).getDefaultValue() != "") {
246  cout << " default=" << (*i).getDefaultValue();
247  }
248  vector<string> flags = (*i).getFlags();
249  if (flags.size() > 0) {
250  cout << " flags=";
251  vector<string>::iterator j = flags.begin();
252  while (j != flags.end()) {
253  cout << *j;
254  ++j;
255  if (j != flags.end()) {
256  cout << ",";
257  }
258  }
259  }
260  cout << endl;
261  }
262 }
263 
264 /** Print pseudo maps.
265  * @param pseudo_maps pseudo maps to print
266  */
267 void
268 InterfaceParser::printPseudoMaps(vector<InterfacePseudoMap> &pseudo_maps)
269 {
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;
273  InterfacePseudoMap::RefList &reflist = i->getRefList();
274 
275  InterfacePseudoMap::RefList::iterator j;
276  for (j = reflist.begin(); j != reflist.end(); ++j) {
277  cout << " Ref: field=" << j->first << " key=" << j->second << endl;
278  }
279 
280  cout << endl;
281  }
282 }
283 
284 /** Print parsed config.
285  * @param constants parsed constants
286  * @param enum_constants parsed enum_constants
287  * @param data_fields parsed data fields
288  * @param pseudo_maps pseudo maps
289  * @param messages parsed messages.
290  */
291 void
292 InterfaceParser::printParsed(vector<InterfaceConstant> & constants,
293  vector<InterfaceEnumConstant> &enum_constants,
294  vector<InterfaceField> & data_fields,
295  vector<InterfacePseudoMap> & pseudo_maps,
296  vector<InterfaceMessage> & messages)
297 {
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;
302  }
303 
304  cout << "EnumConstants" << endl;
305  for (vector<InterfaceEnumConstant>::iterator i = enum_constants.begin();
306  i != enum_constants.end();
307  ++i) {
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;
313  }
314  }
315 
316  cout << "Data block" << endl;
317  printFields(data_fields);
318  printPseudoMaps(pseudo_maps);
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();
322  printFields(msg_fields);
323  }
324 }
325 
326 /** Print parsed data. */
327 void
329 {
330  printParsed(constants, enum_constants, data_fields, pseudo_maps, messages);
331 }
332 
333 /** Parse config. */
334 void
336 {
337  NodeSet set;
338 
339  constants.clear();
340  enum_constants.clear();
341  data_fields.clear();
342  messages.clear();
343 
344  /*
345  * Name and author
346  *
347  */
348  const Element *el = dynamic_cast<const Element *>(root);
349  if (el) {
350  // valid element
351  Attribute *attr;
352  attr = el->get_attribute("name");
353  if (!attr) {
354  throw InterfaceGeneratorInvalidContentException("no name for interface");
355  }
356  name = attr->get_value();
357  if (name.length() > INTERFACE_TYPE_SIZE_) {
358  throw InterfaceGeneratorInvalidContentException("Interface name too long, max length is %u",
359  INTERFACE_TYPE_SIZE_);
360  }
361 
362  attr = el->get_attribute("author");
363  if (attr) {
364  author = attr->get_value();
365  }
366  attr = el->get_attribute("year");
367  if (attr) {
368  year = attr->get_value();
369  }
370  attr = el->get_attribute("created");
371  if (attr) {
372  creation_date = attr->get_value();
373  }
374  } else {
375  throw InterfaceGeneratorInvalidContentException("root is not an element");
376  }
377 
378  /*
379  * constants
380  *
381  */
382  NodeSet constants_set = root->find("/interface/constants");
383  if (constants_set.size() > 1) {
384  throw InterfaceGeneratorInvalidContentException("more than one constants block");
385  }
386  if (constants_set.size() == 1) {
387  // there are actually constants
388  set = constants_set[0]->find("constant");
389  for (NodeSet::iterator i = set.begin(); i != set.end(); ++i) {
390  // Get constant name
391  NodeSet nameset = (*i)->find("text()");
392  if (nameset.size() == 0) {
393  throw InterfaceGeneratorInvalidContentException("no name for constant");
394  }
395  const TextNode *comment_node = dynamic_cast<const TextNode *>(nameset[0]);
396  if (!comment_node) {
397  throw InterfaceGeneratorInvalidContentException("name node not text node for constant");
398  }
399  std::string const_comment = comment_node->get_content();
400  //std::cout << "Constant name: " << const_name << std::endl;
401 
402  // Get attributes
403  std::string type;
404  std::string value;
405  std::string const_name;
406 
407  el = dynamic_cast<const Element *>(*i);
408  if (el) {
409  // valid element
410  Attribute *attr;
411  attr = el->get_attribute("type");
412  if (!attr) {
413  throw InterfaceGeneratorInvalidContentException("no type for constant");
414  }
415  type = attr->get_value();
416 
417  attr = el->get_attribute("name");
418  if (!attr) {
419  throw InterfaceGeneratorInvalidContentException("no name for constant");
420  }
421  const_name = attr->get_value();
422 
423  attr = el->get_attribute("value");
424  if (!attr) {
425  throw InterfaceGeneratorInvalidContentException("no value for constant");
426  }
427  value = attr->get_value();
428  } else {
429  throw InterfaceGeneratorInvalidContentException("constant is not an element");
430  }
431 
432  // Generate constant object
433  try {
434  InterfaceConstant constant(const_name, type, value, const_comment);
435  constants.push_back(constant);
437  e.print_trace();
439  e.print_trace();
440  }
441  }
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()) {
445  throw InterfaceGeneratorAmbiguousNameException((*i).getName().c_str(), "constant");
446  }
447  }
448  }
449 
450  /*
451  * enums
452  *
453  */
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) {
459  throw InterfaceGeneratorInvalidContentException("no comment for enum");
460  } else {
461  const TextNode *comment_node = dynamic_cast<const TextNode *>(comment_set[0]);
462  if (comment_node) {
463  enum_comment = comment_node->get_content();
464  } else {
465  throw InterfaceGeneratorInvalidContentException("enum comment not a text node");
466  }
467  }
468 
469  string enum_name;
470  el = dynamic_cast<const Element *>(*i);
471  if (el) {
472  // valid element
473  Attribute *attr;
474  attr = el->get_attribute("name");
475  if (!attr) {
476  throw InterfaceGeneratorInvalidContentException("no name for enum");
477  }
478  enum_name = attr->get_value();
479 
480  } else {
481  throw InterfaceGeneratorInvalidContentException("enum is not an element");
482  }
483 
484  InterfaceEnumConstant enum_constant(enum_name, enum_comment);
485 
486  // Get constant name
487  NodeSet items = (*i)->find("item");
488  if (items.size() == 0) {
489  throw InterfaceGeneratorInvalidContentException("no items for enum");
490  }
491 
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);
496  if (el) {
497  // valid element
498  Attribute *attr;
499  attr = el->get_attribute("name");
500  if (!attr) {
501  throw InterfaceGeneratorInvalidContentException("no name for enum item");
502  }
503  item_name = attr->get_value();
504 
505  Attribute *val_attr;
506  val_attr = el->get_attribute("value");
507  if (val_attr) {
508  item_value = val_attr->get_value();
509  }
510 
511  } else {
512  throw InterfaceGeneratorInvalidContentException("enum item is not an element");
513  }
514 
515  comment_set = (*j)->find("text()");
516  if (comment_set.size() == 0) {
517  throw InterfaceGeneratorInvalidContentException("enum item without comment");
518  }
519  const TextNode *comment_node = dynamic_cast<const TextNode *>(comment_set[0]);
520  if (comment_node) {
521  if (item_value != "") {
522  enum_constant.add_item(item_name,
523  comment_node->get_content(),
525  } else {
526  enum_constant.add_item(item_name, comment_node->get_content());
527  }
528  } else {
529  throw InterfaceGeneratorInvalidContentException("enum comment not a text node");
530  }
531  }
532 
533  enum_constants.push_back(enum_constant);
534  }
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()) {
540  throw InterfaceGeneratorAmbiguousNameException((*i).get_name().c_str(), "enum constant");
541  }
542  }
543  }
544  }
545 
546  /*
547  * data
548  *
549  */
550  set = root->find("/interface/data");
551  if (set.size() > 1) {
552  throw InterfaceGeneratorInvalidContentException("more than one data block");
553  } else if (set.size() == 0) {
554  throw InterfaceGeneratorInvalidContentException("no data block");
555  }
556 
557  data_fields = getFields(set[0], reserved_names_interface());
558  if (data_fields.size() == 0) {
559  throw InterfaceGeneratorInvalidContentException("data block contains no field");
560  }
561 
562  pseudo_maps = getPseudoMaps(set[0], data_fields);
563 
564  NodeSet comment_set = root->find("/interface/data/comment/text()");
565  if (comment_set.size() == 0) {
566  throw InterfaceGeneratorInvalidContentException("data block without comment");
567  }
568  const TextNode *comment_node = dynamic_cast<const TextNode *>(comment_set[0]);
569  if (comment_node) {
570  data_comment = comment_node->get_content();
571  } else {
572  throw InterfaceGeneratorInvalidContentException("data block comment not a text node");
573  }
574 
575  /*
576  * Messages
577  *
578  */
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;
583 
584  el = dynamic_cast<const Element *>(*i);
585  if (el) {
586  Attribute *attr;
587  attr = el->get_attribute("name");
588  if (!attr) {
589  throw InterfaceGeneratorInvalidContentException("no name for message");
590  }
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",
595  msg_name.c_str(),
596  INTERFACE_MESSAGE_TYPE_SIZE_ - 1 - std::string("Message").length());
597  }
598  } else {
599  throw InterfaceGeneratorInvalidContentException("message is not an element");
600  }
601 
602  comment_set = (*i)->find("text()");
603  if (comment_set.size() == 0) {
604  throw InterfaceGeneratorInvalidContentException("message without comment");
605  }
606  comment_node = dynamic_cast<const TextNode *>(comment_set[0]);
607  if (comment_node) {
608  msg_comment = comment_node->get_content();
609  } else {
610  throw InterfaceGeneratorInvalidContentException("message comment not a text node");
611  }
612 
613  vector<InterfaceField> msg_fields = getFields(*i, reserved_names_message());
614 
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);
618  if (text_node) {
619  // find field in data fields
620  bool found = false;
621  for (vector<InterfaceField>::iterator j = data_fields.begin(); j != data_fields.end();
622  ++j) {
623  if ((*j).getName() == text_node->get_content()) {
624  // field found
625  msg_fields.push_back(*j);
626  found = true;
627  break;
628  }
629  }
630  if (!found) {
631  throw InterfaceGeneratorInvalidContentException("reference to non-existing data field");
632  }
633  } else {
634  throw InterfaceGeneratorInvalidContentException("message ref not a text node");
635  }
636  }
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()) {
640  throw InterfaceGeneratorAmbiguousNameException((*k).getName().c_str(), "message field");
641  }
642  }
643  }
644 
645  InterfaceMessage msg(msg_name, msg_comment);
646  msg.setFields(msg_fields);
647 
648  messages.push_back(msg);
649  }
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)
656  == 0) {
657  cout << "Possible duplicate at message network syncing detected:" << endl;
658  cout << msg1->getName() << " and " << msg2->getName() << endl << endl;
659  duplicateExists = true;
660  }
661  }
662  }
663  if (duplicateExists)
665  "Duplicates after serializing by BB network handler exist!");
666 }
667 
668 /** Get interface name.
669  * Only valid after parse().
670  * @return interface name.
671  */
672 std::string
674 {
675  return name;
676 }
677 
678 /** Get interface author.
679  * Only valid after parse().
680  * @return interface author.
681  */
682 std::string
684 {
685  return author;
686 }
687 
688 /** Get interface copyright year.
689  * Only valid after parse().
690  * @return interface copyright year
691  */
692 std::string
694 {
695  return year;
696 }
697 
698 /** Get interface creation date as string
699  * Only valid after parse().
700  * @return interface creation date
701  */
702 std::string
704 {
705  return creation_date;
706 }
707 
708 /** Get constants.
709  * Only valid after parse().
710  * @return constants.
711  */
712 std::vector<InterfaceConstant>
714 {
715  return constants;
716 }
717 
718 /** Get enum constants.
719  * Only valid after parse().
720  * @return enum constants.
721  */
722 std::vector<InterfaceEnumConstant>
724 {
725  return enum_constants;
726 }
727 
728 /** Get data fields.
729  * Only valid after parse().
730  * @return data fields.
731  */
732 std::vector<InterfaceField>
734 {
735  return data_fields;
736 }
737 
738 /** Get data pseudo maps.
739  * Only valid after parse().
740  * @return pseudo maps
741  */
742 std::vector<InterfacePseudoMap>
744 {
745  return pseudo_maps;
746 }
747 
748 /** Get data comment.
749  * Only valid after parse().
750  * @return data comment.
751  */
752 std::string
754 {
755  return data_comment;
756 }
757 
758 /** Get messages.
759  * Only valid after parse().
760  * @return messages.
761  */
762 std::vector<InterfaceMessage>
764 {
765  return messages;
766 }
InterfaceParser::getConstants
std::vector< InterfaceConstant > getConstants()
Get constants.
Definition: parser.cpp:713
InterfaceField::getName
std::string getName() const
Get name of field.
Definition: field.cpp:49
InterfaceGeneratorAmbiguousNameException
Thrown if name is ambiguous.
Definition: exceptions.h:157
InterfaceParser::getFields
std::vector< InterfaceField > getFields(xmlpp::Node *node, const std::set< std::string > &reserved_names)
Get parsed fields.
Definition: parser.cpp:71
InterfaceParser::printFields
void printFields(std::vector< InterfaceField > &fields)
Print fields.
Definition: parser.cpp:235
InterfaceParser::parse
void parse()
Parse config.
Definition: parser.cpp:335
InterfaceParser::getInterfaceAuthor
std::string getInterfaceAuthor()
Get interface author.
Definition: parser.cpp:683
InterfacePseudoMap::valid
void valid()
Assert validity.
Definition: pseudomap.cpp:97
InterfaceGeneratorInvalidValueException
Thrown if illegal value is supplied.
Definition: exceptions.h:89
InterfaceParser::getDataFields
std::vector< InterfaceField > getDataFields()
Get data fields.
Definition: parser.cpp:733
InterfaceParser::getInterfaceYear
std::string getInterfaceYear()
Get interface copyright year.
Definition: parser.cpp:693
InterfaceGeneratorInvalidContentException
Thrown if document contains illegal content.
Definition: exceptions.h:51
InterfaceEnumConstant
Definition: enum_constant.h:29
InterfaceParser::getPseudoMaps
std::vector< InterfacePseudoMap > getPseudoMaps()
Get data pseudo maps.
Definition: parser.cpp:743
InterfaceParser::printParsed
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.
Definition: parser.cpp:292
InterfaceField
Definition: field.h:31
InterfaceConstant
Definition: constant.h:27
InterfaceGeneratorInvalidTypeException
Thrown if illegal type is supplied.
Definition: exceptions.h:71
fawkes::StringConversions::to_int
static int to_int(std::string s)
Convert string to an int value.
Definition: string_conversions.cpp:183
InterfaceParser::getInterfaceName
std::string getInterfaceName()
Get interface name.
Definition: parser.cpp:673
InterfaceMessage::setFields
void setFields(const std::vector< InterfaceField > &fields)
Set fields of message.
Definition: message.cpp:67
InterfaceParser::~InterfaceParser
~InterfaceParser()
Destructor.
Definition: parser.cpp:59
InterfaceParser::printPseudoMaps
void printPseudoMaps(std::vector< InterfacePseudoMap > &pseudo_maps)
Print pseudo maps.
Definition: parser.cpp:268
InterfacePseudoMap
Definition: pseudomap.h:30
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:600
InterfaceParser::getDataComment
std::string getDataComment()
Get data comment.
Definition: parser.cpp:753
InterfaceParser::InterfaceParser
InterfaceParser(std::string config_filename)
Constructor.
Definition: parser.cpp:46
InterfaceGeneratorInvalidDocumentException
Thrown if document was invalid.
Definition: exceptions.h:31
InterfaceField::setComment
void setComment(const std::string &comment)
Set comment of field.
Definition: field.cpp:265
InterfaceField::setAttribute
void setAttribute(const std::string &attr_name, const std::string &attr_value)
Set attribute.
Definition: field.cpp:338
InterfacePseudoMap::RefList
std::list< std::pair< std::string, std::string > > RefList
Reference list.
Definition: pseudomap.h:39
InterfaceParser::print
void print()
Print parsed data.
Definition: parser.cpp:328
InterfaceMessage
Definition: message.h:30
InterfaceParser::getEnumConstants
std::vector< InterfaceEnumConstant > getEnumConstants()
Get enum constants.
Definition: parser.cpp:723
InterfaceEnumConstant::add_item
void add_item(std::string name, std::string comment)
Add an item without custom value.
Definition: enum_constant.cpp:77
InterfaceParser::getMessages
std::vector< InterfaceMessage > getMessages()
Get messages.
Definition: parser.cpp:763
InterfaceParser::getInterfaceCreationDate
std::string getInterfaceCreationDate()
Get interface creation date as string Only valid after parse().
Definition: parser.cpp:703
InterfacePseudoMap::addRef
void addRef(std::string fieldname, std::string key)
Add reference.
Definition: pseudomap.cpp:126
InterfaceField::valid
void valid(const std::set< std::string > &reserved_names)
Assert validity.
Definition: field.cpp:366
fawkes::Exception
Definition: exception.h:39