+}
+
+int bt_context_add_trace(struct bt_context *ctx, const char *path,
+ const char *format_name,
+ void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
+ int whence),
+ struct bt_mmap_stream_list *stream_list,
+ FILE *metadata)
+{
+ struct bt_trace_descriptor *td;
+ struct bt_format *fmt;
+ struct bt_trace_handle *handle;
+ int ret, closeret;
+
+ if (!ctx || !format_name || (!path && !stream_list))
+ return -EINVAL;
+
+ fmt = bt_lookup_format(g_quark_from_string(format_name));
+ if (!fmt) {
+ fprintf(stderr, "[error] [Context] Format \"%s\" unknown.\n\n",
+ format_name);
+ ret = -1;
+ goto end;
+ }
+ if (path) {
+ td = fmt->open_trace(path, O_RDONLY, packet_seek, NULL);
+ if (!td) {
+ fprintf(stderr, "[warning] [Context] Cannot open_trace of format %s at path %s.\n",
+ format_name, path);
+ ret = -1;
+ goto end;
+ }
+ } else {
+ td = fmt->open_mmap_trace(stream_list, packet_seek, metadata);
+ if (!td) {
+ fprintf(stderr, "[error] [Context] Cannot open_mmap_trace of format %s.\n\n",
+ format_name);
+ ret = -1;
+ goto end;
+ }
+ }
+
+ /* Create an handle for the trace */
+ handle = bt_trace_handle_create(ctx);
+ if (!handle) {
+ fprintf(stderr, "[error] [Context] Creating trace handle %s .\n\n",
+ path);
+ ret = -1;
+ goto error_close;
+ }
+ handle->format = fmt;
+ handle->td = td;
+ if (path) {
+ strncpy(handle->path, path, PATH_MAX);
+ handle->path[PATH_MAX - 1] = '\0';
+ }
+
+ ret = bt_trace_collection_add(ctx->tc, td);
+ if (ret != 0)
+ goto error_destroy_handle;
+
+ if (fmt->set_handle)
+ fmt->set_handle(td, handle);
+ if (fmt->set_context)
+ fmt->set_context(td, ctx);
+
+ if (fmt->convert_index_timestamp) {
+ ret = fmt->convert_index_timestamp(td);
+ if (ret < 0)
+ goto error_collection_del;
+ }