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, "&", 5);
191 pos += 5;
192 break;
193 case '<':
194 strncpy(quote_buf + pos, "<", 4);
195 pos += 4;
196 break;
197 case '>':
198 strncpy(quote_buf + pos, ">", 4);
199 pos += 4;
200 break;
201 case '"':
202 strncpy(quote_buf + pos, """, 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