4 * BabelTrace - Converter
8 * Copyright 2010, 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
21 #include <babeltrace/format.h>
22 #include <babeltrace/babeltrace.h>
28 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
33 str
= g_string_new(prefix
);
34 g_string_append(str
, g_quark_to_string(quark
));
35 nq
= g_quark_from_string(g_string_free(str
, FALSE
));
41 lookup_declaration_scope(GQuark declaration_name
,
42 struct declaration_scope
*scope
)
44 return g_hash_table_lookup(scope
->typedef_declarations
,
45 (gconstpointer
) (unsigned long) declaration_name
);
48 struct declaration
*lookup_declaration(GQuark declaration_name
,
49 struct declaration_scope
*scope
)
51 struct declaration
*declaration
;
54 declaration
= lookup_declaration_scope(declaration_name
,
58 scope
= scope
->parent_scope
;
63 int register_declaration(GQuark name
, struct declaration
*declaration
,
64 struct declaration_scope
*scope
)
69 /* Only lookup in local scope */
70 if (lookup_declaration_scope(name
, scope
))
73 g_hash_table_insert(scope
->typedef_declarations
,
74 (gpointer
) (unsigned long) name
,
76 declaration_ref(declaration
);
82 lookup_field_definition_scope(GQuark field_name
,
83 struct definition_scope
*scope
)
85 return g_hash_table_lookup(scope
->definitions
,
86 (gconstpointer
) (unsigned long) field_name
);
90 * Returns the index at which the paths differ.
91 * If the value returned equals len, it means the paths are identical
92 * from index 0 to len-1.
94 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
98 assert(len
<= a
->len
);
99 assert(len
<= b
->len
);
101 for (i
= 0; i
< len
; i
++) {
104 qa
= g_array_index(a
, GQuark
, i
);
105 qb
= g_array_index(b
, GQuark
, i
);
112 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
116 if (babeltrace_debug
) {
119 printf_debug("Is path \"");
120 for (i
= 0; i
< path
->len
; need_dot
= 1, i
++)
121 printf("%s%s", need_dot
? "." : "",
122 g_quark_to_string(g_array_index(path
, GQuark
, i
)));
124 printf("\" child of \"");
125 for (i
= 0; i
< maybe_parent
->len
; need_dot
= 1, i
++)
126 printf("%s%s", need_dot
? "." : "",
127 g_quark_to_string(g_array_index(maybe_parent
, GQuark
, i
)));
131 if (path
->len
<= maybe_parent
->len
) {
135 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
136 == maybe_parent
->len
)
141 if (babeltrace_debug
)
142 printf("%s\n", ret
? "Yes" : "No");
146 static struct definition_scope
*
147 get_definition_scope(struct definition
*definition
)
149 return definition
->scope
;
153 * OK, here is the fun. We want to lookup a field that is:
154 * - either in the same dynamic scope:
155 * - either in the current scope, but prior to the current field.
156 * - or in a parent scope (or parent of parent ...) still in a field
157 * prior to the current field position within the parents.
158 * - or in a different dynamic scope:
159 * - either in a upper dynamic scope (walk down a targeted scope from
160 * the dynamic scope root)
161 * - or in a lower dynamic scope (failure)
162 * The dynamic scope roots are linked together, so we can access the
163 * parent dynamic scope from the child dynamic scope by walking up to
165 * If we cannot find such a field that is prior to our current path, we
168 * cur_path: the path leading to the variant definition.
169 * lookup_path: the path leading to the enum we want to look for.
170 * scope: the definition scope containing the variant definition.
173 lookup_path_definition(GArray
*cur_path
,
175 struct definition_scope
*scope
)
177 struct definition
*definition
, *lookup_definition
;
181 /* Going up in the hierarchy. Check where we come from. */
182 assert(is_path_child_of(cur_path
, scope
->scope_path
));
183 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
186 * First, check if the target name is size one, present in
187 * our parent path, located prior to us.
189 if (lookup_path
->len
== 1) {
190 last
= g_array_index(lookup_path
, GQuark
, 0);
191 lookup_definition
= lookup_field_definition_scope(last
, scope
);
192 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
193 definition
= lookup_field_definition_scope(last
, scope
);
195 if (lookup_definition
&& lookup_definition
->index
< definition
->index
)
196 return lookup_definition
;
202 if (is_path_child_of(cur_path
, scope
->scope_path
) &&
203 cur_path
->len
- scope
->scope_path
->len
== 1) {
204 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
205 definition
= lookup_field_definition_scope(last
, scope
);
207 index
= definition
->index
;
210 * Getting to a dynamic scope parent. We are
211 * guaranteed that the parent is entirely
212 * located before the child.
217 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
218 /* Means we can lookup the field in this scope */
219 last
= g_array_index(lookup_path
, GQuark
,
220 scope
->scope_path
->len
);
221 lookup_definition
= lookup_field_definition_scope(last
, scope
);
222 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
224 /* Found it! And it is prior to the current field. */
225 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
227 return lookup_definition
;
229 scope
= get_definition_scope(lookup_definition
);
230 /* Check if the definition has a sub-scope */
234 * Don't compare index anymore, because we are
235 * going within a scope that has been validated
236 * to be entirely prior to the current scope.
243 /* lookup_path is within an upper scope */
244 cur_path
= scope
->scope_path
;
245 scope
= scope
->parent_scope
;
251 int register_field_definition(GQuark field_name
, struct definition
*definition
,
252 struct definition_scope
*scope
)
254 if (!scope
|| !field_name
)
257 /* Only lookup in local scope */
258 if (lookup_field_definition_scope(field_name
, scope
))
261 g_hash_table_insert(scope
->definitions
,
262 (gpointer
) (unsigned long) field_name
,
264 /* Don't keep reference on definition */
268 void declaration_ref(struct declaration
*declaration
)
273 void declaration_unref(struct declaration
*declaration
)
277 if (!--declaration
->ref
)
278 declaration
->declaration_free(declaration
);
281 void definition_ref(struct definition
*definition
)
286 void definition_unref(struct definition
*definition
)
290 if (!--definition
->ref
)
291 definition
->declaration
->definition_free(definition
);
294 struct declaration_scope
*
295 new_declaration_scope(struct declaration_scope
*parent_scope
)
297 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
299 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
300 g_direct_equal
, NULL
,
301 (GDestroyNotify
) declaration_unref
);
302 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
303 g_direct_equal
, NULL
,
304 (GDestroyNotify
) declaration_unref
);
305 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
306 g_direct_equal
, NULL
,
307 (GDestroyNotify
) declaration_unref
);
308 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
309 g_direct_equal
, NULL
,
310 (GDestroyNotify
) declaration_unref
);
311 scope
->parent_scope
= parent_scope
;
315 void free_declaration_scope(struct declaration_scope
*scope
)
317 g_hash_table_destroy(scope
->enum_declarations
);
318 g_hash_table_destroy(scope
->variant_declarations
);
319 g_hash_table_destroy(scope
->struct_declarations
);
320 g_hash_table_destroy(scope
->typedef_declarations
);
325 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
326 struct declaration_scope
*scope
)
328 return g_hash_table_lookup(scope
->struct_declarations
,
329 (gconstpointer
) (unsigned long) struct_name
);
332 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
333 struct declaration_scope
*scope
)
335 struct declaration_struct
*declaration
;
338 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
341 scope
= scope
->parent_scope
;
346 int register_struct_declaration(GQuark struct_name
,
347 struct declaration_struct
*struct_declaration
,
348 struct declaration_scope
*scope
)
356 /* Only lookup in local scope */
357 if (lookup_struct_declaration_scope(struct_name
, scope
))
360 g_hash_table_insert(scope
->struct_declarations
,
361 (gpointer
) (unsigned long) struct_name
,
363 declaration_ref(&struct_declaration
->p
);
365 /* Also add in typedef/typealias scopes */
366 prefix_name
= prefix_quark("struct ", struct_name
);
367 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
373 struct declaration_untagged_variant
*
374 lookup_variant_declaration_scope(GQuark variant_name
,
375 struct declaration_scope
*scope
)
377 return g_hash_table_lookup(scope
->variant_declarations
,
378 (gconstpointer
) (unsigned long) variant_name
);
381 struct declaration_untagged_variant
*
382 lookup_variant_declaration(GQuark variant_name
,
383 struct declaration_scope
*scope
)
385 struct declaration_untagged_variant
*declaration
;
388 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
391 scope
= scope
->parent_scope
;
396 int register_variant_declaration(GQuark variant_name
,
397 struct declaration_untagged_variant
*untagged_variant_declaration
,
398 struct declaration_scope
*scope
)
406 /* Only lookup in local scope */
407 if (lookup_variant_declaration_scope(variant_name
, scope
))
410 g_hash_table_insert(scope
->variant_declarations
,
411 (gpointer
) (unsigned long) variant_name
,
412 untagged_variant_declaration
);
413 declaration_ref(&untagged_variant_declaration
->p
);
415 /* Also add in typedef/typealias scopes */
416 prefix_name
= prefix_quark("variant ", variant_name
);
417 ret
= register_declaration(prefix_name
,
418 &untagged_variant_declaration
->p
, scope
);
424 struct declaration_enum
*
425 lookup_enum_declaration_scope(GQuark enum_name
,
426 struct declaration_scope
*scope
)
428 return g_hash_table_lookup(scope
->enum_declarations
,
429 (gconstpointer
) (unsigned long) enum_name
);
432 struct declaration_enum
*
433 lookup_enum_declaration(GQuark enum_name
,
434 struct declaration_scope
*scope
)
436 struct declaration_enum
*declaration
;
439 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
442 scope
= scope
->parent_scope
;
447 int register_enum_declaration(GQuark enum_name
,
448 struct declaration_enum
*enum_declaration
,
449 struct declaration_scope
*scope
)
457 /* Only lookup in local scope */
458 if (lookup_enum_declaration_scope(enum_name
, scope
))
461 g_hash_table_insert(scope
->enum_declarations
,
462 (gpointer
) (unsigned long) enum_name
,
464 declaration_ref(&enum_declaration
->p
);
466 /* Also add in typedef/typealias scopes */
467 prefix_name
= prefix_quark("enum ", enum_name
);
468 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
473 static struct definition_scope
*
474 _new_definition_scope(struct definition_scope
*parent_scope
,
477 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
479 scope
->definitions
= g_hash_table_new(g_direct_hash
,
481 scope
->parent_scope
= parent_scope
;
482 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
484 g_array_set_size(scope
->scope_path
, scope_path_len
);
488 GQuark
new_definition_path(struct definition_scope
*parent_scope
,
489 GQuark field_name
, const char *root_name
)
497 str
= g_string_new("");
499 g_string_append(str
, root_name
);
501 } else if (parent_scope
) {
502 for (i
= 0; i
< parent_scope
->scope_path
->len
; i
++) {
503 GQuark q
= g_array_index(parent_scope
->scope_path
,
508 g_string_append(str
, ".");
509 g_string_append(str
, g_quark_to_string(q
));
515 g_string_append(str
, ".");
516 g_string_append(str
, g_quark_to_string(field_name
));
518 c_str
= g_string_free(str
, FALSE
);
519 if (c_str
[0] == '\0')
521 path
= g_quark_from_string(c_str
);
522 printf_debug("new definition path: %s\n", c_str
);
527 struct definition_scope
*
528 new_definition_scope(struct definition_scope
*parent_scope
,
529 GQuark field_name
, const char *root_name
)
531 struct definition_scope
*scope
;
534 scope
= _new_definition_scope(parent_scope
, 0);
535 append_scope_path(root_name
, scope
->scope_path
);
537 int scope_path_len
= 1;
539 assert(parent_scope
);
540 scope_path_len
+= parent_scope
->scope_path
->len
;
541 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
542 memcpy(scope
->scope_path
->data
, parent_scope
->scope_path
->data
,
543 sizeof(GQuark
) * (scope_path_len
- 1));
544 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
547 if (babeltrace_debug
) {
550 printf_debug("new definition scope: ");
551 for (i
= 0; i
< scope
->scope_path
->len
; need_dot
= 1, i
++)
552 printf("%s%s", need_dot
? "." : "",
553 g_quark_to_string(g_array_index(scope
->scope_path
, GQuark
, i
)));
560 * in: path (dot separated), out: q (GArray of GQuark)
562 void append_scope_path(const char *path
, GArray
*q
)
564 const char *ptrbegin
, *ptrend
= path
;
572 ptrend
= strchr(ptrbegin
, '.');
575 len
= ptrend
- ptrbegin
;
576 /* Don't accept two consecutive dots */
578 str
= g_new(char, len
+ 1); /* include \0 */
579 memcpy(str
, ptrbegin
, len
);
581 quark
= g_quark_from_string(str
);
582 g_array_append_val(q
, quark
);
584 ptrend
++; /* skip current dot */
586 /* last. Check for trailing dot (and discard). */
587 if (ptrbegin
[0] != '\0') {
588 quark
= g_quark_from_string(ptrbegin
);
589 g_array_append_val(q
, quark
);
593 void free_definition_scope(struct definition_scope
*scope
)
595 g_array_free(scope
->scope_path
, TRUE
);
596 g_hash_table_destroy(scope
->definitions
);
601 struct definition
*lookup_definition(struct definition
*definition
,
602 const char *field_name
)
604 struct definition_scope
*scope
= get_definition_scope(definition
);
609 return lookup_field_definition_scope(g_quark_from_string(field_name
),
613 struct definition_integer
*lookup_integer(struct definition
*definition
,
614 const char *field_name
,
617 struct definition
*lookup
;
618 struct definition_integer
*lookup_integer
;
620 lookup
= lookup_definition(definition
, field_name
);
623 if (lookup
->declaration
->id
!= CTF_TYPE_INTEGER
)
625 lookup_integer
= container_of(lookup
, struct definition_integer
, p
);
626 if (lookup_integer
->declaration
->signedness
!= signedness
)
628 return lookup_integer
;
631 struct definition_enum
*lookup_enum(struct definition
*definition
,
632 const char *field_name
,
635 struct definition
*lookup
;
636 struct definition_enum
*lookup_enum
;
638 lookup
= lookup_definition(definition
, field_name
);
641 if (lookup
->declaration
->id
!= CTF_TYPE_ENUM
)
643 lookup_enum
= container_of(lookup
, struct definition_enum
, p
);
644 if (lookup_enum
->integer
->declaration
->signedness
!= signedness
)
649 struct definition
*lookup_variant(struct definition
*definition
,
650 const char *field_name
)
652 struct definition
*lookup
;
653 struct definition_variant
*lookup_variant
;
655 lookup
= lookup_definition(definition
, field_name
);
658 if (lookup
->declaration
->id
!= CTF_TYPE_VARIANT
)
660 lookup_variant
= container_of(lookup
, struct definition_variant
, p
);
661 lookup
= variant_get_current_field(lookup_variant
);