#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.
*/
}
static
-struct ctf_stream *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
+struct ctf_stream_class *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
{
if (trace->streams->len <= stream_id)
return NULL;
declaration = &array_declaration->p;
break;
}
- case NODE_INTEGER:
- case NODE_TYPE_SPECIFIER:
+ case NODE_TYPE_SPECIFIER_LIST:
{
struct declaration_sequence *sequence_declaration;
struct declaration_integer *integer_declaration;
- GQuark dummy_id;
- declaration = ctf_type_declarator_visit(fd, depth,
- length,
- &dummy_id, NULL,
- declaration_scope,
- NULL, trace);
- assert(declaration->id == CTF_TYPE_INTEGER);
+ declaration = ctf_type_specifier_list_visit(fd, depth,
+ length, declaration_scope, trace);
+ if (!declaration) {
+ fprintf(fd, "[error] %s: unable to find declaration type for sequence length\n", __func__);
+ return NULL;
+ }
+ if (declaration->id != CTF_TYPE_INTEGER) {
+ fprintf(fd, "[error] %s: length type for sequence is expected to be an integer (unsigned).\n", __func__);
+ declaration_unref(declaration);
+ return NULL;
+ }
integer_declaration = container_of(declaration, struct declaration_integer, p);
+ if (integer_declaration->signedness != false) {
+ fprintf(fd, "[error] %s: length type for sequence should always be an unsigned integer.\n", __func__);
+ declaration_unref(declaration);
+ return NULL;
+ }
+
sequence_declaration = sequence_declaration_new(integer_declaration,
nested_declaration, declaration_scope);
declaration = &sequence_declaration->p;
&field_name, iter,
struct_declaration->scope,
NULL, trace);
+ if (!field_declaration) {
+ fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
+ return -EINVAL;
+ }
struct_declaration_add_field(struct_declaration,
g_quark_to_string(field_name),
field_declaration);
&field_name, iter,
untagged_variant_declaration->scope,
NULL, trace);
+ if (!field_declaration) {
+ fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
+ return -EINVAL;
+ }
untagged_variant_declaration_add_field(untagged_variant_declaration,
g_quark_to_string(field_name),
field_declaration);
type_specifier_list,
&identifier, iter,
scope, NULL, trace);
+ if (!type_declaration) {
+ fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
+ return -EINVAL;
+ }
+ /*
+ * Don't allow typedef and typealias of untagged
+ * variants.
+ */
+ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
+ fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
+ declaration_unref(type_declaration);
+ return -EPERM;
+ }
ret = register_declaration(identifier, type_declaration, scope);
if (ret) {
type_declaration->declaration_free(type_declaration);
err = -EINVAL;
goto error;
}
+ /*
+ * Don't allow typedef and typealias of untagged
+ * variants.
+ */
+ if (type_declaration->id == CTF_TYPE_UNTAGGED_VARIANT) {
+ fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
+ declaration_unref(type_declaration);
+ return -EPERM;
+ }
/*
* The semantic validator does not check whether the target is
* abstract or not (if it has an identifier). Check it here.
static
struct declaration *ctf_declaration_struct_visit(FILE *fd,
int depth, const char *name, struct cds_list_head *declaration_list,
- int has_body, struct declaration_scope *declaration_scope,
+ int has_body, struct cds_list_head *min_align,
+ struct declaration_scope *declaration_scope,
struct ctf_trace *trace)
{
struct declaration_struct *struct_declaration;
declaration_scope);
return &struct_declaration->p;
} else {
+ uint64_t min_align_value = 0;
+
/* For unnamed struct, create type */
/* For named struct (with body), create type and add to declaration scope */
if (name) {
return NULL;
}
}
- struct_declaration = struct_declaration_new(declaration_scope);
+ if (!cds_list_empty(min_align)) {
+ ret = get_unary_unsigned(min_align, &min_align_value);
+ if (ret) {
+ fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ struct_declaration = struct_declaration_new(declaration_scope,
+ min_align_value);
cds_list_for_each_entry(iter, declaration_list, siblings) {
ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
struct_declaration, trace);
return &variant_declaration->p;
}
error:
- untagged_variant_declaration->p.declaration_free(&variant_declaration->p);
+ untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
return NULL;
}
}
+static
+int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
+{
+ int byte_order;
+
+ if (unary_expression->u.unary_expression.type != UNARY_STRING) {
+ fprintf(fd, "[error] %s: byte_order: expecting string\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
+ byte_order = BIG_ENDIAN;
+ else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
+ byte_order = LITTLE_ENDIAN;
+ else {
+ fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
+ __func__, unary_expression->u.unary_expression.u.string);
+ return -EINVAL;
+ }
+ return byte_order;
+}
+
static
int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
struct ctf_trace *trace)
return NULL;
}
alignment = right->u.unary_expression.u.unsigned_constant;
+ /* Make sure alignment is a power of two */
+ if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
+ fprintf(fd, "[error] %s: align: expecting power of two\n",
+ __func__);
+ return NULL;
+ }
has_alignment = 1;
} else {
fprintf(fd, "[error] %s: unknown attribute name %s\n",
return NULL;
}
alignment = right->u.unary_expression.u.unsigned_constant;
+ /* Make sure alignment is a power of two */
+ if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
+ fprintf(fd, "[error] %s: align: expecting power of two\n",
+ __func__);
+ return NULL;
+ }
has_alignment = 1;
} else {
fprintf(fd, "[error] %s: unknown attribute name %s\n",
node->u._struct.name,
&node->u._struct.declaration_list,
node->u._struct.has_body,
+ &node->u._struct.min_align,
declaration_scope,
trace);
case TYPESPEC_VARIANT:
if (CTF_EVENT_FIELD_IS_SET(event, name)) {
fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
right = concatenate_unary_strings(&node->u.ctf_expression.right);
if (!right) {
fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
event->name = g_quark_from_string(right);
g_free(right);
} else if (!strcmp(left, "id")) {
if (CTF_EVENT_FIELD_IS_SET(event, id)) {
fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_EVENT_SET_FIELD(event, id);
} else if (!strcmp(left, "stream_id")) {
if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
event->stream = trace_stream_lookup(trace, event->stream_id);
if (!event->stream) {
fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_EVENT_SET_FIELD(event, stream_id);
} else if (!strcmp(left, "context")) {
if (event->context_decl) {
fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
declaration = ctf_type_specifier_list_visit(fd, depth,
_cds_list_first_entry(&node->u.ctf_expression.right,
struct ctf_node, siblings),
event->declaration_scope, trace);
- if (!declaration)
- return -EPERM;
- if (declaration->id != CTF_TYPE_STRUCT)
- return -EPERM;
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
event->context_decl = container_of(declaration, struct declaration_struct, p);
} else if (!strcmp(left, "fields")) {
struct declaration *declaration;
if (event->fields_decl) {
fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
declaration = ctf_type_specifier_list_visit(fd, depth,
_cds_list_first_entry(&node->u.ctf_expression.right,
struct ctf_node, siblings),
event->declaration_scope, trace);
- if (!declaration)
- return -EPERM;
- if (declaration->id != CTF_TYPE_STRUCT)
- return -EPERM;
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
event->fields_decl = container_of(declaration, struct declaration_struct, p);
}
+error:
g_free(left);
break;
}
/* TODO: declaration specifier should be added. */
}
- return 0;
+ return ret;
}
static
fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
goto error;
}
- if (!CTF_EVENT_FIELD_IS_SET(event, id)) {
- 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 */
+ 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);
+ 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 stream_id field in event declaration\n", __func__);
+ fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
goto error;
}
if (event->stream->events_by_id->len <= event->id)
static
-int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream *stream, struct ctf_trace *trace)
+int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_class *stream, struct ctf_trace *trace)
{
int ret = 0;
if (!strcmp(left, "id")) {
if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_STREAM_SET_FIELD(stream, stream_id);
} else if (!strcmp(left, "event.header")) {
if (stream->event_header_decl) {
fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
declaration = ctf_type_specifier_list_visit(fd, depth,
_cds_list_first_entry(&node->u.ctf_expression.right,
struct ctf_node, siblings),
stream->declaration_scope, trace);
- if (!declaration)
- return -EPERM;
- if (declaration->id != CTF_TYPE_STRUCT)
- return -EPERM;
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
} else if (!strcmp(left, "event.context")) {
struct declaration *declaration;
if (stream->event_context_decl) {
fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
declaration = ctf_type_specifier_list_visit(fd, depth,
_cds_list_first_entry(&node->u.ctf_expression.right,
struct ctf_node, siblings),
stream->declaration_scope, trace);
- if (!declaration)
- return -EPERM;
- if (declaration->id != CTF_TYPE_STRUCT)
- return -EPERM;
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
} else if (!strcmp(left, "packet.context")) {
struct declaration *declaration;
if (stream->packet_context_decl) {
fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
declaration = ctf_type_specifier_list_visit(fd, depth,
_cds_list_first_entry(&node->u.ctf_expression.right,
struct ctf_node, siblings),
stream->declaration_scope, trace);
- if (!declaration)
- return -EPERM;
- if (declaration->id != CTF_TYPE_STRUCT)
- return -EPERM;
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
}
+error:
g_free(left);
break;
}
/* TODO: declaration specifier should be added. */
}
- return 0;
+ return ret;
}
static
{
int ret = 0;
struct ctf_node *iter;
- struct ctf_stream *stream;
+ struct ctf_stream_class *stream;
struct definition_scope *parent_def_scope;
- stream = g_new0(struct ctf_stream, 1);
+ stream = g_new0(struct ctf_stream_class, 1);
stream->declaration_scope = new_declaration_scope(parent_declaration_scope);
stream->events_by_id = g_ptr_array_new();
stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
- 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;
+ stream->files = g_ptr_array_new();
+ 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)) {
- ret = -EPERM;
- fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
- goto error;
+ if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
+ /* check that packet header has stream_id field. */
+ if (!trace->packet_header_decl
+ || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("stream_id")) < 0) {
+ ret = -EPERM;
+ fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\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);
g_ptr_array_index(trace->streams, stream->stream_id) = stream;
- parent_def_scope = NULL;
+ parent_def_scope = trace->definition_scope;
if (stream->packet_context_decl) {
stream->packet_context =
container_of(
declaration_unref(&stream->event_header_decl->p);
declaration_unref(&stream->event_context_decl->p);
declaration_unref(&stream->packet_context_decl->p);
+ g_ptr_array_free(stream->files, TRUE);
g_ptr_array_free(stream->events_by_id, TRUE);
g_hash_table_destroy(stream->event_quark_to_id);
free_declaration_scope(stream->declaration_scope);
if (!strcmp(left, "major")) {
if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_TRACE_SET_FIELD(trace, major);
} else if (!strcmp(left, "minor")) {
if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_TRACE_SET_FIELD(trace, minor);
- } else if (!strcmp(left, "word_size")) {
- if (CTF_TRACE_FIELD_IS_SET(trace, word_size)) {
- fprintf(fd, "[error] %s: word_size already declared in trace declaration\n", __func__);
- return -EPERM;
- }
- ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->word_size);
- if (ret) {
- fprintf(fd, "[error] %s: unexpected unary expression for trace word_size\n", __func__);
- return -EINVAL;
- }
- CTF_TRACE_SET_FIELD(trace, word_size);
} else if (!strcmp(left, "uuid")) {
if (CTF_TRACE_FIELD_IS_SET(trace, uuid)) {
fprintf(fd, "[error] %s: uuid already declared in trace declaration\n", __func__);
- return -EPERM;
+ ret = -EPERM;
+ goto error;
}
ret = get_unary_uuid(&node->u.ctf_expression.right, &trace->uuid);
if (ret) {
fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
CTF_TRACE_SET_FIELD(trace, uuid);
+ } else if (!strcmp(left, "byte_order")) {
+ struct ctf_node *right;
+ int byte_order;
+
+ if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
+ fprintf(fd, "[error] %s: endianness already declared in trace declaration\n", __func__);
+ ret = -EPERM;
+ goto error;
+ }
+ right = _cds_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
+ byte_order = get_trace_byte_order(fd, depth, right);
+ if (byte_order < 0)
+ return -EINVAL;
+ trace->byte_order = byte_order;
+ CTF_TRACE_SET_FIELD(trace, byte_order);
+ } else if (!strcmp(left, "packet.header")) {
+ struct declaration *declaration;
+
+ if (trace->packet_header_decl) {
+ fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
+ ret = -EINVAL;
+ goto error;
+ }
+ declaration = ctf_type_specifier_list_visit(fd, depth,
+ _cds_list_first_entry(&node->u.ctf_expression.right,
+ struct ctf_node, siblings),
+ trace->declaration_scope, trace);
+ if (!declaration) {
+ ret = -EPERM;
+ goto error;
+ }
+ if (declaration->id != CTF_TYPE_STRUCT) {
+ ret = -EPERM;
+ goto error;
+ }
+ trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
}
+error:
g_free(left);
break;
}
/* TODO: declaration specifier should be added. */
}
- return 0;
+ return ret;
}
static
int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
{
+ struct definition_scope *parent_def_scope;
int ret = 0;
struct ctf_node *iter;
fprintf(fd, "[error] %s: missing uuid field in trace declaration\n", __func__);
goto error;
}
- if (!CTF_TRACE_FIELD_IS_SET(trace, word_size)) {
+ if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
ret = -EPERM;
- fprintf(fd, "[error] %s: missing word_size field in trace declaration\n", __func__);
+ fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
goto error;
}
+
+ parent_def_scope = NULL;
+ if (trace->packet_header_decl) {
+ trace->packet_header =
+ container_of(
+ trace->packet_header_decl->p.definition_new(&trace->packet_header_decl->p,
+ parent_def_scope, 0, 0),
+ struct definition_struct, p);
+ set_dynamic_definition_scope(&trace->packet_header->p,
+ trace->packet_header->scope,
+ "trace.packet.header");
+ parent_def_scope = trace->packet_header->scope;
+ declaration_unref(&trace->packet_header_decl->p);
+ }
+ trace->definition_scope = parent_def_scope;
+
+ if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
+ /* check that the packet header contains a "magic" field */
+ if (!trace->packet_header
+ || struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_static_string("magic")) < 0) {
+ ret = -EPERM;
+ fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
+ goto error_free_def;
+ }
+ }
return 0;
+error_free_def:
+ definition_unref(&trace->packet_header->p);
error:
g_ptr_array_free(trace->streams, TRUE);
free_declaration_scope(trace->declaration_scope);
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->streams = g_ptr_array_new();
trace->byte_order = byte_order;
switch (node->type) {
(int) node->type);
return -EINVAL;
}
- fprintf(fd, "done.\n");
+ printf_verbose("done.\n");
return ret;
}