ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
XML.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
6
7#ifndef _CRT_SECURE_NO_WARNINGS
8#define _CRT_SECURE_NO_WARNINGS
9#endif
10#ifndef NO_ETISS
11#include "etiss/fault/XML.h"
12#else
13#include "fault/XML.h"
14#endif
15
16#include <sstream>
17
18namespace etiss
19{
20
21namespace fault
22{
23
24// some helper for changing Core Names
26void setCoreName(std::string &str)
27{
28 size_t pos = 0;
29 std::string token = "%i%";
30 std::string replace = std::to_string(coreIDActuallXML);
31 while ((pos = str.find(token, pos)) != std::string::npos)
32 {
33 str.replace(pos, token.length(), replace);
34 pos += replace.length();
35 }
36}
37
38#if ETISS_FAULT_XML
39namespace xml
40{
41
42void Diagnostics::ignoredNode(const pugi::xml_node &node, const std::string &msg)
43{
44 warnings.push_back(std::string("XML Warning: ") + msg + " [" + node.path() + "]");
45}
46void Diagnostics::unexpectedNode(const pugi::xml_node &node, const std::string &msg)
47{
48 errors.push_back(std::string("XML Error: ") + msg + " [" + node.path() + "]");
49}
50void Diagnostics::print(std::ostream &out) const
51{
52 for (std::list<std::string>::const_iterator iter = warnings.begin(); iter != warnings.end(); ++iter)
53 {
54 out << *iter << std::endl;
55 }
56 for (std::list<std::string>::const_iterator iter = errors.begin(); iter != errors.end(); ++iter)
57 {
58 out << *iter << std::endl;
59 }
60}
61
62template <>
63bool parse<std::string>(pugi::xml_node node, std::string &dst, Diagnostics &diag)
64{
65 if (node.type() == pugi::node_null)
66 {
67 diag.unexpectedNode(node, "cannot get string from null node");
68 return false;
69 }
70 pugi::xml_node tnode = node.first_child();
71 if (tnode.type() != pugi::node_pcdata)
72 {
73 diag.unexpectedNode(tnode, "cannot get string from non pcdata node");
74 return false;
75 }
76 if (tnode.next_sibling().type() != pugi::node_null)
77 {
78 diag.unexpectedNode(node, "node conatains more than just one text node");
79 return false;
80 }
81 dst = tnode.value();
82 return true;
83}
84template <>
85bool write<std::string>(pugi::xml_node node, const std::string &src, Diagnostics &diag)
86{
87 node.append_child(pugi::node_pcdata).set_value(src.c_str());
88 return true;
89}
90
91template <>
92bool parse<uint64_t>(pugi::xml_node node, uint64_t &dst, Diagnostics &diag)
93{
94 std::string ret;
95 if (!parse<std::string>(node, ret, diag))
96 {
97 return false;
98 }
99 return fromString(ret, dst);
100}
101
102bool parse_hex(pugi::xml_node node, uint64_t &dst, Diagnostics &diag)
103{
104 std::string ret;
105 if (!parse<std::string>(node, ret, diag))
106 {
107 return false;
108 }
109 uint64_t val;
110 val = std::stoll(ret, nullptr, 16);
111 dst = val;
112 return true;
113}
114template <>
115bool write<uint64_t>(pugi::xml_node node, const uint64_t &src, Diagnostics &diag)
116{
117 return write<std::string>(node, std::to_string(src), diag);
118}
119
120template <>
121bool parse<unsigned>(pugi::xml_node node, unsigned &dst, Diagnostics &diag)
122{
123 std::string ret;
124 if (!parse<std::string>(node, ret, diag))
125 {
126 return false;
127 }
128 return fromString(ret, dst);
129}
130template <>
131bool write<unsigned>(pugi::xml_node node, const unsigned &src, Diagnostics &diag)
132{
133 return write<std::string>(node, std::to_string(src), diag);
134}
135
136template <>
137bool parse_attr<std::string>(pugi::xml_node node, const std::string &attr_name, std::string &dst, Diagnostics &diag)
138{
139 unsigned count = 0;
140 for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute())
141 {
142 if (hasName(attr, attr_name))
143 {
144 if (count == 0)
145 {
146 dst = attr.value();
147 }
148 else
149 {
150 diag.unexpectedNode(node, std::string("Duplicated attribute: ") + attr_name);
151 }
152 count++;
153 }
154 }
155 return count == 1;
156}
157
158template <>
159bool write_attr<std::string>(pugi::xml_node node, const std::string &attr_name, const std::string &src,
160 Diagnostics &diag)
161{
162 for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute())
163 {
164 if (hasName(attr, attr_name))
165 {
166 attr.set_value(src.c_str());
167 return true;
168 }
169 }
170 node.append_attribute(attr_name.c_str()).set_value(src.c_str());
171 return true;
172}
173
174template <>
175bool fromString<uint64_t>(const std::string &s, uint64_t &val)
176{
177#if CXX0X_UP_SUPPORTED
178 static_assert(sizeof(uint64_t) <= sizeof(unsigned long long), "cannot convert string to uint64_t with stoull");
179 try
180 {
181 val = std::stoull(s);
182 return true;
183 }
184 catch (...)
185 {
186 return false;
187 }
188#else
189 unsigned long long tmp;
190 if (!sscanf(s.c_str(), "%llu", &tmp))
191 return false;
192 val = (uint64_t)tmp;
193 return true;
194#endif
195}
196template <>
197bool fromString<unsigned>(const std::string &s, unsigned &val)
198{
199#if CXX0X_UP_SUPPORTED
200 try
201 {
202 val = (unsigned)std::stoull(s);
203 return true;
204 }
205 catch (...)
206 {
207 return false;
208 }
209#else
210 if (!sscanf(s.c_str(), "%iu", &val))
211 return false;
212 return true;
213#endif
214}
215
216bool hasName(const pugi::xml_node &node, const std::string &name)
217{
218 const char *cname = node.name();
219 if (cname == 0)
220 return false;
221 return name == cname;
222}
223bool hasName(const pugi::xml_attribute &attr, const std::string &name)
224{
225 const char *cname = attr.name();
226 if (cname == 0)
227 return false;
228 return name == cname;
229}
230
231pugi::xml_node findSingleNode(pugi::xml_node node, const std::string &name, Diagnostics &diag)
232{
233 pugi::xml_node ret;
234 bool retset = false;
235 for (pugi::xml_node cnode = node.first_child(); cnode; cnode = cnode.next_sibling())
236 {
237 if (hasName(cnode, name))
238 {
239 if (retset)
240 {
241 ret = pugi::xml_node();
242 diag.unexpectedNode(cnode, "only one node with this name may exist");
243 }
244 else
245 {
246 retset = true;
247 ret = cnode;
248 }
249 }
250 }
251 return ret;
252}
253
254} // namespace xml
255#endif
256
257bool parseXML(pugi::xml_document &doc, std::istream &input, std::ostream &diagnostics_out)
258{
259 pugi::xml_parse_result pr = doc.load(input); // load from stream
260
261 if (!pr)
262 { // load failure
263 diagnostics_out << "failed to load xml from stream: " << pr.description() << std::endl;
264 return false;
265 }
266
267 return true;
268}
269
270} // namespace fault
271
272} // namespace etiss
contains XML related functions.
__device__ __2f16 float bool s
static __inline__ uint64_t
Definition arm_cde.h:31
void setCoreName(std::string &str)
Definition XML.cpp:26
int coreIDActuallXML
Definition XML.cpp:25
bool parseXML(pugi::xml_document &doc, std::istream &input, std::ostream &diagnostics_out=std::cout)
parse a XML document held in input stream and return as doc
Definition XML.cpp:257
forwards: include/jit/*
Definition Benchmark.h:17