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