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 lookup_typedef_declaration_scope(GQuark declaration_name
,
28 struct declaration_scope
*scope
)
30 return g_hash_table_lookup(scope
->typedef_declarations
,
31 (gconstpointer
) (unsigned long) declaration_name
);
34 struct definition
*lookup_typedef_declaration(GQuark declaration_name
,
35 struct declaration_scope
*scope
)
37 struct definition
*definition
;
40 definition
= lookup_typedef_declaration_scope(declaration_name
,
44 scope
= scope
->parent_scope
;
49 int register_typedef_declaration(GQuark name
, struct declaration
*declaration
,
50 struct declaration_scope
*scope
)
55 /* Only lookup in local scope */
56 if (lookup_typedef_declaration_scope(name
, scope
))
59 g_hash_table_insert(scope
->typedef_declarations
,
60 (gpointer
) (unsigned long) name
,
62 declaration_ref(declaration
);
68 lookup_field_definition_scope(GQuark field_name
,
69 struct definition_scope
*scope
)
71 return g_hash_table_lookup(scope
->definitions
,
72 (gconstpointer
) (unsigned long) field_name
);
76 * Returns the index at which the paths differ.
77 * If the value returned equals len, it means the paths are identical
78 * from index 0 to len-1.
80 static int compare_paths(GArray
*a
, GArray
*b
, int len
)
84 assert(len
<= a
->len
);
85 assert(len
<= b
->len
);
87 for (i
= 0; i
< len
; i
++) {
90 qa
= g_array_index(a
, GQuark
, i
);
91 qb
= g_array_index(b
, GQuark
, i
);
98 static int is_path_child_of(GArray
*path
, GArray
*maybe_parent
)
100 if (path
->len
<= maybe_parent
->len
)
102 if (compare_paths(path
, maybe_parent
, maybe_parent
->len
)
103 == maybe_parent
->len
)
109 static struct definition_scope
*
110 get_definition_scope(struct definition
*definition
)
112 switch (definition
->declaration
->id
) {
113 case CTF_TYPE_STRUCT
:
115 struct definition_struct
*def
=
116 container_of(definition
, struct definition_struct
, p
);
119 case CTF_TYPE_VARIANT
:
121 struct definition_variant
*def
=
122 container_of(definition
, struct definition_variant
, p
);
127 struct definition_array
*def
=
128 container_of(definition
, struct definition_array
, p
);
131 case CTF_TYPE_SEQUENCE
:
133 struct definition_sequence
*def
=
134 container_of(definition
, struct definition_sequence
, p
);
138 case CTF_TYPE_INTEGER
:
141 case CTF_TYPE_STRING
:
142 case CTF_TYPE_UNKNOWN
:
149 * OK, here is the fun. We want to lookup a field that is:
150 * - either in the same dynamic scope:
151 * - either in the current scope, but prior to the current field.
152 * - or in a parent scope (or parent of parent ...) still in a field
153 * prior to the current field position within the parents.
154 * - or in a different dynamic scope:
155 * - either in a upper dynamic scope (walk down a targeted scope from
156 * the dynamic scope root)
157 * - or in a lower dynamic scope (failure)
158 * The dynamic scope roots are linked together, so we can access the
159 * parent dynamic scope from the child dynamic scope by walking up to
161 * If we cannot find such a field that is prior to our current path, we
164 * cur_path: the path leading to the variant definition.
165 * lookup_path: the path leading to the enum we want to look for.
166 * scope: the definition scope containing the variant definition.
169 lookup_definition(GArray
*cur_path
,
171 struct definition_scope
*scope
)
173 struct definition
*definition
, *lookup_definition
;
178 /* going up in the hierarchy. Check where we come from. */
179 assert(is_path_child_of(cur_path
, scope
->scope_path
));
180 assert(cur_path
->len
- scope
->scope_path
->len
== 1);
181 last
= g_array_index(cur_path
, GQuark
, cur_path
->len
- 1);
182 definition
= lookup_field_definition_scope(last
, scope
);
184 index
= definition
->index
;
186 if (is_path_child_of(lookup_path
, scope
->scope_path
)) {
187 /* Means we can lookup the field in this scope */
188 last
= g_array_index(lookup_path
, GQuark
,
189 scope
->scope_path
->len
);
190 lookup_definition
= lookup_field_definition_scope(last
, scope
);
191 if (!lookup_definition
|| ((index
!= -1) && lookup_definition
->index
>= index
))
193 /* Found it! And it is prior to the current field. */
194 if (lookup_path
->len
- scope
->scope_path
->len
== 1) {
196 return lookup_definition
;
198 scope
= get_definition_scope(lookup_definition
);
199 /* Check if the definition has a sub-scope */
203 * Don't compare index anymore, because we are
204 * going within a scope that has been validated
205 * to be entirely prior to the current scope.
213 /* lookup_path is within an upper scope */
214 cur_path
= scope
->scope_path
;
215 scope
= scope
->parent_scope
;
221 int register_field_definition(GQuark field_name
, struct definition
*definition
,
222 struct definition_scope
*scope
)
227 /* Only lookup in local scope */
228 if (lookup_field_definition_scope(field_name
, scope
))
231 g_hash_table_insert(scope
->definitions
,
232 (gpointer
) (unsigned long) field_name
,
234 definition_ref(definition
);
238 void declaration_ref(struct declaration
*declaration
)
243 void declaration_unref(struct declaration
*declaration
)
245 if (!--declaration
->ref
)
246 declaration
->declaration_free(declaration
);
249 void definition_ref(struct definition
*definition
)
254 void definition_unref(struct definition
*definition
)
256 if (!--definition
->ref
)
257 definition
->declaration
->definition_free(definition
);
260 struct declaration_scope
*
261 new_declaration_scope(struct declaration_scope
*parent_scope
)
263 struct declaration_scope
*scope
= g_new(struct declaration_scope
, 1);
265 scope
->typedef_declarations
= g_hash_table_new_full(g_direct_hash
,
266 g_direct_equal
, NULL
,
267 (GDestroyNotify
) definition_unref
);
268 scope
->struct_declarations
= g_hash_table_new_full(g_direct_hash
,
269 g_direct_equal
, NULL
,
270 (GDestroyNotify
) declaration_unref
);
271 scope
->variant_declarations
= g_hash_table_new_full(g_direct_hash
,
272 g_direct_equal
, NULL
,
273 (GDestroyNotify
) declaration_unref
);
274 scope
->enum_declarations
= g_hash_table_new_full(g_direct_hash
,
275 g_direct_equal
, NULL
,
276 (GDestroyNotify
) declaration_unref
);
277 scope
->parent_scope
= parent_scope
;
281 void free_declaration_scope(struct declaration_scope
*scope
)
283 g_hash_table_destroy(scope
->enum_declarations
);
284 g_hash_table_destroy(scope
->variant_declarations
);
285 g_hash_table_destroy(scope
->struct_declarations
);
286 g_hash_table_destroy(scope
->typedef_declarations
);
291 struct declaration_struct
*lookup_struct_declaration_scope(GQuark struct_name
,
292 struct declaration_scope
*scope
)
294 return g_hash_table_lookup(scope
->struct_declarations
,
295 (gconstpointer
) (unsigned long) struct_name
);
298 struct declaration_struct
*lookup_struct_declaration(GQuark struct_name
,
299 struct declaration_scope
*scope
)
301 struct declaration_struct
*declaration
;
304 declaration
= lookup_struct_declaration_scope(struct_name
, scope
);
307 scope
= scope
->parent_scope
;
312 int register_struct_declaration(GQuark struct_name
,
313 struct declaration_struct
*struct_declaration
,
314 struct declaration_scope
*scope
)
319 /* Only lookup in local scope */
320 if (lookup_struct_declaration_scope(struct_name
, scope
))
323 g_hash_table_insert(scope
->struct_declarations
,
324 (gpointer
) (unsigned long) struct_name
,
326 declaration_ref(&struct_declaration
->p
);
331 struct declaration_variant
*
332 lookup_variant_declaration_scope(GQuark variant_name
,
333 struct declaration_scope
*scope
)
335 return g_hash_table_lookup(scope
->variant_declarations
,
336 (gconstpointer
) (unsigned long) variant_name
);
339 struct declaration_variant
*
340 lookup_variant_declaration(GQuark variant_name
,
341 struct declaration_scope
*scope
)
343 struct declaration_variant
*declaration
;
346 declaration
= lookup_variant_declaration_scope(variant_name
, scope
);
349 scope
= scope
->parent_scope
;
354 int register_variant_declaration(GQuark variant_name
,
355 struct declaration_variant
*variant_declaration
,
356 struct declaration_scope
*scope
)
361 /* Only lookup in local scope */
362 if (lookup_variant_declaration_scope(variant_name
, scope
))
365 g_hash_table_insert(scope
->variant_declarations
,
366 (gpointer
) (unsigned long) variant_name
,
367 variant_declaration
);
368 declaration_ref(&variant_declaration
->p
);
373 struct declaration_enum
*
374 lookup_enum_declaration_scope(GQuark enum_name
,
375 struct declaration_scope
*scope
)
377 return g_hash_table_lookup(scope
->enum_declarations
,
378 (gconstpointer
) (unsigned long) enum_name
);
381 struct declaration_enum
*
382 lookup_enum_declaration(GQuark enum_name
,
383 struct declaration_scope
*scope
)
385 struct declaration_enum
*declaration
;
388 declaration
= lookup_enum_declaration_scope(enum_name
, scope
);
391 scope
= scope
->parent_scope
;
396 int register_enum_declaration(GQuark enum_name
,
397 struct declaration_enum
*enum_declaration
,
398 struct declaration_scope
*scope
)
403 /* Only lookup in local scope */
404 if (lookup_enum_declaration_scope(enum_name
, scope
))
407 g_hash_table_insert(scope
->enum_declarations
,
408 (gpointer
) (unsigned long) enum_name
,
410 declaration_ref(&enum_declaration
->p
);
414 static struct definition_scope
*
415 _new_definition_scope(struct definition_scope
*parent_scope
,
418 struct definition_scope
*scope
= g_new(struct definition_scope
, 1);
420 scope
->definitions
= g_hash_table_new_full(g_direct_hash
,
421 g_direct_equal
, NULL
,
422 (GDestroyNotify
) definition_unref
);
423 scope
->parent_scope
= parent_scope
;
424 scope
->scope_path
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
),
426 g_array_set_size(scope
->scope_path
, scope_path_len
);
430 struct definition_scope
*
431 new_definition_scope(struct definition_scope
*parent_scope
,
434 struct definition_scope
*scope
;
435 int scope_path_len
= 1;
438 scope_path_len
+= parent_scope
->scope_path
->len
;
439 scope
= _new_definition_scope(parent_scope
, scope_path_len
);
441 memcpy(scope
->scope_path
, parent_scope
->scope_path
,
442 sizeof(GQuark
) * (scope_path_len
- 1));
443 g_array_index(scope
->scope_path
, GQuark
, scope_path_len
- 1) =
448 void set_dynamic_definition_scope(struct definition_scope
*scope
,
451 g_array_set_size(scope
->scope_path
, 1);
452 g_array_index(scope
->scope_path
, GQuark
, 0) = root_name
;
455 void free_definition_scope(struct definition_scope
*scope
)
457 g_array_free(scope
->scope_path
, TRUE
);
458 g_hash_table_destroy(scope
->definitions
);
This page took 0.037551 seconds and 4 git commands to generate.