• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = "&amp;";
200 			break;
201 		case '<':
202 			quote = "&lt;";
203 			break;
204 		case '>':
205                         quote = "&gt;";
206 			break;
207 		case '"':
208 			quote = "&quot;";
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