GCC Code Coverage Report


Directory: ./
File: src/parser.cc
Date: 2025-05-17 13:07:10
Exec Total Coverage
Lines: 0 153 0.0%
Functions: 0 39 0.0%
Branches: 0 206 0.0%

Line Branch Exec Source
1 // Copyright (c) 2014, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include "hpp/util/parser.hh"
30
31 #include <stdexcept>
32
33 #include "hpp/util/debug.hh"
34
35 namespace hpp {
36 namespace util {
37 namespace parser {
38 ✗ Parser::Parser(FactoryType defaultFactory)
39 ✗ : doc_(), root_(NULL), defaultFactory_(defaultFactory) {}
40
41 ✗ Parser::~Parser() {
42 ✗ for (ObjectFactoryList::iterator it = objectFactories_.begin();
43 ✗ it != objectFactories_.end(); ++it)
44 ✗ delete *it;
45 ✗ if (root_ != NULL) delete root_;
46 ✗ }
47
48 ✗ void Parser::parse(const char* xmlString) {
49 ✗ doc_.Parse(xmlString);
50
51 ✗ parse();
52 ✗ }
53
54 ✗ void Parser::parseFile(const std::string& filename) {
55 ✗ doc_.LoadFile(filename.c_str());
56 ✗ parse();
57 ✗ }
58
59 ✗ bool Parser::checkError() const {
60 ✗ if (doc_.Error()) {
61 hppDout(error, doc_.ErrorStr());
62 ✗ return true;
63 }
64 ✗ return false;
65 }
66
67 ✗ void Parser::parse() {
68 ✗ const XMLElement* el = doc_.RootElement();
69 ✗ root_ = new ObjectFactory();
70 ✗ while (el != NULL) {
71 ✗ parseElement(el, root_);
72 ✗ el = el->NextSiblingElement();
73 }
74 ✗ for (ObjectFactoryList::iterator it = objectFactories_.begin();
75 ✗ it != objectFactories_.end(); ++it)
76 ✗ (*it)->finishFile();
77 ✗ }
78
79 ✗ void Parser::addObjectFactory(const std::string& tagname, FactoryType factory) {
80 ObjectFactoryInsertRet ret =
81 ✗ objFactoryMap_.insert(ObjectFactoryPair(tagname, factory));
82 ✗ if (!ret.second) throw std::logic_error("This tagname already exist");
83 ✗ }
84
85 ✗ void Parser::parseElement(const XMLElement* element, ObjectFactory* parent) {
86 ✗ if (element == NULL) return;
87
88 ✗ ObjectFactory* o = NULL;
89 /// Look for this element in the map
90 ✗ ObjectFactoryMap::const_iterator it = objFactoryMap_.find(element->Value());
91 ✗ if (it != objFactoryMap_.end())
92 ✗ o = it->second(parent, element);
93 else {
94 ✗ o = defaultFactory_(parent, element);
95 hppDout(warning, "I have no factory for tag " << o->tagName());
96 }
97 ✗ objectFactories_.push_back(o);
98 ✗ if (!o->init()) return;
99 ✗ for (const XMLAttribute* attr = element->FirstAttribute(); attr;
100 ✗ attr = attr->Next())
101 ✗ o->setAttribute(attr);
102 ✗ if (!o->finishAttributes()) return;
103
104 /// Loop over is child tags
105 ✗ for (const XMLNode* el = element->FirstChild(); el; el = el->NextSibling()) {
106 ✗ if (el->ToElement() != NULL) {
107 ✗ parseElement(el->ToElement(), o);
108 ✗ } else if (el->ToUnknown() != NULL) {
109 hppDout(warning, "Unknown Node in XML file: " << el->Value());
110 ✗ } else if (el->ToText() != NULL) {
111 ✗ o->addTextChild(el->ToText());
112 ✗ } else if (el->ToComment() != NULL) {
113 }
114 }
115 ✗ o->finishTags();
116 }
117
118 ✗ ObjectFactory* Parser::root() const { return root_; }
119
120 ✗ std::ostream& Parser::print(std::ostream& os) const {
121 ✗ os << "Parser with " << objectFactories_.size() << " object." << std::endl;
122 ✗ if (root_ != NULL) os << *root_;
123 ✗ return os;
124 }
125
126 ✗ std::ostream& operator<<(std::ostream& os, const Parser& p) {
127 ✗ return p.print(os);
128 }
129
130 ✗ std::ostream& operator<<(std::ostream& os, const ObjectFactory& o) {
131 ✗ return o.print(os);
132 }
133
134 ✗ ObjectFactory::ObjectFactory(ObjectFactory* parent, const XMLElement* element)
135 ✗ : parent_(parent), root_(NULL), element_(element), id_(-1) {
136 ✗ if (element_ != NULL)
137 ✗ tagName_ = element_->Value();
138 else
139 ✗ tagName_ = "unamed_tag";
140 ✗ if (parent_ == NULL) {
141 ✗ root_ = this;
142 } else {
143 ✗ root_ = parent_->root();
144 ✗ if (element_ != NULL) parent_->addChild(this);
145 }
146 ✗ }
147
148 ✗ ObjectFactory::ObjectFactory(ObjectFactory* root)
149 ✗ : parent_(NULL), root_(root), element_(NULL), id_(-1) {}
150
151 ✗ bool ObjectFactory::init() { return true; }
152
153 ✗ bool ObjectFactory::finishAttributes() { return true; }
154
155 ✗ void ObjectFactory::finishTags() {}
156
157 ✗ void ObjectFactory::finishFile() {}
158
159 ✗ void ObjectFactory::addTextChild(const XMLText* /* text */) {}
160
161 ✗ ObjectFactory::ObjectFactory(const std::string& tagName, ObjectFactory* parent)
162 ✗ : parent_(parent), root_(NULL), element_(NULL), tagName_(tagName), id_(-1) {
163 ✗ if (parent_ == NULL)
164 ✗ root_ = this;
165 else {
166 ✗ root_ = parent_->root();
167 ✗ parent_->addChild(this);
168 }
169 ✗ }
170
171 ✗ void ObjectFactory::addAttribute(const std::string& name,
172 const std::string& value) {
173 ✗ attrMap_[name] = value;
174 ✗ }
175
176 /// Get a new XMLElement from the content of this factory
177 ✗ XMLNode* ObjectFactory::write(XMLNode* parent) const {
178 ✗ XMLElement* el = parent->GetDocument()->NewElement(tagName().c_str());
179 ✗ for (AttributeMap::const_iterator it = attrMap_.begin(); it != attrMap_.end();
180 ✗ ++it)
181 ✗ el->SetAttribute(it->first.c_str(), it->second.c_str());
182 ✗ for (ChildrenMap::const_iterator it = children_.begin();
183 ✗ it != children_.end(); ++it)
184 ✗ for (ObjectFactoryList::const_iterator of = it->second.begin();
185 ✗ of != it->second.end(); ++of)
186 ✗ (*of)->write(el);
187 ✗ impl_write(el);
188 ✗ return parent->InsertEndChild(el);
189 }
190
191 ✗ std::string ObjectFactory::tagName() const { return tagName_; }
192
193 ✗ std::string ObjectFactory::name() const { return name_; }
194
195 ✗ void ObjectFactory::name(const std::string& n) { name_ = n; }
196
197 ✗ void ObjectFactory::name(const char* n) { name(std::string(n)); }
198
199 ✗ ObjectFactory* ObjectFactory::parent() { return parent_; }
200
201 ✗ ObjectFactory* ObjectFactory::root() { return root_; }
202
203 ✗ bool ObjectFactory::hasParent() const { return parent_ != NULL; }
204
205 ✗ const XMLElement* ObjectFactory::XMLelement() { return element_; }
206
207 ✗ void ObjectFactory::impl_setAttribute(const XMLAttribute* /* attr */) {}
208
209 ✗ void ObjectFactory::impl_write(XMLElement*) const {}
210
211 ✗ void ObjectFactory::addChild(ObjectFactory* child) {
212 ✗ children_[child->tagName()].push_back(child);
213 ✗ }
214
215 ✗ std::list<ObjectFactory*> ObjectFactory::getChildrenOfType(std::string type) {
216 ✗ return children_[type];
217 }
218
219 ✗ bool ObjectFactory::getChildOfType(std::string type, ObjectFactory*& o) {
220 ✗ ObjectFactoryList l = getChildrenOfType(type);
221 ✗ if (l.empty()) {
222 ✗ throw std::invalid_argument("Tag " + tagName() + " has no child of type " +
223 ✗ type);
224 }
225 ✗ o = l.front();
226 ✗ if (l.size() != 1) {
227 hppDout(warning, "Tag " << tagName() << " has several children of type "
228 << type << ". All but the first will be ignored.");
229 ✗ return false;
230 }
231 ✗ return true;
232 ✗ }
233
234 ✗ std::ostream& ObjectFactory::print(std::ostream& os) const {
235 ✗ os << "ObjectFactory " << tagName() << " with name " << name() << std::endl;
236 ✗ for (ChildrenMap::const_iterator itTagName = children_.begin();
237 ✗ itTagName != children_.end(); ++itTagName)
238 ✗ for (ObjectFactoryList::const_iterator itObj = itTagName->second.begin();
239 ✗ itObj != itTagName->second.end(); ++itObj)
240 ✗ os << **itObj;
241 ✗ return os;
242 }
243
244 ✗ void ObjectFactory::setAttribute(const XMLAttribute* attr) {
245 ✗ std::string n = std::string(attr->Name());
246 ✗ if (n == "name")
247 ✗ name(attr->Value());
248 ✗ else if (n == "id") {
249 int v;
250 ✗ if (attr->QueryIntValue(&v) != tinyxml2::XML_SUCCESS) {
251 hppDout(error, "Attribute ID " << attr->Value() << " is incorrect.");
252 } else {
253 ✗ id_ = (int)v;
254 }
255 }
256 ✗ attrMap_[n] = attr->Value();
257 ✗ impl_setAttribute(attr);
258 ✗ }
259
260 ✗ bool ObjectFactory::hasAttribute(const std::string& attr) const {
261 ✗ return attrMap_.find(attr) != attrMap_.end();
262 }
263
264 ✗ std::string ObjectFactory::getAttribute(const std::string& attr) const {
265 ✗ AttributeMap::const_iterator it = attrMap_.find(attr);
266 ✗ if (it == attrMap_.end()) {
267 hppDout(error, "Asking for attribute " << attr);
268 ✗ return std::string();
269 }
270 ✗ return it->second;
271 }
272 } // namespace parser
273 } // namespace util
274 } // namespace hpp
275