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