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