#include <babeltrace/ctf/metadata.h>
#include <babeltrace/ctf-text/types.h>
-static
-int convert_event(struct ctf_text_stream_pos *sout,
- struct ctf_file_stream *sin)
-{
- struct ctf_stream *stream_class = sin->stream;
- struct ctf_event *event_class;
- uint64_t id = 0;
- int len_index;
- int ret;
-
- if (sin->pos.offset == EOF)
- return EOF;
-
- /* Hide event payload struct brackets */
- sout->depth = -1;
-
- /* Read and print event header */
- if (stream_class->event_header) {
- ret = generic_rw(&sin->pos.parent, &stream_class->event_header->p);
- if (ret)
- goto error;
- /* lookup event id */
- len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl,
- g_quark_from_static_string("id"));
- if (len_index >= 0) {
- struct definition_integer *defint;
- struct definition *field;
-
- field = struct_definition_get_field_from_index(stream_class->event_header, len_index);
- assert(field->declaration->id == CTF_TYPE_INTEGER);
- defint = container_of(field, struct definition_integer, p);
- assert(defint->declaration->signedness == FALSE);
- id = defint->value._unsigned; /* set id */
- }
-
- ret = generic_rw(&sout->parent, &stream_class->event_header->p);
- if (ret)
- goto error;
- }
-
- /* Read and print stream-declared event context */
- if (stream_class->event_context) {
- ret = generic_rw(&sin->pos.parent, &stream_class->event_context->p);
- if (ret)
- goto error;
- ret = generic_rw(&sout->parent, &stream_class->event_context->p);
- if (ret)
- goto error;
- }
-
- if (id >= stream_class->events_by_id->len) {
- fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id);
- return -EINVAL;
- }
- event_class = g_ptr_array_index(stream_class->events_by_id, id);
- if (!event_class) {
- fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id);
- return -EINVAL;
- }
-
- /* Read and print event-declared event context */
- if (event_class->context) {
- ret = generic_rw(&sin->pos.parent, &event_class->context->p);
- if (ret)
- goto error;
- ret = generic_rw(&sout->parent, &event_class->context->p);
- if (ret)
- goto error;
- }
-
- /* Read and print event payload */
- if (event_class->fields) {
- ret = generic_rw(&sin->pos.parent, &event_class->fields->p);
- if (ret)
- goto error;
- ret = generic_rw(&sout->parent, &event_class->fields->p);
- if (ret)
- goto error;
- }
-
- return 0;
-
-error:
- fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
- return ret;
-}
-
static
int convert_stream(struct ctf_text_stream_pos *sout,
struct ctf_file_stream *sin)
/* For each event, print header, context, payload */
/* TODO: order events by timestamps across streams */
for (;;) {
- ret = convert_event(sout, sin);
+ ret = sin->pos.parent.event_cb(&sin->pos.parent, sin->stream);
if (ret == EOF)
break;
else if (ret) {
- fprintf(stdout, "[error] Printing event failed.\n");
+ fprintf(stdout, "[error] Reading event failed.\n");
+ goto error;
+ }
+ ret = sout->parent.event_cb(&sout->parent, sin->stream);
+ if (ret) {
+ fprintf(stdout, "[error] Writing event failed.\n");
goto error;
}
}
#include <babeltrace/format.h>
#include <babeltrace/ctf-text/types.h>
+#include <babeltrace/ctf/metadata.h>
#include <babeltrace/babeltrace.h>
#include <inttypes.h>
#include <uuid/uuid.h>
.close_trace = ctf_text_close_trace,
};
+static
+int ctf_text_write_event(struct stream_pos *ppos,
+ struct ctf_stream *stream_class)
+{
+ struct ctf_text_stream_pos *pos =
+ container_of(ppos, struct ctf_text_stream_pos, parent);
+ struct ctf_event *event_class;
+ uint64_t id = 0;
+ int len_index;
+ int ret;
+
+ /* print event header */
+ if (stream_class->event_header) {
+ /* lookup event id */
+ len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl,
+ g_quark_from_static_string("id"));
+ if (len_index >= 0) {
+ struct definition_integer *defint;
+ struct definition *field;
+
+ field = struct_definition_get_field_from_index(stream_class->event_header, len_index);
+ assert(field->declaration->id == CTF_TYPE_INTEGER);
+ defint = container_of(field, struct definition_integer, p);
+ assert(defint->declaration->signedness == FALSE);
+ id = defint->value._unsigned; /* set id */
+ }
+ }
+
+ if (id >= stream_class->events_by_id->len) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id);
+ return -EINVAL;
+ }
+ event_class = g_ptr_array_index(stream_class->events_by_id, id);
+ if (!event_class) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id);
+ return -EINVAL;
+ }
+
+ if (pos->print_names)
+ fprintf(pos->fp, "name = ");
+ fprintf(pos->fp, "%s", g_quark_to_string(event_class->name));
+
+ if (stream_class->event_header) {
+ if (pos->print_names)
+ fprintf(pos->fp, ", stream.event.header =");
+ fprintf(pos->fp, " ");
+ ret = generic_rw(ppos, &stream_class->event_header->p);
+ if (ret)
+ goto error;
+ }
+
+ /* print stream-declared event context */
+ if (stream_class->event_context) {
+ if (pos->print_names)
+ fprintf(pos->fp, ", stream.event.context =");
+ fprintf(pos->fp, " ");
+ ret = generic_rw(ppos, &stream_class->event_context->p);
+ if (ret)
+ goto error;
+ }
+
+ /* print event-declared event context */
+ if (event_class->context) {
+ if (pos->print_names)
+ fprintf(pos->fp, ", event.context =");
+ fprintf(pos->fp, " ");
+ ret = generic_rw(ppos, &event_class->context->p);
+ if (ret)
+ goto error;
+ }
+
+ /* Read and print event payload */
+ if (event_class->fields) {
+ if (pos->print_names)
+ fprintf(pos->fp, ", event.fields =");
+ fprintf(pos->fp, " ");
+ ret = generic_rw(ppos, &event_class->fields->p);
+ if (ret)
+ goto error;
+ }
+ fprintf(pos->fp, "\n");
+
+ return 0;
+
+error:
+ fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
+ return ret;
+}
+
+
struct trace_descriptor *ctf_text_open_trace(const char *path, int flags)
{
struct ctf_text_stream_pos *pos;
goto error;
pos->fp = fp;
pos->parent.rw_table = write_dispatch_table;
+ pos->parent.event_cb = ctf_text_write_event;
+ pos->print_names = 1;
break;
case O_RDONLY:
default:
int ret;
if (!pos->dummy) {
- print_pos_tabs(pos);
- fprintf(pos->fp, "[\n");
+ //print_pos_tabs(pos);
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+ fprintf(pos->fp, "[");
pos->depth++;
}
ret = array_rw(ppos, definition);
if (!pos->dummy) {
pos->depth--;
- print_pos_tabs(pos);
- fprintf(pos->fp, "]\n");
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " ]");
}
return ret;
}
if (pos->dummy)
return 0;
- print_pos_tabs(pos);
+
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+
+ //print_pos_tabs(pos);
fprintf(pos->fp, "(");
pos->depth++;
ret = generic_rw(ppos, &integer_definition->p);
- print_pos_tabs(pos);
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " :");
qs = enum_definition->value;
assert(qs);
for (i = 0; i < qs->len; i++) {
GQuark q = g_array_index(qs, GQuark, i);
const char *str = g_quark_to_string(q);
+
+ if (i != 0)
+ fprintf(pos->fp, ",");
+ fprintf(pos->fp, " ");
fprintf(pos->fp, "%s\n", str);
}
pos->depth--;
- print_pos_tabs(pos);
- fprintf(pos->fp, ")");
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " )");
return ret;
}
if (pos->dummy)
return 0;
- print_pos_tabs(pos);
+ //print_pos_tabs(pos);
+
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+
fprintf(pos->fp, "%Lg\n", float_definition->value);
return 0;
}
if (pos->dummy)
return 0;
- print_pos_tabs(pos);
+
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+
+ //print_pos_tabs(pos);
+
+ if (!compare_definition_path(definition, g_quark_from_static_string("stream.event.header.timestamp"))) {
+ if (!pos->print_names)
+ fprintf(pos->fp, "[%" PRIu64 "]",
+ integer_definition->value._unsigned);
+ else
+ fprintf(pos->fp, "%" PRIu64,
+ integer_definition->value._unsigned);
+ return 0;
+ }
+
if (!integer_declaration->signedness) {
- fprintf(pos->fp, "%" PRIu64" (0x%" PRIX64 ")\n",
+ fprintf(pos->fp, "%" PRIu64" (0x%" PRIX64 ")",
integer_definition->value._unsigned,
integer_definition->value._unsigned);
} else {
- fprintf(pos->fp, "%" PRId64" (0x%" PRIX64 ")\n",
+ fprintf(pos->fp, "%" PRId64" (0x%" PRIX64 ")",
integer_definition->value._signed,
integer_definition->value._signed);
}
int ret;
if (!pos->dummy) {
- print_pos_tabs(pos);
- fprintf(pos->fp, "[\n");
+ //print_pos_tabs(pos);
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+ fprintf(pos->fp, "[");
pos->depth++;
}
ret = sequence_rw(ppos, definition);
if (!pos->dummy) {
pos->depth--;
- print_pos_tabs(pos);
- fprintf(pos->fp, "]\n");
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " ]");
}
return ret;
}
assert(string_definition->value != NULL);
if (pos->dummy)
return 0;
- print_pos_tabs(pos);
- fprintf(pos->fp, "%s\n", string_definition->value);
+ //print_pos_tabs(pos);
+
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+
+ fprintf(pos->fp, "\"%s\"", string_definition->value);
return 0;
}
if (!pos->dummy) {
if (pos->depth >= 0) {
- print_pos_tabs(pos);
- fprintf(pos->fp, "{\n");
+ //print_pos_tabs(pos);
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names && definition->name != 0)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+ fprintf(pos->fp, "{");
}
pos->depth++;
}
if (!pos->dummy) {
pos->depth--;
if (pos->depth >= 0) {
- print_pos_tabs(pos);
- fprintf(pos->fp, "}\n");
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " }");
}
}
return ret;
#include <babeltrace/ctf-text/types.h>
#include <stdio.h>
-int ctf_text_variant_write(struct stream_pos *pos, struct definition *definition)
+int ctf_text_variant_write(struct stream_pos *ppos, struct definition *definition)
{
- return variant_rw(pos, definition);
+ struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
+ int ret;
+
+ if (!pos->dummy) {
+ if (pos->depth >= 0) {
+ //print_pos_tabs(pos);
+ if (definition->index != 0 && definition->index != INT_MAX)
+ fprintf(pos->fp, ",");
+ if (definition->index != INT_MAX)
+ fprintf(pos->fp, " ");
+ if (pos->print_names)
+ fprintf(pos->fp, "%s = ",
+ g_quark_to_string(definition->name));
+ fprintf(pos->fp, "{");
+ }
+ pos->depth++;
+ }
+ ret = variant_rw(ppos, definition);
+ if (!pos->dummy) {
+ pos->depth--;
+ if (pos->depth >= 0) {
+ //print_pos_tabs(pos);
+ fprintf(pos->fp, " }");
+ }
+ }
+ return ret;
}
.close_trace = ctf_close_trace,
};
+static
+int ctf_read_event(struct stream_pos *ppos, struct ctf_stream *stream_class)
+{
+ struct ctf_stream_pos *pos =
+ container_of(ppos, struct ctf_stream_pos, parent);
+ struct ctf_event *event_class;
+ uint64_t id = 0;
+ int len_index;
+ int ret;
+
+ if (pos->offset == EOF)
+ return EOF;
+
+ /* Read event header */
+ if (stream_class->event_header) {
+ ret = generic_rw(ppos, &stream_class->event_header->p);
+ if (ret)
+ goto error;
+ /* lookup event id */
+ len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl,
+ g_quark_from_static_string("id"));
+ if (len_index >= 0) {
+ struct definition_integer *defint;
+ struct definition *field;
+
+ field = struct_definition_get_field_from_index(stream_class->event_header, len_index);
+ assert(field->declaration->id == CTF_TYPE_INTEGER);
+ defint = container_of(field, struct definition_integer, p);
+ assert(defint->declaration->signedness == FALSE);
+ id = defint->value._unsigned; /* set id */
+ }
+ }
+
+ /* Read stream-declared event context */
+ if (stream_class->event_context) {
+ ret = generic_rw(ppos, &stream_class->event_context->p);
+ if (ret)
+ goto error;
+ }
+
+ if (id >= stream_class->events_by_id->len) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id);
+ return -EINVAL;
+ }
+ event_class = g_ptr_array_index(stream_class->events_by_id, id);
+ if (!event_class) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id);
+ return -EINVAL;
+ }
+
+ /* Read event-declared event context */
+ if (event_class->context) {
+ ret = generic_rw(ppos, &event_class->context->p);
+ if (ret)
+ goto error;
+ }
+
+ /* Read event payload */
+ if (event_class->fields) {
+ ret = generic_rw(ppos, &event_class->fields->p);
+ if (ret)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
+ return ret;
+}
+
+static
+int ctf_write_event(struct stream_pos *pos, struct ctf_stream *stream_class)
+{
+ struct ctf_event *event_class;
+ uint64_t id = 0;
+ int len_index;
+ int ret;
+
+ /* print event header */
+ if (stream_class->event_header) {
+ /* lookup event id */
+ len_index = struct_declaration_lookup_field_index(stream_class->event_header_decl,
+ g_quark_from_static_string("id"));
+ if (len_index >= 0) {
+ struct definition_integer *defint;
+ struct definition *field;
+
+ field = struct_definition_get_field_from_index(stream_class->event_header, len_index);
+ assert(field->declaration->id == CTF_TYPE_INTEGER);
+ defint = container_of(field, struct definition_integer, p);
+ assert(defint->declaration->signedness == FALSE);
+ id = defint->value._unsigned; /* set id */
+ }
+
+ ret = generic_rw(pos, &stream_class->event_header->p);
+ if (ret)
+ goto error;
+ }
+
+ /* print stream-declared event context */
+ if (stream_class->event_context) {
+ ret = generic_rw(pos, &stream_class->event_context->p);
+ if (ret)
+ goto error;
+ }
+
+ if (id >= stream_class->events_by_id->len) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is outside range.\n", id);
+ return -EINVAL;
+ }
+ event_class = g_ptr_array_index(stream_class->events_by_id, id);
+ if (!event_class) {
+ fprintf(stdout, "[error] Event id %" PRIu64 " is unknown.\n", id);
+ return -EINVAL;
+ }
+
+ /* print event-declared event context */
+ if (event_class->context) {
+ ret = generic_rw(pos, &event_class->context->p);
+ if (ret)
+ goto error;
+ }
+
+ /* Read and print event payload */
+ if (event_class->fields) {
+ ret = generic_rw(pos, &event_class->fields->p);
+ if (ret)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ fprintf(stdout, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
+ return ret;
+}
+
void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags)
{
pos->fd = fd;
pos->prot = PROT_READ;
pos->flags = MAP_PRIVATE;
pos->parent.rw_table = read_dispatch_table;
+ pos->parent.event_cb = ctf_read_event;
break;
case O_RDWR:
pos->prot = PROT_WRITE; /* Write has priority */
pos->flags = MAP_SHARED;
pos->parent.rw_table = write_dispatch_table;
+ pos->parent.event_cb = ctf_write_event;
if (fd >= 0)
ctf_move_pos_slow(pos, 0, SEEK_SET); /* position for write */
break;
FILE *fp; /* File pointer. NULL if unset. */
int depth;
int dummy; /* disable output */
+ int print_names; /* print field names */
};
static inline
/* Preallocate this many fields for structures */
#define DEFAULT_NR_STRUCT_FIELDS 8
+struct ctf_stream;
struct stream_pos;
struct format;
struct definition;
int index; /* Position of the definition in its container */
GQuark name; /* Field name in its container (or 0 if unset) */
int ref; /* number of references to the definition */
+ GQuark path;
};
typedef int (*rw_dispatch)(struct stream_pos *pos,
struct stream_pos {
/* read/write dispatch table. Specific to plugin used for stream. */
rw_dispatch *rw_table; /* rw dispatch table */
+ int (*event_cb)(struct stream_pos *pos,
+ struct ctf_stream *stream_class);
};
static inline
const char *root_name);
void free_definition_scope(struct definition_scope *scope);
+GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name);
+
+static inline
+int compare_definition_path(struct definition *definition, GQuark path)
+{
+ return definition->path == path;
+}
+
void declaration_ref(struct declaration *declaration);
void declaration_unref(struct declaration *declaration);
*/
void append_scope_path(const char *path, GArray *q);
-#endif /* _BABELTRACE_declarationS_H */
+#endif /* _BABELTRACE_TYPES_H */
array->p.ref = 1;
array->p.index = index;
array->p.name = field_name;
+ array->p.path = new_definition_path(parent_scope, field_name);
array->scope = new_definition_scope(parent_scope, field_name);
array->elems = g_ptr_array_sized_new(array_declaration->len);
g_ptr_array_set_size(array->elems, array_declaration->len);
_enum->p.ref = 1;
_enum->p.index = index;
_enum->p.name = field_name;
+ _enum->p.path = new_definition_path(parent_scope, field_name);
_enum->value = NULL;
definition_integer_parent =
enum_declaration->integer_declaration->p.definition_new(&enum_declaration->integer_declaration->p,
_float->p.ref = 1;
_float->p.index = index;
_float->p.name = field_name;
+ _float->p.path = new_definition_path(parent_scope, field_name);
_float->value = 0.0;
return &_float->p;
}
integer->p.ref = 1;
integer->p.index = index;
integer->p.name = field_name;
+ integer->p.path = new_definition_path(parent_scope, field_name);
integer->value._unsigned = 0;
return &integer->p;
}
sequence->p.ref = 1;
sequence->p.index = index;
sequence->p.name = field_name;
+ sequence->p.path = new_definition_path(parent_scope, field_name);
sequence->scope = new_definition_scope(parent_scope, field_name);
len_parent = sequence_declaration->len_declaration->p.definition_new(&sequence_declaration->len_declaration->p,
sequence->scope,
string->p.ref = 1;
string->p.index = index;
string->p.name = field_name;
+ string->p.path = new_definition_path(parent_scope, field_name);
string->value = NULL;
string->len = 0;
string->alloc_len = 0;
_struct->p.ref = 1;
_struct->p.index = index;
_struct->p.name = field_name;
+ _struct->p.path = new_definition_path(parent_scope, field_name);
_struct->scope = new_definition_scope(parent_scope, field_name);
_struct->fields = g_ptr_array_sized_new(DEFAULT_NR_STRUCT_FIELDS);
g_ptr_array_set_size(_struct->fields, struct_declaration->fields->len);
return scope;
}
+GQuark new_definition_path(struct definition_scope *parent_scope, GQuark field_name)
+{
+ GQuark path;
+ GString *str;
+ gchar *c_str;
+ int i;
+
+ str = g_string_new("");
+ if (parent_scope) {
+ for (i = 0; i < parent_scope->scope_path->len; i++) {
+ GQuark q = g_array_index(parent_scope->scope_path,
+ GQuark, i);
+
+ g_string_append(str, g_quark_to_string(q));
+ g_string_append(str, ".");
+ }
+ }
+ g_string_append(str, g_quark_to_string(field_name));
+ c_str = g_string_free(str, FALSE);
+ path = g_quark_from_string(c_str);
+ g_free(c_str);
+ return path;
+}
+
struct definition_scope *
new_definition_scope(struct definition_scope *parent_scope,
GQuark field_name)
variant->p.ref = 1;
variant->p.index = index;
variant->p.name = field_name;
+ variant->p.path = new_definition_path(parent_scope, field_name);
variant->scope = new_definition_scope(parent_scope, field_name);
variant->enum_tag = lookup_definition(variant->scope->scope_path,
variant_declaration->tag_name,