Show env. in verbose mode
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
index cb3dc008c76c126deffe53e85cbd5b6a829ba521..4a71a27e04024dae8ecfab95d69cd5854391bc13 100644 (file)
@@ -87,6 +87,50 @@ char *concatenate_unary_strings(struct cds_list_head *head)
        return g_string_free(str, FALSE);
 }
 
+static
+GQuark get_map_clock_name_value(struct cds_list_head *head)
+{
+       struct ctf_node *node;
+       const char *name = NULL;
+       int i = 0;
+
+       cds_list_for_each_entry(node, head, siblings) {
+               char *src_string;
+
+               assert(node->type == NODE_UNARY_EXPRESSION);
+               assert(node->u.unary_expression.type == UNARY_STRING);
+               assert((node->u.unary_expression.link == UNARY_LINK_UNKNOWN)
+                       ^ (i != 0));
+               /* needs to be chained with . */
+               switch (node->u.unary_expression.link) {
+               case UNARY_DOTLINK:
+                       break;
+               case UNARY_ARROWLINK:
+               case UNARY_DOTDOTDOT:
+                       return 0;
+               default:
+                       break;
+               }
+               src_string = node->u.unary_expression.u.string;
+               switch (i) {
+               case 0: if (strcmp("clock", src_string) != 0) {
+                               return 0;
+                       }
+                       break;
+               case 1: name = src_string;
+                       break;
+               case 2: if (strcmp("value", src_string) != 0) {
+                               return 0;
+                       }
+                       break;
+               default:
+                       return 0;       /* extra identifier, unknown */
+               }
+               i++;
+       }
+       return g_quark_from_string(name);
+}
+
 static
 int get_unary_unsigned(struct cds_list_head *head, uint64_t *value)
 {
@@ -112,10 +156,20 @@ int get_unary_signed(struct cds_list_head *head, int64_t *value)
 
        cds_list_for_each_entry(node, head, siblings) {
                assert(node->type == NODE_UNARY_EXPRESSION);
-               assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT);
+               assert(node->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT
+                       || node->u.unary_expression.type == UNARY_SIGNED_CONSTANT);
                assert(node->u.unary_expression.link == UNARY_LINK_UNKNOWN);
                assert(i == 0);
-               *value = node->u.unary_expression.u.signed_constant;
+               switch (node->u.unary_expression.type) {
+               case UNARY_UNSIGNED_CONSTANT:
+                       *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
+                       break;
+               case UNARY_SIGNED_CONSTANT:
+                       *value = node->u.unary_expression.u.signed_constant;
+                       break;
+               default:
+                       assert(0);
+               }
                i++;
        }
        return 0;
@@ -149,6 +203,12 @@ struct ctf_stream_class *trace_stream_lookup(struct ctf_trace *trace, uint64_t s
        return g_ptr_array_index(trace->streams, stream_id);
 }
 
+static
+struct ctf_clock *trace_clock_lookup(struct ctf_trace *trace, GQuark clock_name)
+{
+       return g_hash_table_lookup(trace->clocks, (gpointer) (unsigned long) clock_name);
+}
+
 static
 int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
 {
@@ -342,7 +402,8 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
                                         */
                                        integer_declaration = integer_declaration_new(integer_declaration->len,
                                                integer_declaration->byte_order, integer_declaration->signedness,
-                                               integer_declaration->p.alignment, 16, integer_declaration->encoding);
+                                               integer_declaration->p.alignment, 16, integer_declaration->encoding,
+                                               integer_declaration->clock);
                                        nested_declaration = &integer_declaration->p;
                                }
                        }
@@ -1116,6 +1177,7 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
        int has_alignment = 0, has_size = 0;
        int base = 0;
        enum ctf_string_encoding encoding = CTF_STRING_NONE;
+       struct ctf_clock *clock = NULL;
        struct declaration_integer *integer_declaration;
 
        cds_list_for_each_entry(expression, expressions, siblings) {
@@ -1235,21 +1297,35 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
                        }
                        g_free(s_right);
                } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
-                       char *s_right;
+                       GQuark clock_name;
 
                        if (right->u.unary_expression.type != UNARY_STRING) {
                                fprintf(fd, "[error] %s: map: expecting identifier\n",
                                        __func__);
                                return NULL;
                        }
