Add loglevel support
[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 {
1238 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1239 __func__, left->u.unary_expression.u.string);
1240 return NULL;
1241 }
1242 }
1243 if (!has_size) {
1244 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
1245 return NULL;
1246 }
1247 if (!has_alignment) {
1248 if (size % CHAR_BIT) {
1249 /* bit-packed alignment */
1250 alignment = 1;
1251 } else {
1252 /* byte-packed alignment */
1253 alignment = CHAR_BIT;
1254 }
1255 }
1256 integer_declaration = integer_declaration_new(size,
1257 byte_order, signedness, alignment,
1258 base, encoding);
1259 return &integer_declaration->p;
1260 }
1261
1262 static
1263 struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
1264 struct cds_list_head *expressions,
1265 struct ctf_trace *trace)
1266 {
1267 struct ctf_node *expression;
1268 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1269 byte_order = trace->byte_order;
1270 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1271 struct declaration_float *float_declaration;
1272
1273 cds_list_for_each_entry(expression, expressions, siblings) {
1274 struct ctf_node *left, *right;
1275
1276 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1277 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1278 assert(left->u.unary_expression.type == UNARY_STRING);
1279 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
1280 byte_order = get_byte_order(fd, depth, right, trace);
1281 if (byte_order < 0)
1282 return NULL;
1283 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1284 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1285 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
1286 __func__);
1287 return NULL;
1288 }
1289 exp_dig = right->u.unary_expression.u.unsigned_constant;
1290 has_exp_dig = 1;
1291 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1292 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1293 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
1294 __func__);
1295 return NULL;
1296 }
1297 mant_dig = right->u.unary_expression.u.unsigned_constant;
1298 has_mant_dig = 1;
1299 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1300 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
1301 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
1302 __func__);
1303 return NULL;
1304 }
1305 alignment = right->u.unary_expression.u.unsigned_constant;
1306 /* Make sure alignment is a power of two */
1307 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1308 fprintf(fd, "[error] %s: align: expecting power of two\n",
1309 __func__);
1310 return NULL;
1311 }
1312 has_alignment = 1;
1313 } else {
1314 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1315 __func__, left->u.unary_expression.u.string);
1316 return NULL;
1317 }
1318 }
1319 if (!has_mant_dig) {
1320 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
1321 return NULL;
1322 }
1323 if (!has_exp_dig) {
1324 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
1325 return NULL;
1326 }
1327 if (!has_alignment) {
1328 if ((mant_dig + exp_dig) % CHAR_BIT) {
1329 /* bit-packed alignment */
1330 alignment = 1;
1331 } else {
1332 /* byte-packed alignment */
1333 alignment = CHAR_BIT;
1334 }
1335 }
1336 float_declaration = float_declaration_new(mant_dig, exp_dig,
1337 byte_order, alignment);
1338 return &float_declaration->p;
1339 }
1340
1341 static
1342 struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
1343 struct cds_list_head *expressions,
1344 struct ctf_trace *trace)
1345 {
1346 struct ctf_node *expression;
1347 const char *encoding_c = NULL;
1348 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1349 struct declaration_string *string_declaration;
1350
1351 cds_list_for_each_entry(expression, expressions, siblings) {
1352 struct ctf_node *left, *right;
1353
1354 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1355 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
1356 assert(left->u.unary_expression.type == UNARY_STRING);
1357 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1358 if (right->u.unary_expression.type != UNARY_STRING) {
1359 fprintf(fd, "[error] %s: encoding: expecting string\n",
1360 __func__);
1361 return NULL;
1362 }
1363 encoding_c = right->u.unary_expression.u.string;
1364 } else {
1365 fprintf(fd, "[error] %s: unknown attribute name %s\n",
1366 __func__, left->u.unary_expression.u.string);
1367 return NULL;
1368 }
1369 }
1370 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1371 encoding = CTF_STRING_ASCII;
1372 string_declaration = string_declaration_new(encoding);
1373 return &string_declaration->p;
1374 }
1375
1376
1377 static
1378 struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1379 int depth, struct ctf_node *type_specifier_list,
1380 struct declaration_scope *declaration_scope,
1381 struct ctf_trace *trace)
1382 {
1383 struct ctf_node *first;
1384 struct ctf_node *node;
1385
1386 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1387
1388 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
1389
1390 assert(first->type == NODE_TYPE_SPECIFIER);
1391
1392 node = first->u.type_specifier.node;
1393
1394 switch (first->u.type_specifier.type) {
1395 case TYPESPEC_FLOATING_POINT:
1396 return ctf_declaration_floating_point_visit(fd, depth,
1397 &node->u.floating_point.expressions, trace);
1398 case TYPESPEC_INTEGER:
1399 return ctf_declaration_integer_visit(fd, depth,
1400 &node->u.integer.expressions, trace);
1401 case TYPESPEC_STRING:
1402 return ctf_declaration_string_visit(fd, depth,
1403 &node->u.string.expressions, trace);
1404 case TYPESPEC_STRUCT:
1405 return ctf_declaration_struct_visit(fd, depth,
1406 node->u._struct.name,
1407 &node->u._struct.declaration_list,
1408 node->u._struct.has_body,
1409 &node->u._struct.min_align,
1410 declaration_scope,
1411 trace);
1412 case TYPESPEC_VARIANT:
1413 return ctf_declaration_variant_visit(fd, depth,
1414 node->u.variant.name,
1415 node->u.variant.choice,
1416 &node->u.variant.declaration_list,
1417 node->u.variant.has_body,
1418 declaration_scope,
1419 trace);
1420 case TYPESPEC_ENUM:
1421 return ctf_declaration_enum_visit(fd, depth,
1422 node->u._enum.enum_id,
1423 node->u._enum.container_type,
1424 &node->u._enum.enumerator_list,
1425 node->u._enum.has_body,
1426 declaration_scope,
1427 trace);
1428
1429 case TYPESPEC_VOID:
1430 case TYPESPEC_CHAR:
1431 case TYPESPEC_SHORT:
1432 case TYPESPEC_INT:
1433 case TYPESPEC_LONG:
1434 case TYPESPEC_FLOAT:
1435 case TYPESPEC_DOUBLE:
1436 case TYPESPEC_SIGNED:
1437 case TYPESPEC_UNSIGNED:
1438 case TYPESPEC_BOOL:
1439 case TYPESPEC_COMPLEX:
1440 case TYPESPEC_IMAGINARY:
1441 case TYPESPEC_CONST:
1442 case TYPESPEC_ID_TYPE:
1443 return ctf_declaration_type_specifier_visit(fd, depth,
1444 type_specifier_list, declaration_scope);
1445 default:
1446 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
1447 return NULL;
1448 }
1449 }
1450
1451 static
1452 int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1453 {
1454 int ret = 0;
1455
1456 switch (node->type) {
1457 case NODE_TYPEDEF:
1458 ret = ctf_typedef_visit(fd, depth + 1,
1459 event->declaration_scope,
1460 node->u._typedef.type_specifier_list,
1461 &node->u._typedef.type_declarators,
1462 trace);
1463 if (ret)
1464 return ret;
1465 break;
1466 case NODE_TYPEALIAS:
1467 ret = ctf_typealias_visit(fd, depth + 1,
1468 event->declaration_scope,
1469 node->u.typealias.target, node->u.typealias.alias,
1470 trace);
1471 if (ret)
1472 return ret;
1473 break;
1474 case NODE_CTF_EXPRESSION:
1475 {
1476 char *left;
1477
1478 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1479 if (!strcmp(left, "name")) {
1480 char *right;
1481
1482 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1483 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
1484 ret = -EPERM;
1485 goto error;
1486 }
1487 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1488 if (!right) {
1489 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
1490 ret = -EINVAL;
1491 goto error;
1492 }
1493 event->name = g_quark_from_string(right);
1494 g_free(right);
1495 CTF_EVENT_SET_FIELD(event, name);
1496 } else if (!strcmp(left, "id")) {
1497 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1498 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
1499 ret = -EPERM;
1500 goto error;
1501 }
1502 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1503 if (ret) {
1504 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
1505 ret = -EINVAL;
1506 goto error;
1507 }
1508 CTF_EVENT_SET_FIELD(event, id);
1509 } else if (!strcmp(left, "stream_id")) {
1510 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1511 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
1512 ret = -EPERM;
1513 goto error;
1514 }
1515 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1516 if (ret) {
1517 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
1518 ret = -EINVAL;
1519 goto error;
1520 }
1521 event->stream = trace_stream_lookup(trace, event->stream_id);
1522 if (!event->stream) {
1523 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
1524 ret = -EINVAL;
1525 goto error;
1526 }
1527 CTF_EVENT_SET_FIELD(event, stream_id);
1528 } else if (!strcmp(left, "context")) {
1529 struct declaration *declaration;
1530
1531 if (event->context_decl) {
1532 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
1533 ret = -EINVAL;
1534 goto error;
1535 }
1536 declaration = ctf_type_specifier_list_visit(fd, depth,
1537 _cds_list_first_entry(&node->u.ctf_expression.right,
1538 struct ctf_node, siblings),
1539 event->declaration_scope, trace);
1540 if (!declaration) {
1541 ret = -EPERM;
1542 goto error;
1543 }
1544 if (declaration->id != CTF_TYPE_STRUCT) {
1545 ret = -EPERM;
1546 goto error;
1547 }
1548 event->context_decl = container_of(declaration, struct declaration_struct, p);
1549 } else if (!strcmp(left, "fields")) {
1550 struct declaration *declaration;
1551
1552 if (event->fields_decl) {
1553 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
1554 ret = -EINVAL;
1555 goto error;
1556 }
1557 declaration = ctf_type_specifier_list_visit(fd, depth,
1558 _cds_list_first_entry(&node->u.ctf_expression.right,
1559 struct ctf_node, siblings),
1560 event->declaration_scope, trace);
1561 if (!declaration) {
1562 ret = -EPERM;
1563 goto error;
1564 }
1565 if (declaration->id != CTF_TYPE_STRUCT) {
1566 ret = -EPERM;
1567 goto error;
1568 }
1569 event->fields_decl = container_of(declaration, struct declaration_struct, p);
1570 } else if (!strcmp(left, "loglevel.identifier")) {
1571 char *right;
1572
1573 if (CTF_EVENT_FIELD_IS_SET(event, loglevel_identifier)) {
1574 fprintf(fd, "[error] %s: identifier already declared in event declaration\n", __func__);
1575 ret = -EPERM;
1576 goto error;
1577 }
1578 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1579 if (!right) {
1580 fprintf(fd, "[error] %s: unexpected unary expression for event identifier\n", __func__);
1581 ret = -EINVAL;
1582 goto error;
1583 }
1584 event->loglevel_identifier = g_quark_from_string(right);
1585 g_free(right);
1586 CTF_EVENT_SET_FIELD(event, loglevel_identifier);
1587 } else if (!strcmp(left, "loglevel.value")) {
1588 if (CTF_EVENT_FIELD_IS_SET(event, loglevel_value)) {
1589 fprintf(fd, "[error] %s: loglevel value already declared in event declaration\n", __func__);
1590 ret = -EPERM;
1591 goto error;
1592 }
1593 ret = get_unary_signed(&node->u.ctf_expression.right, &event->loglevel_value);
1594 if (ret) {
1595 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel value\n", __func__);
1596 ret = -EINVAL;
1597 goto error;
1598 }
1599 CTF_EVENT_SET_FIELD(event, loglevel_value);
1600 } else {
1601 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1602 ret = -EINVAL;
1603 goto error;
1604 }
1605 error:
1606 g_free(left);
1607 break;
1608 }
1609 default:
1610 return -EPERM;
1611 /* TODO: declaration specifier should be added. */
1612 }
1613
1614 return ret;
1615 }
1616
1617 static
1618 int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
1619 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1620 {
1621 int ret = 0;
1622 struct ctf_node *iter;
1623 struct ctf_event *event;
1624
1625 event = g_new0(struct ctf_event, 1);
1626 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
1627 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1628 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1629 if (ret)
1630 goto error;
1631 }
1632 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1633 ret = -EPERM;
1634 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
1635 goto error;
1636 }
1637 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1638 /* Allow missing stream_id if there is only a single stream */
1639 switch (trace->streams->len) {
1640 case 0: /* Create stream if there was none. */
1641 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1642 if (ret)
1643 goto error;
1644 /* Fall-through */
1645 case 1:
1646 event->stream_id = 0;
1647 event->stream = trace_stream_lookup(trace, event->stream_id);
1648 break;
1649 default:
1650 ret = -EPERM;
1651 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1652 goto error;
1653 }
1654 }
1655 /* Allow only one event without id per stream */
1656 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1657 && event->stream->events_by_id->len != 0) {
1658 ret = -EPERM;
1659 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1660 goto error;
1661 }
1662 if (event->stream->events_by_id->len <= event->id)
1663 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1664 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1665 g_hash_table_insert(event->stream->event_quark_to_id,
1666 (gpointer)(unsigned long) event->name,
1667 &event->id);
1668 return 0;
1669
1670 error:
1671 if (event->fields_decl)
1672 declaration_unref(&event->fields_decl->p);
1673 if (event->context_decl)
1674 declaration_unref(&event->context_decl->p);
1675 free_declaration_scope(event->declaration_scope);
1676 g_free(event);
1677 return ret;
1678 }
1679
1680
1681 static
1682 int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_class *stream, struct ctf_trace *trace)
1683 {
1684 int ret = 0;
1685
1686 switch (node->type) {
1687 case NODE_TYPEDEF:
1688 ret = ctf_typedef_visit(fd, depth + 1,
1689 stream->declaration_scope,
1690 node->u._typedef.type_specifier_list,
1691 &node->u._typedef.type_declarators,
1692 trace);
1693 if (ret)
1694 return ret;
1695 break;
1696 case NODE_TYPEALIAS:
1697 ret = ctf_typealias_visit(fd, depth + 1,
1698 stream->declaration_scope,
1699 node->u.typealias.target, node->u.typealias.alias,
1700 trace);
1701 if (ret)
1702 return ret;
1703 break;
1704 case NODE_CTF_EXPRESSION:
1705 {
1706 char *left;
1707
1708 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1709 if (!strcmp(left, "id")) {
1710 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1711 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
1712 ret = -EPERM;
1713 goto error;
1714 }
1715 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
1716 if (ret) {
1717 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
1718 ret = -EINVAL;
1719 goto error;
1720 }
1721 CTF_STREAM_SET_FIELD(stream, stream_id);
1722 } else if (!strcmp(left, "event.header")) {
1723 struct declaration *declaration;
1724
1725 if (stream->event_header_decl) {
1726 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
1727 ret = -EINVAL;
1728 goto error;
1729 }
1730 declaration = ctf_type_specifier_list_visit(fd, depth,
1731 _cds_list_first_entry(&node->u.ctf_expression.right,
1732 struct ctf_node, siblings),
1733 stream->declaration_scope, trace);
1734 if (!declaration) {
1735 ret = -EPERM;
1736 goto error;
1737 }
1738 if (declaration->id != CTF_TYPE_STRUCT) {
1739 ret = -EPERM;
1740 goto error;
1741 }
1742 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1743 } else if (!strcmp(left, "event.context")) {
1744 struct declaration *declaration;
1745
1746 if (stream->event_context_decl) {
1747 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
1748 ret = -EINVAL;
1749 goto error;
1750 }
1751 declaration = ctf_type_specifier_list_visit(fd, depth,
1752 _cds_list_first_entry(&node->u.ctf_expression.right,
1753 struct ctf_node, siblings),
1754 stream->declaration_scope, trace);
1755 if (!declaration) {
1756 ret = -EPERM;
1757 goto error;
1758 }
1759 if (declaration->id != CTF_TYPE_STRUCT) {
1760 ret = -EPERM;
1761 goto error;
1762 }
1763 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1764 } else if (!strcmp(left, "packet.context")) {
1765 struct declaration *declaration;
1766
1767 if (stream->packet_context_decl) {
1768 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
1769 ret = -EINVAL;
1770 goto error;
1771 }
1772 declaration = ctf_type_specifier_list_visit(fd, depth,
1773 _cds_list_first_entry(&node->u.ctf_expression.right,
1774 struct ctf_node, siblings),
1775 stream->declaration_scope, trace);
1776 if (!declaration) {
1777 ret = -EPERM;
1778 goto error;
1779 }
1780 if (declaration->id != CTF_TYPE_STRUCT) {
1781 ret = -EPERM;
1782 goto error;
1783 }
1784 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
1785 } else {
1786 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1787 ret = -EINVAL;
1788 goto error;
1789 }
1790
1791 error:
1792 g_free(left);
1793 break;
1794 }
1795 default:
1796 return -EPERM;
1797 /* TODO: declaration specifier should be added. */
1798 }
1799
1800 return ret;
1801 }
1802
1803 static
1804 int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
1805 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
1806 {
1807 int ret = 0;
1808 struct ctf_node *iter;
1809 struct ctf_stream_class *stream;
1810
1811 stream = g_new0(struct ctf_stream_class, 1);
1812 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
1813 stream->events_by_id = g_ptr_array_new();
1814 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
1815 stream->streams = g_ptr_array_new();
1816 if (node) {
1817 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1818 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1819 if (ret)
1820 goto error;
1821 }
1822 }
1823 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1824 /* check that packet header has stream_id field. */
1825 if (!trace->packet_header_decl
1826 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1827 ret = -EPERM;
1828 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1829 goto error;
1830 }
1831 } else {
1832 /* Allow only one id-less stream */
1833 if (trace->streams->len != 0) {
1834 ret = -EPERM;
1835 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
1836 goto error;
1837 }
1838 stream->stream_id = 0;
1839 }
1840 if (trace->streams->len <= stream->stream_id)
1841 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1842 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
1843 stream->trace = trace;
1844
1845 return 0;
1846
1847 error:
1848 if (stream->event_header_decl)
1849 declaration_unref(&stream->event_header_decl->p);
1850 if (stream->event_context_decl)
1851 declaration_unref(&stream->event_context_decl->p);
1852 if (stream->packet_context_decl)
1853 declaration_unref(&stream->packet_context_decl->p);
1854 g_ptr_array_free(stream->streams, TRUE);
1855 g_ptr_array_free(stream->events_by_id, TRUE);
1856 g_hash_table_destroy(stream->event_quark_to_id);
1857 free_declaration_scope(stream->declaration_scope);
1858 g_free(stream);
1859 return ret;
1860 }
1861
1862 static
1863 int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1864 {
1865 int ret = 0;
1866
1867 switch (node->type) {
1868 case NODE_TYPEDEF:
1869 ret = ctf_typedef_visit(fd, depth + 1,
1870 trace->declaration_scope,
1871 node->u._typedef.type_specifier_list,
1872 &node->u._typedef.type_declarators,
1873 trace);
1874 if (ret)
1875 return ret;
1876 break;
1877 case NODE_TYPEALIAS:
1878 ret = ctf_typealias_visit(fd, depth + 1,
1879 trace->declaration_scope,
1880 node->u.typealias.target, node->u.typealias.alias,
1881 trace);
1882 if (ret)
1883 return ret;
1884 break;
1885 case NODE_CTF_EXPRESSION:
1886 {
1887 char *left;
1888
1889 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1890 if (!strcmp(left, "major")) {
1891 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1892 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
1893 ret = -EPERM;
1894 goto error;
1895 }
1896 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1897 if (ret) {
1898 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
1899 ret = -EINVAL;
1900 goto error;
1901 }
1902 CTF_TRACE_SET_FIELD(trace, major);
1903 } else if (!strcmp(left, "minor")) {
1904 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1905 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
1906 ret = -EPERM;
1907 goto error;
1908 }
1909 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1910 if (ret) {
1911 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
1912 ret = -EINVAL;
1913 goto error;
1914 }
1915 CTF_TRACE_SET_FIELD(trace, minor);
1916 } else if (!strcmp(left, "uuid")) {
1917 uuid_t uuid;
1918
1919 ret = get_unary_uuid(&node->u.ctf_expression.right, &uuid);
1920 if (ret) {
1921 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
1922 ret = -EINVAL;
1923 goto error;
1924 }
1925 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
1926 && uuid_compare(uuid, trace->uuid)) {
1927 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
1928 ret = -EPERM;
1929 goto error;
1930 } else {
1931 memcpy(trace->uuid, uuid, sizeof(uuid));
1932 }
1933 CTF_TRACE_SET_FIELD(trace, uuid);
1934 } else if (!strcmp(left, "byte_order")) {
1935 struct ctf_node *right;
1936 int byte_order;
1937
1938 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
1939 byte_order = get_trace_byte_order(fd, depth, right);
1940 if (byte_order < 0)
1941 return -EINVAL;
1942
1943 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
1944 && byte_order != trace->byte_order) {
1945 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
1946 ret = -EPERM;
1947 goto error;
1948 } else {
1949 if (byte_order != trace->byte_order) {
1950 trace->byte_order = byte_order;
1951 /*
1952 * We need to restart
1953 * construction of the
1954 * intermediate representation.
1955 */
1956 trace->field_mask = 0;
1957 CTF_TRACE_SET_FIELD(trace, byte_order);
1958 ret = -EINTR;
1959 goto error;
1960 }
1961 }
1962 CTF_TRACE_SET_FIELD(trace, byte_order);
1963 } else if (!strcmp(left, "packet.header")) {
1964 struct declaration *declaration;
1965
1966 if (trace->packet_header_decl) {
1967 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
1968 ret = -EINVAL;
1969 goto error;
1970 }
1971 declaration = ctf_type_specifier_list_visit(fd, depth,
1972 _cds_list_first_entry(&node->u.ctf_expression.right,
1973 struct ctf_node, siblings),
1974 trace->declaration_scope, trace);
1975 if (!declaration) {
1976 ret = -EPERM;
1977 goto error;
1978 }
1979 if (declaration->id != CTF_TYPE_STRUCT) {
1980 ret = -EPERM;
1981 goto error;
1982 }
1983 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
1984 } else {
1985 fprintf(fd, "[error] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
1986 ret = -EINVAL;
1987 goto error;
1988 }
1989
1990 error:
1991 g_free(left);
1992 break;
1993 }
1994 default:
1995 return -EPERM;
1996 /* TODO: declaration specifier should be added. */
1997 }
1998
1999 return ret;
2000 }
2001
2002 static
2003 int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2004 {
2005 int ret = 0;
2006 struct ctf_node *iter;
2007
2008 if (trace->declaration_scope)
2009 return -EEXIST;
2010 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
2011 trace->streams = g_ptr_array_new();
2012 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
2013 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2014 if (ret)
2015 goto error;
2016 }
2017 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
2018 ret = -EPERM;
2019 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
2020 goto error;
2021 }
2022 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2023 ret = -EPERM;
2024 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
2025 goto error;
2026 }
2027 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
2028 ret = -EPERM;
2029 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
2030 goto error;
2031 }
2032 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2033 ret = -EPERM;
2034 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2035 goto error;
2036 }
2037
2038 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2039 /* check that the packet header contains a "magic" field */
2040 if (!trace->packet_header_decl
2041 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2042 ret = -EPERM;
2043 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
2044 goto error;
2045 }
2046 }
2047 return 0;
2048
2049 error:
2050 if (trace->packet_header_decl) {
2051 declaration_unref(&trace->packet_header_decl->p);
2052 trace->packet_header_decl = NULL;
2053 }
2054 g_ptr_array_free(trace->streams, TRUE);
2055 free_declaration_scope(trace->declaration_scope);
2056 trace->declaration_scope = NULL;
2057 return ret;
2058 }
2059
2060 static
2061 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2062 {
2063 int ret = 0;
2064
2065 switch (node->type) {
2066 case NODE_TYPEDEF:
2067 ret = ctf_typedef_visit(fd, depth + 1,
2068 trace->root_declaration_scope,
2069 node->u._typedef.type_specifier_list,
2070 &node->u._typedef.type_declarators,
2071 trace);
2072 if (ret)
2073 return ret;
2074 break;
2075 case NODE_TYPEALIAS:
2076 ret = ctf_typealias_visit(fd, depth + 1,
2077 trace->root_declaration_scope,
2078 node->u.typealias.target, node->u.typealias.alias,
2079 trace);
2080 if (ret)
2081 return ret;
2082 break;
2083 case NODE_TYPE_SPECIFIER_LIST:
2084 {
2085 struct declaration *declaration;
2086
2087 /*
2088 * Just add the type specifier to the root scope
2089 * declaration scope. Release local reference.
2090 */
2091 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2092 node, trace->root_declaration_scope, trace);
2093 if (!declaration)
2094 return -ENOMEM;
2095 declaration_unref(declaration);
2096 break;
2097 }
2098 default:
2099 return -EPERM;
2100 }
2101
2102 return 0;
2103 }
2104
2105 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2106 struct ctf_trace *trace, int byte_order)
2107 {
2108 int ret = 0;
2109 struct ctf_node *iter;
2110
2111 printf_verbose("CTF visitor: metadata construction... ");
2112 trace->byte_order = byte_order;
2113
2114 retry:
2115 trace->root_declaration_scope = new_declaration_scope(NULL);
2116
2117 switch (node->type) {
2118 case NODE_ROOT:
2119 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
2120 siblings) {
2121 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
2122 if (ret) {
2123 fprintf(fd, "[error] %s: root declaration error\n", __func__);
2124 goto error;
2125 }
2126 }
2127 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
2128 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
2129 if (ret == -EINTR) {
2130 free_declaration_scope(trace->root_declaration_scope);
2131 /*
2132 * Need to restart creation of type
2133 * definitions, aliases and
2134 * trace header declarations.
2135 */
2136 goto retry;
2137 }
2138 if (ret) {
2139 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
2140 goto error;
2141 }
2142 }
2143 if (!trace->streams) {
2144 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
2145 ret = -EINVAL;
2146 goto error;
2147 }
2148 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
2149 ret = ctf_stream_visit(fd, depth + 1, iter,
2150 trace->root_declaration_scope, trace);
2151 if (ret) {
2152 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
2153 goto error;
2154 }
2155 }
2156 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
2157 ret = ctf_event_visit(fd, depth + 1, iter,
2158 trace->root_declaration_scope, trace);
2159 if (ret) {
2160 fprintf(fd, "[error] %s: event declaration error\n", __func__);
2161 goto error;
2162 }
2163 }
2164 break;
2165 case NODE_UNKNOWN:
2166 default:
2167 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
2168 (int) node->type);
2169 ret = -EINVAL;
2170 goto error;
2171 }
2172 printf_verbose("done.\n");
2173 return ret;
2174
2175 error:
2176 free_declaration_scope(trace->root_declaration_scope);
2177 return ret;
2178 }
This page took 0.114622 seconds and 4 git commands to generate.