3c1d37e74827b7e1b7a7034361f7cd45330297b3
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-xml.c
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 * 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
24 * SOFTWARE.
25 */
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <glib.h>
33 #include <inttypes.h>
34 #include <errno.h>
35 #include <babeltrace/babeltrace-internal.h>
36 #include <babeltrace/list.h>
37 #include "ctf-scanner.h"
38 #include "ctf-parser.h"
39 #include "ctf-ast.h"
40
41 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
42
43 static
44 void print_tabs(FILE *fd, int depth)
45 {
46 int i;
47
48 for (i = 0; i < depth; i++)
49 fprintf(fd, "\t");
50 }
51
52 static
53 int ctf_visitor_print_unary_expression(FILE *fd, int depth, struct ctf_node *node)
54 {
55 int ret = 0;
56
57 switch (node->u.unary_expression.link) {
58 case UNARY_LINK_UNKNOWN:
59 break;
60 case UNARY_DOTLINK:
61 print_tabs(fd, depth);
62 fprintf(fd, "<dotlink/>\n");
63 break;
64 case UNARY_ARROWLINK:
65 print_tabs(fd, depth);
66 fprintf(fd, "<arrowlink/>\n");
67 break;
68 case UNARY_DOTDOTDOT:
69 print_tabs(fd, depth);
70 fprintf(fd, "<dotdotdot/>\n");
71 break;
72 default:
73 fprintf(stderr, "[error] %s: unknown expression link type %d\n", __func__,
74 (int) node->u.unary_expression.link);
75 return -EINVAL;
76 }
77
78 switch (node->u.unary_expression.type) {
79 case UNARY_STRING:
80 print_tabs(fd, depth);
81 fprintf(fd, "<unary_expression value=");
82 fprintf(fd, "\"%s\"", node->u.unary_expression.u.string);
83 fprintf(fd, " />\n");
84 break;
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");
90 break;
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");
96 break;
97 case UNARY_SBRAC:
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);
102 if (ret)
103 return ret;
104 print_tabs(fd, depth);
105 fprintf(fd, "</unary_expression_sbrac>\n");
106 break;
107
108 case UNARY_UNKNOWN:
109 default:
110 fprintf(stderr, "[error] %s: unknown expression type %d\n", __func__,
111 (int) node->u.unary_expression.type);
112 return -EINVAL;
113 }
114 return 0;
115 }
116
117 static
118 int ctf_visitor_print_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
119 {
120 struct ctf_node *iter;
121 int ret;
122
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);
127 if (ret)
128 return ret;
129 }
130 print_tabs(fd, depth);
131 fprintf(fd, "</type_specifier_list>\n");
132 return 0;
133 }
134
135 static
136 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
137 {
138 int ret;
139 print_tabs(fd, depth);
140
141 switch (node->u.type_specifier.type) {
142 case TYPESPEC_VOID:
143 case TYPESPEC_CHAR:
144 case TYPESPEC_SHORT:
145 case TYPESPEC_INT:
146 case TYPESPEC_LONG:
147 case TYPESPEC_FLOAT:
148 case TYPESPEC_DOUBLE:
149 case TYPESPEC_SIGNED:
150 case TYPESPEC_UNSIGNED:
151 case TYPESPEC_BOOL:
152 case TYPESPEC_COMPLEX:
153 case TYPESPEC_IMAGINARY:
154 case TYPESPEC_CONST:
155 case TYPESPEC_ID_TYPE:
156 fprintf(fd, "<type_specifier type=\"");
157 break;
158 case TYPESPEC_FLOATING_POINT:
159 case TYPESPEC_INTEGER:
160 case TYPESPEC_STRING:
161 case TYPESPEC_STRUCT:
162 case TYPESPEC_VARIANT:
163 case TYPESPEC_ENUM:
164 fprintf(fd, "<type_specifier>\n");
165 depth++;
166 break;
167 case TYPESPEC_UNKNOWN:
168 default:
169 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
170 (int) node->u.type_specifier.type);
171 return -EINVAL;
172 }
173
174 switch (node->u.type_specifier.type) {
175 case TYPESPEC_VOID:
176 fprintf(fd, "void");
177 break;
178 case TYPESPEC_CHAR:
179 fprintf(fd, "char");
180 break;
181 case TYPESPEC_SHORT:
182 fprintf(fd, "short");
183 break;
184 case TYPESPEC_INT:
185 fprintf(fd, "int");
186 break;
187 case TYPESPEC_LONG:
188 fprintf(fd, "long");
189 break;
190 case TYPESPEC_FLOAT:
191 fprintf(fd, "float");
192 break;
193 case TYPESPEC_DOUBLE:
194 fprintf(fd, "double");
195 break;
196 case TYPESPEC_SIGNED:
197 fprintf(fd, "signed");
198 break;
199 case TYPESPEC_UNSIGNED:
200 fprintf(fd, "unsigned");
201 break;
202 case TYPESPEC_BOOL:
203 fprintf(fd, "bool");
204 break;
205 case TYPESPEC_COMPLEX:
206 fprintf(fd, "_Complex");
207 break;
208 case TYPESPEC_IMAGINARY:
209 fprintf(fd, "_Imaginary");
210 break;
211 case TYPESPEC_CONST:
212 fprintf(fd, "const");
213 break;
214 case TYPESPEC_ID_TYPE:
215 fprintf(fd, "%s", node->u.type_specifier.id_type);
216 break;
217 case TYPESPEC_FLOATING_POINT:
218 case TYPESPEC_INTEGER:
219 case TYPESPEC_STRING:
220 case TYPESPEC_STRUCT:
221 case TYPESPEC_VARIANT:
222 case TYPESPEC_ENUM:
223 ret = ctf_visitor_print_xml(fd, depth, node->u.type_specifier.node);
224 if (ret)
225 return ret;
226 break;
227 case TYPESPEC_UNKNOWN:
228 default:
229 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
230 (int) node->u.type_specifier.type);
231 return -EINVAL;
232 }
233
234 switch (node->u.type_specifier.type) {
235 case TYPESPEC_VOID:
236 case TYPESPEC_CHAR:
237 case TYPESPEC_SHORT:
238 case TYPESPEC_INT:
239 case TYPESPEC_LONG:
240 case TYPESPEC_FLOAT:
241 case TYPESPEC_DOUBLE:
242 case TYPESPEC_SIGNED:
243 case TYPESPEC_UNSIGNED:
244 case TYPESPEC_BOOL:
245 case TYPESPEC_COMPLEX:
246 case TYPESPEC_IMAGINARY:
247 case TYPESPEC_CONST:
248 case TYPESPEC_ID_TYPE:
249 fprintf(fd, "\"/>\n");
250 break;
251 case TYPESPEC_FLOATING_POINT:
252 case TYPESPEC_INTEGER:
253 case TYPESPEC_STRING:
254 case TYPESPEC_STRUCT:
255 case TYPESPEC_VARIANT:
256 case TYPESPEC_ENUM:
257 depth--;
258 print_tabs(fd, depth);
259 fprintf(fd, "</type_specifier>\n");
260 break;
261 case TYPESPEC_UNKNOWN:
262 default:
263 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
264 (int) node->u.type_specifier.type);
265 return -EINVAL;
266 }
267
268 return 0;
269 }
270
271 static
272 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
273 {
274 int ret = 0;
275 struct ctf_node *iter;
276
277 print_tabs(fd, depth);
278 fprintf(fd, "<type_declarator>\n");
279 depth++;
280
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,
285 siblings) {
286 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
287 if (ret)
288 return ret;
289 }
290 print_tabs(fd, depth);
291 fprintf(fd, "</pointers>\n");
292 }
293
294 switch (node->u.type_declarator.type) {
295 case TYPEDEC_ID:
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");
301 }
302 break;
303 case TYPEDEC_NESTED:
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);
309 if (ret)
310 return ret;
311 print_tabs(fd, depth);
312 fprintf(fd, "</type_declarator>\n");
313 }
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,
323 siblings) {
324 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
325 if (ret)
326 return ret;
327 }
328 print_tabs(fd, depth);
329 fprintf(fd, "</length>\n");
330 }
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);
336 if (ret)
337 return ret;
338 print_tabs(fd, depth);
339 fprintf(fd, "</bitfield_len>\n");
340 }
341 break;
342 case TYPEDEC_UNKNOWN:
343 default:
344 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
345 (int) node->u.type_declarator.type);
346 return -EINVAL;
347 }
348
349 depth--;
350 print_tabs(fd, depth);
351 fprintf(fd, "</type_declarator>\n");
352 return 0;
353 }
354
355 int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
356 {
357 int ret = 0;
358 struct ctf_node *iter;
359
360 switch (node->type) {
361 case NODE_ROOT:
362 print_tabs(fd, depth);
363 fprintf(fd, "<root>\n");
364 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
365 siblings) {
366 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
367 if (ret)
368 return ret;
369 }
370 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
371 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
372 if (ret)
373 return ret;
374 }
375 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
376 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
377 if (ret)
378 return ret;
379 }
380 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
381 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
382 if (ret)
383 return ret;
384 }
385 print_tabs(fd, depth);
386 fprintf(fd, "</root>\n");
387 break;
388
389 case NODE_EVENT:
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);
394 if (ret)
395 return ret;
396 }
397 print_tabs(fd, depth);
398 fprintf(fd, "</event>\n");
399 break;
400 case NODE_STREAM:
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);
405 if (ret)
406 return ret;
407 }
408 print_tabs(fd, depth);
409 fprintf(fd, "</stream>\n");
410 break;
411 case NODE_ENV:
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);
416 if (ret)
417 return ret;
418 }
419 print_tabs(fd, depth);
420 fprintf(fd, "</env>\n");
421 break;
422 case NODE_TRACE:
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);
427 if (ret)
428 return ret;
429 }
430 print_tabs(fd, depth);
431 fprintf(fd, "</trace>\n");
432 break;
433 case NODE_CLOCK:
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);
438 if (ret)
439 return ret;
440 }
441 print_tabs(fd, depth);
442 fprintf(fd, "</clock>\n");
443 break;
444 case NODE_CALLSITE:
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);
449 if (ret)
450 return ret;
451 }
452 print_tabs(fd, depth);
453 fprintf(fd, "</callsite>\n");
454 break;
455
456
457 case NODE_CTF_EXPRESSION:
458 print_tabs(fd, depth);
459 fprintf(fd, "<ctf_expression>\n");
460 depth++;
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);
465 if (ret)
466 return ret;
467 }
468
469 print_tabs(fd, depth);
470 fprintf(fd, "</left>\n");
471
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);
476 if (ret)
477 return ret;
478 }
479 print_tabs(fd, depth);
480 fprintf(fd, "</right>\n");
481 depth--;
482 print_tabs(fd, depth);
483 fprintf(fd, "</ctf_expression>\n");
484 break;
485 case NODE_UNARY_EXPRESSION:
486 return ctf_visitor_print_unary_expression(fd, depth, node);
487
488 case NODE_TYPEDEF:
489 print_tabs(fd, depth);
490 fprintf(fd, "<typedef>\n");
491 depth++;
492 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._typedef.type_specifier_list);
493 if (ret)
494 return ret;
495
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);
500 if (ret)
501 return ret;
502 }
503 print_tabs(fd, depth);
504 fprintf(fd, "</type_declarator_list>\n");
505 depth--;
506 print_tabs(fd, depth);
507 fprintf(fd, "</typedef>\n");
508 break;
509 case NODE_TYPEALIAS_TARGET:
510 print_tabs(fd, depth);
511 fprintf(fd, "<target>\n");
512 depth++;
513
514 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_target.type_specifier_list);
515 if (ret)
516 return ret;
517
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);
522 if (ret)
523 return ret;
524 }
525 print_tabs(fd, depth);
526 fprintf(fd, "</type_declarator_list>\n");
527
528 depth--;
529 print_tabs(fd, depth);
530 fprintf(fd, "</target>\n");
531 break;
532 case NODE_TYPEALIAS_ALIAS:
533 print_tabs(fd, depth);
534 fprintf(fd, "<alias>\n");
535 depth++;
536
537 ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_alias.type_specifier_list);
538 if (ret)
539 return ret;
540
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);
545 if (ret)
546 return ret;
547 }
548 print_tabs(fd, depth);
549 fprintf(fd, "</type_declarator_list>\n");
550
551 depth--;
552 print_tabs(fd, depth);
553 fprintf(fd, "</alias>\n");
554 break;
555 case NODE_TYPEALIAS:
556 print_tabs(fd, depth);
557 fprintf(fd, "<typealias>\n");
558 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
559 if (ret)
560 return ret;
561 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
562 if (ret)
563 return ret;
564 print_tabs(fd, depth);
565 fprintf(fd, "</typealias>\n");
566 break;
567
568 case NODE_TYPE_SPECIFIER_LIST:
569 ret = ctf_visitor_print_type_specifier_list(fd, depth, node);
570 if (ret)
571 return ret;
572 break;
573
574 case NODE_TYPE_SPECIFIER:
575 ret = ctf_visitor_print_type_specifier(fd, depth, node);
576 if (ret)
577 return ret;
578 break;
579 case NODE_POINTER:
580 print_tabs(fd, depth);
581 if (node->u.pointer.const_qualifier)
582 fprintf(fd, "<const_pointer />\n");
583 else
584 fprintf(fd, "<pointer />\n");
585 break;
586 case NODE_TYPE_DECLARATOR:
587 ret = ctf_visitor_print_type_declarator(fd, depth, node);
588 if (ret)
589 return ret;
590 break;
591
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);
597 if (ret)
598 return ret;
599 }
600 print_tabs(fd, depth);
601 fprintf(fd, "</floating_point>\n");
602 break;
603 case NODE_INTEGER:
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);
608 if (ret)
609 return ret;
610 }
611 print_tabs(fd, depth);
612 fprintf(fd, "</integer>\n");
613 break;
614 case NODE_STRING:
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);
619 if (ret)
620 return ret;
621 }
622 print_tabs(fd, depth);
623 fprintf(fd, "</string>\n");
624 break;
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);
630 fprintf(fd, ">\n");
631 bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
632 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
633 if (ret)
634 return ret;
635 }
636 print_tabs(fd, depth);
637 fprintf(fd, "</enumerator>\n");
638 break;
639 case NODE_ENUM:
640 print_tabs(fd, depth);
641 if (node->u._struct.name)
642 fprintf(fd, "<enum name=\"%s\">\n",
643 node->u._enum.enum_id);
644 else
645 fprintf(fd, "<enum >\n");
646 depth++;
647
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);
652 if (ret)
653 return ret;
654 print_tabs(fd, depth);
655 fprintf(fd, "</container_type>\n");
656 }
657
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);
662 if (ret)
663 return ret;
664 }
665 print_tabs(fd, depth);
666 fprintf(fd, "</enumerator_list>\n");
667
668 depth--;
669 print_tabs(fd, depth);
670 fprintf(fd, "</enum>\n");
671 break;
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);
675 if (ret)
676 return ret;
677
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);
682 if (ret)
683 return ret;
684 }
685 print_tabs(fd, depth);
686 fprintf(fd, "</type_declarator_list>\n");
687 break;
688 case NODE_VARIANT:
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);
695 fprintf(fd, ">\n");
696 bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
697 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
698 if (ret)
699 return ret;
700 }
701 print_tabs(fd, depth);
702 fprintf(fd, "</variant>\n");
703 break;
704 case NODE_STRUCT:
705 print_tabs(fd, depth);
706 if (node->u._struct.name)
707 fprintf(fd, "<struct name=\"%s\">\n",
708 node->u._struct.name);
709 else
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);
713 if (ret)
714 return ret;
715 }
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);
723 if (ret)
724 return ret;
725 }
726 print_tabs(fd, depth);
727 fprintf(fd, "</align>\n");
728 }
729 break;
730
731 case NODE_UNKNOWN:
732 default:
733 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
734 (int) node->type);
735 return -EINVAL;
736 }
737 return ret;
738 }
This page took 0.04296 seconds and 3 git commands to generate.