Add XML dump visitor
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-xml.c
CommitLineData
7de8808c
MD
1/*
2 * ctf-visitor-xml.c
3 *
4 * Common Trace Format Metadata Visitor (XML dump).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19#include <stdio.h>
20#include <unistd.h>
21#include <string.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <helpers/list.h>
25#include <glib.h>
26#include <errno.h>
27#include "ctf-scanner.h"
28#include "ctf-parser.h"
29#include "ctf-ast.h"
30
31#define printf_dbg(fmt, args...) fprintf(stderr, "%s: " fmt, __func__, ## args)
32
33static void print_tabs(FILE *fd, int depth)
34{
35 int i;
36
37 for (i = 0; i < depth; i++)
38 fprintf(fd, "\t");
39}
40
41int ctf_visitor_print_unary_expression(FILE *fd, int depth, struct ctf_node *node)
42{
43 int ret = 0;
44
45 switch (node->u.unary_expression.type) {
46 case UNARY_STRING:
47 print_tabs(fd, depth);
48 fprintf(fd, "<unary_expression value=");
49 fprintf(fd, "\"%s\"", node->u.unary_expression.u.string);
50 fprintf(fd, "/>\n");
51 break;
52 case UNARY_SIGNED_CONSTANT:
53 print_tabs(fd, depth);
54 fprintf(fd, "<unary_expression value=");
55 fprintf(fd, "%lld", node->u.unary_expression.u.signed_constant);
56 fprintf(fd, "/>\n");
57 break;
58 case UNARY_UNSIGNED_CONSTANT:
59 print_tabs(fd, depth);
60 fprintf(fd, "<unary_expression value=");
61 fprintf(fd, "%llu", node->u.unary_expression.u.signed_constant);
62 fprintf(fd, "/>\n");
63 break;
64 case UNARY_SBRAC:
65 print_tabs(fd, depth);
66 fprintf(fd, "<unary_expression_sbrac>");
67 ret = ctf_visitor_print_unary_expression(fd, depth + 1,
68 node->u.unary_expression.u.sbrac_exp);
69 if (ret)
70 return ret;
71 print_tabs(fd, depth);
72 fprintf(fd, "</unary_expression_sbrac>");
73 break;
74
75 case UNARY_UNKNOWN:
76 default:
77 fprintf(stderr, "[error] %s: unknown expression type %d\n", __func__,
78 (int) node->u.unary_expression.type);
79 return -EINVAL;
80 }
81 switch (node->u.unary_expression.link) {
82 case UNARY_LINK_UNKNOWN:
83 break;
84 case UNARY_DOTLINK:
85 print_tabs(fd, depth);
86 fprintf(fd, "<dotlink/>\n");
87 break;
88 case UNARY_ARROWLINK:
89 print_tabs(fd, depth);
90 fprintf(fd, "<arrowlink/>\n");
91 break;
92 default:
93 fprintf(stderr, "[error] %s: unknown expression link type %d\n", __func__,
94 (int) node->u.unary_expression.link);
95 return -EINVAL;
96 }
97 return 0;
98}
99
100int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
101{
102 print_tabs(fd, depth);
103 fprintf(fd, "<type_specifier =\"");
104
105 switch (node->u.type_specifier.type) {
106 case TYPESPEC_VOID:
107 fprintf(fd, "void");
108 break;
109 case TYPESPEC_CHAR:
110 fprintf(fd, "char");
111 break;
112 case TYPESPEC_SHORT:
113 fprintf(fd, "short");
114 break;
115 case TYPESPEC_INT:
116 fprintf(fd, "int");
117 break;
118 case TYPESPEC_LONG:
119 fprintf(fd, "long");
120 break;
121 case TYPESPEC_FLOAT:
122 fprintf(fd, "float");
123 break;
124 case TYPESPEC_DOUBLE:
125 fprintf(fd, "double");
126 break;
127 case TYPESPEC_SIGNED:
128 fprintf(fd, "signed");
129 break;
130 case TYPESPEC_UNSIGNED:
131 fprintf(fd, "unsigned");
132 break;
133 case TYPESPEC_BOOL:
134 fprintf(fd, "bool");
135 break;
136 case TYPESPEC_COMPLEX:
137 fprintf(fd, "complex");
138 break;
139 case TYPESPEC_CONST:
140 fprintf(fd, "const");
141 break;
142 case TYPESPEC_ID_TYPE:
143 fprintf(fd, "%s", node->u.type_specifier.id_type);
144 break;
145
146 case TYPESPEC_UNKNOWN:
147 default:
148 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
149 (int) node->u.type_specifier.type);
150 return -EINVAL;
151 }
152 fprintf(fd, "\"/>\n");
153 return 0;
154}
155
156int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
157{
158 int ret = 0;
159 struct ctf_node *iter;
160
161 print_tabs(fd, depth);
162 fprintf(fd, "<type_declarator>\n");
163 depth++;
164
165 print_tabs(fd, depth);
166 fprintf(fd, "<pointers>\n");
167 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
168 siblings) {
169 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
170 if (ret)
171 return ret;
172 }
173 print_tabs(fd, depth);
174 fprintf(fd, "</pointers>\n");
175
176 switch (node->u.type_declarator.type) {
177 case TYPEDEC_ID:
178 print_tabs(fd, depth);
179 fprintf(fd, "<id \"");
180 fprintf(fd, "%s", node->u.type_declarator.u.id);
181 fprintf(fd, "<\" />\n");
182 break;
183 case TYPEDEC_NESTED:
184 if (node->u.type_declarator.u.nested.type_declarator) {
185 print_tabs(fd, depth);
186 fprintf(fd, "<type_declarator>\n");
187 ret = ctf_visitor_print_xml(fd, depth + 1,
188 node->u.type_declarator.u.nested.type_declarator);
189 if (ret)
190 return ret;
191 print_tabs(fd, depth);
192 fprintf(fd, "</type_declarator>\n");
193 }
194 if (node->u.type_declarator.u.nested.length) {
195 print_tabs(fd, depth);
196 fprintf(fd, "<length>\n");
197 ret = ctf_visitor_print_xml(fd, depth + 1,
198 node->u.type_declarator.u.nested.length);
199 if (ret)
200 return ret;
201 print_tabs(fd, depth);
202 fprintf(fd, "</length>\n");
203 }
204 if (node->u.type_declarator.u.nested.abstract_array) {
205 print_tabs(fd, depth);
206 fprintf(fd, "<length>\n");
207 print_tabs(fd, depth);
208 fprintf(fd, "</length>\n");
209 }
210 if (node->u.type_declarator.bitfield_len) {
211 print_tabs(fd, depth);
212 fprintf(fd, "<bitfield_len>\n");
213 ret = ctf_visitor_print_xml(fd, depth + 1,
214 node->u.type_declarator.bitfield_len);
215 if (ret)
216 return ret;
217 print_tabs(fd, depth);
218 fprintf(fd, "</bitfield_len>\n");
219 }
220 break;
221 case TYPEDEC_UNKNOWN:
222 default:
223 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
224 (int) node->u.type_declarator.type);
225 return -EINVAL;
226 }
227
228 depth--;
229 print_tabs(fd, depth);
230 fprintf(fd, "</type_declarator>\n");
231 return 0;
232}
233
234int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
235{
236 int ret = 0;
237 struct ctf_node *iter;
238
239 switch (node->type) {
240 case NODE_ROOT:
241 print_tabs(fd, depth);
242 fprintf(fd, "<root>\n");
243 cds_list_for_each_entry(iter, &node->u.root._typedef,
244 siblings) {
245 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
246 if (ret)
247 return ret;
248 }
249 cds_list_for_each_entry(iter, &node->u.root.typealias,
250 siblings) {
251 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
252 if (ret)
253 return ret;
254 }
255 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
256 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
257 if (ret)
258 return ret;
259 }
260 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
261 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
262 if (ret)
263 return ret;
264 }
265 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
266 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
267 if (ret)
268 return ret;
269 }
270 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
271 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
272 if (ret)
273 return ret;
274 }
275 print_tabs(fd, depth);
276 fprintf(fd, "</root>\n");
277 break;
278
279 case NODE_EVENT:
280 print_tabs(fd, depth);
281 fprintf(fd, "<event>\n");
282 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
283 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
284 if (ret)
285 return ret;
286 }
287 print_tabs(fd, depth);
288 fprintf(fd, "</event>\n");
289 break;
290 case NODE_STREAM:
291 print_tabs(fd, depth);
292 fprintf(fd, "<stream>\n");
293 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
294 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
295 if (ret)
296 return ret;
297 }
298 print_tabs(fd, depth);
299 fprintf(fd, "</stream>\n");
300 break;
301 case NODE_TRACE:
302 print_tabs(fd, depth);
303 fprintf(fd, "<trace>\n");
304 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
305 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
306 if (ret)
307 return ret;
308 }
309 print_tabs(fd, depth);
310 fprintf(fd, "</trace>\n");
311 break;
312
313 case NODE_CTF_EXPRESSION:
314 print_tabs(fd, depth);
315 fprintf(fd, "<ctf_expression>\n");
316 depth++;
317 print_tabs(fd, depth);
318 fprintf(fd, "<left>\n");
319 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.ctf_expression.left);
320 if (ret)
321 return ret;
322 print_tabs(fd, depth);
323 fprintf(fd, "</left>\n");
324
325 print_tabs(fd, depth);
326 fprintf(fd, "<right>\n");
327 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.ctf_expression.right);
328 if (ret)
329 return ret;
330 print_tabs(fd, depth);
331 fprintf(fd, "</right>\n");
332 depth--;
333 print_tabs(fd, depth);
334 fprintf(fd, "</ctf_expression>\n");
335 break;
336 case NODE_UNARY_EXPRESSION:
337 return ctf_visitor_print_unary_expression(fd, depth, node);
338
339 case NODE_TYPEDEF:
340 print_tabs(fd, depth);
341 fprintf(fd, "<typedef>\n");
342 depth++;
343 print_tabs(fd, depth);
344 fprintf(fd, "<declaration_specifier>\n");
345 cds_list_for_each_entry(iter, &node->u._typedef.declaration_specifier, siblings) {
346 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
347 if (ret)
348 return ret;
349 }
350 print_tabs(fd, depth);
351 fprintf(fd, "</declaration_specifier>\n");
352
353 print_tabs(fd, depth);
354 fprintf(fd, "<type_declarators>\n");
355 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
356 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
357 if (ret)
358 return ret;
359 }
360 print_tabs(fd, depth);
361 fprintf(fd, "</type_declarators>\n");
362 depth--;
363 print_tabs(fd, depth);
364 fprintf(fd, "</typedef>\n");
365 break;
366 case NODE_TYPEALIAS_TARGET:
367 print_tabs(fd, depth);
368 fprintf(fd, "<target>\n");
369 depth++;
370
371 print_tabs(fd, depth);
372 fprintf(fd, "<declaration_specifier>\n");
373 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
374 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
375 if (ret)
376 return ret;
377 }
378 print_tabs(fd, depth);
379 fprintf(fd, "</declaration_specifier>\n");
380
381 print_tabs(fd, depth);
382 fprintf(fd, "<type_declarators>\n");
383 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
384 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
385 if (ret)
386 return ret;
387 }
388 print_tabs(fd, depth);
389 fprintf(fd, "</type_declarators>\n");
390
391 depth--;
392 print_tabs(fd, depth);
393 fprintf(fd, "</target>\n");
394 break;
395 case NODE_TYPEALIAS_ALIAS:
396 print_tabs(fd, depth);
397 fprintf(fd, "<alias>\n");
398 depth++;
399
400 print_tabs(fd, depth);
401 fprintf(fd, "<declaration_specifier>\n");
402 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
403 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
404 if (ret)
405 return ret;
406 }
407 print_tabs(fd, depth);
408 fprintf(fd, "</declaration_specifier>\n");
409
410 print_tabs(fd, depth);
411 fprintf(fd, "<type_declarators>\n");
412 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
413 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
414 if (ret)
415 return ret;
416 }
417 print_tabs(fd, depth);
418 fprintf(fd, "</type_declarators>\n");
419
420 depth--;
421 print_tabs(fd, depth);
422 fprintf(fd, "</alias>\n");
423 break;
424 case NODE_TYPEALIAS:
425 print_tabs(fd, depth);
426 fprintf(fd, "<typealias>\n");
427 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
428 if (ret)
429 return ret;
430 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
431 if (ret)
432 return ret;
433 print_tabs(fd, depth);
434 fprintf(fd, "</typealias>\n");
435 break;
436
437 case NODE_TYPE_SPECIFIER:
438 ret = ctf_visitor_print_type_specifier(fd, depth, node);
439 if (ret)
440 return ret;
441 break;
442 case NODE_POINTER:
443 print_tabs(fd, depth);
444 if (node->u.pointer.const_qualifier)
445 fprintf(fd, "<const_pointer />\n");
446 else
447 fprintf(fd, "<pointer />\n");
448 break;
449 case NODE_TYPE_DECLARATOR:
450 ret = ctf_visitor_print_type_declarator(fd, depth, node);
451 if (ret)
452 return ret;
453 break;
454
455 case NODE_FLOATING_POINT:
456 print_tabs(fd, depth);
457 fprintf(fd, "<floating_point>\n");
458 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
459 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
460 if (ret)
461 return ret;
462 }
463 print_tabs(fd, depth);
464 fprintf(fd, "</floating_point>\n");
465 break;
466 case NODE_INTEGER:
467 print_tabs(fd, depth);
468 fprintf(fd, "<integer>\n");
469 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
470 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
471 if (ret)
472 return ret;
473 }
474 print_tabs(fd, depth);
475 fprintf(fd, "</integer>\n");
476 break;
477 case NODE_STRING:
478 print_tabs(fd, depth);
479 fprintf(fd, "<string>\n");
480 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
481 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
482 if (ret)
483 return ret;
484 }
485 print_tabs(fd, depth);
486 fprintf(fd, "</string>\n");
487 break;
488 case NODE_ENUMERATOR:
489 print_tabs(fd, depth);
490 fprintf(fd, "<enumerator");
491 if (node->u.enumerator.id)
492 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
493 fprintf(fd, ">\n");
494 if (node->u.enumerator.values) {
495 ret = ctf_visitor_print_xml(fd, depth + 1,
496 node->u.enumerator.values);
497 if (ret)
498 return ret;
499 }
500 print_tabs(fd, depth);
501 fprintf(fd, "</enumerator>");
502 break;
503 case NODE_ENUM:
504 print_tabs(fd, depth);
505 if (node->u._struct.name)
506 fprintf(fd, "<enum name=\"%s\">\n",
507 node->u._enum.enum_id);
508 else
509 fprintf(fd, "<enum >\n");
510 depth++;
511
512 if (node->u._enum.container_type) {
513 print_tabs(fd, depth);
514 fprintf(fd, "<container_type>");
515 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
516 if (ret)
517 return ret;
518 print_tabs(fd, depth);
519 fprintf(fd, "</container_type>");
520 }
521
522 print_tabs(fd, depth);
523 fprintf(fd, "<enumerator_list>");
524 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
525 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
526 if (ret)
527 return ret;
528 }
529 print_tabs(fd, depth);
530 fprintf(fd, "</enumerator_list>");
531
532 depth--;
533 print_tabs(fd, depth);
534 fprintf(fd, "</enum>\n");
535 break;
536 case NODE_STRUCT_OR_VARIANT_DECLARATION:
537 print_tabs(fd, depth);
538 fprintf(fd, "<declaration_specifier>\n");
539 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
540 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
541 if (ret)
542 return ret;
543 }
544 print_tabs(fd, depth);
545 fprintf(fd, "</declaration_specifier>\n");
546
547 print_tabs(fd, depth);
548 fprintf(fd, "<type_declarators>\n");
549 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
550 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
551 if (ret)
552 return ret;
553 }
554 print_tabs(fd, depth);
555 fprintf(fd, "</type_declarators>\n");
556 break;
557 case NODE_VARIANT:
558 print_tabs(fd, depth);
559 fprintf(fd, "<variant");
560 if (node->u.variant.name)
561 fprintf(fd, " name=\"%s\"", node->u.variant.name);
562 if (node->u.variant.choice)
563 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
564 fprintf(fd, ">\n");
565 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
566 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
567 if (ret)
568 return ret;
569 }
570 print_tabs(fd, depth);
571 fprintf(fd, "</variant>\n");
572 break;
573 case NODE_STRUCT:
574 print_tabs(fd, depth);
575 if (node->u._struct.name)
576 fprintf(fd, "<struct name=\"%s\">\n",
577 node->u._struct.name);
578 else
579 fprintf(fd, "<struct>\n");
580 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
581 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
582 if (ret)
583 return ret;
584 }
585 print_tabs(fd, depth);
586 fprintf(fd, "</struct>\n");
587 break;
588
589 case NODE_UNKNOWN:
590 default:
591 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
592 (int) node->type);
593 return -EINVAL;
594 }
595 return ret;
596}
This page took 0.043836 seconds and 4 git commands to generate.