Dynamic definition scope hierarchy
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 15 Apr 2011 02:14:11 +0000 (22:14 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 15 Apr 2011 02:14:11 +0000 (22:14 -0400)
Correctly handle hierarchy of definition scope lookups.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
include/babeltrace/ctf/metadata.h
include/babeltrace/types.h
types/types.c

index a6773eeaab4d7d11236fa8c054323afc9605a822..260fc31ce3f7e0870d7ec758a765833445b3acdd 100644 (file)
@@ -384,7 +384,7 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                fprintf(stderr, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
                                return -EINVAL;
                        }
-                       event->definition_scope = new_definition_scope(stream->definition_scope);
+                       event->definition_scope = new_dynamic_definition_scope(stream->definition_scope);
                        if (!event->definition_scope) {
                                fprintf(stderr, "[error] %s: Error allocating declaration scope\n", __func__);
                                return -EPERM;
@@ -402,8 +402,7 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
                                return -EPERM;
-                       /* TODO: definition */
-                       event->context = container_of(declaration, struct declaration_struct, p);
+                       event->context_decl = container_of(declaration, struct declaration_struct, p);
                } else if (!strcmp(left, "fields")) {
                        struct declaration *declaration;
 
@@ -416,8 +415,7 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
                                return -EPERM;
-                       /* TODO: definition */
-                       event->fields = container_of(declaration, struct declaration_struct, p);
+                       event->fields_decl = container_of(declaration, struct declaration_struct, p);
                }
                free(left);
                break;
@@ -437,6 +435,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
        int ret = 0;
        struct ctf_node *iter;
        struct ctf_event *event;
+       struct definition_scope *parent_def_scope;
 
        event = g_new0(struct ctf_event, 1);
        event->declaration_scope = new_declaration_scope(parent_declaration_scope);
@@ -463,11 +462,30 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
        g_hash_table_insert(event->stream->event_quark_to_id,
                            (gpointer)(unsigned long) event->name,
                            &event->id);
+       parent_def_scope = event->definition_scope;
+       if (event->context_decl) {
+               event->context =
+                       event->context_decl->definition_new(event->context_decl,
+                               parent_def_scope,
+                               g_quark_from_string("event.context"),
+                               MAX_INT);
+               parent_def_scope = event->context->scope;
+               declaration_unref(event->context_decl);
+       }
+       if (event->fields_decl) {
+               event->fields =
+                       event->fields_decl->definition_new(event->fields_decl,
+                               parent_def_scope,
+                               g_quark_from_string("event.fields"),
+                               MAX_INT);
+               parent_def_scope = event->fields->scope;
+               declaration_unref(event->fields_decl);
+       }
        return 0;
 
 error:
-       declaration_unref(event->fields);
-       declaration_unref(event->context);
+       declaration_unref(event->fields_decl);
+       declaration_unref(event->context_decl);
        free_definition_scope(event->definition_scope);
        free_declaration_scope(event->declaration_scope);
        g_free(event);
@@ -510,7 +528,7 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
                                return -EINVAL;
                        }
                        CTF_EVENT_SET_FIELD(event, stream_id);
