]> git.stg.codes - stg.git/blob - projects/sgconf/xml.cpp
Added XML pretty-printer.
[stg.git] / projects / sgconf / xml.cpp
1 #include "xml.h"
2
3 #include <expat.h>
4
5 namespace
6 {
7
8 struct ParserState
9 {
10 size_t level;
11 };
12
13 std::string Indent(size_t size)
14 {
15 return std::string(level * 4, ' ');
16 }
17
18 std::string PrintAttr(const char ** attr)
19 {
20 std::string res;
21 if (attr == NULL)
22     return res;
23 while (*attr)
24     {
25     if (*(attr + 1) == NULL)
26         return res;
27     res += std::string(" ") + *attr + "=\"" + *(attr + 1) + "\"";
28     ++attr; ++attr;
29     }
30 return res;
31 }
32
33 void Start(void * data, const char * el, const char ** attr)
34 {
35 ParserState * state = static_cast<ParserState *>(data);
36 if (el != NULL)
37     std::cout << Indent(state->level) << "<" << el << PrintAttrs(attr) << ">\n";
38 ++state->level;
39 }
40
41 void End(void * data, const char * el)
42 {
43 ParserState * state = static_cast<ParserState *>(data);
44 if (el != NULL)
45     std::cout << Indent(state->level) << "</" << el << ">\n";
46 --state->level;
47 }
48
49 }
50
51 void SGCONF::PrintXML(const std::string& xml)
52 {
53 ParserState state = { 0 };
54
55 XML_Parser parser = XML_ParserCreate(NULL);
56 XML_ParserReset(parser, NULL);
57 XML_SetElementHandler(parser, Start, End);
58 XML_SetUserData(parser, &state);
59
60 if (XML_Parse(parser, xml.c_str(), xml.length(), true) == XML_STATUS_ERROR)
61     std::cerr << "XML parse error at line " << XML_GetCurrentLineNumber(sc->parser)
62               << ": '" << XML_ErrorString(XML_GetErrorCode(sc->parser)) << "'"
63               << std::endl;
64
65 XML_ParserFree(parser);
66 }