-                       s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
-                       if (!s_right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
+                       /* currently only support clock.name.value */
+                       clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
+                       if (!clock_name) {
+                               char *s_right;
+
+                               s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
+                               if (!s_right) {
+                                       fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
+                                       g_free(s_right);
+                                       return NULL;
+                               }
+                               fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
+                                       s_right);
                                g_free(s_right);
+                               continue;
+                       }
+                       clock = trace_clock_lookup(trace, clock_name);
+                       if (!clock) {
+                               fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
+                                       __func__, g_quark_to_string(clock_name));
                                return NULL;
                        }
-                       /* TODO: lookup */
-
                } else {
                        fprintf(fd, "[warning] %s: unknown attribute name %s\n",
                                __func__, left->u.unary_expression.u.string);
@@ -1271,7 +1347,7 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
        }
        integer_declaration = integer_declaration_new(size,
                                byte_order, signedness, alignment,
-                               base, encoding);
+                               base, encoding, clock);
        return &integer_declaration->p;
 }
 
@@ -1583,36 +1659,22 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                                goto error;
                        }
                        event->fields_decl = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "loglevel.identifier")) {
-                       char *right;
+               } else if (!strcmp(left, "loglevel")) {
+                       int64_t loglevel = -1;
 
-                       if (CTF_EVENT_FIELD_IS_SET(event, loglevel_identifier)) {
-                               fprintf(fd, "[error] %s: identifier already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event identifier\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       event->loglevel_identifier = g_quark_from_string(right);
-                       g_free(right);
-                       CTF_EVENT_SET_FIELD(event, loglevel_identifier);
-               } else if (!strcmp(left, "loglevel.value")) {
-                       if (CTF_EVENT_FIELD_IS_SET(event, loglevel_value)) {
-                               fprintf(fd, "[error] %s: loglevel value already declared in event declaration\n", __func__);
+                       if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
+                               fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
                                ret = -EPERM;
                                goto error;
                        }
-                       ret = get_unary_signed(&node->u.ctf_expression.right, &event->loglevel_value);
+                       ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
                        if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event loglevel value\n", __func__);
+                               fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
                                ret = -EINVAL;
                                goto error;
                        }
-                       CTF_EVENT_SET_FIELD(event, loglevel_value);
+                       event->loglevel = (int) loglevel;
+                       CTF_EVENT_SET_FIELD(event, loglevel);
                } else {
                        fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
                        /* Fall-through after warning */
@@ -1639,6 +1701,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
 
        event = g_new0(struct ctf_event, 1);
        event->declaration_scope = new_declaration_scope(parent_declaration_scope);
+       event->loglevel = -1;
        cds_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
                ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
                if (ret)
@@ -1678,7 +1741,7 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
                g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
        g_ptr_array_index(event->stream->events_by_id, event->id) = event;
        g_hash_table_insert(event->stream->event_quark_to_id,
-                           (gpointer)(unsigned long) event->name,
+                           (gpointer) (unsigned long) event->name,
                            &event->id);
        return 0;
 
@@ -2175,6 +2238,17 @@ int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                                ret = -EINVAL;
                                goto error;
                        }
+               } else if (!strcmp(left, "absolute")) {
+                       struct ctf_node *right;
+
+                       right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
+                       ret = get_boolean(fd, depth, right);
+                       if (ret < 0) {
+                               fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
+                               ret = -EINVAL;
+                               goto error;
+                       }
+                       clock->absolute = ret;
                } else {
                        fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
                }
@@ -2227,6 +2301,144 @@ void clock_free(gpointer data)
        g_free(clock);
 }
 
