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