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