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