+static
+int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
+               struct ctf_trace *trace)
+{
+       int ret = 0;
+       struct ctf_tracer_env *env = &trace->env;
+
+       switch (node->type) {
+       case NODE_CTF_EXPRESSION:
+       {
+               char *left;
+
+               left = concatenate_unary_strings(&node->u.ctf_expression.left);
+               if (!strcmp(left, "vpid")) {
+                       uint64_t v;
+
+                       if (env->vpid != -1) {
+                               fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
+                       if (ret) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       env->vpid = (int) v;
+                       printf_verbose("env.vpid = %d\n", env->vpid);
+               } else if (!strcmp(left, "procname")) {
+                       char *right;
+
+                       if (env->procname[0]) {
+                               fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       strncpy(env->procname, right, TRACER_ENV_LEN);
+                       env->procname[TRACER_ENV_LEN - 1] = '\0';
+                       printf_verbose("env.procname = %s\n", env->procname);
+               } else if (!strcmp(left, "domain")) {
+                       char *right;
+
+                       if (env->domain[0]) {
+                               fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       strncpy(env->domain, right, TRACER_ENV_LEN);
+                       env->domain[TRACER_ENV_LEN - 1] = '\0';
+                       printf_verbose("env.domain = %s\n", env->domain);
+               } else if (!strcmp(left, "sysname")) {
+                       char *right;
+
+                       if (env->sysname[0]) {
+                               fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       strncpy(env->sysname, right, TRACER_ENV_LEN);
+                       env->sysname[TRACER_ENV_LEN - 1] = '\0';
+                       printf_verbose("env.sysname = %s\n", env->sysname);
+               } else if (!strcmp(left, "release")) {
+                       char *right;
+
+                       if (env->release[0]) {
+                               fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       strncpy(env->release, right, TRACER_ENV_LEN);
+                       env->release[TRACER_ENV_LEN - 1] = '\0';
+                       printf_verbose("env.release = %s\n", env->release);
+               } else if (!strcmp(left, "version")) {
+                       char *right;
+
+                       if (env->version[0]) {
+                               fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
+                       if (!right) {
+                               fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
+                               goto error;     /* ret is 0, so not an actual error, just warn. */
+                       }
+                       strncpy(env->version, right, TRACER_ENV_LEN);
+                       env->version[TRACER_ENV_LEN - 1] = '\0';
+                       printf_verbose("env.version = %s\n", env->version);
+               } else {
+                       printf_verbose("%s: attribute \"%s\" is unknown in environment declaration.\n", __func__, left);
+               }
+
+error:
+               g_free(left);
+               break;
+       }
+       default:
+               return -EPERM;
+       }
+
+       return ret;
+}
+
+static
+int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
+{
+       int ret = 0;
+       struct ctf_node *iter;
+
+       trace->env.vpid = -1;
+       trace->env.procname[0] = '\0';
+       trace->env.domain[0] = '\0';
+       trace->env.sysname[0] = '\0';
+       trace->env.release[0] = '\0';
+       trace->env.version[0] = '\0';
+       cds_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
+               ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
+               if (ret)
+                       goto error;
+       }
+error:
+       return 0;
+}
+
 static
 int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
 {
@@ -2278,6 +2490,7 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
 {
        int ret = 0;
        struct ctf_node *iter;
+       int env_clock_done = 0;
 
        printf_verbose("CTF visitor: metadata construction... ");
        trace->byte_order = byte_order;
@@ -2289,6 +2502,21 @@ retry:
 
        switch (node->type) {
        case NODE_ROOT:
+               if (!env_clock_done) {
+                       /*
+                        * declarations need to query clock hash table,
+                        * so clock need to be treated first.
+                        */
+                       cds_list_for_each_entry(iter, &node->u.root.clock, siblings) {
+                               ret = ctf_clock_visit(fd, depth + 1, iter,
+                                                     trace);
+                               if (ret) {
+                                       fprintf(fd, "[error] %s: clock declaration error\n", __func__);
+                                       goto error;
+                               }
+                       }
+                       env_clock_done = 1;
+               }
                cds_list_for_each_entry(iter, &node->u.root.declaration_list,
                                        siblings) {
                        ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
@@ -2313,20 +2541,18 @@ retry:
                                goto error;
                        }
                }
-               cds_list_for_each_entry(iter, &node->u.root.clock, siblings) {
-                       ret = ctf_clock_visit(fd, depth + 1, iter,
-                                             trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: clock declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-
                if (!trace->streams) {
                        fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
                        ret = -EINVAL;
                        goto error;
                }
+               cds_list_for_each_entry(iter, &node->u.root.env, siblings) {
+                       ret = ctf_env_visit(fd, depth + 1, iter, trace);
+                       if (ret) {
+                               fprintf(fd, "[error] %s: env declaration error\n", __func__);
+                               goto error;
+                       }
+               }
                cds_list_for_each_entry(iter, &node->u.root.stream, siblings) {
                        ret = ctf_stream_visit(fd, depth + 1, iter,
                                               trace->root_declaration_scope, trace);
This page took 0.029205 seconds and 4 git commands to generate.