Add missing string declaration (without {})
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
CommitLineData
05628561
MD
1/*
2 * ctf-visitor-generate-io-struct.c
3 *
4 * Common Trace Format Metadata Visitor (generate I/O structures).
5 *
6 * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 */
18
19#include <stdio.h>
20#include <unistd.h>
21#include <string.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <glib.h>
25#include <inttypes.h>
add40b62 26#include <endian.h>
05628561
MD
27#include <errno.h>
28#include <babeltrace/list.h>
a0720417
MD
29#include <babeltrace/types.h>
30#include <babeltrace/ctf/metadata.h>
41253107 31#include <uuid/uuid.h>
05628561
MD
32#include "ctf-scanner.h"
33#include "ctf-parser.h"
34#include "ctf-ast.h"
35
36#define fprintf_dbg(fd, fmt, args...) fprintf(fd, "%s: " fmt, __func__, ## args)
37
de47353a
MD
38#define _cds_list_first_entry(ptr, type, member) \
39 cds_list_entry((ptr)->next, type, member)
05628561 40
a3cca9e9 41static
78af2bcd
MD
42struct declaration *ctf_type_specifier_list_visit(FILE *fd,
43 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
44 struct declaration_scope *declaration_scope,
45 struct ctf_trace *trace);
a3cca9e9 46
05628561 47/*
41253107 48 * String returned must be freed by the caller using g_free.
05628561
MD
49 */
50static
add40b62 51char *concatenate_unary_strings(struct cds_list_head *head)
05628561 52{
41253107
MD
53 struct ctf_node *node;
54 GString *str;
55 int i = 0;
56
a0720417 57 str = g_string_new("");
41253107
MD
58 cds_list_for_each_entry(node, head, siblings) {
59 char *src_string;
60
61 assert(node->type == NODE_UNARY_EXPRESSION);
62 assert(node->u.unary_expression.type == UNARY_STRING);
63 assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
a0720417 64 ^ (i != 0));
41253107
MD
65 switch (node->u.unary_expression.link) {
66 case UNARY_DOTLINK:
a0720417 67 g_string_append(str, ".");
41253107
MD
68 break;
69 case UNARY_ARROWLINK:
a0720417 70 g_string_append(str, "->");
41253107
MD
71 break;
72 case UNARY_DOTDOTDOT:
a0720417
MD
73 g_string_append(str, "...");
74 break;
75 default:
41253107
MD
76 break;
77 }
a0720417 78 src_string = node->u.unary_expression.u.string;
41253107
MD
79 g_string_append(str, src_string);
80 i++;
81 }
82 return g_string_free(str, FALSE);
05628561
MD
83}
84
85static
add40b62 86int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
05628561 87{
41253107
MD
88 struct ctf_node *node;
89 int i = 0;
90
91 cds_list_for_each_entry(node, head, siblings) {
92 assert(node->type == NODE_UNARY_EXPRESSION);
93 assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
94 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
95 assert(i == 0);
a0720417 96 *value = node->u.unary_expression.u.unsigned_constant;
41253107
MD
97 i++;
98 }
99 return 0;
05628561
MD
100}
101
102static
add40b62 103int get_unary_uuid(struct cds_list_head *head, uuid_t *uuid)
05628561 104{
41253107
MD
105 struct ctf_node *node;
106 int i = 0;
107 int ret = -1;
108
109 cds_list_for_each_entry(node, head, siblings) {
110 const char *src_string;
111
112 assert(node->type == NODE_UNARY_EXPRESSION);
113 assert(node->u.unary_expression.type == UNARY_STRING);
114 assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
115 assert(i == 0);
a0720417
MD
116 src_string = node->u.unary_expression.u.string;
117 ret = uuid_parse(node->u.unary_expression.u.string, *uuid);
41253107
MD
118 }
119 return ret;
05628561
MD
120}
121
122static
123struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
124{
125 if (trace->streams->len <= stream_id)
126 return NULL;
127 return g_ptr_array_index(trace->streams, stream_id);
128}
129
add40b62 130static
78af2bcd
MD
131int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
132{
133 assert(type_specifier->type == NODE_TYPE_SPECIFIER);
134
135 switch (type_specifier->u.type_specifier.type) {
136 case TYPESPEC_VOID:
137 g_string_append(str, "void");
138 break;
139 case TYPESPEC_CHAR:
140 g_string_append(str, "char");
141 break;
142 case TYPESPEC_SHORT:
143 g_string_append(str, "short");
144 break;
145 case TYPESPEC_INT:
146 g_string_append(str, "int");
147 break;
148 case TYPESPEC_LONG:
149 g_string_append(str, "long");
150 break;
151 case TYPESPEC_FLOAT:
152 g_string_append(str, "float");
153 break;
154 case TYPESPEC_DOUBLE:
155 g_string_append(str, "double");
156 break;
157 case TYPESPEC_SIGNED:
158 g_string_append(str, "signed");
159 break;
160 case TYPESPEC_UNSIGNED:
161 g_string_append(str, "unsigned");
162 break;
163 case TYPESPEC_BOOL:
164 g_string_append(str, "bool");
165 break;
166 case TYPESPEC_COMPLEX:
167 g_string_append(str, "_Complex");
168 break;
169 case TYPESPEC_IMAGINARY:
170 g_string_append(str, "_Imaginary");
171 break;
172 case TYPESPEC_CONST:
173 g_string_append(str, "const");
174 break;
175 case TYPESPEC_ID_TYPE:
176 if (type_specifier->u.type_specifier.id_type)
177 g_string_append(str, type_specifier->u.type_specifier.id_type);
178 break;
179 case TYPESPEC_STRUCT:
180 {
181 struct ctf_node *node = type_specifier->u.type_specifier.node;
182
183 if (!node->u._struct.name) {
184 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
185 return -EINVAL;
186 }
187 g_string_append(str, "struct ");
188 g_string_append(str, node->u._struct.name);
189 break;
190 }
191 case TYPESPEC_VARIANT:
192 {
193 struct ctf_node *node = type_specifier->u.type_specifier.node;
194
195 if (!node->u.variant.name) {
196 fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
197 return -EINVAL;
198 }
199 g_string_append(str, "variant ");
200 g_string_append(str, node->u.variant.name);
201 break;
202 }
203 case TYPESPEC_ENUM:
204 {
205 struct ctf_node *node = type_specifier->u.type_specifier.node;
206
207 if (!node->u._enum.enum_id) {
208 fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
209 return -EINVAL;
210 }
211 g_string_append(str, "enum ");
212 g_string_append(str, node->u._enum.enum_id);
213 break;
214 }
215 case TYPESPEC_FLOATING_POINT:
216 case TYPESPEC_INTEGER:
217 case TYPESPEC_STRING:
218 default:
219 fprintf(fd, "[error] %s: unknown specifier\n", __func__);
220 return -EINVAL;
221 }
222 return 0;
223}
224
225static
226int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
add40b62
MD
227{
228 struct ctf_node *iter;
229 int alias_item_nr = 0;
78af2bcd 230 int ret;
add40b62 231
78af2bcd 232 cds_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
add40b62
MD
233 if (alias_item_nr != 0)
234 g_string_append(str, " ");
235 alias_item_nr++;
78af2bcd
MD
236 ret = visit_type_specifier(fd, iter, str);
237 if (ret)
238 return ret;
add40b62
MD
239 }
240 return 0;
add40b62
MD
241}
242
243static
8fdba45b 244GQuark create_typealias_identifier(FILE *fd, int depth,
78af2bcd 245 struct ctf_node *type_specifier_list,
add40b62
MD
246 struct ctf_node *node_type_declarator)
247{
a0720417 248 struct ctf_node *iter;
add40b62 249 GString *str;
a0720417 250 char *str_c;
add40b62
MD
251 GQuark alias_q;
252 int ret;
253
a0720417 254 str = g_string_new("");
78af2bcd 255 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
256 if (ret) {
257 g_string_free(str, TRUE);
258 return 0;
259 }
260 cds_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
261 g_string_append(str, " *");
262 if (iter->u.pointer.const_qualifier)
263 g_string_append(str, " const");
264 }
265 str_c = g_string_free(str, FALSE);
266 alias_q = g_quark_from_string(str_c);
267 g_free(str_c);
268 return alias_q;
269}
270
a3cca9e9 271static
8fdba45b 272struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
78af2bcd 273 struct ctf_node *type_specifier_list,
a3cca9e9
MD
274 GQuark *field_name,
275 struct ctf_node *node_type_declarator,
add40b62 276 struct declaration_scope *declaration_scope,
e397791f
MD
277 struct declaration *nested_declaration,
278 struct ctf_trace *trace)
a3cca9e9
MD
279{
280 /*
281 * Visit type declarator by first taking care of sequence/array
282 * (recursively). Then, when we get to the identifier, take care
283 * of pointers.
284 */
285
e397791f
MD
286 if (node_type_declarator) {
287 assert(node_type_declarator->u.type_declarator.type != TYPEDEC_UNKNOWN);
add40b62 288
e397791f
MD
289 /* TODO: gcc bitfields not supported yet. */
290 if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
78af2bcd 291 fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
e397791f
MD
292 return NULL;
293 }
add40b62 294 }
a3cca9e9
MD
295
296 if (!nested_declaration) {
e397791f 297 if (node_type_declarator && !cds_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
add40b62
MD
298 GQuark alias_q;
299
a3cca9e9
MD
300 /*
301 * If we have a pointer declarator, it _has_ to be present in
302 * the typealiases (else fail).
303 */
add40b62 304 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 305 type_specifier_list, node_type_declarator);
add40b62
MD
306 nested_declaration = lookup_declaration(alias_q, declaration_scope);
307 if (!nested_declaration) {
78af2bcd 308 fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
add40b62
MD
309 return NULL;
310 }
a3cca9e9 311 } else {
78af2bcd
MD
312 nested_declaration = ctf_type_specifier_list_visit(fd, depth,
313 type_specifier_list, declaration_scope, trace);
a3cca9e9 314 }
a3cca9e9
MD
315 }
316
e397791f
MD
317 if (!node_type_declarator)
318 return nested_declaration;
319
a3cca9e9
MD
320 if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
321 if (node_type_declarator->u.type_declarator.u.id)
322 *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
323 else
324 *field_name = 0;
325 return nested_declaration;
326 } else {
327 struct declaration *declaration;
78af2bcd 328 struct ctf_node *length;
a3cca9e9
MD
329
330 /* TYPEDEC_NESTED */
331
332 /* create array/sequence, pass nested_declaration as child. */
78af2bcd
MD
333 length = node_type_declarator->u.type_declarator.u.nested.length;
334 if (!length) {
335 fprintf(fd, "[error] %s: expecting length type or value.\n", __func__);
a0720417
MD
336 return NULL;
337 }
78af2bcd 338 switch (length->type) {
a0720417
MD
339 case NODE_UNARY_EXPRESSION:
340 {
341 struct declaration_array *array_declaration;
342 size_t len;
343
78af2bcd
MD
344 if (length->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
345 fprintf(fd, "[error] %s: array: unexpected unary expression.\n", __func__);
a0720417 346 return NULL;
a3cca9e9 347 }
78af2bcd 348 len = length->u.unary_expression.u.unsigned_constant;
a0720417
MD
349 array_declaration = array_declaration_new(len, nested_declaration,
350 declaration_scope);
351 declaration = &array_declaration->p;
352 break;
353 }
2dd46001 354 case NODE_TYPE_SPECIFIER_LIST:
a0720417
MD
355 {
356 struct declaration_sequence *sequence_declaration;
357 struct declaration_integer *integer_declaration;
a0720417 358
2dd46001
MD
359 declaration = ctf_type_specifier_list_visit(fd, depth,
360 length, declaration_scope, trace);
361 if (!declaration) {
362 fprintf(fd, "[error] %s: unable to find declaration type for sequence length\n", __func__);
363 return NULL;
364 }
365 if (declaration->id != CTF_TYPE_INTEGER) {
366 fprintf(fd, "[error] %s: length type for sequence is expected to be an integer (unsigned).\n", __func__);
367 declaration_unref(declaration);
368 return NULL;
369 }
a0720417 370 integer_declaration = container_of(declaration, struct declaration_integer, p);
2dd46001
MD
371 if (integer_declaration->signedness != false) {
372 fprintf(fd, "[error] %s: length type for sequence should always be an unsigned integer.\n", __func__);
373 declaration_unref(declaration);
374 return NULL;
375 }
376
a0720417
MD
377 sequence_declaration = sequence_declaration_new(integer_declaration,
378 nested_declaration, declaration_scope);
379 declaration = &sequence_declaration->p;
380 break;
381 }
382 default:
383 assert(0);
a3cca9e9
MD
384 }
385
386 /* Pass it as content of outer container */
387 declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 388 type_specifier_list, field_name,
a3cca9e9 389 node_type_declarator->u.type_declarator.u.nested.type_declarator,
e397791f 390 declaration_scope, declaration, trace);
a3cca9e9
MD
391 return declaration;
392 }
393}
394
395static
8fdba45b 396int ctf_struct_type_declarators_visit(FILE *fd, int depth,
a3cca9e9 397 struct declaration_struct *struct_declaration,
78af2bcd 398 struct ctf_node *type_specifier_list,
a3cca9e9 399 struct cds_list_head *type_declarators,
e397791f
MD
400 struct declaration_scope *declaration_scope,
401 struct ctf_trace *trace)
a3cca9e9
MD
402{
403 struct ctf_node *iter;
404 GQuark field_name;
405
406 cds_list_for_each_entry(iter, type_declarators, siblings) {
407 struct declaration *field_declaration;
408
409 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 410 type_specifier_list,
a3cca9e9
MD
411 &field_name, iter,
412 struct_declaration->scope,
e397791f 413 NULL, trace);
2dd46001
MD
414 if (!field_declaration) {
415 fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
416 return -EINVAL;
417 }
a3cca9e9
MD
418 struct_declaration_add_field(struct_declaration,
419 g_quark_to_string(field_name),
420 field_declaration);
421 }
add40b62
MD
422 return 0;
423}
a3cca9e9 424
add40b62 425static
8fdba45b 426int ctf_variant_type_declarators_visit(FILE *fd, int depth,
a0720417 427 struct declaration_untagged_variant *untagged_variant_declaration,
78af2bcd 428 struct ctf_node *type_specifier_list,
add40b62 429 struct cds_list_head *type_declarators,
e397791f
MD
430 struct declaration_scope *declaration_scope,
431 struct ctf_trace *trace)
add40b62
MD
432{
433 struct ctf_node *iter;
434 GQuark field_name;
435
436 cds_list_for_each_entry(iter, type_declarators, siblings) {
437 struct declaration *field_declaration;
438
439 field_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 440 type_specifier_list,
add40b62 441 &field_name, iter,
a0720417 442 untagged_variant_declaration->scope,
e397791f 443 NULL, trace);
2dd46001
MD
444 if (!field_declaration) {
445 fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
446 return -EINVAL;
447 }
a0720417 448 untagged_variant_declaration_add_field(untagged_variant_declaration,
add40b62
MD
449 g_quark_to_string(field_name),
450 field_declaration);
451 }
a3cca9e9
MD
452 return 0;
453}
454
455static
8fdba45b 456int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
78af2bcd 457 struct ctf_node *type_specifier_list,
e397791f
MD
458 struct cds_list_head *type_declarators,
459 struct ctf_trace *trace)
a3cca9e9
MD
460{
461 struct ctf_node *iter;
462 GQuark identifier;
463
464 cds_list_for_each_entry(iter, type_declarators, siblings) {
465 struct declaration *type_declaration;
466 int ret;
467
468 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 469 type_specifier_list,
a3cca9e9 470 &identifier, iter,
e397791f 471 scope, NULL, trace);
2dd46001
MD
472 if (!type_declaration) {
473 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
474 return -EINVAL;
475 }
476 /*
477 * Don't allow typedef and typealias of untagged
478 * variants.
479 */
480 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
481 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
482 declaration_unref(type_declaration);
483 return -EPERM;
484 }
a3cca9e9
MD
485 ret = register_declaration(identifier, type_declaration, scope);
486 if (ret) {
487 type_declaration->declaration_free(type_declaration);
488 return ret;
489 }
490 }
491 return 0;
492}
493
494static
8fdba45b 495int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
e397791f
MD
496 struct ctf_node *target, struct ctf_node *alias,
497 struct ctf_trace *trace)
a3cca9e9
MD
498{
499 struct declaration *type_declaration;
a0720417 500 struct ctf_node *node;
add40b62 501 GQuark dummy_id;
a3cca9e9 502 GQuark alias_q;
a0720417 503 int err;
a3cca9e9
MD
504
505 /* See ctf_visitor_type_declarator() in the semantic validator. */
506
507 /*
508 * Create target type declaration.
509 */
510
427c09b7 511 if (cds_list_empty(&target->u.typealias_target.type_declarators))
a0720417
MD
512 node = NULL;
513 else
427c09b7 514 node = _cds_list_first_entry(&target->u.typealias_target.type_declarators,
a0720417 515 struct ctf_node, siblings);
a3cca9e9 516 type_declaration = ctf_type_declarator_visit(fd, depth,
78af2bcd 517 target->u.typealias_target.type_specifier_list,
a0720417 518 &dummy_id, node,
e397791f 519 scope, NULL, trace);
a3cca9e9 520 if (!type_declaration) {
78af2bcd 521 fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
a3cca9e9
MD
522 err = -EINVAL;
523 goto error;
524 }
2dd46001
MD
525 /*
526 * Don't allow typedef and typealias of untagged
527 * variants.
528 */
529 if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
530 fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
531 declaration_unref(type_declaration);
532 return -EPERM;
533 }
a3cca9e9
MD
534 /*
535 * The semantic validator does not check whether the target is
536 * abstract or not (if it has an identifier). Check it here.
537 */
538 if (dummy_id != 0) {
78af2bcd 539 fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
a3cca9e9
MD
540 err = -EINVAL;
541 goto error;
542 }
543 /*
544 * Create alias identifier.
545 */
a3cca9e9
MD
546
547 node = _cds_list_first_entry(&alias->u.typealias_alias.type_declarators,
a0720417 548 struct ctf_node, siblings);
add40b62 549 alias_q = create_typealias_identifier(fd, depth,
78af2bcd 550 alias->u.typealias_alias.type_specifier_list, node);
a0720417
MD
551 err = register_declaration(alias_q, type_declaration, scope);
552 if (err)
a3cca9e9
MD
553 goto error;
554 return 0;
555
556error:
557 type_declaration->declaration_free(type_declaration);
a0720417 558 return err;
a3cca9e9
MD
559}
560
561static
8fdba45b 562int ctf_struct_declaration_list_visit(FILE *fd, int depth,
e397791f
MD
563 struct ctf_node *iter, struct declaration_struct *struct_declaration,
564 struct ctf_trace *trace)
a3cca9e9 565{
a3cca9e9
MD
566 int ret;
567
568 switch (iter->type) {
569 case NODE_TYPEDEF:
570 /* For each declarator, declare type and add type to struct declaration scope */
571 ret = ctf_typedef_visit(fd, depth,
572 struct_declaration->scope,
78af2bcd 573 iter->u._typedef.type_specifier_list,
e397791f 574 &iter->u._typedef.type_declarators, trace);
a3cca9e9
MD
575 if (ret)
576 return ret;
577 break;
578 case NODE_TYPEALIAS:
579 /* Declare type with declarator and add type to struct declaration scope */
580 ret = ctf_typealias_visit(fd, depth,
581 struct_declaration->scope,
582 iter->u.typealias.target,
e397791f 583 iter->u.typealias.alias, trace);
a3cca9e9
MD
584 if (ret)
585 return ret;
586 break;
587 case NODE_STRUCT_OR_VARIANT_DECLARATION:
588 /* Add field to structure declaration */
589 ret = ctf_struct_type_declarators_visit(fd, depth,
590 struct_declaration,
78af2bcd 591 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
592 &iter->u.struct_or_variant_declaration.type_declarators,
593 struct_declaration->scope, trace);
a3cca9e9
MD
594 if (ret)
595 return ret;
596 break;
597 default:
78af2bcd 598 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
a3cca9e9
MD
599 assert(0);
600 }
601 return 0;
602}
603
add40b62 604static
8fdba45b 605int ctf_variant_declaration_list_visit(FILE *fd, int depth,
a0720417
MD
606 struct ctf_node *iter,
607 struct declaration_untagged_variant *untagged_variant_declaration,
e397791f 608 struct ctf_trace *trace)
add40b62 609{
add40b62
MD
610 int ret;
611
612 switch (iter->type) {
613 case NODE_TYPEDEF:
614 /* For each declarator, declare type and add type to variant declaration scope */
615 ret = ctf_typedef_visit(fd, depth,
a0720417 616 untagged_variant_declaration->scope,
78af2bcd 617 iter->u._typedef.type_specifier_list,
e397791f 618 &iter->u._typedef.type_declarators, trace);
add40b62
MD
619 if (ret)
620 return ret;
621 break;
622 case NODE_TYPEALIAS:
623 /* Declare type with declarator and add type to variant declaration scope */
624 ret = ctf_typealias_visit(fd, depth,
a0720417 625 untagged_variant_declaration->scope,
add40b62 626 iter->u.typealias.target,
e397791f 627 iter->u.typealias.alias, trace);
add40b62
MD
628 if (ret)
629 return ret;
630 break;
631 case NODE_STRUCT_OR_VARIANT_DECLARATION:
632 /* Add field to structure declaration */
633 ret = ctf_variant_type_declarators_visit(fd, depth,
a0720417 634 untagged_variant_declaration,
78af2bcd 635 iter->u.struct_or_variant_declaration.type_specifier_list,
a0720417
MD
636 &iter->u.struct_or_variant_declaration.type_declarators,
637 untagged_variant_declaration->scope, trace);
add40b62
MD
638 if (ret)
639 return ret;
640 break;
641 default:
78af2bcd 642 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
add40b62
MD
643 assert(0);
644 }
645 return 0;
646}
647
a3cca9e9 648static
a0720417 649struct declaration *ctf_declaration_struct_visit(FILE *fd,
a3cca9e9 650 int depth, const char *name, struct cds_list_head *declaration_list,
e397791f
MD
651 int has_body, struct declaration_scope *declaration_scope,
652 struct ctf_trace *trace)
a3cca9e9 653{
a3cca9e9
MD
654 struct declaration_struct *struct_declaration;
655 struct ctf_node *iter;
a0720417 656 int ret;
a3cca9e9
MD
657
658 /*
659 * For named struct (without body), lookup in
660 * declaration scope. Don't take reference on struct
661 * declaration: ref is only taken upon definition.
662 */
663 if (!has_body) {
664 assert(name);
665 struct_declaration =
666 lookup_struct_declaration(g_quark_from_string(name),
667 declaration_scope);
a0720417 668 return &struct_declaration->p;
a3cca9e9
MD
669 } else {
670 /* For unnamed struct, create type */
671 /* For named struct (with body), create type and add to declaration scope */
672 if (name) {
673 if (lookup_struct_declaration(g_quark_from_string(name),
674 declaration_scope)) {
675
78af2bcd 676 fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
a3cca9e9
MD
677 return NULL;
678 }
679 }
a0720417 680 struct_declaration = struct_declaration_new(declaration_scope);
a3cca9e9 681 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f
MD
682 ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
683 struct_declaration, trace);
a3cca9e9
MD
684 if (ret)
685 goto error;
686 }
687 if (name) {
688 ret = register_struct_declaration(g_quark_from_string(name),
689 struct_declaration,
690 declaration_scope);
691 assert(!ret);
692 }
a0720417 693 return &struct_declaration->p;
a3cca9e9
MD
694 }
695error:
696 struct_declaration->p.declaration_free(&struct_declaration->p);
697 return NULL;
698}
699
05628561 700static
a0720417
MD
701struct declaration *ctf_declaration_variant_visit(FILE *fd,
702 int depth, const char *name, const char *choice,
703 struct cds_list_head *declaration_list,
e397791f
MD
704 int has_body, struct declaration_scope *declaration_scope,
705 struct ctf_trace *trace)
05628561 706{
a0720417 707 struct declaration_untagged_variant *untagged_variant_declaration;
add40b62
MD
708 struct declaration_variant *variant_declaration;
709 struct ctf_node *iter;
a0720417 710 int ret;
de47353a 711
add40b62
MD
712 /*
713 * For named variant (without body), lookup in
714 * declaration scope. Don't take reference on variant
715 * declaration: ref is only taken upon definition.
716 */
717 if (!has_body) {
718 assert(name);
a0720417 719 untagged_variant_declaration =
add40b62
MD
720 lookup_variant_declaration(g_quark_from_string(name),
721 declaration_scope);
add40b62 722 } else {
de47353a 723 /* For unnamed variant, create type */
add40b62
MD
724 /* For named variant (with body), create type and add to declaration scope */
725 if (name) {
726 if (lookup_variant_declaration(g_quark_from_string(name),
727 declaration_scope)) {
728
78af2bcd 729 fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
add40b62
MD
730 return NULL;
731 }
732 }
a0720417 733 untagged_variant_declaration = untagged_variant_declaration_new(declaration_scope);
add40b62 734 cds_list_for_each_entry(iter, declaration_list, siblings) {
e397791f 735 ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
a0720417 736 untagged_variant_declaration, trace);
add40b62
MD
737 if (ret)
738 goto error;
739 }
740 if (name) {
741 ret = register_variant_declaration(g_quark_from_string(name),
a0720417 742 untagged_variant_declaration,
add40b62
MD
743 declaration_scope);
744 assert(!ret);
745 }
a0720417
MD
746 }
747 /*
748 * if tagged, create tagged variant and return. else return
749 * untagged variant.
750 */
751 if (!choice) {
752 return &untagged_variant_declaration->p;
753 } else {
754 variant_declaration = variant_declaration_new(untagged_variant_declaration, choice);
755 if (!variant_declaration)
756 goto error;
757 declaration_unref(&untagged_variant_declaration->p);
758 return &variant_declaration->p;
de47353a 759 }
add40b62 760error:
2dd46001 761 untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
add40b62 762 return NULL;
05628561
MD
763}
764
05628561 765static
8fdba45b 766int ctf_enumerator_list_visit(FILE *fd, int depth,
add40b62
MD
767 struct ctf_node *enumerator,
768 struct declaration_enum *enum_declaration)
769{
1cfda062
MD
770 GQuark q;
771 struct ctf_node *iter;
772
773 q = g_quark_from_string(enumerator->u.enumerator.id);
a0720417 774 if (enum_declaration->integer_declaration->signedness) {
1cfda062
MD
775 int64_t start, end;
776 int nr_vals = 0;
777
a0720417 778 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
1cfda062
MD
779 int64_t *target;
780
781 assert(iter->type == NODE_UNARY_EXPRESSION);
782 if (nr_vals == 0)
783 target = &start;
784 else
785 target = &end;
786
787 switch (iter->u.unary_expression.type) {
788 case UNARY_SIGNED_CONSTANT:
789 *target = iter->u.unary_expression.u.signed_constant;
790 break;
791 case UNARY_UNSIGNED_CONSTANT:
792 *target = iter->u.unary_expression.u.unsigned_constant;
793 break;
794 default:
78af2bcd 795 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
796 return -EINVAL;
797 }
798 if (nr_vals > 1) {
78af2bcd 799 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
800 return -EINVAL;
801 }
802 nr_vals++;
803 }
804 if (nr_vals == 1)
805 end = start;
806 enum_signed_insert(enum_declaration, start, end, q);
a0720417 807 } else {
1cfda062
MD
808 uint64_t start, end;
809 int nr_vals = 0;
810
a0720417
MD
811 cds_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
812 uint64_t *target;
1cfda062
MD
813
814 assert(iter->type == NODE_UNARY_EXPRESSION);
815 if (nr_vals == 0)
816 target = &start;
817 else
818 target = &end;
819
820 switch (iter->u.unary_expression.type) {
821 case UNARY_UNSIGNED_CONSTANT:
822 *target = iter->u.unary_expression.u.unsigned_constant;
823 break;
824 case UNARY_SIGNED_CONSTANT:
825 /*
826 * We don't accept signed constants for enums with unsigned
827 * container type.
828 */
78af2bcd 829 fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
1cfda062
MD
830 return -EINVAL;
831 default:
78af2bcd 832 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
833 return -EINVAL;
834 }
835 if (nr_vals > 1) {
78af2bcd 836 fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
1cfda062
MD
837 return -EINVAL;
838 }
839 nr_vals++;
840 }
841 if (nr_vals == 1)
842 end = start;
843 enum_unsigned_insert(enum_declaration, start, end, q);
844 }
add40b62
MD
845 return 0;
846}
847
848static
8fdba45b 849struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
add40b62 850 const char *name,
78af2bcd 851 struct ctf_node *container_type,
add40b62 852 struct cds_list_head *enumerator_list,
1cfda062
MD
853 int has_body,
854 struct declaration_scope *declaration_scope,
855 struct ctf_trace *trace)
05628561 856{
add40b62
MD
857 struct declaration *declaration;
858 struct declaration_enum *enum_declaration;
859 struct declaration_integer *integer_declaration;
78af2bcd 860 struct ctf_node *iter;
1cfda062 861 GQuark dummy_id;
a0720417 862 int ret;
add40b62 863
05628561 864 /*
add40b62
MD
865 * For named enum (without body), lookup in
866 * declaration scope. Don't take reference on enum
867 * declaration: ref is only taken upon definition.
05628561 868 */
add40b62
MD
869 if (!has_body) {
870 assert(name);
871 enum_declaration =
872 lookup_enum_declaration(g_quark_from_string(name),
873 declaration_scope);
a0720417 874 return &enum_declaration->p;
add40b62
MD
875 } else {
876 /* For unnamed enum, create type */
877 /* For named enum (with body), create type and add to declaration scope */
878 if (name) {
879 if (lookup_enum_declaration(g_quark_from_string(name),
880 declaration_scope)) {
881
78af2bcd 882 fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
add40b62
MD
883 return NULL;
884 }
885 }
78af2bcd 886 if (!container_type) {
6743829a
MD
887 declaration = lookup_declaration(g_quark_from_static_string("int"),
888 declaration_scope);
889 if (!declaration) {
890 fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
891 return NULL;
892 }
893 } else {
894 declaration = ctf_type_declarator_visit(fd, depth,
895 container_type,
896 &dummy_id, NULL,
897 declaration_scope,
898 NULL, trace);
1cfda062 899 }
30ea18a1
MD
900 if (!declaration) {
901 fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
902 return NULL;
903 }
904 if (declaration->id != CTF_TYPE_INTEGER) {
905 fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
906 return NULL;
1cfda062 907 }
30ea18a1 908 integer_declaration = container_of(declaration, struct declaration_integer, p);
a0720417 909 enum_declaration = enum_declaration_new(integer_declaration);
add40b62
MD
910 declaration_unref(&integer_declaration->p); /* leave ref to enum */
911 cds_list_for_each_entry(iter, enumerator_list, siblings) {
912 ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration);
913 if (ret)
914 goto error;
915 }
916 if (name) {
917 ret = register_enum_declaration(g_quark_from_string(name),
918 enum_declaration,
919 declaration_scope);
920 assert(!ret);
921 }
a0720417 922 return &enum_declaration->p;
05628561 923 }
add40b62
MD
924error:
925 enum_declaration->p.declaration_free(&enum_declaration->p);
926 return NULL;
05628561
MD
927}
928
929static
8fdba45b 930struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
78af2bcd 931 struct ctf_node *type_specifier_list,
d20f5e59 932 struct declaration_scope *declaration_scope)
05628561 933{
add40b62
MD
934 GString *str;
935 struct declaration *declaration;
a0720417
MD
936 char *str_c;
937 int ret;
938 GQuark id_q;
05628561 939
a0720417 940 str = g_string_new("");
78af2bcd 941 ret = visit_type_specifier_list(fd, type_specifier_list, str);
add40b62
MD
942 if (ret)
943 return NULL;
944 str_c = g_string_free(str, FALSE);
945 id_q = g_quark_from_string(str_c);
946 g_free(str_c);
947 declaration = lookup_declaration(id_q, declaration_scope);
948 return declaration;
949}
950
ab4cf058
MD
951/*
952 * Returns 0/1 boolean, or < 0 on error.
953 */
954static
a0720417 955int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
ab4cf058
MD
956{
957 if (unary_expression->type != NODE_UNARY_EXPRESSION) {
78af2bcd 958 fprintf(fd, "[error] %s: expecting unary expression\n",
ab4cf058
MD
959 __func__);
960 return -EINVAL;
961 }
962 switch (unary_expression->u.unary_expression.type) {
963 case UNARY_UNSIGNED_CONSTANT:
964 if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
965 return 0;
966 else
967 return 1;
968 case UNARY_SIGNED_CONSTANT:
969 if (unary_expression->u.unary_expression.u.signed_constant == 0)
970 return 0;
971 else
972 return 1;
973 case UNARY_STRING:
974 if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
975 return 1;
976 else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
977 return 1;
978 else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
979 return 0;
980 else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
981 return 0;
982 else {
78af2bcd 983 fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
ab4cf058
MD
984 __func__, unary_expression->u.unary_expression.u.string);
985 return -EINVAL;
986 }
987 break;
988 default:
78af2bcd 989 fprintf(fd, "[error] %s: unexpected unary expression type\n",
ab4cf058
MD
990 __func__);
991 return -EINVAL;
992 }
993
994}
995
0f980a35
MD
996static
997int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
998{
999 int byte_order;
1000
1001 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
1002 fprintf(fd, "[error] %s: byte_order: expecting string\n",
1003 __func__);
1004 return -EINVAL;
1005 }
1006 if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1007 byte_order = BIG_ENDIAN;
1008 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1009 byte_order = LITTLE_ENDIAN;
1010 else {
1011 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
1012 __func__, unary_expression->u.unary_expression.u.string);
1013 return -EINVAL;
1014 }
1015 return byte_order;
1016}
1017
ab4cf058 1018static
a0720417
MD
1019int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
1020 struct ctf_trace *trace)
ab4cf058
MD
1021{
1022 int byte_order;
1023
1024 if (unary_expression->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1025 fprintf(fd, "[error] %s: byte_order: expecting string\n",
ab4cf058
MD
1026 __func__);
1027 return -EINVAL;
1028 }
1029 if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
1030 byte_order = trace->byte_order;
1031 else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
1032 byte_order = BIG_ENDIAN;
1033 else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
1034 byte_order = BIG_ENDIAN;
1035 else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
1036 byte_order = LITTLE_ENDIAN;
1037 else {
78af2bcd 1038 fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
a0720417 1039 __func__, unary_expression->u.unary_expression.u.string);
ab4cf058
MD
1040 return -EINVAL;
1041 }
1042 return byte_order;
1043}
1044
add40b62 1045static
8fdba45b 1046struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
ab4cf058
MD
1047 struct cds_list_head *expressions,
1048 struct ctf_trace *trace)
add40b62 1049{
a0720417 1050 struct ctf_node *expression;
ab4cf058
MD
1051 uint64_t alignment, size;
1052 int byte_order = trace->byte_order;
1053 int signedness = 0;
add40b62
MD
1054 int has_alignment = 0, has_size = 0;
1055 struct declaration_integer *integer_declaration;
1056
1057 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1058 struct ctf_node *left, *right;
add40b62 1059
a0720417
MD
1060 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1061 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
add40b62
MD
1062 assert(left->u.unary_expression.type == UNARY_STRING);
1063 if (!strcmp(left->u.unary_expression.u.string, "signed")) {
ab4cf058
MD
1064 signedness = get_boolean(fd, depth, right);
1065 if (signedness < 0)
1066 return NULL;
add40b62 1067 } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1068 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1069 if (byte_order < 0)
1070 return NULL;
add40b62 1071 } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
ab4cf058 1072 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1073 fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
ab4cf058
MD
1074 __func__);
1075 return NULL;
1076 }
1077 size = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1078 has_size = 1;
1079 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
ab4cf058 1080 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1081 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1082 __func__);
1083 return NULL;
1084 }
1085 alignment = right->u.unary_expression.u.unsigned_constant;
add40b62
MD
1086 has_alignment = 1;
1087 } else {
78af2bcd 1088 fprintf(fd, "[error] %s: unknown attribute name %s\n",
add40b62
MD
1089 __func__, left->u.unary_expression.u.string);
1090 return NULL;
1091 }
05628561 1092 }
add40b62 1093 if (!has_size) {
78af2bcd 1094 fprintf(fd, "[error] %s: missing size attribute\n", __func__);
add40b62
MD
1095 return NULL;
1096 }
ab4cf058
MD
1097 if (!has_alignment) {
1098 if (size % CHAR_BIT) {
1099 /* bit-packed alignment */
1100 alignment = 1;
1101 } else {
1102 /* byte-packed alignment */
1103 alignment = CHAR_BIT;
1104 }
1105 }
add40b62
MD
1106 integer_declaration = integer_declaration_new(size,
1107 byte_order, signedness, alignment);
1108 return &integer_declaration->p;
05628561
MD
1109}
1110
ab4cf058 1111static
8fdba45b 1112struct declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
ab4cf058
MD
1113 struct cds_list_head *expressions,
1114 struct ctf_trace *trace)
1115{
a0720417 1116 struct ctf_node *expression;
ab4cf058
MD
1117 uint64_t alignment, exp_dig, mant_dig, byte_order = trace->byte_order;
1118 int has_alignment = 0, has_exp_dig = 0, has_mant_dig = 0;
1119 struct declaration_float *float_declaration;
1120
1121 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1122 struct ctf_node *left, *right;
ab4cf058 1123
a0720417
MD
1124 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1125 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1126 assert(left->u.unary_expression.type == UNARY_STRING);
1127 if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
a0720417 1128 byte_order = get_byte_order(fd, depth, right, trace);
ab4cf058
MD
1129 if (byte_order < 0)
1130 return NULL;
1131 } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
1132 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1133 fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
ab4cf058
MD
1134 __func__);
1135 return NULL;
1136 }
1137 exp_dig = right->u.unary_expression.u.unsigned_constant;
1138 has_exp_dig = 1;
1139 } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
1140 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1141 fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
ab4cf058
MD
1142 __func__);
1143 return NULL;
1144 }
1145 mant_dig = right->u.unary_expression.u.unsigned_constant;
1146 has_mant_dig = 1;
1147 } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
1148 if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
78af2bcd 1149 fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
ab4cf058
MD
1150 __func__);
1151 return NULL;
1152 }
1153 alignment = right->u.unary_expression.u.unsigned_constant;
1154 has_alignment = 1;
1155 } else {
78af2bcd 1156 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1157 __func__, left->u.unary_expression.u.string);
1158 return NULL;
1159 }
1160 }
1161 if (!has_mant_dig) {
78af2bcd 1162 fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
ab4cf058
MD
1163 return NULL;
1164 }
1165 if (!has_exp_dig) {
78af2bcd 1166 fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
ab4cf058
MD
1167 return NULL;
1168 }
1169 if (!has_alignment) {
1170 if ((mant_dig + exp_dig) % CHAR_BIT) {
1171 /* bit-packed alignment */
1172 alignment = 1;
1173 } else {
1174 /* byte-packed alignment */
1175 alignment = CHAR_BIT;
1176 }
1177 }
1178 float_declaration = float_declaration_new(mant_dig, exp_dig,
1179 byte_order, alignment);
1180 return &float_declaration->p;
1181}
1182
1183static
8fdba45b 1184struct declaration *ctf_declaration_string_visit(FILE *fd, int depth,
ab4cf058
MD
1185 struct cds_list_head *expressions,
1186 struct ctf_trace *trace)
1187{
a0720417 1188 struct ctf_node *expression;
ab4cf058
MD
1189 const char *encoding_c = NULL;
1190 enum ctf_string_encoding encoding = CTF_STRING_UTF8;
1191 struct declaration_string *string_declaration;
1192
1193 cds_list_for_each_entry(expression, expressions, siblings) {
a0720417 1194 struct ctf_node *left, *right;
ab4cf058 1195
a0720417
MD
1196 left = _cds_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
1197 right = _cds_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
ab4cf058
MD
1198 assert(left->u.unary_expression.type == UNARY_STRING);
1199 if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
a0720417 1200 if (right->u.unary_expression.type != UNARY_STRING) {
78af2bcd 1201 fprintf(fd, "[error] %s: encoding: expecting string\n",
ab4cf058
MD
1202 __func__);
1203 return NULL;
1204 }
1205 encoding_c = right->u.unary_expression.u.string;
1206 } else {
78af2bcd 1207 fprintf(fd, "[error] %s: unknown attribute name %s\n",
ab4cf058
MD
1208 __func__, left->u.unary_expression.u.string);
1209 return NULL;
1210 }
1211 }
1212 if (encoding_c && !strcmp(encoding_c, "ASCII"))
1213 encoding = CTF_STRING_ASCII;
1214 string_declaration = string_declaration_new(encoding);
1215 return &string_declaration->p;
1216}
1217
1218
05628561 1219static
78af2bcd
MD
1220struct declaration *ctf_type_specifier_list_visit(FILE *fd,
1221 int depth, struct ctf_node *type_specifier_list,
ab4cf058
MD
1222 struct declaration_scope *declaration_scope,
1223 struct ctf_trace *trace)
05628561 1224{
a0720417 1225 struct ctf_node *first;
78af2bcd 1226 struct ctf_node *node;
d20f5e59 1227
427c09b7
MD
1228 assert(type_specifier_list->type == NODE_TYPE_SPECIFIER_LIST);
1229
78af2bcd 1230 first = _cds_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
05628561 1231
78af2bcd
MD
1232 assert(first->type == NODE_TYPE_SPECIFIER);
1233
1234 node = first->u.type_specifier.node;
1235
1236 switch (first->u.type_specifier.type) {
1237 case TYPESPEC_FLOATING_POINT:
1238 return ctf_declaration_floating_point_visit(fd, depth,
1239 &node->u.floating_point.expressions, trace);
1240 case TYPESPEC_INTEGER:
1241 return ctf_declaration_integer_visit(fd, depth,
1242 &node->u.integer.expressions, trace);
1243 case TYPESPEC_STRING:
1244 return ctf_declaration_string_visit(fd, depth,
5039b4cc 1245 &node->u.string.expressions, trace);
78af2bcd 1246 case TYPESPEC_STRUCT:
add40b62 1247 return ctf_declaration_struct_visit(fd, depth,
78af2bcd
MD
1248 node->u._struct.name,
1249 &node->u._struct.declaration_list,
1250 node->u._struct.has_body,
ab4cf058
MD
1251 declaration_scope,
1252 trace);
78af2bcd 1253 case TYPESPEC_VARIANT:
add40b62 1254 return ctf_declaration_variant_visit(fd, depth,
78af2bcd
MD
1255 node->u.variant.name,
1256 node->u.variant.choice,
1257 &node->u.variant.declaration_list,
1258 node->u.variant.has_body,
ab4cf058
MD
1259 declaration_scope,
1260 trace);
78af2bcd 1261 case TYPESPEC_ENUM:
add40b62 1262 return ctf_declaration_enum_visit(fd, depth,
78af2bcd
MD
1263 node->u._enum.enum_id,
1264 node->u._enum.container_type,
1265 &node->u._enum.enumerator_list,
1266 node->u._enum.has_body,
1cfda062 1267 declaration_scope,
ab4cf058 1268 trace);
78af2bcd
MD
1269
1270 case TYPESPEC_VOID:
1271 case TYPESPEC_CHAR:
1272 case TYPESPEC_SHORT:
1273 case TYPESPEC_INT:
1274 case TYPESPEC_LONG:
1275 case TYPESPEC_FLOAT:
1276 case TYPESPEC_DOUBLE:
1277 case TYPESPEC_SIGNED:
1278 case TYPESPEC_UNSIGNED:
1279 case TYPESPEC_BOOL:
1280 case TYPESPEC_COMPLEX:
1281 case TYPESPEC_IMAGINARY:
1282 case TYPESPEC_CONST:
1283 case TYPESPEC_ID_TYPE:
add40b62 1284 return ctf_declaration_type_specifier_visit(fd, depth,
78af2bcd 1285 type_specifier_list, declaration_scope);
a0720417 1286 default:
78af2bcd 1287 fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
a0720417 1288 return NULL;
add40b62 1289 }
05628561
MD
1290}
1291
1292static
1293int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event *event, struct ctf_trace *trace)
1294{
1295 int ret = 0;
1296
1297 switch (node->type) {
1298 case NODE_TYPEDEF:
1299 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1300 event->declaration_scope,
78af2bcd 1301 node->u._typedef.type_specifier_list,
05628561 1302 &node->u._typedef.type_declarators,
a0720417 1303 trace);
05628561
MD
1304 if (ret)
1305 return ret;
1306 break;
1307 case NODE_TYPEALIAS:
1308 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1309 event->declaration_scope,
1310 node->u.typealias.target, node->u.typealias.alias,
1311 trace);
05628561
MD
1312 if (ret)
1313 return ret;
1314 break;
1315 case NODE_CTF_EXPRESSION:
1316 {
1317 char *left;
1318
1319 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1320 if (!strcmp(left, "name")) {
1321 char *right;
1322
427c09b7
MD
1323 if (CTF_EVENT_FIELD_IS_SET(event, name)) {
1324 fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
0f980a35
MD
1325 ret = -EPERM;
1326 goto error;
427c09b7 1327 }
05628561
MD
1328 right = concatenate_unary_strings(&node->u.ctf_expression.right);
1329 if (!right) {
78af2bcd 1330 fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
0f980a35
MD
1331 ret = -EINVAL;
1332 goto error;
05628561
MD
1333 }
1334 event->name = g_quark_from_string(right);
41253107 1335 g_free(right);
05628561
MD
1336 CTF_EVENT_SET_FIELD(event, name);
1337 } else if (!strcmp(left, "id")) {
427c09b7
MD
1338 if (CTF_EVENT_FIELD_IS_SET(event, id)) {
1339 fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
0f980a35
MD
1340 ret = -EPERM;
1341 goto error;
427c09b7 1342 }
05628561
MD
1343 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
1344 if (ret) {
78af2bcd 1345 fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
0f980a35
MD
1346 ret = -EINVAL;
1347 goto error;
05628561
MD
1348 }
1349 CTF_EVENT_SET_FIELD(event, id);
1350 } else if (!strcmp(left, "stream_id")) {
427c09b7
MD
1351 if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
1352 fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
0f980a35
MD
1353 ret = -EPERM;
1354 goto error;
427c09b7 1355 }
05628561
MD
1356 ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
1357 if (ret) {
78af2bcd 1358 fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
0f980a35
MD
1359 ret = -EINVAL;
1360 goto error;
05628561
MD
1361 }
1362 event->stream = trace_stream_lookup(trace, event->stream_id);
1363 if (!event->stream) {
78af2bcd 1364 fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
0f980a35
MD
1365 ret = -EINVAL;
1366 goto error;
05628561 1367 }
05628561
MD
1368 CTF_EVENT_SET_FIELD(event, stream_id);
1369 } else if (!strcmp(left, "context")) {
1370 struct declaration *declaration;
1371
427c09b7
MD
1372 if (event->context_decl) {
1373 fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
0f980a35
MD
1374 ret = -EINVAL;
1375 goto error;
427c09b7 1376 }
78af2bcd
MD
1377 declaration = ctf_type_specifier_list_visit(fd, depth,
1378 _cds_list_first_entry(&node->u.ctf_expression.right,
1379 struct ctf_node, siblings),
ab4cf058 1380 event->declaration_scope, trace);
0f980a35
MD
1381 if (!declaration) {
1382 ret = -EPERM;
1383 goto error;
1384 }
1385 if (declaration->id != CTF_TYPE_STRUCT) {
1386 ret = -EPERM;
1387 goto error;
1388 }
9e29e16e 1389 event->context_decl = container_of(declaration, struct declaration_struct, p);
05628561
MD
1390 } else if (!strcmp(left, "fields")) {
1391 struct declaration *declaration;
1392
427c09b7
MD
1393 if (event->fields_decl) {
1394 fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
0f980a35
MD
1395 ret = -EINVAL;
1396 goto error;
427c09b7 1397 }
78af2bcd
MD
1398 declaration = ctf_type_specifier_list_visit(fd, depth,
1399 _cds_list_first_entry(&node->u.ctf_expression.right,
1400 struct ctf_node, siblings),
ab4cf058 1401 event->declaration_scope, trace);
0f980a35
MD
1402 if (!declaration) {
1403 ret = -EPERM;
1404 goto error;
1405 }
1406 if (declaration->id != CTF_TYPE_STRUCT) {
1407 ret = -EPERM;
1408 goto error;
1409 }
9e29e16e 1410 event->fields_decl = container_of(declaration, struct declaration_struct, p);
05628561 1411 }
0f980a35 1412error:
41253107 1413 g_free(left);
05628561
MD
1414 break;
1415 }
1416 default:
1417 return -EPERM;
1418 /* TODO: declaration specifier should be added. */
1419 }
1420
0f980a35 1421 return ret;
05628561
MD
1422}
1423
1424static
1425int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1426 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1427{
1428 int ret = 0;
1429 struct ctf_node *iter;
1430 struct ctf_event *event;
9e29e16e 1431 struct definition_scope *parent_def_scope;
05628561
MD
1432
1433 event = g_new0(struct ctf_event, 1);
d20f5e59 1434 event->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561
MD
1435 cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
1436 ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
1437 if (ret)
1438 goto error;
1439 }
1440 if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
1441 ret = -EPERM;
427c09b7 1442 fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
05628561
MD
1443 goto error;
1444 }
0f980a35
MD
1445 /* Allow only one event without id per stream */
1446 if (!CTF_EVENT_FIELD_IS_SET(event, id)
1447 && event->stream->events_by_id->len != 0) {
05628561 1448 ret = -EPERM;
427c09b7 1449 fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
05628561
MD
1450 goto error;
1451 }
1452 if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
0f980a35
MD
1453 /* Allow missing stream_id if there is only a single stream */
1454 if (trace->streams->len == 1) {
1455 event->stream_id = 0;
1456 event->stream = trace_stream_lookup(trace, event->stream_id);
1457 } else {
1458 ret = -EPERM;
1459 fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
1460 goto error;
1461 }
05628561
MD
1462 }
1463 if (event->stream->events_by_id->len <= event->id)
1464 g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
1465 g_ptr_array_index(event->stream->events_by_id, event->id) = event;
1466 g_hash_table_insert(event->stream->event_quark_to_id,
1467 (gpointer)(unsigned long) event->name,
1468 &event->id);
a0720417 1469 parent_def_scope = event->stream->definition_scope;
9e29e16e
MD
1470 if (event->context_decl) {
1471 event->context =
a0720417
MD
1472 container_of(
1473 event->context_decl->p.definition_new(&event->context_decl->p,
1474 parent_def_scope, 0, 0),
1475 struct definition_struct, p);
6a36ddca
MD
1476 set_dynamic_definition_scope(&event->context->p,
1477 event->context->scope,
d00d17d1 1478 "event.context");
9e29e16e 1479 parent_def_scope = event->context->scope;
a0720417 1480 declaration_unref(&event->context_decl->p);
9e29e16e
MD
1481 }
1482 if (event->fields_decl) {
1483 event->fields =
a0720417
MD
1484 container_of(
1485 event->fields_decl->p.definition_new(&event->fields_decl->p,
1486 parent_def_scope, 0, 0),
1487 struct definition_struct, p);
6a36ddca
MD
1488 set_dynamic_definition_scope(&event->fields->p,
1489 event->fields->scope,
d00d17d1 1490 "event.fields");
9e29e16e 1491 parent_def_scope = event->fields->scope;
a0720417 1492 declaration_unref(&event->fields_decl->p);
9e29e16e 1493 }
05628561
MD
1494 return 0;
1495
1496error:
a0720417
MD
1497 declaration_unref(&event->fields_decl->p);
1498 declaration_unref(&event->context_decl->p);
d20f5e59 1499 free_declaration_scope(event->declaration_scope);
05628561
MD
1500 g_free(event);
1501 return ret;
1502}
1503
1504
1505static
1506int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
1507{
1508 int ret = 0;
1509
1510 switch (node->type) {
1511 case NODE_TYPEDEF:
1512 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1513 stream->declaration_scope,
78af2bcd 1514 node->u._typedef.type_specifier_list,
05628561 1515 &node->u._typedef.type_declarators,
a0720417 1516 trace);
05628561
MD
1517 if (ret)
1518 return ret;
1519 break;
1520 case NODE_TYPEALIAS:
1521 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1522 stream->declaration_scope,
1523 node->u.typealias.target, node->u.typealias.alias,
1524 trace);
05628561
MD
1525 if (ret)
1526 return ret;
1527 break;
1528 case NODE_CTF_EXPRESSION:
1529 {
1530 char *left;
1531
1532 left = concatenate_unary_strings(&node->u.ctf_expression.left);
427c09b7
MD
1533 if (!strcmp(left, "id")) {
1534 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1535 fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
0f980a35
MD
1536 ret = -EPERM;
1537 goto error;
427c09b7 1538 }
a0720417 1539 ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
05628561 1540 if (ret) {
427c09b7 1541 fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
0f980a35
MD
1542 ret = -EINVAL;
1543 goto error;
05628561 1544 }
a0720417 1545 CTF_STREAM_SET_FIELD(stream, stream_id);
9e29e16e 1546 } else if (!strcmp(left, "event.header")) {
05628561
MD
1547 struct declaration *declaration;
1548
427c09b7
MD
1549 if (stream->event_header_decl) {
1550 fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
0f980a35
MD
1551 ret = -EINVAL;
1552 goto error;
427c09b7 1553 }
78af2bcd
MD
1554 declaration = ctf_type_specifier_list_visit(fd, depth,
1555 _cds_list_first_entry(&node->u.ctf_expression.right,
1556 struct ctf_node, siblings),
a0720417 1557 stream->declaration_scope, trace);
0f980a35
MD
1558 if (!declaration) {
1559 ret = -EPERM;
1560 goto error;
1561 }
1562 if (declaration->id != CTF_TYPE_STRUCT) {
1563 ret = -EPERM;
1564 goto error;
1565 }
9e29e16e
MD
1566 stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
1567 } else if (!strcmp(left, "event.context")) {
05628561
MD
1568 struct declaration *declaration;
1569
427c09b7
MD
1570 if (stream->event_context_decl) {
1571 fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
0f980a35
MD
1572 ret = -EINVAL;
1573 goto error;
427c09b7 1574 }
78af2bcd
MD
1575 declaration = ctf_type_specifier_list_visit(fd, depth,
1576 _cds_list_first_entry(&node->u.ctf_expression.right,
1577 struct ctf_node, siblings),
ab4cf058 1578 stream->declaration_scope, trace);
0f980a35
MD
1579 if (!declaration) {
1580 ret = -EPERM;
1581 goto error;
1582 }
1583 if (declaration->id != CTF_TYPE_STRUCT) {
1584 ret = -EPERM;
1585 goto error;
1586 }
9e29e16e
MD
1587 stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
1588 } else if (!strcmp(left, "packet.context")) {
05628561
MD
1589 struct declaration *declaration;
1590
427c09b7
MD
1591 if (stream->packet_context_decl) {
1592 fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
0f980a35
MD
1593 ret = -EINVAL;
1594 goto error;
427c09b7 1595 }
78af2bcd
MD
1596 declaration = ctf_type_specifier_list_visit(fd, depth,
1597 _cds_list_first_entry(&node->u.ctf_expression.right,
1598 struct ctf_node, siblings),
ab4cf058 1599 stream->declaration_scope, trace);
0f980a35
MD
1600 if (!declaration) {
1601 ret = -EPERM;
1602 goto error;
1603 }
1604 if (declaration->id != CTF_TYPE_STRUCT) {
1605 ret = -EPERM;
1606 goto error;
1607 }
9e29e16e 1608 stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
05628561 1609 }
0f980a35 1610error:
41253107 1611 g_free(left);
05628561
MD
1612 break;
1613 }
1614 default:
1615 return -EPERM;
1616 /* TODO: declaration specifier should be added. */
1617 }
1618
0f980a35 1619 return ret;
05628561
MD
1620}
1621
1622static
1623int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
d20f5e59 1624 struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
05628561
MD
1625{
1626 int ret = 0;
1627 struct ctf_node *iter;
1628 struct ctf_stream *stream;
9e29e16e 1629 struct definition_scope *parent_def_scope;
05628561
MD
1630
1631 stream = g_new0(struct ctf_stream, 1);
d20f5e59 1632 stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
05628561 1633 stream->events_by_id = g_ptr_array_new();
068665f5 1634 stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
0f980a35 1635 stream->files = g_ptr_array_new();
05628561
MD
1636 cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
1637 ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
1638 if (ret)
1639 goto error;
1640 }
0f980a35
MD
1641 if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
1642 /* check that packet header has stream_id field. */
1643 if (!trace->packet_header_decl
1644 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
1645 ret = -EPERM;
1646 fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
1647 goto error;
1648 }
1649 }
1650
1651 /* Allow only one id-less stream */
1652 if (!CTF_STREAM_FIELD_IS_SET(stream, stream_id)
1653 && trace->streams->len != 0) {
05628561 1654 ret = -EPERM;
427c09b7 1655 fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
05628561
MD
1656 goto error;
1657 }
1658 if (trace->streams->len <= stream->stream_id)
1659 g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
1660 g_ptr_array_index(trace->streams, stream->stream_id) = stream;
9e29e16e 1661
0f980a35 1662 parent_def_scope = trace->definition_scope;
9e29e16e
MD
1663 if (stream->packet_context_decl) {
1664 stream->packet_context =
a0720417
MD
1665 container_of(
1666 stream->packet_context_decl->p.definition_new(&stream->packet_context_decl->p,
1667 parent_def_scope, 0, 0),
1668 struct definition_struct, p);
6a36ddca
MD
1669 set_dynamic_definition_scope(&stream->packet_context->p,
1670 stream->packet_context->scope,
d00d17d1 1671 "stream.packet.context");
9e29e16e 1672 parent_def_scope = stream->packet_context->scope;
a0720417 1673 declaration_unref(&stream->packet_context_decl->p);
9e29e16e
MD
1674 }
1675 if (stream->event_header_decl) {
1676 stream->event_header =
a0720417
MD
1677 container_of(
1678 stream->event_header_decl->p.definition_new(&stream->event_header_decl->p,
1679 parent_def_scope, 0, 0),
1680 struct definition_struct, p);
6a36ddca
MD
1681 set_dynamic_definition_scope(&stream->event_header->p,
1682 stream->event_header->scope,
d00d17d1 1683 "stream.event.header");
9e29e16e 1684 parent_def_scope = stream->event_header->scope;
a0720417 1685 declaration_unref(&stream->event_header_decl->p);
9e29e16e
MD
1686 }
1687 if (stream->event_context_decl) {
1688 stream->event_context =
a0720417
MD
1689 container_of(
1690 stream->event_context_decl->p.definition_new(&stream->event_context_decl->p,
1691 parent_def_scope, 0, 0),
1692 struct definition_struct, p);
6a36ddca
MD
1693 set_dynamic_definition_scope(&stream->event_context->p,
1694 stream->event_context->scope,
d00d17d1 1695 "stream.event.context");
9e29e16e 1696 parent_def_scope = stream->event_context->scope;
a0720417 1697 declaration_unref(&stream->event_context_decl->p);
9e29e16e 1698 }
41253107 1699 stream->definition_scope = parent_def_scope;
9e29e16e 1700
05628561
MD
1701 return 0;
1702
1703error:
a0720417
MD
1704 declaration_unref(&stream->event_header_decl->p);
1705 declaration_unref(&stream->event_context_decl->p);
1706 declaration_unref(&stream->packet_context_decl->p);
0f980a35 1707 g_ptr_array_free(stream->files, TRUE);
05628561 1708 g_ptr_array_free(stream->events_by_id, TRUE);
a0720417 1709 g_hash_table_destroy(stream->event_quark_to_id);
d20f5e59 1710 free_declaration_scope(stream->declaration_scope);
05628561
MD
1711 g_free(stream);
1712 return ret;
1713}
1714
1715static
1716int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1717{
1718 int ret = 0;
1719
1720 switch (node->type) {
1721 case NODE_TYPEDEF:
1722 ret = ctf_typedef_visit(fd, depth + 1,
a0720417 1723 trace->declaration_scope,
78af2bcd 1724 node->u._typedef.type_specifier_list,
05628561 1725 &node->u._typedef.type_declarators,
a0720417 1726 trace);
05628561
MD
1727 if (ret)
1728 return ret;
1729 break;
1730 case NODE_TYPEALIAS:
1731 ret = ctf_typealias_visit(fd, depth + 1,
a0720417
MD
1732 trace->declaration_scope,
1733 node->u.typealias.target, node->u.typealias.alias,
1734 trace);
05628561
MD
1735 if (ret)
1736 return ret;
1737 break;
1738 case NODE_CTF_EXPRESSION:
1739 {
1740 char *left;
1741
1742 left = concatenate_unary_strings(&node->u.ctf_expression.left);
1743 if (!strcmp(left, "major")) {
427c09b7
MD
1744 if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
1745 fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
0f980a35
MD
1746 ret = -EPERM;
1747 goto error;
427c09b7 1748 }
05628561
MD
1749 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
1750 if (ret) {
78af2bcd 1751 fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
0f980a35
MD
1752 ret = -EINVAL;
1753 goto error;
05628561 1754 }
a0720417 1755 CTF_TRACE_SET_FIELD(trace, major);
05628561 1756 } else if (!strcmp(left, "minor")) {
427c09b7
MD
1757 if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
1758 fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
0f980a35
MD
1759 ret = -EPERM;
1760 goto error;
427c09b7 1761 }
05628561
MD
1762 ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
1763 if (ret) {
78af2bcd 1764 fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
0f980a35
MD
1765 ret = -EINVAL;
1766 goto error;
05628561 1767 }
a0720417 1768 CTF_TRACE_SET_FIELD(trace, minor);
05628561 1769 } else if (!strcmp(left, "uuid")) {
427c09b7
MD
1770 if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
1771 fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
0f980a35
MD
1772 ret = -EPERM;
1773 goto error;
427c09b7 1774 }
05628561
MD
1775 ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
1776 if (ret) {
78af2bcd 1777 fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
0f980a35
MD
1778 ret = -EINVAL;
1779 goto error;
05628561 1780 }
a0720417 1781 CTF_TRACE_SET_FIELD(trace, uuid);
0f980a35
MD
1782 } else if (!strcmp(left, "byte_order")) {
1783 struct ctf_node *right;
1784 int byte_order;
1785
1786 if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1787 fprintf(fd, "[error] %s: endianness already declared in trace declaration\n", __func__);
1788 ret = -EPERM;
1789 goto error;
1790 }
1791 right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
1792 byte_order = get_trace_byte_order(fd, depth, right);
1793 if (byte_order < 0)
1794 return -EINVAL;
1795 trace->byte_order = byte_order;
1796 CTF_TRACE_SET_FIELD(trace, byte_order);
1797 } else if (!strcmp(left, "packet.header")) {
1798 struct declaration *declaration;
1799
1800 if (trace->packet_header_decl) {
1801 fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
1802 ret = -EINVAL;
1803 goto error;
1804 }
1805 declaration = ctf_type_specifier_list_visit(fd, depth,
1806 _cds_list_first_entry(&node->u.ctf_expression.right,
1807 struct ctf_node, siblings),
1808 trace->declaration_scope, trace);
1809 if (!declaration) {
1810 ret = -EPERM;
1811 goto error;
1812 }
1813 if (declaration->id != CTF_TYPE_STRUCT) {
1814 ret = -EPERM;
1815 goto error;
1816 }
1817 trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
05628561 1818 }
0f980a35 1819error:
41253107 1820 g_free(left);
05628561
MD
1821 break;
1822 }
1823 default:
1824 return -EPERM;
1825 /* TODO: declaration specifier should be added. */
1826 }
1827
0f980a35 1828 return ret;
05628561
MD
1829}
1830
05628561
MD
1831static
1832int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1833{
0f980a35 1834 struct definition_scope *parent_def_scope;
05628561
MD
1835 int ret = 0;
1836 struct ctf_node *iter;
1837
d20f5e59 1838 if (trace->declaration_scope)
05628561 1839 return -EEXIST;
d20f5e59 1840 trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
05628561
MD
1841 trace->streams = g_ptr_array_new();
1842 cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
1843 ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
1844 if (ret)
1845 goto error;
1846 }
a0720417 1847 if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
05628561 1848 ret = -EPERM;
427c09b7 1849 fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
05628561
MD
1850 goto error;
1851 }
a0720417 1852 if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
05628561 1853 ret = -EPERM;
427c09b7 1854 fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
05628561
MD
1855 goto error;
1856 }
a0720417 1857 if (!CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
05628561 1858 ret = -EPERM;
427c09b7 1859 fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
05628561
MD
1860 goto error;
1861 }
dc48ecad
MD
1862 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1863 ret = -EPERM;
1864 fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
1865 goto error;
1866 }
0f980a35
MD
1867
1868 parent_def_scope = NULL;
1869 if (trace->packet_header_decl) {
1870 trace->packet_header =
1871 container_of(
1872 trace->packet_header_decl->p.definition_new(&trace->packet_header_decl->p,
1873 parent_def_scope, 0, 0),
1874 struct definition_struct, p);
1875 set_dynamic_definition_scope(&trace->packet_header->p,
1876 trace->packet_header->scope,
1877 "trace.packet.header");
1878 parent_def_scope = trace->packet_header->scope;
1879 declaration_unref(&trace->packet_header_decl->p);
1880 }
1881 trace->definition_scope = parent_def_scope;
1882
1883 if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
1884 /* check that the packet header contains a "magic" field */
1885 if (!trace->packet_header
1886 || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
1887 ret = -EPERM;
1888 fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
1889 goto error_free_def;
1890 }
1891 }
05628561
MD
1892 return 0;
1893
0f980a35
MD
1894error_free_def:
1895 definition_unref(&trace->packet_header->p);
05628561
MD
1896error:
1897 g_ptr_array_free(trace->streams, TRUE);
a0720417 1898 free_declaration_scope(trace->declaration_scope);
05628561
MD
1899 return ret;
1900}
1901
78af2bcd
MD
1902static
1903int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
1904{
1905 int ret = 0;
1906
1907 switch (node->type) {
1908 case NODE_TYPEDEF:
1909 ret = ctf_typedef_visit(fd, depth + 1,
1910 trace->root_declaration_scope,
1911 node->u._typedef.type_specifier_list,
1912 &node->u._typedef.type_declarators,
1913 trace);
1914 if (ret)
1915 return ret;
1916 break;
1917 case NODE_TYPEALIAS:
1918 ret = ctf_typealias_visit(fd, depth + 1,
1919 trace->root_declaration_scope,
1920 node->u.typealias.target, node->u.typealias.alias,
1921 trace);
1922 if (ret)
1923 return ret;
1924 break;
1925 case NODE_TYPE_SPECIFIER_LIST:
1926 {
1927 struct declaration *declaration;
1928
1929 /*
1930 * Just add the type specifier to the root scope
1931 * declaration scope. Release local reference.
1932 */
1933 declaration = ctf_type_specifier_list_visit(fd, depth + 1,
1934 node, trace->root_declaration_scope, trace);
1935 if (!declaration)
1936 return -ENOMEM;
1937 declaration_unref(declaration);
1938 break;
1939 }
1940 default:
1941 return -EPERM;
1942 }
1943
1944 return 0;
1945}
1946
ab4cf058
MD
1947int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
1948 struct ctf_trace *trace, int byte_order)
05628561
MD
1949{
1950 int ret = 0;
1951 struct ctf_node *iter;
1952
78af2bcd
MD
1953 fprintf(fd, "CTF visitor: metadata construction... ");
1954 trace->root_declaration_scope = new_declaration_scope(NULL);
ab4cf058
MD
1955 trace->byte_order = byte_order;
1956
05628561
MD
1957 switch (node->type) {
1958 case NODE_ROOT:
3e11b713 1959 cds_list_for_each_entry(iter, &node->u.root.declaration_list,
05628561 1960 siblings) {
78af2bcd 1961 ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
427c09b7
MD
1962 if (ret) {
1963 fprintf(fd, "[error] %s: root declaration error\n", __func__);
78af2bcd 1964 return ret;
427c09b7 1965 }
05628561
MD
1966 }
1967 cds_list_for_each_entry(iter, &node->u.root.trace, siblings) {
1968 ret = ctf_trace_visit(fd, depth + 1, iter, trace);
427c09b7
MD
1969 if (ret) {
1970 fprintf(fd, "[error] %s: trace declaration error\n", __func__);
05628561 1971 return ret;
427c09b7 1972 }
05628561 1973 }
5039b4cc
MD
1974 if (!trace->streams) {
1975 fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
1976 return -EINVAL;
1977 }
05628561
MD
1978 cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
1979 ret = ctf_stream_visit(fd, depth + 1, iter,
41253107 1980 trace->root_declaration_scope, trace);
427c09b7
MD
1981 if (ret) {
1982 fprintf(fd, "[error] %s: stream declaration error\n", __func__);
05628561 1983 return ret;
427c09b7 1984 }
05628561
MD
1985 }
1986 cds_list_for_each_entry(iter, &node->u.root.event, siblings) {
1987 ret = ctf_event_visit(fd, depth + 1, iter,
41253107 1988 trace->root_declaration_scope, trace);
427c09b7
MD
1989 if (ret) {
1990 fprintf(fd, "[error] %s: event declaration error\n", __func__);
05628561 1991 return ret;
427c09b7 1992 }
05628561
MD
1993 }
1994 break;
05628561
MD
1995 case NODE_UNKNOWN:
1996 default:
78af2bcd 1997 fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
05628561
MD
1998 (int) node->type);
1999 return -EINVAL;
2000 }
78af2bcd 2001 fprintf(fd, "done.\n");
05628561
MD
2002 return ret;
2003}
This page took 0.120798 seconds and 4 git commands to generate.