fix double-free on error path
[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;
a0720417 893 int ret;
de47353a 894
add40b62
MD
895 /*
896 * For named variant (without body), lookup in
897 * declaration scope. Don't take reference on variant
898 * declaration: ref is only taken upon definition.
899 */
900 if (!has_body) {
901 assert(name);
a0720417 902 untagged_variant_declaration =
add40b62
MD
903 lookup_variant_declaration(g_quark_from_string(name),
904 declaration_scope);
15d4fe3c 905 declaration_ref(&untagged_variant_declaration->p);
add40b62 906 } else {
de47353a 907 /* For unnamed variant, create type */
add40b62
MD
908 /* For named variant (with body), create type and add to declaration scope */
909 if (name) {
910 if (lookup_variant_declaration(g_quark_from_string(name),
911 declaration_scope)) {
912
78af2bcd 913 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
add40b62
MD
914 return NULL;
915 }
916 }
a0720417 917 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
3122e6f0 918 bt_list_for_each_entry(iter, declaration_list, siblings) {
e397791f 919 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
a0720417 920 untagged_variant_declaration, trace);
add40b62
MD
921 if (ret)
922 goto error;
923 }
924 if (name) {
925 ret = register_variant_declaration(g_quark_from_string(name),
a0720417 926 untagged_variant_declaration,
add40b62
MD
927 declaration_scope);
928 assert(!ret);
929 }
a0720417
MD
930 }
931 /*
932 * if tagged, create tagged variant and return. else return
933 * untagged variant.
934 */
935 if (!choice) {
936 return &untagged_variant_declaration->p;
937 } else {
938 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
939 if (!variant_declaration)
940 goto error;
941 declaration_unref(&untagged_variant_declaration->p);
942 return &variant_declaration->p;
de47353a 943 }
add40b62 944error:
2dd46001 945 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
add40b62 946 return NULL;
05628561
MD
947}
948
05628561 949static
8fdba45b 950int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62 951 struct ctf_node *enumerator,
65052a93
MD
952 struct declaration_enum *enum_declaration,
953 struct last_enum_value *last)
add40b62 954{
1cfda062
MD
955 GQuark q;
956 struct ctf_node *iter;
957
958 q = g_quark_from_string(enumerator->u.enumerator.id);
a0720417 959 if (enum_declaration->integer_declaration->signedness) {
1cfda062
MD
960 int64_t start, end;
961 int nr_vals = 0;
962
3122e6f0 963 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1cfda062
MD
964 int64_t *target;
965
966 assert(iter->type == NODE_UNARY_EXPRESSION);
967 if (nr_vals == 0)
968 target = &start;
969 else
970 target = &end;
971
972 switch (iter->u.unary_expression.type) {
973 case UNARY_SIGNED_CONSTANT:
974 *target = iter->u.unary_expression.u.signed_constant;
975 break;
976 case UNARY_UNSIGNED_CONSTANT:
977 *target = iter->u.unary_expression.u.unsigned_constant;
978 break;
979 default:
78af2bcd 980 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
981 return -EINVAL;
982 }
983 if (nr_vals > 1) {
78af2bcd 984 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
985 return -EINVAL;
986 }
987 nr_vals++;
988 }
65052a93
MD
989 if (nr_vals == 0)
990 start = last->u.s;
991 if (nr_vals <= 1)
1cfda062 992 end = start;
65052a93 993 last->u.s = end + 1;
1cfda062 994 enum_signed_insert(enum_declaration, start, end, q);
a0720417 995 } else {
1cfda062
MD
996 uint64_t start, end;
997 int nr_vals = 0;
998
3122e6f0 999 bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
a0720417 1000 uint64_t *target;
1cfda062
MD
1001
1002 assert(iter->type == NODE_UNARY_EXPRESSION);
1003 if (nr_vals == 0)
1004 target = &start;
1005 else
1006 target = &end;
1007
1008 switch (iter->u.unary_expression.type) {
1009 case UNARY_UNSIGNED_CONSTANT:
1010 *target = iter->u.unary_expression.u.unsigned_constant;
1011 break;
1012 case UNARY_SIGNED_CONSTANT:
1013 /*
1014 * We don't accept signed constants for enums with unsigned
1015 * container type.
1016 */
78af2bcd 1017 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1cfda062
MD
1018 return -EINVAL;
1019 default:
78af2bcd 1020 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
1021 return -EINVAL;
1022 }
1023 if (nr_vals > 1) {
78af2bcd 1024 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
1025 return -EINVAL;
1026 }
1027 nr_vals++;
1028 }
65052a93
MD
1029 if (nr_vals == 0)
1030 start = last->u.u;
1031 if (nr_vals <= 1)
1cfda062 1032 end = start;
65052a93 1033 last->u.u = end + 1;
1cfda062
MD
1034 enum_unsigned_insert(enum_declaration, start, end, q);
1035 }
add40b62
MD
1036 return 0;
1037}
1038
1039static
8fdba45b 1040struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 1041 const char *name,
78af2bcd 1042 struct ctf_node *container_type,
3122e6f0 1043 struct bt_list_head *enumerator_list,
1cfda062
MD
1044 int has_body,
1045 struct declaration_scope *declaration_scope,
1046 struct ctf_trace *trace)
05628561 1047{
add40b62
MD
1048 struct declaration *declaration;
1049 struct declaration_enum *enum_declaration;
1050 struct declaration_integer *integer_declaration;
65052a93 1051 struct last_enum_value last_value;
78af2bcd 1052 struct ctf_node *iter;
1cfda062 1053 GQuark dummy_id;
a0720417 1054 int ret;
add40b62 1055
05628561 1056 /*
add40b62
MD
1057 * For named enum (without body), lookup in
1058 * declaration scope. Don't take reference on enum
1059 * declaration: ref is only taken upon definition.
05628561 1060 */
add40b62
MD
1061 if (!has_body) {
1062 assert(name);
1063 enum_declaration =
1064 lookup_enum_declaration(g_quark_from_string(name),
1065 declaration_scope);
15d4fe3c 1066 declaration_ref(&enum_declaration->p);
a0720417 1067 return &enum_declaration->p;
add40b62
MD
1068 } else {
1069 /* For unnamed enum, create type */
1070 /* For named enum (with body), create type and add to declaration scope */
1071 if (name) {
1072 if (lookup_enum_declaration(g_quark_from_string(name),
1073 declaration_scope)) {
1074
78af2bcd 1075 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
add40b62
MD
1076 return NULL;
1077 }
1078 }
78af2bcd 1079 if (!container_type) {
6743829a
MD
1080 declaration = lookup_declaration(g_quark_from_static_string("int"),
1081 declaration_scope);
1082 if (!declaration) {
1083 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
1084 return NULL;
1085 }
1086 } else {
1087 declaration = ctf_type_declarator_visit(fd, depth,
1088 container_type,
1089 &dummy_id, NULL,
1090 declaration_scope,
1091 NULL, trace);
1cfda062 1092 }
30ea18a1
MD
1093 if (!declaration) {
1094 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
1095 return NULL;
1096 }
1097 if (declaration->id != CTF_TYPE_INTEGER) {
1098 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
1099 return NULL;
1cfda062 1100 }
30ea18a1 1101 integer_declaration = container_of(declaration, struct declaration_integer, p);
a0720417 1102 enum_declaration = enum_declaration_new(integer_declaration);
add40b62 1103 declaration_unref(&integer_declaration->p); /* leave ref to enum */
65052a93
MD
1104 if (enum_declaration->integer_declaration->signedness) {
1105 last_value.u.s = 0;
1106 } else {
1107 last_value.u.u = 0;
1108 }
3122e6f0 1109 bt_list_for_each_entry(iter, enumerator_list, siblings) {
65052a93
MD
1110 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration,
1111 &last_value);
add40b62
MD
1112 if (ret)
1113 goto error;
1114 }
1115 if (name) {
1116 ret = register_enum_declaration(g_quark_from_string(name),
1117 enum_declaration,
1118 declaration_scope);
1119 assert(!ret);
15d4fe3c 1120 declaration_unref(&enum_declaration->p);
add40b62 1121 }
a0720417 1122 return &enum_declaration->p;
05628561 1123 }
add40b62
MD
1124error:
1125 enum_declaration->p.declaration_free(&enum_declaration->p);
1126 return NULL;
05628561
MD
1127}
1128
1129static
8fdba45b 1130struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
78af2bcd 1131 struct ctf_node *type_specifier_list,
d20f5e59 1132 struct declaration_scope *declaration_scope)
05628561 1133{
add40b62
MD
1134 GString *str;
1135 struct declaration *declaration;
a0720417
MD
1136 char *str_c;
1137 int ret;
1138 GQuark id_q;
05628561 1139
a0720417 1140 str = g_string_new("");
78af2bcd 1141 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
1142 if (ret)
1143 return NULL;
1144 str_c = g_string_free(str, FALSE);
1145 id_q = g_quark_from_string(str_c);
1146 g_free(str_c);
1147 declaration = lookup_declaration(id_q, declaration_scope);
15d4fe3c 1148 declaration_ref(declaration);
add40b62
MD
1149 return declaration;
1150}
1151
ab4cf058
MD
1152/*
1153 * Returns 0/1 boolean, or < 0 on error.
1154 */
1155static
a0720417 1156int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
ab4cf058
MD
1157{
1158 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
78af2bcd 1159 fprintf(fd, "[error] %s: expecting unary expression\n",
ab4cf058
MD
1160 __func__);
1161 return -EINVAL;
1162 }
1163 switch (unary_expression->u.unary_expression.type) {
1164 case UNARY_UNSIGNED_CONSTANT:
1165 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
1166 return 0;
1167 else
1168 return 1;
1169 case UNARY_SIGNED_CONSTANT:
1170 if (unary_expression->u.unary_expression.u.signed_constant == 0)
1171 return 0;
1172 else
1173 return 1;
1174 case UNARY_STRING:
1175 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
1176 return 1;
1177 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
1178 return 1;
1179 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
1180 return 0;
1181 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
1182 return 0;
1183 else {
78af2bcd 1184 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
ab4cf058
MD
1185 __func__, unary_expression->u.unary_expression.u.string);
1186 return -EINVAL;
1187 }
1188 break;
1189 default:
78af2bcd 1190 fprintf(fd, "[error] %s: unexpected unary expression type\n",
ab4cf058
MD
1191 __func__);
1192 return -EINVAL;
1193 }
1194
1195}
1196
0f980a35
MD
1197static
1198int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
1199{
1200 int byte_order;
1201
1202 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1203 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1204 __func__);
1205 return -EINVAL;
1206 }
1207 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1208 byte_order = BIG_ENDIAN;
1209 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1210 byte_order = LITTLE_ENDIAN;
1211 else {
1212 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1213 __func__, unary_expression->u.unary_expression.u.string);
1214 return -EINVAL;
1215 }
1216 return byte_order;
1217}
1218
ab4cf058 1219static
a0720417
MD
1220int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1221 struct ctf_trace *trace)
ab4cf058
MD
1222{
1223 int byte_order;
1224
1225 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1226 fprintf(fd, "[error] %s: byte_order: expecting string\n",
ab4cf058
MD
1227 __func__);
1228 return -EINVAL;
1229 }
1230 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1231 byte_order = trace->byte_order;
1232 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1233 byte_order = BIG_ENDIAN;
1234 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1235 byte_order = BIG_ENDIAN;
1236 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1237 byte_order = LITTLE_ENDIAN;
1238 else {
78af2bcd 1239 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
a0720417 1240 __func__, unary_expression->u.unary_expression.u.string);
ab4cf058
MD
1241 return -EINVAL;
1242 }
1243 return byte_order;
1244}
1245
add40b62 1246static
8fdba45b 1247struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
3122e6f0 1248 struct bt_list_head *expressions,
ab4cf058 1249 struct ctf_trace *trace)
add40b62 1250{
a0720417 1251 struct ctf_node *expression;
68262b11 1252 uint64_t alignment = 1, size = 0;
ab4cf058
MD
1253 int byte_order = trace->byte_order;
1254 int signedness = 0;
add40b62 1255 int has_alignment = 0, has_size = 0;
4d5fc303 1256 int base = 0;
81dee1bb 1257 enum ctf_string_encoding encoding = CTF_STRING_NONE;
56e60373 1258 struct ctf_clock *clock = NULL;
add40b62
MD
1259 struct declaration_integer *integer_declaration;
1260
3122e6f0 1261 bt_list_for_each_entry(expression, expressions, siblings) {
a0720417 1262 struct ctf_node *left, *right;
add40b62 1263
3122e6f0
JD
1264 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1265 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
add40b62
MD
1266 assert(left->u.unary_expression.type == UNARY_STRING);
1267 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
1268 signedness = get_boolean(fd, depth, right);
1269 if (signedness < 0)
1270 return NULL;
add40b62 1271 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1272 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1273 if (byte_order < 0)
1274 return NULL;
add40b62 1275 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058 1276 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1277 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
ab4cf058
MD
1278 __func__);
1279 return NULL;
1280 }
1281 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1282 has_size = 1;
1283 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058 1284 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1285 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1286 __func__);
1287 return NULL;
1288 }
1289 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1290 /* Make sure alignment is a power of two */
1291 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1292 fprintf(fd, "[error] %s: align: expecting power of two\n",
1293 __func__);
1294 return NULL;
1295 }
add40b62 1296 has_alignment = 1;
164078da
MD
1297 } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
1298 switch (right->u.unary_expression.type) {
1299 case UNARY_UNSIGNED_CONSTANT:
1300 switch (right->u.unary_expression.u.unsigned_constant) {
1301 case 2:
1302 case 8:
1303 case 10:
1304 case 16:
1305 base = right->u.unary_expression.u.unsigned_constant;
1306 break;
1307 default:
1308 fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
1309 __func__, right->u.unary_expression.u.unsigned_constant);
1310 return NULL;
1311 }
1312 break;
1313 case UNARY_STRING:
1314 {
1315 char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1316 if (!s_right) {
1317 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1318 g_free(s_right);
1319 return NULL;
1320 }
1321 if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
1322 || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
1323 base = 10;
1324 } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
1325 || !strcmp(s_right, "x") || !strcmp(s_right, "X")
1326 || !strcmp(s_right, "p")) {
1327 base = 16;
1328 } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
1329 || !strcmp(s_right, "o")) {
1330 base = 8;
1331 } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
1332 base = 2;
1333 } else {
1334 fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
1335 g_free(s_right);
1336 return NULL;
1337 }
1338
1339 g_free(s_right);
1340 break;
1341 }
1342 default:
1343 fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
1344 __func__);
1345 return NULL;
1346 }
81dee1bb
MD
1347 } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
1348 char *s_right;
1349
1350 if (right->u.unary_expression.type != UNARY_STRING) {
1351 fprintf(fd, "[error] %s: encoding: expecting unary string\n",
1352 __func__);
1353 return NULL;
1354 }
1355 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1356 if (!s_right) {
1357 fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
1358 g_free(s_right);
1359 return NULL;
1360 }
1361 if (!strcmp(s_right, "UTF8")
1362 || !strcmp(s_right, "utf8")
1363 || !strcmp(s_right, "utf-8")
1364 || !strcmp(s_right, "UTF-8"))
1365 encoding = CTF_STRING_UTF8;
1366 else if (!strcmp(s_right, "ASCII")
1367 || !strcmp(s_right, "ascii"))
1368 encoding = CTF_STRING_ASCII;
b5bf4179
MD
1369 else if (!strcmp(s_right, "none"))
1370 encoding = CTF_STRING_NONE;
81dee1bb
MD
1371 else {
1372 fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
1373 g_free(s_right);
1374 return NULL;
1375 }
1376 g_free(s_right);
73d15916 1377 } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
56e60373 1378 GQuark clock_name;
73d15916
MD
1379
1380 if (right->u.unary_expression.type != UNARY_STRING) {
1381 fprintf(fd, "[error] %s: map: expecting identifier\n",
1382 __func__);
1383 return NULL;
1384 }
56e60373
MD
1385 /* currently only support clock.name.value */
1386 clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
1387 if (!clock_name) {
1388 char *s_right;
1389
1390 s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
1391 if (!s_right) {
1392 fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
1393 g_free(s_right);
1394 return NULL;
1395 }
1396 fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
1397 s_right);
73d15916 1398 g_free(s_right);
56e60373
MD
1399 continue;
1400 }
1401 clock = trace_clock_lookup(trace, clock_name);
1402 if (!clock) {
1403 fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
1404 __func__, g_quark_to_string(clock_name));
73d15916
MD
1405 return NULL;
1406 }
add40b62 1407 } else {
b3ab6665 1408 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
add40b62 1409 __func__, left->u.unary_expression.u.string);
b3ab6665 1410 /* Fall-through after warning */
add40b62 1411 }
05628561 1412 }
add40b62 1413 if (!has_size) {
78af2bcd 1414 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
add40b62
MD
1415 return NULL;
1416 }
ab4cf058
MD
1417 if (!has_alignment) {
1418 if (size % CHAR_BIT) {
1419 /* bit-packed alignment */
1420 alignment = 1;
1421 } else {
1422 /* byte-packed alignment */
1423 alignment = CHAR_BIT;
1424 }
1425 }
add40b62 1426 integer_declaration = integer_declaration_new(size,
81dee1bb 1427 byte_order, signedness, alignment,
56e60373 1428 base, encoding, clock);
add40b62 1429 return &integer_declaration->p;
05628561
MD
1430}
1431
ab4cf058 1432static
8fdba45b 1433struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
3122e6f0 1434 struct bt_list_head *expressions,
ab4cf058
MD
1435 struct ctf_trace *trace)
1436{
a0720417 1437 struct ctf_node *expression;
5c551b40
MD
1438 uint64_t alignment = 1, exp_dig = 0, mant_dig = 0,
1439 byte_order = trace->byte_order;
ab4cf058
MD
1440 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1441 struct declaration_float *float_declaration;
1442
3122e6f0 1443 bt_list_for_each_entry(expression, expressions, siblings) {
a0720417 1444 struct ctf_node *left, *right;
ab4cf058 1445
3122e6f0
JD
1446 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1447 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1448 assert(left->u.unary_expression.type == UNARY_STRING);
1449 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1450 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1451 if (byte_order < 0)
1452 return NULL;
1453 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1454 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1455 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
ab4cf058
MD
1456 __func__);
1457 return NULL;
1458 }
1459 exp_dig = right->u.unary_expression.u.unsigned_constant;
1460 has_exp_dig = 1;
1461 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1462 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1463 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
ab4cf058
MD
1464 __func__);
1465 return NULL;
1466 }
1467 mant_dig = right->u.unary_expression.u.unsigned_constant;
1468 has_mant_dig = 1;
1469 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1470 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1471 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1472 __func__);
1473 return NULL;
1474 }
1475 alignment = right->u.unary_expression.u.unsigned_constant;
53532829
MD
1476 /* Make sure alignment is a power of two */
1477 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
1478 fprintf(fd, "[error] %s: align: expecting power of two\n",
1479 __func__);
1480 return NULL;
1481 }
ab4cf058
MD
1482 has_alignment = 1;
1483 } else {
b3ab6665 1484 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
ab4cf058 1485 __func__, left->u.unary_expression.u.string);
b3ab6665 1486 /* Fall-through after warning */
ab4cf058
MD
1487 }
1488 }
1489 if (!has_mant_dig) {
78af2bcd 1490 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
ab4cf058
MD
1491 return NULL;
1492 }
1493 if (!has_exp_dig) {
78af2bcd 1494 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
ab4cf058
MD
1495 return NULL;
1496 }
1497 if (!has_alignment) {
1498 if ((mant_dig + exp_dig) % CHAR_BIT) {
1499 /* bit-packed alignment */
1500 alignment = 1;
1501 } else {
1502 /* byte-packed alignment */
1503 alignment = CHAR_BIT;
1504 }
1505 }
1506 float_declaration = float_declaration_new(mant_dig, exp_dig,
1507 byte_order, alignment);
1508 return &float_declaration->p;
1509}
1510
1511static
8fdba45b 1512struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
3122e6f0 1513 struct bt_list_head *expressions,
ab4cf058
MD
1514 struct ctf_trace *trace)
1515{
a0720417 1516 struct ctf_node *expression;
ab4cf058
MD
1517 const char *encoding_c = NULL;
1518 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1519 struct declaration_string *string_declaration;
1520
3122e6f0 1521 bt_list_for_each_entry(expression, expressions, siblings) {
a0720417 1522 struct ctf_node *left, *right;
ab4cf058 1523
3122e6f0
JD
1524 left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1525 right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1526 assert(left->u.unary_expression.type == UNARY_STRING);
1527 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
a0720417 1528 if (right->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1529 fprintf(fd, "[error] %s: encoding: expecting string\n",
ab4cf058
MD
1530 __func__);
1531 return NULL;
1532 }
1533 encoding_c = right->u.unary_expression.u.string;
1534 } else {
b3ab6665 1535 fprintf(fd, "[warning] %s: unknown attribute name %s\n",
ab4cf058 1536 __func__, left->u.unary_expression.u.string);
b3ab6665 1537 /* Fall-through after warning */
ab4cf058
MD
1538 }
1539 }
1540 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1541 encoding = CTF_STRING_ASCII;
1542 string_declaration = string_declaration_new(encoding);
1543 return &string_declaration->p;
1544}
1545
1546
05628561 1547static
78af2bcd
MD
1548struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1549 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
1550 struct declaration_scope *declaration_scope,
1551 struct ctf_trace *trace)
05628561 1552{
a0720417 1553 struct ctf_node *first;
78af2bcd 1554 struct ctf_node *node;
d20f5e59 1555
427c09b7
MD
1556 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1557
3122e6f0 1558 first = _bt_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
05628561 1559
78af2bcd
MD
1560 assert(first->type == NODE_TYPE_SPECIFIER);
1561
1562 node = first->u.type_specifier.node;
1563
1564 switch (first->u.type_specifier.type) {
1565 case TYPESPEC_FLOATING_POINT:
1566 return ctf_declaration_floating_point_visit(fd, depth,
1567 &node->u.floating_point.expressions, trace);
1568 case TYPESPEC_INTEGER:
1569 return ctf_declaration_integer_visit(fd, depth,
1570 &node->u.integer.expressions, trace);
1571 case TYPESPEC_STRING:
1572 return ctf_declaration_string_visit(fd, depth,
5039b4cc 1573 &node->u.string.expressions, trace);
78af2bcd 1574 case TYPESPEC_STRUCT:
add40b62 1575 return ctf_declaration_struct_visit(fd, depth,
78af2bcd
MD
1576 node->u._struct.name,
1577 &node->u._struct.declaration_list,
1578 node->u._struct.has_body,
b7e35bad 1579 &node->u._struct.min_align,
ab4cf058
MD
1580 declaration_scope,
1581 trace);
78af2bcd 1582 case TYPESPEC_VARIANT:
add40b62 1583 return ctf_declaration_variant_visit(fd, depth,
78af2bcd
MD
1584 node->u.variant.name,
1585 node->u.variant.choice,
1586 &node->u.variant.declaration_list,
1587 node->u.variant.has_body,
ab4cf058
MD
1588 declaration_scope,
1589 trace);
78af2bcd 1590 case TYPESPEC_ENUM:
add40b62 1591 return ctf_declaration_enum_visit(fd, depth,
78af2bcd
MD
1592 node->u._enum.enum_id,
1593 node->u._enum.container_type,
1594 &node->u._enum.enumerator_list,
1595 node->u._enum.has_body,
1cfda062 1596 declaration_scope,
ab4cf058 1597 trace);
78af2bcd
MD
1598
1599 case TYPESPEC_VOID:
1600 case TYPESPEC_CHAR:
1601 case TYPESPEC_SHORT:
1602 case TYPESPEC_INT:
1603 case TYPESPEC_LONG:
1604 case TYPESPEC_FLOAT:
1605 case TYPESPEC_DOUBLE:
1606 case TYPESPEC_SIGNED:
1607 case TYPESPEC_UNSIGNED:
1608 case TYPESPEC_BOOL:
1609 case TYPESPEC_COMPLEX:
1610 case TYPESPEC_IMAGINARY:
1611 case TYPESPEC_CONST:
1612 case TYPESPEC_ID_TYPE:
add40b62 1613 return ctf_declaration_type_specifier_visit(fd, depth,
78af2bcd 1614 type_specifier_list, declaration_scope);
a0720417 1615 default:
78af2bcd 1616 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
a0720417 1617 return NULL;
add40b62 1618 }
05628561
MD
1619}
1620
1621static
4716614a 1622int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event_declaration *event, struct ctf_trace *trace)
05628561
MD
1623{
1624 int ret = 0;
1625
1626 switch (node->type) {
1627 case NODE_TYPEDEF:
1628 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1629 event->declaration_scope,
78af2bcd 1630 node->u._typedef.type_specifier_list,
05628561 1631 &node->u._typedef.type_declarators,
a0720417 1632 trace);
05628561
MD
1633 if (ret)
1634 return ret;
1635 break;
1636 case NODE_TYPEALIAS:
1637 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1638 event->declaration_scope,
1639 node->u.typealias.target, node->u.typealias.alias,
1640 trace);
05628561
MD
1641 if (ret)
1642 return ret;
1643 break;
1644 case NODE_CTF_EXPRESSION:
1645 {
1646 char *left;
1647
1648 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1649 if (!strcmp(left, "name")) {
1650 char *right;
1651
427c09b7
MD
1652 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1653 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
0f980a35
MD
1654 ret = -EPERM;
1655 goto error;
427c09b7 1656 }
05628561
MD
1657 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1658 if (!right) {
78af2bcd 1659 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
0f980a35
MD
1660 ret = -EINVAL;
1661 goto error;
05628561
MD
1662 }
1663 event->name = g_quark_from_string(right);
41253107 1664 g_free(right);
05628561
MD
1665 CTF_EVENT_SET_FIELD(event, name);
1666 } else if (!strcmp(left, "id")) {
427c09b7
MD
1667 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1668 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
0f980a35
MD
1669 ret = -EPERM;
1670 goto error;
427c09b7 1671 }
05628561
MD
1672 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1673 if (ret) {
78af2bcd 1674 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
0f980a35
MD
1675 ret = -EINVAL;
1676 goto error;
05628561
MD
1677 }
1678 CTF_EVENT_SET_FIELD(event, id);
1679 } else if (!strcmp(left, "stream_id")) {
427c09b7
MD
1680 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1681 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
0f980a35
MD
1682 ret = -EPERM;
1683 goto error;
427c09b7 1684 }
05628561
MD
1685 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1686 if (ret) {
78af2bcd 1687 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
0f980a35
MD
1688 ret = -EINVAL;
1689 goto error;
05628561
MD
1690 }
1691 event->stream = trace_stream_lookup(trace, event->stream_id);
1692 if (!event->stream) {
78af2bcd 1693 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
0f980a35
MD
1694 ret = -EINVAL;
1695 goto error;
05628561 1696 }
05628561
MD
1697 CTF_EVENT_SET_FIELD(event, stream_id);
1698 } else if (!strcmp(left, "context")) {
1699 struct declaration *declaration;
1700
427c09b7
MD
1701 if (event->context_decl) {
1702 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
0f980a35
MD
1703 ret = -EINVAL;
1704 goto error;
427c09b7 1705 }
78af2bcd 1706 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 1707 _bt_list_first_entry(&node->u.ctf_expression.right,
78af2bcd 1708 struct ctf_node, siblings),
ab4cf058 1709 event->declaration_scope, trace);
0f980a35
MD
1710 if (!declaration) {
1711 ret = -EPERM;
1712 goto error;
1713 }
1714 if (declaration->id != CTF_TYPE_STRUCT) {
1715 ret = -EPERM;
1716 goto error;
1717 }
9e29e16e 1718 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1719 } else if (!strcmp(left, "fields")) {
1720 struct declaration *declaration;
1721
427c09b7
MD
1722 if (event->fields_decl) {
1723 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
0f980a35
MD
1724 ret = -EINVAL;
1725 goto error;
427c09b7 1726 }
78af2bcd 1727 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 1728 _bt_list_first_entry(&node->u.ctf_expression.right,
78af2bcd 1729 struct ctf_node, siblings),
ab4cf058 1730 event->declaration_scope, trace);
0f980a35
MD
1731 if (!declaration) {
1732 ret = -EPERM;
1733 goto error;
1734 }
1735 if (declaration->id != CTF_TYPE_STRUCT) {
1736 ret = -EPERM;
1737 goto error;
1738 }
9e29e16e 1739 event->fields_decl = container_of(declaration, struct declaration_struct, p);
306eeaa6
MD
1740 } else if (!strcmp(left, "loglevel")) {
1741 int64_t loglevel = -1;
d86d62f8 1742
306eeaa6
MD
1743 if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
1744 fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
d86d62f8
MD
1745 ret = -EPERM;
1746 goto error;
1747 }
306eeaa6 1748 ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
d86d62f8 1749 if (ret) {
306eeaa6 1750 fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
d86d62f8
MD
1751 ret = -EINVAL;
1752 goto error;
1753 }
209209be 1754 event->loglevel = (int) loglevel;
306eeaa6 1755 CTF_EVENT_SET_FIELD(event, loglevel);
f6714e20
MD
1756 } else if (!strcmp(left, "model.emf.uri")) {
1757 char *right;
1758
1759 if (CTF_EVENT_FIELD_IS_SET(event, model_emf_uri)) {
1760 fprintf(fd, "[error] %s: model.emf.uri already declared in event declaration\n", __func__);
1761 ret = -EPERM;
1762 goto error;
1763 }
1764 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1765 if (!right) {
1766 fprintf(fd, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__);
1767 ret = -EINVAL;
1768 goto error;
1769 }
1770 event->model_emf_uri = g_quark_from_string(right);
1771 g_free(right);
1772 CTF_EVENT_SET_FIELD(event, model_emf_uri);
98df1c9f 1773 } else {
b3ab6665
MD
1774 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
1775 /* Fall-through after warning */
05628561 1776 }
0f980a35 1777error:
41253107 1778 g_free(left);
05628561
MD
1779 break;
1780 }
1781 default:
1782 return -EPERM;
1783 /* TODO: declaration specifier should be added. */
1784 }
1785
0f980a35 1786 return ret;
05628561
MD
1787}
1788
1789static
1790int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1791 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1792{
1793 int ret = 0;
1794 struct ctf_node *iter;
4716614a 1795 struct ctf_event_declaration *event;
e003ab50 1796 struct bt_ctf_event_decl *event_decl;
05628561 1797
e003ab50
JD
1798 event_decl = g_new0(struct bt_ctf_event_decl, 1);
1799 event = &event_decl->parent;
d20f5e59 1800 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
306eeaa6 1801 event->loglevel = -1;
3122e6f0 1802 bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
05628561
MD
1803 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1804 if (ret)
1805 goto error;
1806 }
1807 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1808 ret = -EPERM;
427c09b7 1809 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
05628561
MD
1810 goto error;
1811 }
05628561 1812 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
0f980a35 1813 /* Allow missing stream_id if there is only a single stream */
33105c61
MD
1814 switch (trace->streams->len) {
1815 case 0: /* Create stream if there was none. */
1816 ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
1817 if (ret)
1818 goto error;
1819 /* Fall-through */
1820 case 1:
0f980a35
MD
1821 event->stream_id = 0;
1822 event->stream = trace_stream_lookup(trace, event->stream_id);
33105c61
MD
1823 break;
1824 default:
0f980a35
MD
1825 ret = -EPERM;
1826 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1827 goto error;
1828 }
05628561 1829 }
8c572eba
MD
1830 /* Allow only one event without id per stream */
1831 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1832 && event->stream->events_by_id->len != 0) {
1833 ret = -EPERM;
1834 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
1835 goto error;
1836 }
05628561
MD
1837 if (event->stream->events_by_id->len <= event->id)
1838 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1839 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1840 g_hash_table_insert(event->stream->event_quark_to_id,
56e60373 1841 (gpointer) (unsigned long) event->name,
05628561 1842 &event->id);
e003ab50 1843 g_ptr_array_add(trace->event_declarations, event_decl);
05628561
MD
1844 return 0;
1845
1846error:
98df1c9f
MD
1847 if (event->fields_decl)
1848 declaration_unref(&event->fields_decl->p);
1849 if (event->context_decl)
1850 declaration_unref(&event->context_decl->p);
d20f5e59 1851 free_declaration_scope(event->declaration_scope);
e003ab50 1852 g_free(event_decl);
05628561
MD
1853 return ret;
1854}
1855
1856
1857static
f380e105 1858int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream, struct ctf_trace *trace)
05628561
MD
1859{
1860 int ret = 0;
1861
1862 switch (node->type) {
1863 case NODE_TYPEDEF:
1864 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1865 stream->declaration_scope,
78af2bcd 1866 node->u._typedef.type_specifier_list,
05628561 1867 &node->u._typedef.type_declarators,
a0720417 1868 trace);
05628561
MD
1869 if (ret)
1870 return ret;
1871 break;
1872 case NODE_TYPEALIAS:
1873 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1874 stream->declaration_scope,
1875 node->u.typealias.target, node->u.typealias.alias,
1876 trace);
05628561
MD
1877 if (ret)
1878 return ret;
1879 break;
1880 case NODE_CTF_EXPRESSION:
1881 {
1882 char *left;
1883
1884 left = concatenate_unary_strings(&node->u.ctf_expression.left);
427c09b7
MD
1885 if (!strcmp(left, "id")) {
1886 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1887 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
0f980a35
MD
1888 ret = -EPERM;
1889 goto error;
427c09b7 1890 }
a0720417 1891 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
05628561 1892 if (ret) {
427c09b7 1893 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
0f980a35
MD
1894 ret = -EINVAL;
1895 goto error;
05628561 1896 }
a0720417 1897 CTF_STREAM_SET_FIELD(stream, stream_id);
9e29e16e 1898 } else if (!strcmp(left, "event.header")) {
05628561
MD
1899 struct declaration *declaration;
1900
427c09b7
MD
1901 if (stream->event_header_decl) {
1902 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
0f980a35
MD
1903 ret = -EINVAL;
1904 goto error;
427c09b7 1905 }
78af2bcd 1906 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 1907 _bt_list_first_entry(&node->u.ctf_expression.right,
78af2bcd 1908 struct ctf_node, siblings),
a0720417 1909 stream->declaration_scope, trace);
0f980a35
MD
1910 if (!declaration) {
1911 ret = -EPERM;
1912 goto error;
1913 }
1914 if (declaration->id != CTF_TYPE_STRUCT) {
1915 ret = -EPERM;
1916 goto error;
1917 }
9e29e16e
MD
1918 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1919 } else if (!strcmp(left, "event.context")) {
05628561
MD
1920 struct declaration *declaration;
1921
427c09b7
MD
1922 if (stream->event_context_decl) {
1923 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
0f980a35
MD
1924 ret = -EINVAL;
1925 goto error;
427c09b7 1926 }
78af2bcd 1927 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 1928 _bt_list_first_entry(&node->u.ctf_expression.right,
78af2bcd 1929 struct ctf_node, siblings),
ab4cf058 1930 stream->declaration_scope, trace);
0f980a35
MD
1931 if (!declaration) {
1932 ret = -EPERM;
1933 goto error;
1934 }
1935 if (declaration->id != CTF_TYPE_STRUCT) {
1936 ret = -EPERM;
1937 goto error;
1938 }
9e29e16e
MD
1939 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1940 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1941 struct declaration *declaration;
1942
427c09b7
MD
1943 if (stream->packet_context_decl) {
1944 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
0f980a35
MD
1945 ret = -EINVAL;
1946 goto error;
427c09b7 1947 }
78af2bcd 1948 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 1949 _bt_list_first_entry(&node->u.ctf_expression.right,
78af2bcd 1950 struct ctf_node, siblings),
ab4cf058 1951 stream->declaration_scope, trace);
0f980a35
MD
1952 if (!declaration) {
1953 ret = -EPERM;
1954 goto error;
1955 }
1956 if (declaration->id != CTF_TYPE_STRUCT) {
1957 ret = -EPERM;
1958 goto error;
1959 }
9e29e16e 1960 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f 1961 } else {
b3ab6665
MD
1962 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
1963 /* Fall-through after warning */
05628561 1964 }
98df1c9f 1965
0f980a35 1966error:
41253107 1967 g_free(left);
05628561
MD
1968 break;
1969 }
1970 default:
1971 return -EPERM;
1972 /* TODO: declaration specifier should be added. */
1973 }
1974
0f980a35 1975 return ret;
05628561
MD
1976}
1977
1978static
1979int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1980 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1981{
1982 int ret = 0;
1983 struct ctf_node *iter;
f380e105 1984 struct ctf_stream_declaration *stream;
05628561 1985
f380e105 1986 stream = g_new0(struct ctf_stream_declaration, 1);
d20f5e59 1987 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561 1988 stream->events_by_id = g_ptr_array_new();
068665f5 1989 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
2d0bea29 1990 stream->streams = g_ptr_array_new();
33105c61 1991 if (node) {
3122e6f0 1992 bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
33105c61
MD
1993 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1994 if (ret)
1995 goto error;
1996 }
05628561 1997 }
0f980a35
MD
1998 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1999 /* check that packet header has stream_id field. */
2000 if (!trace->packet_header_decl
2001 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
2002 ret = -EPERM;
2003 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
2004 goto error;
2005 }
8c572eba
MD
2006 } else {
2007 /* Allow only one id-less stream */
2008 if (trace->streams->len != 0) {
2009 ret = -EPERM;
2010 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
2011 goto error;
2012 }
2013 stream->stream_id = 0;
05628561
MD
2014 }
2015 if (trace->streams->len <= stream->stream_id)
2016 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
2017 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
82662ad4 2018 stream->trace = trace;
9e29e16e 2019
05628561
MD
2020 return 0;
2021
2022error:
98df1c9f
MD
2023 if (stream->event_header_decl)
2024 declaration_unref(&stream->event_header_decl->p);
2025 if (stream->event_context_decl)
2026 declaration_unref(&stream->event_context_decl->p);
2027 if (stream->packet_context_decl)
2028 declaration_unref(&stream->packet_context_decl->p);
2d0bea29 2029 g_ptr_array_free(stream->streams, TRUE);
05628561 2030 g_ptr_array_free(stream->events_by_id, TRUE);
a0720417 2031 g_hash_table_destroy(stream->event_quark_to_id);
d20f5e59 2032 free_declaration_scope(stream->declaration_scope);
05628561
MD
2033 g_free(stream);
2034 return ret;
2035}
2036
2037static
2038int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2039{
2040 int ret = 0;
2041
2042 switch (node->type) {
2043 case NODE_TYPEDEF:
2044 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 2045 trace->declaration_scope,
78af2bcd 2046 node->u._typedef.type_specifier_list,
05628561 2047 &node->u._typedef.type_declarators,
a0720417 2048 trace);
05628561
MD
2049 if (ret)
2050 return ret;
2051 break;
2052 case NODE_TYPEALIAS:
2053 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
2054 trace->declaration_scope,
2055 node->u.typealias.target, node->u.typealias.alias,
2056 trace);
05628561
MD
2057 if (ret)
2058 return ret;
2059 break;
2060 case NODE_CTF_EXPRESSION:
2061 {
2062 char *left;
2063
2064 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2065 if (!strcmp(left, "major")) {
427c09b7
MD
2066 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
2067 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
0f980a35
MD
2068 ret = -EPERM;
2069 goto error;
427c09b7 2070 }
05628561
MD
2071 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
2072 if (ret) {
78af2bcd 2073 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
0f980a35
MD
2074 ret = -EINVAL;
2075 goto error;
05628561 2076 }
a0720417 2077 CTF_TRACE_SET_FIELD(trace, major);
05628561 2078 } else if (!strcmp(left, "minor")) {
427c09b7
MD
2079 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
2080 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
0f980a35
MD
2081 ret = -EPERM;
2082 goto error;
427c09b7 2083 }
05628561
MD
2084 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
2085 if (ret) {
78af2bcd 2086 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
0f980a35
MD
2087 ret = -EINVAL;
2088 goto error;
05628561 2089 }
a0720417 2090 CTF_TRACE_SET_FIELD(trace, minor);
05628561 2091 } else if (!strcmp(left, "uuid")) {
bf81a25e 2092 unsigned char uuid[BABELTRACE_UUID_LEN];
a0fe7d97 2093
bf81a25e 2094 ret = get_unary_uuid(&node->u.ctf_expression.right, uuid);
05628561 2095 if (ret) {
78af2bcd 2096 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
0f980a35
MD
2097 ret = -EINVAL;
2098 goto error;
05628561 2099 }
b4c19c1e 2100 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
a4dfa07b 2101 && babeltrace_uuid_compare(uuid, trace->uuid)) {
b4c19c1e
MD
2102 fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
2103 ret = -EPERM;
2104 goto error;
a0fe7d97
MD
2105 } else {
2106 memcpy(trace->uuid, uuid, sizeof(uuid));
b4c19c1e 2107 }
a0720417 2108 CTF_TRACE_SET_FIELD(trace, uuid);
0f980a35
MD
2109 } else if (!strcmp(left, "byte_order")) {
2110 struct ctf_node *right;
2111 int byte_order;
2112
3122e6f0 2113 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
0f980a35
MD
2114 byte_order = get_trace_byte_order(fd, depth, right);
2115 if (byte_order < 0)
2116 return -EINVAL;
a0fe7d97
MD
2117
2118 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
2119 && byte_order != trace->byte_order) {
2120 fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
2121 ret = -EPERM;
2122 goto error;
2123 } else {
fdce39de
MD
2124 if (byte_order != trace->byte_order) {
2125 trace->byte_order = byte_order;
2126 /*
2127 * We need to restart
2128 * construction of the
2129 * intermediate representation.
2130 */
2e0c6b58
MD
2131 trace->field_mask = 0;
2132 CTF_TRACE_SET_FIELD(trace, byte_order);
2133 ret = -EINTR;
2134 goto error;
fdce39de 2135 }
a0fe7d97 2136 }
7c8a1386 2137 CTF_TRACE_SET_FIELD(trace, byte_order);
0f980a35
MD
2138 } else if (!strcmp(left, "packet.header")) {
2139 struct declaration *declaration;
2140
2141 if (trace->packet_header_decl) {
2142 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
2143 ret = -EINVAL;
2144 goto error;
2145 }
2146 declaration = ctf_type_specifier_list_visit(fd, depth,
3122e6f0 2147 _bt_list_first_entry(&node->u.ctf_expression.right,
0f980a35
MD
2148 struct ctf_node, siblings),
2149 trace->declaration_scope, trace);
2150 if (!declaration) {
2151 ret = -EPERM;
2152 goto error;
2153 }
2154 if (declaration->id != CTF_TYPE_STRUCT) {
2155 ret = -EPERM;
2156 goto error;
2157 }
2158 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
98df1c9f 2159 } else {
b3ab6665 2160 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
05628561 2161 }
98df1c9f 2162
0f980a35 2163error:
41253107 2164 g_free(left);
05628561
MD
2165 break;
2166 }
2167 default:
2168 return -EPERM;
2169 /* TODO: declaration specifier should be added. */
2170 }
2171
0f980a35 2172 return ret;
05628561
MD
2173}
2174
05628561
MD
2175static
2176int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2177{
2178 int ret = 0;
2179 struct ctf_node *iter;
2180
d20f5e59 2181 if (trace->declaration_scope)
05628561 2182 return -EEXIST;
d20f5e59 2183 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
05628561 2184 trace->streams = g_ptr_array_new();
e003ab50 2185 trace->event_declarations = g_ptr_array_new();
3122e6f0 2186 bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
05628561
MD
2187 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
2188 if (ret)
2189 goto error;
2190 }
a0720417 2191 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
05628561 2192 ret = -EPERM;
427c09b7 2193 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
05628561
MD
2194 goto error;
2195 }
a0720417 2196 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
05628561 2197 ret = -EPERM;
427c09b7 2198 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
05628561
MD
2199 goto error;
2200 }
dc48ecad
MD
2201 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2202 ret = -EPERM;
2203 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
2204 goto error;
2205 }
0f980a35 2206
0f980a35
MD
2207 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
2208 /* check that the packet header contains a "magic" field */
e28d4618 2209 if (!trace->packet_header_decl
0f980a35
MD
2210 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
2211 ret = -EPERM;
2212 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
98df1c9f 2213 goto error;
0f980a35
MD
2214 }
2215 }
05628561
MD
2216 return 0;
2217
2218error:
0d72513f 2219 if (trace->packet_header_decl) {
98df1c9f 2220 declaration_unref(&trace->packet_header_decl->p);
0d72513f
MD
2221 trace->packet_header_decl = NULL;
2222 }
05628561 2223 g_ptr_array_free(trace->streams, TRUE);
e003ab50 2224 g_ptr_array_free(trace->event_declarations, TRUE);
a0720417 2225 free_declaration_scope(trace->declaration_scope);
fdce39de 2226 trace->declaration_scope = NULL;
05628561
MD
2227 return ret;
2228}
2229
50cb9c56
MD
2230static
2231int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2232 struct ctf_clock *clock, struct ctf_trace *trace)
2233{
2234 int ret = 0;
2235
2236 switch (node->type) {
2237 case NODE_CTF_EXPRESSION:
2238 {
2239 char *left;
2240
2241 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2242 if (!strcmp(left, "name")) {
2243 char *right;
2244
2245 if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2246 fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
2247 ret = -EPERM;
2248 goto error;
2249 }
2250 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2251 if (!right) {
2252 fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
2253 ret = -EINVAL;
2254 goto error;
2255 }
2256 clock->name = g_quark_from_string(right);
2257 g_free(right);
bf94ab2b 2258 CTF_CLOCK_SET_FIELD(clock, name);
50cb9c56
MD
2259 } else if (!strcmp(left, "uuid")) {
2260 char *right;
2261
2262 if (clock->uuid) {
2263 fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
2264 ret = -EPERM;
2265 goto error;
2266 }
2267 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2268 if (!right) {
2269 fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
2270 ret = -EINVAL;
2271 goto error;
2272 }
2273 clock->uuid = g_quark_from_string(right);
2274 g_free(right);
2275 } else if (!strcmp(left, "description")) {
2276 char *right;
2277
2278 if (clock->description) {
2279 fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
2280 goto error; /* ret is 0, so not an actual error, just warn. */
2281 }
2282 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2283 if (!right) {
2284 fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
2285 goto error; /* ret is 0, so not an actual error, just warn. */
2286 }
2287 clock->description = right;
2288 } else if (!strcmp(left, "freq")) {
bf94ab2b 2289 if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
50cb9c56
MD
2290 fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
2291 ret = -EPERM;
2292 goto error;
2293 }
2294 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
2295 if (ret) {
2296 fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
2297 ret = -EINVAL;
2298 goto error;
2299 }
bf94ab2b 2300 CTF_CLOCK_SET_FIELD(clock, freq);
50cb9c56
MD
2301 } else if (!strcmp(left, "precision")) {
2302 if (clock->precision) {
2303 fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
2304 ret = -EPERM;
2305 goto error;
2306 }
2307 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
2308 if (ret) {
2309 fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
2310 ret = -EINVAL;
2311 goto error;
2312 }
2313 } else if (!strcmp(left, "offset_s")) {
2314 if (clock->offset_s) {
2315 fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
2316 ret = -EPERM;
2317 goto error;
2318 }
2319 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset_s);
2320 if (ret) {
2321 fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
2322 ret = -EINVAL;
2323 goto error;
2324 }
2325 } else if (!strcmp(left, "offset")) {
2326 if (clock->offset) {
2327 fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
2328 ret = -EPERM;
2329 goto error;
2330 }
2331 ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->offset);
2332 if (ret) {
2333 fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
2334 ret = -EINVAL;
2335 goto error;
2336 }
11ac6674
MD
2337 } else if (!strcmp(left, "absolute")) {
2338 struct ctf_node *right;
2339
3122e6f0 2340 right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
11ac6674
MD
2341 ret = get_boolean(fd, depth, right);
2342 if (ret < 0) {
2343 fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
2344 ret = -EINVAL;
2345 goto error;
2346 }
2347 clock->absolute = ret;
50cb9c56
MD
2348 } else {
2349 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
2350 }
2351
2352error:
2353 g_free(left);
2354 break;
2355 }
2356 default:
2357 return -EPERM;
2358 /* TODO: declaration specifier should be added. */
2359 }
2360
2361 return ret;
2362}
2363
2364static
2365int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2366{
2367 int ret = 0;
2368 struct ctf_node *iter;
2369 struct ctf_clock *clock;
2370
2371 clock = g_new0(struct ctf_clock, 1);
25ccc85b
MD
2372 /* Default clock frequency is set to 1000000000 */
2373 clock->freq = 1000000000ULL;
3122e6f0 2374 bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
50cb9c56
MD
2375 ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
2376 if (ret)
2377 goto error;
2378 }
82ace6d6
MD
2379 if (opt_clock_force_correlate) {
2380 /*
2381 * User requested to forcibly correlate the clock
2382 * sources, even if we have no correlatation
2383 * information.
2384 */
2385 if (!clock->absolute) {
2386 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2387 }
2388 clock->absolute = 1;
2389 }
50cb9c56
MD
2390 if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
2391 ret = -EPERM;
50052405 2392 fprintf(fd, "[error] %s: missing name field in clock declaration\n", __func__);
50cb9c56
MD
2393 goto error;
2394 }
25ccc85b 2395 if (g_hash_table_size(trace->clocks) > 0) {
82ace6d6 2396 fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
25ccc85b
MD
2397 ret = -EINVAL;
2398 goto error;
2399 }
2400 trace->single_clock = clock;
50cb9c56
MD
2401 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2402 return 0;
2403
2404error:
2405 g_free(clock->description);
2406 g_free(clock);
2407 return ret;
2408}
2409
f57447bd
JN
2410static
2411void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
2412{
2413 struct ctf_clock *clock;
2414
2415 clock = g_new0(struct ctf_clock, 1);
2416 clock->name = g_quark_from_string("monotonic");
2417 clock->uuid = 0;
2418 clock->description = g_strdup("Default clock");
2419 /* Default clock frequency is set to 1000000000 */
2420 clock->freq = 1000000000ULL;
82ace6d6
MD
2421 if (opt_clock_force_correlate) {
2422 /*
2423 * User requested to forcibly correlate the clock
2424 * sources, even if we have no correlatation
2425 * information.
2426 */
2427 if (!clock->absolute) {
2428 fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
2429 }
2430 clock->absolute = 1;
2431 } else {
2432 clock->absolute = 0; /* Not an absolute reference across traces */
2433 }
f57447bd
JN
2434
2435 trace->single_clock = clock;
2436 g_hash_table_insert(trace->clocks, (gpointer) (unsigned long) clock->name, clock);
2437}
2438
50cb9c56
MD
2439static
2440void clock_free(gpointer data)
2441{
2442 struct ctf_clock *clock = data;
2443
2444 g_free(clock->description);
2445 g_free(clock);
2446}
2447
f133896d
MD
2448static
2449int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2450 struct ctf_callsite *callsite, struct ctf_trace *trace)
2451{
2452 int ret = 0;
2453
2454 switch (node->type) {
2455 case NODE_CTF_EXPRESSION:
2456 {
2457 char *left;
2458
2459 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2460 if (!strcmp(left, "name")) {
2461 char *right;
2462
2463 if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2464 fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__);
2465 ret = -EPERM;
2466 goto error;
2467 }
2468 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2469 if (!right) {
2470 fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__);
2471 ret = -EINVAL;
2472 goto error;
2473 }
2474 callsite->name = g_quark_from_string(right);
2475 g_free(right);
2476 CTF_CALLSITE_SET_FIELD(callsite, name);
2477 } else if (!strcmp(left, "func")) {
2478 char *right;
2479
2480 if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2481 fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__);
2482 ret = -EPERM;
2483 goto error;
2484 }
2485 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2486 if (!right) {
2487 fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__);
2488 ret = -EINVAL;
2489 goto error;
2490 }
2491 callsite->func = right;
2492 CTF_CALLSITE_SET_FIELD(callsite, func);
2493 } else if (!strcmp(left, "file")) {
2494 char *right;
2495
2496 if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2497 fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__);
2498 ret = -EPERM;
2499 goto error;
2500 }
2501 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2502 if (!right) {
2503 fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__);
2504 ret = -EINVAL;
2505 goto error;
2506 }
2507 callsite->file = right;
2508 CTF_CALLSITE_SET_FIELD(callsite, file);
2509 } else if (!strcmp(left, "line")) {
2510 if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2511 fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__);
2512 ret = -EPERM;
2513 goto error;
2514 }
2515 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line);
2516 if (ret) {
2517 fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__);
2518 ret = -EINVAL;
2519 goto error;
2520 }
2521 CTF_CALLSITE_SET_FIELD(callsite, line);
b448902b
MD
2522 } else if (!strcmp(left, "ip")) {
2523 if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) {
2524 fprintf(fd, "[error] %s: ip already declared in callsite declaration\n", __func__);
2525 ret = -EPERM;
2526 goto error;
2527 }
2528 ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->ip);
2529 if (ret) {
2530 fprintf(fd, "[error] %s: unexpected unary expression for callsite ip\n", __func__);
2531 ret = -EINVAL;
2532 goto error;
2533 }
2534 CTF_CALLSITE_SET_FIELD(callsite, ip);
f133896d
MD
2535 } else {
2536 fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left);
2537 }
2538
2539error:
2540 g_free(left);
2541 break;
2542 }
2543 default:
2544 return -EPERM;
2545 /* TODO: declaration specifier should be added. */
2546 }
2547
2548 return ret;
2549}
2550
2551static
2552int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2553{
2554 int ret = 0;
2555 struct ctf_node *iter;
2556 struct ctf_callsite *callsite;
c5ff71a3 2557 struct ctf_callsite_dups *cs_dups;
f133896d
MD
2558
2559 callsite = g_new0(struct ctf_callsite, 1);
2560 bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
2561 ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace);
2562 if (ret)
2563 goto error;
2564 }
2565 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
2566 ret = -EPERM;
2567 fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__);
2568 goto error;
2569 }
2570 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
2571 ret = -EPERM;
2572 fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__);
2573 goto error;
2574 }
2575 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
2576 ret = -EPERM;
2577 fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__);
2578 goto error;
2579 }
2580 if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
2581 ret = -EPERM;
2582 fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__);
2583 goto error;
2584 }
2585
c5ff71a3
MD
2586 cs_dups = g_hash_table_lookup(trace->callsites,
2587 (gpointer) (unsigned long) callsite->name);
2588 if (!cs_dups) {
2589 cs_dups = g_new0(struct ctf_callsite_dups, 1);
2590 BT_INIT_LIST_HEAD(&cs_dups->head);
2591 g_hash_table_insert(trace->callsites,
2592 (gpointer) (unsigned long) callsite->name, cs_dups);
2593 }
2594 bt_list_add_tail(&callsite->node, &cs_dups->head);
f133896d
MD
2595 return 0;
2596
2597error:
2598 g_free(callsite->func);
2599 g_free(callsite->file);
2600 g_free(callsite);
2601 return ret;
2602}
2603
2604static
2605void callsite_free(gpointer data)
2606{
c5ff71a3
MD
2607 struct ctf_callsite_dups *cs_dups = data;
2608 struct ctf_callsite *callsite, *cs_n;
f133896d 2609
c5ff71a3
MD
2610 bt_list_for_each_entry_safe(callsite, cs_n, &cs_dups->head, node) {
2611 g_free(callsite->func);
2612 g_free(callsite->file);
2613 g_free(callsite);
2614 }
98ef2474 2615 g_free(cs_dups);
f133896d
MD
2616}
2617
cadd09e9
MD
2618static
2619int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
2620 struct ctf_trace *trace)
2621{
2622 int ret = 0;
2623 struct ctf_tracer_env *env = &trace->env;
2624
2625 switch (node->type) {
2626 case NODE_CTF_EXPRESSION:
2627 {
2628 char *left;
2629
2630 left = concatenate_unary_strings(&node->u.ctf_expression.left);
2631 if (!strcmp(left, "vpid")) {
2632 uint64_t v;
2633
2634 if (env->vpid != -1) {
2635 fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
2636 goto error; /* ret is 0, so not an actual error, just warn. */
2637 }
2638 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2639 if (ret) {
2640 fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
2641 goto error; /* ret is 0, so not an actual error, just warn. */
2642 }
2643 env->vpid = (int) v;
6070d2f1 2644 printf_verbose("env.vpid = %d\n", env->vpid);
cadd09e9
MD
2645 } else if (!strcmp(left, "procname")) {
2646 char *right;
2647
2648 if (env->procname[0]) {
2649 fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
2650 goto error; /* ret is 0, so not an actual error, just warn. */
2651 }
2652 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2653 if (!right) {
2654 fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
2655 goto error; /* ret is 0, so not an actual error, just warn. */
2656 }
2657 strncpy(env->procname, right, TRACER_ENV_LEN);
2658 env->procname[TRACER_ENV_LEN - 1] = '\0';
127631b1 2659 printf_verbose("env.procname = \"%s\"\n", env->procname);
15d4fe3c 2660 g_free(right);
32cfb8ad
MD
2661 } else if (!strcmp(left, "hostname")) {
2662 char *right;
2663
2664 if (env->hostname[0]) {
2665 fprintf(fd, "[warning] %s: duplicated env hostname\n", __func__);
2666 goto error; /* ret is 0, so not an actual error, just warn. */
2667 }
2668 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2669 if (!right) {
2670 fprintf(fd, "[warning] %s: unexpected unary expression for env hostname\n", __func__);
2671 goto error; /* ret is 0, so not an actual error, just warn. */
2672 }
2673 strncpy(env->hostname, right, TRACER_ENV_LEN);
2674 env->hostname[TRACER_ENV_LEN - 1] = '\0';
2675 printf_verbose("env.hostname = \"%s\"\n", env->hostname);
15d4fe3c 2676 g_free(right);
cadd09e9
MD
2677 } else if (!strcmp(left, "domain")) {
2678 char *right;
2679
2680 if (env->domain[0]) {
2681 fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
2682 goto error; /* ret is 0, so not an actual error, just warn. */
2683 }
2684 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2685 if (!right) {
2686 fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
2687 goto error; /* ret is 0, so not an actual error, just warn. */
2688 }
2689 strncpy(env->domain, right, TRACER_ENV_LEN);
2690 env->domain[TRACER_ENV_LEN - 1] = '\0';
127631b1 2691 printf_verbose("env.domain = \"%s\"\n", env->domain);
15d4fe3c 2692 g_free(right);
cadd09e9
MD
2693 } else if (!strcmp(left, "sysname")) {
2694 char *right;
2695
2696 if (env->sysname[0]) {
2697 fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
2698 goto error; /* ret is 0, so not an actual error, just warn. */
2699 }
2700 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2701 if (!right) {
2702 fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
2703 goto error; /* ret is 0, so not an actual error, just warn. */
2704 }
2705 strncpy(env->sysname, right, TRACER_ENV_LEN);
2706 env->sysname[TRACER_ENV_LEN - 1] = '\0';
127631b1 2707 printf_verbose("env.sysname = \"%s\"\n", env->sysname);
15d4fe3c 2708 g_free(right);
127631b1 2709 } else if (!strcmp(left, "kernel_release")) {
cadd09e9
MD
2710 char *right;
2711
2712 if (env->release[0]) {
2713 fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
2714 goto error; /* ret is 0, so not an actual error, just warn. */
2715 }
2716 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2717 if (!right) {
2718 fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
2719 goto error; /* ret is 0, so not an actual error, just warn. */
2720 }
2721 strncpy(env->release, right, TRACER_ENV_LEN);
2722 env->release[TRACER_ENV_LEN - 1] = '\0';
127631b1 2723 printf_verbose("env.release = \"%s\"\n", env->release);
15d4fe3c 2724 g_free(right);
127631b1 2725 } else if (!strcmp(left, "kernel_version")) {
cadd09e9
MD
2726 char *right;
2727
2728 if (env->version[0]) {
2729 fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
2730 goto error; /* ret is 0, so not an actual error, just warn. */
2731 }
2732 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2733 if (!right) {
2734 fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
2735 goto error; /* ret is 0, so not an actual error, just warn. */
2736 }
2737 strncpy(env->version, right, TRACER_ENV_LEN);
2738 env->version[TRACER_ENV_LEN - 1] = '\0';
127631b1 2739 printf_verbose("env.version = \"%s\"\n", env->version);
15d4fe3c 2740 g_free(right);
cadd09e9 2741 } else {
127631b1
MD
2742 if (is_unary_string(&node->u.ctf_expression.right)) {
2743 char *right;
2744
2745 right = concatenate_unary_strings(&node->u.ctf_expression.right);
2746 printf_verbose("env.%s = \"%s\"\n", left, right);
15d4fe3c 2747 g_free(right);
127631b1
MD
2748 } else if (is_unary_unsigned(&node->u.ctf_expression.right)) {
2749 uint64_t v;
2750 int ret;
2751
2752 ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
2753 assert(ret == 0);
2754 printf_verbose("env.%s = %" PRIu64 "\n", left, v);
2755 } else if (is_unary_signed(&node->u.ctf_expression.right)) {
2756 int64_t v;
2757 int ret;
2758
2759 ret = get_unary_signed(&node->u.ctf_expression.right, &v);
2760 assert(ret == 0);
2761 printf_verbose("env.%s = %" PRId64 "\n", left, v);
2762 } else {
2763 printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__, left);
2764 }
cadd09e9
MD
2765 }
2766
2767error:
2768 g_free(left);
2769 break;
2770 }
2771 default:
2772 return -EPERM;
2773 }
2774
2775 return ret;
2776}
2777
e2c76a4d
MD
2778static
2779int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2780{
cadd09e9
MD
2781 int ret = 0;
2782 struct ctf_node *iter;
2783
2784 trace->env.vpid = -1;
2785 trace->env.procname[0] = '\0';
32cfb8ad 2786 trace->env.hostname[0] = '\0';
cadd09e9
MD
2787 trace->env.domain[0] = '\0';
2788 trace->env.sysname[0] = '\0';
2789 trace->env.release[0] = '\0';
2790 trace->env.version[0] = '\0';
3122e6f0 2791 bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
cadd09e9
MD
2792 ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
2793 if (ret)
2794 goto error;
2795 }
2796error:
2797 return 0;
e2c76a4d
MD
2798}
2799
78af2bcd
MD
2800static
2801int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
2802{
2803 int ret = 0;
2804
2805 switch (node->type) {
2806 case NODE_TYPEDEF:
2807 ret = ctf_typedef_visit(fd, depth + 1,
2808 trace->root_declaration_scope,
2809 node->u._typedef.type_specifier_list,
2810 &node->u._typedef.type_declarators,
2811 trace);
2812 if (ret)
2813 return ret;
2814 break;
2815 case NODE_TYPEALIAS:
2816 ret = ctf_typealias_visit(fd, depth + 1,
2817 trace->root_declaration_scope,
2818 node->u.typealias.target, node->u.typealias.alias,
2819 trace);
2820 if (ret)
2821 return ret;
2822 break;
2823 case NODE_TYPE_SPECIFIER_LIST:
2824 {
2825 struct declaration *declaration;
2826
2827 /*
2828 * Just add the type specifier to the root scope
2829 * declaration scope. Release local reference.
2830 */
2831 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
2832 node, trace->root_declaration_scope, trace);
2833 if (!declaration)
2834 return -ENOMEM;
2835 declaration_unref(declaration);
2836 break;
2837 }
2838 default:
2839 return -EPERM;
2840 }
2841
2842 return 0;
2843}
2844
ab4cf058
MD
2845int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
2846 struct ctf_trace *trace, int byte_order)
05628561
MD
2847{
2848 int ret = 0;
2849 struct ctf_node *iter;
e2c76a4d 2850 int env_clock_done = 0;
05628561 2851
c8b219a3 2852 printf_verbose("CTF visitor: metadata construction... ");
ab4cf058 2853 trace->byte_order = byte_order;
50cb9c56
MD
2854 trace->clocks = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2855 NULL, clock_free);
f133896d
MD
2856 trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2857 NULL, callsite_free);
ab4cf058 2858
00f7c1a5
MD
2859retry:
2860 trace->root_declaration_scope = new_declaration_scope(NULL);
2861
05628561
MD
2862 switch (node->type) {
2863 case NODE_ROOT:
e2c76a4d 2864 if (!env_clock_done) {
56e60373
MD
2865 /*
2866 * declarations need to query clock hash table,
2867 * so clock need to be treated first.
2868 */
3122e6f0 2869 if (bt_list_empty(&node->u.root.clock)) {
f57447bd
JN
2870 ctf_clock_default(fd, depth + 1, trace);
2871 } else {
3122e6f0 2872 bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
f57447bd
JN
2873 ret = ctf_clock_visit(fd, depth + 1, iter,
2874 trace);
2875 if (ret) {
2876 fprintf(fd, "[error] %s: clock declaration error\n", __func__);
2877 goto error;
2878 }
56e60373
MD
2879 }
2880 }
e2c76a4d 2881 env_clock_done = 1;
56e60373 2882 }
3122e6f0 2883 bt_list_for_each_entry(iter, &node->u.root.declaration_list,
05628561 2884 siblings) {
78af2bcd 2885 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
427c09b7
MD
2886 if (ret) {
2887 fprintf(fd, "[error] %s: root declaration error\n", __func__);
a0fe7d97 2888 goto error;
427c09b7 2889 }
05628561 2890 }
3122e6f0 2891 bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
05628561 2892 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
00f7c1a5
MD
2893 if (ret == -EINTR) {
2894 free_declaration_scope(trace->root_declaration_scope);
2895 /*
2896 * Need to restart creation of type
2897 * definitions, aliases and
2898 * trace header declarations.
2899 */
2900 goto retry;
2901 }
427c09b7
MD
2902 if (ret) {
2903 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
a0fe7d97 2904 goto error;
427c09b7 2905 }
05628561 2906 }
f133896d
MD
2907 bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
2908 ret = ctf_callsite_visit(fd, depth + 1, iter,
2909 trace);
2910 if (ret) {
2911 fprintf(fd, "[error] %s: callsite declaration error\n", __func__);
2912 goto error;
2913 }
2914 }
5039b4cc
MD
2915 if (!trace->streams) {
2916 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
a0fe7d97
MD
2917 ret = -EINVAL;
2918 goto error;
5039b4cc 2919 }
3122e6f0 2920 bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
cadd09e9
MD
2921 ret = ctf_env_visit(fd, depth + 1, iter, trace);
2922 if (ret) {
2923 fprintf(fd, "[error] %s: env declaration error\n", __func__);
2924 goto error;
2925 }
2926 }
3122e6f0 2927 bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
05628561 2928 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 2929 trace->root_declaration_scope, trace);
427c09b7
MD
2930 if (ret) {
2931 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
a0fe7d97 2932 goto error;
427c09b7 2933 }
05628561 2934 }
3122e6f0 2935 bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
05628561 2936 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 2937 trace->root_declaration_scope, trace);
427c09b7
MD
2938 if (ret) {
2939 fprintf(fd, "[error] %s: event declaration error\n", __func__);
a0fe7d97 2940 goto error;
427c09b7 2941 }
05628561
MD
2942 }
2943 break;
05628561
MD
2944 case NODE_UNKNOWN:
2945 default:
78af2bcd 2946 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
05628561 2947 (int) node->type);
a0fe7d97
MD
2948 ret = -EINVAL;
2949 goto error;
05628561 2950 }
c8b219a3 2951 printf_verbose("done.\n");
05628561 2952 return ret;
a0fe7d97
MD
2953
2954error:
2955 free_declaration_scope(trace->root_declaration_scope);
f133896d 2956 g_hash_table_destroy(trace->callsites);
50cb9c56 2957 g_hash_table_destroy(trace->clocks);
a0fe7d97 2958 return ret;
05628561 2959}
15d4fe3c
JD
2960
2961int ctf_destroy_metadata(struct ctf_trace *trace)
2962{
2963 int i, j, k;
2964 struct ctf_file_stream *metadata_stream;
2965
2966 if (trace->streams) {
2967 for (i = 0; i < trace->streams->len; i++) {
2968 struct ctf_stream_declaration *stream;
2969
2970 stream = g_ptr_array_index(trace->streams, i);
2971 if (!stream)
2972 continue;
2973 for (j = 0; j < stream->streams->len; j++) {
2974 struct ctf_stream_definition *stream_def;
2975
2976 stream_def = g_ptr_array_index(stream->streams, j);
2977 if (!stream_def)
2978 continue;
2979 for (k = 0; k < stream_def->events_by_id->len; k++) {
2980 struct ctf_event_definition *event;
2981
2982 event = g_ptr_array_index(stream_def->events_by_id, k);
2983 if (!event)
2984 continue;
2985 if (&event->event_fields->p)
2986 definition_unref(&event->event_fields->p);
2987 if (&event->event_context->p)
2988 definition_unref(&event->event_context->p);
2989 g_free(event);
2990 }
2991 if (&stream_def->trace_packet_header->p)
2992 definition_unref(&stream_def->trace_packet_header->p);
2993 if (&stream_def->stream_event_header->p)
2994 definition_unref(&stream_def->stream_event_header->p);
2995 if (&stream_def->stream_packet_context->p)
2996 definition_unref(&stream_def->stream_packet_context->p);
2997 if (&stream_def->stream_event_context->p)
2998 definition_unref(&stream_def->stream_event_context->p);
2999 g_ptr_array_free(stream_def->events_by_id, TRUE);
3000 g_free(stream_def);
3001 }
3002 if (stream->event_header_decl)
3003 declaration_unref(&stream->event_header_decl->p);
3004 if (stream->event_context_decl)
3005 declaration_unref(&stream->event_context_decl->p);
3006 if (stream->packet_context_decl)
3007 declaration_unref(&stream->packet_context_decl->p);
3008 g_ptr_array_free(stream->streams, TRUE);
3009 g_ptr_array_free(stream->events_by_id, TRUE);
3010 g_hash_table_destroy(stream->event_quark_to_id);
3011 free_declaration_scope(stream->declaration_scope);
3012 g_free(stream);
3013 }
3014 g_ptr_array_free(trace->streams, TRUE);
3015 }
3016
3017 if (trace->event_declarations) {
3018 for (i = 0; i < trace->event_declarations->len; i++) {
3019 struct bt_ctf_event_decl *event_decl;
3020 struct ctf_event_declaration *event;
3021
3022 event_decl = g_ptr_array_index(trace->event_declarations, i);
3023 if (event_decl->context_decl)
3024 g_ptr_array_free(event_decl->context_decl, TRUE);
3025 if (event_decl->fields_decl)
3026 g_ptr_array_free(event_decl->fields_decl, TRUE);
3027 if (event_decl->packet_header_decl)
3028 g_ptr_array_free(event_decl->packet_header_decl, TRUE);
3029 if (event_decl->event_context_decl)
3030 g_ptr_array_free(event_decl->event_context_decl, TRUE);
3031 if (event_decl->event_header_decl)
3032 g_ptr_array_free(event_decl->event_header_decl, TRUE);
3033 if (event_decl->packet_context_decl)
3034 g_ptr_array_free(event_decl->packet_context_decl, TRUE);
3035
3036 event = &event_decl->parent;
3037 if (event->fields_decl)
3038 declaration_unref(&event->fields_decl->p);
3039 if (event->context_decl)
3040 declaration_unref(&event->context_decl->p);
3041 free_declaration_scope(event->declaration_scope);
3042
3043 g_free(event);
3044 }
3045 g_ptr_array_free(trace->event_declarations, TRUE);
3046 }
3047 if (trace->packet_header_decl)
3048 declaration_unref(&trace->packet_header_decl->p);
3049
3050 free_declaration_scope(trace->root_declaration_scope);
3051 free_declaration_scope(trace->declaration_scope);
3052
3053 g_hash_table_destroy(trace->callsites);
3054 g_hash_table_destroy(trace->clocks);
3055
3056 metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent);
3057 g_free(metadata_stream);
3058
3059 return 0;
3060}
This page took 0.207329 seconds and 4 git commands to generate.