30#include <boost/algorithm/string.hpp>
31#include <boost/format.hpp>
61 if (iter ==
map_.end()) {
62 throw std::runtime_error(
"property not found: " + key);
68 for (; n != tok.
end(); ++n) {
71 }
catch (std::runtime_error &) {
73 throw std::runtime_error(
"property not found: " + key);
94 const std::string &value) {
96 if (key.size() == 1) {
99 std::vector<std::string> subkey(key.begin() + 1, key.end());
100 if (this->
exists(key[0])) {
125 }
catch (std::exception &) {
166 std::vector<const Property *> selection;
170 selection.push_back(
this);
171 for (
const auto &n : tok) {
172 std::vector<const Property *> selected;
173 for (
const Property *p : selection) {
175 if (
wildcmp(n, child.name())) {
176 selected.push_back(&child);
180 selection = selected;
187 std::vector<Property *> selection;
191 selection.push_back(
this);
192 for (
const auto &n : tok) {
193 std::vector<Property *> selected;
196 if (
wildcmp(n, child.name())) {
197 selected.push_back(&child);
201 selection = selected;
210static void start_hndl(
void *data,
const char *el,
const char **attr) {
211 stack<Property *> *property_stack =
212 (stack<Property *> *)XML_GetUserData((XML_Parser *)data);
214 Property *cur = property_stack->top();
217 for (
Index i = 0; attr[i]; i += 2) {
221 property_stack->push(&np);
225 stack<Property *> *property_stack =
226 (stack<Property *> *)XML_GetUserData((XML_Parser *)data);
227 property_stack->pop();
230void char_hndl(
void *data,
const char *txt,
int txtlen) {
231 stack<Property *> *property_stack =
232 (stack<Property *> *)XML_GetUserData((XML_Parser *)data);
234 Property *cur = property_stack->top();
235 cur->
value().append(txt, txtlen);
242 throw std::ios_base::failure(
"Error on open xml file: " + filename);
245 XML_Parser parser = XML_ParserCreate(
nullptr);
247 throw std::runtime_error(
"Couldn't allocate memory for xml parser");
250 XML_UseParserAsHandlerArg(parser);
252 XML_SetCharacterDataHandler(parser,
char_hndl);
254 stack<Property *> pstack;
257 XML_SetUserData(parser, (
void *)&pstack);
262 if (line.length() > (
size_t)std::numeric_limits<int>::max()) {
263 throw std::runtime_error(
"Property::LoadFromXML: line is too long");
265 if (!XML_Parse(parser, line.c_str(), (
int)line.length(), fl.eof())) {
266 throw std::ios_base::failure(
267 filename +
": Parse error at line " +
268 boost::lexical_cast<string>(XML_GetCurrentLineNumber(parser)) +
"\n" +
269 XML_ErrorString(XML_GetErrorCode(parser)));
273 XML_ParserFree(parser);
277 Index level = 0,
string prefix =
"",
string offset =
"") {
279 if (level >= start_level) {
280 if ((p.
value()).find_first_not_of(
"\t\n ") != std::string::npos) {
281 out << offset << prefix <<
" = " << p.
value() << endl;
291 PrintNodeTXT(out, prop, start_level, level, prefix + prop.name(), offset);
293 PrintNodeTXT(out, prop, start_level, level, prefix +
"." + prop.name(),
302 string offset =
"") {
304 bool linebreak =
true;
305 bool has_value =
false;
310 Index start_level(0);
318 string cKey = color->
Magenta();
319 string cAttribute = color->
Blue();
320 string cAttributeValue = color->
Green();
321 string cReset = color->
Reset();
325 if (level >= start_level) {
327 out << indent << offset <<
"<" << cKey << p.
name() << cReset;
330 out <<
" " << cAttribute << ia->first << cReset <<
"=\""
331 << cAttributeValue << ia->second << cReset <<
"\"";
334 has_value = ((p.
value()).find_first_not_of(
"\t\n ") != std::string::npos);
338 out <<
"/>" << std::endl;
341 out << cAttributeValue << p.
value() << cReset;
357 if (level > start_level) {
361 if (level > start_level) {
362 offset.resize(offset.size() - 1);
367 if (level >= start_level) {
369 out << indent << offset <<
"</" << cKey << p.
name() << cReset <<
">"
371 }
else if (has_value) {
372 out <<
"</" << cKey << p.
name() << cReset <<
">" << std::endl;
379 const string &prefix =
"",
const string &offset =
"") {
382 string fmt =
"t|%1%%|15t|" + string(RGB.
Blue()) +
"%2%" +
383 string(RGB.
Green()) +
"%|40t|%3%%|55t|" + string(RGB.
Reset()) +
386 Index leveloffset = level;
389 if (level == start_level) {
390 string head_name = string(RGB.
Magenta()) + p.
name();
395 out << boost::format(
" %1%: %|18t| %2%" +
string(RGB.
Reset()) +
"\n") %
399 out << boost::format(
"%|3" + fmt) %
"OPTION" %
"DEFAULT" %
"UNIT" %
403 if (level > start_level) {
404 string ofmt =
"%|" + boost::lexical_cast<string>(leveloffset) + fmt;
417 unit =
"[" + unit +
"]";
419 if (!defaults.empty()) {
420 defaults =
"(" + defaults +
")";
423 string name = p.
name();
425 out << boost::format(ofmt) % name % defaults % unit % help;
431 PrintNodeHLP(out, pp, start_level, level, pp.name(), offset);
433 PrintNodeHLP(out, pp, start_level, level, prefix +
"." + pp.name(),
445 std::ostream::sentry sentry(out);
452 string indentation(
"");
462 if (!isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) {
base class for all analysis tools