Allow missing stream {} declarator in single-stream traces
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-generate-io-struct.c
index f54307118f2601029688326f231360eb7d017ea4..ca1a83dd47617910320f4d7393b765f774a88a57 100644 (file)
@@ -44,6 +44,10 @@ struct declaration *ctf_type_specifier_list_visit(FILE *fd,
                struct declaration_scope *declaration_scope,
                struct ctf_trace *trace);
 
+static
+int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
+                    struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
+
 /*
  * String returned must be freed by the caller using g_free.
  */
@@ -1442,24 +1446,31 @@ int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
                fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
                goto error;
        }
-       /* Allow only one event without id per stream */
-       if (!CTF_EVENT_FIELD_IS_SET(event, id)
-           && event->stream->events_by_id->len != 0) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
-               goto error;
-       }
        if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
                /* Allow missing stream_id if there is only a single stream */
-               if (trace->streams->len == 1) {
+               switch (trace->streams->len) {
+               case 0: /* Create stream if there was none. */
+                       ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
+                       if (ret)
+                               goto error;
+                       /* Fall-through */
+               case 1:
                        event->stream_id = 0;
                        event->stream = trace_stream_lookup(trace, event->stream_id);
-               } else {
+                       break;
+               default:
                        ret = -EPERM;
                        fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
                        goto error;
                }
        }
+       /* Allow only one event without id per stream */
+       if (!CTF_EVENT_FIELD_IS_SET(event, id)
+           && event->stream->events_by_id->len != 0) {
+               ret = -EPERM;
+               fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
+               goto error;
+       }
        if (event->stream->events_by_id->len <= event->id)
                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;
@@ -1633,10 +1644,12 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
        stream->events_by_id = g_ptr_array_new();
        stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
        stream->files = g_ptr_array_new();
-       cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
-               ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
-               if (ret)
-                       goto error;
+       if (node) {
+               cds_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
+                       ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
+                       if (ret)
+                               goto error;
+               }
        }
        if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
                /* check that packet header has stream_id field. */
@@ -1646,14 +1659,14 @@ int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
                        fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
                        goto error;
                }
-       }
-
-       /* Allow only one id-less stream */
-       if (!CTF_STREAM_FIELD_IS_SET(stream, stream_id)
-           && trace->streams->len != 0) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
-               goto error;
+       } else {
+               /* Allow only one id-less stream */
+               if (trace->streams->len != 0) {
+                       ret = -EPERM;
+                       fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
+                       goto error;
+               }
+               stream->stream_id = 0;
        }
        if (trace->streams->len <= stream->stream_id)
                g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
This page took 0.024877 seconds and 4 git commands to generate.