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