Add base integer attribute, and use it in ctf-text
[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 <endian.h>
27 #include <errno.h>
28 #include <babeltrace/babeltrace.h>
29 #include <babeltrace/list.h>
30 #include <babeltrace/types.h>
31 #include <babeltrace/ctf/metadata.h>
32 #include <uuid/uuid.h>
33 #include "ctf-scanner.h"
34 #include "ctf-parser.h"
35 #include "ctf-ast.h"
36
37 #define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
38
39 #define _cds_list_first_entry(ptr, type, member) \
40 cds_list_entry((ptr)->next, type, member)
41
42 static
43 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
44 int depth, struct ctf_node *type_specifier_list,
45 struct declaration_scope *declaration_scope,
46 struct ctf_trace *trace);
47
48 static
49 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
50 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
51
52 /*
53 * String returned must be freed by the caller using g_free.
54 */
55 static
56 char *concatenate_unary_strings(struct cds_list_head *head)
57 {
58 struct ctf_node *node;
59 GString *str;
60 int i = 0;
61
62 str = g_string_new("");
63 cds_list_for_each_entry(node, head, siblings) {
64 char *src_string;
65
66 assert(node->type == NODE_UNARY_EXPRESSION);
67 assert(node->u.unary_expression.type == UNARY_STRING);
68 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
69 ^ (i != 0));
70 switch (node->u.unary_expression.link) {
71 case UNARY_DOTLINK:
72 g_string_append(str, ".");
73 break;
74 case UNARY_ARROWLINK:
75 g_string_append(str, "->");
76 break;
77 case UNARY_DOTDOTDOT:
78 g_string_append(str, "...");
79 break;
80 default:
81 break;
82 }
83 src_string = node->u.unary_expression.u.string;
84 g_string_append(str, src_string);
85 i++;
86 }
87 return g_string_free(str, FALSE);
88 }
89
90 static
91 int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
92 {
93 struct ctf_node *node;
94 int i = 0;
95
96 cds_list_for_each_entry(node, head, siblings) {
97 assert(node->type == NODE_UNARY_EXPRESSION);
98 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
99 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
100 assert(i == 0);
101 *value = node->u.unary_expression.u.unsigned_constant;
102 i++;
103 }
104 return 0;
105 }
106
107 static
108 int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
109 {
110 struct ctf_node *node;
111 int i = 0;
112 int ret = -1;
113
114 cds_list_for_each_entry(node, head, siblings) {
115 const char *src_string;
116
117 assert(node->type == NODE_UNARY_EXPRESSION);
118 assert(node->u.unary_expression.type == UNARY_STRING);
119 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
120 assert(i == 0);
121 src_string = node->u.unary_expression.u.string;
122 ret = uuid_parse(node->u.unary_expression.u.string, *uuid);
123 }
124 return ret;
125 }
126
127 static
128 struct ctf_stream_class *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
129 {
130 if (trace->streams->len <= stream_id)
131 return NULL;
132 return g_ptr_array_index(trace->streams, stream_id);
133 }
134
135 static
136 int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
137 {
138 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
139
140 switch (type_specifier->u.type_specifier.type) {
141 case TYPESPEC_VOID:
142 g_string_append(str, "void");
143 break;
144 case TYPESPEC_CHAR:
145 g_string_append(str, "char");
146 break;
147 case TYPESPEC_SHORT:
148 g_string_append(str, "short");
149 break;
150 case TYPESPEC_INT:
151 g_string_append(str, "int");
152 break;
153 case TYPESPEC_LONG:
154 g_string_append(str, "long");
155 break;
156 case TYPESPEC_FLOAT:
157 g_string_append(str, "float");
158 break;
159 case TYPESPEC_DOUBLE:
160 g_string_append(str, "double");
161 break;
162 case TYPESPEC_SIGNED:
163 g_string_append(str, "signed");
164 break;
165 case TYPESPEC_UNSIGNED:
166 g_string_append(str, "unsigned");
167 break;
168 case TYPESPEC_BOOL:
169 g_string_append(str, "bool");
170 break;
171 case TYPESPEC_COMPLEX:
172 g_string_append(str, "_Complex");
173 break;
174 case TYPESPEC_IMAGINARY:
175 g_string_append(str, "_Imaginary");
176 break;
177 case TYPESPEC_CONST:
178 g_string_append(str, "const");
179 break;
180 case TYPESPEC_ID_TYPE:
181 if (type_specifier->u.type_specifier.id_type)
182 g_string_append(str, type_specifier->u.type_specifier.id_type);
183 break;
184 case TYPESPEC_STRUCT:
185 {
186 struct ctf_node *node = type_specifier->u.type_specifier.node;
187
188 if (!node->u._struct.name) {
189 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
190 return -EINVAL;
191 }
192 g_string_append(str, "struct ");
193 g_string_append(str, node->u._struct.name);
194 break;
195 }
196 case TYPESPEC_VARIANT:
197 {
198 struct ctf_node *node = type_specifier->u.type_specifier.node;
199
200 if (!node->u.variant.name) {
201 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
202 return -EINVAL;
203 }
204 g_string_append(str, "variant ");
205 g_string_append(str, node->u.variant.name);
206 break;
207 }
208 case TYPESPEC_ENUM:
209 {
210 struct ctf_node *node = type_specifier->u.type_specifier.node;
211
212 if (!node->u._enum.enum_id) {
213 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
214 return -EINVAL;
215 }
216 g_string_append(str, "enum ");
217 g_string_append(str, node->u._enum.enum_id);
218 break;
219 }
220 case TYPESPEC_FLOATING_POINT:
221 case TYPESPEC_INTEGER:
222 case TYPESPEC_STRING:
223 default:
224 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
225 return -EINVAL;
226 }
227 return 0;
228 }
229
230 static
231 int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
232 {
233 struct ctf_node *iter;
234 int alias_item_nr = 0;
235 int ret;
236
237 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
238 if (alias_item_nr != 0)
239 g_string_append(str, " ");
240 alias_item_nr++;
241 ret = visit_type_specifier(fd, iter, str);
242 if (ret)
243 return ret;
244 }
245 return 0;
246 }
247
248 static
249 GQuark create_typealias_identifier(FILE *fd, int depth,
250 struct ctf_node *type_specifier_list,
251 struct ctf_node *node_type_declarator)
252 {
253 struct ctf_node *iter;
254 GString *str;
255 char *str_c;
256 GQuark alias_q;
257 int ret;
258
259 str = g_string_new("");
260 ret = visit_type_specifier_list(fd, type_specifier_list, str);
261 if (ret) {
262 g_string_free(str, TRUE);
263 return 0;
264 }
265 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
266 g_string_append(str, " *");
267 if (iter->u.pointer.const_qualifier)
268 g_string_append(str, " const");
269 }
270 str_c = g_string_free(str, FALSE);
271 alias_q = g_quark_from_string(str_c);
272 g_free(str_c);
273 return alias_q;
274 }
275
276 static
277 struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
278 struct ctf_node *type_specifier_list,
279 GQuark *field_name,
280 struct ctf_node *node_type_declarator,
281 struct declaration_scope *declaration_scope,
282 struct declaration *nested_declaration,
283 struct ctf_trace *trace)
284 {
285 /*
286 * Visit type declarator by first taking care of sequence/array
287 * (recursively). Then, when we get to the identifier, take care
288 * of pointers.
289 */
290
291 if (node_type_declarator) {
292 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
293
294 /* TODO: gcc bitfields not supported yet. */
295 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
296 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
297 return NULL;
298 }
299 }
300
301 if (!nested_declaration) {
302 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
303 GQuark alias_q;
304
305 /*
306 * If we have a pointer declarator, it _has_ to be present in
307 * the typealiases (else fail).
308 */
309 alias_q = create_typealias_identifier(fd, depth,
310 type_specifier_list, node_type_declarator);
311 nested_declaration = lookup_declaration(alias_q, declaration_scope);
312 if (!nested_declaration) {
313 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
314 return NULL;
315 }
316 } else {
317 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
318 type_specifier_list, declaration_scope, trace);
319 }
320 }
321
322 if (!node_type_declarator)
323 return nested_declaration;
324
325 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
326 if (node_type_declarator->u.type_declarator.u.id)
327 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
328 else
329 *field_name = 0;
330 return nested_declaration;
331 } else {
332 struct declaration *declaration;
333 struct ctf_node *length;
334
335 /* TYPEDEC_NESTED */
336
337 /* create array/sequence, pass nested_declaration as child. */
338 length = node_type_declarator->u.type_declarator.u.nested.length;
339 if (!length) {
340 fprintf(fd, "[error] %s: expecting length type or value.\n", __func__);
341 return NULL;
342 }
343 switch (length->type) {
344 case NODE_UNARY_EXPRESSION:
345 {
346 struct declaration_array *array_declaration;
347 size_t len;
348
349 if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
350 fprintf(fd, "[error] %s: array: unexpected unary expression.\n", __func__);
351 return NULL;
352 }
353 len = length->u.unary_expression.u.unsigned_constant;
354 array_declaration = array_declaration_new(len, nested_declaration,
355 declaration_scope);
356 declaration = &array_declaration->p;
357 break;
358 }
359 case NODE_TYPE_SPECIFIER_LIST:
360 {
361 struct declaration_sequence *sequence_declaration;
362 struct declaration_integer *integer_declaration;
363
364 declaration = ctf_type_specifier_list_visit(fd, depth,
365 length, declaration_scope, trace);
366 if (!declaration) {
367 fprintf(fd, "[error] %s: unable to find declaration type for sequence length\n", __func__);
368 return NULL;
369 }
370 if (declaration->id != CTF_TYPE_INTEGER) {
371 fprintf(fd, "[error] %s: length type for sequence is expected to be an integer (unsigned).\n", __func__);
372 declaration_unref(declaration);
373 return NULL;
374 }
375 integer_declaration = container_of(declaration, struct declaration_integer, p);
376 if (integer_declaration->signedness != false) {
377 fprintf(fd, "[error] %s: length type for sequence should always be an unsigned integer.\n", __func__);
378 declaration_unref(declaration);
379 return NULL;
380 }
381
382 sequence_declaration = sequence_declaration_new(integer_declaration,
383 nested_declaration, declaration_scope);
384 declaration = &sequence_declaration->p;
385 break;
386 }
387 default:
388 assert(0);
389 }
390
391 /* Pass it as content of outer container */
392 declaration = ctf_type_declarator_visit(fd, depth,
393 type_specifier_list, field_name,
394 node_type_declarator->u.type_declarator.u.nested.type_declarator,
395 declaration_scope, declaration, trace);
396 return declaration;
397 }
398 }
399
400 static
401 int ctf_struct_type_declarators_visit(FILE *fd, int depth,
402 struct declaration_struct *struct_declaration,
403 struct ctf_node *type_specifier_list,
404 struct cds_list_head *type_declarators,
405 struct declaration_scope *declaration_scope,
406 struct ctf_trace *trace)
407 {
408 struct ctf_node *iter;
409 GQuark field_name;
410
411 cds_list_for_each_entry(iter, type_declarators, siblings) {
412 struct declaration *field_declaration;
413
414 field_declaration = ctf_type_declarator_visit(fd, depth,
415 type_specifier_list,
416 &field_name, iter,
417 struct_declaration->scope,
418 NULL, trace);
419 if (!field_declaration) {
420 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
421 return -EINVAL;
422 }
423 struct_declaration_add_field(struct_declaration,
424 g_quark_to_string(field_name),
425 field_declaration);
426 }
427 return 0;
428 }
429
430 static
431 int ctf_variant_type_declarators_visit(FILE *fd, int depth,
432 struct declaration_untagged_variant *untagged_variant_declaration,
433 struct ctf_node *type_specifier_list,
434 struct cds_list_head *type_declarators,
435 struct declaration_scope *declaration_scope,
436 struct ctf_trace *trace)
437 {
438 struct ctf_node *iter;
439 GQuark field_name;
440
441 cds_list_for_each_entry(iter, type_declarators, siblings) {
442 struct declaration *field_declaration;
443
444 field_declaration = ctf_type_declarator_visit(fd, depth,
445 type_specifier_list,
446 &field_name, iter,
447 untagged_variant_declaration->scope,
448 NULL, trace);
449 if (!field_declaration) {
450 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
451 return -EINVAL;
452 }
453 untagged_variant_declaration_add_field(untagged_variant_declaration,
454 g_quark_to_string(field_name),
455 field_declaration);
456 }
457 return 0;
458 }
459
460 static
461 int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
462 struct ctf_node *type_specifier_list,
463 struct cds_list_head *type_declarators,
464 struct ctf_trace *trace)
465 {
466 struct ctf_node *iter;
467 GQuark identifier;
468
469 cds_list_for_each_entry(iter, type_declarators, siblings) {
470 struct declaration *type_declaration;
471 int ret;
472
473 type_declaration = ctf_type_declarator_visit(fd, depth,
474 type_specifier_list,
475 &identifier, iter,
476 scope, NULL, trace);
477 if (!type_declaration) {
478 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
479 return -EINVAL;
480 }
481 /*
482 * Don't allow typedef and typealias of untagged
483 * variants.
484 */
485 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
486 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
487 declaration_unref(type_declaration);
488 return -EPERM;
489 }
490 ret = register_declaration(identifier, type_declaration, scope);
491 if (ret) {
492 type_declaration->declaration_free(type_declaration);
493 return ret;
494 }
495 }
496 return 0;
497 }
498
499 static
500 int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
501 struct ctf_node *target, struct ctf_node *alias,
502 struct ctf_trace *trace)
503 {
504 struct declaration *type_declaration;
505 struct ctf_node *node;
506 GQuark dummy_id;
507 GQuark alias_q;
508 int err;
509
510 /* See ctf_visitor_type_declarator() in the semantic validator. */
511
512 /*
513 * Create target type declaration.
514 */
515
516 if (cds_list_empty(&target->u.typealias_target.type_declarators))
517 node = NULL;
518 else
519 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
520 struct ctf_node, siblings);
521 type_declaration = ctf_type_declarator_visit(fd, depth,
522 target->u.typealias_target.type_specifier_list,
523 &dummy_id, node,
524 scope, NULL, trace);
525 if (!type_declaration) {
526 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
527 err = -EINVAL;
528 goto error;
529 }
530 /*
531 * Don't allow typedef and typealias of untagged
532 * variants.
533 */
534 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
535 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
536 declaration_unref(type_declaration);
537 return -EPERM;
538 }
539 /*
540 * The semantic validator does not check whether the target is
541 * abstract or not (if it has an identifier). Check it here.
542 */
543 if (dummy_id != 0) {
544 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
545 err = -EINVAL;
546 goto error;
547 }
548 /*
549 * Create alias identifier.
550 */
551
552 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
553 struct ctf_node, siblings);
554 alias_q = create_typealias_identifier(fd, depth,
555 alias->u.typealias_alias.type_specifier_list, node);
556 err = register_declaration(alias_q, type_declaration, scope);
557 if (err)
558 goto error;
559 return 0;
560
561 error:
562 type_declaration->declaration_free(type_declaration);
563 return err;
564 }
565
566 static
567 int ctf_struct_declaration_list_visit(FILE *fd, int depth,
568 struct ctf_node *iter, struct declaration_struct *struct_declaration,
569 struct ctf_trace *trace)
570 {
571 int ret;
572
573 switch (iter->type) {
574 case NODE_TYPEDEF:
575 /* For each declarator, declare type and add type to struct declaration scope */
576 ret = ctf_typedef_visit(fd, depth,
577 struct_declaration->scope,
578 iter->u._typedef.type_specifier_list,
579 &iter->u._typedef.type_declarators, trace);
580 if (ret)
581 return ret;
582 break;
583 case NODE_TYPEALIAS:
584 /* Declare type with declarator and add type to struct declaration scope */
585 ret = ctf_typealias_visit(fd, depth,
586 struct_declaration->scope,
587 iter->u.typealias.target,
588 iter->u.typealias.alias, trace);
589 if (ret)
590 return ret;
591 break;
592 case NODE_STRUCT_OR_VARIANT_DECLARATION:
593 /* Add field to structure declaration */
594 ret = ctf_struct_type_declarators_visit(fd, depth,
595 struct_declaration,
596 iter->u.struct_or_variant_declaration.type_specifier_list,
597 &iter->u.struct_or_variant_declaration.type_declarators,
598 struct_declaration->scope, trace);
599 if (ret)
600 return ret;
601 break;
602 default:
603 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
604 assert(0);
605 }
606 return 0;
607 }
608
609 static
610 int ctf_variant_declaration_list_visit(FILE *fd, int depth,
611 struct ctf_node *iter,
612 struct declaration_untagged_variant *untagged_variant_declaration,
613 struct ctf_trace *trace)
614 {
615 int ret;
616
617 switch (iter->type) {
618 case NODE_TYPEDEF:
619 /* For each declarator, declare type and add type to variant declaration scope */
620 ret = ctf_typedef_visit(fd, depth,
621 untagged_variant_declaration->scope,
622 iter->u._typedef.type_specifier_list,
623 &iter->u._typedef.type_declarators, trace);
624 if (ret)
625 return ret;
626 break;
627 case NODE_TYPEALIAS:
628 /* Declare type with declarator and add type to variant declaration scope */
629 ret = ctf_typealias_visit(fd, depth,
630 untagged_variant_declaration->scope,
631 iter->u.typealias.target,
632 iter->u.typealias.alias, trace);
633 if (ret)
634 return ret;
635 break;
636 case NODE_STRUCT_OR_VARIANT_DECLARATION:
637 /* Add field to structure declaration */
638 ret = ctf_variant_type_declarators_visit(fd, depth,
639 untagged_variant_declaration,
640 iter->u.struct_or_variant_declaration.type_specifier_list,
641 &iter->u.struct_or_variant_declaration.type_declarators,
642 untagged_variant_declaration->scope, trace);
643 if (ret)
644 return ret;
645 break;
646 default:
647 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
648 assert(0);
649 }
650 return 0;
651 }
652
653 static
654 struct declaration *ctf_declaration_struct_visit(FILE *fd,
655 int depth, const char *name, struct cds_list_head *declaration_list,
656 int has_body, struct cds_list_head *min_align,
657 struct declaration_scope *declaration_scope,
658 struct ctf_trace *trace)
659 {
660 struct declaration_struct *struct_declaration;
661 struct ctf_node *iter;
662 int ret;
663
664 /*
665 * For named struct (without body), lookup in
666 * declaration scope. Don't take reference on struct
667 * declaration: ref is only taken upon definition.
668 */
669 if (!has_body) {
670 assert(name);
671 struct_declaration =
672 lookup_struct_declaration(g_quark_from_string(name),
673 declaration_scope);
674 return &struct_declaration->p;
675 } else {
676 uint64_t min_align_value = 0;
677
678 /* For unnamed struct, create type */
679 /* For named struct (with body), create type and add to declaration scope */
680 if (name) {
681 if (lookup_struct_declaration(g_quark_from_string(name),
682 declaration_scope)) {
683
684 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
685 return NULL;
686 }
687 }
688 if (!cds_list_empty(min_align)) {
689 ret = get_unary_unsigned(min_align, &min_align_value);
690 if (ret) {
691 fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
692 ret = -EINVAL;
693 goto error;
694 }
695 }
696 struct_declaration = struct_declaration_new(declaration_scope,
697 min_align_value);
698 cds_list_for_each_entry(iter, declaration_list, siblings) {
699 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
700 struct_declaration, trace);
701 if (ret)
702 goto error;
703 }
704 if (name) {
705 ret = register_struct_declaration(g_quark_from_string(name),
706 struct_declaration,
707 declaration_scope);
708 assert(!ret);
709 }
710 return &struct_declaration->p;
711 }
712 error:
713 struct_declaration->p.declaration_free(&struct_declaration->p);
714 return NULL;
715 }
716
717 static
718 struct declaration *ctf_declaration_variant_visit(FILE *fd,
719 int depth, const char *name, const char *choice,
720 struct cds_list_head *declaration_list,
721 int has_body, struct declaration_scope *declaration_scope,
722 struct ctf_trace *trace)
723 {
724 struct declaration_untagged_variant *untagged_variant_declaration;
725 struct declaration_variant *variant_declaration;
726 struct ctf_node *iter;
727 int ret;
728
729 /*
730 * For named variant (without body), lookup in
731 * declaration scope. Don't take reference on variant
732 * declaration: ref is only taken upon definition.
733 */
734 if (!has_body) {
735 assert(name);
736 untagged_variant_declaration =
737 lookup_variant_declaration(g_quark_from_string(name),
738 declaration_scope);
739 } else {
740 /* For unnamed variant, create type */
741 /* For named variant (with body), create type and add to declaration scope */
742 if (name) {
743 if (lookup_variant_declaration(g_quark_from_string(name),
744 declaration_scope)) {
745
746 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
747 return NULL;
748 }
749 }
750 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
751 cds_list_for_each_entry(iter, declaration_list, siblings) {
752 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
753 untagged_variant_declaration, trace);
754 if (ret)
755 goto error;
756 }
757 if (name) {
758 ret = register_variant_declaration(g_quark_from_string(name),
759 untagged_variant_declaration,
760 declaration_scope);
761 assert(!ret);
762 }
763 }
764 /*
765 * if tagged, create tagged variant and return. else return
766 * untagged variant.
767 */
768 if (!choice) {
769 return &untagged_variant_declaration->p;
770 } else {
771 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
772 if (!variant_declaration)
773 goto error;
774 declaration_unref(&untagged_variant_declaration->p);
775 return &variant_declaration->p;
776 }
777 error:
778 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
779 return NULL;
780 }
781
782 static
783 int ctf_enumerator_list_visit(FILE *fd, int depth,
784 struct ctf_node *enumerator,
785 struct declaration_enum *enum_declaration)
786 {
787 GQuark q;
788 struct ctf_node *iter;
789
790 q = g_quark_from_string(enumerator->u.enumerator.id);
791 if (enum_declaration->integer_declaration->signedness) {
792 int64_t start, end;
793 int nr_vals = 0;
794
795 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
796 int64_t *target;
797
798 assert(iter->type == NODE_UNARY_EXPRESSION);
799 if (nr_vals == 0)
800 target = &start;
801 else
802 target = &end;
803
804 switch (iter->u.unary_expression.type) {
805 case UNARY_SIGNED_CONSTANT:
806 *target = iter->u.unary_expression.u.signed_constant;
807 break;
808 case UNARY_UNSIGNED_CONSTANT:
809 *target = iter->u.unary_expression.u.unsigned_constant;
810 break;
811 default:
812 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
813 return -EINVAL;
814 }
815 if (nr_vals > 1) {
816 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
817 return -EINVAL;
818 }
819 nr_vals++;
820 }
821 if (nr_vals == 1)
822 end = start;
823 enum_signed_insert(enum_declaration, start, end, q);
824 } else {
825 uint64_t start, end;
826 int nr_vals = 0;
827
828 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
829 uint64_t *target;
830
831 assert(iter->type == NODE_UNARY_EXPRESSION);
832 if (nr_vals == 0)
833 target = &start;
834 else
835 target = &end;
836
837 switch (iter->u.unary_expression.type) {
838 case UNARY_UNSIGNED_CONSTANT:
839 *target = iter->u.unary_expression.u.unsigned_constant;
840 break;
841 case UNARY_SIGNED_CONSTANT:
842 /*
843 * We don't accept signed constants for enums with unsigned
844 * container type.
845 */
846 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
847 return -EINVAL;
848 default:
849 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
850 return -EINVAL;
851 }
852 if (nr_vals > 1) {
853 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
854 return -EINVAL;
855 }
856 nr_vals++;
857 }
858 if (nr_vals == 1)
859 end = start;
860 enum_unsigned_insert(enum_declaration, start, end, q);
861 }
862 return 0;
863 }
864
865 static
866 struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
867 const char *name,
868 struct ctf_node *container_type,
869 struct cds_list_head *enumerator_list,
870 int has_body,
871 struct declaration_scope *declaration_scope,
872 struct ctf_trace *trace)
873 {
874 struct declaration *declaration;
875 struct declaration_enum *enum_declaration;
876 struct declaration_integer *integer_declaration;
877 struct ctf_node *iter;
878 GQuark dummy_id;
879 int ret;
880
881 /*
882 * For named enum (without body), lookup in
883 * declaration scope. Don't take reference on enum
884 * declaration: ref is only taken upon definition.
885 */
886 if (!has_body) {
887 assert(name);
888 enum_declaration =
889 lookup_enum_declaration(g_quark_from_string(name),
890 declaration_scope);
891 return &enum_declaration->p;
892 } else {
893 /* For unnamed enum, create type */
894 /* For named enum (with body), create type and add to declaration scope */
895 if (name) {
896 if (lookup_enum_declaration(g_quark_from_string(name),
897 declaration_scope)) {
898
899 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
900 return NULL;
901 }
902 }
903 if (!container_type) {
904 declaration = lookup_declaration(g_quark_from_static_string("int"),
905 declaration_scope);
906 if (!declaration) {
907 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
908 return NULL;
909 }
910 } else {
911 declaration = ctf_type_declarator_visit(fd, depth,
912 container_type,
913 &dummy_id, NULL,
914 declaration_scope,
915 NULL, trace);
916 }
917 if (!declaration) {
918 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
919 return NULL;
920 }
921 if (declaration->id != CTF_TYPE_INTEGER) {
922 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
923 return NULL;
924 }
925 integer_declaration = container_of(declaration, struct declaration_integer, p);
926 enum_declaration = enum_declaration_new(integer_declaration);
927 declaration_unref(&integer_declaration->p); /* leave ref to enum */
928 cds_list_for_each_entry(iter, enumerator_list, siblings) {
929 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
930 if (ret)
931 goto error;
932 }
933 if (name) {
934 ret = register_enum_declaration(g_quark_from_string(name),
935 enum_declaration,
936 declaration_scope);
937 assert(!ret);
938 }
939 return &enum_declaration->p;
940 }
941 error:
942 enum_declaration->p.declaration_free(&enum_declaration->p);
943 return NULL;
944 }
945
946 static
947 struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
948 struct ctf_node *type_specifier_list,
949 struct declaration_scope *declaration_scope)
950 {
951 GString *str;
952 struct declaration *declaration;
953 char *str_c;
954 int ret;
955 GQuark id_q;
956
957 str = g_string_new("");
958 ret = visit_type_specifier_list(fd, type_specifier_list, str);
959 if (ret)
960 return NULL;
961 str_c = g_string_free(str, FALSE);
962 id_q = g_quark_from_string(str_c);
963 g_free(str_c);
964 declaration = lookup_declaration(id_q, declaration_scope);
965 return declaration;
966 }
967
968 /*
969 * Returns 0/1 boolean, or < 0 on error.
970 */
971 static
972 int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
973 {
974 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
975 fprintf(fd, "[error] %s: expecting unary expression\n",
976 __func__);
977 return -EINVAL;
978 }
979 switch (unary_expression->u.unary_expression.type) {
980 case UNARY_UNSIGNED_CONSTANT:
981 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
982 return 0;
983 else
984 return 1;
985 case UNARY_SIGNED_CONSTANT:
986 if (unary_expression->u.unary_expression.u.signed_constant == 0)
987 return 0;
988 else
989 return 1;
990 case UNARY_STRING:
991 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
992 return 1;
993 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
994 return 1;
995 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
996 return 0;
997 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
998 return 0;
999 else {
1000 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
1001 __func__, unary_expression->u.unary_expression.u.string);
1002 return -EINVAL;
1003 }
1004 break;
1005 default:
1006 fprintf(fd, "[error] %s: unexpected unary expression type\n",
1007 __func__);
1008 return -EINVAL;
1009 }
1010
1011 }
1012
1013 static
1014 int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1015 {
1016 int byte_order;
1017
1018 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1019 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1020 __func__);
1021 return -EINVAL;
1022 }
1023 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1024 byte_order = BIG_ENDIAN;
1025 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1026 byte_order = LITTLE_ENDIAN;
1027 else {
1028 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1029 __func__, unary_expression->u.unary_expression.u.string);
1030 return -EINVAL;
1031 }
1032 return byte_order;
1033 }
1034
1035 static
1036 int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1037 struct ctf_trace *trace)
1038 {
1039 int byte_order;
1040
1041 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1042 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1043 __func__);
1044 return -EINVAL;
1045 }
1046 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1047 byte_order = trace->byte_order;
1048 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1049 byte_order = BIG_ENDIAN;
1050 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1051 byte_order = BIG_ENDIAN;
1052 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1053 byte_order = LITTLE_ENDIAN;
1054 else {
1055 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1056 __func__, unary_expression->u.unary_expression.u.string);
1057 return -EINVAL;
1058 }
1059 return byte_order;
1060 }
1061
1062 static
1063 struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
1064 struct cds_list_head *expressions,
1065 struct ctf_trace *trace)
1066 {
1067 struct ctf_node *expression;
1068 uint64_t alignment, size;
1069 int byte_order = trace->byte_order;
1070 int signedness = 0;
1071 int has_alignment = 0, has_size = 0;
1072 int base = 10;
1073 struct declaration_integer *integer_declaration;
1074
1075 cds_list_for_each_entry(expression, expressions, siblings) {
1076 struct ctf_node *left, *right;
1077
1078 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1079 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1080 assert(left->u.unary_expression.type == UNARY_STRING);
1081 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
1082 signedness = get_boolean(fd, depth, right);
1083 if (signedness < 0)
1084 return NULL;
1085 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1086 byte_order = get_byte_order(fd, depth, right, trace);
1087 if (byte_order < 0)
1088 return NULL;
1089 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
1090 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1091 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
1092 __func__);
1093 return NULL;
1094 }
1095 size = right->u.unary_expression.u.unsigned_constant;
1096 has_size = 1;
1097 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1098 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1099 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1100 __func__);
1101 return NULL;
1102 }
1103 alignment = right->u.unary_expression.u.unsigned_constant;
1104 /* Make sure alignment is a power of two */
1105 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1106 fprintf(fd, "[error] %s: align: expecting power of two\n",
1107 __func__);
1108 return NULL;
1109 }
1110 has_alignment = 1;
1111 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1112 switch (right->u.unary_expression.type) {
1113 case UNARY_UNSIGNED_CONSTANT:
1114 switch (right->u.unary_expression.u.unsigned_constant) {
1115 case 2:
1116 case 8:
1117 case 10:
1118 case 16:
1119 base = right->u.unary_expression.u.unsigned_constant;
1120 break;
1121 default:
1122 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1123 __func__, right->u.unary_expression.u.unsigned_constant);
1124 return NULL;
1125 }
1126 break;
1127 case UNARY_STRING:
1128 {
1129 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1130 if (!s_right) {
1131 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1132 g_free(s_right);
1133 return NULL;
1134 }
1135 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1136 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1137 base = 10;
1138 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1139 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1140 || !strcmp(s_right, "p")) {
1141 base = 16;
1142 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1143 || !strcmp(s_right, "o")) {
1144 base = 8;
1145 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1146 base = 2;
1147 } else {
1148 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1149 g_free(s_right);
1150 return NULL;
1151 }
1152
1153 g_free(s_right);
1154 break;
1155 }
1156 default:
1157 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1158 __func__);
1159 return NULL;
1160 }
1161 } else {
1162 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1163 __func__, left->u.unary_expression.u.string);
1164 return NULL;
1165 }
1166 }
1167 if (!has_size) {
1168 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1169 return NULL;
1170 }
1171 if (!has_alignment) {
1172 if (size % CHAR_BIT) {
1173 /* bit-packed alignment */
1174 alignment = 1;
1175 } else {
1176 /* byte-packed alignment */
1177 alignment = CHAR_BIT;
1178 }
1179 }
1180 integer_declaration = integer_declaration_new(size,
1181 byte_order, signedness, alignment, base);
1182 return &integer_declaration->p;
1183 }
1184
1185 static
1186 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1187 struct cds_list_head *expressions,
1188 struct ctf_trace *trace)
1189 {
1190 struct ctf_node *expression;
1191 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
1192 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1193 struct declaration_float *float_declaration;
1194
1195 cds_list_for_each_entry(expression, expressions, siblings) {
1196 struct ctf_node *left, *right;
1197
1198 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1199 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1200 assert(left->u.unary_expression.type == UNARY_STRING);
1201 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1202 byte_order = get_byte_order(fd, depth, right, trace);
1203 if (byte_order < 0)
1204 return NULL;
1205 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1206 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1207 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1208 __func__);
1209 return NULL;
1210 }
1211 exp_dig = right->u.unary_expression.u.unsigned_constant;
1212 has_exp_dig = 1;
1213 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1214 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1215 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1216 __func__);
1217 return NULL;
1218 }
1219 mant_dig = right->u.unary_expression.u.unsigned_constant;
1220 has_mant_dig = 1;
1221 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1222 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1223 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1224 __func__);
1225 return NULL;
1226 }
1227 alignment = right->u.unary_expression.u.unsigned_constant;
1228 /* Make sure alignment is a power of two */
1229 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1230 fprintf(fd, "[error] %s: align: expecting power of two\n",
1231 __func__);
1232 return NULL;
1233 }
1234 has_alignment = 1;
1235 } else {
1236 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1237 __func__, left->u.unary_expression.u.string);
1238 return NULL;
1239 }
1240 }
1241 if (!has_mant_dig) {
1242 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1243 return NULL;
1244 }
1245 if (!has_exp_dig) {
1246 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1247 return NULL;
1248 }
1249 if (!has_alignment) {
1250 if ((mant_dig + exp_dig) % CHAR_BIT) {
1251 /* bit-packed alignment */
1252 alignment = 1;
1253 } else {
1254 /* byte-packed alignment */
1255 alignment = CHAR_BIT;
1256 }
1257 }
1258 float_declaration = float_declaration_new(mant_dig, exp_dig,
1259 byte_order, alignment);
1260 return &float_declaration->p;
1261 }
1262
1263 static
1264 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1265 struct cds_list_head *expressions,
1266 struct ctf_trace *trace)
1267 {
1268 struct ctf_node *expression;
1269 const char *encoding_c = NULL;
1270 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1271 struct declaration_string *string_declaration;
1272
1273 cds_list_for_each_entry(expression, expressions, siblings) {
1274 struct ctf_node *left, *right;
1275
1276 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1277 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1278 assert(left->u.unary_expression.type == UNARY_STRING);
1279 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1280 if (right->u.unary_expression.type != UNARY_STRING) {
1281 fprintf(fd, "[error] %s: encoding: expecting string\n",
1282 __func__);
1283 return NULL;
1284 }
1285 encoding_c = right->u.unary_expression.u.string;
1286 } else {
1287 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1288 __func__, left->u.unary_expression.u.string);
1289 return NULL;
1290 }
1291 }
1292 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1293 encoding = CTF_STRING_ASCII;
1294 string_declaration = string_declaration_new(encoding);
1295 return &string_declaration->p;
1296 }
1297
1298
1299 static
1300 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1301 int depth, struct ctf_node *type_specifier_list,
1302 struct declaration_scope *declaration_scope,
1303 struct ctf_trace *trace)
1304 {
1305 struct ctf_node *first;
1306 struct ctf_node *node;
1307
1308 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1309
1310 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1311
1312 assert(first->type == NODE_TYPE_SPECIFIER);
1313
1314 node = first->u.type_specifier.node;
1315
1316 switch (first->u.type_specifier.type) {
1317 case TYPESPEC_FLOATING_POINT:
1318 return ctf_declaration_floating_point_visit(fd, depth,
1319 &node->u.floating_point.expressions, trace);
1320 case TYPESPEC_INTEGER:
1321 return ctf_declaration_integer_visit(fd, depth,
1322 &node->u.integer.expressions, trace);
1323 case TYPESPEC_STRING:
1324 return ctf_declaration_string_visit(fd, depth,
1325 &node->u.string.expressions, trace);
1326 case TYPESPEC_STRUCT:
1327 return ctf_declaration_struct_visit(fd, depth,
1328 node->u._struct.name,
1329 &node->u._struct.declaration_list,
1330 node->u._struct.has_body,
1331 &node->u._struct.min_align,
1332 declaration_scope,
1333 trace);
1334 case TYPESPEC_VARIANT:
1335 return ctf_declaration_variant_visit(fd, depth,
1336 node->u.variant.name,
1337 node->u.variant.choice,
1338 &node->u.variant.declaration_list,
1339 node->u.variant.has_body,
1340 declaration_scope,
1341 trace);
1342 case TYPESPEC_ENUM:
1343 return ctf_declaration_enum_visit(fd, depth,
1344 node->u._enum.enum_id,
1345 node->u._enum.container_type,
1346 &node->u._enum.enumerator_list,
1347 node->u._enum.has_body,
1348 declaration_scope,
1349 trace);
1350
1351 case TYPESPEC_VOID:
1352 case TYPESPEC_CHAR:
1353 case TYPESPEC_SHORT:
1354 case TYPESPEC_INT:
1355 case TYPESPEC_LONG:
1356 case TYPESPEC_FLOAT:
1357 case TYPESPEC_DOUBLE:
1358 case TYPESPEC_SIGNED:
1359 case TYPESPEC_UNSIGNED:
1360 case TYPESPEC_BOOL:
1361 case TYPESPEC_COMPLEX:
1362 case TYPESPEC_IMAGINARY:
1363 case TYPESPEC_CONST:
1364 case TYPESPEC_ID_TYPE:
1365 return ctf_declaration_type_specifier_visit(fd, depth,
1366 type_specifier_list, declaration_scope);
1367 default:
1368 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1369 return NULL;
1370 }
1371 }
1372
1373 static
1374 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1375 {
1376 int ret = 0;
1377
1378 switch (node->type) {
1379 case NODE_TYPEDEF:
1380 ret = ctf_typedef_visit(fd, depth + 1,
1381 event->declaration_scope,
1382 node->u._typedef.type_specifier_list,
1383 &node->u._typedef.type_declarators,
1384 trace);
1385 if (ret)
1386 return ret;
1387 break;
1388 case NODE_TYPEALIAS:
1389 ret = ctf_typealias_visit(fd, depth + 1,
1390 event->declaration_scope,
1391 node->u.typealias.target, node->u.typealias.alias,
1392 trace);
1393 if (ret)
1394 return ret;
1395 break;
1396 case NODE_CTF_EXPRESSION:
1397 {
1398 char *left;
1399
1400 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1401 if (!strcmp(left, "name")) {
1402 char *right;
1403
1404 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1405 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1406 ret = -EPERM;
1407 goto error;
1408 }
1409 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1410 if (!right) {
1411 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1412 ret = -EINVAL;
1413 goto error;
1414 }
1415 event->name = g_quark_from_string(right);
1416 g_free(right);
1417 CTF_EVENT_SET_FIELD(event, name);
1418 } else if (!strcmp(left, "id")) {
1419 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1420 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1421 ret = -EPERM;
1422 goto error;
1423 }
1424 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1425 if (ret) {
1426 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1427 ret = -EINVAL;
1428 goto error;
1429 }
1430 CTF_EVENT_SET_FIELD(event, id);
1431 } else if (!strcmp(left, "stream_id")) {
1432 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1433 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1434 ret = -EPERM;
1435 goto error;
1436 }
1437 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1438 if (ret) {
1439 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1440 ret = -EINVAL;
1441 goto error;
1442 }
1443 event->stream = trace_stream_lookup(trace, event->stream_id);
1444 if (!event->stream) {
1445 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1446 ret = -EINVAL;
1447 goto error;
1448 }
1449 CTF_EVENT_SET_FIELD(event, stream_id);
1450 } else if (!strcmp(left, "context")) {
1451 struct declaration *declaration;
1452
1453 if (event->context_decl) {
1454 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1455 ret = -EINVAL;
1456 goto error;
1457 }
1458 declaration = ctf_type_specifier_list_visit(fd, depth,
1459 _cds_list_first_entry(&node->u.ctf_expression.right,
1460 struct ctf_node, siblings),
1461 event->declaration_scope, trace);
1462 if (!declaration) {
1463 ret = -EPERM;
1464 goto error;
1465 }
1466 if (declaration->id != CTF_TYPE_STRUCT) {
1467 ret = -EPERM;
1468 goto error;
1469 }
1470 event->context_decl = container_of(declaration, struct declaration_struct, p);
1471 } else if (!strcmp(left, "fields")) {
1472 struct declaration *declaration;
1473
1474 if (event->fields_decl) {
1475 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1476 ret = -EINVAL;
1477 goto error;
1478 }
1479 declaration = ctf_type_specifier_list_visit(fd, depth,
1480 _cds_list_first_entry(&node->u.ctf_expression.right,
1481 struct ctf_node, siblings),
1482 event->declaration_scope, trace);
1483 if (!declaration) {
1484 ret = -EPERM;
1485 goto error;
1486 }
1487 if (declaration->id != CTF_TYPE_STRUCT) {
1488 ret = -EPERM;
1489 goto error;
1490 }
1491 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1492 }
1493 error:
1494 g_free(left);
1495 break;
1496 }
1497 default:
1498 return -EPERM;
1499 /* TODO: declaration specifier should be added. */
1500 }
1501
1502 return ret;
1503 }
1504
1505 static
1506 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1507 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1508 {
1509 int ret = 0;
1510 struct ctf_node *iter;
1511 struct ctf_event *event;
1512 struct definition_scope *parent_def_scope;
1513
1514 event = g_new0(struct ctf_event, 1);
1515 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1516 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1517 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1518 if (ret)
1519 goto error;
1520 }
1521 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1522 ret = -EPERM;
1523 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1524 goto error;
1525 }
1526 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1527 /* Allow missing stream_id if there is only a single stream */
1528 switch (trace->streams->len) {
1529 case 0: /* Create stream if there was none. */
1530 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1531 if (ret)
1532 goto error;
1533 /* Fall-through */
1534 case 1:
1535 event->stream_id = 0;
1536 event->stream = trace_stream_lookup(trace, event->stream_id);
1537 break;
1538 default:
1539 ret = -EPERM;
1540 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1541 goto error;
1542 }
1543 }
1544 /* Allow only one event without id per stream */
1545 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1546 && event->stream->events_by_id->len != 0) {
1547 ret = -EPERM;
1548 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1549 goto error;
1550 }
1551 if (event->stream->events_by_id->len <= event->id)
1552 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1553 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1554 g_hash_table_insert(event->stream->event_quark_to_id,
1555 (gpointer)(unsigned long) event->name,
1556 &event->id);
1557 parent_def_scope = event->stream->definition_scope;
1558 if (event->context_decl) {
1559 event->context =
1560 container_of(
1561 event->context_decl->p.definition_new(&event->context_decl->p,
1562 parent_def_scope, 0, 0),
1563 struct definition_struct, p);
1564 set_dynamic_definition_scope(&event->context->p,
1565 event->context->scope,
1566 "event.context");
1567 parent_def_scope = event->context->scope;
1568 declaration_unref(&event->context_decl->p);
1569 }
1570 if (event->fields_decl) {
1571 event->fields =
1572 container_of(
1573 event->fields_decl->p.definition_new(&event->fields_decl->p,
1574 parent_def_scope, 0, 0),
1575 struct definition_struct, p);
1576 set_dynamic_definition_scope(&event->fields->p,
1577 event->fields->scope,
1578 "event.fields");
1579 parent_def_scope = event->fields->scope;
1580 declaration_unref(&event->fields_decl->p);
1581 }
1582 return 0;
1583
1584 error:
1585 declaration_unref(&event->fields_decl->p);
1586 declaration_unref(&event->context_decl->p);
1587 free_declaration_scope(event->declaration_scope);
1588 g_free(event);
1589 return ret;
1590 }
1591
1592
1593 static
1594 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_class *stream, struct ctf_trace *trace)
1595 {
1596 int ret = 0;
1597
1598 switch (node->type) {
1599 case NODE_TYPEDEF:
1600 ret = ctf_typedef_visit(fd, depth + 1,
1601 stream->declaration_scope,
1602 node->u._typedef.type_specifier_list,
1603 &node->u._typedef.type_declarators,
1604 trace);
1605 if (ret)
1606 return ret;
1607 break;
1608 case NODE_TYPEALIAS:
1609 ret = ctf_typealias_visit(fd, depth + 1,
1610 stream->declaration_scope,
1611 node->u.typealias.target, node->u.typealias.alias,
1612 trace);
1613 if (ret)
1614 return ret;
1615 break;
1616 case NODE_CTF_EXPRESSION:
1617 {
1618 char *left;
1619
1620 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1621 if (!strcmp(left, "id")) {
1622 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1623 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1624 ret = -EPERM;
1625 goto error;
1626 }
1627 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1628 if (ret) {
1629 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1630 ret = -EINVAL;
1631 goto error;
1632 }
1633 CTF_STREAM_SET_FIELD(stream, stream_id);
1634 } else if (!strcmp(left, "event.header")) {
1635 struct declaration *declaration;
1636
1637 if (stream->event_header_decl) {
1638 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1639 ret = -EINVAL;
1640 goto error;
1641 }
1642 declaration = ctf_type_specifier_list_visit(fd, depth,
1643 _cds_list_first_entry(&node->u.ctf_expression.right,
1644 struct ctf_node, siblings),
1645 stream->declaration_scope, trace);
1646 if (!declaration) {
1647 ret = -EPERM;
1648 goto error;
1649 }
1650 if (declaration->id != CTF_TYPE_STRUCT) {
1651 ret = -EPERM;
1652 goto error;
1653 }
1654 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1655 } else if (!strcmp(left, "event.context")) {
1656 struct declaration *declaration;
1657
1658 if (stream->event_context_decl) {
1659 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1660 ret = -EINVAL;
1661 goto error;
1662 }
1663 declaration = ctf_type_specifier_list_visit(fd, depth,
1664 _cds_list_first_entry(&node->u.ctf_expression.right,
1665 struct ctf_node, siblings),
1666 stream->declaration_scope, trace);
1667 if (!declaration) {
1668 ret = -EPERM;
1669 goto error;
1670 }
1671 if (declaration->id != CTF_TYPE_STRUCT) {
1672 ret = -EPERM;
1673 goto error;
1674 }
1675 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1676 } else if (!strcmp(left, "packet.context")) {
1677 struct declaration *declaration;
1678
1679 if (stream->packet_context_decl) {
1680 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1681 ret = -EINVAL;
1682 goto error;
1683 }
1684 declaration = ctf_type_specifier_list_visit(fd, depth,
1685 _cds_list_first_entry(&node->u.ctf_expression.right,
1686 struct ctf_node, siblings),
1687 stream->declaration_scope, trace);
1688 if (!declaration) {
1689 ret = -EPERM;
1690 goto error;
1691 }
1692 if (declaration->id != CTF_TYPE_STRUCT) {
1693 ret = -EPERM;
1694 goto error;
1695 }
1696 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1697 }
1698 error:
1699 g_free(left);
1700 break;
1701 }
1702 default:
1703 return -EPERM;
1704 /* TODO: declaration specifier should be added. */
1705 }
1706
1707 return ret;
1708 }
1709
1710 static
1711 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1712 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1713 {
1714 int ret = 0;
1715 struct ctf_node *iter;
1716 struct ctf_stream_class *stream;
1717 struct definition_scope *parent_def_scope;
1718
1719 stream = g_new0(struct ctf_stream_class, 1);
1720 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1721 stream->events_by_id = g_ptr_array_new();
1722 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1723 stream->files = g_ptr_array_new();
1724 if (node) {
1725 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1726 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1727 if (ret)
1728 goto error;
1729 }
1730 }
1731 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1732 /* check that packet header has stream_id field. */
1733 if (!trace->packet_header_decl
1734 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1735 ret = -EPERM;
1736 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1737 goto error;
1738 }
1739 } else {
1740 /* Allow only one id-less stream */
1741 if (trace->streams->len != 0) {
1742 ret = -EPERM;
1743 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1744 goto error;
1745 }
1746 stream->stream_id = 0;
1747 }
1748 if (trace->streams->len <= stream->stream_id)
1749 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1750 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1751
1752 parent_def_scope = trace->definition_scope;
1753 if (stream->packet_context_decl) {
1754 stream->packet_context =
1755 container_of(
1756 stream->packet_context_decl->p.definition_new(&stream->packet_context_decl->p,
1757 parent_def_scope, 0, 0),
1758 struct definition_struct, p);
1759 set_dynamic_definition_scope(&stream->packet_context->p,
1760 stream->packet_context->scope,
1761 "stream.packet.context");
1762 parent_def_scope = stream->packet_context->scope;
1763 declaration_unref(&stream->packet_context_decl->p);
1764 }
1765 if (stream->event_header_decl) {
1766 stream->event_header =
1767 container_of(
1768 stream->event_header_decl->p.definition_new(&stream->event_header_decl->p,
1769 parent_def_scope, 0, 0),
1770 struct definition_struct, p);
1771 set_dynamic_definition_scope(&stream->event_header->p,
1772 stream->event_header->scope,
1773 "stream.event.header");
1774 parent_def_scope = stream->event_header->scope;
1775 declaration_unref(&stream->event_header_decl->p);
1776 }
1777 if (stream->event_context_decl) {
1778 stream->event_context =
1779 container_of(
1780 stream->event_context_decl->p.definition_new(&stream->event_context_decl->p,
1781 parent_def_scope, 0, 0),
1782 struct definition_struct, p);
1783 set_dynamic_definition_scope(&stream->event_context->p,
1784 stream->event_context->scope,
1785 "stream.event.context");
1786 parent_def_scope = stream->event_context->scope;
1787 declaration_unref(&stream->event_context_decl->p);
1788 }
1789 stream->definition_scope = parent_def_scope;
1790
1791 return 0;
1792
1793 error:
1794 declaration_unref(&stream->event_header_decl->p);
1795 declaration_unref(&stream->event_context_decl->p);
1796 declaration_unref(&stream->packet_context_decl->p);
1797 g_ptr_array_free(stream->files, TRUE);
1798 g_ptr_array_free(stream->events_by_id, TRUE);
1799 g_hash_table_destroy(stream->event_quark_to_id);
1800 free_declaration_scope(stream->declaration_scope);
1801 g_free(stream);
1802 return ret;
1803 }
1804
1805 static
1806 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1807 {
1808 int ret = 0;
1809
1810 switch (node->type) {
1811 case NODE_TYPEDEF:
1812 ret = ctf_typedef_visit(fd, depth + 1,
1813 trace->declaration_scope,
1814 node->u._typedef.type_specifier_list,
1815 &node->u._typedef.type_declarators,
1816 trace);
1817 if (ret)
1818 return ret;
1819 break;
1820 case NODE_TYPEALIAS:
1821 ret = ctf_typealias_visit(fd, depth + 1,
1822 trace->declaration_scope,
1823 node->u.typealias.target, node->u.typealias.alias,
1824 trace);
1825 if (ret)
1826 return ret;
1827 break;
1828 case NODE_CTF_EXPRESSION:
1829 {
1830 char *left;
1831
1832 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1833 if (!strcmp(left, "major")) {
1834 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1835 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
1836 ret = -EPERM;
1837 goto error;
1838 }
1839 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1840 if (ret) {
1841 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1842 ret = -EINVAL;
1843 goto error;
1844 }
1845 CTF_TRACE_SET_FIELD(trace, major);
1846 } else if (!strcmp(left, "minor")) {
1847 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1848 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
1849 ret = -EPERM;
1850 goto error;
1851 }
1852 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1853 if (ret) {
1854 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1855 ret = -EINVAL;
1856 goto error;
1857 }
1858 CTF_TRACE_SET_FIELD(trace, minor);
1859 } else if (!strcmp(left, "uuid")) {
1860 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1861 fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
1862 ret = -EPERM;
1863 goto error;
1864 }
1865 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1866 if (ret) {
1867 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1868 ret = -EINVAL;
1869 goto error;
1870 }
1871 CTF_TRACE_SET_FIELD(trace, uuid);
1872 } else if (!strcmp(left, "byte_order")) {
1873 struct ctf_node *right;
1874 int byte_order;
1875
1876 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1877 fprintf(fd, "[error] %s: endianness already declared in trace declaration\n", __func__);
1878 ret = -EPERM;
1879 goto error;
1880 }
1881 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
1882 byte_order = get_trace_byte_order(fd, depth, right);
1883 if (byte_order < 0)
1884 return -EINVAL;
1885 trace->byte_order = byte_order;
1886 CTF_TRACE_SET_FIELD(trace, byte_order);
1887 } else if (!strcmp(left, "packet.header")) {
1888 struct declaration *declaration;
1889
1890 if (trace->packet_header_decl) {
1891 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
1892 ret = -EINVAL;
1893 goto error;
1894 }
1895 declaration = ctf_type_specifier_list_visit(fd, depth,
1896 _cds_list_first_entry(&node->u.ctf_expression.right,
1897 struct ctf_node, siblings),
1898 trace->declaration_scope, trace);
1899 if (!declaration) {
1900 ret = -EPERM;
1901 goto error;
1902 }
1903 if (declaration->id != CTF_TYPE_STRUCT) {
1904 ret = -EPERM;
1905 goto error;
1906 }
1907 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
1908 }
1909 error:
1910 g_free(left);
1911 break;
1912 }
1913 default:
1914 return -EPERM;
1915 /* TODO: declaration specifier should be added. */
1916 }
1917
1918 return ret;
1919 }
1920
1921 static
1922 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1923 {
1924 struct definition_scope *parent_def_scope;
1925 int ret = 0;
1926 struct ctf_node *iter;
1927
1928 if (trace->declaration_scope)
1929 return -EEXIST;
1930 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
1931 trace->streams = g_ptr_array_new();
1932 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1933 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1934 if (ret)
1935 goto error;
1936 }
1937 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
1938 ret = -EPERM;
1939 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
1940 goto error;
1941 }
1942 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1943 ret = -EPERM;
1944 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
1945 goto error;
1946 }
1947 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1948 ret = -EPERM;
1949 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
1950 goto error;
1951 }
1952 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1953 ret = -EPERM;
1954 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
1955 goto error;
1956 }
1957
1958 parent_def_scope = NULL;
1959 if (trace->packet_header_decl) {
1960 trace->packet_header =
1961 container_of(
1962 trace->packet_header_decl->p.definition_new(&trace->packet_header_decl->p,
1963 parent_def_scope, 0, 0),
1964 struct definition_struct, p);
1965 set_dynamic_definition_scope(&trace->packet_header->p,
1966 trace->packet_header->scope,
1967 "trace.packet.header");
1968 parent_def_scope = trace->packet_header->scope;
1969 declaration_unref(&trace->packet_header_decl->p);
1970 }
1971 trace->definition_scope = parent_def_scope;
1972
1973 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1974 /* check that the packet header contains a "magic" field */
1975 if (!trace->packet_header
1976 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
1977 ret = -EPERM;
1978 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
1979 goto error_free_def;
1980 }
1981 }
1982 return 0;
1983
1984 error_free_def:
1985 definition_unref(&trace->packet_header->p);
1986 error:
1987 g_ptr_array_free(trace->streams, TRUE);
1988 free_declaration_scope(trace->declaration_scope);
1989 return ret;
1990 }
1991
1992 static
1993 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1994 {
1995 int ret = 0;
1996
1997 switch (node->type) {
1998 case NODE_TYPEDEF:
1999 ret = ctf_typedef_visit(fd, depth + 1,
2000 trace->root_declaration_scope,
2001 node->u._typedef.type_specifier_list,
2002 &node->u._typedef.type_declarators,
2003 trace);
2004 if (ret)
2005 return ret;
2006 break;
2007 case NODE_TYPEALIAS:
2008 ret = ctf_typealias_visit(fd, depth + 1,
2009 trace->root_declaration_scope,
2010 node->u.typealias.target, node->u.typealias.alias,
2011 trace);
2012 if (ret)
2013 return ret;
2014 break;
2015 case NODE_TYPE_SPECIFIER_LIST:
2016 {
2017 struct declaration *declaration;
2018
2019 /*
2020 * Just add the type specifier to the root scope
2021 * declaration scope. Release local reference.
2022 */
2023 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2024 node, trace->root_declaration_scope, trace);
2025 if (!declaration)
2026 return -ENOMEM;
2027 declaration_unref(declaration);
2028 break;
2029 }
2030 default:
2031 return -EPERM;
2032 }
2033
2034 return 0;
2035 }
2036
2037 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2038 struct ctf_trace *trace, int byte_order)
2039 {
2040 int ret = 0;
2041 struct ctf_node *iter;
2042
2043 printf_verbose("CTF visitor: metadata construction... ");
2044 trace->root_declaration_scope = new_declaration_scope(NULL);
2045 trace->streams = g_ptr_array_new();
2046 trace->byte_order = byte_order;
2047
2048 switch (node->type) {
2049 case NODE_ROOT:
2050 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
2051 siblings) {
2052 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
2053 if (ret) {
2054 fprintf(fd, "[error] %s: root declaration error\n", __func__);
2055 return ret;
2056 }
2057 }
2058 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2059 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
2060 if (ret) {
2061 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
2062 return ret;
2063 }
2064 }
2065 if (!trace->streams) {
2066 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
2067 return -EINVAL;
2068 }
2069 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2070 ret = ctf_stream_visit(fd, depth + 1, iter,
2071 trace->root_declaration_scope, trace);
2072 if (ret) {
2073 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
2074 return ret;
2075 }
2076 }
2077 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
2078 ret = ctf_event_visit(fd, depth + 1, iter,
2079 trace->root_declaration_scope, trace);
2080 if (ret) {
2081 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2082 return ret;
2083 }
2084 }
2085 break;
2086 case NODE_UNKNOWN:
2087 default:
2088 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2089 (int) node->type);
2090 return -EINVAL;
2091 }
2092 printf_verbose("done.\n");
2093 return ret;
2094 }
This page took 0.113766 seconds and 5 git commands to generate.