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