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