#include <inttypes.h>
#include <endian.h>
#include <errno.h>
+#include <babeltrace/babeltrace.h>
#include <babeltrace/list.h>
#include <babeltrace/types.h>
#include <babeltrace/ctf/metadata.h>
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.
*/
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;
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. */
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);
fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
goto error;
}
+ if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
+ ret = -EPERM;
+ fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
+ goto error;
+ }
parent_def_scope = NULL;
if (trace->packet_header_decl) {
int ret = 0;
struct ctf_node *iter;
- fprintf(fd, "CTF visitor: metadata construction... ");
+ printf_verbose("CTF visitor: metadata construction... ");
trace->root_declaration_scope = new_declaration_scope(NULL);
trace->byte_order = byte_order;
(int) node->type);
return -EINVAL;
}
- fprintf(fd, "done.\n");
+ printf_verbose("done.\n");
return ret;
}