blob: f6d9042b0bc12f24f2be0d5deb0b3fbd06221ee4 [file] [log] [blame]
Ben Cheng5a4eb4e2009-09-14 16:00:41 -07001/**
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",
Ben Cheng5bbbe462010-09-02 21:48:01 -070080 "ext",
Ben Cheng5a4eb4e2009-09-14 16:00:41 -070081 "unit_masks",
82 "default",
Jeff Brown7a33c862011-02-02 14:00:44 -080083 "category",
Ben Cheng5a4eb4e2009-09-14 16:00:41 -070084 "unit_mask",
85 "mask",
86 "desc"
87};
88
89#define MAX_BUF_LEN 2048
90char const * xml_tag_name(tag_t tag)
91{
92 return xml_tag_map[tag];
93}
94
95
Ben Cheng5bbbe462010-09-02 21:48:01 -070096void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -070097{
Ben Cheng5bbbe462010-09-02 21:48:01 -070098 char *buf;
99 int size, ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700100
Ben Cheng5bbbe462010-09-02 21:48:01 -0700101 buffer[max - 1] = '\0';
102 size = strlen(buffer);
103 buf = &buffer[size];
104 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700105
Ben Cheng5bbbe462010-09-02 21:48:01 -0700106 ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag),
107 (with_attrs ? " " : ">\n"));
108
109 if (ret < 0 || ret >= size) {
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700110 fprintf(stderr,"open_xml_element: snprintf failed\n");
111 exit(EXIT_FAILURE);
112 }
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700113}
114
115
Ben Cheng5bbbe462010-09-02 21:48:01 -0700116void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700117{
Ben Cheng5bbbe462010-09-02 21:48:01 -0700118 char *buf;
119 int size, ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700120
Ben Cheng5bbbe462010-09-02 21:48:01 -0700121 buffer[max - 1] = '\0';
122 size = strlen(buffer);
123 buf = &buffer[size];
124 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700125
Ben Cheng5bbbe462010-09-02 21:48:01 -0700126 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);
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700134 }
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700135}
136
137
Ben Cheng5bbbe462010-09-02 21:48:01 -0700138void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700139{
Ben Cheng5bbbe462010-09-02 21:48:01 -0700140 char *buf;
141 int size, ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700142
Ben Cheng5bbbe462010-09-02 21:48:01 -0700143 buffer[max - 1] = '\0';
144 size = strlen(buffer);
145 buf = &buffer[size];
146 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700147
Ben Cheng5bbbe462010-09-02 21:48:01 -0700148 ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value);
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700149
Ben Cheng5bbbe462010-09-02 21:48:01 -0700150 if (ret < 0 || ret >= size) {
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700151 fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
152 exit(EXIT_FAILURE);
153 }
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700154}
155
156
Ben Cheng5bbbe462010-09-02 21:48:01 -0700157void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700158{
Ben Cheng5bbbe462010-09-02 21:48:01 -0700159 char *buf;
160 int size, ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700161
Ben Cheng5bbbe462010-09-02 21:48:01 -0700162 buffer[max - 1] = '\0';
163 size = strlen(buffer);
164 buf = &buffer[size];
165 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700166
Ben Cheng5bbbe462010-09-02 21:48:01 -0700167 ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value);
168
169 if (ret < 0 || ret >= size) {
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700170 fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
171 exit(EXIT_FAILURE);
172 }
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700173}
174
175
Ben Cheng5bbbe462010-09-02 21:48:01 -0700176static void xml_quote(char const *str, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700177{
Ben Cheng5bbbe462010-09-02 21:48:01 -0700178 char *buf;
179 char *quote;
180 char *pos = (char*)str;
181 size_t size;
182 int ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700183
Ben Cheng5bbbe462010-09-02 21:48:01 -0700184 buffer[max - 1] = '\0';
185 size = strlen(buffer);
186 buf = &buffer[size];
187 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700188
Ben Cheng5bbbe462010-09-02 21:48:01 -0700189 if (size < strlen(pos) + 2)
190 goto Error;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700191
Ben Cheng5bbbe462010-09-02 21:48:01 -0700192 *buf = '"';
193 buf++;
194 size--;
195
196 while (*pos) {
197 switch(*pos) {
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700198 case '&':
Ben Cheng5bbbe462010-09-02 21:48:01 -0700199 quote = "&amp;";
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700200 break;
201 case '<':
Ben Cheng5bbbe462010-09-02 21:48:01 -0700202 quote = "&lt;";
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700203 break;
204 case '>':
Ben Cheng5bbbe462010-09-02 21:48:01 -0700205 quote = "&gt;";
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700206 break;
207 case '"':
Ben Cheng5bbbe462010-09-02 21:48:01 -0700208 quote = "&quot;";
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700209 break;
210 default:
Ben Cheng5bbbe462010-09-02 21:48:01 -0700211 *buf = *pos;
212 pos++;
213 buf++;
214 size--;
215 continue;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700216 }
Ben Cheng5bbbe462010-09-02 21:48:01 -0700217
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;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700226 }
227
Ben Cheng5bbbe462010-09-02 21:48:01 -0700228 if (!size)
229 goto Error;
230
231 *buf = '"';
232 buf++;
233 *buf = '\0';
234
235 return;
236
237Error:
238 fprintf(stderr,"quote_str: buffer overflow\n");
239 exit(EXIT_FAILURE);
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700240}
241
242
Ben Cheng5bbbe462010-09-02 21:48:01 -0700243void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max)
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700244{
Ben Cheng5bbbe462010-09-02 21:48:01 -0700245 char *buf;
246 int size, ret;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700247
Ben Cheng5bbbe462010-09-02 21:48:01 -0700248 buffer[max - 1] = '\0';
249 size = strlen(buffer);
250 buf = &buffer[size];
251 size = max - 1 - size;
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700252
Ben Cheng5bbbe462010-09-02 21:48:01 -0700253 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;
265Error:
266 fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
267 exit(EXIT_FAILURE);
Ben Cheng5a4eb4e2009-09-14 16:00:41 -0700268}