op_xml_out.c revision 5bbbe460405564a1aed8a67a13c43e9356ffc656
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
16char 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	"unit_mask",
84		"mask",
85		"desc"
86};
87
88#define MAX_BUF_LEN 2048
89char const * xml_tag_name(tag_t tag)
90{
91	return xml_tag_map[tag];
92}
93
94
95void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max)
96{
97	char *buf;
98	int size, ret;
99
100	buffer[max - 1] = '\0';
101	size = strlen(buffer);
102	buf = &buffer[size];
103	size = max - 1 - size;
104
105	ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag),
106		       (with_attrs ? " " : ">\n"));
107
108	if (ret < 0 || ret >= size) {
109		fprintf(stderr,"open_xml_element: snprintf failed\n");
110		exit(EXIT_FAILURE);
111	}
112}
113
114
115void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max)
116{
117	char *buf;
118	int size, ret;
119
120	buffer[max - 1] = '\0';
121	size = strlen(buffer);
122	buf = &buffer[size];
123	size = max - 1 - size;
124
125	if (tag == NONE)
126		ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>"));
127	else
128		ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag));
129
130	if (ret < 0 || ret >= size) {
131		fprintf(stderr, "close_xml_element: snprintf failed\n");
132		exit(EXIT_FAILURE);
133	}
134}
135
136
137void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max)
138{
139	char *buf;
140	int size, ret;
141
142	buffer[max - 1] = '\0';
143	size = strlen(buffer);
144	buf = &buffer[size];
145	size = max - 1 - size;
146
147	ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value);
148
149	if (ret < 0 || ret >= size) {
150		fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
151		exit(EXIT_FAILURE);
152	}
153}
154
155
156void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max)
157{
158	char *buf;
159	int size, ret;
160
161	buffer[max - 1] = '\0';
162	size = strlen(buffer);
163	buf = &buffer[size];
164	size = max - 1 - size;
165
166	ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value);
167
168	if (ret < 0 || ret >= size) {
169		fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
170		exit(EXIT_FAILURE);
171	}
172}
173
174
175static void xml_quote(char const *str, char *buffer, size_t max)
176{
177	char *buf;
178	char *quote;
179	char *pos = (char*)str;
180	size_t size;
181	int ret;
182
183	buffer[max - 1] = '\0';
184	size = strlen(buffer);
185	buf = &buffer[size];
186	size = max - 1 - size;
187
188	if (size < strlen(pos) + 2)
189		goto Error;
190
191	*buf = '"';
192	buf++;
193	size--;
194
195	while (*pos) {
196		switch(*pos) {
197		case '&':
198			quote = "&amp;";
199			break;
200		case '<':
201			quote = "&lt;";
202			break;
203		case '>':
204                        quote = "&gt;";
205			break;
206		case '"':
207			quote = "&quot;";
208			break;
209		default:
210			*buf = *pos;
211			pos++;
212			buf++;
213			size--;
214			continue;
215		}
216
217		pos++;
218		ret = snprintf(buf, size, "%s", quote);
219		if (ret < 0 || ret >= (int)size)
220			goto Error;
221		buf += ret;
222		size -= ret;
223		if (size < strlen(pos))
224			goto Error;
225	}
226
227	if (!size)
228		goto Error;
229
230	*buf = '"';
231	buf++;
232	*buf = '\0';
233
234	return;
235
236Error:
237	fprintf(stderr,"quote_str: buffer overflow\n");
238	exit(EXIT_FAILURE);
239}
240
241
242void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max)
243{
244	char *buf;
245	int size, ret;
246
247	buffer[max - 1] = '\0';
248	size = strlen(buffer);
249	buf = &buffer[size];
250	size = max - 1 - size;
251
252	ret = snprintf(buf, size, " %s=", xml_tag_name(attr));
253	if (ret < 0 || ret >= size)
254		goto Error;
255
256	buf += ret;
257	size -= ret;
258
259	if (!size)
260		goto Error;
261
262	xml_quote(str, buf, size);
263	return;
264Error:
265	fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
266	exit(EXIT_FAILURE);
267}
268