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