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