4 * BabelTrace - Converter
8 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
10 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
12 * Permission is hereby granted, free of charge, to any person obtaining a copy
13 * of this software and associated documentation files (the "Software"), to deal
14 * in the Software without restriction, including without limitation the rights
15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the Software is
17 * furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
23 #include <babeltrace/format.h>
24 #include <babeltrace/babeltrace-internal.h>
25 #include <babeltrace/types.h>
31 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
37 str
= g_string_new(prefix
);
38 g_string_append(str
, g_quark_to_string(quark
));
39 quark_str
= g_string_free(str
, FALSE
);
40 nq
= g_quark_from_string(quark_str
);
47 lookup_declaration_scope(GQuark declaration_name
,
48 struct declaration_scope
*scope
)
50 return g_hash_table_lookup(scope
->typedef_declarations
,
51 (gconstpointer
) (unsigned long) declaration_name
);
54 struct declaration
*lookup_declaration(GQuark declaration_name
,
55 struct declaration_scope
*scope
)
57 struct declaration
*declaration
;
60 declaration
= lookup_declaration_scope(declaration_name
,
64 scope
= scope
->parent_scope
;
69 int register_declaration(GQuark name
, struct declaration
*declaration
,
70 struct declaration_scope
*scope
)
75 /* Only lookup in local scope */
76 if (lookup_declaration_scope(name
, scope
))
79 g_hash_table_insert(scope
->typedef_declarations
,
80 (gpointer
) (unsigned long) name
,
82 declaration_ref(declaration
);
88 lookup_field_definition_scope(GQuark field_name
,
89 struct definition_scope
*scope
)
91 return g_hash_table_lookup(scope
->definitions
,
92 (gconstpointer
) (unsigned long) field_name
);
96 * Returns the index at which the paths differ.
97 * If the value returned equals len, it means the paths are identical
98 * from index 0 to len-1.
100 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
104 assert(len
<= a
->len
);
105 assert(len
<= b
->len
);
107 for (i
= 0; i
< len
; i
++) {
110 qa
= g_array_index(a
, GQuark
, i
);
111 qb
= g_array_index(b
, GQuark
, i
);
118 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
122 if (babeltrace_debug
) {
125 printf_debug("Is path \"");
126 for (i
= 0; i
< path
->len
; need_dot
= 1, i
++)
127 printf("%s%s", need_dot
? "." : "",
128 g_quark_to_string(g_array_index(path
, GQuark
, i
)));
130 printf("\" child of \"");
131 for (i
= 0; i
< maybe_parent
->len
; need_dot
= 1, i
++)
132 printf("%s%s", need_dot
? "." : "",
133 g_quark_to_string(g_array_index(maybe_parent
, GQuark
, i
)));
137 if (path
->len
<= maybe_parent
->len
) {
141 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
142 == maybe_parent
->len
)
147 if (babeltrace_debug
)
148 printf("%s\n", ret
? "Yes" : "No");
152 static struct definition_scope
*
153 get_definition_scope(const struct definition
*definition
)
155 return definition
->scope
;
159 * OK, here is the fun. We want to lookup a field that is:
160 * - either in the same dynamic scope:
161 * - either in the current scope, but prior to the current field.
162 * - or in a parent scope (or parent of parent ...) still in a field
163 * prior to the current field position within the parents.
164 * - or in a different dynamic scope:
165 * - either in a upper dynamic scope (walk down a targeted scope from
166 * the dynamic scope root)
167 * - or in a lower dynamic scope (failure)
168 * The dynamic scope roots are linked together, so we can access the
169 * parent dynamic scope from the child dynamic scope by walking up to
171 * If we cannot find such a field that is prior to our current path, we
174 * cur_path: the path leading to the variant definition.
175 * lookup_path: the path leading to the enum we want to look for.
176 * scope: the definition scope containing the variant definition.
179 lookup_path_definition(GArray
*cur_path
,
181 struct definition_scope
*scope
)
183 struct definition
*definition
, *lookup_definition
;
187 /* Going up in the hierarchy. Check where we come from. */
188 assert(is_path_child_of(cur_path
, scope
->scope_path
));
189 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
192 * First, check if the target name is size one, present in
193 * our parent path, located prior to us.
195 if (lookup_path
->len
== 1) {
196 last
= g_array_index(lookup_path
, GQuark
, 0);
197 lookup_definition
= lookup_field_definition_scope(last
, scope
);
198 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
199 definition
= lookup_field_definition_scope(last
, scope
);
201 if (lookup_definition
&& lookup_definition
->index
< definition
->index
)
202 return lookup_definition
;
208 if (is_path_child_of(cur_path
, scope
->scope_path
) &&
209 cur_path
->len
- scope
->scope_path
->len
== 1) {
210 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
211 definition
= lookup_field_definition_scope(last
, scope
);
213 index
= definition
->index
;
216 * Getting to a dynamic scope parent. We are
217 * guaranteed that the parent is entirely
218 * located before the child.
223 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
224 /* Means we can lookup the field in this scope */
225 last
= g_array_index(lookup_path
, GQuark
,
226 scope
->scope_path
->len
);
227 lookup_definition
= lookup_field_definition_scope(last
, scope
);
228 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
230 /* Found it! And it is prior to the current field. */
231 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
233 return lookup_definition
;
235 scope
= get_definition_scope(lookup_definition
);
236 /* Check if the definition has a sub-scope */
240 * Don't compare index anymore, because we are
241 * going within a scope that has been validated
242 * to be entirely prior to the current scope.
249 /* lookup_path is within an upper scope */
250 cur_path
= scope
->scope_path
;
251 scope
= scope
->parent_scope
;
257 int register_field_definition(GQuark field_name
, struct definition
*definition
,
258 struct definition_scope
*scope
)
260 if (!scope
|| !field_name
)
263 /* Only lookup in local scope */
264 if (lookup_field_definition_scope(field_name
, scope
))
267 g_hash_table_insert(scope
->definitions
,
268 (gpointer
) (unsigned long) field_name
,
270 /* Don't keep reference on definition */
274 void declaration_ref(struct declaration
*declaration
)
279 void declaration_unref(struct declaration
*declaration
)
283 if (!--declaration
->ref
)
284 declaration
->declaration_free(declaration
);
287 void definition_ref(struct definition
*definition
)
292 void definition_unref(struct definition
*definition
)
296 if (!--definition
->ref
)
297 definition
->declaration
->definition_free(definition
);
300 struct declaration_scope
*
301 new_declaration_scope(struct declaration_scope
*parent_scope
)
303 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
305 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
306 g_direct_equal
, NULL
,
307 (GDestroyNotify
) declaration_unref
);
308 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
309 g_direct_equal
, NULL
,
310 (GDestroyNotify
) declaration_unref
);
311 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
312 g_direct_equal
, NULL
,
313 (GDestroyNotify
) declaration_unref
);
314 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
315 g_direct_equal
, NULL
,
316 (GDestroyNotify
) declaration_unref
);
317 scope
->parent_scope
= parent_scope
;
321 void free_declaration_scope(struct declaration_scope
*scope
)
323 g_hash_table_destroy(scope
->enum_declarations
);
324 g_hash_table_destroy(scope
->variant_declarations
);
325 g_hash_table_destroy(scope
->struct_declarations
);
326 g_hash_table_destroy(scope
->typedef_declarations
);
331 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
332 struct declaration_scope
*scope
)
334 return g_hash_table_lookup(scope
->struct_declarations
,
335 (gconstpointer
) (unsigned long) struct_name
);
338 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
339 struct declaration_scope
*scope
)
341 struct declaration_struct
*declaration
;
344 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
347 scope
= scope
->parent_scope
;
352 int register_struct_declaration(GQuark struct_name
,
353 struct declaration_struct
*struct_declaration
,
354 struct declaration_scope
*scope
)
362 /* Only lookup in local scope */
363 if (lookup_struct_declaration_scope(struct_name
, scope
))
366 g_hash_table_insert(scope
->struct_declarations
,
367 (gpointer
) (unsigned long) struct_name
,
369 declaration_ref(&struct_declaration
->p
);
371 /* Also add in typedef/typealias scopes */
372 prefix_name
= prefix_quark("struct ", struct_name
);
373 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
379 struct declaration_untagged_variant
*
380 lookup_variant_declaration_scope(GQuark variant_name
,
381 struct declaration_scope
*scope
)
383 return g_hash_table_lookup(scope
->variant_declarations
,
384 (gconstpointer
) (unsigned long) variant_name
);
387 struct declaration_untagged_variant
*
388 lookup_variant_declaration(GQuark variant_name
,
389 struct declaration_scope
*scope
)
391 struct declaration_untagged_variant
*declaration
;
394 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
397 scope
= scope
->parent_scope
;
402 int register_variant_declaration(GQuark variant_name
,
403 struct declaration_untagged_variant
*untagged_variant_declaration
,
404 struct declaration_scope
*scope
)
412 /* Only lookup in local scope */
413 if (lookup_variant_declaration_scope(variant_name
, scope
))
416 g_hash_table_insert(scope
->variant_declarations
,
417 (gpointer
) (unsigned long) variant_name
,
418 untagged_variant_declaration
);
419 declaration_ref(&untagged_variant_declaration
->p
);
421 /* Also add in typedef/typealias scopes */
422 prefix_name
= prefix_quark("variant ", variant_name
);
423 ret
= register_declaration(prefix_name
,
424 &untagged_variant_declaration
->p
, scope
);
430 struct declaration_enum
*
431 lookup_enum_declaration_scope(GQuark enum_name
,
432 struct declaration_scope
*scope
)
434 return g_hash_table_lookup(scope
->enum_declarations
,
435 (gconstpointer
) (unsigned long) enum_name
);
438 struct declaration_enum
*
439 lookup_enum_declaration(GQuark enum_name
,
440 struct declaration_scope
*scope
)
442 struct declaration_enum
*declaration
;
445 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
448 scope
= scope
->parent_scope
;
453 int register_enum_declaration(GQuark enum_name
,
454 struct declaration_enum
*enum_declaration
,
455 struct declaration_scope
*scope
)
463 /* Only lookup in local scope */
464 if (lookup_enum_declaration_scope(enum_name
, scope
))
467 g_hash_table_insert(scope
->enum_declarations
,
468 (gpointer
) (unsigned long) enum_name
,
470 declaration_ref(&enum_declaration
->p
);
472 /* Also add in typedef/typealias scopes */
473 prefix_name
= prefix_quark("enum ", enum_name
);
474 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
479 static struct definition_scope
*
480 _new_definition_scope(struct definition_scope
*parent_scope
,
483 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
485 scope
->definitions
= g_hash_table_new(g_direct_hash
,
487 scope
->parent_scope
= parent_scope
;
488 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
490 g_array_set_size(scope
->scope_path
, scope_path_len
);
494 GQuark
new_definition_path(struct definition_scope
*parent_scope
,
495 GQuark field_name
, const char *root_name
)
502 str
= g_string_new("");
504 g_string_append(str
, root_name
);
506 } else if (parent_scope
) {
509 for (i
= 0; i
< parent_scope
->scope_path
->len
; i
++) {
510 GQuark q
= g_array_index(parent_scope
->scope_path
,
515 g_string_append(str
, ".");
516 g_string_append(str
, g_quark_to_string(q
));
522 g_string_append(str
, ".");
523 g_string_append(str
, g_quark_to_string(field_name
));
525 c_str
= g_string_free(str
, FALSE
);
526 if (c_str
[0] == '\0')
528 path
= g_quark_from_string(c_str
);
529 printf_debug("new definition path: %s\n", c_str
);
534 struct definition_scope
*
535 new_definition_scope(struct definition_scope
*parent_scope
,
536 GQuark field_name
, const char *root_name
)
538 struct definition_scope
*scope
;
541 scope
= _new_definition_scope(parent_scope
, 0);
542 append_scope_path(root_name
, scope
->scope_path
);
544 int scope_path_len
= 1;
546 assert(parent_scope
);
547 scope_path_len
+= parent_scope
->scope_path
->len
;
548 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
549 memcpy(scope
->scope_path
->data
, parent_scope
->scope_path
->data
,
550 sizeof(GQuark
) * (scope_path_len
- 1));
551 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
554 if (babeltrace_debug
) {
557 printf_debug("new definition scope: ");
558 for (i
= 0; i
< scope
->scope_path
->len
; need_dot
= 1, i
++)
559 printf("%s%s", need_dot
? "." : "",
560 g_quark_to_string(g_array_index(scope
->scope_path
, GQuark
, i
)));
567 * in: path (dot separated), out: q (GArray of GQuark)
569 void append_scope_path(const char *path
, GArray
*q
)
571 const char *ptrbegin
, *ptrend
= path
;
579 ptrend
= strchr(ptrbegin
, '.');
582 len
= ptrend
- ptrbegin
;
583 /* Don't accept two consecutive dots */
585 str
= g_new(char, len
+ 1); /* include \0 */
586 memcpy(str
, ptrbegin
, len
);
588 quark
= g_quark_from_string(str
);
589 g_array_append_val(q
, quark
);
591 ptrend
++; /* skip current dot */
593 /* last. Check for trailing dot (and discard). */
594 if (ptrbegin
[0] != '\0') {
595 quark
= g_quark_from_string(ptrbegin
);
596 g_array_append_val(q
, quark
);
600 void free_definition_scope(struct definition_scope
*scope
)
602 g_array_free(scope
->scope_path
, TRUE
);
603 g_hash_table_destroy(scope
->definitions
);
607 struct definition
*lookup_definition(const struct definition
*definition
,
608 const char *field_name
)
610 struct definition_scope
*scope
= get_definition_scope(definition
);
615 return lookup_field_definition_scope(g_quark_from_string(field_name
),
619 struct definition_integer
*lookup_integer(const struct definition
*definition
,
620 const char *field_name
,
623 struct definition
*lookup
;
624 struct definition_integer
*lookup_integer
;
626 lookup
= lookup_definition(definition
, field_name
);
629 if (lookup
->declaration
->id
!= CTF_TYPE_INTEGER
)
631 lookup_integer
= container_of(lookup
, struct definition_integer
, p
);
632 if (lookup_integer
->declaration
->signedness
!= signedness
)
634 return lookup_integer
;
637 struct definition_enum
*lookup_enum(const struct definition
*definition
,
638 const char *field_name
,
641 struct definition
*lookup
;
642 struct definition_enum
*lookup_enum
;
644 lookup
= lookup_definition(definition
, field_name
);
647 if (lookup
->declaration
->id
!= CTF_TYPE_ENUM
)
649 lookup_enum
= container_of(lookup
, struct definition_enum
, p
);
650 if (lookup_enum
->integer
->declaration
->signedness
!= signedness
)
655 struct definition
*lookup_variant(const struct definition
*definition
,
656 const char *field_name
)
658 struct definition
*lookup
;
659 struct definition_variant
*lookup_variant
;
661 lookup
= lookup_definition(definition
, field_name
);
664 if (lookup
->declaration
->id
!= CTF_TYPE_VARIANT
)
666 lookup_variant
= container_of(lookup
, struct definition_variant
, p
);
667 lookup
= variant_get_current_field(lookup_variant
);