3bd4238c8ef4a18a6c67d4e7b159ff48a8ec5218
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
1 /*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
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 fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
33
34
35 static
36 int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
37 {
38 print_tabs(fd, depth);
39 fprintf(fd, "<type_specifier \"");
40
41 switch (node->u.type_specifier.type) {
42 case TYPESPEC_VOID:
43 fprintf(fd, "void");
44 break;
45 case TYPESPEC_CHAR:
46 fprintf(fd, "char");
47 break;
48 case TYPESPEC_SHORT:
49 fprintf(fd, "short");
50 break;
51 case TYPESPEC_INT:
52 fprintf(fd, "int");
53 break;
54 case TYPESPEC_LONG:
55 fprintf(fd, "long");
56 break;
57 case TYPESPEC_FLOAT:
58 fprintf(fd, "float");
59 break;
60 case TYPESPEC_DOUBLE:
61 fprintf(fd, "double");
62 break;
63 case TYPESPEC_SIGNED:
64 fprintf(fd, "signed");
65 break;
66 case TYPESPEC_UNSIGNED:
67 fprintf(fd, "unsigned");
68 break;
69 case TYPESPEC_BOOL:
70 fprintf(fd, "bool");
71 break;
72 case TYPESPEC_COMPLEX:
73 fprintf(fd, "complex");
74 break;
75 case TYPESPEC_CONST:
76 fprintf(fd, "const");
77 break;
78 case TYPESPEC_ID_TYPE:
79 fprintf(fd, "%s", node->u.type_specifier.id_type);
80 break;
81
82 case TYPESPEC_UNKNOWN:
83 default:
84 fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
85 (int) node->u.type_specifier.type);
86 return -EINVAL;
87 }
88 fprintf(fd, "\"/>\n");
89 return 0;
90 }
91
92 static
93 int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
94 {
95 int ret = 0;
96 struct ctf_node *iter;
97
98 print_tabs(fd, depth);
99 fprintf(fd, "<type_declarator>\n");
100 depth++;
101
102 if (!cds_list_empty(&node->u.type_declarator.pointers)) {
103 print_tabs(fd, depth);
104 fprintf(fd, "<pointers>\n");
105 cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
106 siblings) {
107 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
108 if (ret)
109 return ret;
110 }
111 print_tabs(fd, depth);
112 fprintf(fd, "</pointers>\n");
113 }
114
115 switch (node->u.type_declarator.type) {
116 case TYPEDEC_ID:
117 if (node->u.type_declarator.u.id) {
118 print_tabs(fd, depth);
119 fprintf(fd, "<id \"");
120 fprintf(fd, "%s", node->u.type_declarator.u.id);
121 fprintf(fd, "\" />\n");
122 }
123 break;
124 case TYPEDEC_NESTED:
125 if (node->u.type_declarator.u.nested.type_declarator) {
126 print_tabs(fd, depth);
127 fprintf(fd, "<type_declarator>\n");
128 ret = ctf_visitor_print_xml(fd, depth + 1,
129 node->u.type_declarator.u.nested.type_declarator);
130 if (ret)
131 return ret;
132 print_tabs(fd, depth);
133 fprintf(fd, "</type_declarator>\n");
134 }
135 if (node->u.type_declarator.u.nested.length) {
136 print_tabs(fd, depth);
137 fprintf(fd, "<length>\n");
138 ret = ctf_visitor_print_xml(fd, depth + 1,
139 node->u.type_declarator.u.nested.length);
140 if (ret)
141 return ret;
142 print_tabs(fd, depth);
143 fprintf(fd, "</length>\n");
144 }
145 if (node->u.type_declarator.u.nested.abstract_array) {
146 print_tabs(fd, depth);
147 fprintf(fd, "<length>\n");
148 print_tabs(fd, depth);
149 fprintf(fd, "</length>\n");
150 }
151 if (node->u.type_declarator.bitfield_len) {
152 print_tabs(fd, depth);
153 fprintf(fd, "<bitfield_len>\n");
154 ret = ctf_visitor_print_xml(fd, depth + 1,
155 node->u.type_declarator.bitfield_len);
156 if (ret)
157 return ret;
158 print_tabs(fd, depth);
159 fprintf(fd, "</bitfield_len>\n");
160 }
161 break;
162 case TYPEDEC_UNKNOWN:
163 default:
164 fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
165 (int) node->u.type_declarator.type);
166 return -EINVAL;
167 }
168
169 depth--;
170 print_tabs(fd, depth);
171 fprintf(fd, "</type_declarator>\n");
172 return 0;
173 }
174
175 /*
176 * String returned must be freed by the caller.
177 */
178 static
179 char *concatenate_unary_strings(struct list_head *head)
180 {
181
182 }
183
184 static
185 int get_unary_unsigned(struct list_head *head, uint64_t *value)
186 {
187
188 }
189
190 static
191 int get_unary_uuid(struct list_head *head, uuid_t *uuid)
192 {
193
194 }
195
196 static
197 struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
198 {
199 if (trace->streams->len <= stream_id)
200 return NULL;
201 return g_ptr_array_index(trace->streams, stream_id);
202 }
203
204 static
205 struct ctf_declaration *ctf_declaration_specifier_visit(FILE *fd,
206 int depth, struct list_head *head,
207 struct type_scope *type_scope,
208 struct declaration_scope *declaration_scope)
209 {
210
211 }
212
213 /*
214 * Use declaration specifier visitor, and add resulting variant, struct
215 * or enum to the current type scope.
216 */
217 static
218 int ctf_type_specifier_visit(FILE *fd,
219 int depth, struct list_head *head,
220 struct type_scope *type_scope,
221 struct declaration_scope *declaration_scope)
222 {
223
224 }
225
226 static
227 int ctf_typedef_declarator_visit(FILE *fd, int depth,
228 struct list_head *declaration_specifier,
229 struct node *type_declarator, struct type_scope *type_scope,
230 struct declaration_scope *declaration_scope)
231 {
232 /*
233 * Build the type using declaration specifier, then apply type
234 * declarator, add the resulting type to the current type scope.
235 */
236 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
237
238
239 }
240 return 0;
241 }
242
243 static
244 int ctf_typedef_visit(FILE *fd, int depth,
245 struct list_head *declaration_specifier,
246 struct list_head *type_declarators,
247 struct type_scope *type_scope,
248 struct declaration_scope *declaration_scope)
249 {
250 struct ctf_node *iter;
251
252 cds_list_for_each_entry(iter, type_declarators, siblings) {
253 ret = ctf_typedef_declarator_visit(fd, depth + 1,
254 &node->u._typedef.declaration_specifier, iter,
255 type_scope, declaration_scope);
256 if (ret)
257 return ret;
258 }
259 return 0;
260 }
261
262 static
263 int ctf_typealias_visit(FILE *fd, int depth, struct ctf_node *target,
264 struct ctf_node *alias, struct type_scope *type_scope,
265 struct declaration_scope *declaration_scope)
266 {
267 /* Build target type, check that it is reachable in current type scope. */
268 /* Only one type declarator is allowed */
269
270 /* Build alias type, add to current type scope. */
271 /* Only one type declarator is allowed */
272 }
273
274 static
275 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
276 {
277 int ret = 0;
278
279 switch (node->type) {
280 case NODE_TYPEDEF:
281 ret = ctf_typedef_visit(fd, depth + 1,
282 &node->u._typedef.declaration_specifier,
283 &node->u._typedef.type_declarators,
284 event->type_scope, event->declaration_scope);
285 if (ret)
286 return ret;
287 break;
288 case NODE_TYPEALIAS:
289 ret = ctf_typealias_visit(fd, depth + 1,
290 &node->u.typealias.target, &node->u.typealias.alias
291 event->type_scope, event->declaration_scope);
292 if (ret)
293 return ret;
294 break;
295 case NODE_CTF_EXPRESSION:
296 {
297 char *left;
298
299 left = concatenate_unary_strings(&node->u.ctf_expression.left);
300 if (!strcmp(left, "name")) {
301 char *right;
302
303 if (CTF_EVENT_FIELD_IS_SET(event, name))
304 return -EPERM;
305 right = concatenate_unary_strings(&node->u.ctf_expression.right);
306 if (!right) {
307 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
308 return -EINVAL;
309 }
310 event->name = g_quark_from_string(right);
311 free(right);
312 CTF_EVENT_SET_FIELD(event, name);
313 } else if (!strcmp(left, "id")) {
314 if (CTF_EVENT_FIELD_IS_SET(event, id))
315 return -EPERM;
316 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
317 if (ret) {
318 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
319 return -EINVAL;
320 }
321 CTF_EVENT_SET_FIELD(event, id);
322 } else if (!strcmp(left, "stream_id")) {
323 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
324 return -EPERM;
325 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
326 if (ret) {
327 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
328 return -EINVAL;
329 }
330 event->stream = trace_stream_lookup(trace, event->stream_id);
331 if (!event->stream) {
332 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
333 return -EINVAL;
334 }
335 event->declaration_scope = new_declaration_scope(stream->declaration_scope);
336 if (!event->declaration_scope) {
337 fprintf(stderr, "[error] %s: Error allocating declaration scope\n", __func__);
338 return -EPERM;
339 }
340 CTF_EVENT_SET_FIELD(event, stream_id);
341 } else if (!strcmp(left, "context")) {
342 struct declaration *declaration;
343
344 if (!event->declaration_scope)
345 return -EPERM;
346 declaration = ctf_declaration_specifier_visit(fd, depth,
347 &node->u.ctf_expression.right,
348 event->type_scope, event->declaration_scope);
349 if (!declaration)
350 return -EPERM;
351 if (declaration->type->id != CTF_TYPE_STRUCT)
352 return -EPERM;
353 event->context = container_of(declaration, struct declaration_struct, p);
354 } else if (!strcmp(left, "fields")) {
355 struct declaration *declaration;
356
357 if (!event->declaration_scope)
358 return -EPERM;
359 declaration = ctf_declaration_specifier_visit(fd, depth,
360 &node->u.ctf_expression.right,
361 event->type_scope, event->declaration_scope);
362 if (!declaration)
363 return -EPERM;
364 if (declaration->type->id != CTF_TYPE_STRUCT)
365 return -EPERM;
366 event->fields = container_of(declaration, struct declaration_struct, p);
367 }
368 free(left);
369 break;
370 }
371 default:
372 return -EPERM;
373 /* TODO: declaration specifier should be added. */
374 }
375
376 return 0;
377 }
378
379 static
380 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
381 struct type_scope *parent_type_scope, struct ctf_trace *trace)
382 {
383 int ret = 0;
384 struct ctf_node *iter;
385 struct ctf_event *event;
386
387 event = g_new0(struct ctf_event, 1);
388 event->type_scope = new_type_scope(parent_type_scope);
389 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
390 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
391 if (ret)
392 goto error;
393 }
394 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
395 ret = -EPERM;
396 goto error;
397 }
398 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
399 ret = -EPERM;
400 goto error;
401 }
402 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
403 ret = -EPERM;
404 goto error;
405 }
406 if (event->stream->events_by_id->len <= event->id)
407 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
408 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
409 g_hash_table_insert(event->stream->event_quark_to_id,
410 (gpointer)(unsigned long) event->name,
411 &event->id);
412 return 0;
413
414 error:
415 declaration_unref(event->fields);
416 declaration_unref(event->context);
417 free_declaration_scope(event->declaration_scope);
418 free_type_scope(event->type_scope);
419 g_free(event);
420 return ret;
421 }
422
423
424 static
425 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
426 {
427 int ret = 0;
428
429 switch (node->type) {
430 case NODE_TYPEDEF:
431 ret = ctf_typedef_visit(fd, depth + 1,
432 &node->u._typedef.declaration_specifier,
433 &node->u._typedef.type_declarators,
434 stream->type_scope, stream->declaration_scope);
435 if (ret)
436 return ret;
437 break;
438 case NODE_TYPEALIAS:
439 ret = ctf_typealias_visit(fd, depth + 1,
440 &node->u.typealias.target, &node->u.typealias.alias
441 stream->type_scope, stream->declaration_scope);
442 if (ret)
443 return ret;
444 break;
445 case NODE_CTF_EXPRESSION:
446 {
447 char *left;
448
449 left = concatenate_unary_strings(&node->u.ctf_expression.left);
450 if (!strcmp(left, "stream_id")) {
451 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
452 return -EPERM;
453 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
454 if (ret) {
455 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
456 return -EINVAL;
457 }
458 CTF_EVENT_SET_FIELD(event, stream_id);
459 } else if (!strcmp(left, "event_header")) {
460 struct declaration *declaration;
461
462 declaration = ctf_declaration_specifier_visit(fd, depth,
463 &node->u.ctf_expression.right,
464 stream->type_scope, stream->declaration_scope);
465 if (!declaration)
466 return -EPERM;
467 if (declaration->type->id != CTF_TYPE_STRUCT)
468 return -EPERM;
469 stream->event_header = container_of(declaration, struct declaration_struct, p);
470 } else if (!strcmp(left, "event_context")) {
471 struct declaration *declaration;
472
473 declaration = ctf_declaration_specifier_visit(fd, depth,
474 &node->u.ctf_expression.right,
475 stream->type_scope, stream->declaration_scope);
476 if (!declaration)
477 return -EPERM;
478 if (declaration->type->id != CTF_TYPE_STRUCT)
479 return -EPERM;
480 stream->event_context = container_of(declaration, struct declaration_struct, p);
481 } else if (!strcmp(left, "packet_context")) {
482 struct declaration *declaration;
483
484 declaration = ctf_declaration_specifier_visit(fd, depth,
485 &node->u.ctf_expression.right,
486 stream->type_scope, stream->declaration_scope);
487 if (!declaration)
488 return -EPERM;
489 if (declaration->type->id != CTF_TYPE_STRUCT)
490 return -EPERM;
491 stream->packet_context = container_of(declaration, struct declaration_struct, p);
492 }
493 free(left);
494 break;
495 }
496 default:
497 return -EPERM;
498 /* TODO: declaration specifier should be added. */
499 }
500
501 return 0;
502 }
503
504 static
505 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
506 struct type_scope *parent_type_scope, struct ctf_trace *trace)
507 {
508 int ret = 0;
509 struct ctf_node *iter;
510 struct ctf_stream *stream;
511
512 stream = g_new0(struct ctf_stream, 1);
513 stream->type_scope = new_type_scope(parent_type_scope);
514 stream->declaration_scope = new_declaration_scope(trace->declaration_scope);
515 stream->events_by_id = g_ptr_array_new();
516 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
517 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
518 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
519 if (ret)
520 goto error;
521 }
522 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
523 ret = -EPERM;
524 goto error;
525 }
526 if (trace->streams->len <= stream->stream_id)
527 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
528 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
529 return 0;
530
531 error:
532 declaration_unref(stream->event_header);
533 declaration_unref(stream->event_context);
534 declaration_unref(stream->packet_context);
535 g_ptr_array_free(stream->events_by_id, TRUE);
536 g_hash_table_free(stream->event_quark_to_id);
537 free_declaration_scope(stream->declaration_scope);
538 free_type_scope(stream->type_scope);
539 g_free(stream);
540 return ret;
541 }
542
543 static
544 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
545 {
546 int ret = 0;
547
548 switch (node->type) {
549 case NODE_TYPEDEF:
550 ret = ctf_typedef_visit(fd, depth + 1,
551 &node->u._typedef.declaration_specifier,
552 &node->u._typedef.type_declarators,
553 trace->type_scope, trace->declaration_scope);
554 if (ret)
555 return ret;
556 break;
557 case NODE_TYPEALIAS:
558 ret = ctf_typealias_visit(fd, depth + 1,
559 &node->u.typealias.target, &node->u.typealias.alias
560 trace->type_scope, trace->declaration_scope);
561 if (ret)
562 return ret;
563 break;
564 case NODE_CTF_EXPRESSION:
565 {
566 char *left;
567
568 left = concatenate_unary_strings(&node->u.ctf_expression.left);
569 if (!strcmp(left, "major")) {
570 if (CTF_EVENT_FIELD_IS_SET(trace, major))
571 return -EPERM;
572 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
573 if (ret) {
574 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
575 return -EINVAL;
576 }
577 CTF_EVENT_SET_FIELD(trace, major);
578 } else if (!strcmp(left, "minor")) {
579 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
580 return -EPERM;
581 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
582 if (ret) {
583 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
584 return -EINVAL;
585 }
586 CTF_EVENT_SET_FIELD(trace, minor);
587 } else if (!strcmp(left, "word_size")) {
588 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
589 return -EPERM;
590 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
591 if (ret) {
592 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
593 return -EINVAL;
594 }
595 CTF_EVENT_SET_FIELD(trace, word_size);
596 } else if (!strcmp(left, "uuid")) {
597 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
598 return -EPERM;
599 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
600 if (ret) {
601 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
602 return -EINVAL;
603 }
604 CTF_EVENT_SET_FIELD(trace, uuid);
605 }
606 free(left);
607 break;
608 }
609 default:
610 return -EPERM;
611 /* TODO: declaration specifier should be added. */
612 }
613
614 return 0;
615 }
616
617
618 static
619 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
620 {
621 int ret = 0;
622 struct ctf_node *iter;
623
624 if (trace->type_scope)
625 return -EEXIST;
626 trace->type_scope = new_type_scope(trace->root_type_scope);
627 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
628 trace->streams = g_ptr_array_new();
629 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
630 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
631 if (ret)
632 goto error;
633 }
634 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
635 ret = -EPERM;
636 goto error;
637 }
638 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
639 ret = -EPERM;
640 goto error;
641 }
642 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
643 ret = -EPERM;
644 goto error;
645 }
646 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
647 ret = -EPERM;
648 goto error;
649 }
650 return 0;
651
652 error:
653 g_ptr_array_free(trace->streams, TRUE);
654 free_declaration_scope(stream->declaration_scope);
655 free_type_scope(stream->type_scope);
656 return ret;
657 }
658
659 int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
660 {
661 int ret = 0;
662 struct ctf_node *iter;
663
664 switch (node->type) {
665 case NODE_ROOT:
666 cds_list_for_each_entry(iter, &node->u.root._typedef,
667 siblings) {
668 ret = ctf_typedef_visit(fd, depth + 1,
669 &iter->u._typedef.declaration_specifier,
670 &iter->u._typedef.type_declarators,
671 trace->type_scope, trace->declaration_scope);
672 if (ret)
673 return ret;
674 }
675 cds_list_for_each_entry(iter, &node->u.root.typealias,
676 siblings) {
677 ret = ctf_typealias_visit(fd, depth + 1,
678 &iter->u.typealias.target, &iter->u.typealias.alias
679 trace->type_scope, trace->declaration_scope);
680 if (ret)
681 return ret;
682 }
683 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
684 ret = ctf_type_specifier_visit(fd, depth, iter,
685 trace->root_type_scope,
686 trace->root_declaration_scope);
687 if (ret)
688 return ret;
689 }
690 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
691 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
692 if (ret)
693 return ret;
694 }
695 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
696 ret = ctf_stream_visit(fd, depth + 1, iter,
697 trace->type_scope, trace);
698 if (ret)
699 return ret;
700 }
701 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
702 ret = ctf_event_visit(fd, depth + 1, iter,
703 trace->type_scope, trace);
704 if (ret)
705 return ret;
706 }
707 break;
708
709 case NODE_TYPEALIAS_TARGET:
710 print_tabs(fd, depth);
711 fprintf(fd, "<target>\n");
712 depth++;
713
714 print_tabs(fd, depth);
715 fprintf(fd, "<declaration_specifier>\n");
716 cds_list_for_each_entry(iter, &node->u.typealias_target.declaration_specifier, siblings) {
717 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
718 if (ret)
719 return ret;
720 }
721 print_tabs(fd, depth);
722 fprintf(fd, "</declaration_specifier>\n");
723
724 print_tabs(fd, depth);
725 fprintf(fd, "<type_declarators>\n");
726 cds_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
727 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
728 if (ret)
729 return ret;
730 }
731 print_tabs(fd, depth);
732 fprintf(fd, "</type_declarators>\n");
733
734 depth--;
735 print_tabs(fd, depth);
736 fprintf(fd, "</target>\n");
737 break;
738 case NODE_TYPEALIAS_ALIAS:
739 print_tabs(fd, depth);
740 fprintf(fd, "<alias>\n");
741 depth++;
742
743 print_tabs(fd, depth);
744 fprintf(fd, "<declaration_specifier>\n");
745 cds_list_for_each_entry(iter, &node->u.typealias_alias.declaration_specifier, siblings) {
746 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
747 if (ret)
748 return ret;
749 }
750 print_tabs(fd, depth);
751 fprintf(fd, "</declaration_specifier>\n");
752
753 print_tabs(fd, depth);
754 fprintf(fd, "<type_declarators>\n");
755 cds_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
756 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
757 if (ret)
758 return ret;
759 }
760 print_tabs(fd, depth);
761 fprintf(fd, "</type_declarators>\n");
762
763 depth--;
764 print_tabs(fd, depth);
765 fprintf(fd, "</alias>\n");
766 break;
767 case NODE_TYPEALIAS:
768 print_tabs(fd, depth);
769 fprintf(fd, "<typealias>\n");
770 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
771 if (ret)
772 return ret;
773 ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
774 if (ret)
775 return ret;
776 print_tabs(fd, depth);
777 fprintf(fd, "</typealias>\n");
778 break;
779
780 case NODE_TYPE_SPECIFIER:
781 ret = ctf_visitor_print_type_specifier(fd, depth, node);
782 if (ret)
783 return ret;
784 break;
785 case NODE_POINTER:
786 print_tabs(fd, depth);
787 if (node->u.pointer.const_qualifier)
788 fprintf(fd, "<const_pointer />\n");
789 else
790 fprintf(fd, "<pointer />\n");
791 break;
792 case NODE_TYPE_DECLARATOR:
793 ret = ctf_visitor_print_type_declarator(fd, depth, node);
794 if (ret)
795 return ret;
796 break;
797
798 case NODE_FLOATING_POINT:
799 print_tabs(fd, depth);
800 fprintf(fd, "<floating_point>\n");
801 cds_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
802 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
803 if (ret)
804 return ret;
805 }
806 print_tabs(fd, depth);
807 fprintf(fd, "</floating_point>\n");
808 break;
809 case NODE_INTEGER:
810 print_tabs(fd, depth);
811 fprintf(fd, "<integer>\n");
812 cds_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
813 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
814 if (ret)
815 return ret;
816 }
817 print_tabs(fd, depth);
818 fprintf(fd, "</integer>\n");
819 break;
820 case NODE_STRING:
821 print_tabs(fd, depth);
822 fprintf(fd, "<string>\n");
823 cds_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
824 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
825 if (ret)
826 return ret;
827 }
828 print_tabs(fd, depth);
829 fprintf(fd, "</string>\n");
830 break;
831 case NODE_ENUMERATOR:
832 print_tabs(fd, depth);
833 fprintf(fd, "<enumerator");
834 if (node->u.enumerator.id)
835 fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
836 fprintf(fd, ">\n");
837 cds_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
838 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
839 if (ret)
840 return ret;
841 }
842 print_tabs(fd, depth);
843 fprintf(fd, "</enumerator>\n");
844 break;
845 case NODE_ENUM:
846 print_tabs(fd, depth);
847 if (node->u._struct.name)
848 fprintf(fd, "<enum name=\"%s\">\n",
849 node->u._enum.enum_id);
850 else
851 fprintf(fd, "<enum >\n");
852 depth++;
853
854 if (node->u._enum.container_type) {
855 print_tabs(fd, depth);
856 fprintf(fd, "<container_type>\n");
857 ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
858 if (ret)
859 return ret;
860 print_tabs(fd, depth);
861 fprintf(fd, "</container_type>\n");
862 }
863
864 print_tabs(fd, depth);
865 fprintf(fd, "<enumerator_list>\n");
866 cds_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
867 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
868 if (ret)
869 return ret;
870 }
871 print_tabs(fd, depth);
872 fprintf(fd, "</enumerator_list>\n");
873
874 depth--;
875 print_tabs(fd, depth);
876 fprintf(fd, "</enum>\n");
877 break;
878 case NODE_STRUCT_OR_VARIANT_DECLARATION:
879 print_tabs(fd, depth);
880 fprintf(fd, "<declaration_specifier>\n");
881 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.declaration_specifier, siblings) {
882 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
883 if (ret)
884 return ret;
885 }
886 print_tabs(fd, depth);
887 fprintf(fd, "</declaration_specifier>\n");
888
889 print_tabs(fd, depth);
890 fprintf(fd, "<type_declarators>\n");
891 cds_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
892 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
893 if (ret)
894 return ret;
895 }
896 print_tabs(fd, depth);
897 fprintf(fd, "</type_declarators>\n");
898 break;
899 case NODE_VARIANT:
900 print_tabs(fd, depth);
901 fprintf(fd, "<variant");
902 if (node->u.variant.name)
903 fprintf(fd, " name=\"%s\"", node->u.variant.name);
904 if (node->u.variant.choice)
905 fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
906 fprintf(fd, ">\n");
907 cds_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
908 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
909 if (ret)
910 return ret;
911 }
912 print_tabs(fd, depth);
913 fprintf(fd, "</variant>\n");
914 break;
915 case NODE_STRUCT:
916 print_tabs(fd, depth);
917 if (node->u._struct.name)
918 fprintf(fd, "<struct name=\"%s\">\n",
919 node->u._struct.name);
920 else
921 fprintf(fd, "<struct>\n");
922 cds_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
923 ret = ctf_visitor_print_xml(fd, depth + 1, iter);
924 if (ret)
925 return ret;
926 }
927 print_tabs(fd, depth);
928 fprintf(fd, "</struct>\n");
929 break;
930
931 case NODE_UNKNOWN:
932 default:
933 fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
934 (int) node->type);
935 return -EINVAL;
936 }
937 return ret;
938 }
This page took 0.055138 seconds and 3 git commands to generate.