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.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/list.h>
37 #include "ctf-scanner.h"
38 #include "ctf-parser.h"
41 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
44 void print_tabs(FILE *fd
, int depth
)
48 for (i
= 0; i
< depth
; i
++)
53 int ctf_visitor_print_unary_expression(FILE *fd
, int depth
, struct ctf_node
*node
)
57 switch (node
->u
.unary_expression
.link
) {
58 case UNARY_LINK_UNKNOWN
:
61 print_tabs(fd
, depth
);
62 fprintf(fd
, "<dotlink/>\n");
65 print_tabs(fd
, depth
);
66 fprintf(fd
, "<arrowlink/>\n");
69 print_tabs(fd
, depth
);
70 fprintf(fd
, "<dotdotdot/>\n");
73 fprintf(stderr
, "[error] %s: unknown expression link type %d\n", __func__
,
74 (int) node
->u
.unary_expression
.link
);
78 switch (node
->u
.unary_expression
.type
) {
80 print_tabs(fd
, depth
);
81 fprintf(fd
, "<unary_expression value=");
82 fprintf(fd
, "\"%s\"", node
->u
.unary_expression
.u
.string
);
85 case UNARY_SIGNED_CONSTANT
:
86 print_tabs(fd
, depth
);
87 fprintf(fd
, "<unary_expression value=\"");
88 fprintf(fd
, "%" PRId64
, node
->u
.unary_expression
.u
.signed_constant
);
89 fprintf(fd
, "\" />\n");
91 case UNARY_UNSIGNED_CONSTANT
:
92 print_tabs(fd
, depth
);
93 fprintf(fd
, "<unary_expression value=\"");
94 fprintf(fd
, "%" PRIu64
, node
->u
.unary_expression
.u
.signed_constant
);
95 fprintf(fd
, "\" />\n");
98 print_tabs(fd
, depth
);
99 fprintf(fd
, "<unary_expression_sbrac>\n");
100 ret
= ctf_visitor_print_unary_expression(fd
, depth
+ 1,
101 node
->u
.unary_expression
.u
.sbrac_exp
);
104 print_tabs(fd
, depth
);
105 fprintf(fd
, "</unary_expression_sbrac>\n");
110 fprintf(stderr
, "[error] %s: unknown expression type %d\n", __func__
,
111 (int) node
->u
.unary_expression
.type
);
118 int ctf_visitor_print_type_specifier_list(FILE *fd
, int depth
, struct ctf_node
*node
)
120 struct ctf_node
*iter
;
123 print_tabs(fd
, depth
);
124 fprintf(fd
, "<type_specifier_list>\n");
125 bt_list_for_each_entry(iter
, &node
->u
.type_specifier_list
.head
, siblings
) {
126 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
130 print_tabs(fd
, depth
);
131 fprintf(fd
, "</type_specifier_list>\n");
136 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 type=\"");
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 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.type_specifier
.node
);
227 case TYPESPEC_UNKNOWN
:
229 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
230 (int) node
->u
.type_specifier
.type
);
234 switch (node
->u
.type_specifier
.type
) {
241 case TYPESPEC_DOUBLE
:
242 case TYPESPEC_SIGNED
:
243 case TYPESPEC_UNSIGNED
:
245 case TYPESPEC_COMPLEX
:
246 case TYPESPEC_IMAGINARY
:
248 case TYPESPEC_ID_TYPE
:
249 fprintf(fd
, "\"/>\n");
251 case TYPESPEC_FLOATING_POINT
:
252 case TYPESPEC_INTEGER
:
253 case TYPESPEC_STRING
:
254 case TYPESPEC_STRUCT
:
255 case TYPESPEC_VARIANT
:
258 print_tabs(fd
, depth
);
259 fprintf(fd
, "</type_specifier>\n");
261 case TYPESPEC_UNKNOWN
:
263 fprintf(stderr
, "[error] %s: unknown type specifier %d\n", __func__
,
264 (int) node
->u
.type_specifier
.type
);
272 int ctf_visitor_print_type_declarator(FILE *fd
, int depth
, struct ctf_node
*node
)
275 struct ctf_node
*iter
;
277 print_tabs(fd
, depth
);
278 fprintf(fd
, "<type_declarator>\n");
281 if (!bt_list_empty(&node
->u
.type_declarator
.pointers
)) {
282 print_tabs(fd
, depth
);
283 fprintf(fd
, "<pointers>\n");
284 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.pointers
,
286 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
290 print_tabs(fd
, depth
);
291 fprintf(fd
, "</pointers>\n");
294 switch (node
->u
.type_declarator
.type
) {
296 if (node
->u
.type_declarator
.u
.id
) {
297 print_tabs(fd
, depth
);
298 fprintf(fd
, "<id name=\"");
299 fprintf(fd
, "%s", node
->u
.type_declarator
.u
.id
);
300 fprintf(fd
, "\" />\n");
304 if (node
->u
.type_declarator
.u
.nested
.type_declarator
) {
305 print_tabs(fd
, depth
);
306 fprintf(fd
, "<type_declarator>\n");
307 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
308 node
->u
.type_declarator
.u
.nested
.type_declarator
);
311 print_tabs(fd
, depth
);
312 fprintf(fd
, "</type_declarator>\n");
314 if (node
->u
.type_declarator
.u
.nested
.abstract_array
) {
315 print_tabs(fd
, depth
);
316 fprintf(fd
, "<length>\n");
317 print_tabs(fd
, depth
);
318 fprintf(fd
, "</length>\n");
319 } else if (!bt_list_empty(&node
->u
.type_declarator
.u
.nested
.length
)) {
320 print_tabs(fd
, depth
);
321 fprintf(fd
, "<length>\n");
322 bt_list_for_each_entry(iter
, &node
->u
.type_declarator
.u
.nested
.length
,
324 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
328 print_tabs(fd
, depth
);
329 fprintf(fd
, "</length>\n");
331 if (node
->u
.type_declarator
.bitfield_len
) {
332 print_tabs(fd
, depth
);
333 fprintf(fd
, "<bitfield_len>\n");
334 ret
= ctf_visitor_print_xml(fd
, depth
+ 1,
335 node
->u
.type_declarator
.bitfield_len
);
338 print_tabs(fd
, depth
);
339 fprintf(fd
, "</bitfield_len>\n");
342 case TYPEDEC_UNKNOWN
:
344 fprintf(stderr
, "[error] %s: unknown type declarator %d\n", __func__
,
345 (int) node
->u
.type_declarator
.type
);
350 print_tabs(fd
, depth
);
351 fprintf(fd
, "</type_declarator>\n");
355 int ctf_visitor_print_xml(FILE *fd
, int depth
, struct ctf_node
*node
)
358 struct ctf_node
*iter
;
360 switch (node
->type
) {
362 print_tabs(fd
, depth
);
363 fprintf(fd
, "<root>\n");
364 bt_list_for_each_entry(iter
, &node
->u
.root
.declaration_list
,
366 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
370 bt_list_for_each_entry(iter
, &node
->u
.root
.trace
, siblings
) {
371 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
375 bt_list_for_each_entry(iter
, &node
->u
.root
.stream
, siblings
) {
376 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
380 bt_list_for_each_entry(iter
, &node
->u
.root
.event
, siblings
) {
381 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
385 print_tabs(fd
, depth
);
386 fprintf(fd
, "</root>\n");
390 print_tabs(fd
, depth
);
391 fprintf(fd
, "<event>\n");
392 bt_list_for_each_entry(iter
, &node
->u
.event
.declaration_list
, siblings
) {
393 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
397 print_tabs(fd
, depth
);
398 fprintf(fd
, "</event>\n");
401 print_tabs(fd
, depth
);
402 fprintf(fd
, "<stream>\n");
403 bt_list_for_each_entry(iter
, &node
->u
.stream
.declaration_list
, siblings
) {
404 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
408 print_tabs(fd
, depth
);
409 fprintf(fd
, "</stream>\n");
412 print_tabs(fd
, depth
);
413 fprintf(fd
, "<env>\n");
414 bt_list_for_each_entry(iter
, &node
->u
.env
.declaration_list
, siblings
) {
415 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
419 print_tabs(fd
, depth
);
420 fprintf(fd
, "</env>\n");
423 print_tabs(fd
, depth
);
424 fprintf(fd
, "<trace>\n");
425 bt_list_for_each_entry(iter
, &node
->u
.trace
.declaration_list
, siblings
) {
426 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
430 print_tabs(fd
, depth
);
431 fprintf(fd
, "</trace>\n");
434 print_tabs(fd
, depth
);
435 fprintf(fd
, "<clock>\n");
436 bt_list_for_each_entry(iter
, &node
->u
.clock
.declaration_list
, siblings
) {
437 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
441 print_tabs(fd
, depth
);
442 fprintf(fd
, "</clock>\n");
445 print_tabs(fd
, depth
);
446 fprintf(fd
, "<callsite>\n");
447 bt_list_for_each_entry(iter
, &node
->u
.callsite
.declaration_list
, siblings
) {
448 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
452 print_tabs(fd
, depth
);
453 fprintf(fd
, "</callsite>\n");
457 case NODE_CTF_EXPRESSION
:
458 print_tabs(fd
, depth
);
459 fprintf(fd
, "<ctf_expression>\n");
461 print_tabs(fd
, depth
);
462 fprintf(fd
, "<left>\n");
463 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.left
, siblings
) {
464 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
469 print_tabs(fd
, depth
);
470 fprintf(fd
, "</left>\n");
472 print_tabs(fd
, depth
);
473 fprintf(fd
, "<right>\n");
474 bt_list_for_each_entry(iter
, &node
->u
.ctf_expression
.right
, siblings
) {
475 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
479 print_tabs(fd
, depth
);
480 fprintf(fd
, "</right>\n");
482 print_tabs(fd
, depth
);
483 fprintf(fd
, "</ctf_expression>\n");
485 case NODE_UNARY_EXPRESSION
:
486 return ctf_visitor_print_unary_expression(fd
, depth
, node
);
489 print_tabs(fd
, depth
);
490 fprintf(fd
, "<typedef>\n");
492 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._typedef
.type_specifier_list
);
496 print_tabs(fd
, depth
);
497 fprintf(fd
, "<type_declarator_list>\n");
498 bt_list_for_each_entry(iter
, &node
->u
._typedef
.type_declarators
, siblings
) {
499 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
503 print_tabs(fd
, depth
);
504 fprintf(fd
, "</type_declarator_list>\n");
506 print_tabs(fd
, depth
);
507 fprintf(fd
, "</typedef>\n");
509 case NODE_TYPEALIAS_TARGET
:
510 print_tabs(fd
, depth
);
511 fprintf(fd
, "<target>\n");
514 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_target
.type_specifier_list
);
518 print_tabs(fd
, depth
);
519 fprintf(fd
, "<type_declarator_list>\n");
520 bt_list_for_each_entry(iter
, &node
->u
.typealias_target
.type_declarators
, siblings
) {
521 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
525 print_tabs(fd
, depth
);
526 fprintf(fd
, "</type_declarator_list>\n");
529 print_tabs(fd
, depth
);
530 fprintf(fd
, "</target>\n");
532 case NODE_TYPEALIAS_ALIAS
:
533 print_tabs(fd
, depth
);
534 fprintf(fd
, "<alias>\n");
537 ret
= ctf_visitor_print_xml(fd
, depth
, node
->u
.typealias_alias
.type_specifier_list
);
541 print_tabs(fd
, depth
);
542 fprintf(fd
, "<type_declarator_list>\n");
543 bt_list_for_each_entry(iter
, &node
->u
.typealias_alias
.type_declarators
, siblings
) {
544 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
548 print_tabs(fd
, depth
);
549 fprintf(fd
, "</type_declarator_list>\n");
552 print_tabs(fd
, depth
);
553 fprintf(fd
, "</alias>\n");
556 print_tabs(fd
, depth
);
557 fprintf(fd
, "<typealias>\n");
558 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.target
);
561 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
.typealias
.alias
);
564 print_tabs(fd
, depth
);
565 fprintf(fd
, "</typealias>\n");
568 case NODE_TYPE_SPECIFIER_LIST
:
569 ret
= ctf_visitor_print_type_specifier_list(fd
, depth
, node
);
574 case NODE_TYPE_SPECIFIER
:
575 ret
= ctf_visitor_print_type_specifier(fd
, depth
, node
);
580 print_tabs(fd
, depth
);
581 if (node
->u
.pointer
.const_qualifier
)
582 fprintf(fd
, "<const_pointer />\n");
584 fprintf(fd
, "<pointer />\n");
586 case NODE_TYPE_DECLARATOR
:
587 ret
= ctf_visitor_print_type_declarator(fd
, depth
, node
);
592 case NODE_FLOATING_POINT
:
593 print_tabs(fd
, depth
);
594 fprintf(fd
, "<floating_point>\n");
595 bt_list_for_each_entry(iter
, &node
->u
.floating_point
.expressions
, siblings
) {
596 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
600 print_tabs(fd
, depth
);
601 fprintf(fd
, "</floating_point>\n");
604 print_tabs(fd
, depth
);
605 fprintf(fd
, "<integer>\n");
606 bt_list_for_each_entry(iter
, &node
->u
.integer
.expressions
, siblings
) {
607 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
611 print_tabs(fd
, depth
);
612 fprintf(fd
, "</integer>\n");
615 print_tabs(fd
, depth
);
616 fprintf(fd
, "<string>\n");
617 bt_list_for_each_entry(iter
, &node
->u
.string
.expressions
, siblings
) {
618 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
622 print_tabs(fd
, depth
);
623 fprintf(fd
, "</string>\n");
625 case NODE_ENUMERATOR
:
626 print_tabs(fd
, depth
);
627 fprintf(fd
, "<enumerator");
628 if (node
->u
.enumerator
.id
)
629 fprintf(fd
, " id=\"%s\"", node
->u
.enumerator
.id
);
631 bt_list_for_each_entry(iter
, &node
->u
.enumerator
.values
, siblings
) {
632 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
636 print_tabs(fd
, depth
);
637 fprintf(fd
, "</enumerator>\n");
640 print_tabs(fd
, depth
);
641 if (node
->u
._struct
.name
)
642 fprintf(fd
, "<enum name=\"%s\">\n",
643 node
->u
._enum
.enum_id
);
645 fprintf(fd
, "<enum >\n");
648 if (node
->u
._enum
.container_type
) {
649 print_tabs(fd
, depth
);
650 fprintf(fd
, "<container_type>\n");
651 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, node
->u
._enum
.container_type
);
654 print_tabs(fd
, depth
);
655 fprintf(fd
, "</container_type>\n");
658 print_tabs(fd
, depth
);
659 fprintf(fd
, "<enumerator_list>\n");
660 bt_list_for_each_entry(iter
, &node
->u
._enum
.enumerator_list
, siblings
) {
661 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
665 print_tabs(fd
, depth
);
666 fprintf(fd
, "</enumerator_list>\n");
669 print_tabs(fd
, depth
);
670 fprintf(fd
, "</enum>\n");
672 case NODE_STRUCT_OR_VARIANT_DECLARATION
:
673 ret
= ctf_visitor_print_xml(fd
, depth
,
674 node
->u
.struct_or_variant_declaration
.type_specifier_list
);
678 print_tabs(fd
, depth
);
679 fprintf(fd
, "<type_declarator_list>\n");
680 bt_list_for_each_entry(iter
, &node
->u
.struct_or_variant_declaration
.type_declarators
, siblings
) {
681 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
685 print_tabs(fd
, depth
);
686 fprintf(fd
, "</type_declarator_list>\n");
689 print_tabs(fd
, depth
);
690 fprintf(fd
, "<variant");
691 if (node
->u
.variant
.name
)
692 fprintf(fd
, " name=\"%s\"", node
->u
.variant
.name
);
693 if (node
->u
.variant
.choice
)
694 fprintf(fd
, " choice=\"%s\"", node
->u
.variant
.choice
);
696 bt_list_for_each_entry(iter
, &node
->u
.variant
.declaration_list
, siblings
) {
697 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
701 print_tabs(fd
, depth
);
702 fprintf(fd
, "</variant>\n");
705 print_tabs(fd
, depth
);
706 if (node
->u
._struct
.name
)
707 fprintf(fd
, "<struct name=\"%s\">\n",
708 node
->u
._struct
.name
);
710 fprintf(fd
, "<struct>\n");
711 bt_list_for_each_entry(iter
, &node
->u
._struct
.declaration_list
, siblings
) {
712 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
716 print_tabs(fd
, depth
);
717 fprintf(fd
, "</struct>\n");
718 if (!bt_list_empty(&node
->u
._struct
.min_align
)) {
719 print_tabs(fd
, depth
);
720 fprintf(fd
, "<align>\n");
721 bt_list_for_each_entry(iter
, &node
->u
._struct
.min_align
, siblings
) {
722 ret
= ctf_visitor_print_xml(fd
, depth
+ 1, iter
);
726 print_tabs(fd
, depth
);
727 fprintf(fd
, "</align>\n");
733 fprintf(stderr
, "[error] %s: unknown node type %d\n", __func__
,