4 * Common Trace Format Metadata Visitor (XML dump).
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
27 #include <babeltrace/list.h>
28 #include "ctf-scanner.h"
29 #include "ctf-parser.h"
32 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
35 void print_tabs(FILE *fd
, int depth
)
39 for (i
= 0; i
< depth
; i
++)
44 int ctf_visitor_print_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
48 switch (node
->u
.unary_expression
.link
) {
49 case UNARY_LINK_UNKNOWN
:
52 print_tabs(fd
, depth
);
53 fprintf(fd
, "<dotlink/>\n");
56 print_tabs(fd
, depth
);
57 fprintf(fd
, "<arrowlink/>\n");
60 print_tabs(fd
, depth
);
61 fprintf(fd
, "<dotdotdot/>\n");
64 fprintf(stderr
, "[error] %s: unknown expression link type %d\n", __func__
,
65 (int) node
->u
.unary_expression
.link
);
69 switch (node
->u
.unary_expression
.type
) {
71 print_tabs(fd
, depth
);
72 fprintf(fd
, "<unary_expression value=");
73 fprintf(fd
, "\"%s\"", node
->u
.unary_expression
.u
.string
);
76 case UNARY_SIGNED_CONSTANT
:
77 print_tabs(fd
, depth
);
78 fprintf(fd
, "<unary_expression value=");
79 fprintf(fd
, "%" PRId64
, node
->u
.unary_expression
.u
.signed_constant
);
82 case UNARY_UNSIGNED_CONSTANT
:
83 print_tabs(fd
, depth
);
84 fprintf(fd
, "<unary_expression value=");
85 fprintf(fd
, "%" PRIu64
, node
->u
.unary_expression
.u
.signed_constant
);
89 print_tabs(fd
, depth
);
90 fprintf(fd
, "<unary_expression_sbrac>\n");
91 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
92 node
->u
.unary_expression
.u
.sbrac_exp
);
95 print_tabs(fd
, depth
);
96 fprintf(fd
, "</unary_expression_sbrac>\n");
99 print_tabs(fd
, depth
);
100 fprintf(fd
, "<unary_expression_nested>\n");
101 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
102 node
->u
.unary_expression
.u
.nested_exp
);
105 print_tabs(fd
, depth
);
106 fprintf(fd
, "</unary_expression_nested>\n");
111 fprintf(stderr
, "[error] %s: unknown expression type %d\n", __func__
,
112 (int) node
->u
.unary_expression
.type
);
119 int ctf_visitor_print_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
121 struct ctf_node
*iter
;
124 print_tabs(fd
, depth
);
125 fprintf(fd
, "<type_specifier_list>\n");
126 cds_list_for_each_entry(iter
, &node
->u
.type_specifier_list
.head
, siblings
) {
127 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
131 print_tabs(fd
, depth
);
132 fprintf(fd
, "</type_specifier_list>\n");
137 int ctf_visitor_print_type_specifier(FILE *fd
, int depth
, struct ctf_node
*node
)
139 print_tabs(fd
, depth
);
141 switch (node
->u
.type_specifier
.type
) {
148 case TYPESPEC_DOUBLE
:
149 case TYPESPEC_SIGNED
:
150 case TYPESPEC_UNSIGNED
:
152 case TYPESPEC_COMPLEX
:
153 case TYPESPEC_IMAGINARY
:
155 case TYPESPEC_ID_TYPE
:
156 fprintf(fd
, "<type_specifier \"");
158 case TYPESPEC_FLOATING_POINT
:
159 case TYPESPEC_INTEGER
:
160 case TYPESPEC_STRING
:
161 case TYPESPEC_STRUCT
:
162 case TYPESPEC_VARIANT
:
164 fprintf(fd
, "<type_specifier>\n");
167 case TYPESPEC_UNKNOWN
:
169 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
170 (int) node
->u
.type_specifier
.type
);
174 switch (node
->u
.type_specifier
.type
) {
182 fprintf(fd
, "short");
191 fprintf(fd
, "float");
193 case TYPESPEC_DOUBLE
:
194 fprintf(fd
, "double");
196 case TYPESPEC_SIGNED
:
197 fprintf(fd
, "signed");
199 case TYPESPEC_UNSIGNED
:
200 fprintf(fd
, "unsigned");
205 case TYPESPEC_COMPLEX
:
206 fprintf(fd
, "_Complex");
208 case TYPESPEC_IMAGINARY
:
209 fprintf(fd
, "_Imaginary");
212 fprintf(fd
, "const");
214 case TYPESPEC_ID_TYPE
:
215 fprintf(fd
, "%s", node
->u
.type_specifier
.id_type
);
217 case TYPESPEC_FLOATING_POINT
:
218 case TYPESPEC_INTEGER
:
219 case TYPESPEC_STRING
:
220 case TYPESPEC_STRUCT
:
221 case TYPESPEC_VARIANT
:
223 return ctf_visitor_print_xml(fd
, depth
, node
->u
.type_specifier
.node
);
224 case TYPESPEC_UNKNOWN
:
226 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
227 (int) node
->u
.type_specifier
.type
);
231 switch (node
->u
.type_specifier
.type
) {
238 case TYPESPEC_DOUBLE
:
239 case TYPESPEC_SIGNED
:
240 case TYPESPEC_UNSIGNED
:
242 case TYPESPEC_COMPLEX
:
243 case TYPESPEC_IMAGINARY
:
245 case TYPESPEC_ID_TYPE
:
246 fprintf(fd
, "\"/>\n");
248 case TYPESPEC_FLOATING_POINT
:
249 case TYPESPEC_INTEGER
:
250 case TYPESPEC_STRING
:
251 case TYPESPEC_STRUCT
:
252 case TYPESPEC_VARIANT
:
254 print_tabs(fd
, depth
);
255 fprintf(fd
, "</type_specifier>\n");
258 case TYPESPEC_UNKNOWN
:
260 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
261 (int) node
->u
.type_specifier
.type
);
269 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
272 struct ctf_node
*iter
;
274 print_tabs(fd
, depth
);
275 fprintf(fd
, "<type_declarator>\n");
278 if (!cds_list_empty(&node
->u
.type_declarator
.pointers
)) {
279 print_tabs(fd
, depth
);
280 fprintf(fd
, "<pointers>\n");
281 cds_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
283 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
287 print_tabs(fd
, depth
);
288 fprintf(fd
, "</pointers>\n");
291 switch (node
->u
.type_declarator
.type
) {
293 if (node
->u
.type_declarator
.u
.id
) {
294 print_tabs(fd
, depth
);
295 fprintf(fd
, "<id \"");
296 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
297 fprintf(fd
, "\" />\n");
301 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
302 print_tabs(fd
, depth
);
303 fprintf(fd
, "<type_declarator>\n");
304 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
305 node
->u
.type_declarator
.u
.nested
.type_declarator
);
308 print_tabs(fd
, depth
);
309 fprintf(fd
, "</type_declarator>\n");
311 if (node
->u
.type_declarator
.u
.nested
.length
) {
312 print_tabs(fd
, depth
);
313 fprintf(fd
, "<length>\n");
314 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.type_declarator
.u
.nested
.length
);
317 print_tabs(fd
, depth
);
318 fprintf(fd
, "</length>\n");
320 if (node
->u
.type_declarator
.u
.nested
.abstract_array
) {
321 print_tabs(fd
, depth
);
322 fprintf(fd
, "<length>\n");
323 print_tabs(fd
, depth
);
324 fprintf(fd
, "</length>\n");
326 if (node
->u
.type_declarator
.bitfield_len
) {
327 print_tabs(fd
, depth
);
328 fprintf(fd
, "<bitfield_len>\n");
329 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
330 node
->u
.type_declarator
.bitfield_len
);
333 print_tabs(fd
, depth
);
334 fprintf(fd
, "</bitfield_len>\n");
337 case TYPEDEC_UNKNOWN
:
339 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
340 (int) node
->u
.type_declarator
.type
);
345 print_tabs(fd
, depth
);
346 fprintf(fd
, "</type_declarator>\n");
350 int ctf_visitor_print_xml(FILE *fd
, int depth
, struct ctf_node
*node
)
353 struct ctf_node
*iter
;
355 switch (node
->type
) {
357 print_tabs(fd
, depth
);
358 fprintf(fd
, "<root>\n");
359 cds_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
361 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
365 cds_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
366 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
370 cds_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
371 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
375 cds_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
376 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
380 print_tabs(fd
, depth
);
381 fprintf(fd
, "</root>\n");
385 print_tabs(fd
, depth
);
386 fprintf(fd
, "<event>\n");
387 cds_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
388 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
392 print_tabs(fd
, depth
);
393 fprintf(fd
, "</event>\n");
396 print_tabs(fd
, depth
);
397 fprintf(fd
, "<stream>\n");
398 cds_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
399 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
403 print_tabs(fd
, depth
);
404 fprintf(fd
, "</stream>\n");
407 print_tabs(fd
, depth
);
408 fprintf(fd
, "<trace>\n");
409 cds_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
410 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
414 print_tabs(fd
, depth
);
415 fprintf(fd
, "</trace>\n");
418 case NODE_CTF_EXPRESSION
:
419 print_tabs(fd
, depth
);
420 fprintf(fd
, "<ctf_expression>\n");
422 print_tabs(fd
, depth
);
423 fprintf(fd
, "<left>\n");
424 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
425 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
430 print_tabs(fd
, depth
);
431 fprintf(fd
, "</left>\n");
433 print_tabs(fd
, depth
);
434 fprintf(fd
, "<right>\n");
435 cds_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
436 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
440 print_tabs(fd
, depth
);
441 fprintf(fd
, "</right>\n");
443 print_tabs(fd
, depth
);
444 fprintf(fd
, "</ctf_expression>\n");
446 case NODE_UNARY_EXPRESSION
:
447 return ctf_visitor_print_unary_expression(fd
, depth
, node
);
450 print_tabs(fd
, depth
);
451 fprintf(fd
, "<typedef>\n");
453 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._typedef
.type_specifier_list
);
457 print_tabs(fd
, depth
);
458 fprintf(fd
, "<type_declarator_list>\n");
459 cds_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
460 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
464 print_tabs(fd
, depth
);
465 fprintf(fd
, "</type_declarator_list>\n");
467 print_tabs(fd
, depth
);
468 fprintf(fd
, "</typedef>\n");
470 case NODE_TYPEALIAS_TARGET
:
471 print_tabs(fd
, depth
);
472 fprintf(fd
, "<target>\n");
475 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_target
.type_specifier_list
);
479 print_tabs(fd
, depth
);
480 fprintf(fd
, "<type_declarator_list>\n");
481 cds_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
482 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
486 print_tabs(fd
, depth
);
487 fprintf(fd
, "</type_declarator_list>\n");
490 print_tabs(fd
, depth
);
491 fprintf(fd
, "</target>\n");
493 case NODE_TYPEALIAS_ALIAS
:
494 print_tabs(fd
, depth
);
495 fprintf(fd
, "<alias>\n");
498 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_alias
.type_specifier_list
);
502 print_tabs(fd
, depth
);
503 fprintf(fd
, "<type_declarator_list>\n");
504 cds_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
505 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
509 print_tabs(fd
, depth
);
510 fprintf(fd
, "</type_declarator_list>\n");
513 print_tabs(fd
, depth
);
514 fprintf(fd
, "</alias>\n");
517 print_tabs(fd
, depth
);
518 fprintf(fd
, "<typealias>\n");
519 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
522 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
525 print_tabs(fd
, depth
);
526 fprintf(fd
, "</typealias>\n");
529 case NODE_TYPE_SPECIFIER_LIST
:
530 ret
= ctf_visitor_print_type_specifier_list(fd
, depth
, node
);
535 case NODE_TYPE_SPECIFIER
:
536 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
541 print_tabs(fd
, depth
);
542 if (node
->u
.pointer
.const_qualifier
)
543 fprintf(fd
, "<const_pointer />\n");
545 fprintf(fd
, "<pointer />\n");
547 case NODE_TYPE_DECLARATOR
:
548 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
553 case NODE_FLOATING_POINT
:
554 print_tabs(fd
, depth
);
555 fprintf(fd
, "<floating_point>\n");
556 cds_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
557 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
561 print_tabs(fd
, depth
);
562 fprintf(fd
, "</floating_point>\n");
565 print_tabs(fd
, depth
);
566 fprintf(fd
, "<integer>\n");
567 cds_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
568 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
572 print_tabs(fd
, depth
);
573 fprintf(fd
, "</integer>\n");
576 print_tabs(fd
, depth
);
577 fprintf(fd
, "<string>\n");
578 cds_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
579 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
583 print_tabs(fd
, depth
);
584 fprintf(fd
, "</string>\n");
586 case NODE_ENUMERATOR
:
587 print_tabs(fd
, depth
);
588 fprintf(fd
, "<enumerator");
589 if (node
->u
.enumerator
.id
)
590 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
592 cds_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
593 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
597 print_tabs(fd
, depth
);
598 fprintf(fd
, "</enumerator>\n");
601 print_tabs(fd
, depth
);
602 if (node
->u
._struct
.name
)
603 fprintf(fd
, "<enum name=\"%s\">\n",
604 node
->u
._enum
.enum_id
);
606 fprintf(fd
, "<enum >\n");
609 if (node
->u
._enum
.container_type
) {
610 print_tabs(fd
, depth
);
611 fprintf(fd
, "<container_type>\n");
614 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
617 if (node
->u
._enum
.container_type
) {
618 print_tabs(fd
, depth
);
619 fprintf(fd
, "</container_type>\n");
622 print_tabs(fd
, depth
);
623 fprintf(fd
, "<enumerator_list>\n");
624 cds_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
625 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
629 print_tabs(fd
, depth
);
630 fprintf(fd
, "</enumerator_list>\n");
633 print_tabs(fd
, depth
);
634 fprintf(fd
, "</enum>\n");
636 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
637 ret
= ctf_visitor_print_xml(fd
, depth
,
638 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
642 print_tabs(fd
, depth
);
643 fprintf(fd
, "<type_declarator_list>\n");
644 cds_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
645 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
649 print_tabs(fd
, depth
);
650 fprintf(fd
, "</type_declarator_list>\n");
653 print_tabs(fd
, depth
);
654 fprintf(fd
, "<variant");
655 if (node
->u
.variant
.name
)
656 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
657 if (node
->u
.variant
.choice
)
658 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
660 cds_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
661 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
665 print_tabs(fd
, depth
);
666 fprintf(fd
, "</variant>\n");
669 print_tabs(fd
, depth
);
670 if (node
->u
._struct
.name
)
671 fprintf(fd
, "<struct name=\"%s\">\n",
672 node
->u
._struct
.name
);
674 fprintf(fd
, "<struct>\n");
675 cds_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
676 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
680 print_tabs(fd
, depth
);
681 fprintf(fd
, "</struct>\n");
686 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,