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