• 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 	"unit_masks",
81 		"default",
82 	"unit_mask",
83 		"mask",
84 		"desc"
85 };
86 
87 #define MAX_BUF_LEN 2048
xml_tag_name(tag_t tag)88 char const * xml_tag_name(tag_t tag)
89 {
90 	return xml_tag_map[tag];
91 }
92 
93 
open_xml_element(tag_t tag,int with_attrs,char * buffer)94 void open_xml_element(tag_t tag, int with_attrs, char * buffer)
95 {
96 	char const * tag_name = xml_tag_name(tag);
97 	unsigned int const max_len = strlen(tag_name) + 3;
98 	char tmp_buf[MAX_BUF_LEN];
99 
100 	if (max_len >= sizeof(tmp_buf))
101 		fprintf(stderr,"Warning: open_xml_element: buffer overflow %d\n", max_len);
102 
103 	if (snprintf(tmp_buf, sizeof(tmp_buf), "<%s%s", tag_name,
104 		(with_attrs ? " " : ">\n")) < 0) {
105 		fprintf(stderr,"open_xml_element: snprintf failed\n");
106 		exit(EXIT_FAILURE);
107 	}
108 	strncat(buffer, tmp_buf, sizeof(tmp_buf));
109 }
110 
111 
close_xml_element(tag_t tag,int has_nested,char * buffer)112 void close_xml_element(tag_t tag, int has_nested, char * buffer)
113 {
114 	char const * tag_name = xml_tag_name(tag);
115 	unsigned int const max_len = strlen(tag_name) + 3;
116 	char tmp_buf[MAX_BUF_LEN];
117 
118 	if (max_len >= sizeof(tmp_buf))
119 		fprintf(stderr,"Warning: close_xml_element: buffer overflow %d\n", max_len);
120 
121 	if (tag == NONE) {
122 		if (snprintf(tmp_buf, sizeof(tmp_buf), "%s\n", (has_nested ? ">" : "/>")) < 0) {
123 			fprintf(stderr, "close_xml_element: snprintf failed\n");
124 			exit(EXIT_FAILURE);
125 		}
126 	} else {
127 		if (snprintf(tmp_buf, sizeof(tmp_buf), "</%s>\n", tag_name) < 0) {
128 			fprintf(stderr, "close_xml_element: snprintf failed\n");
129 			exit(EXIT_FAILURE);
130 		}
131 	}
132 	strncat(buffer, tmp_buf, sizeof(tmp_buf));
133 }
134 
135 
init_xml_int_attr(tag_t attr,int value,char * buffer)136 void init_xml_int_attr(tag_t attr, int value, char * buffer)
137 {
138 	char const * attr_name = xml_tag_name(attr);
139 	char tmp_buf[MAX_BUF_LEN];
140 	unsigned int const max_len = strlen(attr_name) + 50;
141 
142 	if (max_len >= sizeof(tmp_buf)) {
143 		fprintf(stderr,
144 			"Warning: init_xml_int_attr: buffer overflow %d\n", max_len);
145 	}
146 
147 
148 	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=\"%d\"", attr_name, value) < 0) {
149 		fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
150 		exit(EXIT_FAILURE);
151 	}
152 	strncat(buffer, tmp_buf, sizeof(tmp_buf));
153 }
154 
155 
init_xml_dbl_attr(tag_t attr,double value,char * buffer)156 void init_xml_dbl_attr(tag_t attr, double value, char * buffer)
157 {
158 	char const * attr_name = xml_tag_name(attr);
159 	unsigned int const max_len = strlen(attr_name) + 50;
160 	char tmp_buf[MAX_BUF_LEN];
161 
162 	if (max_len >= sizeof(tmp_buf))
163 		fprintf(stderr, "Warning: init_xml_dbl_attr: buffer overflow %d\n", max_len);
164 
165 	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=\"%.2f\"", attr_name, value) < 0) {
166 		fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
167 		exit(EXIT_FAILURE);
168 	}
169 	strncat(buffer, tmp_buf, sizeof(tmp_buf));
170 }
171 
172 
xml_quote(char const * str,char * quote_buf)173 static char * xml_quote(char const * str, char * quote_buf)
174 {
175 	int i;
176 	int pos = 0;
177 	int len = strlen(str);
178 
179 
180 	quote_buf[pos++] = '"';
181 
182 	for (i = 0; i < len; i++) {
183 		if (pos >= MAX_BUF_LEN - 10) {
184 			fprintf(stderr,"quote_str: buffer overflow %d\n", pos);
185 			exit(EXIT_FAILURE);
186 		}
187 
188 		switch(str[i]) {
189 		case '&':
190 			strncpy(quote_buf + pos, "&amp;", 5);
191 			pos += 5;
192 			break;
193 		case '<':
194 			strncpy(quote_buf + pos, "&lt;", 4);
195 			pos += 4;
196 			break;
197 		case '>':
198 			strncpy(quote_buf + pos, "&gt;", 4);
199 			pos += 4;
200 			break;
201 		case '"':
202 			strncpy(quote_buf + pos, "&quot;", 6);
203 			pos += 6;
204 			break;
205 		default:
206 			quote_buf[pos++] = str[i];
207 			break;
208 		}
209 	}
210 
211 	quote_buf[pos++] = '"';
212 	quote_buf[pos++] = '\0';
213 	return quote_buf;
214 }
215 
216 
init_xml_str_attr(tag_t attr,char const * str,char * buffer)217 void init_xml_str_attr(tag_t attr, char const * str, char * buffer)
218 {
219 	char tmp_buf[MAX_BUF_LEN];
220 	char quote_buf[MAX_BUF_LEN];
221 	char const * attr_name = xml_tag_name(attr);
222 	char const * quote_str = xml_quote(str, quote_buf);
223 	const unsigned int max_len = strlen(attr_name) + strlen(quote_str) + 10;
224 
225 	if (max_len >= sizeof(tmp_buf))
226 		fprintf(stderr, "Warning: init_xml_str_attr: buffer overflow %d\n", max_len);
227 
228 	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=""%s""", attr_name, quote_str) < 0) {
229 		fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
230 		exit(EXIT_FAILURE);
231 	}
232 	strncat(buffer, tmp_buf, sizeof(tmp_buf));
233 }
234