Generate IO struct visitor adapt to def/declaration
[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 206/*
d20f5e59 207 * Also add named variant, struct or enum to the current declaration scope.
de47353a 208 */
05628561 209static
d20f5e59
MD
210struct ctf_declaration *ctf_declaration_specifier_visit(FILE *fd,
211 int depth, struct list_head *head,
212 struct declaration_scope *declaration_scope)
05628561 213{
d20f5e59 214 struct ctf_declaration *declaration;
de47353a
MD
215 struct node *first;
216
217 first = _cds_list_first_entry(head, struct node, siblings);
218
219 switch (first->type) {
220 case NODE_STRUCT:
d20f5e59
MD
221 /*
222 * For named struct (without body), lookup in
223 * declaration scope and create declaration copy.
224 */
225 /* For named struct (with body), create type and add to declaration scope */
de47353a
MD
226 /* For unnamed struct, create type */
227 break;
228 case NODE_VARIANT:
d20f5e59
MD
229 /*
230 * For named variant (without body), lookup in
231 * declaration scope and create declaration copy.
232 */
233 /* For named variant (with body), create type and add to declaration scope */
de47353a 234 /* For unnamed variant, create type */
d20f5e59 235 /* If variant has a tag field specifier, assign tag name. */
de47353a
MD
236 break;
237 case NODE_ENUM:
d20f5e59
MD
238 /*
239 * For named enum (without body), lookup in declaration
240 * scope and create declaration copy.
241 */
242 /* For named enum (with body), create type and add to declaration scope */
de47353a 243 /* For unnamed enum, create type */
d20f5e59 244 /* Enumerations need to have their size/type specifier (< >). */
de47353a
MD
245 break;
246 case NODE_INTEGER:
d20f5e59
MD
247 /*
248 * Create an integer declaration.
249 */
de47353a
MD
250 break;
251 case NODE_FLOATING_POINT:
d20f5e59
MD
252 /*
253 * Create a floating point declaration.
254 */
255 break;
256 case NODE_STRING:
257 /*
258 * Create a string declaration.
259 */
de47353a
MD
260 break;
261 case NODE_TYPE_SPECIFIER:
d20f5e59
MD
262 /*
263 * Lookup named type in typedef declarations (in
264 * declaration scope). Create a copy of the declaration.
265 */
de47353a 266 break;
05628561 267
de47353a 268 }
05628561
MD
269}
270
05628561
MD
271static
272int ctf_typedef_declarator_visit(FILE *fd, int depth,
d20f5e59
MD
273 struct list_head *declaration_specifier,
274 struct node *type_declarator,
275 struct declaration_scope *declaration_scope)
05628561
MD
276{
277 /*
de47353a
MD
278 * Build the type using declaration specifier (creating
279 * declaration from type_specifier), then apply type declarator,
d20f5e59 280 * add the resulting type to the current declaration scope.
05628561
MD
281 */
282 cds_list_for_each_entry(iter, declaration_specifier, siblings) {
283
284
285 }
286 return 0;
287}
288
289static
290int ctf_typedef_visit(FILE *fd, int depth,
d20f5e59
MD
291 struct list_head *declaration_specifier,
292 struct list_head *type_declarators,
293 struct declaration_scope *declaration_scope)
05628561
MD
294{
295 struct ctf_node *iter;
296
297 cds_list_for_each_entry(iter, type_declarators, siblings) {
298 ret = ctf_typedef_declarator_visit(fd, depth + 1,
299 &node->u._typedef.declaration_specifier, iter,
d20f5e59 300 declaration_scope);
05628561
MD
301 if (ret)
302 return ret;
303 }
304 return 0;
305}
306
307static
308int ctf_typealias_visit(FILE *fd, int depth, struct ctf_node *target,
d20f5e59
MD
309 struct ctf_node *alias,
310 struct declaration_scope *declaration_scope)
05628561 311{
d20f5e59
MD
312 /*
313 * Build target type, check that it is reachable in current
314 * declaration scope.
315 */
316
05628561
MD
317 /* Only one type declarator is allowed */
318
d20f5e59 319 /* Build alias type, add to current declaration scope. */
05628561
MD
320 /* Only one type declarator is allowed */
321}
322
323static
324int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
325{
326 int ret = 0;
327
328 switch (node->type) {
329 case NODE_TYPEDEF:
330 ret = ctf_typedef_visit(fd, depth + 1,
331 &node->u._typedef.declaration_specifier,
332 &node->u._typedef.type_declarators,
d20f5e59 333 event->declaration_scope);
05628561
MD
334 if (ret)
335 return ret;
336 break;
337 case NODE_TYPEALIAS:
338 ret = ctf_typealias_visit(fd, depth + 1,
339 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 340 event->declaration_scope);
05628561
MD
341 if (ret)
342 return ret;
343 break;
344 case NODE_CTF_EXPRESSION:
345 {
346 char *left;
347
348 left = concatenate_unary_strings(&node->u.ctf_expression.left);
349 if (!strcmp(left, "name")) {
350 char *right;
351
352 if (CTF_EVENT_FIELD_IS_SET(event, name))
353 return -EPERM;
354 right = concatenate_unary_strings(&node->u.ctf_expression.right);
355 if (!right) {
356 fprintf(stderr, "[error] %s: unexpected unary expression for event name\n", __func__);
357 return -EINVAL;
358 }
359 event->name = g_quark_from_string(right);
360 free(right);
361 CTF_EVENT_SET_FIELD(event, name);
362 } else if (!strcmp(left, "id")) {
363 if (CTF_EVENT_FIELD_IS_SET(event, id))
364 return -EPERM;
365 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
366 if (ret) {
367 fprintf(stderr, "[error] %s: unexpected unary expression for event id\n", __func__);
368 return -EINVAL;
369 }
370 CTF_EVENT_SET_FIELD(event, id);
371 } else if (!strcmp(left, "stream_id")) {
372 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
373 return -EPERM;
374 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
375 if (ret) {
376 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
377 return -EINVAL;
378 }
379 event->stream = trace_stream_lookup(trace, event->stream_id);
380 if (!event->stream) {
381 fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
382 return -EINVAL;
383 }
e1151715
MD
384 event->definition_scope = new_definition_scope(stream->definition_scope);
385 if (!event->definition_scope) {
05628561
MD
386 fprintf(stderr, "[error] %s: Error allocating declaration scope\n", __func__);
387 return -EPERM;
388 }
389 CTF_EVENT_SET_FIELD(event, stream_id);
390 } else if (!strcmp(left, "context")) {
391 struct declaration *declaration;
392
e1151715 393 if (!event->definition_scope)
05628561
MD
394 return -EPERM;
395 declaration = ctf_declaration_specifier_visit(fd, depth,
396 &node->u.ctf_expression.right,
d20f5e59 397 event->declaration_scope);
05628561
MD
398 if (!declaration)
399 return -EPERM;
400 if (declaration->type->id != CTF_TYPE_STRUCT)
401 return -EPERM;
d20f5e59 402 /* TODO: definition */
05628561
MD
403 event->context = container_of(declaration, struct declaration_struct, p);
404 } else if (!strcmp(left, "fields")) {
405 struct declaration *declaration;
406
e1151715 407 if (!event->definition_scope)
05628561
MD
408 return -EPERM;
409 declaration = ctf_declaration_specifier_visit(fd, depth,
410 &node->u.ctf_expression.right,
d20f5e59 411 event->declaration_scope);
05628561
MD
412 if (!declaration)
413 return -EPERM;
414 if (declaration->type->id != CTF_TYPE_STRUCT)
415 return -EPERM;
d20f5e59 416 /* TODO: definition */
05628561
MD
417 event->fields = container_of(declaration, struct declaration_struct, p);
418 }
419 free(left);
420 break;
421 }
422 default:
423 return -EPERM;
424 /* TODO: declaration specifier should be added. */
425 }
426
427 return 0;
428}
429
430static
431int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 432 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
433{
434 int ret = 0;
435 struct ctf_node *iter;
436 struct ctf_event *event;
437
438 event = g_new0(struct ctf_event, 1);
d20f5e59 439 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
440 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
441 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
442 if (ret)
443 goto error;
444 }
445 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
446 ret = -EPERM;
447 goto error;
448 }
449 if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
450 ret = -EPERM;
451 goto error;
452 }
453 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
454 ret = -EPERM;
455 goto error;
456 }
457 if (event->stream->events_by_id->len <= event->id)
458 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
459 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
460 g_hash_table_insert(event->stream->event_quark_to_id,
461 (gpointer)(unsigned long) event->name,
462 &event->id);
463 return 0;
464
465error:
466 declaration_unref(event->fields);
467 declaration_unref(event->context);
e1151715 468 free_definition_scope(event->definition_scope);
d20f5e59 469 free_declaration_scope(event->declaration_scope);
05628561
MD
470 g_free(event);
471 return ret;
472}
473
474
475static
476int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
477{
478 int ret = 0;
479
480 switch (node->type) {
481 case NODE_TYPEDEF:
482 ret = ctf_typedef_visit(fd, depth + 1,
483 &node->u._typedef.declaration_specifier,
484 &node->u._typedef.type_declarators,
d20f5e59 485 stream->declaration_scope);
05628561
MD
486 if (ret)
487 return ret;
488 break;
489 case NODE_TYPEALIAS:
490 ret = ctf_typealias_visit(fd, depth + 1,
491 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 492 stream->declaration_scope);
05628561
MD
493 if (ret)
494 return ret;
495 break;
496 case NODE_CTF_EXPRESSION:
497 {
498 char *left;
499
500 left = concatenate_unary_strings(&node->u.ctf_expression.left);
501 if (!strcmp(left, "stream_id")) {
502 if (CTF_EVENT_FIELD_IS_SET(event, stream_id))
503 return -EPERM;
504 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
505 if (ret) {
506 fprintf(stderr, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
507 return -EINVAL;
508 }
509 CTF_EVENT_SET_FIELD(event, stream_id);
510 } else if (!strcmp(left, "event_header")) {
511 struct declaration *declaration;
512
513 declaration = ctf_declaration_specifier_visit(fd, depth,
514 &node->u.ctf_expression.right,
d20f5e59 515 stream->declaration_scope, stream->definition_scope);
05628561
MD
516 if (!declaration)
517 return -EPERM;
518 if (declaration->type->id != CTF_TYPE_STRUCT)
519 return -EPERM;
d20f5e59 520 /* TODO: definition */
05628561
MD
521 stream->event_header = container_of(declaration, struct declaration_struct, p);
522 } else if (!strcmp(left, "event_context")) {
523 struct declaration *declaration;
524
525 declaration = ctf_declaration_specifier_visit(fd, depth,
526 &node->u.ctf_expression.right,
d20f5e59 527 stream->declaration_scope);
05628561
MD
528 if (!declaration)
529 return -EPERM;
530 if (declaration->type->id != CTF_TYPE_STRUCT)
531 return -EPERM;
d20f5e59 532 /* TODO: definition */
05628561
MD
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,
d20f5e59 539 stream->declaration_scope);
05628561
MD
540 if (!declaration)
541 return -EPERM;
542 if (declaration->type->id != CTF_TYPE_STRUCT)
543 return -EPERM;
d20f5e59 544 /* TODO: definition */
05628561
MD
545 stream->packet_context = container_of(declaration, struct declaration_struct, p);
546 }
547 free(left);
548 break;
549 }
550 default:
551 return -EPERM;
552 /* TODO: declaration specifier should be added. */
553 }
554
555 return 0;
556}
557
558static
559int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 560 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
561{
562 int ret = 0;
563 struct ctf_node *iter;
564 struct ctf_stream *stream;
565
566 stream = g_new0(struct ctf_stream, 1);
d20f5e59 567 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
e1151715 568 stream->definition_scope = new_definition_scope(trace->definition_scope);
05628561
MD
569 stream->events_by_id = g_ptr_array_new();
570 stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
571 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
572 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
573 if (ret)
574 goto error;
575 }
576 if (!CTF_EVENT_FIELD_IS_SET(stream, stream_id)) {
577 ret = -EPERM;
578 goto error;
579 }
580 if (trace->streams->len <= stream->stream_id)
581 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
582 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
583 return 0;
584
585error:
586 declaration_unref(stream->event_header);
587 declaration_unref(stream->event_context);
588 declaration_unref(stream->packet_context);
589 g_ptr_array_free(stream->events_by_id, TRUE);
590 g_hash_table_free(stream->event_quark_to_id);
e1151715 591 free_definition_scope(stream->definition_scope);
d20f5e59 592 free_declaration_scope(stream->declaration_scope);
05628561
MD
593 g_free(stream);
594 return ret;
595}
596
597static
598int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
599{
600 int ret = 0;
601
602 switch (node->type) {
603 case NODE_TYPEDEF:
604 ret = ctf_typedef_visit(fd, depth + 1,
605 &node->u._typedef.declaration_specifier,
606 &node->u._typedef.type_declarators,
d20f5e59 607 trace->declaration_scope);
05628561
MD
608 if (ret)
609 return ret;
610 break;
611 case NODE_TYPEALIAS:
612 ret = ctf_typealias_visit(fd, depth + 1,
613 &node->u.typealias.target, &node->u.typealias.alias
d20f5e59 614 trace->declaration_scope);
05628561
MD
615 if (ret)
616 return ret;
617 break;
618 case NODE_CTF_EXPRESSION:
619 {
620 char *left;
621
622 left = concatenate_unary_strings(&node->u.ctf_expression.left);
623 if (!strcmp(left, "major")) {
624 if (CTF_EVENT_FIELD_IS_SET(trace, major))
625 return -EPERM;
626 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
627 if (ret) {
628 fprintf(stderr, "[error] %s: unexpected unary expression for trace major number\n", __func__);
629 return -EINVAL;
630 }
631 CTF_EVENT_SET_FIELD(trace, major);
632 } else if (!strcmp(left, "minor")) {
633 if (CTF_EVENT_FIELD_IS_SET(trace, minor))
634 return -EPERM;
635 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
636 if (ret) {
637 fprintf(stderr, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
638 return -EINVAL;
639 }
640 CTF_EVENT_SET_FIELD(trace, minor);
641 } else if (!strcmp(left, "word_size")) {
642 if (CTF_EVENT_FIELD_IS_SET(trace, word_size))
643 return -EPERM;
644 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
645 if (ret) {
646 fprintf(stderr, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
647 return -EINVAL;
648 }
649 CTF_EVENT_SET_FIELD(trace, word_size);
650 } else if (!strcmp(left, "uuid")) {
651 if (CTF_EVENT_FIELD_IS_SET(trace, uuid))
652 return -EPERM;
653 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
654 if (ret) {
655 fprintf(stderr, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
656 return -EINVAL;
657 }
658 CTF_EVENT_SET_FIELD(trace, uuid);
659 }
660 free(left);
661 break;
662 }
663 default:
664 return -EPERM;
665 /* TODO: declaration specifier should be added. */
666 }
667
668 return 0;
669}
670
671
672static
673int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
674{
675 int ret = 0;
676 struct ctf_node *iter;
677
d20f5e59 678 if (trace->declaration_scope)
05628561 679 return -EEXIST;
d20f5e59 680 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
e1151715 681 trace->definition_scope = new_definition_scope(trace->root_definition_scope);
05628561
MD
682 trace->streams = g_ptr_array_new();
683 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
684 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
685 if (ret)
686 goto error;
687 }
688 if (!CTF_EVENT_FIELD_IS_SET(trace, major)) {
689 ret = -EPERM;
690 goto error;
691 }
692 if (!CTF_EVENT_FIELD_IS_SET(trace, minor)) {
693 ret = -EPERM;
694 goto error;
695 }
696 if (!CTF_EVENT_FIELD_IS_SET(trace, uuid)) {
697 ret = -EPERM;
698 goto error;
699 }
700 if (!CTF_EVENT_FIELD_IS_SET(trace, word_size)) {
701 ret = -EPERM;
702 goto error;
703 }
704 return 0;
705
706error:
707 g_ptr_array_free(trace->streams, TRUE);
e1151715 708 free_definition_scope(stream->definition_scope);
d20f5e59 709 free_declaration_scope(stream->declaration_scope);
05628561
MD
710 return ret;
711}
712
713int _ctf_visitor(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
714{
715 int ret = 0;
716 struct ctf_node *iter;
717
718 switch (node->type) {
719 case NODE_ROOT:
720 cds_list_for_each_entry(iter, &node->u.root._typedef,
721 siblings) {
722 ret = ctf_typedef_visit(fd, depth + 1,
723 &iter->u._typedef.declaration_specifier,
724 &iter->u._typedef.type_declarators,
d20f5e59 725 trace->declaration_scope);
05628561
MD
726 if (ret)
727 return ret;
728 }
729 cds_list_for_each_entry(iter, &node->u.root.typealias,
730 siblings) {
731 ret = ctf_typealias_visit(fd, depth + 1,
732 &iter->u.typealias.target, &iter->u.typealias.alias
d20f5e59 733 trace->declaration_scope);
05628561
MD
734 if (ret)
735 return ret;
736 }
737 cds_list_for_each_entry(iter, &node->u.root.declaration_specifier, siblings) {
de47353a 738 ret = ctf_declaration_specifier_visit(fd, depth, iter,
d20f5e59 739 trace->root_declaration_scope);
05628561
MD
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,
d20f5e59 750 trace->declaration_scope, trace);
05628561
MD
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,
d20f5e59 756 trace->declaration_scope, trace);
05628561
MD
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.062616 seconds and 4 git commands to generate.