X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=types%2Ftypes.c;h=450c93ba6b5206c9edcdd8fb726e92c0b029d73a;hp=7369f30d09ffb5a272c3d54f14e5466ac3b005b2;hb=9b3c1d6f8e01603488e317ffef7a8e3c15c98459;hpb=312623540c466defab45503fbe0ce7ec79dcce85 diff --git a/types/types.c b/types/types.c index 7369f30d..450c93ba 100644 --- a/types/types.c +++ b/types/types.c @@ -5,7 +5,9 @@ * * Types registry. * - * Copyright 2010, 2011 - Mathieu Desnoyers + * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation + * + * Author: Mathieu Desnoyers * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -19,6 +21,8 @@ */ #include +#include +#include #include #include #include @@ -110,52 +114,42 @@ static int compare_paths(GArray *a, GArray *b, int len) static int is_path_child_of(GArray *path, GArray *maybe_parent) { - if (path->len <= maybe_parent->len) - return 0; + int i, ret; + + if (babeltrace_debug) { + int need_dot = 0; + + printf_debug("Is path \""); + for (i = 0; i < path->len; need_dot = 1, i++) + printf("%s%s", need_dot ? "." : "", + g_quark_to_string(g_array_index(path, GQuark, i))); + need_dot = 0; + printf("\" child of \""); + for (i = 0; i < maybe_parent->len; need_dot = 1, i++) + printf("%s%s", need_dot ? "." : "", + g_quark_to_string(g_array_index(maybe_parent, GQuark, i))); + printf("\" ? "); + } + + if (path->len <= maybe_parent->len) { + ret = 0; + goto end; + } if (compare_paths(path, maybe_parent, maybe_parent->len) == maybe_parent->len) - return 1; + ret = 1; else - return 0; + ret = 0; +end: + if (babeltrace_debug) + printf("%s\n", ret ? "Yes" : "No"); + return ret; } static struct definition_scope * - get_definition_scope(struct definition *definition) -{ - switch (definition->declaration->id) { - case CTF_TYPE_STRUCT: - { - struct definition_struct *def = - container_of(definition, struct definition_struct, p); - return def->scope; - } - case CTF_TYPE_VARIANT: - { - struct definition_variant *def = - container_of(definition, struct definition_variant, p); - return def->scope; - } - case CTF_TYPE_ARRAY: - { - struct definition_array *def = - container_of(definition, struct definition_array, p); - return def->scope; - } - case CTF_TYPE_SEQUENCE: - { - struct definition_sequence *def = - container_of(definition, struct definition_sequence, p); - return def->scope; - } - - case CTF_TYPE_INTEGER: - case CTF_TYPE_FLOAT: - case CTF_TYPE_ENUM: - case CTF_TYPE_STRING: - case CTF_TYPE_UNKNOWN: - default: - return NULL; - } + get_definition_scope(const struct definition *definition) +{ + return definition->scope; } /* @@ -179,22 +173,49 @@ static struct definition_scope * * scope: the definition scope containing the variant definition. */ struct definition * - lookup_definition(GArray *cur_path, - GArray *lookup_path, - struct definition_scope *scope) + lookup_path_definition(GArray *cur_path, + GArray *lookup_path, + struct definition_scope *scope) { struct definition *definition, *lookup_definition; GQuark last; int index; - while (scope) { - /* going up in the hierarchy. Check where we come from. */ - assert(is_path_child_of(cur_path, scope->scope_path)); - assert(cur_path->len - scope->scope_path->len == 1); + /* Going up in the hierarchy. Check where we come from. */ + assert(is_path_child_of(cur_path, scope->scope_path)); + assert(cur_path->len - scope->scope_path->len == 1); + + /* + * First, check if the target name is size one, present in + * our parent path, located prior to us. + */ + if (lookup_path->len == 1) { + last = g_array_index(lookup_path, GQuark, 0); + lookup_definition = lookup_field_definition_scope(last, scope); last = g_array_index(cur_path, GQuark, cur_path->len - 1); definition = lookup_field_definition_scope(last, scope); assert(definition); - index = definition->index; + if (lookup_definition && lookup_definition->index < definition->index) + return lookup_definition; + else + return NULL; + } + + while (scope) { + if (is_path_child_of(cur_path, scope->scope_path) && + cur_path->len - scope->scope_path->len == 1) { + last = g_array_index(cur_path, GQuark, cur_path->len - 1); + definition = lookup_field_definition_scope(last, scope); + assert(definition); + index = definition->index; + } else { + /* + * Getting to a dynamic scope parent. We are + * guaranteed that the parent is entirely + * located before the child. + */ + index = -1; + } lookup: if (is_path_child_of(lookup_path, scope->scope_path)) { /* Means we can lookup the field in this scope */ @@ -222,7 +243,6 @@ lookup: goto lookup; } } else { - assert(index != -1); /* lookup_path is within an upper scope */ cur_path = scope->scope_path; scope = scope->parent_scope; @@ -234,7 +254,7 @@ lookup: int register_field_definition(GQuark field_name, struct definition *definition, struct definition_scope *scope) { - if (!field_name) + if (!scope || !field_name) return -EPERM; /* Only lookup in local scope */ @@ -244,7 +264,7 @@ int register_field_definition(GQuark field_name, struct definition *definition, g_hash_table_insert(scope->definitions, (gpointer) (unsigned long) field_name, definition); - definition_ref(definition); + /* Don't keep reference on definition */ return 0; } @@ -281,7 +301,7 @@ struct declaration_scope * scope->typedef_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - (GDestroyNotify) definition_unref); + (GDestroyNotify) declaration_unref); scope->struct_declarations = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) declaration_unref); @@ -459,9 +479,8 @@ static struct definition_scope * { struct definition_scope *scope = g_new(struct definition_scope, 1); - scope->definitions = g_hash_table_new_full(g_direct_hash, - g_direct_equal, NULL, - (GDestroyNotify) definition_unref); + scope->definitions = g_hash_table_new(g_direct_hash, + g_direct_equal); scope->parent_scope = parent_scope; scope->scope_path = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), scope_path_len); @@ -469,45 +488,74 @@ static struct definition_scope * return scope; } -GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name) +GQuark new_definition_path(struct definition_scope *parent_scope, + GQuark field_name, const char *root_name) { GQuark path; GString *str; gchar *c_str; int i; + int need_dot = 0; str = g_string_new(""); - if (parent_scope) { + if (root_name) { + g_string_append(str, root_name); + need_dot = 1; + } else if (parent_scope) { for (i = 0; i < parent_scope->scope_path->len; i++) { GQuark q = g_array_index(parent_scope->scope_path, GQuark, i); - + if (!q) + continue; + if (need_dot) + g_string_append(str, "."); g_string_append(str, g_quark_to_string(q)); - g_string_append(str, "."); + need_dot = 1; } } - g_string_append(str, g_quark_to_string(field_name)); + if (field_name) { + if (need_dot) + g_string_append(str, "."); + g_string_append(str, g_quark_to_string(field_name)); + } c_str = g_string_free(str, FALSE); + if (c_str[0] == '\0') + return 0; path = g_quark_from_string(c_str); + printf_debug("new definition path: %s\n", c_str); g_free(c_str); return path; } struct definition_scope * new_definition_scope(struct definition_scope *parent_scope, - GQuark field_name) + GQuark field_name, const char *root_name) { struct definition_scope *scope; - int scope_path_len = 1; - if (parent_scope) + if (root_name) { + scope = _new_definition_scope(parent_scope, 0); + append_scope_path(root_name, scope->scope_path); + } else { + int scope_path_len = 1; + + assert(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, + scope = _new_definition_scope(parent_scope, scope_path_len); + memcpy(scope->scope_path->data, parent_scope->scope_path->data, sizeof(GQuark) * (scope_path_len - 1)); - g_array_index(scope->scope_path, GQuark, scope_path_len - 1) = - field_name; + g_array_index(scope->scope_path, GQuark, scope_path_len - 1) = + field_name; + } + if (babeltrace_debug) { + int i, need_dot = 0; + + printf_debug("new definition scope: "); + for (i = 0; i < scope->scope_path->len; need_dot = 1, i++) + printf("%s%s", need_dot ? "." : "", + g_quark_to_string(g_array_index(scope->scope_path, GQuark, i))); + printf("\n"); + } return scope; } @@ -545,22 +593,74 @@ void append_scope_path(const char *path, GArray *q) } } -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); g_hash_table_destroy(scope->definitions); g_free(scope); } + +struct definition *lookup_definition(const struct definition *definition, + const char *field_name) +{ + struct definition_scope *scope = get_definition_scope(definition); + + if (!scope) + return NULL; + + return lookup_field_definition_scope(g_quark_from_string(field_name), + scope); +} + +struct definition_integer *lookup_integer(const struct definition *definition, + const char *field_name, + int signedness) +{ + struct definition *lookup; + struct definition_integer *lookup_integer; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_INTEGER) + return NULL; + lookup_integer = container_of(lookup, struct definition_integer, p); + if (lookup_integer->declaration->signedness != signedness) + return NULL; + return lookup_integer; +} + +struct definition_enum *lookup_enum(const struct definition *definition, + const char *field_name, + int signedness) +{ + struct definition *lookup; + struct definition_enum *lookup_enum; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_ENUM) + return NULL; + lookup_enum = container_of(lookup, struct definition_enum, p); + if (lookup_enum->integer->declaration->signedness != signedness) + return NULL; + return lookup_enum; +} + +struct definition *lookup_variant(const struct definition *definition, + const char *field_name) +{ + struct definition *lookup; + struct definition_variant *lookup_variant; + + lookup = lookup_definition(definition, field_name); + if (!lookup) + return NULL; + if (lookup->declaration->id != CTF_TYPE_VARIANT) + return NULL; + lookup_variant = container_of(lookup, struct definition_variant, p); + lookup = variant_get_current_field(lookup_variant); + assert(lookup); + return lookup; +}