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