1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include <iostream>
26 #include <vector>
27 #include <cstdio>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <xml/xml.h>
32 #include <unistd.h>
33 #include <memory.h>
34 #include <stdlib.h>
35
36 using namespace std;
37 const char* arg0;
38
39 bool Inhale(const char* path, vector<char>& data)
40 {
41 struct stat st;
42
43 mike 1.1 if (stat(path, &st) != 0)
44 {
45 cerr << arg0 << ": failed to stat file: " << path << endl;
46 exit(1);
47 }
48
49 data.reserve(st.st_size + 1);
50
51 FILE* is = fopen(path, "r");
52
53 if (!is)
54 return false;
55
56 size_t n;
57 char buf[4096];
58
59 while ((n = fread(buf, 1, sizeof(buf), is)) != 0)
60 {
61 data.insert(data.end(), buf, buf + n);
62 }
63
64 mike 1.1 data.push_back('\0');
65
66 fclose(is);
67
68 return true;
69 }
70
71 static void Indent(size_t level)
72 {
73 size_t n = level * 2;
74
75 for (size_t i = 0; i < n; i++)
76 {
77 putchar(' ');
78 }
79 }
80
81 static void Print(const char* path)
82 {
83 XML xml;
84 XML_Elem e;
85 mike 1.1 int r;
86 vector<char> data;
87 size_t level = 0;
88
89 if (!Inhale(path, data))
90 {
91 cerr << arg0 << ": failed to open " << path << endl;
92 exit(1);
93 }
94
95 XML_Init(&xml);
96 XML_SetText(&xml, &data[0]);
97
98 while ((r = XML_Next(&xml, &e)) == 0)
99 {
100 switch (e.type)
101 {
102 case XML_NONE:
103 break;
104 case XML_INSTRUCTION:
105 case XML_START:
106 mike 1.1 {
107 Indent(level);
108
109 if (e.type == XML_START)
110 {
111 printf("<%.*s", (int)e.size, e.data);
112 level++;
113 }
114 else
115 printf("<?%.*s", (int)e.size, e.data);
116
117 if (e.attrsSize)
118 printf(" ");
119
120 for (size_t i = 0; i < e.attrsSize; i++)
121 {
122 const XML_Attr& a = e.attrs[i];
123
124 printf("%s=\"%s\"", a.name, a.value);
125
126 if (i + 1 != e.attrsSize)
127 mike 1.1 {
128 printf(" ");
129 }
130 }
131
132 if (e.type == XML_START)
133 printf(">\n");
134 else
135 printf("?>\n");
136 break;
137 }
138 case XML_END:
139 {
140 level--;
141 Indent(level);
142 printf("</%.*s>\n", (int)e.size, e.data);
143
144 break;
145 }
146 case XML_CHARS:
147 {
148 mike 1.1 Indent(level);
149 printf("%.*s\n", (int)e.size, e.data);
150 break;
151 }
152 case XML_COMMENT:
153 {
154 Indent(level);
155 printf("<!--%.*s-->\n", (int)e.size, e.data);
156 break;
157 }
158 }
159 }
160
161 if (r != 1)
162 {
163 char msg[1024];
164 XML_FormatError(&xml, msg, sizeof(msg));
165 printf("%s:%s\n", path, msg);
166 exit(1);
167 }
168 }
169 mike 1.1
170 int main(int argc, char** argv)
171 {
172 arg0 = argv[0];
173
174 if (argc != 2)
175 {
176 cerr << "Usage: " << arg0 << " file" << endl;
177 exit(1);
178 }
179
180 Print(argv[1]);
181
182 return 0;
183 }
|