aboutsummaryrefslogtreecommitdiffstats
path: root/trace-xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'trace-xml.c')
-rw-r--r--trace-xml.c248
1 files changed, 248 insertions, 0 deletions
diff --git a/trace-xml.c b/trace-xml.c
new file mode 100644
index 0000000..bef1f9f
--- /dev/null
+++ b/trace-xml.c
@@ -0,0 +1,248 @@
1/*
2 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
3 *
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 of the License (not later!)
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25
26#include <libxml/xmlwriter.h>
27#include <libxml/parser.h>
28#include <libxml/xpath.h>
29
30#include "trace-cmd.h"
31#include "trace-xml.h"
32
33struct tracecmd_xml_handle {
34 xmlTextWriterPtr writer;
35 xmlDocPtr doc;
36};
37
38struct tracecmd_xml_system {
39 struct tracecmd_xml_handle *handle;
40 xmlXPathObjectPtr result;
41 xmlNodePtr cur;
42};
43
44#define TRACE_ENCODING "UTF-8"
45
46int tracecmd_xml_write_element(struct tracecmd_xml_handle *handle,
47 const char *obj,
48 const char *fmt, ...)
49{
50 va_list ap;
51 int ret;
52
53 va_start(ap, fmt);
54 ret = xmlTextWriterWriteVFormatElement(handle->writer,
55 BAD_CAST obj, fmt, ap);
56 va_end(ap);
57
58 return ret;
59}
60
61struct tracecmd_xml_handle *tracecmd_xml_create(const char *name,
62 const char *version)
63{
64 struct tracecmd_xml_handle *handle;
65 int ret;
66
67 handle = malloc_or_die(sizeof(*handle));
68 memset(handle, 0, sizeof(*handle));
69
70 handle->writer = xmlNewTextWriterFilename(name, 0);
71 if (!handle->writer)
72 goto fail_free;
73
74 ret = xmlTextWriterStartDocument(handle->writer, NULL,
75 TRACE_ENCODING, NULL);
76 if (ret < 0)
77 goto fail_close;
78
79 ret = xmlTextWriterStartElement(handle->writer,
80 BAD_CAST "KernelShark");
81 if (ret < 0)
82 goto fail_close;
83
84 return handle;
85
86 fail_close:
87 xmlFreeTextWriter(handle->writer);
88 fail_free:
89 free(handle);
90 return NULL;
91}
92
93int tracecmd_xml_start_system(struct tracecmd_xml_handle *handle,
94 const char *system)
95{
96 int ret;
97
98 ret = xmlTextWriterStartElement(handle->writer,
99 BAD_CAST system);
100
101 if (ret < 0)
102 return ret;
103
104 return 0;
105}
106
107int tracecmd_xml_start_sub_system(struct tracecmd_xml_handle *handle,
108 const char *subsystem)
109{
110 int ret;
111
112 ret = xmlTextWriterStartElement(handle->writer,
113 BAD_CAST subsystem);
114
115 return ret;
116}
117
118void tracecmd_xml_end_system(struct tracecmd_xml_handle *handle)
119{
120 xmlTextWriterEndElement(handle->writer);
121}
122
123void tracecmd_xml_end_sub_system(struct tracecmd_xml_handle *handle)
124{
125 xmlTextWriterEndElement(handle->writer);
126}
127
128void tracecmd_xml_close(struct tracecmd_xml_handle *handle)
129{
130 if (handle->writer) {
131 xmlTextWriterEndElement(handle->writer);
132 xmlTextWriterEndDocument(handle->writer);
133 xmlFreeTextWriter(handle->writer);
134 }
135 if (handle->doc) {
136 xmlFreeDoc(handle->doc);
137 }
138 free(handle);
139}
140
141/***********************************************************/
142/*** Reading XML files ***/
143/***********************************************************/
144
145
146struct tracecmd_xml_handle *tracecmd_xml_open(const char *file)
147{
148 struct tracecmd_xml_handle *handle;
149
150 handle = malloc_or_die(sizeof(*handle));
151 memset(handle, 0, sizeof(*handle));
152
153 handle->doc = xmlParseFile(file);
154 if (!handle->doc)
155 goto fail_free;
156
157 return handle;
158
159 fail_free:
160 free(handle);
161 return NULL;
162}
163
164struct tracecmd_xml_system *
165tracecmd_xml_find_system(struct tracecmd_xml_handle *handle,
166 const char *system)
167{
168 struct tracecmd_xml_system *sys;
169 xmlXPathContextPtr context;
170 xmlXPathObjectPtr result;
171 xmlChar *xpath;
172 char *path;
173
174 path = malloc_or_die(strlen(system) + 3);
175 sprintf(path, "//%s", system);
176 xpath = BAD_CAST path;
177
178 context = xmlXPathNewContext(handle->doc);
179 result = xmlXPathEvalExpression(xpath, context);
180 free(path);
181
182 if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
183 xmlXPathFreeObject(result);
184 return NULL;
185 }
186
187 sys = malloc_or_die(sizeof(*sys));
188 sys->handle = handle;
189 sys->result = result;
190 sys->cur = result->nodesetval->nodeTab[0]->xmlChildrenNode;
191
192 return sys;
193}
194
195struct tracecmd_xml_system_node *
196tracecmd_xml_system_node(struct tracecmd_xml_system *system)
197{
198 return (struct tracecmd_xml_system_node *)system->cur;
199}
200
201const char *tracecmd_xml_node_type(struct tracecmd_xml_system_node *tnode)
202{
203 xmlNodePtr node = (xmlNodePtr)tnode;
204 return (const char *)node->name;
205}
206
207struct tracecmd_xml_system_node *
208tracecmd_xml_node_child(struct tracecmd_xml_system_node *tnode)
209{
210 xmlNodePtr node = (xmlNodePtr)tnode;
211 return (struct tracecmd_xml_system_node *)node->xmlChildrenNode;
212}
213
214struct tracecmd_xml_system_node *
215tracecmd_xml_node_next(struct tracecmd_xml_system_node *tnode)
216{
217 xmlNodePtr node = (xmlNodePtr)tnode;
218 return (struct tracecmd_xml_system_node *)node->next;
219}
220
221const char *tracecmd_xml_node_value(struct tracecmd_xml_handle *handle,
222 struct tracecmd_xml_system_node *tnode)
223{
224 xmlNodePtr node = (xmlNodePtr)tnode;
225 return (const char *)xmlNodeListGetString(handle->doc, node->xmlChildrenNode, 1);
226}
227
228void tracecmd_xml_free_system(struct tracecmd_xml_system *system)
229{
230 xmlXPathFreeObject(system->result);
231 free(system);
232}
233
234int tracecmd_xml_system_exists(struct tracecmd_xml_handle *handle,
235 const char *system)
236{
237 struct tracecmd_xml_system *sys;
238 int exists = 0;
239
240 sys = tracecmd_xml_find_system(handle, system);
241 if (sys) {
242 exists = 1;
243 tracecmd_xml_free_system(sys);
244 }
245
246 return exists;
247}
248