22829d9b47401ab1132cfcf0465fb113267bdce4
[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
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
33 static 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
41 int 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.link) {
46 case UNARY_LINK_UNKNOWN:
47 break;
48 case UNARY_DOTLINK:
49 print_tabs(fd, depth);
50 fprintf(fd, "<dotlink/>\n");
51 break;
52 case UNARY_ARROWLINK:
53 print_tabs(fd, depth);
54 fprintf(fd, "<arrowlink/>\n");
55 break;
56 case UNARY_DOTDOTDOT:
57 print_tabs(fd, depth);
58 fprintf(fd, "<dotdotdot/>\n");
59 break;
60 default:
61 fprintf(stderr, "[error] %s: unknown expression link type %d\n", __func__,
62 (int) node->u.unary_expression.link);
63 return -EINVAL;
64 }
65
66 switch (node->u.unary_expression.type) {
67 case UNARY_STRING:
68 print_tabs(fd, depth);
69 fprintf(fd, "<unary_expression value=");
70 fprintf(fd, "\"%s\"", node->u.unary_expression.u.string);
71 fprintf(fd, " />\n");
72 break;
73 case UNARY_SIGNED_CONSTANT:
74 print_tabs(fd, depth);
75 fprintf(fd, "<unary_expression value=");
76 fprintf(fd, "%lld", node->u.unary_expression.u.signed_constant);
77 fprintf(fd, " />\n");
78 break;
79 case UNARY_UNSIGNED_CONSTANT:
80 print_tabs(fd, depth);
81 fprintf(fd, "<unary_expression value=");
82 fprintf(fd, "%llu", node->u.unary_expression.u.signed_constant);
83 fprintf(fd, " />\n");
84 break;
85 case UNARY_SBRAC:
86 print_tabs(fd, depth);
87 fprintf(fd, "<unary_expression_sbrac>");
88 ret = ctf_visitor_print_unary_expression(fd, depth + 1,
89 node->u.unary_expression.u.sbrac_exp);
90 if (ret)
91 return ret;
92 print_tabs(fd, depth);
93 fprintf(fd, "</unary_expression_sbrac>");
94 break;
95 case UNARY_NESTED:
96 print_tabs(fd, depth);
97 fprintf(fd, "<unary_expression_nested>");
98 ret = ctf_visitor_print_unary_expression(fd, depth + 1,
99 node->u.unary_expression.u.nested_exp);
100 if (ret)
101 return ret;
102 print_tabs(fd, depth);
103 fprintf(fd, "</unary_expression_nested>");
104 break;
105
106 case UNARY_UNKNOWN:
107 default:
108 fprintf(stderr, "[error] %s: unknown expression type %d\n", __func__,
109 (int) node->u.unary_expression.type);
110 return -EINVAL;
111 }
112 return 0;
113 }
114
115 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
116 {
117 print_tabs(fd, depth);
118 fprintf(fd, "<type_specifier \"");
119
120 switch (node->u.type_specifier.type) {
121 case TYPESPEC_VOID:
122 fprintf(fd, "void");
123 break;
124 case TYPESPEC_CHAR:
125 fprintf(fd, "char");
126 break;
127 case TYPESPEC_SHORT:
128 fprintf(fd, "short");
129 break;
130 case TYPESPEC_INT:
131 fprintf(fd, "int");
132 break;
133 case TYPESPEC_LONG:
134 fprintf(fd, "long");
135 break;
136 case TYPESPEC_FLOAT:
137 fprintf(fd, "float");
138 break;
139 case TYPESPEC_DOUBLE:
140 fprintf(fd, "double");
141 break;
142 case TYPESPEC_SIGNED:
143 fprintf(fd, "signed");
144 break;
145 case TYPESPEC_UNSIGNED:
146 fprintf(fd, "unsigned");
147 break;
148 case TYPESPEC_BOOL:
149 fprintf(fd, "bool");
150 break;
151 case TYPESPEC_COMPLEX:
152 fprintf(fd, "complex");
153 break;
154 case TYPESPEC_CONST:
155 fprintf(fd, "const");
156 break;
157 case TYPESPEC_ID_TYPE:
158 fprintf(fd, "%s", node->u.type_specifier.id_type);
159 break;
160
161 case TYPESPEC_UNKNOWN:
162 default:
163 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
164 (int) node->u.type_specifier.type);
165 return -EINVAL;
166 }
167 fprintf(fd, "\"/>\n");
168 return 0;
169 }
170
171 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
172 {
173 int ret = 0;
174 struct ctf_node *iter;
175
176 print_tabs(fd, depth);
177 fprintf(fd, "<type_declarator>\n");
178 depth++;
179
180 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
181 print_tabs(fd, depth);
182 fprintf(fd, "<pointers>\n");
183 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
184 siblings) {
185 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
186 if (ret)
187 return ret;
188 }
189 print_tabs(fd, depth);
190 fprintf(fd, "</pointers>\n");
191 }
192
193 switch (node->u.type_declarator.type) {
194 case TYPEDEC_ID:
195 print_tabs(fd, depth);
196 fprintf(fd, "<id \"");
197 fprintf(fd, "%s", node->u.type_declarator.u.id);
198 fprintf(fd, "\" />\n");
199 break;
200 case TYPEDEC_NESTED:
201 if (node->u.type_declarator.u.nested.type_declarator) {
202 print_tabs(fd, depth);
203 fprintf(fd, "<type_declarator>\n");
204 ret = ctf_visitor_print_xml(fd, depth + 1,
205 node->u.type_declarator.u.nested.type_declarator);
206 if (ret)
207 return ret;
208 print_tabs(fd, depth);
209 fprintf(fd, "</type_declarator>\n");
210 }
211 if (node->u.type_declarator.u.nested.length) {
212 print_tabs(fd, depth);
213 fprintf(fd, "<length>\n");
214 ret = ctf_visitor_print_xml(fd, depth + 1,
215 node->u.type_declarator.u.nested.length);
216 if (ret)
217 return ret;
218 print_tabs(fd, depth);
219 fprintf(fd, "</length>\n");
220 }
221 if (node->u.type_declarator.u.nested.abstract_array) {
222 print_tabs(fd, depth);
223 fprintf(fd, "<length>\n");
224 print_tabs(fd, depth);
225 fprintf(fd, "</length>\n");
226 }
227 if (node->u.type_declarator.bitfield_len) {
228 print_tabs(fd, depth);
229 fprintf(fd, "<bitfield_len>\n");
230 ret = ctf_visitor_print_xml(fd, depth + 1,
231 node->u.type_declarator.bitfield_len);
232 if (ret)
233 return ret;
234 print_tabs(fd, depth);
235 fprintf(fd, "</bitfield_len>\n");
236 }
237 break;
238 case TYPEDEC_UNKNOWN:
239 default:
240 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
241 (int) node->u.type_declarator.type);
242 return -EINVAL;
243 }
244
245 depth--;
246 print_tabs(fd, depth);
247 fprintf(fd, "</type_declarator>\n");
248 return 0;
249 }
250
251 int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
252 {
253 int ret = 0;
254 struct ctf_node *iter;
255
256 switch (node->type) {
257 case NODE_ROOT:
258 print_tabs(fd, depth);
259 fprintf(fd, "<root>\n");
260 cds_list_for_each_entry(iter, &node->u.root._typedef,
261 siblings) {
262 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
263 if (ret)
264 return ret;
265 }
266 cds_list_for_each_entry(iter, &node->u.root.typealias,
267 siblings) {
268 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
269 if (ret)
270 return ret;
271 }
272 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
273 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
274 if (ret)
275 return ret;
276 }
277 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
278 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
279 if (ret)
280 return ret;
281 }
282 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
283 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
284 if (ret)
285 return ret;
286 }
287 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
288 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
289 if (ret)
290 return ret;
291 }
292 print_tabs(fd, depth);
293 fprintf(fd, "</root>\n");
294 break;
295
296 case NODE_EVENT:
297 print_tabs(fd, depth);
298 fprintf(fd, "<event>\n");
299 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
300 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
301 if (ret)
302 return ret;
303 }
304 print_tabs(fd, depth);
305 fprintf(fd, "</event>\n");
306 break;
307 case NODE_STREAM:
308 print_tabs(fd, depth);
309 fprintf(fd, "<stream>\n");
310 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
311 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
312 if (ret)
313 return ret;
314 }
315 print_tabs(fd, depth);
316 fprintf(fd, "</stream>\n");
317 break;
318 case NODE_TRACE:
319 print_tabs(fd, depth);
320 fprintf(fd, "<trace>\n");
321 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
322 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
323 if (ret)
324 return ret;
325 }
326 print_tabs(fd, depth);
327 fprintf(fd, "</trace>\n");
328 break;
329
330 case NODE_CTF_EXPRESSION:
331 print_tabs(fd, depth);
332 fprintf(fd, "<ctf_expression>\n");
333 depth++;
334 print_tabs(fd, depth);
335 fprintf(fd, "<left>\n");
336 cds_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
337 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
338 if (ret)
339 return ret;
340 }
341
342 print_tabs(fd, depth);
343 fprintf(fd, "</left>\n");
344
345 print_tabs(fd, depth);
346 fprintf(fd, "<right>\n");
347 cds_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
348 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
349 if (ret)
350 return ret;
351 }
352 print_tabs(fd, depth);
353 fprintf(fd, "</right>\n");
354 depth--;
355 print_tabs(fd, depth);
356 fprintf(fd, "</ctf_expression>\n");
357 break;
358 case NODE_UNARY_EXPRESSION:
359 return ctf_visitor_print_unary_expression(fd, depth, node);
360
361 case NODE_TYPEDEF:
362 print_tabs(fd, depth);
363 fprintf(fd, "<typedef>\n");
364 depth++;
365 print_tabs(fd, depth);
366 fprintf(fd, "<declaration_specifier>\n");
367 cds_list_for_each_entry(iter, &node->u._typedef.declaration_specifier, siblings) {
368 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
369 if (ret)
370 return ret;
371 }
372 print_tabs(fd, depth);
373 fprintf(fd, "</declaration_specifier>\n");
374
375 print_tabs(fd, depth);
376 fprintf(fd, "<type_declarators>\n");
377 cds_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
378 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
379 if (ret)
380 return ret;
381 }
382 print_tabs(fd, depth);
383 fprintf(fd, "</type_declarators>\n");
384 depth--;
385 print_tabs(fd, depth);
386 fprintf(fd, "</typedef>\n");
387 break;
388 case NODE_TYPEALIAS_TARGET:
389 print_tabs(fd, depth);
390 fprintf(fd, "<target>\n");
391 depth++;
392
393 print_tabs(fd, depth);
394 fprintf(fd, "<declaration_specifier>\n");
395 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
396 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
397 if (ret)
398 return ret;
399 }
400 print_tabs(fd, depth);
401 fprintf(fd, "</declaration_specifier>\n");
402
403 print_tabs(fd, depth);
404 fprintf(fd, "<type_declarators>\n");
405 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
406 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
407 if (ret)
408 return ret;
409 }
410 print_tabs(fd, depth);
411 fprintf(fd, "</type_declarators>\n");
412
413 depth--;
414 print_tabs(fd, depth);
415 fprintf(fd, "</target>\n");
416 break;
417 case NODE_TYPEALIAS_ALIAS:
418 print_tabs(fd, depth);
419 fprintf(fd, "<alias>\n");
420 depth++;
421
422 print_tabs(fd, depth);
423 fprintf(fd, "<declaration_specifier>\n");
424 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
425 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
426 if (ret)
427 return ret;
428 }
429 print_tabs(fd, depth);
430 fprintf(fd, "</declaration_specifier>\n");
431
432 print_tabs(fd, depth);
433 fprintf(fd, "<type_declarators>\n");
434 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
435 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
436 if (ret)
437 return ret;
438 }
439 print_tabs(fd, depth);
440 fprintf(fd, "</type_declarators>\n");
441
442 depth--;
443 print_tabs(fd, depth);
444 fprintf(fd, "</alias>\n");
445 break;
446 case NODE_TYPEALIAS:
447 print_tabs(fd, depth);
448 fprintf(fd, "<typealias>\n");
449 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
450 if (ret)
451 return ret;
452 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
453 if (ret)
454 return ret;
455 print_tabs(fd, depth);
456 fprintf(fd, "</typealias>\n");
457 break;
458
459 case NODE_TYPE_SPECIFIER:
460 ret = ctf_visitor_print_type_specifier(fd, depth, node);
461 if (ret)
462 return ret;
463 break;
464 case NODE_POINTER:
465 print_tabs(fd, depth);
466 if (node->u.pointer.const_qualifier)
467 fprintf(fd, "<const_pointer />\n");
468 else
469 fprintf(fd, "<pointer />\n");
470 break;
471 case NODE_TYPE_DECLARATOR:
472 ret = ctf_visitor_print_type_declarator(fd, depth, node);
473 if (ret)
474 return ret;
475 break;
476
477 case NODE_FLOATING_POINT:
478 print_tabs(fd, depth);
479 fprintf(fd, "<floating_point>\n");
480 cds_list_for_each_entry(iter, &node->u.floating_point.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, "</floating_point>\n");
487 break;
488 case NODE_INTEGER:
489 print_tabs(fd, depth);
490 fprintf(fd, "<integer>\n");
491 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
492 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
493 if (ret)
494 return ret;
495 }
496 print_tabs(fd, depth);
497 fprintf(fd, "</integer>\n");
498 break;
499 case NODE_STRING:
500 print_tabs(fd, depth);
501 fprintf(fd, "<string>\n");
502 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
503 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
504 if (ret)
505 return ret;
506 }
507 print_tabs(fd, depth);
508 fprintf(fd, "</string>\n");
509 break;
510 case NODE_ENUMERATOR:
511 print_tabs(fd, depth);
512 fprintf(fd, "<enumerator");
513 if (node->u.enumerator.id)
514 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
515 fprintf(fd, ">\n");
516 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
517 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
518 if (ret)
519 return ret;
520 }
521 print_tabs(fd, depth);
522 fprintf(fd, "</enumerator>\n");
523 break;
524 case NODE_ENUM:
525 print_tabs(fd, depth);
526 if (node->u._struct.name)
527 fprintf(fd, "<enum name=\"%s\">\n",
528 node->u._enum.enum_id);
529 else
530 fprintf(fd, "<enum >\n");
531 depth++;
532
533 if (node->u._enum.container_type) {
534 print_tabs(fd, depth);
535 fprintf(fd, "<container_type>\n");
536 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
537 if (ret)
538 return ret;
539 print_tabs(fd, depth);
540 fprintf(fd, "</container_type>\n");
541 }
542
543 print_tabs(fd, depth);
544 fprintf(fd, "<enumerator_list>\n");
545 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
546 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
547 if (ret)
548 return ret;
549 }
550 print_tabs(fd, depth);
551 fprintf(fd, "</enumerator_list>\n");
552
553 depth--;
554 print_tabs(fd, depth);
555 fprintf(fd, "</enum>\n");
556 break;
557 case NODE_STRUCT_OR_VARIANT_DECLARATION:
558 print_tabs(fd, depth);
559 fprintf(fd, "<declaration_specifier>\n");
560 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
561 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
562 if (ret)
563 return ret;
564 }
565 print_tabs(fd, depth);
566 fprintf(fd, "</declaration_specifier>\n");
567
568 print_tabs(fd, depth);
569 fprintf(fd, "<type_declarators>\n");
570 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
571 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
572 if (ret)
573 return ret;
574 }
575 print_tabs(fd, depth);
576 fprintf(fd, "</type_declarators>\n");
577 break;
578 case NODE_VARIANT:
579 print_tabs(fd, depth);
580 fprintf(fd, "<variant");
581 if (node->u.variant.name)
582 fprintf(fd, " name=\"%s\"", node->u.variant.name);
583 if (node->u.variant.choice)
584 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
585 fprintf(fd, ">\n");
586 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
587 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
588 if (ret)
589 return ret;
590 }
591 print_tabs(fd, depth);
592 fprintf(fd, "</variant>\n");
593 break;
594 case NODE_STRUCT:
595 print_tabs(fd, depth);
596 if (node->u._struct.name)
597 fprintf(fd, "<struct name=\"%s\">\n",
598 node->u._struct.name);
599 else
600 fprintf(fd, "<struct>\n");
601 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
602 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
603 if (ret)
604 return ret;
605 }
606 print_tabs(fd, depth);
607 fprintf(fd, "</struct>\n");
608 break;
609
610 case NODE_UNKNOWN:
611 default:
612 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
613 (int) node->type);
614 return -EINVAL;
615 }
616 return ret;
617 }
This page took 0.040977 seconds and 3 git commands to generate.