X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=types%2Ftypes.c;h=e57624fb707b73225b2400d4b8f29d192e828132;hp=208b303f1e00c270694572ee48a1667db0a01001;hb=d00d17d1e06065eb31a699ce59e16ceb6b858029;hpb=05c749e538ebc3a4f6735f62d022655cf92fc17e diff --git a/types/types.c b/types/types.c index 208b303f..e57624fb 100644 --- a/types/types.c +++ b/types/types.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -147,12 +148,17 @@ static struct definition_scope * /* * OK, here is the fun. We want to lookup a field that is: - * - either in the current scope, but prior to the current field. - * - or in a parent scope (or parent of parent ...) still in a field - * prior to the current field position within the parents. - * A reaching through a dynamic scoping (e.g. from payload structure to - * event header structure), the parent fields are always entirely prior - * to the child. + * - either in the same dynamic scope: + * - either in the current scope, but prior to the current field. + * - or in a parent scope (or parent of parent ...) still in a field + * prior to the current field position within the parents. + * - or in a different dynamic scope: + * - either in a upper dynamic scope (walk down a targeted scope from + * the dynamic scope root) + * - or in a lower dynamic scope (failure) + * The dynamic scope roots are linked together, so we can access the + * parent dynamic scope from the child dynamic scope by walking up to + * the parent. * If we cannot find such a field that is prior to our current path, we * return NULL. * @@ -406,30 +412,87 @@ int register_enum_declaration(GQuark enum_name, return 0; } -struct definition_scope * - new_definition_scope(struct definition_scope *parent_scope, - GQuark field_name) +static struct definition_scope * + _new_definition_scope(struct definition_scope *parent_scope, + int scope_path_len) { struct definition_scope *scope = g_new(struct definition_scope, 1); - int scope_path_len = 1; scope->definitions = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) definition_unref); scope->parent_scope = parent_scope; - if (scope->parent_scope) - scope_path_len += scope->parent_scope->scope_path->len; scope->scope_path = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), scope_path_len); g_array_set_size(scope->scope_path, scope_path_len); - if (scope->parent_scope) - memcpy(scope->scope_path, scope->parent_scope->scope_path, + return scope; +} + +struct definition_scope * + new_definition_scope(struct definition_scope *parent_scope, + GQuark field_name) +{ + struct definition_scope *scope; + int scope_path_len = 1; + + if (parent_scope) + scope_path_len += parent_scope->scope_path->len; + scope = _new_definition_scope(parent_scope, scope_path_len); + if (parent_scope) + memcpy(scope->scope_path, parent_scope->scope_path, sizeof(GQuark) * (scope_path_len - 1)); g_array_index(scope->scope_path, GQuark, scope_path_len - 1) = field_name; return scope; } +/* + * in: path, out: q (GArray of GQuark) + */ +static +void append_scope_path(const char *path, GArray *q) +{ + const char *ptrbegin, *ptrend = path; + GQuark quark; + + for (;;) { + char *str; + size_t len; + + ptrbegin = ptrend; + ptrend = strchr(ptrbegin, '.'); + if (!ptrend) + break; + len = ptrend - ptrbegin; + /* Don't accept two consecutive dots */ + assert(len != 0); + str = g_new(char, len + 1); /* include \0 */ + memcpy(str, ptrbegin, len); + str[len] = '\0'; + quark = g_quark_from_string(str); + g_array_append_val(q, quark); + g_free(str); + } + /* last. Check for trailing dot (and discard). */ + if (ptrbegin[0] != '\0') { + quark = g_quark_from_string(ptrbegin); + g_array_append_val(q, quark); + } +} + +void set_dynamic_definition_scope(struct definition *definition, + struct definition_scope *scope, + const char *root_name) +{ + g_array_set_size(scope->scope_path, 0); + append_scope_path(root_name, scope->scope_path); + /* + * Use INT_MAX order to ensure that all fields of the parent + * scope are seen as being prior to this scope. + */ + definition->index = INT_MAX; +} + void free_definition_scope(struct definition_scope *scope) { g_array_free(scope->scope_path, TRUE);