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