-               } else if (!strcmp(left, "event_header")) {
+               } else if (!strcmp(left, "event.header")) {
                        struct declaration *declaration;
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
@@ -520,9 +538,8 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
                                return -EPERM;
-                       /* TODO: definition */
-                       stream->event_header = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "event_context")) {
+                       stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
+               } else if (!strcmp(left, "event.context")) {
                        struct declaration *declaration;
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
@@ -532,9 +549,8 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
                                return -EPERM;
-                       /* TODO: definition */
-                       stream->event_context = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "packet_context")) {
+                       stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
+               } else if (!strcmp(left, "packet.context")) {
                        struct declaration *declaration;
 
                        declaration = ctf_declaration_specifier_visit(fd, depth,
@@ -544,8 +560,7 @@ int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, str
                                return -EPERM;
                        if (declaration->type->id != CTF_TYPE_STRUCT)
                                return -EPERM;
-                       /* TODO: definition */
-                       stream->packet_context = container_of(declaration, struct declaration_struct, p);
+                       stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
                }
                free(left);
                break;
@@ -565,10 +580,11 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
        int ret = 0;
        struct ctf_node *iter;
        struct ctf_stream *stream;
+       struct definition_scope *parent_def_scope;
 
        stream = g_new0(struct ctf_stream, 1);
        stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
-       stream->definition_scope = new_definition_scope(trace->definition_scope);
+       stream->definition_scope = new_dynamic_definition_scope(trace->definition_scope);
        stream->events_by_id = g_ptr_array_new();
        stream->event_quark_to_id = g_hash_table_new(g_int_hash, g_int_equal);
        cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
@@ -583,6 +599,36 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
        if (trace->streams->len <= stream->stream_id)
                g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
        g_ptr_array_index(trace->streams, stream->stream_id) = stream;
+
+       parent_def_scope = stream->definition_scope;
+       if (stream->packet_context_decl) {
+               stream->packet_context =
+                       stream->packet_context_decl->definition_new(stream->packet_context_decl,
+                               parent_def_scope,
+                               g_quark_from_string("stream.packet.context"),
+                               MAX_INT);
+               parent_def_scope = stream->packet_context->scope;
+               declaration_unref(stream->packet_context_decl);
+       }
+       if (stream->event_header_decl) {
+               stream->event_header =
+                       stream->event_header_decl->definition_new(stream->event_header_decl,
+                               parent_def_scope,
+                               g_quark_from_string("stream.event.header"),
+                               MAX_INT);
+               parent_def_scope = stream->event_header->scope;
+               declaration_unref(stream->event_header_decl);
+       }
+       if (stream->event_context_decl) {
+               stream->event_context =
+                       stream->event_context_decl->definition_new(stream->event_context_decl,
+                               parent_def_scope,
+                               g_quark_from_string("stream.event.context"),
+                               MAX_INT);
+               parent_def_scope = stream->event_context->scope;
+               declaration_unref(stream->event_context_decl);
+       }
+
        return 0;
 
 error:
@@ -681,7 +727,7 @@ int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace
        if (trace->declaration_scope)
                return -EEXIST;
        trace->declaration_scope = new_declaration_scope(trace->root_declaration_scope);
-       trace->definition_scope = new_definition_scope(trace->root_definition_scope);
+       trace->definition_scope = new_dynamic_definition_scope(trace->root_definition_scope);
        trace->streams = g_ptr_array_new();
        cds_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
                ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
index 85ff1cb8145922ec31ef59443907218114de5a02..a60f17763c239e4bac7023d51c8d436b622542ce 100644 (file)
@@ -91,9 +91,15 @@ struct ctf_stream {
        GPtrArray *events_by_id;                /* Array of struct ctf_event pointers indexed by id */
        GHashTable *event_quark_to_id;          /* GQuark to numeric id */
 
+       /* Declarations only used when parsing */
+       struct declaration_struct *packet_context_decl;
+       struct declaration_struct *event_header_decl;
+       struct declaration_struct *event_context_decl;
+
+       /* Definitions used afterward */
+       struct definition_struct *packet_context;
        struct definition_struct *event_header;
        struct definition_struct *event_context;
-       struct definition_struct *packet_context;
 
        uint64_t stream_id;
 
@@ -123,6 +129,12 @@ struct ctf_event {
        struct declaration_scope *declaration_scope;
        /* parent is stream scope */
        struct definition_scope *definition_scope;
+
+       /* Declarations only used when parsing */
+       struct declaration_struct *context_decl;
+       struct declaration_struct *fields_decl;
+
+       /* Definitions used afterward */
        struct definition_struct *context;
        struct definition_struct *fields;
 
index 885a6a1b85c07ff1195e85b051606b8d6e5fb87f..34e49aef18b7be474fb74f7221701f5e709deae4 100644 (file)
@@ -107,8 +107,11 @@ struct definition_scope {
        struct definition_scope *parent_scope;
        /*
         * Complete "path" leading to this definition scope.
-        * Includes trace/stream/event '.' field name '.' field name '.' ....
+        * Includes dynamic scope name '.' field name '.' field name '.' ....
         * Array of GQuark elements (which are each separated by dots).
+        * The dynamic scope name can contain dots, and is encoded into
+        * a single GQuark. Thus, scope_path[0] returns the GQuark
+        * identifying the dynamic scope.
         */
        GArray *scope_path;     /* array of GQuark */
 };
@@ -377,6 +380,9 @@ int register_field_definition(GQuark field_name,
 struct definition_scope *
        new_definition_scope(struct definition_scope *parent_scope,
                             GQuark field_name);
+struct definition_scope *
+       new_dynamic_definition_scope(struct definition_scope *parent_scope,
+                                    GQuark field_name);
 void free_definition_scope(struct definition_scope *scope);
 
 void declaration_ref(struct declaration *declaration);
index 208b303f1e00c270694572ee48a1667db0a01001..227a1e5e3125976730b79197a987e291e82a1714 100644 (file)
@@ -147,12 +147,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 +411,54 @@ 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;
 }
 
+/*
+ * Same as new_definition_scope, but reset the scope path.
+ */
+struct definition_scope *
+       new_dynamic_definition_scope(struct definition_scope *parent_scope,
+                                    GQuark field_name)
+{
+       struct definition_scope *scope;
+
+       scope = _new_definition_scope(parent_scope, 1);
+       g_array_index(scope->scope_path, GQuark, 0) = field_name;
+       return scope;
+}
+
 void free_definition_scope(struct definition_scope *scope)
 {
        g_array_free(scope->scope_path, TRUE);
This page took 0.042298 seconds and 4 git commands to generate.