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