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>
27 GQuark
prefix_quark(const char *prefix
, GQuark quark
)
32 str
= g_string_new(prefix
);
33 g_string_append(str
, g_quark_to_string(quark
));
34 nq
= g_quark_from_string(g_string_free(str
, FALSE
));
40 lookup_declaration_scope(GQuark declaration_name
,
41 struct declaration_scope
*scope
)
43 return g_hash_table_lookup(scope
->typedef_declarations
,
44 (gconstpointer
) (unsigned long) declaration_name
);
47 struct declaration
*lookup_declaration(GQuark declaration_name
,
48 struct declaration_scope
*scope
)
50 struct declaration
*declaration
;
53 declaration
= lookup_declaration_scope(declaration_name
,
57 scope
= scope
->parent_scope
;
62 int register_declaration(GQuark name
, struct declaration
*declaration
,
63 struct declaration_scope
*scope
)
68 /* Only lookup in local scope */
69 if (lookup_declaration_scope(name
, scope
))
72 g_hash_table_insert(scope
->typedef_declarations
,
73 (gpointer
) (unsigned long) name
,
75 declaration_ref(declaration
);
81 lookup_field_definition_scope(GQuark field_name
,
82 struct definition_scope
*scope
)
84 return g_hash_table_lookup(scope
->definitions
,
85 (gconstpointer
) (unsigned long) field_name
);
89 * Returns the index at which the paths differ.
90 * If the value returned equals len, it means the paths are identical
91 * from index 0 to len-1.
93 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
97 assert(len
<= a
->len
);
98 assert(len
<= b
->len
);
100 for (i
= 0; i
< len
; i
++) {
103 qa
= g_array_index(a
, GQuark
, i
);
104 qb
= g_array_index(b
, GQuark
, i
);
111 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
113 if (path
->len
<= maybe_parent
->len
)
115 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
116 == maybe_parent
->len
)
122 static struct definition_scope
*
123 get_definition_scope(struct definition
*definition
)
125 switch (definition
->declaration
->id
) {
126 case CTF_TYPE_STRUCT
:
128 struct definition_struct
*def
=
129 container_of(definition
, struct definition_struct
, p
);
132 case CTF_TYPE_VARIANT
:
134 struct definition_variant
*def
=
135 container_of(definition
, struct definition_variant
, p
);
140 struct definition_array
*def
=
141 container_of(definition
, struct definition_array
, p
);
144 case CTF_TYPE_SEQUENCE
:
146 struct definition_sequence
*def
=
147 container_of(definition
, struct definition_sequence
, p
);
151 case CTF_TYPE_INTEGER
:
154 case CTF_TYPE_STRING
:
155 case CTF_TYPE_UNKNOWN
:
162 * OK, here is the fun. We want to lookup a field that is:
163 * - either in the same dynamic scope:
164 * - either in the current scope, but prior to the current field.
165 * - or in a parent scope (or parent of parent ...) still in a field
166 * prior to the current field position within the parents.
167 * - or in a different dynamic scope:
168 * - either in a upper dynamic scope (walk down a targeted scope from
169 * the dynamic scope root)
170 * - or in a lower dynamic scope (failure)
171 * The dynamic scope roots are linked together, so we can access the
172 * parent dynamic scope from the child dynamic scope by walking up to
174 * If we cannot find such a field that is prior to our current path, we
177 * cur_path: the path leading to the variant definition.
178 * lookup_path: the path leading to the enum we want to look for.
179 * scope: the definition scope containing the variant definition.
182 lookup_definition(GArray
*cur_path
,
184 struct definition_scope
*scope
)
186 struct definition
*definition
, *lookup_definition
;
191 /* going up in the hierarchy. Check where we come from. */
192 assert(is_path_child_of(cur_path
, scope
->scope_path
));
193 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
194 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
195 definition
= lookup_field_definition_scope(last
, scope
);
197 index
= definition
->index
;
199 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
200 /* Means we can lookup the field in this scope */
201 last
= g_array_index(lookup_path
, GQuark
,
202 scope
->scope_path
->len
);
203 lookup_definition
= lookup_field_definition_scope(last
, scope
);
204 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
206 /* Found it! And it is prior to the current field. */
207 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
209 return lookup_definition
;
211 scope
= get_definition_scope(lookup_definition
);
212 /* Check if the definition has a sub-scope */
216 * Don't compare index anymore, because we are
217 * going within a scope that has been validated
218 * to be entirely prior to the current scope.
226 /* lookup_path is within an upper scope */
227 cur_path
= scope
->scope_path
;
228 scope
= scope
->parent_scope
;
234 int register_field_definition(GQuark field_name
, struct definition
*definition
,
235 struct definition_scope
*scope
)
240 /* Only lookup in local scope */
241 if (lookup_field_definition_scope(field_name
, scope
))
244 g_hash_table_insert(scope
->definitions
,
245 (gpointer
) (unsigned long) field_name
,
247 definition_ref(definition
);
251 void declaration_ref(struct declaration
*declaration
)
256 void declaration_unref(struct declaration
*declaration
)
260 if (!--declaration
->ref
)
261 declaration
->declaration_free(declaration
);
264 void definition_ref(struct definition
*definition
)
269 void definition_unref(struct definition
*definition
)
273 if (!--definition
->ref
)
274 definition
->declaration
->definition_free(definition
);
277 struct declaration_scope
*
278 new_declaration_scope(struct declaration_scope
*parent_scope
)
280 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
282 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
283 g_direct_equal
, NULL
,
284 (GDestroyNotify
) definition_unref
);
285 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
286 g_direct_equal
, NULL
,
287 (GDestroyNotify
) declaration_unref
);
288 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
289 g_direct_equal
, NULL
,
290 (GDestroyNotify
) declaration_unref
);
291 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
292 g_direct_equal
, NULL
,
293 (GDestroyNotify
) declaration_unref
);
294 scope
->parent_scope
= parent_scope
;
298 void free_declaration_scope(struct declaration_scope
*scope
)
300 g_hash_table_destroy(scope
->enum_declarations
);
301 g_hash_table_destroy(scope
->variant_declarations
);
302 g_hash_table_destroy(scope
->struct_declarations
);
303 g_hash_table_destroy(scope
->typedef_declarations
);
308 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
309 struct declaration_scope
*scope
)
311 return g_hash_table_lookup(scope
->struct_declarations
,
312 (gconstpointer
) (unsigned long) struct_name
);
315 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
316 struct declaration_scope
*scope
)
318 struct declaration_struct
*declaration
;
321 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
324 scope
= scope
->parent_scope
;
329 int register_struct_declaration(GQuark struct_name
,
330 struct declaration_struct
*struct_declaration
,
331 struct declaration_scope
*scope
)
339 /* Only lookup in local scope */
340 if (lookup_struct_declaration_scope(struct_name
, scope
))
343 g_hash_table_insert(scope
->struct_declarations
,
344 (gpointer
) (unsigned long) struct_name
,
346 declaration_ref(&struct_declaration
->p
);
348 /* Also add in typedef/typealias scopes */
349 prefix_name
= prefix_quark("struct ", struct_name
);
350 ret
= register_declaration(prefix_name
, &struct_declaration
->p
, scope
);
356 struct declaration_untagged_variant
*
357 lookup_variant_declaration_scope(GQuark variant_name
,
358 struct declaration_scope
*scope
)
360 return g_hash_table_lookup(scope
->variant_declarations
,
361 (gconstpointer
) (unsigned long) variant_name
);
364 struct declaration_untagged_variant
*
365 lookup_variant_declaration(GQuark variant_name
,
366 struct declaration_scope
*scope
)
368 struct declaration_untagged_variant
*declaration
;
371 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
374 scope
= scope
->parent_scope
;
379 int register_variant_declaration(GQuark variant_name
,
380 struct declaration_untagged_variant
*untagged_variant_declaration
,
381 struct declaration_scope
*scope
)
389 /* Only lookup in local scope */
390 if (lookup_variant_declaration_scope(variant_name
, scope
))
393 g_hash_table_insert(scope
->variant_declarations
,
394 (gpointer
) (unsigned long) variant_name
,
395 untagged_variant_declaration
);
396 declaration_ref(&untagged_variant_declaration
->p
);
398 /* Also add in typedef/typealias scopes */
399 prefix_name
= prefix_quark("variant ", variant_name
);
400 ret
= register_declaration(prefix_name
,
401 &untagged_variant_declaration
->p
, scope
);
407 struct declaration_enum
*
408 lookup_enum_declaration_scope(GQuark enum_name
,
409 struct declaration_scope
*scope
)
411 return g_hash_table_lookup(scope
->enum_declarations
,
412 (gconstpointer
) (unsigned long) enum_name
);
415 struct declaration_enum
*
416 lookup_enum_declaration(GQuark enum_name
,
417 struct declaration_scope
*scope
)
419 struct declaration_enum
*declaration
;
422 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
425 scope
= scope
->parent_scope
;
430 int register_enum_declaration(GQuark enum_name
,
431 struct declaration_enum
*enum_declaration
,
432 struct declaration_scope
*scope
)
440 /* Only lookup in local scope */
441 if (lookup_enum_declaration_scope(enum_name
, scope
))
444 g_hash_table_insert(scope
->enum_declarations
,
445 (gpointer
) (unsigned long) enum_name
,
447 declaration_ref(&enum_declaration
->p
);
449 /* Also add in typedef/typealias scopes */
450 prefix_name
= prefix_quark("enum ", enum_name
);
451 ret
= register_declaration(prefix_name
, &enum_declaration
->p
, scope
);
456 static struct definition_scope
*
457 _new_definition_scope(struct definition_scope
*parent_scope
,
460 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
462 scope
->definitions
= g_hash_table_new_full(g_direct_hash
,
463 g_direct_equal
, NULL
,
464 (GDestroyNotify
) definition_unref
);
465 scope
->parent_scope
= parent_scope
;
466 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
468 g_array_set_size(scope
->scope_path
, scope_path_len
);
472 struct definition_scope
*
473 new_definition_scope(struct definition_scope
*parent_scope
,
476 struct definition_scope
*scope
;
477 int scope_path_len
= 1;
480 scope_path_len
+= parent_scope
->scope_path
->len
;
481 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
483 memcpy(scope
->scope_path
, parent_scope
->scope_path
,
484 sizeof(GQuark
) * (scope_path_len
- 1));
485 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
491 * in: path (dot separated), out: q (GArray of GQuark)
493 void append_scope_path(const char *path
, GArray
*q
)
495 const char *ptrbegin
, *ptrend
= path
;
503 ptrend
= strchr(ptrbegin
, '.');
506 len
= ptrend
- ptrbegin
;
507 /* Don't accept two consecutive dots */
509 str
= g_new(char, len
+ 1); /* include \0 */
510 memcpy(str
, ptrbegin
, len
);
512 quark
= g_quark_from_string(str
);
513 g_array_append_val(q
, quark
);
515 ptrend
++; /* skip current dot */
517 /* last. Check for trailing dot (and discard). */
518 if (ptrbegin
[0] != '\0') {
519 quark
= g_quark_from_string(ptrbegin
);
520 g_array_append_val(q
, quark
);
524 void set_dynamic_definition_scope(struct definition
*definition
,
525 struct definition_scope
*scope
,
526 const char *root_name
)
528 g_array_set_size(scope
->scope_path
, 0);
529 append_scope_path(root_name
, scope
->scope_path
);
531 * Use INT_MAX order to ensure that all fields of the parent
532 * scope are seen as being prior to this scope.
534 definition
->index
= INT_MAX
;
537 void free_definition_scope(struct definition_scope
*scope
)
539 g_array_free(scope
->scope_path
, TRUE
);
540 g_hash_table_destroy(scope
->definitions
);