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