1 /**
2 * @file op_xml_out.c
3 * C utility routines for writing XML
4 *
5 * @remark Copyright 2008 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Dave Nomura
9 */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include "op_xml_out.h"
15
16 char const * xml_tag_map[] = {
17 "NONE",
18 "id",
19 "profile",
20 "processor",
21 "cputype",
22 "title",
23 "schemaversion",
24 "mhz",
25 "setup",
26 "timersetup",
27 "rtcinterrupts",
28 "eventsetup",
29 "eventname",
30 "unitmask",
31 "setupcount",
32 "separatedcpus",
33 "options",
34 "session", "debuginfo", "details", "excludedependent",
35 "excludesymbols", "imagepath", "includesymbols", "merge",
36 "classes",
37 "class",
38 "cpu",
39 "event",
40 "mask",
41 "process",
42 "pid",
43 "thread",
44 "tid",
45 "binary",
46 "module",
47 "name",
48 "callers",
49 "callees",
50 "symbol",
51 "idref",
52 "self",
53 "detaillo",
54 "detailhi",
55 "symboltable",
56 "symboldata",
57 "startingaddr",
58 "file",
59 "line",
60 "codelength",
61 "summarydata",
62 "sampledata",
63 "count",
64 "detailtable",
65 "symboldetails",
66 "detaildata",
67 "vmaoffset",
68 "bytestable",
69 "bytes",
70 "help_events",
71 "header",
72 "title",
73 "doc",
74 "event",
75 "event_name",
76 "group",
77 "desc",
78 "counter_mask",
79 "min_count",
80 "ext",
81 "unit_masks",
82 "default",
83 "category",
84 "unit_mask",
85 "mask",
86 "desc"
87 };
88
89 #define MAX_BUF_LEN 2048
xml_tag_name(tag_t tag)90 char const * xml_tag_name(tag_t tag)
91 {
92 return xml_tag_map[tag];
93 }
94
95
open_xml_element(tag_t tag,int with_attrs,char * buffer,size_t max)96 void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max)
97 {
98 char *buf;
99 int size, ret;
100
101 buffer[max - 1] = '\0';
102 size = strlen(buffer);
103 buf = &buffer[size];
104 size = max - 1 - size;
105
106 ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag),
107 (with_attrs ? " " : ">\n"));
108
109 if (ret < 0 || ret >= size) {
110 fprintf(stderr,"open_xml_element: snprintf failed\n");
111 exit(EXIT_FAILURE);
112 }
113 }
114
115
close_xml_element(tag_t tag,int has_nested,char * buffer,size_t max)116 void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max)
117 {
118 char *buf;
119 int size, ret;
120
121 buffer[max - 1] = '\0';
122 size = strlen(buffer);
123 buf = &buffer[size];
124 size = max - 1 - size;
125
126 if (tag == NONE)
127 ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>"));
128 else
129 ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag));
130
131 if (ret < 0 || ret >= size) {
132 fprintf(stderr, "close_xml_element: snprintf failed\n");
133 exit(EXIT_FAILURE);
134 }
135 }
136
137
init_xml_int_attr(tag_t attr,int value,char * buffer,size_t max)138 void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max)
139 {
140 char *buf;
141 int size, ret;
142
143 buffer[max - 1] = '\0';
144 size = strlen(buffer);
145 buf = &buffer[size];
146 size = max - 1 - size;
147
148 ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value);
149
150 if (ret < 0 || ret >= size) {
151 fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
152 exit(EXIT_FAILURE);
153 }
154 }
155
156
init_xml_dbl_attr(tag_t attr,double value,char * buffer,size_t max)157 void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max)
158 {
159 char *buf;
160 int size, ret;
161
162 buffer[max - 1] = '\0';
163 size = strlen(buffer);
164 buf = &buffer[size];
165 size = max - 1 - size;
166
167 ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value);
168
169 if (ret < 0 || ret >= size) {
170 fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
171 exit(EXIT_FAILURE);
172 }
173 }
174
175
xml_quote(char const * str,char * buffer,size_t max)176 static void xml_quote(char const *str, char *buffer, size_t max)
177 {
178 char *buf;
179 char *quote;
180 char *pos = (char*)str;
181 size_t size;
182 int ret;
183
184 buffer[max - 1] = '\0';
185 size = strlen(buffer);
186 buf = &buffer[size];
187 size = max - 1 - size;
188
189 if (size < strlen(pos) + 2)
190 goto Error;
191
192 *buf = '"';
193 buf++;
194 size--;
195
196 while (*pos) {
197 switch(*pos) {
198 case '&':
199 quote = "&";
200 break;
201 case '<':
202 quote = "<";
203 break;
204 case '>':
205 quote = ">";
206 break;
207 case '"':
208 quote = """;
209 break;
210 default:
211 *buf = *pos;
212 pos++;
213 buf++;
214 size--;
215 continue;
216 }
217
218 pos++;
219 ret = snprintf(buf, size, "%s", quote);
220 if (ret < 0 || ret >= (int)size)
221 goto Error;
222 buf += ret;
223 size -= ret;
224 if (size < strlen(pos))
225 goto Error;
226 }
227
228 if (!size)
229 goto Error;
230
231 *buf = '"';
232 buf++;
233 *buf = '\0';
234
235 return;
236
237 Error:
238 fprintf(stderr,"quote_str: buffer overflow\n");
239 exit(EXIT_FAILURE);
240 }
241
242
init_xml_str_attr(tag_t attr,char const * str,char * buffer,size_t max)243 void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max)
244 {
245 char *buf;
246 int size, ret;
247
248 buffer[max - 1] = '\0';
249 size = strlen(buffer);
250 buf = &buffer[size];
251 size = max - 1 - size;
252
253 ret = snprintf(buf, size, " %s=", xml_tag_name(attr));
254 if (ret < 0 || ret >= size)
255 goto Error;
256
257 buf += ret;
258 size -= ret;
259
260 if (!size)
261 goto Error;
262
263 xml_quote(str, buf, size);
264 return;
265 Error:
266 fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
267 exit(EXIT_FAILURE);
268 }
269