CTF IR -> Trace IR
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 15 Nov 2018 13:20:23 +0000 (08:20 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 3 May 2019 22:19:35 +0000 (18:19 -0400)
Also, keep an `include/babeltrace/ctf-ir` directory of which the headers
are only including corresponding CTF writer headers for backward
compatibility.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
142 files changed:
.gitignore
CONTRIBUTING.adoc
configure.ac
include/Makefile.am
include/babeltrace/babeltrace.h
include/babeltrace/common-internal.h
include/babeltrace/ctf-ir/attributes-internal.h [deleted file]
include/babeltrace/ctf-ir/clock-class-internal.h [deleted file]
include/babeltrace/ctf-ir/clock-class.h [deleted file]
include/babeltrace/ctf-ir/clock-value-internal.h [deleted file]
include/babeltrace/ctf-ir/clock-value-set-internal.h [deleted file]
include/babeltrace/ctf-ir/clock-value.h [deleted file]
include/babeltrace/ctf-ir/clock.h
include/babeltrace/ctf-ir/event-class-internal.h [deleted file]
include/babeltrace/ctf-ir/event-class.h
include/babeltrace/ctf-ir/event-fields.h [new file with mode: 0644]
include/babeltrace/ctf-ir/event-header-field.h [deleted file]
include/babeltrace/ctf-ir/event-internal.h [deleted file]
include/babeltrace/ctf-ir/event-types.h [new file with mode: 0644]
include/babeltrace/ctf-ir/event.h
include/babeltrace/ctf-ir/field-path-internal.h [deleted file]
include/babeltrace/ctf-ir/field-path.h [deleted file]
include/babeltrace/ctf-ir/field-types-internal.h [deleted file]
include/babeltrace/ctf-ir/field-types.h
include/babeltrace/ctf-ir/field-wrapper-internal.h [deleted file]
include/babeltrace/ctf-ir/fields-internal.h [deleted file]
include/babeltrace/ctf-ir/fields.h
include/babeltrace/ctf-ir/packet-context-field.h [deleted file]
include/babeltrace/ctf-ir/packet-header-field.h [deleted file]
include/babeltrace/ctf-ir/packet-internal.h [deleted file]
include/babeltrace/ctf-ir/packet.h [deleted file]
include/babeltrace/ctf-ir/resolve-field-path-internal.h [deleted file]
include/babeltrace/ctf-ir/resolve-internal.h [deleted file]
include/babeltrace/ctf-ir/stream-class-internal.h [deleted file]
include/babeltrace/ctf-ir/stream-class.h
include/babeltrace/ctf-ir/stream-internal.h [deleted file]
include/babeltrace/ctf-ir/stream.h
include/babeltrace/ctf-ir/trace-internal.h [deleted file]
include/babeltrace/ctf-ir/trace.h
include/babeltrace/ctf-ir/utils-internal.h [deleted file]
include/babeltrace/ctf-ir/utils.h [new file with mode: 0644]
include/babeltrace/ctf-writer/visitor.h
include/babeltrace/ctf/events.h
include/babeltrace/graph/notification-event-internal.h
include/babeltrace/graph/notification-inactivity-internal.h
include/babeltrace/graph/notification-internal.h
include/babeltrace/graph/notification-packet-internal.h
include/babeltrace/graph/notification-stream-internal.h
include/babeltrace/lib-logging-internal.h
include/babeltrace/trace-ir/attributes-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock-class-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock-class.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock-value-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock-value-set-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock-value.h [new file with mode: 0644]
include/babeltrace/trace-ir/clock.h [new file with mode: 0644]
include/babeltrace/trace-ir/event-class-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/event-class.h [new file with mode: 0644]
include/babeltrace/trace-ir/event-header-field.h [new file with mode: 0644]
include/babeltrace/trace-ir/event-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/event.h [new file with mode: 0644]
include/babeltrace/trace-ir/field-path-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/field-path.h [new file with mode: 0644]
include/babeltrace/trace-ir/field-types-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/field-types.h [new file with mode: 0644]
include/babeltrace/trace-ir/field-wrapper-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/fields-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/fields.h [new file with mode: 0644]
include/babeltrace/trace-ir/packet-context-field.h [new file with mode: 0644]
include/babeltrace/trace-ir/packet-header-field.h [new file with mode: 0644]
include/babeltrace/trace-ir/packet-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/packet.h [new file with mode: 0644]
include/babeltrace/trace-ir/resolve-field-path-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/resolve-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/stream-class-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/stream-class.h [new file with mode: 0644]
include/babeltrace/trace-ir/stream-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/stream.h [new file with mode: 0644]
include/babeltrace/trace-ir/trace-internal.h [new file with mode: 0644]
include/babeltrace/trace-ir/trace.h [new file with mode: 0644]
include/babeltrace/trace-ir/utils-internal.h [new file with mode: 0644]
lib/Makefile.am
lib/ctf-ir/Makefile.am [deleted file]
lib/ctf-ir/attributes.c [deleted file]
lib/ctf-ir/clock-class.c [deleted file]
lib/ctf-ir/clock-value.c [deleted file]
lib/ctf-ir/event-class.c [deleted file]
lib/ctf-ir/event-header-field.c [deleted file]
lib/ctf-ir/event.c [deleted file]
lib/ctf-ir/field-path.c [deleted file]
lib/ctf-ir/field-types.c [deleted file]
lib/ctf-ir/field-wrapper.c [deleted file]
lib/ctf-ir/fields.c [deleted file]
lib/ctf-ir/packet-context-field.c [deleted file]
lib/ctf-ir/packet-header-field.c [deleted file]
lib/ctf-ir/packet.c [deleted file]
lib/ctf-ir/resolve-field-path.c [deleted file]
lib/ctf-ir/stream-class.c [deleted file]
lib/ctf-ir/stream.c [deleted file]
lib/ctf-ir/trace.c [deleted file]
lib/ctf-ir/utils.c [deleted file]
lib/graph/iterator.c
lib/graph/notification/event.c
lib/graph/notification/inactivity.c
lib/graph/notification/packet.c
lib/graph/notification/stream.c
lib/lib-logging.c
lib/trace-ir/Makefile.am [new file with mode: 0644]
lib/trace-ir/attributes.c [new file with mode: 0644]
lib/trace-ir/clock-class.c [new file with mode: 0644]
lib/trace-ir/clock-value.c [new file with mode: 0644]
lib/trace-ir/event-class.c [new file with mode: 0644]
lib/trace-ir/event-header-field.c [new file with mode: 0644]
lib/trace-ir/event.c [new file with mode: 0644]
lib/trace-ir/field-path.c [new file with mode: 0644]
lib/trace-ir/field-types.c [new file with mode: 0644]
lib/trace-ir/field-wrapper.c [new file with mode: 0644]
lib/trace-ir/fields.c [new file with mode: 0644]
lib/trace-ir/packet-context-field.c [new file with mode: 0644]
lib/trace-ir/packet-header-field.c [new file with mode: 0644]
lib/trace-ir/packet.c [new file with mode: 0644]
lib/trace-ir/resolve-field-path.c [new file with mode: 0644]
lib/trace-ir/stream-class.c [new file with mode: 0644]
lib/trace-ir/stream.c [new file with mode: 0644]
lib/trace-ir/trace.c [new file with mode: 0644]
lib/trace-ir/utils.c [new file with mode: 0644]
plugins/ctf/fs-src/fs.h
tests/Makefile.am
tests/lib/Makefile.am
tests/lib/ctf-ir/Makefile.am [deleted file]
tests/lib/ctf-ir/test_ctf_ir.in [deleted file]
tests/lib/ctf-ir/test_stream_class.py [deleted file]
tests/lib/ctf-ir/test_trace.py [deleted file]
tests/lib/test_bt_notification_iterator.c
tests/lib/test_ctf_ir_ref.c [deleted file]
tests/lib/test_ir_visit.c
tests/lib/test_plugin.c
tests/lib/test_trace_ir_ref.c [new file with mode: 0644]
tests/lib/trace-ir/Makefile.am [new file with mode: 0644]
tests/lib/trace-ir/test_stream_class.py [new file with mode: 0644]
tests/lib/trace-ir/test_trace.py [new file with mode: 0644]
tests/lib/trace-ir/test_trace_ir.in [new file with mode: 0644]

index b2dcb450c74326241ca2fe2b352c22ac6075fe05..0ef95c97367d7329c79f77de2b2c8b317f17d0ca 100644 (file)
@@ -18,7 +18,7 @@
 /tests/lib/test_bt_notification_heap
 /tests/lib/test_bt_objects
 /tests/lib/test_bt_values
-/tests/lib/test_ctf_ir_ref
+/tests/lib/test_trace_ir_ref
 /tests/lib/test_ctf_writer
 /tests/lib/test_ctf_writer_complete
 /tests/lib/test_dwarf
@@ -33,7 +33,7 @@
 /tests/lib/test_bt_notification_iterator
 /tests/lib/test_cc_prio_map
 /tests/lib/test_graph_topo
-/tests/lib/ctf-ir/test_ctf_ir
+/tests/lib/trace-ir/test_trace_ir
 /tests/lib/ctf-writer/test_ctf_writer
 /tests/plugins/test-utils-muxer
 /tests/plugins/test-utils-muxer-complete
index f18f9b06d49517e739e575ad8ae20cb757942b35..bc6ff471ec403e22e6f2e1698ed35211eedee2f2 100644 (file)
@@ -69,9 +69,9 @@ node of the graph keeps all other reachable nodes alive.
 
 The scheme employed in Babeltrace to break this cycle consists in the
 "children" holding *reverse component references* to their parents. That
-is, in the context of CTF IR, that event classes hold a reference to
-their parent stream class and stream classes hold a reference to their
-parent trace.
+is, in the context of the trace IR, that event classes hold a reference
+to their parent stream class and stream classes hold a reference to
+their parent trace.
 
 On the other hand, parents hold *claiming aggregation references* to
 their children. A claiming aggregation reference means that the object
index 16d45c81f4cfe2f92c1d4691c64f8eac1e17b8c9..bf065d63479bbcc2651ea334e3487146a7878747 100644 (file)
@@ -744,7 +744,7 @@ AC_CONFIG_FILES([
        lib/plugin/Makefile
        lib/graph/Makefile
        lib/graph/notification/Makefile
-       lib/ctf-ir/Makefile
+       lib/trace-ir/Makefile
        lib/ctf-writer/Makefile
        include/Makefile
        logging/Makefile
@@ -754,7 +754,7 @@ AC_CONFIG_FILES([
        tests/cli/intersection/Makefile
        tests/lib/Makefile
        tests/lib/test-plugin-plugins/Makefile
-       tests/lib/ctf-ir/Makefile
+       tests/lib/trace-ir/Makefile
        tests/lib/ctf-writer/Makefile
        tests/utils/common.sh
        tests/utils/Makefile
@@ -800,7 +800,7 @@ AC_CONFIG_FILES([tests/cli/test_trace_read], [chmod +x tests/cli/test_trace_read
 AC_CONFIG_FILES([tests/cli/test_trimmer], [chmod +x tests/cli/test_trimmer])
 AC_CONFIG_FILES([tests/lib/test_ctf_writer_complete], [chmod +x tests/lib/test_ctf_writer_complete])
 AC_CONFIG_FILES([tests/lib/test_plugin_complete], [chmod +x tests/lib/test_plugin_complete])
-AC_CONFIG_FILES([tests/lib/ctf-ir/test_ctf_ir], [chmod +x tests/lib/ctf-ir/test_ctf_ir])
+AC_CONFIG_FILES([tests/lib/trace-ir/test_trace_ir], [chmod +x tests/lib/trace-ir/test_trace_ir])
 AC_CONFIG_FILES([tests/lib/ctf-writer/test_ctf_writer], [chmod +x tests/lib/ctf-writer/test_ctf_writer])
 AC_CONFIG_FILES([tests/plugins/test-utils-muxer-complete], [chmod +x tests/plugins/test-utils-muxer-complete])
 AC_CONFIG_FILES([tests/plugins/test_lttng_utils_debug_info], [chmod +x tests/plugins/test_lttng_utils_debug_info])
index 0bdd90a836867b01a77e4270618b8615de72fc6a..11ecd94c4e2c194678d3bfc897bfe65c7addda0f 100644 (file)
@@ -99,24 +99,39 @@ babeltracectfwriterinclude_HEADERS = \
        babeltrace/ctf-writer/visitor.h \
        babeltrace/ctf-writer/writer.h
 
-# CTF IR API
+# Legacy API (for CTF writer)
 babeltracectfirincludedir = "$(includedir)/babeltrace/ctf-ir"
 babeltracectfirinclude_HEADERS = \
-       babeltrace/ctf-ir/clock-class.h \
-       babeltrace/ctf-ir/clock-value.h \
        babeltrace/ctf-ir/clock.h \
        babeltrace/ctf-ir/event-class.h \
+       babeltrace/ctf-ir/event-fields.h \
+       babeltrace/ctf-ir/event-types.h \
        babeltrace/ctf-ir/event.h \
-       babeltrace/ctf-ir/event-header-field.h \
-       babeltrace/ctf-ir/field-path.h \
        babeltrace/ctf-ir/field-types.h \
        babeltrace/ctf-ir/fields.h \
-       babeltrace/ctf-ir/packet.h \
-       babeltrace/ctf-ir/packet-context-field.h \
-       babeltrace/ctf-ir/packet-header-field.h \
        babeltrace/ctf-ir/stream-class.h \
        babeltrace/ctf-ir/stream.h \
-       babeltrace/ctf-ir/trace.h
+       babeltrace/ctf-ir/trace.h \
+       babeltrace/ctf-ir/utils.h
+
+
+# Trace IR API
+babeltracetraceirincludedir = "$(includedir)/babeltrace/trace-ir"
+babeltracetraceirinclude_HEADERS = \
+       babeltrace/trace-ir/clock-class.h \
+       babeltrace/trace-ir/clock-value.h \
+       babeltrace/trace-ir/event-class.h \
+       babeltrace/trace-ir/event.h \
+       babeltrace/trace-ir/event-header-field.h \
+       babeltrace/trace-ir/field-path.h \
+       babeltrace/trace-ir/field-types.h \
+       babeltrace/trace-ir/fields.h \
+       babeltrace/trace-ir/packet.h \
+       babeltrace/trace-ir/packet-context-field.h \
+       babeltrace/trace-ir/packet-header-field.h \
+       babeltrace/trace-ir/stream-class.h \
+       babeltrace/trace-ir/stream.h \
+       babeltrace/trace-ir/trace.h
 
 # Plugin and plugin development API
 babeltracepluginincludedir = "$(includedir)/babeltrace/plugin"
@@ -202,21 +217,21 @@ noinst_HEADERS = \
        babeltrace/align-internal.h \
        babeltrace/logging-internal.h \
        babeltrace/endian-internal.h \
-       babeltrace/ctf-ir/packet-internal.h \
-       babeltrace/ctf-ir/event-class-internal.h \
-       babeltrace/ctf-ir/utils-internal.h \
-       babeltrace/ctf-ir/fields-internal.h \
-       babeltrace/ctf-ir/stream-class-internal.h \
-       babeltrace/ctf-ir/event-internal.h \
-       babeltrace/ctf-ir/field-path-internal.h \
-       babeltrace/ctf-ir/field-wrapper-internal.h \
-       babeltrace/ctf-ir/trace-internal.h \
-       babeltrace/ctf-ir/clock-class-internal.h \
-       babeltrace/ctf-ir/field-types-internal.h \
-       babeltrace/ctf-ir/clock-value-internal.h \
-       babeltrace/ctf-ir/attributes-internal.h \
-       babeltrace/ctf-ir/stream-internal.h \
-       babeltrace/ctf-ir/resolve-field-path-internal.h \
+       babeltrace/trace-ir/packet-internal.h \
+       babeltrace/trace-ir/event-class-internal.h \
+       babeltrace/trace-ir/utils-internal.h \
+       babeltrace/trace-ir/fields-internal.h \
+       babeltrace/trace-ir/stream-class-internal.h \
+       babeltrace/trace-ir/event-internal.h \
+       babeltrace/trace-ir/field-path-internal.h \
+       babeltrace/trace-ir/field-wrapper-internal.h \
+       babeltrace/trace-ir/trace-internal.h \
+       babeltrace/trace-ir/clock-class-internal.h \
+       babeltrace/trace-ir/field-types-internal.h \
+       babeltrace/trace-ir/clock-value-internal.h \
+       babeltrace/trace-ir/attributes-internal.h \
+       babeltrace/trace-ir/stream-internal.h \
+       babeltrace/trace-ir/resolve-field-path-internal.h \
        babeltrace/prio-heap-internal.h \
        babeltrace/lib-logging-internal.h \
        babeltrace/compiler-internal.h \
index 3f99631db27815e6069140b49069222566507e66..ab8a95ccc3c5780a1f0a3ff8579efd6330b0c244 100644 (file)
 #include <babeltrace/ctf-writer/visitor.h>
 #include <babeltrace/ctf-writer/writer.h>
 
-/* CTF IR API */
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/clock.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-header-field.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/packet-context-field.h>
-#include <babeltrace/ctf-ir/packet-header-field.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
+/* Trace IR API */
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/clock.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-header-field.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/packet-context-field.h>
+#include <babeltrace/trace-ir/packet-header-field.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
 
 /* Plugin and plugin development API */
 #include <babeltrace/plugin/plugin-dev.h>
index e22a9231a8590b6d661a8d3375a10ef0dc22bde3..584e38a1e6320da4005f7fce50e75b29caa217b6 100644 (file)
@@ -4,9 +4,9 @@
 #include <stdbool.h>
 #include <babeltrace/assert-internal.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/event-class.h>
 #include <stdarg.h>
 #include <inttypes.h>
 #include <stdint.h>
diff --git a/include/babeltrace/ctf-ir/attributes-internal.h b/include/babeltrace/ctf-ir/attributes-internal.h
deleted file mode 100644 (file)
index d7dda55..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_ATTRIBUTES_H
-#define BABELTRACE_CTF_IR_ATTRIBUTES_H
-
-/*
- * attributes.c
- *
- * Babeltrace - CTF IR: Attributes internal
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-
-BT_HIDDEN
-struct bt_value *bt_attributes_create(void);
-
-BT_HIDDEN
-void bt_attributes_destroy(struct bt_value *attr_obj);
-
-BT_HIDDEN
-int64_t bt_attributes_get_count(struct bt_value *attr_obj);
-
-BT_HIDDEN
-const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
-               uint64_t index);
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
-               uint64_t index);
-
-BT_HIDDEN
-int bt_attributes_set_field_value(struct bt_value *attr_obj,
-               const char *name, struct bt_value *value_obj);
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value_by_name(
-               struct bt_value *attr_obj, const char *name);
-
-BT_HIDDEN
-int bt_attributes_freeze(struct bt_value *attr_obj);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_ATTRIBUTES_H */
diff --git a/include/babeltrace/ctf-ir/clock-class-internal.h b/include/babeltrace/ctf-ir/clock-class-internal.h
deleted file mode 100644 (file)
index aab9cb4..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Clock internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/property-internal.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <glib.h>
-
-struct bt_clock_class {
-       struct bt_object base;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } name;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } description;
-
-       uint64_t frequency;
-       uint64_t precision;
-       int64_t offset_seconds;
-       uint64_t offset_cycles;
-
-       struct {
-               uint8_t uuid[BABELTRACE_UUID_LEN];
-
-               /* NULL or `uuid` above */
-               bt_uuid value;
-       } uuid;
-
-       bool is_absolute;
-
-       /*
-        * This is computed every time you call
-        * bt_clock_class_set_frequency() or
-        * bt_clock_class_set_offset(), as well as initially. It is the
-        * base offset in nanoseconds including both `offset_seconds`
-        * and `offset_cycles` above in the result. It is used to
-        * accelerate future calls to
-        * bt_clock_value_get_ns_from_origin() and
-        * bt_clock_class_cycles_to_ns_from_origin().
-        *
-        * `overflows` is true if the base offset cannot be computed
-        * because of an overflow.
-        */
-       struct {
-               int64_t value_ns;
-               bool overflows;
-       } base_offset;
-
-       /* Pool of `struct bt_clock_value *` */
-       struct bt_object_pool cv_pool;
-
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_clock_class_freeze(struct bt_clock_class *clock_class);
-
-#ifdef BT_DEV_MODE
-# define bt_clock_class_freeze         _bt_clock_class_freeze
-#else
-# define bt_clock_class_freeze(_cc)
-#endif
-
-BT_HIDDEN
-bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class);
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/clock-class.h b/include/babeltrace/ctf-ir/clock-class.h
deleted file mode 100644 (file)
index 40f53ad..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_CLOCK_CLASS_H
-#define BABELTRACE_CTF_IR_CLOCK_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool, bt_uuid */
-#include <babeltrace/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_clock_class;
-struct bt_clock_value;
-
-extern struct bt_clock_class *bt_clock_class_create(void);
-
-extern const char *bt_clock_class_get_name(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_name(struct bt_clock_class *clock_class,
-               const char *name);
-
-extern const char *bt_clock_class_get_description(
-               struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_description(struct bt_clock_class *clock_class,
-               const char *description);
-
-extern uint64_t bt_clock_class_get_frequency(
-               struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
-               uint64_t freq);
-
-extern uint64_t bt_clock_class_get_precision(
-               struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
-               uint64_t precision);
-
-extern void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
-               int64_t *seconds, uint64_t *cycles);
-
-extern int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
-               int64_t seconds, uint64_t cycles);
-
-extern bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
-               bt_bool is_absolute);
-
-extern bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class);
-
-extern int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
-               bt_uuid uuid);
-
-extern int bt_clock_class_cycles_to_ns_from_origin(
-               struct bt_clock_class *clock_class,
-               uint64_t cycles, int64_t *ns_from_origin);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_CLASS_H */
diff --git a/include/babeltrace/ctf-ir/clock-value-internal.h b/include/babeltrace/ctf-ir/clock-value-internal.h
deleted file mode 100644 (file)
index 1beb9fa..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
-#define BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H
-
-/*
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-struct bt_clock_class;
-
-struct bt_clock_value {
-       struct bt_object base;
-       struct bt_clock_class *clock_class;
-       uint64_t value_cycles;
-       bool ns_from_origin_overflows;
-       int64_t ns_from_origin;
-       bool is_set;
-};
-
-static inline
-void bt_clock_value_set(struct bt_clock_value *clock_value)
-{
-       BT_ASSERT(clock_value);
-       clock_value->is_set = true;
-}
-
-static inline
-void bt_clock_value_reset(struct bt_clock_value *clock_value)
-{
-       BT_ASSERT(clock_value);
-       clock_value->is_set = false;
-}
-
-static inline
-void set_ns_from_origin(struct bt_clock_value *clock_value)
-{
-       if (bt_util_ns_from_origin(clock_value->clock_class, clock_value->value_cycles,
-                       &clock_value->ns_from_origin)) {
-               clock_value->ns_from_origin_overflows = true;
-       }
-
-}
-
-static inline
-void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
-               uint64_t cycles)
-{
-       BT_ASSERT(clock_value);
-       clock_value->value_cycles = cycles;
-       set_ns_from_origin(clock_value);
-       bt_clock_value_set(clock_value);
-}
-
-static inline
-void bt_clock_value_set_value_inline(struct bt_clock_value *clock_value,
-               uint64_t raw_value)
-{
-       bt_clock_value_set_raw_value(clock_value, raw_value);
-}
-
-BT_HIDDEN
-void bt_clock_value_destroy(struct bt_clock_value *clock_value);
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class);
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_create(
-               struct bt_clock_class *clock_class);
-
-BT_HIDDEN
-void bt_clock_value_recycle(struct bt_clock_value *clock_value);
-
-BT_HIDDEN
-void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
-               uint64_t cycles);
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_VALUE_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/clock-value-set-internal.h b/include/babeltrace/ctf-ir/clock-value-set-internal.h
deleted file mode 100644 (file)
index 43205d0..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-#ifndef BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
-#define BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdint.h>
-#include <glib.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/assert-internal.h>
-
-struct bt_clock_value_set {
-       /* Unique objects owned by this */
-       GPtrArray *clock_values;
-
-       /* Weak; points to one of the clock values above */
-       struct bt_clock_value *default_cv;
-};
-
-static inline
-int bt_clock_value_set_initialize(struct bt_clock_value_set *cv_set)
-{
-       int ret = 0;
-
-       cv_set->clock_values = g_ptr_array_sized_new(1);
-       if (!cv_set->clock_values) {
-#ifdef BT_LOGE_STR
-               BT_LOGE_STR("Failed to allocate one GPtrArray.");
-#endif
-
-               ret = -1;
-               goto end;
-       }
-
-       cv_set->default_cv = NULL;
-
-end:
-       return ret;
-}
-
-static inline
-void bt_clock_value_set_reset(struct bt_clock_value_set *cv_set)
-{
-       uint64_t i;
-
-       BT_ASSERT(cv_set);
-       BT_ASSERT(cv_set->clock_values);
-
-       for (i = 0; i < cv_set->clock_values->len; i++) {
-               struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
-
-               BT_ASSERT(cv);
-               bt_clock_value_reset(cv);
-       }
-
-       cv_set->default_cv = NULL;
-}
-
-static inline
-void bt_clock_value_set_finalize(struct bt_clock_value_set *cv_set)
-{
-       uint64_t i;
-
-       BT_ASSERT(cv_set);
-
-       if (cv_set->clock_values) {
-               for (i = 0; i < cv_set->clock_values->len; i++) {
-                       struct bt_clock_value *cv =
-                               cv_set->clock_values->pdata[i];
-
-                       BT_ASSERT(cv);
-                       bt_clock_value_recycle(cv);
-               }
-
-               g_ptr_array_free(cv_set->clock_values, TRUE);
-       }
-
-       cv_set->default_cv = NULL;
-}
-
-static inline
-int bt_clock_value_set_set_clock_value(struct bt_clock_value_set *cv_set,
-               struct bt_clock_class *cc, uint64_t raw_value)
-{
-       int ret = 0;
-       struct bt_clock_value *clock_value = NULL;
-       uint64_t i;
-
-       BT_ASSERT(cv_set);
-       BT_ASSERT(cc);
-
-       /*
-        * Check if we already have a value for this clock class.
-        *
-        * TODO: When we have many clock classes, make this more
-        * efficient.
-        */
-       for (i = 0; i < cv_set->clock_values->len; i++) {
-               struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
-
-               BT_ASSERT(cv);
-
-               if (cv->clock_class == cc) {
-                       clock_value = cv;
-                       break;
-               }
-       }
-
-       if (!clock_value) {
-               clock_value = bt_clock_value_create(cc);
-               if (!clock_value) {
-#ifdef BT_LIB_LOGE
-                       BT_LIB_LOGE("Cannot create a clock value from a clock class: "
-                               "%![cc-]+K", cc);
-#endif
-
-                       ret = -1;
-                       goto end;
-               }
-
-               g_ptr_array_add(cv_set->clock_values, clock_value);
-       }
-
-       bt_clock_value_set_value_inline(clock_value, raw_value);
-
-end:
-       return ret;
-}
-
-static inline
-void  bt_clock_value_set_set_default_clock_value(
-               struct bt_clock_value_set *cv_set, uint64_t raw_value)
-{
-       BT_ASSERT(cv_set);
-       BT_ASSERT(cv_set->default_cv);
-       bt_clock_value_set_value_inline(cv_set->default_cv, raw_value);
-}
-
-#endif /* BABELTRACE_GRAPH_CLOCK_VALUE_SET_H */
diff --git a/include/babeltrace/ctf-ir/clock-value.h b/include/babeltrace/ctf-ir/clock-value.h
deleted file mode 100644 (file)
index 5f30242..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_CLOCK_VALUE_H
-#define BABELTRACE_CTF_IR_CLOCK_VALUE_H
-
-/*
- * BabelTrace - CTF IR: Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_clock_class;
-struct bt_clock_value;
-
-enum bt_clock_value_status {
-       BT_CLOCK_VALUE_STATUS_KNOWN,
-       BT_CLOCK_VALUE_STATUS_UNKNOWN,
-};
-
-extern struct bt_clock_class *bt_clock_value_borrow_clock_class(
-               struct bt_clock_value *clock_value);
-
-extern uint64_t bt_clock_value_get_value(
-               struct bt_clock_value *clock_value);
-
-extern int bt_clock_value_get_ns_from_origin(
-               struct bt_clock_value *clock_value, int64_t *ns_from_origin);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_VALUE_H */
index 5f08ac1d808002a3597607df476489414e200df0..72ca2a3aee000b7c8f12a793dd44b9922614d7e7 100644 (file)
@@ -1,35 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_CLOCK_H
-#define BABELTRACE_CTF_IR_CLOCK_H
-
-/*
- * BabelTrace - CTF IR: Clock
- *
- * Copyright 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
+/* Pre-2.0 CTF writer backward compatibility */
 #include <babeltrace/ctf-writer/clock.h>
-
-#endif /* BABELTRACE_CTF_IR_CLOCK_H */
diff --git a/include/babeltrace/ctf-ir/event-class-internal.h b/include/babeltrace/ctf-ir/event-class-internal.h
deleted file mode 100644 (file)
index 8fa2ba0..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event class internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/property-internal.h>
-#include <glib.h>
-#include <stdbool.h>
-
-struct bt_event_class {
-       struct bt_object base;
-       struct bt_field_type *specific_context_ft;
-       struct bt_field_type *payload_ft;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } name;
-
-       uint64_t id;
-       struct bt_property_uint log_level;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } emf_uri;
-
-       /* Pool of `struct bt_event *` */
-       struct bt_object_pool event_pool;
-
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_event_class_freeze(struct bt_event_class *event_class);
-
-#ifdef BT_DEV_MODE
-# define bt_event_class_freeze         _bt_event_class_freeze
-#else
-# define bt_event_class_freeze(_ec)
-#endif
-
-static inline
-struct bt_stream_class *bt_event_class_borrow_stream_class_inline(
-               struct bt_event_class *event_class)
-{
-       BT_ASSERT(event_class);
-       return (void *) bt_object_borrow_parent(&event_class->base);
-}
-
-#endif /* BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H */
index 8752b406d9dda64368cded8620280d4e676ae39f..f687a7d1793e0258affe43aaf85f51c09e659307 100644 (file)
@@ -1,112 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_EVENT_CLASS_H
-#define BABELTRACE_CTF_IR_EVENT_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Event class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_event_class;
-struct bt_field_type;
-struct bt_stream_class;
-
-enum bt_event_class_log_level {
-       BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY,
-       BT_EVENT_CLASS_LOG_LEVEL_ALERT,
-       BT_EVENT_CLASS_LOG_LEVEL_CRITICAL,
-       BT_EVENT_CLASS_LOG_LEVEL_ERROR,
-       BT_EVENT_CLASS_LOG_LEVEL_WARNING,
-       BT_EVENT_CLASS_LOG_LEVEL_NOTICE,
-       BT_EVENT_CLASS_LOG_LEVEL_INFO,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE,
-       BT_EVENT_CLASS_LOG_LEVEL_DEBUG,
-};
-
-extern struct bt_event_class *bt_event_class_create(
-               struct bt_stream_class *stream_class);
-
-extern struct bt_event_class *bt_event_class_create_with_id(
-               struct bt_stream_class *stream_class, uint64_t id);
-
-extern struct bt_stream_class *bt_event_class_borrow_stream_class(
-               struct bt_event_class *event_class);
-
-extern const char *bt_event_class_get_name(struct bt_event_class *event_class);
-
-extern int bt_event_class_set_name(struct bt_event_class *event_class,
-               const char *name);
-
-extern uint64_t bt_event_class_get_id(struct bt_event_class *event_class);
-
-extern enum bt_property_availability bt_event_class_get_log_level(
-               struct bt_event_class *event_class,
-               enum bt_event_class_log_level *log_level);
-
-extern int bt_event_class_set_log_level(struct bt_event_class *event_class,
-               enum bt_event_class_log_level log_level);
-
-extern const char *bt_event_class_get_emf_uri(
-               struct bt_event_class *event_class);
-
-extern int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
-               const char *emf_uri);
-
-extern struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
-               struct bt_event_class *event_class);
-
-extern int bt_event_class_set_specific_context_field_type(
-               struct bt_event_class *event_class,
-               struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_event_class_borrow_payload_field_type(
-               struct bt_event_class *event_class);
-
-extern int bt_event_class_set_payload_field_type(
-               struct bt_event_class *event_class,
-               struct bt_field_type *field_type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_CLASS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-class.h>
diff --git a/include/babeltrace/ctf-ir/event-fields.h b/include/babeltrace/ctf-ir/event-fields.h
new file mode 100644 (file)
index 0000000..0c9395a
--- /dev/null
@@ -0,0 +1,2 @@
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-fields.h>
diff --git a/include/babeltrace/ctf-ir/event-header-field.h b/include/babeltrace/ctf-ir/event-header-field.h
deleted file mode 100644 (file)
index 0ac9eea..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H
-#define BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream_class;
-struct bt_event_header_field;
-struct bt_field;
-
-extern
-struct bt_event_header_field *bt_event_header_field_create(
-               struct bt_stream_class *stream_class);
-
-extern
-struct bt_field *bt_event_header_field_borrow_field(
-               struct bt_event_header_field *field);
-
-extern
-void bt_event_header_field_release(struct bt_event_header_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_HEADER_FIELD_H */
diff --git a/include/babeltrace/ctf-ir/event-internal.h b/include/babeltrace/ctf-ir/event-internal.h
deleted file mode 100644 (file)
index 39efd2f..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
-#define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* Protection: this file uses BT_LIB_LOG*() macros directly */
-#ifndef BABELTRACE_LIB_LOGGING_INTERNAL_H
-# error Please define include <babeltrace/lib-logging-internal.h> before including this file.
-#endif
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_EVENT_HOT(_event) \
-       BT_ASSERT_PRE_HOT((_event), "Event", ": %!+e", (_event))
-
-struct bt_event {
-       struct bt_object base;
-       struct bt_event_class *class;
-       struct bt_packet *packet;
-       struct bt_field_wrapper *header_field;
-       struct bt_field *common_context_field;
-       struct bt_field *specific_context_field;
-       struct bt_field *payload_field;
-       struct bt_clock_value *default_cv;
-       bool frozen;
-};
-
-BT_HIDDEN
-void bt_event_destroy(struct bt_event *event);
-
-BT_HIDDEN
-struct bt_event *bt_event_new(struct bt_event_class *event_class);
-
-BT_HIDDEN
-void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
-
-#ifdef BT_DEV_MODE
-# define bt_event_set_is_frozen                _bt_event_set_is_frozen
-#else
-# define bt_event_set_is_frozen(_event, _is_frozen)
-#endif
-
-BT_UNUSED
-static inline
-void _bt_event_reset_dev_mode(struct bt_event *event)
-{
-       BT_ASSERT(event);
-
-       if (event->header_field) {
-               bt_field_set_is_frozen(
-                       event->header_field->field, false);
-               bt_field_reset(
-                       event->header_field->field);
-       }
-
-       if (event->common_context_field) {
-               bt_field_set_is_frozen(
-                       event->common_context_field, false);
-               bt_field_reset(
-                       event->common_context_field);
-       }
-
-       if (event->specific_context_field) {
-               bt_field_set_is_frozen(
-                       event->specific_context_field, false);
-               bt_field_reset(event->specific_context_field);
-       }
-
-       if (event->payload_field) {
-               bt_field_set_is_frozen(
-                       event->payload_field, false);
-               bt_field_reset(event->payload_field);
-       }
-}
-
-#ifdef BT_DEV_MODE
-# define bt_event_reset_dev_mode       _bt_event_reset_dev_mode
-#else
-# define bt_event_reset_dev_mode(_x)
-#endif
-
-static inline
-void bt_event_reset(struct bt_event *event)
-{
-       BT_ASSERT(event);
-       BT_LIB_LOGD("Resetting event: %!+e", event);
-       bt_event_set_is_frozen(event, false);
-
-       if (event->default_cv) {
-               bt_clock_value_reset(event->default_cv);
-       }
-
-       bt_object_put_no_null_check(&event->packet->base);
-       event->packet = NULL;
-}
-
-static inline
-void bt_event_recycle(struct bt_event *event)
-{
-       struct bt_event_class *event_class;
-
-       BT_ASSERT(event);
-       BT_LIB_LOGD("Recycling event: %!+e", event);
-
-       /*
-        * Those are the important ordered steps:
-        *
-        * 1. Reset the event object (put any permanent reference it
-        *    has, unfreeze it and its fields in developer mode, etc.),
-        *    but do NOT put its class's reference. This event class
-        *    contains the pool to which we're about to recycle this
-        *    event object, so we must guarantee its existence thanks
-        *    to this existing reference.
-        *
-        * 2. Move the event class reference to our `event_class`
-        *    variable so that we can set the event's class member
-        *    to NULL before recycling it. We CANNOT do this after
-        *    we put the event class reference because this bt_put()
-        *    could destroy the event class, also destroying its
-        *    event pool, thus also destroying our event object (this
-        *    would result in an invalid write access).
-        *
-        * 3. Recycle the event object.
-        *
-        * 4. Put our event class reference.
-        */
-       bt_event_reset(event);
-       event_class = event->class;
-       BT_ASSERT(event_class);
-       event->class = NULL;
-       bt_object_pool_recycle_object(&event_class->event_pool, event);
-       bt_object_put_no_null_check(&event_class->base);
-}
-
-static inline
-void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_EVENT_HOT(event);
-       BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
-               event->class) == packet->stream->class,
-               "Packet's stream class and event's stream class differ: "
-               "%![event-]+e, %![packet-]+a", event, packet);
-
-       BT_ASSERT(!event->packet);
-       event->packet = packet;
-       bt_object_get_no_null_check_no_parent_check(&event->packet->base);
-       BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a",
-               event, packet);
-}
-
-static inline
-struct bt_event *bt_event_create(struct bt_event_class *event_class,
-               struct bt_packet *packet)
-{
-       struct bt_event *event = NULL;
-
-       BT_ASSERT(event_class);
-       event = bt_object_pool_create_object(&event_class->event_pool);
-       if (unlikely(!event)) {
-               BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
-                       "%![ec-]+E", event_class);
-               goto end;
-       }
-
-       if (likely(!event->class)) {
-               event->class = event_class;
-               bt_object_get_no_null_check(&event_class->base);
-       }
-
-       BT_ASSERT(packet);
-       bt_event_set_packet(event, packet);
-       goto end;
-
-end:
-       return event;
-}
-
-#endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/event-types.h b/include/babeltrace/ctf-ir/event-types.h
new file mode 100644 (file)
index 0000000..5bbdda2
--- /dev/null
@@ -0,0 +1,2 @@
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event-types.h>
index 67df08b5e53c390f67592c9ba34e87727500ecd6..3106be8dc0f4c3a24fa453f19949f9cafe9f0144 100644 (file)
@@ -1,79 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_EVENT_H
-#define BABELTRACE_CTF_IR_EVENT_H
-
-/*
- * BabelTrace - CTF IR: Event
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-#include <stddef.h>
-
-/* For enum bt_clock_value_status */
-#include <babeltrace/ctf-ir/clock-value.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_event;
-struct bt_event_header_field;
-struct bt_clock_value;
-struct bt_event_class;
-struct bt_field;
-struct bt_packet;
-
-extern struct bt_event_class *bt_event_borrow_class(struct bt_event *event);
-
-extern struct bt_packet *bt_event_borrow_packet(struct bt_event *event);
-
-extern struct bt_stream *bt_event_borrow_stream(struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_header_field(struct bt_event *event);
-
-extern int bt_event_move_header(struct bt_event *event,
-               struct bt_event_header_field *header);
-
-extern struct bt_field *bt_event_borrow_common_context_field(
-               struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_specific_context_field(
-               struct bt_event *event);
-
-extern struct bt_field *bt_event_borrow_payload_field(struct bt_event *event);
-
-extern int bt_event_set_default_clock_value(struct bt_event *event,
-               uint64_t value_cycles);
-
-extern enum bt_clock_value_status bt_event_borrow_default_clock_value(
-               struct bt_event *event, struct bt_clock_value **clock_value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_EVENT_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/event.h>
diff --git a/include/babeltrace/ctf-ir/field-path-internal.h b/include/babeltrace/ctf-ir/field-path-internal.h
deleted file mode 100644 (file)
index f8cb136..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL
-#define BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-struct bt_field_path {
-       struct bt_object base;
-       enum bt_scope root;
-
-       /* Array of `uint64_t` (indexes) */
-       GArray *indexes;
-};
-
-BT_HIDDEN
-struct bt_field_path *bt_field_path_create(void);
-
-static inline
-uint64_t bt_field_path_get_index_by_index_inline(
-               struct bt_field_path *field_path, uint64_t index)
-{
-       BT_ASSERT(field_path);
-       BT_ASSERT(index < field_path->indexes->len);
-       return g_array_index(field_path->indexes, uint64_t, index);
-}
-
-#endif /* BABELTRACE_CTF_IR_FIELD_PATH_INTERNAL */
diff --git a/include/babeltrace/ctf-ir/field-path.h b/include/babeltrace/ctf-ir/field-path.h
deleted file mode 100644 (file)
index 7c435ab..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_FIELD_PATH_H
-#define BABELTRACE_CTF_IR_FIELD_PATH_H
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field_path;
-
-enum bt_scope {
-       BT_SCOPE_PACKET_HEADER,
-       BT_SCOPE_PACKET_CONTEXT,
-       BT_SCOPE_EVENT_HEADER,
-       BT_SCOPE_EVENT_COMMON_CONTEXT,
-       BT_SCOPE_EVENT_SPECIFIC_CONTEXT,
-       BT_SCOPE_EVENT_PAYLOAD,
-};
-
-extern enum bt_scope bt_field_path_get_root_scope(
-               struct bt_field_path *field_path);
-
-extern uint64_t bt_field_path_get_index_count(
-               struct bt_field_path *field_path);
-
-extern uint64_t bt_field_path_get_index_by_index(
-               struct bt_field_path *field_path, uint64_t index);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_PATH_H */
diff --git a/include/babeltrace/ctf-ir/field-types-internal.h b/include/babeltrace/ctf-ir/field-types-internal.h
deleted file mode 100644 (file)
index fcefa06..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Event field types internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_FT_IS_INT(_ft, _name)                            \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
-               _name " is not an integer field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(_ft, _name)                   \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
-               _name " is not an unsigned integer field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_ENUM(_ft, _name)                           \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
-               _name " is not an enumeration field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_IS_ARRAY(_ft, _name)                          \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
-               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
-               _name " is not an array field type: %![ft-]+F", (_ft))
-
-#define BT_ASSERT_PRE_FT_HAS_ID(_ft, _id, _name)                       \
-       BT_ASSERT_PRE(((struct bt_field_type *) (_ft))->id == (_id),    \
-               _name " has the wrong ID: expected-id=%s, "             \
-               "%![ft-]+F", bt_common_field_type_id_string(_id), (_ft))
-
-#define BT_ASSERT_PRE_FT_HOT(_ft, _name)                               \
-       BT_ASSERT_PRE_HOT((struct bt_field_type *) (_ft),               \
-               (_name), ": %!+F", (_ft))
-
-#define BT_FIELD_TYPE_NAMED_FT_AT_INDEX(_ft, _index)           \
-       (&g_array_index(((struct bt_field_type_named_field_types_container *) (_ft))->named_fts, \
-               struct bt_named_field_type, (_index)))
-
-#define BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(_ft, _index)               \
-       (&g_array_index(((struct bt_field_type_enumeration *) (_ft))->mappings, \
-               struct bt_field_type_enumeration_mapping, (_index)))
-
-#define BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index)    \
-       (&g_array_index((_mapping)->ranges,                             \
-               struct bt_field_type_enumeration_mapping_range, (_index)))
-
-struct bt_field;
-struct bt_field_type;
-
-struct bt_field_type {
-       struct bt_object base;
-       enum bt_field_type_id id;
-       bool frozen;
-
-       /*
-        * Only used in developer mode, this flag indicates whether or
-        * not this field type is part of a trace.
-        */
-       bool part_of_trace;
-};
-
-struct bt_field_type_integer {
-       struct bt_field_type common;
-
-       /*
-        * Value range of fields built from this integer field type:
-        * this is an equivalent integer size in bits. More formally,
-        * `range` is `n` in:
-        *
-        * Unsigned range: [0, 2^n - 1]
-        * Signed range: [-2^(n - 1), 2^(n - 1) - 1]
-        */
-       uint64_t range;
-
-       enum bt_field_type_integer_preferred_display_base base;
-};
-
-struct bt_field_type_enumeration_mapping_range {
-       union {
-               uint64_t u;
-               int64_t i;
-       } lower;
-
-       union {
-               uint64_t u;
-               int64_t i;
-       } upper;
-};
-
-struct bt_field_type_enumeration_mapping {
-       GString *label;
-
-       /* Array of `struct bt_field_type_enumeration_mapping_range` */
-       GArray *ranges;
-};
-
-struct bt_field_type_enumeration {
-       struct bt_field_type_integer common;
-
-       /* Array of `struct bt_field_type_enumeration_mapping *` */
-       GArray *mappings;
-
-       /*
-        * This is an array of `const char *` which acts as a temporary
-        * (potentially growing) buffer for
-        * bt_field_type_unsigned_enumeration_get_mapping_labels_by_value()
-        * and
-        * bt_field_type_signed_enumeration_get_mapping_labels_by_value().
-        *
-        * The actual strings are owned by the mappings above.
-        */
-       GPtrArray *label_buf;
-};
-
-struct bt_field_type_real {
-       struct bt_field_type common;
-       bool is_single_precision;
-};
-
-struct bt_field_type_string {
-       struct bt_field_type common;
-};
-
-/* A named field type is a (name, field type) pair */
-struct bt_named_field_type {
-       GString *name;
-
-       /* Owned by this */
-       struct bt_field_type *ft;
-};
-
-/*
- * This is the base field type for a container of named field types.
- * Structure and variant field types inherit this.
- */
-struct bt_field_type_named_field_types_container {
-       struct bt_field_type common;
-
-       /*
-        * Key: `const char *`, not owned by this (owned by named field
-        * type objects contained in `named_fts` below).
-        */
-       GHashTable *name_to_index;
-
-       /* Array of `struct bt_named_field_type` */
-       GArray *named_fts;
-};
-
-struct bt_field_type_structure {
-       struct bt_field_type_named_field_types_container common;
-};
-
-struct bt_field_type_array {
-       struct bt_field_type common;
-
-       /* Owned by this */
-       struct bt_field_type *element_ft;
-};
-
-struct bt_field_type_static_array {
-       struct bt_field_type_array common;
-       uint64_t length;
-};
-
-struct bt_field_type_dynamic_array {
-       struct bt_field_type_array common;
-
-       /* Weak: never dereferenced, only use to find it elsewhere */
-       struct bt_field_type *length_ft;
-
-       /* Owned by this */
-       struct bt_field_path *length_field_path;
-};
-
-struct bt_field_type_variant {
-       struct bt_field_type_named_field_types_container common;
-
-       /* Weak: never dereferenced, only use to find it elsewhere */
-       struct bt_field_type *selector_ft;
-
-       /* Owned by this */
-       struct bt_field_path *selector_field_path;
-};
-
-static inline
-bool bt_field_type_has_known_id(struct bt_field_type *ft)
-{
-       return ft->id >= BT_FIELD_TYPE_ID_UNSIGNED_INTEGER &&
-               ft->id <= BT_FIELD_TYPE_ID_VARIANT;
-}
-
-BT_HIDDEN
-void _bt_field_type_freeze(struct bt_field_type *field_type);
-
-#ifdef BT_DEV_MODE
-# define bt_field_type_freeze          _bt_field_type_freeze
-#else
-# define bt_field_type_freeze(_ft)
-#endif
-
-/*
- * This function recursively marks `field_type` and its children as
- * being part of a trace. This is used to validate that all field types
- * are used at a single location within trace objects even if they are
- * shared objects for other purposes.
- */
-BT_HIDDEN
-void _bt_field_type_make_part_of_trace(struct bt_field_type *field_type);
-
-#ifdef BT_DEV_MODE
-# define bt_field_type_make_part_of_trace      _bt_field_type_make_part_of_trace
-#else
-# define bt_field_type_make_part_of_trace(_ft) ((void) _ft)
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_TYPES_INTERNAL_H */
index 95bc646c7d8ee3574e3d186986ea594bdfcc69c8..ba9e929c84c4e013b1885aafd8c971eaea8e584d 100644 (file)
@@ -1,222 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_FIELD_TYPES_H
-#define BABELTRACE_CTF_IR_FIELD_TYPES_H
-
-/*
- * BabelTrace - CTF IR: Event field types
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For bt_get() */
-#include <babeltrace/ref.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-#include <stdint.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field_type;
-struct bt_field_path;
-struct bt_field_type_signed_enumeration_mapping_ranges;
-struct bt_field_type_unsigned_enumeration_mapping_ranges;
-
-typedef const char * const *bt_field_type_enumeration_mapping_label_array;
-
-enum bt_field_type_id {
-       BT_FIELD_TYPE_ID_UNSIGNED_INTEGER,
-       BT_FIELD_TYPE_ID_SIGNED_INTEGER,
-       BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
-       BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
-       BT_FIELD_TYPE_ID_REAL,
-       BT_FIELD_TYPE_ID_STRING,
-       BT_FIELD_TYPE_ID_STRUCTURE,
-       BT_FIELD_TYPE_ID_STATIC_ARRAY,
-       BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
-       BT_FIELD_TYPE_ID_VARIANT,
-};
-
-enum bt_field_type_integer_preferred_display_base {
-       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_BINARY,
-       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL,
-       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
-       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
-};
-
-extern enum bt_field_type_id bt_field_type_get_type_id(
-               struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_field_type_unsigned_integer_create(void);
-
-extern struct bt_field_type *bt_field_type_signed_integer_create(void);
-
-extern uint64_t bt_field_type_integer_get_field_value_range(
-               struct bt_field_type *field_type);
-
-extern int bt_field_type_integer_set_field_value_range(
-               struct bt_field_type *field_type, uint64_t size);
-
-extern enum bt_field_type_integer_preferred_display_base
-bt_field_type_integer_get_preferred_display_base(
-               struct bt_field_type *field_type);
-
-extern int bt_field_type_integer_set_preferred_display_base(
-               struct bt_field_type *field_type,
-               enum bt_field_type_integer_preferred_display_base base);
-
-extern struct bt_field_type *bt_field_type_real_create(void);
-
-extern bt_bool bt_field_type_real_is_single_precision(
-               struct bt_field_type *field_type);
-
-extern int bt_field_type_real_set_is_single_precision(
-               struct bt_field_type *field_type,
-               bt_bool is_single_precision);
-
-extern struct bt_field_type *bt_field_type_unsigned_enumeration_create(void);
-
-extern struct bt_field_type *bt_field_type_signed_enumeration_create(void);
-
-extern uint64_t bt_field_type_enumeration_get_mapping_count(
-               struct bt_field_type *field_type);
-
-extern void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
-               struct bt_field_type *field_type, uint64_t index,
-               const char **label,
-               struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges);
-
-extern void bt_field_type_signed_enumeration_borrow_mapping_by_index(
-               struct bt_field_type *field_type, uint64_t index,
-               const char **label,
-               struct bt_field_type_signed_enumeration_mapping_ranges **ranges);
-
-extern uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges);
-
-extern uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
-               struct bt_field_type_signed_enumeration_mapping_ranges *ranges);
-
-extern void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
-               uint64_t index, uint64_t *lower, uint64_t *upper);
-
-extern void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
-               uint64_t index, int64_t *lower, int64_t *upper);
-
-extern int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
-               struct bt_field_type *field_type, uint64_t value,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count);
-
-extern int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
-               struct bt_field_type *field_type, int64_t value,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count);
-
-extern int bt_field_type_unsigned_enumeration_map_range(
-               struct bt_field_type *field_type, const char *label,
-               uint64_t range_lower, uint64_t range_upper);
-
-extern int bt_field_type_signed_enumeration_map_range(
-               struct bt_field_type *field_type, const char *label,
-               int64_t range_lower, int64_t range_upper);
-
-extern struct bt_field_type *bt_field_type_string_create(void);
-
-extern struct bt_field_type *bt_field_type_structure_create(void);
-
-extern uint64_t bt_field_type_structure_get_member_count(
-               struct bt_field_type *field_type);
-
-extern void bt_field_type_structure_borrow_member_by_index(
-               struct bt_field_type *struct_field_type, uint64_t index,
-               const char **name, struct bt_field_type **field_type);
-
-extern
-struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
-               struct bt_field_type *field_type, const char *name);
-
-extern int bt_field_type_structure_append_member(
-               struct bt_field_type *struct_field_type, const char *name,
-               struct bt_field_type *field_type);
-
-extern struct bt_field_type *bt_field_type_static_array_create(
-               struct bt_field_type *elem_field_type,
-               uint64_t length);
-
-extern struct bt_field_type *bt_field_type_dynamic_array_create(
-               struct bt_field_type *elem_field_type);
-
-extern struct bt_field_type *bt_field_type_array_borrow_element_field_type(
-               struct bt_field_type *field_type);
-
-extern uint64_t bt_field_type_static_array_get_length(
-               struct bt_field_type *field_type);
-
-extern struct bt_field_path *
-bt_field_type_dynamic_array_borrow_length_field_path(
-               struct bt_field_type *field_type);
-
-extern int bt_field_type_dynamic_array_set_length_field_type(
-               struct bt_field_type *field_type,
-               struct bt_field_type *length_field_type);
-
-extern struct bt_field_type *bt_field_type_variant_create(void);
-
-extern struct bt_field_path *
-bt_field_type_variant_borrow_selector_field_path(
-               struct bt_field_type *field_type);
-
-extern int bt_field_type_variant_set_selector_field_type(
-               struct bt_field_type *field_type,
-               struct bt_field_type *selector_field_type);
-
-extern uint64_t bt_field_type_variant_get_option_count(
-               struct bt_field_type *field_type);
-
-extern void bt_field_type_variant_borrow_option_by_index(
-               struct bt_field_type *variant_field_type, uint64_t index,
-               const char **name, struct bt_field_type **field_type);
-
-extern
-struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
-               struct bt_field_type *field_type,
-               const char *name);
-
-extern int bt_field_type_variant_append_option(
-               struct bt_field_type *var_field_type,
-               const char *name, struct bt_field_type *field_type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELD_TYPES_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/field-types.h>
diff --git a/include/babeltrace/ctf-ir/field-wrapper-internal.h b/include/babeltrace/ctf-ir/field-wrapper-internal.h
deleted file mode 100644 (file)
index cc164e0..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/object-internal.h>
-
-struct bt_field_wrapper {
-       struct bt_object base;
-
-       /* Owned by this */
-       struct bt_field *field;
-};
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_new(void *data);
-
-BT_HIDDEN
-void bt_field_wrapper_destroy(struct bt_field_wrapper *field);
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_create(
-               struct bt_object_pool *pool, struct bt_field_type *ft);
-
-#endif /* BABELTRACE_CTF_IR_FIELD_WRAPPER_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/fields-internal.h b/include/babeltrace/ctf-ir/fields-internal.h
deleted file mode 100644 (file)
index 31ec621..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
-#define BABELTRACE_CTF_IR_FIELDS_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Event Fields internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/common-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <glib.h>
-
-#define BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(_field, _type_id, _name)       \
-       BT_ASSERT_PRE(((struct bt_field *) (_field))->type->id == (_type_id), \
-               _name " has the wrong type ID: expected-type-id=%s, "   \
-               "%![field-]+f",                                         \
-               bt_common_field_type_id_string(_type_id), (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name)             \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
-               _name " is not an unsigned integer field: %![field-]+f", \
-               (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name)               \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
-               _name " is not a signed integer field: %![field-]+f", \
-               (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name)                    \
-       BT_ASSERT_PRE(                                                  \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
-               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
-               _name " is not an array field: %![field-]+f", (_field))
-
-#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name)                      \
-       BT_ASSERT_PRE(bt_field_is_set(_field),                          \
-               _name " is not set: %!+f", (_field))
-
-#define BT_ASSERT_PRE_FIELD_HOT(_field, _name)                         \
-       BT_ASSERT_PRE_HOT((struct bt_field *) (_field), (_name),        \
-               ": %!+f", (_field))
-
-struct bt_field;
-
-typedef struct bt_field *(* bt_field_create_func)(struct bt_field_type *);
-typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool);
-typedef bool (*bt_field_method_is_set)(struct bt_field *);
-typedef void (*bt_field_method_reset)(struct bt_field *);
-
-struct bt_field_methods {
-       bt_field_method_set_is_frozen set_is_frozen;
-       bt_field_method_is_set is_set;
-       bt_field_method_reset reset;
-};
-
-struct bt_field {
-       struct bt_object base;
-
-       /* Owned by this */
-       struct bt_field_type *type;
-
-       /* Virtual table for slow path (dev mode) operations */
-       struct bt_field_methods *methods;
-
-       bool is_set;
-       bool frozen;
-};
-
-struct bt_field_integer {
-       struct bt_field common;
-
-       union {
-               uint64_t u;
-               int64_t i;
-       } value;
-};
-
-struct bt_field_real {
-       struct bt_field common;
-       double value;
-};
-
-struct bt_field_structure {
-       struct bt_field common;
-
-       /* Array of `struct bt_field *`, owned by this */
-       GPtrArray *fields;
-};
-
-struct bt_field_variant {
-       struct bt_field common;
-
-       /* Weak: belongs to `fields` below */
-       struct bt_field *selected_field;
-
-       /* Index of currently selected field */
-       uint64_t selected_index;
-
-       /* Array of `struct bt_field *`, owned by this */
-       GPtrArray *fields;
-};
-
-struct bt_field_array {
-       struct bt_field common;
-
-       /* Array of `struct bt_field *`, owned by this */
-       GPtrArray *fields;
-
-       /* Current effective length */
-       uint64_t length;
-};
-
-struct bt_field_string {
-       struct bt_field common;
-       GArray *buf;
-       uint64_t length;
-};
-
-#ifdef BT_DEV_MODE
-# define bt_field_set_is_frozen                _bt_field_set_is_frozen
-# define bt_field_is_set               _bt_field_is_set
-# define bt_field_reset                        _bt_field_reset
-# define bt_field_set_single           _bt_field_set_single
-#else
-# define bt_field_set_is_frozen(_field, _is_frozen)
-# define bt_field_is_set(_field)       (BT_FALSE)
-# define bt_field_reset(_field)
-# define bt_field_set_single(_field, _val)
-#endif
-
-BT_HIDDEN
-void _bt_field_set_is_frozen(struct bt_field *field, bool is_frozen);
-
-static inline
-void _bt_field_reset(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       BT_ASSERT(field->methods->reset);
-       field->methods->reset(field);
-}
-
-static inline
-void _bt_field_set_single(struct bt_field *field, bool value)
-{
-       BT_ASSERT(field);
-       field->is_set = value;
-}
-
-static inline
-bt_bool _bt_field_is_set(struct bt_field *field)
-{
-       bt_bool is_set = BT_FALSE;
-
-       if (!field) {
-               goto end;
-       }
-
-       BT_ASSERT(bt_field_type_has_known_id(field->type));
-       BT_ASSERT(field->methods->is_set);
-       is_set = field->methods->is_set(field);
-
-end:
-       return is_set;
-}
-
-BT_HIDDEN
-struct bt_field *bt_field_create(struct bt_field_type *type);
-
-BT_HIDDEN
-void bt_field_destroy(struct bt_field *field);
-
-#endif /* BABELTRACE_CTF_IR_FIELDS_INTERNAL_H */
index 5bf0c3b634743f1d9354928e7d91cba1fc31f2db..dc6543b0702e722be4330f7a9079026df32c0d63 100644 (file)
@@ -1,117 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_FIELDS_H
-#define BABELTRACE_CTF_IR_FIELDS_H
-
-/*
- * Babeltrace - CTF IR: Event Fields
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-/* For enum bt_field_type_id */
-#include <babeltrace/ctf-ir/field-types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_field;
-struct bt_field_type;
-struct bt_field_type_enumeration_mapping_iterator;
-
-extern struct bt_field_type *bt_field_borrow_type(struct bt_field *field);
-
-extern enum bt_field_type_id bt_field_get_type_id(struct bt_field *field);
-
-extern int64_t bt_field_signed_integer_get_value(struct bt_field *field);
-
-extern void bt_field_signed_integer_set_value(struct bt_field *field,
-               int64_t value);
-
-extern uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field);
-
-extern void bt_field_unsigned_integer_set_value(struct bt_field *field,
-               uint64_t value);
-
-extern double bt_field_real_get_value(struct bt_field *field);
-
-extern void bt_field_real_set_value(struct bt_field *field, double value);
-
-extern int bt_field_unsigned_enumeration_get_mapping_labels(
-               struct bt_field *field,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count);
-
-extern int bt_field_signed_enumeration_get_mapping_labels(
-               struct bt_field *field,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count);
-
-extern const char *bt_field_string_get_value(struct bt_field *field);
-
-extern uint64_t bt_field_string_get_length(struct bt_field *field);
-
-extern int bt_field_string_set_value(struct bt_field *field, const char *value);
-
-extern int bt_field_string_append(struct bt_field *field, const char *value);
-
-extern int bt_field_string_append_with_length(struct bt_field *field,
-               const char *value, uint64_t length);
-
-extern int bt_field_string_clear(struct bt_field *field);
-
-extern struct bt_field *bt_field_structure_borrow_member_field_by_index(
-               struct bt_field *field, uint64_t index);
-
-extern struct bt_field *bt_field_structure_borrow_member_field_by_name(
-               struct bt_field *field, const char *name);
-
-extern uint64_t bt_field_array_get_length(struct bt_field *field);
-
-extern struct bt_field *bt_field_array_borrow_element_field_by_index(
-               struct bt_field *field, uint64_t index);
-
-extern int bt_field_dynamic_array_set_length(struct bt_field *field,
-               uint64_t length);
-
-extern int bt_field_variant_select_option_field(struct bt_field *field,
-               uint64_t index);
-
-extern uint64_t bt_field_variant_get_selected_option_field_index(
-               struct bt_field *field);
-
-extern struct bt_field *bt_field_variant_borrow_selected_option_field(
-               struct bt_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_FIELDS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/fields.h>
diff --git a/include/babeltrace/ctf-ir/packet-context-field.h b/include/babeltrace/ctf-ir/packet-context-field.h
deleted file mode 100644 (file)
index 1962542..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H
-#define BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream_class;
-struct bt_packet_context_field;
-struct bt_field;
-
-extern
-struct bt_packet_context_field *bt_packet_context_field_create(
-               struct bt_stream_class *stream_class);
-
-extern
-struct bt_field *bt_packet_context_field_borrow_field(
-               struct bt_packet_context_field *field);
-
-extern
-void bt_packet_context_field_release(struct bt_packet_context_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_CONTEXT_FIELD_H */
diff --git a/include/babeltrace/ctf-ir/packet-header-field.h b/include/babeltrace/ctf-ir/packet-header-field.h
deleted file mode 100644 (file)
index 1e14a8c..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H
-#define BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H
-
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_packet_header_field;
-struct bt_field;
-
-extern
-struct bt_packet_header_field *bt_packet_header_field_create(
-               struct bt_trace *trace);
-
-extern
-struct bt_field *bt_packet_header_field_borrow_field(
-               struct bt_packet_header_field *field);
-
-extern
-void bt_packet_header_field_release(struct bt_packet_header_field *field);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_HEADER_FIELD_H */
diff --git a/include/babeltrace/ctf-ir/packet-internal.h b/include/babeltrace/ctf-ir/packet-internal.h
deleted file mode 100644 (file)
index 712903a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_PACKET_INTERNAL_H
-#define BABELTRACE_CTF_IR_PACKET_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Stream packet internal
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdbool.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/property-internal.h>
-
-struct bt_packet {
-       struct bt_object base;
-       struct bt_field_wrapper *header_field;
-       struct bt_field_wrapper *context_field;
-       struct bt_stream *stream;
-       struct bt_clock_value *default_beginning_cv;
-       struct bt_clock_value *default_end_cv;
-       struct bt_property_uint discarded_event_counter_snapshot;
-       struct bt_property_uint packet_counter_snapshot;
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen);
-
-#ifdef BT_DEV_MODE
-# define bt_packet_set_is_frozen       _bt_packet_set_is_frozen
-#else
-# define bt_packet_set_is_frozen(_packet, _is_frozen)
-#endif /* BT_DEV_MODE */
-
-BT_HIDDEN
-struct bt_packet *bt_packet_new(struct bt_stream *stream);
-
-BT_HIDDEN
-void bt_packet_recycle(struct bt_packet *packet);
-
-BT_HIDDEN
-void bt_packet_destroy(struct bt_packet *packet);
-
-#endif /* BABELTRACE_CTF_IR_PACKET_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/packet.h b/include/babeltrace/ctf-ir/packet.h
deleted file mode 100644 (file)
index 7ff057f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_PACKET_H
-#define BABELTRACE_CTF_IR_PACKET_H
-
-/*
- * BabelTrace - CTF IR: Stream packet
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-/* For enum bt_clock_value_status */
-#include <babeltrace/ctf-ir/clock-value.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_packet;
-struct bt_packet_header_field;
-struct bt_packet_context_field;
-struct bt_stream;
-struct bt_clock_value;
-
-extern struct bt_packet *bt_packet_create(struct bt_stream *stream);
-
-extern struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet);
-
-extern
-struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet);
-
-extern
-int bt_packet_move_header_field(struct bt_packet *packet,
-               struct bt_packet_header_field *header);
-
-extern
-struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet);
-
-extern
-int bt_packet_move_context_field(struct bt_packet *packet,
-               struct bt_packet_context_field *context);
-
-extern
-enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
-               struct bt_packet *packet, struct bt_clock_value **clock_value);
-
-extern
-int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
-               uint64_t value_cycles);
-
-extern
-enum bt_clock_value_status bt_packet_borrow_default_end_clock_valeu(
-               struct bt_packet *packet, struct bt_clock_value **clock_value);
-
-extern
-int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
-               uint64_t value_cycles);
-
-extern
-enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
-               struct bt_packet *packet, uint64_t *value);
-
-extern
-int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
-               uint64_t value);
-
-extern
-enum bt_property_availability bt_packet_get_packet_counter_snapshot(
-               struct bt_packet *packet, uint64_t *value);
-
-extern
-int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
-               uint64_t value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_PACKET_H */
diff --git a/include/babeltrace/ctf-ir/resolve-field-path-internal.h b/include/babeltrace/ctf-ir/resolve-field-path-internal.h
deleted file mode 100644 (file)
index f2d0321..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL
-#define BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL
-
-/*
- * BabelTrace - CTF IR: Field path
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <glib.h>
-
-struct bt_resolve_field_path_context {
-       struct bt_field_type *packet_header;
-       struct bt_field_type *packet_context;
-       struct bt_field_type *event_header;
-       struct bt_field_type *event_common_context;
-       struct bt_field_type *event_specific_context;
-       struct bt_field_type *event_payload;
-};
-
-BT_HIDDEN
-int bt_resolve_field_paths(struct bt_field_type *ft,
-               struct bt_resolve_field_path_context *ctx);
-
-#endif /* BABELTRACE_CTF_IR_RESOLVE_FIELD_PATH_INTERNAL */
diff --git a/include/babeltrace/ctf-ir/resolve-internal.h b/include/babeltrace/ctf-ir/resolve-internal.h
deleted file mode 100644 (file)
index dad9790..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H
-#define BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H
-
-/*
- * Babeltrace - CTF IR: Type resolving internal
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *          Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-
-enum bt_resolve_flag {
-       BT_RESOLVE_FLAG_PACKET_HEADER           = 0x01,
-       BT_RESOLVE_FLAG_PACKET_CONTEXT          = 0x02,
-       BT_RESOLVE_FLAG_EVENT_HEADER            = 0x04,
-       BT_RESOLVE_FLAG_STREAM_EVENT_CTX        = 0x08,
-       BT_RESOLVE_FLAG_EVENT_CONTEXT           = 0x10,
-       BT_RESOLVE_FLAG_EVENT_PAYLOAD           = 0x20,
-};
-
-/*
- * Resolves CTF IR field types: recursively locates the tag and length
- * field types of resp. variant and sequence field types.
- *
- * All `*_type` parameters may be resolved, and may as well serve as
- * resolving targets.
- *
- * Resolving is performed based on the flags in `flags`.
- *
- * It is expected that, amongst all the provided types, no common
- * references to sequence variant field types exist. In other words,
- * this function does not copy field types.
- *
- * All parameters are owned by the caller.
- */
-BT_HIDDEN
-int bt_resolve_types(struct bt_value *environment,
-               struct bt_field_type *packet_header_type,
-               struct bt_field_type *packet_context_type,
-               struct bt_field_type *event_header_type,
-               struct bt_field_type *stream_event_ctx_type,
-               struct bt_field_type *event_context_type,
-               struct bt_field_type *event_payload_type,
-               enum bt_resolve_flag flags);
-
-#endif /* BABELTRACE_CTF_IR_RESOLVE_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/stream-class-internal.h b/include/babeltrace/ctf-ir/stream-class-internal.h
deleted file mode 100644 (file)
index 844a0c7..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
-#define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Stream class internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/common-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-#include <inttypes.h>
-
-struct bt_stream_class {
-       struct bt_object base;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } name;
-
-       uint64_t id;
-       bool assigns_automatic_event_class_id;
-       bool assigns_automatic_stream_id;
-       bool packets_have_discarded_event_counter_snapshot;
-       bool packets_have_packet_counter_snapshot;
-       bool packets_have_default_beginning_cv;
-       bool packets_have_default_end_cv;
-       struct bt_field_type *packet_context_ft;
-       struct bt_field_type *event_header_ft;
-       struct bt_field_type *event_common_context_ft;
-       struct bt_clock_class *default_clock_class;
-
-       /* Array of `struct bt_event_class *` */
-       GPtrArray *event_classes;
-
-       /* Pool of `struct bt_field_wrapper *` */
-       struct bt_object_pool event_header_field_pool;
-
-       /* Pool of `struct bt_field_wrapper *` */
-       struct bt_object_pool packet_context_field_pool;
-
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_stream_class_freeze(struct bt_stream_class *stream_class);
-
-#ifdef BT_DEV_MODE
-# define bt_stream_class_freeze                _bt_stream_class_freeze
-#else
-# define bt_stream_class_freeze(_sc)
-#endif
-
-static inline
-struct bt_trace *bt_stream_class_borrow_trace_inline(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT(stream_class);
-       return (void *) bt_object_borrow_parent(&stream_class->base);
-}
-
-#endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
index ca0b9ef954581a4b8a53b30b2675f68cae6f23ed..0322d67184925e1862b371d043033ea194622623 100644 (file)
@@ -1,147 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_STREAM_CLASS_H
-#define BABELTRACE_CTF_IR_STREAM_CLASS_H
-
-/*
- * BabelTrace - CTF IR: Stream Class
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-#include <stdint.h>
-
-/* For bt_bool */
-#include <babeltrace/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_stream_class;
-struct bt_event_class;
-struct bt_clock_class;
-struct bt_event_header_field;
-struct bt_packet_context_field;
-
-extern struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace);
-
-extern struct bt_stream_class *bt_stream_class_create_with_id(
-               struct bt_trace *trace, uint64_t id);
-
-extern struct bt_trace *bt_stream_class_borrow_trace(
-               struct bt_stream_class *stream_class);
-
-extern const char *bt_stream_class_get_name(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_name(struct bt_stream_class *stream_class,
-               const char *name);
-
-extern bt_bool bt_stream_class_assigns_automatic_event_class_id(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_assigns_automatic_event_class_id(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_assigns_automatic_stream_id(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_assigns_automatic_stream_id(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-extern uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class);
-
-extern struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packet_context_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type);
-
-extern struct bt_field_type *
-bt_stream_class_borrow_event_header_field_type(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_event_header_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type);
-
-extern struct bt_field_type *
-bt_stream_class_borrow_event_common_context_field_type(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_event_common_context_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type);
-
-extern uint64_t bt_stream_class_get_event_class_count(
-               struct bt_stream_class *stream_class);
-
-extern struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
-               struct bt_stream_class *stream_class, uint64_t index);
-
-extern struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
-               struct bt_stream_class *stream_class, uint64_t id);
-
-extern int bt_stream_class_set_default_clock_class(
-               struct bt_stream_class *stream_class,
-               struct bt_clock_class *clock_class);
-
-extern struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
-               struct bt_stream_class *stream_class);
-
-extern bt_bool bt_stream_class_default_clock_is_always_known(
-               struct bt_stream_class *stream_class);
-
-extern bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_packet_counter_snapshot(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_default_beginning_clock_value(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-extern bt_bool bt_stream_class_packets_have_default_end_clock_value(
-               struct bt_stream_class *stream_class);
-
-extern int bt_stream_class_set_packets_have_default_end_clock_value(
-               struct bt_stream_class *stream_class, bt_bool value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_CLASS_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/stream-class.h>
diff --git a/include/babeltrace/ctf-ir/stream-internal.h b/include/babeltrace/ctf-ir/stream-internal.h
deleted file mode 100644 (file)
index 0cbd18b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_STREAM_INTERNAL_H
-#define BABELTRACE_CTF_IR_STREAM_INTERNAL_H
-
-/*
- * BabelTrace - CTF Writer: Stream internal
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <glib.h>
-
-struct bt_stream_class;
-struct bt_stream;
-
-struct bt_stream {
-       struct bt_object base;
-
-       /* Weak: parent is this class's trace */
-       struct bt_stream_class *class;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } name;
-
-       uint64_t id;
-
-       /* Pool of `struct bt_packet *` */
-       struct bt_object_pool packet_pool;
-
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_stream_freeze(struct bt_stream *stream);
-
-#ifdef BT_DEV_MODE
-# define bt_stream_freeze              _bt_stream_freeze
-#else
-# define bt_stream_freeze(_stream)
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_INTERNAL_H */
index 69829280c904e5cb4f7b3c65a01e9469853ae4a6..eb7d57fe84438816f30c607c1c9c6708fbdd4fa9 100644 (file)
@@ -1,62 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_STREAM_H
-#define BABELTRACE_CTF_IR_STREAM_H
-
-/*
- * BabelTrace - CTF IR: Stream
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For enum bt_property_availability */
-#include <babeltrace/property.h>
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_stream;
-struct bt_stream_class;
-
-extern struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class);
-
-extern struct bt_stream *bt_stream_create_with_id(
-               struct bt_stream_class *stream_class, uint64_t id);
-
-extern struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream);
-
-extern const char *bt_stream_get_name(struct bt_stream *stream);
-
-extern int bt_stream_set_name(struct bt_stream *stream, const char *name);
-
-extern uint64_t bt_stream_get_id(struct bt_stream *stream);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_STREAM_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/stream.h>
diff --git a/include/babeltrace/ctf-ir/trace-internal.h b/include/babeltrace/ctf-ir/trace-internal.h
deleted file mode 100644 (file)
index 30b0ba4..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_TRACE_INTERNAL_H
-#define BABELTRACE_CTF_IR_TRACE_INTERNAL_H
-
-/*
- * BabelTrace - CTF IR: Trace internal
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/types.h>
-#include <glib.h>
-#include <sys/types.h>
-#include <babeltrace/compat/uuid-internal.h>
-
-struct bt_trace {
-       struct bt_object base;
-
-       struct {
-               GString *str;
-
-               /* NULL or `str->str` above */
-               const char *value;
-       } name;
-
-       struct {
-               uint8_t uuid[BABELTRACE_UUID_LEN];
-
-               /* NULL or `uuid` above */
-               bt_uuid value;
-       } uuid;
-
-       struct bt_value *environment;
-
-       /* Array of `struct bt_stream_class *` */
-       GPtrArray *stream_classes;
-
-       /* Array of `struct bt_stream *` */
-       GPtrArray *streams;
-
-       /*
-        * Stream class (weak) to number of instantiated streams, used
-        * to automatically assign stream IDs per stream class.
-        */
-       GHashTable *stream_classes_stream_count;
-
-       struct bt_field_type *packet_header_ft;
-       bool assigns_automatic_stream_class_id;
-
-       GArray *is_static_listeners;
-       bool is_static;
-       bool in_remove_listener;
-
-       /* Pool of `struct bt_field_wrapper *` */
-       struct bt_object_pool packet_header_field_pool;
-
-       bool frozen;
-};
-
-BT_HIDDEN
-void _bt_trace_freeze(struct bt_trace *trace);
-
-#ifdef BT_DEV_MODE
-# define bt_trace_freeze               _bt_trace_freeze
-#else
-# define bt_trace_freeze(_trace)
-#endif
-
-BT_HIDDEN
-void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream);
-
-BT_HIDDEN
-uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
-               struct bt_stream_class *stream_class);
-
-#endif /* BABELTRACE_CTF_IR_TRACE_INTERNAL_H */
index 690c88a32680fc12bc4758f15628dc31a7e390f9..84b9b7a92258027db94db571b2891a5aab0d9bb5 100644 (file)
@@ -1,127 +1,2 @@
-#ifndef BABELTRACE_CTF_IR_TRACE_H
-#define BABELTRACE_CTF_IR_TRACE_H
-
-/*
- * BabelTrace - CTF IR: Trace
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/* For bt_bool, bt_uuid */
-#include <babeltrace/types.h>
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_trace;
-struct bt_stream;
-struct bt_stream_class;
-struct bt_field_type;
-struct bt_value;
-struct bt_packet_header_field;
-
-typedef void (* bt_trace_is_static_listener)(
-       struct bt_trace *trace, void *data);
-
-typedef void (* bt_trace_listener_removed)(
-       struct bt_trace *trace, void *data);
-
-extern struct bt_trace *bt_trace_create(void);
-
-extern bt_bool bt_trace_assigns_automatic_stream_class_id(
-               struct bt_trace *trace);
-
-extern int bt_trace_set_assigns_automatic_stream_class_id(
-               struct bt_trace *trace, bt_bool value);
-
-extern const char *bt_trace_get_name(struct bt_trace *trace);
-
-extern int bt_trace_set_name(struct bt_trace *trace, const char *name);
-
-extern bt_uuid bt_trace_get_uuid(struct bt_trace *trace);
-
-extern int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid);
-
-extern uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace);
-
-extern void bt_trace_borrow_environment_entry_by_index(
-               struct bt_trace *trace, uint64_t index,
-               const char **name, struct bt_value **value);
-
-extern struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
-               struct bt_trace *trace, const char *name);
-
-extern int bt_trace_set_environment_entry_integer(
-               struct bt_trace *trace, const char *name,
-               int64_t value);
-
-extern int bt_trace_set_environment_entry_string(
-               struct bt_trace *trace, const char *name,
-               const char *value);
-
-extern struct bt_field_type *bt_trace_borrow_packet_header_field_type(
-               struct bt_trace *trace);
-
-extern int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
-               struct bt_field_type *packet_header_type);
-
-extern uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace);
-
-extern struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
-               struct bt_trace *trace, uint64_t index);
-
-extern struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
-               struct bt_trace *trace, uint64_t id);
-
-extern uint64_t bt_trace_get_stream_count(struct bt_trace *trace);
-
-extern struct bt_stream *bt_trace_borrow_stream_by_index(
-               struct bt_trace *trace, uint64_t index);
-
-extern struct bt_stream *bt_trace_borrow_stream_by_id(
-               struct bt_trace *trace, uint64_t id);
-
-extern bt_bool bt_trace_is_static(struct bt_trace *trace);
-
-extern int bt_trace_make_static(struct bt_trace *trace);
-
-extern int bt_trace_add_is_static_listener(
-               struct bt_trace *trace,
-               bt_trace_is_static_listener listener,
-               bt_trace_listener_removed listener_removed, void *data,
-               uint64_t *listener_id);
-
-extern int bt_trace_remove_is_static_listener(
-               struct bt_trace *trace, uint64_t listener_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BABELTRACE_CTF_IR_TRACE_H */
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/trace.h>
diff --git a/include/babeltrace/ctf-ir/utils-internal.h b/include/babeltrace/ctf-ir/utils-internal.h
deleted file mode 100644 (file)
index 3c53942..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef BABELTRACE_CTF_IR_UTILS_INTERNAL_H
-#define BABELTRACE_CTF_IR_UTILS_INTERNAL_H
-
-/*
- * Babeltrace - Internal CTF IR utilities
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <stdint.h>
-
-struct search_query {
-       gpointer value;
-       int found;
-};
-
-static inline
-uint64_t bt_util_ns_from_value(uint64_t frequency, uint64_t value_cycles)
-{
-       uint64_t ns;
-
-       if (frequency == UINT64_C(1000000000)) {
-               ns = value_cycles;
-       } else {
-               double dblres = ((1e9 * (double) value_cycles) / (double) frequency);
-
-               if (dblres >= (double) UINT64_MAX) {
-                       /* Overflows uint64_t */
-                       ns = UINT64_C(-1);
-               } else {
-                       ns = (uint64_t) dblres;
-               }
-       }
-
-       return ns;
-}
-
-static inline
-int bt_util_ns_from_origin(struct bt_clock_class *clock_class, uint64_t value,
-               int64_t *ns_from_origin)
-{
-       int ret = 0;
-       uint64_t value_ns_unsigned;
-       int64_t value_ns_signed;
-
-       if (clock_class->base_offset.overflows) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Initialize to clock class's base offset */
-       *ns_from_origin = clock_class->base_offset.value_ns;
-
-       /* Add given value in cycles */
-       value_ns_unsigned = bt_util_ns_from_value(clock_class->frequency, value);
-       if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
-               /*
-                * FIXME: `value_ns_unsigned` could be greater than
-                * `INT64_MAX` in fact: in this case, we need to
-                * subtract `INT64_MAX` from `value_ns_unsigned`, make
-                * sure that the difference is less than `INT64_MAX`,
-                * and try to add them one after the other to
-                * `*ns_from_origin`.
-                */
-               ret = -1;
-               goto end;
-       }
-
-       value_ns_signed = (int64_t) value_ns_unsigned;
-       BT_ASSERT(value_ns_signed >= 0);
-
-       if (*ns_from_origin <= 0) {
-               goto add_value;
-       }
-
-       if (value_ns_signed > INT64_MAX - *ns_from_origin) {
-               ret = -1;
-               goto end;
-       }
-
-add_value:
-       *ns_from_origin += value_ns_signed;
-
-end:
-       return ret;
-}
-
-static inline
-bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
-{
-       int64_t min_value = UINT64_C(-1) << (size - 1);
-       int64_t max_value = (UINT64_C(1) << (size - 1)) - 1;
-       return value >= min_value && value <= max_value;
-}
-
-static inline
-bool bt_util_value_is_in_range_unsigned(unsigned int size, uint64_t value)
-{
-       uint64_t max_value = (size == 64) ? UINT64_MAX :
-               (UINT64_C(1) << size) - 1;
-       return value <= max_value;
-}
-
-#endif /* BABELTRACE_CTF_IR_UTILS_INTERNAL_H */
diff --git a/include/babeltrace/ctf-ir/utils.h b/include/babeltrace/ctf-ir/utils.h
new file mode 100644 (file)
index 0000000..ce14a42
--- /dev/null
@@ -0,0 +1,2 @@
+/* Pre-2.0 CTF writer backward compatibility */
+#include <babeltrace/ctf-writer/utils.h>
index b6583a9336784ca6a7fcf75550d0ad202c39d0dd..0020e7b29b82360b9872144900269705a0a76707 100644 (file)
@@ -40,7 +40,7 @@ extern "C" {
 @brief CTF IR visitor.
 
 @code
-#include <babeltrace/ctf-ir/visitor.h>
+#include <babeltrace/trace-ir/visitor.h>
 @endcode
 
 A CTF IR <strong><em>visitor</em></strong> is a function that you
index 2fd1ffeb1d730b0b0f8fd0b8f1e29d7b6d88c44d..68ec9a6e621d57adeaf8641134ca54175cfa5e3d 100644 (file)
@@ -1,41 +1,7 @@
-#ifndef BABELTRACE_CTF_EVENTS_H
-#define BABELTRACE_CTF_EVENTS_H
-
-/*
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * The Common Trace Format (CTF) Specification is available at
- * http://www.efficios.com/ctf
- */
-
-/*
- * This header still exists for backward compatibility reasons because
- * CTF writer needed it to be included.
- */
-
+/* Pre-2.0 CTF writer backward compatibility */
 #include <babeltrace/ctf-writer/clock.h>
 #include <babeltrace/ctf-writer/event-fields.h>
 #include <babeltrace/ctf-writer/event-types.h>
 #include <babeltrace/ctf-writer/stream-class.h>
 #include <babeltrace/ctf-writer/stream.h>
 #include <babeltrace/ctf-writer/writer.h>
-
-#endif /* BABELTRACE_CTF_EVENTS_H */
index 83a02069954c40e9b1e28212ab65e1cf54abb066..2b401f20b25eb420524b88d02e6621254a0a2ab7 100644 (file)
@@ -28,8 +28,8 @@
  */
 
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event.h>
 #include <babeltrace/graph/notification-internal.h>
 #include <babeltrace/assert-internal.h>
 
index 42551c6f09328f38c3d86bfd41f2b292952d9dc8..9a74e8fdb4446a5f8e1a742a37fbb3e34e1bf148 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include <glib.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
 #include <babeltrace/graph/notification.h>
 
 struct bt_notification_inactivity {
index 206c110b791f4d656182fd3737c7b6e454490913..81f7d660a22482dbfb8968c5e7591926470bc685 100644 (file)
@@ -32,7 +32,7 @@
 #include <babeltrace/assert-internal.h>
 #include <babeltrace/graph/graph.h>
 #include <babeltrace/graph/notification.h>
-#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/trace-ir/stream.h>
 #include <babeltrace/object-pool-internal.h>
 #include <babeltrace/types.h>
 
index 639925b43add25018974a2bdc5e9f1420e1ad784..18f6db954355aa3efeb8f0afc8c4c423e0fdaf08 100644 (file)
@@ -28,7 +28,7 @@
  */
 
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/trace-ir/packet.h>
 #include <babeltrace/graph/notification-internal.h>
 #include <babeltrace/assert-internal.h>
 
index 15dd084751c405b6752b1d572a9f55f04fa6a6e7..818fc431ff2d268de8d2a0c70036c2d125baaa81 100644 (file)
@@ -28,9 +28,9 @@
  */
 
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/trace-ir/packet.h>
 #include <babeltrace/graph/notification-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
 #include <babeltrace/assert-internal.h>
 
 struct bt_notification_stream_begin {
index e2483b29d9a472980c748526d43360dafcafa974..6e04f9a25a91af218a656c8530aa8b391c7e5ef4 100644 (file)
@@ -79,31 +79,34 @@ int bt_lib_log_level;
  * The available format specifiers are:
  *
  *   `F`:
- *       CTF IR field type. The parameter type is `struct bt_field_type *`.
+ *       Trace IR field type. The parameter type is `struct
+ *       bt_field_type *`.
  *
  *   `f`:
- *       CTF IR field. The parameter type is `struct bt_field *`.
+ *       Trace IR field. The parameter type is `struct bt_field *`.
  *
  *   `P`:
  *       Field path. The parameter type is `struct bt_field_path *`.
  *
  *   `E`:
- *       CTF IR event class. The parameter type is `struct bt_event_class *`.
+ *       Trace IR event class. The parameter type is `struct
+ *       bt_event_class *`.
  *
  *   `e`:
- *       CTF IR event. The parameter type is `struct bt_event *`.
+ *       Trace IR event. The parameter type is `struct bt_event *`.
  *
  *   `S`:
- *       CTF IR stream class. The parameter type is `struct bt_stream_class *`.
+ *       Trace IR stream class. The parameter type is `struct
+ *       bt_stream_class *`.
  *
  *   `s`:
- *       CTF IR stream. The parameter type is `struct bt_stream *`.
+ *       Trace IR stream. The parameter type is `struct bt_stream *`.
  *
  *   `a`:
  *       Packet. The parameter type is `struct bt_packet *`.
  *
  *   `t`:
- *       CTF IR trace. The parameter type is `struct bt_trace *`.
+ *       Trace IR trace. The parameter type is `struct bt_trace *`.
  *
  *   `K`:
  *       Clock class. The parameter type is `struct bt_clock_class *`.
@@ -122,7 +125,8 @@ int bt_lib_log_level;
  *       `struct bt_notification_iterator *`.
  *
  *   `C`:
- *       Component class. The parameter type is `struct bt_component_class *`.
+ *       Component class. The parameter type is `struct
+ *       bt_component_class *`.
  *
  *   `c`:
  *       Component. The parameter type is `struct bt_component *`.
diff --git a/include/babeltrace/trace-ir/attributes-internal.h b/include/babeltrace/trace-ir/attributes-internal.h
new file mode 100644 (file)
index 0000000..3820abd
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef BABELTRACE_TRACE_IR_ATTRIBUTES_H
+#define BABELTRACE_TRACE_IR_ATTRIBUTES_H
+
+/*
+ * attributes.c
+ *
+ * Babeltrace - Trace IR: Attributes internal
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+
+BT_HIDDEN
+struct bt_value *bt_attributes_create(void);
+
+BT_HIDDEN
+void bt_attributes_destroy(struct bt_value *attr_obj);
+
+BT_HIDDEN
+int64_t bt_attributes_get_count(struct bt_value *attr_obj);
+
+BT_HIDDEN
+const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
+               uint64_t index);
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
+               uint64_t index);
+
+BT_HIDDEN
+int bt_attributes_set_field_value(struct bt_value *attr_obj,
+               const char *name, struct bt_value *value_obj);
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value_by_name(
+               struct bt_value *attr_obj, const char *name);
+
+BT_HIDDEN
+int bt_attributes_freeze(struct bt_value *attr_obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_ATTRIBUTES_H */
diff --git a/include/babeltrace/trace-ir/clock-class-internal.h b/include/babeltrace/trace-ir/clock-class-internal.h
new file mode 100644 (file)
index 0000000..86e0e39
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Clock internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/property-internal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <glib.h>
+
+struct bt_clock_class {
+       struct bt_object base;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } name;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } description;
+
+       uint64_t frequency;
+       uint64_t precision;
+       int64_t offset_seconds;
+       uint64_t offset_cycles;
+
+       struct {
+               uint8_t uuid[BABELTRACE_UUID_LEN];
+
+               /* NULL or `uuid` above */
+               bt_uuid value;
+       } uuid;
+
+       bool is_absolute;
+
+       /*
+        * This is computed every time you call
+        * bt_clock_class_set_frequency() or
+        * bt_clock_class_set_offset(), as well as initially. It is the
+        * base offset in nanoseconds including both `offset_seconds`
+        * and `offset_cycles` above in the result. It is used to
+        * accelerate future calls to
+        * bt_clock_value_get_ns_from_origin() and
+        * bt_clock_class_cycles_to_ns_from_origin().
+        *
+        * `overflows` is true if the base offset cannot be computed
+        * because of an overflow.
+        */
+       struct {
+               int64_t value_ns;
+               bool overflows;
+       } base_offset;
+
+       /* Pool of `struct bt_clock_value *` */
+       struct bt_object_pool cv_pool;
+
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_clock_class_freeze(struct bt_clock_class *clock_class);
+
+#ifdef BT_DEV_MODE
+# define bt_clock_class_freeze         _bt_clock_class_freeze
+#else
+# define bt_clock_class_freeze(_cc)
+#endif
+
+BT_HIDDEN
+bt_bool bt_clock_class_is_valid(struct bt_clock_class *clock_class);
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_CLASS_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/clock-class.h b/include/babeltrace/trace-ir/clock-class.h
new file mode 100644 (file)
index 0000000..f06a2b0
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef BABELTRACE_TRACE_IR_CLOCK_CLASS_H
+#define BABELTRACE_TRACE_IR_CLOCK_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool, bt_uuid */
+#include <babeltrace/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_clock_class;
+struct bt_clock_value;
+
+extern struct bt_clock_class *bt_clock_class_create(void);
+
+extern const char *bt_clock_class_get_name(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_name(struct bt_clock_class *clock_class,
+               const char *name);
+
+extern const char *bt_clock_class_get_description(
+               struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_description(struct bt_clock_class *clock_class,
+               const char *description);
+
+extern uint64_t bt_clock_class_get_frequency(
+               struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
+               uint64_t freq);
+
+extern uint64_t bt_clock_class_get_precision(
+               struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
+               uint64_t precision);
+
+extern void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
+               int64_t *seconds, uint64_t *cycles);
+
+extern int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
+               int64_t seconds, uint64_t cycles);
+
+extern bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
+               bt_bool is_absolute);
+
+extern bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class);
+
+extern int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
+               bt_uuid uuid);
+
+extern int bt_clock_class_cycles_to_ns_from_origin(
+               struct bt_clock_class *clock_class,
+               uint64_t cycles, int64_t *ns_from_origin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_CLASS_H */
diff --git a/include/babeltrace/trace-ir/clock-value-internal.h b/include/babeltrace/trace-ir/clock-value-internal.h
new file mode 100644 (file)
index 0000000..8cb7802
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H
+
+/*
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+struct bt_clock_class;
+
+struct bt_clock_value {
+       struct bt_object base;
+       struct bt_clock_class *clock_class;
+       uint64_t value_cycles;
+       bool ns_from_origin_overflows;
+       int64_t ns_from_origin;
+       bool is_set;
+};
+
+static inline
+void bt_clock_value_set(struct bt_clock_value *clock_value)
+{
+       BT_ASSERT(clock_value);
+       clock_value->is_set = true;
+}
+
+static inline
+void bt_clock_value_reset(struct bt_clock_value *clock_value)
+{
+       BT_ASSERT(clock_value);
+       clock_value->is_set = false;
+}
+
+static inline
+void set_ns_from_origin(struct bt_clock_value *clock_value)
+{
+       if (bt_util_ns_from_origin(clock_value->clock_class, clock_value->value_cycles,
+                       &clock_value->ns_from_origin)) {
+               clock_value->ns_from_origin_overflows = true;
+       }
+
+}
+
+static inline
+void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
+               uint64_t cycles)
+{
+       BT_ASSERT(clock_value);
+       clock_value->value_cycles = cycles;
+       set_ns_from_origin(clock_value);
+       bt_clock_value_set(clock_value);
+}
+
+static inline
+void bt_clock_value_set_value_inline(struct bt_clock_value *clock_value,
+               uint64_t raw_value)
+{
+       bt_clock_value_set_raw_value(clock_value, raw_value);
+}
+
+BT_HIDDEN
+void bt_clock_value_destroy(struct bt_clock_value *clock_value);
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class);
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_create(
+               struct bt_clock_class *clock_class);
+
+BT_HIDDEN
+void bt_clock_value_recycle(struct bt_clock_value *clock_value);
+
+BT_HIDDEN
+void bt_clock_value_set_raw_value(struct bt_clock_value *clock_value,
+               uint64_t cycles);
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_VALUE_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/clock-value-set-internal.h b/include/babeltrace/trace-ir/clock-value-set-internal.h
new file mode 100644 (file)
index 0000000..5c7e7bd
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
+#define BABELTRACE_GRAPH_CLOCK_VALUE_SET_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <glib.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/assert-internal.h>
+
+struct bt_clock_value_set {
+       /* Unique objects owned by this */
+       GPtrArray *clock_values;
+
+       /* Weak; points to one of the clock values above */
+       struct bt_clock_value *default_cv;
+};
+
+static inline
+int bt_clock_value_set_initialize(struct bt_clock_value_set *cv_set)
+{
+       int ret = 0;
+
+       cv_set->clock_values = g_ptr_array_sized_new(1);
+       if (!cv_set->clock_values) {
+#ifdef BT_LOGE_STR
+               BT_LOGE_STR("Failed to allocate one GPtrArray.");
+#endif
+
+               ret = -1;
+               goto end;
+       }
+
+       cv_set->default_cv = NULL;
+
+end:
+       return ret;
+}
+
+static inline
+void bt_clock_value_set_reset(struct bt_clock_value_set *cv_set)
+{
+       uint64_t i;
+
+       BT_ASSERT(cv_set);
+       BT_ASSERT(cv_set->clock_values);
+
+       for (i = 0; i < cv_set->clock_values->len; i++) {
+               struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
+
+               BT_ASSERT(cv);
+               bt_clock_value_reset(cv);
+       }
+
+       cv_set->default_cv = NULL;
+}
+
+static inline
+void bt_clock_value_set_finalize(struct bt_clock_value_set *cv_set)
+{
+       uint64_t i;
+
+       BT_ASSERT(cv_set);
+
+       if (cv_set->clock_values) {
+               for (i = 0; i < cv_set->clock_values->len; i++) {
+                       struct bt_clock_value *cv =
+                               cv_set->clock_values->pdata[i];
+
+                       BT_ASSERT(cv);
+                       bt_clock_value_recycle(cv);
+               }
+
+               g_ptr_array_free(cv_set->clock_values, TRUE);
+       }
+
+       cv_set->default_cv = NULL;
+}
+
+static inline
+int bt_clock_value_set_set_clock_value(struct bt_clock_value_set *cv_set,
+               struct bt_clock_class *cc, uint64_t raw_value)
+{
+       int ret = 0;
+       struct bt_clock_value *clock_value = NULL;
+       uint64_t i;
+
+       BT_ASSERT(cv_set);
+       BT_ASSERT(cc);
+
+       /*
+        * Check if we already have a value for this clock class.
+        *
+        * TODO: When we have many clock classes, make this more
+        * efficient.
+        */
+       for (i = 0; i < cv_set->clock_values->len; i++) {
+               struct bt_clock_value *cv = cv_set->clock_values->pdata[i];
+
+               BT_ASSERT(cv);
+
+               if (cv->clock_class == cc) {
+                       clock_value = cv;
+                       break;
+               }
+       }
+
+       if (!clock_value) {
+               clock_value = bt_clock_value_create(cc);
+               if (!clock_value) {
+#ifdef BT_LIB_LOGE
+                       BT_LIB_LOGE("Cannot create a clock value from a clock class: "
+                               "%![cc-]+K", cc);
+#endif
+
+                       ret = -1;
+                       goto end;
+               }
+
+               g_ptr_array_add(cv_set->clock_values, clock_value);
+       }
+
+       bt_clock_value_set_value_inline(clock_value, raw_value);
+
+end:
+       return ret;
+}
+
+static inline
+void  bt_clock_value_set_set_default_clock_value(
+               struct bt_clock_value_set *cv_set, uint64_t raw_value)
+{
+       BT_ASSERT(cv_set);
+       BT_ASSERT(cv_set->default_cv);
+       bt_clock_value_set_value_inline(cv_set->default_cv, raw_value);
+}
+
+#endif /* BABELTRACE_GRAPH_CLOCK_VALUE_SET_H */
diff --git a/include/babeltrace/trace-ir/clock-value.h b/include/babeltrace/trace-ir/clock-value.h
new file mode 100644 (file)
index 0000000..0676fa0
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef BABELTRACE_TRACE_IR_CLOCK_VALUE_H
+#define BABELTRACE_TRACE_IR_CLOCK_VALUE_H
+
+/*
+ * BabelTrace - Trace IR: Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_clock_class;
+struct bt_clock_value;
+
+enum bt_clock_value_status {
+       BT_CLOCK_VALUE_STATUS_KNOWN,
+       BT_CLOCK_VALUE_STATUS_UNKNOWN,
+};
+
+extern struct bt_clock_class *bt_clock_value_borrow_clock_class(
+               struct bt_clock_value *clock_value);
+
+extern uint64_t bt_clock_value_get_value(
+               struct bt_clock_value *clock_value);
+
+extern int bt_clock_value_get_ns_from_origin(
+               struct bt_clock_value *clock_value, int64_t *ns_from_origin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_VALUE_H */
diff --git a/include/babeltrace/trace-ir/clock.h b/include/babeltrace/trace-ir/clock.h
new file mode 100644 (file)
index 0000000..2fcf48f
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef BABELTRACE_TRACE_IR_CLOCK_H
+#define BABELTRACE_TRACE_IR_CLOCK_H
+
+/*
+ * BabelTrace - Trace IR: Clock
+ *
+ * Copyright 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/ctf-writer/clock.h>
+
+#endif /* BABELTRACE_TRACE_IR_CLOCK_H */
diff --git a/include/babeltrace/trace-ir/event-class-internal.h b/include/babeltrace/trace-ir/event-class-internal.h
new file mode 100644 (file)
index 0000000..3f366dd
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/property-internal.h>
+#include <glib.h>
+#include <stdbool.h>
+
+struct bt_event_class {
+       struct bt_object base;
+       struct bt_field_type *specific_context_ft;
+       struct bt_field_type *payload_ft;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } name;
+
+       uint64_t id;
+       struct bt_property_uint log_level;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } emf_uri;
+
+       /* Pool of `struct bt_event *` */
+       struct bt_object_pool event_pool;
+
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_event_class_freeze(struct bt_event_class *event_class);
+
+#ifdef BT_DEV_MODE
+# define bt_event_class_freeze         _bt_event_class_freeze
+#else
+# define bt_event_class_freeze(_ec)
+#endif
+
+static inline
+struct bt_stream_class *bt_event_class_borrow_stream_class_inline(
+               struct bt_event_class *event_class)
+{
+       BT_ASSERT(event_class);
+       return (void *) bt_object_borrow_parent(&event_class->base);
+}
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_CLASS_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/event-class.h b/include/babeltrace/trace-ir/event-class.h
new file mode 100644 (file)
index 0000000..ae052ee
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef BABELTRACE_TRACE_IR_EVENT_CLASS_H
+#define BABELTRACE_TRACE_IR_EVENT_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Event class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_event_class;
+struct bt_field_type;
+struct bt_stream_class;
+
+enum bt_event_class_log_level {
+       BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY,
+       BT_EVENT_CLASS_LOG_LEVEL_ALERT,
+       BT_EVENT_CLASS_LOG_LEVEL_CRITICAL,
+       BT_EVENT_CLASS_LOG_LEVEL_ERROR,
+       BT_EVENT_CLASS_LOG_LEVEL_WARNING,
+       BT_EVENT_CLASS_LOG_LEVEL_NOTICE,
+       BT_EVENT_CLASS_LOG_LEVEL_INFO,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE,
+       BT_EVENT_CLASS_LOG_LEVEL_DEBUG,
+};
+
+extern struct bt_event_class *bt_event_class_create(
+               struct bt_stream_class *stream_class);
+
+extern struct bt_event_class *bt_event_class_create_with_id(
+               struct bt_stream_class *stream_class, uint64_t id);
+
+extern struct bt_stream_class *bt_event_class_borrow_stream_class(
+               struct bt_event_class *event_class);
+
+extern const char *bt_event_class_get_name(struct bt_event_class *event_class);
+
+extern int bt_event_class_set_name(struct bt_event_class *event_class,
+               const char *name);
+
+extern uint64_t bt_event_class_get_id(struct bt_event_class *event_class);
+
+extern enum bt_property_availability bt_event_class_get_log_level(
+               struct bt_event_class *event_class,
+               enum bt_event_class_log_level *log_level);
+
+extern int bt_event_class_set_log_level(struct bt_event_class *event_class,
+               enum bt_event_class_log_level log_level);
+
+extern const char *bt_event_class_get_emf_uri(
+               struct bt_event_class *event_class);
+
+extern int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
+               const char *emf_uri);
+
+extern struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
+               struct bt_event_class *event_class);
+
+extern int bt_event_class_set_specific_context_field_type(
+               struct bt_event_class *event_class,
+               struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_event_class_borrow_payload_field_type(
+               struct bt_event_class *event_class);
+
+extern int bt_event_class_set_payload_field_type(
+               struct bt_event_class *event_class,
+               struct bt_field_type *field_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_CLASS_H */
diff --git a/include/babeltrace/trace-ir/event-header-field.h b/include/babeltrace/trace-ir/event-header-field.h
new file mode 100644 (file)
index 0000000..fa3719e
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H
+#define BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream_class;
+struct bt_event_header_field;
+struct bt_field;
+
+extern
+struct bt_event_header_field *bt_event_header_field_create(
+               struct bt_stream_class *stream_class);
+
+extern
+struct bt_field *bt_event_header_field_borrow_field(
+               struct bt_event_header_field *field);
+
+extern
+void bt_event_header_field_release(struct bt_event_header_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_HEADER_FIELD_H */
diff --git a/include/babeltrace/trace-ir/event-internal.h b/include/babeltrace/trace-ir/event-internal.h
new file mode 100644 (file)
index 0000000..ef5bdf0
--- /dev/null
@@ -0,0 +1,219 @@
+#ifndef BABELTRACE_TRACE_IR_EVENT_INTERNAL_H
+#define BABELTRACE_TRACE_IR_EVENT_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* Protection: this file uses BT_LIB_LOG*() macros directly */
+#ifndef BABELTRACE_LIB_LOGGING_INTERNAL_H
+# error Please define include <babeltrace/lib-logging-internal.h> before including this file.
+#endif
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_EVENT_HOT(_event) \
+       BT_ASSERT_PRE_HOT((_event), "Event", ": %!+e", (_event))
+
+struct bt_event {
+       struct bt_object base;
+       struct bt_event_class *class;
+       struct bt_packet *packet;
+       struct bt_field_wrapper *header_field;
+       struct bt_field *common_context_field;
+       struct bt_field *specific_context_field;
+       struct bt_field *payload_field;
+       struct bt_clock_value *default_cv;
+       bool frozen;
+};
+
+BT_HIDDEN
+void bt_event_destroy(struct bt_event *event);
+
+BT_HIDDEN
+struct bt_event *bt_event_new(struct bt_event_class *event_class);
+
+BT_HIDDEN
+void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
+
+#ifdef BT_DEV_MODE
+# define bt_event_set_is_frozen                _bt_event_set_is_frozen
+#else
+# define bt_event_set_is_frozen(_event, _is_frozen)
+#endif
+
+BT_UNUSED
+static inline
+void _bt_event_reset_dev_mode(struct bt_event *event)
+{
+       BT_ASSERT(event);
+
+       if (event->header_field) {
+               bt_field_set_is_frozen(
+                       event->header_field->field, false);
+               bt_field_reset(
+                       event->header_field->field);
+       }
+
+       if (event->common_context_field) {
+               bt_field_set_is_frozen(
+                       event->common_context_field, false);
+               bt_field_reset(
+                       event->common_context_field);
+       }
+
+       if (event->specific_context_field) {
+               bt_field_set_is_frozen(
+                       event->specific_context_field, false);
+               bt_field_reset(event->specific_context_field);
+       }
+
+       if (event->payload_field) {
+               bt_field_set_is_frozen(
+                       event->payload_field, false);
+               bt_field_reset(event->payload_field);
+       }
+}
+
+#ifdef BT_DEV_MODE
+# define bt_event_reset_dev_mode       _bt_event_reset_dev_mode
+#else
+# define bt_event_reset_dev_mode(_x)
+#endif
+
+static inline
+void bt_event_reset(struct bt_event *event)
+{
+       BT_ASSERT(event);
+       BT_LIB_LOGD("Resetting event: %!+e", event);
+       bt_event_set_is_frozen(event, false);
+
+       if (event->default_cv) {
+               bt_clock_value_reset(event->default_cv);
+       }
+
+       bt_object_put_no_null_check(&event->packet->base);
+       event->packet = NULL;
+}
+
+static inline
+void bt_event_recycle(struct bt_event *event)
+{
+       struct bt_event_class *event_class;
+
+       BT_ASSERT(event);
+       BT_LIB_LOGD("Recycling event: %!+e", event);
+
+       /*
+        * Those are the important ordered steps:
+        *
+        * 1. Reset the event object (put any permanent reference it
+        *    has, unfreeze it and its fields in developer mode, etc.),
+        *    but do NOT put its class's reference. This event class
+        *    contains the pool to which we're about to recycle this
+        *    event object, so we must guarantee its existence thanks
+        *    to this existing reference.
+        *
+        * 2. Move the event class reference to our `event_class`
+        *    variable so that we can set the event's class member
+        *    to NULL before recycling it. We CANNOT do this after
+        *    we put the event class reference because this bt_put()
+        *    could destroy the event class, also destroying its
+        *    event pool, thus also destroying our event object (this
+        *    would result in an invalid write access).
+        *
+        * 3. Recycle the event object.
+        *
+        * 4. Put our event class reference.
+        */
+       bt_event_reset(event);
+       event_class = event->class;
+       BT_ASSERT(event_class);
+       event->class = NULL;
+       bt_object_pool_recycle_object(&event_class->event_pool, event);
+       bt_object_put_no_null_check(&event_class->base);
+}
+
+static inline
+void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_EVENT_HOT(event);
+       BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
+               event->class) == packet->stream->class,
+               "Packet's stream class and event's stream class differ: "
+               "%![event-]+e, %![packet-]+a", event, packet);
+
+       BT_ASSERT(!event->packet);
+       event->packet = packet;
+       bt_object_get_no_null_check_no_parent_check(&event->packet->base);
+       BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a",
+               event, packet);
+}
+
+static inline
+struct bt_event *bt_event_create(struct bt_event_class *event_class,
+               struct bt_packet *packet)
+{
+       struct bt_event *event = NULL;
+
+       BT_ASSERT(event_class);
+       event = bt_object_pool_create_object(&event_class->event_pool);
+       if (unlikely(!event)) {
+               BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
+                       "%![ec-]+E", event_class);
+               goto end;
+       }
+
+       if (likely(!event->class)) {
+               event->class = event_class;
+               bt_object_get_no_null_check(&event_class->base);
+       }
+
+       BT_ASSERT(packet);
+       bt_event_set_packet(event, packet);
+       goto end;
+
+end:
+       return event;
+}
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/event.h b/include/babeltrace/trace-ir/event.h
new file mode 100644 (file)
index 0000000..574af84
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef BABELTRACE_TRACE_IR_EVENT_H
+#define BABELTRACE_TRACE_IR_EVENT_H
+
+/*
+ * BabelTrace - Trace IR: Event
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* For enum bt_clock_value_status */
+#include <babeltrace/trace-ir/clock-value.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_event;
+struct bt_event_header_field;
+struct bt_clock_value;
+struct bt_event_class;
+struct bt_field;
+struct bt_packet;
+
+extern struct bt_event_class *bt_event_borrow_class(struct bt_event *event);
+
+extern struct bt_packet *bt_event_borrow_packet(struct bt_event *event);
+
+extern struct bt_stream *bt_event_borrow_stream(struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_header_field(struct bt_event *event);
+
+extern int bt_event_move_header(struct bt_event *event,
+               struct bt_event_header_field *header);
+
+extern struct bt_field *bt_event_borrow_common_context_field(
+               struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_specific_context_field(
+               struct bt_event *event);
+
+extern struct bt_field *bt_event_borrow_payload_field(struct bt_event *event);
+
+extern int bt_event_set_default_clock_value(struct bt_event *event,
+               uint64_t value_cycles);
+
+extern enum bt_clock_value_status bt_event_borrow_default_clock_value(
+               struct bt_event *event, struct bt_clock_value **clock_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_EVENT_H */
diff --git a/include/babeltrace/trace-ir/field-path-internal.h b/include/babeltrace/trace-ir/field-path-internal.h
new file mode 100644 (file)
index 0000000..fd6ebc3
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL
+#define BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+struct bt_field_path {
+       struct bt_object base;
+       enum bt_scope root;
+
+       /* Array of `uint64_t` (indexes) */
+       GArray *indexes;
+};
+
+BT_HIDDEN
+struct bt_field_path *bt_field_path_create(void);
+
+static inline
+uint64_t bt_field_path_get_index_by_index_inline(
+               struct bt_field_path *field_path, uint64_t index)
+{
+       BT_ASSERT(field_path);
+       BT_ASSERT(index < field_path->indexes->len);
+       return g_array_index(field_path->indexes, uint64_t, index);
+}
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL */
diff --git a/include/babeltrace/trace-ir/field-path.h b/include/babeltrace/trace-ir/field-path.h
new file mode 100644 (file)
index 0000000..2556a6f
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef BABELTRACE_TRACE_IR_FIELD_PATH_H
+#define BABELTRACE_TRACE_IR_FIELD_PATH_H
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field_path;
+
+enum bt_scope {
+       BT_SCOPE_PACKET_HEADER,
+       BT_SCOPE_PACKET_CONTEXT,
+       BT_SCOPE_EVENT_HEADER,
+       BT_SCOPE_EVENT_COMMON_CONTEXT,
+       BT_SCOPE_EVENT_SPECIFIC_CONTEXT,
+       BT_SCOPE_EVENT_PAYLOAD,
+};
+
+extern enum bt_scope bt_field_path_get_root_scope(
+               struct bt_field_path *field_path);
+
+extern uint64_t bt_field_path_get_index_count(
+               struct bt_field_path *field_path);
+
+extern uint64_t bt_field_path_get_index_by_index(
+               struct bt_field_path *field_path, uint64_t index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_PATH_H */
diff --git a/include/babeltrace/trace-ir/field-types-internal.h b/include/babeltrace/trace-ir/field-types-internal.h
new file mode 100644 (file)
index 0000000..82ec15c
--- /dev/null
@@ -0,0 +1,255 @@
+#ifndef BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Event field types internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/types.h>
+#include <stdint.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_FT_IS_INT(_ft, _name)                            \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+               _name " is not an integer field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(_ft, _name)                   \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
+               _name " is not an unsigned integer field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_ENUM(_ft, _name)                           \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+               _name " is not an enumeration field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_IS_ARRAY(_ft, _name)                          \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
+               ((struct bt_field_type *) (_ft))->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
+               _name " is not an array field type: %![ft-]+F", (_ft))
+
+#define BT_ASSERT_PRE_FT_HAS_ID(_ft, _id, _name)                       \
+       BT_ASSERT_PRE(((struct bt_field_type *) (_ft))->id == (_id),    \
+               _name " has the wrong ID: expected-id=%s, "             \
+               "%![ft-]+F", bt_common_field_type_id_string(_id), (_ft))
+
+#define BT_ASSERT_PRE_FT_HOT(_ft, _name)                               \
+       BT_ASSERT_PRE_HOT((struct bt_field_type *) (_ft),               \
+               (_name), ": %!+F", (_ft))
+
+#define BT_FIELD_TYPE_NAMED_FT_AT_INDEX(_ft, _index)           \
+       (&g_array_index(((struct bt_field_type_named_field_types_container *) (_ft))->named_fts, \
+               struct bt_named_field_type, (_index)))
+
+#define BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(_ft, _index)               \
+       (&g_array_index(((struct bt_field_type_enumeration *) (_ft))->mappings, \
+               struct bt_field_type_enumeration_mapping, (_index)))
+
+#define BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index)    \
+       (&g_array_index((_mapping)->ranges,                             \
+               struct bt_field_type_enumeration_mapping_range, (_index)))
+
+struct bt_field;
+struct bt_field_type;
+
+struct bt_field_type {
+       struct bt_object base;
+       enum bt_field_type_id id;
+       bool frozen;
+
+       /*
+        * Only used in developer mode, this flag indicates whether or
+        * not this field type is part of a trace.
+        */
+       bool part_of_trace;
+};
+
+struct bt_field_type_integer {
+       struct bt_field_type common;
+
+       /*
+        * Value range of fields built from this integer field type:
+        * this is an equivalent integer size in bits. More formally,
+        * `range` is `n` in:
+        *
+        * Unsigned range: [0, 2^n - 1]
+        * Signed range: [-2^(n - 1), 2^(n - 1) - 1]
+        */
+       uint64_t range;
+
+       enum bt_field_type_integer_preferred_display_base base;
+};
+
+struct bt_field_type_enumeration_mapping_range {
+       union {
+               uint64_t u;
+               int64_t i;
+       } lower;
+
+       union {
+               uint64_t u;
+               int64_t i;
+       } upper;
+};
+
+struct bt_field_type_enumeration_mapping {
+       GString *label;
+
+       /* Array of `struct bt_field_type_enumeration_mapping_range` */
+       GArray *ranges;
+};
+
+struct bt_field_type_enumeration {
+       struct bt_field_type_integer common;
+
+       /* Array of `struct bt_field_type_enumeration_mapping *` */
+       GArray *mappings;
+
+       /*
+        * This is an array of `const char *` which acts as a temporary
+        * (potentially growing) buffer for
+        * bt_field_type_unsigned_enumeration_get_mapping_labels_by_value()
+        * and
+        * bt_field_type_signed_enumeration_get_mapping_labels_by_value().
+        *
+        * The actual strings are owned by the mappings above.
+        */
+       GPtrArray *label_buf;
+};
+
+struct bt_field_type_real {
+       struct bt_field_type common;
+       bool is_single_precision;
+};
+
+struct bt_field_type_string {
+       struct bt_field_type common;
+};
+
+/* A named field type is a (name, field type) pair */
+struct bt_named_field_type {
+       GString *name;
+
+       /* Owned by this */
+       struct bt_field_type *ft;
+};
+
+/*
+ * This is the base field type for a container of named field types.
+ * Structure and variant field types inherit this.
+ */
+struct bt_field_type_named_field_types_container {
+       struct bt_field_type common;
+
+       /*
+        * Key: `const char *`, not owned by this (owned by named field
+        * type objects contained in `named_fts` below).
+        */
+       GHashTable *name_to_index;
+
+       /* Array of `struct bt_named_field_type` */
+       GArray *named_fts;
+};
+
+struct bt_field_type_structure {
+       struct bt_field_type_named_field_types_container common;
+};
+
+struct bt_field_type_array {
+       struct bt_field_type common;
+
+       /* Owned by this */
+       struct bt_field_type *element_ft;
+};
+
+struct bt_field_type_static_array {
+       struct bt_field_type_array common;
+       uint64_t length;
+};
+
+struct bt_field_type_dynamic_array {
+       struct bt_field_type_array common;
+
+       /* Weak: never dereferenced, only use to find it elsewhere */
+       struct bt_field_type *length_ft;
+
+       /* Owned by this */
+       struct bt_field_path *length_field_path;
+};
+
+struct bt_field_type_variant {
+       struct bt_field_type_named_field_types_container common;
+
+       /* Weak: never dereferenced, only use to find it elsewhere */
+       struct bt_field_type *selector_ft;
+
+       /* Owned by this */
+       struct bt_field_path *selector_field_path;
+};
+
+static inline
+bool bt_field_type_has_known_id(struct bt_field_type *ft)
+{
+       return ft->id >= BT_FIELD_TYPE_ID_UNSIGNED_INTEGER &&
+               ft->id <= BT_FIELD_TYPE_ID_VARIANT;
+}
+
+BT_HIDDEN
+void _bt_field_type_freeze(struct bt_field_type *field_type);
+
+#ifdef BT_DEV_MODE
+# define bt_field_type_freeze          _bt_field_type_freeze
+#else
+# define bt_field_type_freeze(_ft)
+#endif
+
+/*
+ * This function recursively marks `field_type` and its children as
+ * being part of a trace. This is used to validate that all field types
+ * are used at a single location within trace objects even if they are
+ * shared objects for other purposes.
+ */
+BT_HIDDEN
+void _bt_field_type_make_part_of_trace(struct bt_field_type *field_type);
+
+#ifdef BT_DEV_MODE
+# define bt_field_type_make_part_of_trace      _bt_field_type_make_part_of_trace
+#else
+# define bt_field_type_make_part_of_trace(_ft) ((void) _ft)
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_TYPES_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/field-types.h b/include/babeltrace/trace-ir/field-types.h
new file mode 100644 (file)
index 0000000..58ce8a6
--- /dev/null
@@ -0,0 +1,222 @@
+#ifndef BABELTRACE_TRACE_IR_FIELD_TYPES_H
+#define BABELTRACE_TRACE_IR_FIELD_TYPES_H
+
+/*
+ * BabelTrace - Trace IR: Event field types
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For bt_get() */
+#include <babeltrace/ref.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field_type;
+struct bt_field_path;
+struct bt_field_type_signed_enumeration_mapping_ranges;
+struct bt_field_type_unsigned_enumeration_mapping_ranges;
+
+typedef const char * const *bt_field_type_enumeration_mapping_label_array;
+
+enum bt_field_type_id {
+       BT_FIELD_TYPE_ID_UNSIGNED_INTEGER,
+       BT_FIELD_TYPE_ID_SIGNED_INTEGER,
+       BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+       BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+       BT_FIELD_TYPE_ID_REAL,
+       BT_FIELD_TYPE_ID_STRING,
+       BT_FIELD_TYPE_ID_STRUCTURE,
+       BT_FIELD_TYPE_ID_STATIC_ARRAY,
+       BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+       BT_FIELD_TYPE_ID_VARIANT,
+};
+
+enum bt_field_type_integer_preferred_display_base {
+       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_BINARY,
+       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL,
+       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL,
+       BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL,
+};
+
+extern enum bt_field_type_id bt_field_type_get_type_id(
+               struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_field_type_unsigned_integer_create(void);
+
+extern struct bt_field_type *bt_field_type_signed_integer_create(void);
+
+extern uint64_t bt_field_type_integer_get_field_value_range(
+               struct bt_field_type *field_type);
+
+extern int bt_field_type_integer_set_field_value_range(
+               struct bt_field_type *field_type, uint64_t size);
+
+extern enum bt_field_type_integer_preferred_display_base
+bt_field_type_integer_get_preferred_display_base(
+               struct bt_field_type *field_type);
+
+extern int bt_field_type_integer_set_preferred_display_base(
+               struct bt_field_type *field_type,
+               enum bt_field_type_integer_preferred_display_base base);
+
+extern struct bt_field_type *bt_field_type_real_create(void);
+
+extern bt_bool bt_field_type_real_is_single_precision(
+               struct bt_field_type *field_type);
+
+extern int bt_field_type_real_set_is_single_precision(
+               struct bt_field_type *field_type,
+               bt_bool is_single_precision);
+
+extern struct bt_field_type *bt_field_type_unsigned_enumeration_create(void);
+
+extern struct bt_field_type *bt_field_type_signed_enumeration_create(void);
+
+extern uint64_t bt_field_type_enumeration_get_mapping_count(
+               struct bt_field_type *field_type);
+
+extern void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
+               struct bt_field_type *field_type, uint64_t index,
+               const char **label,
+               struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges);
+
+extern void bt_field_type_signed_enumeration_borrow_mapping_by_index(
+               struct bt_field_type *field_type, uint64_t index,
+               const char **label,
+               struct bt_field_type_signed_enumeration_mapping_ranges **ranges);
+
+extern uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges);
+
+extern uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
+               struct bt_field_type_signed_enumeration_mapping_ranges *ranges);
+
+extern void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+               uint64_t index, uint64_t *lower, uint64_t *upper);
+
+extern void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+               uint64_t index, int64_t *lower, int64_t *upper);
+
+extern int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+               struct bt_field_type *field_type, uint64_t value,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count);
+
+extern int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+               struct bt_field_type *field_type, int64_t value,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count);
+
+extern int bt_field_type_unsigned_enumeration_map_range(
+               struct bt_field_type *field_type, const char *label,
+               uint64_t range_lower, uint64_t range_upper);
+
+extern int bt_field_type_signed_enumeration_map_range(
+               struct bt_field_type *field_type, const char *label,
+               int64_t range_lower, int64_t range_upper);
+
+extern struct bt_field_type *bt_field_type_string_create(void);
+
+extern struct bt_field_type *bt_field_type_structure_create(void);
+
+extern uint64_t bt_field_type_structure_get_member_count(
+               struct bt_field_type *field_type);
+
+extern void bt_field_type_structure_borrow_member_by_index(
+               struct bt_field_type *struct_field_type, uint64_t index,
+               const char **name, struct bt_field_type **field_type);
+
+extern
+struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
+               struct bt_field_type *field_type, const char *name);
+
+extern int bt_field_type_structure_append_member(
+               struct bt_field_type *struct_field_type, const char *name,
+               struct bt_field_type *field_type);
+
+extern struct bt_field_type *bt_field_type_static_array_create(
+               struct bt_field_type *elem_field_type,
+               uint64_t length);
+
+extern struct bt_field_type *bt_field_type_dynamic_array_create(
+               struct bt_field_type *elem_field_type);
+
+extern struct bt_field_type *bt_field_type_array_borrow_element_field_type(
+               struct bt_field_type *field_type);
+
+extern uint64_t bt_field_type_static_array_get_length(
+               struct bt_field_type *field_type);
+
+extern struct bt_field_path *
+bt_field_type_dynamic_array_borrow_length_field_path(
+               struct bt_field_type *field_type);
+
+extern int bt_field_type_dynamic_array_set_length_field_type(
+               struct bt_field_type *field_type,
+               struct bt_field_type *length_field_type);
+
+extern struct bt_field_type *bt_field_type_variant_create(void);
+
+extern struct bt_field_path *
+bt_field_type_variant_borrow_selector_field_path(
+               struct bt_field_type *field_type);
+
+extern int bt_field_type_variant_set_selector_field_type(
+               struct bt_field_type *field_type,
+               struct bt_field_type *selector_field_type);
+
+extern uint64_t bt_field_type_variant_get_option_count(
+               struct bt_field_type *field_type);
+
+extern void bt_field_type_variant_borrow_option_by_index(
+               struct bt_field_type *variant_field_type, uint64_t index,
+               const char **name, struct bt_field_type **field_type);
+
+extern
+struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
+               struct bt_field_type *field_type,
+               const char *name);
+
+extern int bt_field_type_variant_append_option(
+               struct bt_field_type *var_field_type,
+               const char *name, struct bt_field_type *field_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_TYPES_H */
diff --git a/include/babeltrace/trace-ir/field-wrapper-internal.h b/include/babeltrace/trace-ir/field-wrapper-internal.h
new file mode 100644 (file)
index 0000000..e2b6913
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+
+struct bt_field_wrapper {
+       struct bt_object base;
+
+       /* Owned by this */
+       struct bt_field *field;
+};
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_new(void *data);
+
+BT_HIDDEN
+void bt_field_wrapper_destroy(struct bt_field_wrapper *field);
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_create(
+               struct bt_object_pool *pool, struct bt_field_type *ft);
+
+#endif /* BABELTRACE_TRACE_IR_FIELD_WRAPPER_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/fields-internal.h b/include/babeltrace/trace-ir/fields-internal.h
new file mode 100644 (file)
index 0000000..c8a1dcf
--- /dev/null
@@ -0,0 +1,206 @@
+#ifndef BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Event Fields internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/common-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <glib.h>
+
+#define BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(_field, _type_id, _name)       \
+       BT_ASSERT_PRE(((struct bt_field *) (_field))->type->id == (_type_id), \
+               _name " has the wrong type ID: expected-type-id=%s, "   \
+               "%![field-]+f",                                         \
+               bt_common_field_type_id_string(_type_id), (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name)             \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER || \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, \
+               _name " is not an unsigned integer field: %![field-]+f", \
+               (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name)               \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_INTEGER || \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, \
+               _name " is not a signed integer field: %![field-]+f", \
+               (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name)                    \
+       BT_ASSERT_PRE(                                                  \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_STATIC_ARRAY || \
+               ((struct bt_field *) (_field))->type->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, \
+               _name " is not an array field: %![field-]+f", (_field))
+
+#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name)                      \
+       BT_ASSERT_PRE(bt_field_is_set(_field),                          \
+               _name " is not set: %!+f", (_field))
+
+#define BT_ASSERT_PRE_FIELD_HOT(_field, _name)                         \
+       BT_ASSERT_PRE_HOT((struct bt_field *) (_field), (_name),        \
+               ": %!+f", (_field))
+
+struct bt_field;
+
+typedef struct bt_field *(* bt_field_create_func)(struct bt_field_type *);
+typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool);
+typedef bool (*bt_field_method_is_set)(struct bt_field *);
+typedef void (*bt_field_method_reset)(struct bt_field *);
+
+struct bt_field_methods {
+       bt_field_method_set_is_frozen set_is_frozen;
+       bt_field_method_is_set is_set;
+       bt_field_method_reset reset;
+};
+
+struct bt_field {
+       struct bt_object base;
+
+       /* Owned by this */
+       struct bt_field_type *type;
+
+       /* Virtual table for slow path (dev mode) operations */
+       struct bt_field_methods *methods;
+
+       bool is_set;
+       bool frozen;
+};
+
+struct bt_field_integer {
+       struct bt_field common;
+
+       union {
+               uint64_t u;
+               int64_t i;
+       } value;
+};
+
+struct bt_field_real {
+       struct bt_field common;
+       double value;
+};
+
+struct bt_field_structure {
+       struct bt_field common;
+
+       /* Array of `struct bt_field *`, owned by this */
+       GPtrArray *fields;
+};
+
+struct bt_field_variant {
+       struct bt_field common;
+
+       /* Weak: belongs to `fields` below */
+       struct bt_field *selected_field;
+
+       /* Index of currently selected field */
+       uint64_t selected_index;
+
+       /* Array of `struct bt_field *`, owned by this */
+       GPtrArray *fields;
+};
+
+struct bt_field_array {
+       struct bt_field common;
+
+       /* Array of `struct bt_field *`, owned by this */
+       GPtrArray *fields;
+
+       /* Current effective length */
+       uint64_t length;
+};
+
+struct bt_field_string {
+       struct bt_field common;
+       GArray *buf;
+       uint64_t length;
+};
+
+#ifdef BT_DEV_MODE
+# define bt_field_set_is_frozen                _bt_field_set_is_frozen
+# define bt_field_is_set               _bt_field_is_set
+# define bt_field_reset                        _bt_field_reset
+# define bt_field_set_single           _bt_field_set_single
+#else
+# define bt_field_set_is_frozen(_field, _is_frozen)
+# define bt_field_is_set(_field)       (BT_FALSE)
+# define bt_field_reset(_field)
+# define bt_field_set_single(_field, _val)
+#endif
+
+BT_HIDDEN
+void _bt_field_set_is_frozen(struct bt_field *field, bool is_frozen);
+
+static inline
+void _bt_field_reset(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       BT_ASSERT(field->methods->reset);
+       field->methods->reset(field);
+}
+
+static inline
+void _bt_field_set_single(struct bt_field *field, bool value)
+{
+       BT_ASSERT(field);
+       field->is_set = value;
+}
+
+static inline
+bt_bool _bt_field_is_set(struct bt_field *field)
+{
+       bt_bool is_set = BT_FALSE;
+
+       if (!field) {
+               goto end;
+       }
+
+       BT_ASSERT(bt_field_type_has_known_id(field->type));
+       BT_ASSERT(field->methods->is_set);
+       is_set = field->methods->is_set(field);
+
+end:
+       return is_set;
+}
+
+BT_HIDDEN
+struct bt_field *bt_field_create(struct bt_field_type *type);
+
+BT_HIDDEN
+void bt_field_destroy(struct bt_field *field);
+
+#endif /* BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/fields.h b/include/babeltrace/trace-ir/fields.h
new file mode 100644 (file)
index 0000000..99a6aa5
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef BABELTRACE_TRACE_IR_FIELDS_H
+#define BABELTRACE_TRACE_IR_FIELDS_H
+
+/*
+ * Babeltrace - Trace IR: Event Fields
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+/* For enum bt_field_type_id */
+#include <babeltrace/trace-ir/field-types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_field;
+struct bt_field_type;
+struct bt_field_type_enumeration_mapping_iterator;
+
+extern struct bt_field_type *bt_field_borrow_type(struct bt_field *field);
+
+extern enum bt_field_type_id bt_field_get_type_id(struct bt_field *field);
+
+extern int64_t bt_field_signed_integer_get_value(struct bt_field *field);
+
+extern void bt_field_signed_integer_set_value(struct bt_field *field,
+               int64_t value);
+
+extern uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field);
+
+extern void bt_field_unsigned_integer_set_value(struct bt_field *field,
+               uint64_t value);
+
+extern double bt_field_real_get_value(struct bt_field *field);
+
+extern void bt_field_real_set_value(struct bt_field *field, double value);
+
+extern int bt_field_unsigned_enumeration_get_mapping_labels(
+               struct bt_field *field,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count);
+
+extern int bt_field_signed_enumeration_get_mapping_labels(
+               struct bt_field *field,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count);
+
+extern const char *bt_field_string_get_value(struct bt_field *field);
+
+extern uint64_t bt_field_string_get_length(struct bt_field *field);
+
+extern int bt_field_string_set_value(struct bt_field *field, const char *value);
+
+extern int bt_field_string_append(struct bt_field *field, const char *value);
+
+extern int bt_field_string_append_with_length(struct bt_field *field,
+               const char *value, uint64_t length);
+
+extern int bt_field_string_clear(struct bt_field *field);
+
+extern struct bt_field *bt_field_structure_borrow_member_field_by_index(
+               struct bt_field *field, uint64_t index);
+
+extern struct bt_field *bt_field_structure_borrow_member_field_by_name(
+               struct bt_field *field, const char *name);
+
+extern uint64_t bt_field_array_get_length(struct bt_field *field);
+
+extern struct bt_field *bt_field_array_borrow_element_field_by_index(
+               struct bt_field *field, uint64_t index);
+
+extern int bt_field_dynamic_array_set_length(struct bt_field *field,
+               uint64_t length);
+
+extern int bt_field_variant_select_option_field(struct bt_field *field,
+               uint64_t index);
+
+extern uint64_t bt_field_variant_get_selected_option_field_index(
+               struct bt_field *field);
+
+extern struct bt_field *bt_field_variant_borrow_selected_option_field(
+               struct bt_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_FIELDS_H */
diff --git a/include/babeltrace/trace-ir/packet-context-field.h b/include/babeltrace/trace-ir/packet-context-field.h
new file mode 100644 (file)
index 0000000..b21f82b
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H
+#define BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream_class;
+struct bt_packet_context_field;
+struct bt_field;
+
+extern
+struct bt_packet_context_field *bt_packet_context_field_create(
+               struct bt_stream_class *stream_class);
+
+extern
+struct bt_field *bt_packet_context_field_borrow_field(
+               struct bt_packet_context_field *field);
+
+extern
+void bt_packet_context_field_release(struct bt_packet_context_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_CONTEXT_FIELD_H */
diff --git a/include/babeltrace/trace-ir/packet-header-field.h b/include/babeltrace/trace-ir/packet-header-field.h
new file mode 100644 (file)
index 0000000..605b1b8
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H
+#define BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H
+
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_packet_header_field;
+struct bt_field;
+
+extern
+struct bt_packet_header_field *bt_packet_header_field_create(
+               struct bt_trace *trace);
+
+extern
+struct bt_field *bt_packet_header_field_borrow_field(
+               struct bt_packet_header_field *field);
+
+extern
+void bt_packet_header_field_release(struct bt_packet_header_field *field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_HEADER_FIELD_H */
diff --git a/include/babeltrace/trace-ir/packet-internal.h b/include/babeltrace/trace-ir/packet-internal.h
new file mode 100644 (file)
index 0000000..ec709a3
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef BABELTRACE_TRACE_IR_PACKET_INTERNAL_H
+#define BABELTRACE_TRACE_IR_PACKET_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Stream packet internal
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/property-internal.h>
+
+struct bt_packet {
+       struct bt_object base;
+       struct bt_field_wrapper *header_field;
+       struct bt_field_wrapper *context_field;
+       struct bt_stream *stream;
+       struct bt_clock_value *default_beginning_cv;
+       struct bt_clock_value *default_end_cv;
+       struct bt_property_uint discarded_event_counter_snapshot;
+       struct bt_property_uint packet_counter_snapshot;
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen);
+
+#ifdef BT_DEV_MODE
+# define bt_packet_set_is_frozen       _bt_packet_set_is_frozen
+#else
+# define bt_packet_set_is_frozen(_packet, _is_frozen)
+#endif /* BT_DEV_MODE */
+
+BT_HIDDEN
+struct bt_packet *bt_packet_new(struct bt_stream *stream);
+
+BT_HIDDEN
+void bt_packet_recycle(struct bt_packet *packet);
+
+BT_HIDDEN
+void bt_packet_destroy(struct bt_packet *packet);
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/packet.h b/include/babeltrace/trace-ir/packet.h
new file mode 100644 (file)
index 0000000..1573016
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef BABELTRACE_TRACE_IR_PACKET_H
+#define BABELTRACE_TRACE_IR_PACKET_H
+
+/*
+ * BabelTrace - Trace IR: Stream packet
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+/* For enum bt_clock_value_status */
+#include <babeltrace/trace-ir/clock-value.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_packet;
+struct bt_packet_header_field;
+struct bt_packet_context_field;
+struct bt_stream;
+struct bt_clock_value;
+
+extern struct bt_packet *bt_packet_create(struct bt_stream *stream);
+
+extern struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet);
+
+extern
+struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet);
+
+extern
+int bt_packet_move_header_field(struct bt_packet *packet,
+               struct bt_packet_header_field *header);
+
+extern
+struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet);
+
+extern
+int bt_packet_move_context_field(struct bt_packet *packet,
+               struct bt_packet_context_field *context);
+
+extern
+enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
+               struct bt_packet *packet, struct bt_clock_value **clock_value);
+
+extern
+int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
+               uint64_t value_cycles);
+
+extern
+enum bt_clock_value_status bt_packet_borrow_default_end_clock_valeu(
+               struct bt_packet *packet, struct bt_clock_value **clock_value);
+
+extern
+int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
+               uint64_t value_cycles);
+
+extern
+enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
+               struct bt_packet *packet, uint64_t *value);
+
+extern
+int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
+               uint64_t value);
+
+extern
+enum bt_property_availability bt_packet_get_packet_counter_snapshot(
+               struct bt_packet *packet, uint64_t *value);
+
+extern
+int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
+               uint64_t value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_PACKET_H */
diff --git a/include/babeltrace/trace-ir/resolve-field-path-internal.h b/include/babeltrace/trace-ir/resolve-field-path-internal.h
new file mode 100644 (file)
index 0000000..dafe50d
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL
+#define BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL
+
+/*
+ * BabelTrace - Trace IR: Field path
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <glib.h>
+
+struct bt_resolve_field_path_context {
+       struct bt_field_type *packet_header;
+       struct bt_field_type *packet_context;
+       struct bt_field_type *event_header;
+       struct bt_field_type *event_common_context;
+       struct bt_field_type *event_specific_context;
+       struct bt_field_type *event_payload;
+};
+
+BT_HIDDEN
+int bt_resolve_field_paths(struct bt_field_type *ft,
+               struct bt_resolve_field_path_context *ctx);
+
+#endif /* BABELTRACE_TRACE_IR_RESOLVE_FIELD_PATH_INTERNAL */
diff --git a/include/babeltrace/trace-ir/resolve-internal.h b/include/babeltrace/trace-ir/resolve-internal.h
new file mode 100644 (file)
index 0000000..85c0c87
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H
+
+/*
+ * Babeltrace - Trace IR: Type resolving internal
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Authors: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *          Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+
+enum bt_resolve_flag {
+       BT_RESOLVE_FLAG_PACKET_HEADER           = 0x01,
+       BT_RESOLVE_FLAG_PACKET_CONTEXT          = 0x02,
+       BT_RESOLVE_FLAG_EVENT_HEADER            = 0x04,
+       BT_RESOLVE_FLAG_STREAM_EVENT_CTX        = 0x08,
+       BT_RESOLVE_FLAG_EVENT_CONTEXT           = 0x10,
+       BT_RESOLVE_FLAG_EVENT_PAYLOAD           = 0x20,
+};
+
+/*
+ * Resolves Trace IR field types: recursively locates the tag and length
+ * field types of resp. variant and sequence field types.
+ *
+ * All `*_type` parameters may be resolved, and may as well serve as
+ * resolving targets.
+ *
+ * Resolving is performed based on the flags in `flags`.
+ *
+ * It is expected that, amongst all the provided types, no common
+ * references to sequence variant field types exist. In other words,
+ * this function does not copy field types.
+ *
+ * All parameters are owned by the caller.
+ */
+BT_HIDDEN
+int bt_resolve_types(struct bt_value *environment,
+               struct bt_field_type *packet_header_type,
+               struct bt_field_type *packet_context_type,
+               struct bt_field_type *event_header_type,
+               struct bt_field_type *stream_event_ctx_type,
+               struct bt_field_type *event_context_type,
+               struct bt_field_type *event_payload_type,
+               enum bt_resolve_flag flags);
+
+#endif /* BABELTRACE_TRACE_IR_RESOLVE_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/stream-class-internal.h b/include/babeltrace/trace-ir/stream-class-internal.h
new file mode 100644 (file)
index 0000000..f3f8a62
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Stream class internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/common-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+#include <inttypes.h>
+
+struct bt_stream_class {
+       struct bt_object base;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } name;
+
+       uint64_t id;
+       bool assigns_automatic_event_class_id;
+       bool assigns_automatic_stream_id;
+       bool packets_have_discarded_event_counter_snapshot;
+       bool packets_have_packet_counter_snapshot;
+       bool packets_have_default_beginning_cv;
+       bool packets_have_default_end_cv;
+       struct bt_field_type *packet_context_ft;
+       struct bt_field_type *event_header_ft;
+       struct bt_field_type *event_common_context_ft;
+       struct bt_clock_class *default_clock_class;
+
+       /* Array of `struct bt_event_class *` */
+       GPtrArray *event_classes;
+
+       /* Pool of `struct bt_field_wrapper *` */
+       struct bt_object_pool event_header_field_pool;
+
+       /* Pool of `struct bt_field_wrapper *` */
+       struct bt_object_pool packet_context_field_pool;
+
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_stream_class_freeze(struct bt_stream_class *stream_class);
+
+#ifdef BT_DEV_MODE
+# define bt_stream_class_freeze                _bt_stream_class_freeze
+#else
+# define bt_stream_class_freeze(_sc)
+#endif
+
+static inline
+struct bt_trace *bt_stream_class_borrow_trace_inline(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT(stream_class);
+       return (void *) bt_object_borrow_parent(&stream_class->base);
+}
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_CLASS_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/stream-class.h b/include/babeltrace/trace-ir/stream-class.h
new file mode 100644 (file)
index 0000000..f071244
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef BABELTRACE_TRACE_IR_STREAM_CLASS_H
+#define BABELTRACE_TRACE_IR_STREAM_CLASS_H
+
+/*
+ * BabelTrace - Trace IR: Stream Class
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+
+/* For bt_bool */
+#include <babeltrace/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_stream_class;
+struct bt_event_class;
+struct bt_clock_class;
+struct bt_event_header_field;
+struct bt_packet_context_field;
+
+extern struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace);
+
+extern struct bt_stream_class *bt_stream_class_create_with_id(
+               struct bt_trace *trace, uint64_t id);
+
+extern struct bt_trace *bt_stream_class_borrow_trace(
+               struct bt_stream_class *stream_class);
+
+extern const char *bt_stream_class_get_name(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_name(struct bt_stream_class *stream_class,
+               const char *name);
+
+extern bt_bool bt_stream_class_assigns_automatic_event_class_id(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_assigns_automatic_event_class_id(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_assigns_automatic_stream_id(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_assigns_automatic_stream_id(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+extern uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class);
+
+extern struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packet_context_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type);
+
+extern struct bt_field_type *
+bt_stream_class_borrow_event_header_field_type(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_event_header_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type);
+
+extern struct bt_field_type *
+bt_stream_class_borrow_event_common_context_field_type(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_event_common_context_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type);
+
+extern uint64_t bt_stream_class_get_event_class_count(
+               struct bt_stream_class *stream_class);
+
+extern struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
+               struct bt_stream_class *stream_class, uint64_t index);
+
+extern struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
+               struct bt_stream_class *stream_class, uint64_t id);
+
+extern int bt_stream_class_set_default_clock_class(
+               struct bt_stream_class *stream_class,
+               struct bt_clock_class *clock_class);
+
+extern struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
+               struct bt_stream_class *stream_class);
+
+extern bt_bool bt_stream_class_default_clock_is_always_known(
+               struct bt_stream_class *stream_class);
+
+extern bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_packet_counter_snapshot(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_default_beginning_clock_value(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+extern bt_bool bt_stream_class_packets_have_default_end_clock_value(
+               struct bt_stream_class *stream_class);
+
+extern int bt_stream_class_set_packets_have_default_end_clock_value(
+               struct bt_stream_class *stream_class, bt_bool value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_CLASS_H */
diff --git a/include/babeltrace/trace-ir/stream-internal.h b/include/babeltrace/trace-ir/stream-internal.h
new file mode 100644 (file)
index 0000000..cdb87ac
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef BABELTRACE_TRACE_IR_STREAM_INTERNAL_H
+#define BABELTRACE_TRACE_IR_STREAM_INTERNAL_H
+
+/*
+ * BabelTrace - CTF Writer: Stream internal
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <glib.h>
+
+struct bt_stream_class;
+struct bt_stream;
+
+struct bt_stream {
+       struct bt_object base;
+
+       /* Weak: parent is this class's trace */
+       struct bt_stream_class *class;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } name;
+
+       uint64_t id;
+
+       /* Pool of `struct bt_packet *` */
+       struct bt_object_pool packet_pool;
+
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_stream_freeze(struct bt_stream *stream);
+
+#ifdef BT_DEV_MODE
+# define bt_stream_freeze              _bt_stream_freeze
+#else
+# define bt_stream_freeze(_stream)
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/stream.h b/include/babeltrace/trace-ir/stream.h
new file mode 100644 (file)
index 0000000..839c0a3
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef BABELTRACE_TRACE_IR_STREAM_H
+#define BABELTRACE_TRACE_IR_STREAM_H
+
+/*
+ * BabelTrace - Trace IR: Stream
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For enum bt_property_availability */
+#include <babeltrace/property.h>
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_stream;
+struct bt_stream_class;
+
+extern struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class);
+
+extern struct bt_stream *bt_stream_create_with_id(
+               struct bt_stream_class *stream_class, uint64_t id);
+
+extern struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream);
+
+extern const char *bt_stream_get_name(struct bt_stream *stream);
+
+extern int bt_stream_set_name(struct bt_stream *stream, const char *name);
+
+extern uint64_t bt_stream_get_id(struct bt_stream *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_STREAM_H */
diff --git a/include/babeltrace/trace-ir/trace-internal.h b/include/babeltrace/trace-ir/trace-internal.h
new file mode 100644 (file)
index 0000000..f829d59
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef BABELTRACE_TRACE_IR_TRACE_INTERNAL_H
+#define BABELTRACE_TRACE_IR_TRACE_INTERNAL_H
+
+/*
+ * BabelTrace - Trace IR: Trace internal
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/types.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <babeltrace/compat/uuid-internal.h>
+
+struct bt_trace {
+       struct bt_object base;
+
+       struct {
+               GString *str;
+
+               /* NULL or `str->str` above */
+               const char *value;
+       } name;
+
+       struct {
+               uint8_t uuid[BABELTRACE_UUID_LEN];
+
+               /* NULL or `uuid` above */
+               bt_uuid value;
+       } uuid;
+
+       struct bt_value *environment;
+
+       /* Array of `struct bt_stream_class *` */
+       GPtrArray *stream_classes;
+
+       /* Array of `struct bt_stream *` */
+       GPtrArray *streams;
+
+       /*
+        * Stream class (weak) to number of instantiated streams, used
+        * to automatically assign stream IDs per stream class.
+        */
+       GHashTable *stream_classes_stream_count;
+
+       struct bt_field_type *packet_header_ft;
+       bool assigns_automatic_stream_class_id;
+
+       GArray *is_static_listeners;
+       bool is_static;
+       bool in_remove_listener;
+
+       /* Pool of `struct bt_field_wrapper *` */
+       struct bt_object_pool packet_header_field_pool;
+
+       bool frozen;
+};
+
+BT_HIDDEN
+void _bt_trace_freeze(struct bt_trace *trace);
+
+#ifdef BT_DEV_MODE
+# define bt_trace_freeze               _bt_trace_freeze
+#else
+# define bt_trace_freeze(_trace)
+#endif
+
+BT_HIDDEN
+void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream);
+
+BT_HIDDEN
+uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
+               struct bt_stream_class *stream_class);
+
+#endif /* BABELTRACE_TRACE_IR_TRACE_INTERNAL_H */
diff --git a/include/babeltrace/trace-ir/trace.h b/include/babeltrace/trace-ir/trace.h
new file mode 100644 (file)
index 0000000..cb34063
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef BABELTRACE_TRACE_IR_TRACE_H
+#define BABELTRACE_TRACE_IR_TRACE_H
+
+/*
+ * BabelTrace - Trace IR: Trace
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+/* For bt_bool, bt_uuid */
+#include <babeltrace/types.h>
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct bt_trace;
+struct bt_stream;
+struct bt_stream_class;
+struct bt_field_type;
+struct bt_value;
+struct bt_packet_header_field;
+
+typedef void (* bt_trace_is_static_listener)(
+       struct bt_trace *trace, void *data);
+
+typedef void (* bt_trace_listener_removed)(
+       struct bt_trace *trace, void *data);
+
+extern struct bt_trace *bt_trace_create(void);
+
+extern bt_bool bt_trace_assigns_automatic_stream_class_id(
+               struct bt_trace *trace);
+
+extern int bt_trace_set_assigns_automatic_stream_class_id(
+               struct bt_trace *trace, bt_bool value);
+
+extern const char *bt_trace_get_name(struct bt_trace *trace);
+
+extern int bt_trace_set_name(struct bt_trace *trace, const char *name);
+
+extern bt_uuid bt_trace_get_uuid(struct bt_trace *trace);
+
+extern int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid);
+
+extern uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace);
+
+extern void bt_trace_borrow_environment_entry_by_index(
+               struct bt_trace *trace, uint64_t index,
+               const char **name, struct bt_value **value);
+
+extern struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
+               struct bt_trace *trace, const char *name);
+
+extern int bt_trace_set_environment_entry_integer(
+               struct bt_trace *trace, const char *name,
+               int64_t value);
+
+extern int bt_trace_set_environment_entry_string(
+               struct bt_trace *trace, const char *name,
+               const char *value);
+
+extern struct bt_field_type *bt_trace_borrow_packet_header_field_type(
+               struct bt_trace *trace);
+
+extern int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
+               struct bt_field_type *packet_header_type);
+
+extern uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace);
+
+extern struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
+               struct bt_trace *trace, uint64_t index);
+
+extern struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
+               struct bt_trace *trace, uint64_t id);
+
+extern uint64_t bt_trace_get_stream_count(struct bt_trace *trace);
+
+extern struct bt_stream *bt_trace_borrow_stream_by_index(
+               struct bt_trace *trace, uint64_t index);
+
+extern struct bt_stream *bt_trace_borrow_stream_by_id(
+               struct bt_trace *trace, uint64_t id);
+
+extern bt_bool bt_trace_is_static(struct bt_trace *trace);
+
+extern int bt_trace_make_static(struct bt_trace *trace);
+
+extern int bt_trace_add_is_static_listener(
+               struct bt_trace *trace,
+               bt_trace_is_static_listener listener,
+               bt_trace_listener_removed listener_removed, void *data,
+               uint64_t *listener_id);
+
+extern int bt_trace_remove_is_static_listener(
+               struct bt_trace *trace, uint64_t listener_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE_TRACE_IR_TRACE_H */
diff --git a/include/babeltrace/trace-ir/utils-internal.h b/include/babeltrace/trace-ir/utils-internal.h
new file mode 100644 (file)
index 0000000..4c3f8c0
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
+#define BABELTRACE_TRACE_IR_UTILS_INTERNAL_H
+
+/*
+ * Babeltrace - Internal Trace IR utilities
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <stdint.h>
+
+struct search_query {
+       gpointer value;
+       int found;
+};
+
+static inline
+uint64_t bt_util_ns_from_value(uint64_t frequency, uint64_t value_cycles)
+{
+       uint64_t ns;
+
+       if (frequency == UINT64_C(1000000000)) {
+               ns = value_cycles;
+       } else {
+               double dblres = ((1e9 * (double) value_cycles) / (double) frequency);
+
+               if (dblres >= (double) UINT64_MAX) {
+                       /* Overflows uint64_t */
+                       ns = UINT64_C(-1);
+               } else {
+                       ns = (uint64_t) dblres;
+               }
+       }
+
+       return ns;
+}
+
+static inline
+int bt_util_ns_from_origin(struct bt_clock_class *clock_class, uint64_t value,
+               int64_t *ns_from_origin)
+{
+       int ret = 0;
+       uint64_t value_ns_unsigned;
+       int64_t value_ns_signed;
+
+       if (clock_class->base_offset.overflows) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Initialize to clock class's base offset */
+       *ns_from_origin = clock_class->base_offset.value_ns;
+
+       /* Add given value in cycles */
+       value_ns_unsigned = bt_util_ns_from_value(clock_class->frequency, value);
+       if (value_ns_unsigned >= (uint64_t) INT64_MAX) {
+               /*
+                * FIXME: `value_ns_unsigned` could be greater than
+                * `INT64_MAX` in fact: in this case, we need to
+                * subtract `INT64_MAX` from `value_ns_unsigned`, make
+                * sure that the difference is less than `INT64_MAX`,
+                * and try to add them one after the other to
+                * `*ns_from_origin`.
+                */
+               ret = -1;
+               goto end;
+       }
+
+       value_ns_signed = (int64_t) value_ns_unsigned;
+       BT_ASSERT(value_ns_signed >= 0);
+
+       if (*ns_from_origin <= 0) {
+               goto add_value;
+       }
+
+       if (value_ns_signed > INT64_MAX - *ns_from_origin) {
+               ret = -1;
+               goto end;
+       }
+
+add_value:
+       *ns_from_origin += value_ns_signed;
+
+end:
+       return ret;
+}
+
+static inline
+bool bt_util_value_is_in_range_signed(uint64_t size, int64_t value)
+{
+       int64_t min_value = UINT64_C(-1) << (size - 1);
+       int64_t max_value = (UINT64_C(1) << (size - 1)) - 1;
+       return value >= min_value && value <= max_value;
+}
+
+static inline
+bool bt_util_value_is_in_range_unsigned(unsigned int size, uint64_t value)
+{
+       uint64_t max_value = (size == 64) ? UINT64_MAX :
+               (UINT64_C(1) << size) - 1;
+       return value <= max_value;
+}
+
+#endif /* BABELTRACE_TRACE_IR_UTILS_INTERNAL_H */
index 121279a2b57b0a37f87bc73e3d70dacba3b46ade..04ece47438e82d2a1bb0ec1053775c610ad82446 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = ctf-ir ctf-writer prio_heap plugin graph .
+SUBDIRS = trace-ir ctf-writer prio_heap plugin graph .
 
 lib_LTLIBRARIES = libbabeltrace.la libbabeltrace-ctf.la
 
@@ -16,7 +16,7 @@ libbabeltrace_la_LIBADD = \
        prio_heap/libprio_heap.la \
        graph/libgraph.la \
        plugin/libplugin.la \
-       ctf-ir/libctf-ir.la \
+       trace-ir/libtrace-ir.la \
        ctf-writer/libctf-writer.la \
        $(top_builddir)/logging/libbabeltrace-logging.la \
        $(top_builddir)/common/libbabeltrace-common.la \
@@ -36,7 +36,7 @@ libbabeltrace_ctf_la_LDFLAGS = $(LT_NO_UNDEFINED) \
 
 libbabeltrace_ctf_la_LIBADD = \
        graph/libgraph.la \
-       ctf-ir/libctf-ir.la \
+       trace-ir/libtrace-ir.la \
        ctf-writer/libctf-writer.la \
        $(top_builddir)/logging/libbabeltrace-logging.la \
        $(top_builddir)/common/libbabeltrace-common.la \
diff --git a/lib/ctf-ir/Makefile.am b/lib/ctf-ir/Makefile.am
deleted file mode 100644 (file)
index dda79a6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-noinst_LTLIBRARIES = libctf-ir.la
-
-libctf_ir_la_SOURCES = \
-       attributes.c \
-       clock-class.c \
-       clock-value.c \
-       event.c \
-       event-class.c \
-       event-header-field.c \
-       field-wrapper.c \
-       fields.c \
-       field-types.c \
-       field-path.c \
-       packet.c \
-       packet-context-field.c \
-       packet-header-field.c \
-       resolve-field-path.c \
-       stream.c \
-       stream-class.c \
-       trace.c \
-       utils.c
-
-libctf_ir_la_LIBADD = $(UUID_LIBS)
diff --git a/lib/ctf-ir/attributes.c b/lib/ctf-ir/attributes.c
deleted file mode 100644 (file)
index ccd93b1..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * attributes.c
- *
- * Babeltrace CTF IR - Attributes
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "ATTRS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/ref.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/values-internal.h>
-#include <inttypes.h>
-#include <babeltrace/compat/string-internal.h>
-#include <babeltrace/assert-internal.h>
-
-#define BT_ATTR_NAME_INDEX             0
-#define BT_ATTR_VALUE_INDEX            1
-
-BT_HIDDEN
-struct bt_value *bt_attributes_create(void)
-{
-       struct bt_value *attr_obj;
-
-       /*
-        * Attributes: array value object of array value objects, each one
-        * containing two entries: a string value object (attributes
-        * field name), and a value object (attributes field value).
-        *
-        * Example (JSON representation):
-        *
-        *     [
-        *         ["hostname", "eeppdesk"],
-        *         ["sysname", "Linux"],
-        *         ["tracer_major", 2],
-        *         ["tracer_minor", 5]
-        *     ]
-        */
-       BT_LOGD_STR("Creating attributes object.");
-       attr_obj = bt_value_array_create();
-       if (!attr_obj) {
-               BT_LOGE_STR("Failed to create array value.");
-       } else {
-               BT_LOGD("Created attributes object: addr=%p",
-                       attr_obj);
-       }
-
-       return attr_obj;
-}
-
-BT_HIDDEN
-void bt_attributes_destroy(struct bt_value *attr_obj)
-{
-       BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
-       bt_put(attr_obj);
-}
-
-BT_HIDDEN
-int64_t bt_attributes_get_count(struct bt_value *attr_obj)
-{
-       return bt_value_array_size(attr_obj);
-}
-
-BT_HIDDEN
-const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
-               uint64_t index)
-{
-       int rc;
-       const char *ret = NULL;
-       struct bt_value *attr_field_obj = NULL;
-       struct bt_value *attr_field_name_obj = NULL;
-
-       if (!attr_obj) {
-               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
-               goto end;
-       }
-
-       if (index >= bt_value_array_size(attr_obj)) {
-               BT_LOGW("Invalid parameter: index is out of bounds: "
-                       "index=%" PRIu64 ", count=%" PRId64,
-                       index, bt_value_array_size(attr_obj));
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_borrow(attr_obj, index);
-       if (!attr_field_obj) {
-               BT_LOGE("Cannot get attributes object's array value's element by index: "
-                       "value-addr=%p, index=%" PRIu64, attr_obj, index);
-               goto end;
-       }
-
-       attr_field_name_obj = bt_value_array_borrow(attr_field_obj,
-               BT_ATTR_NAME_INDEX);
-       if (!attr_field_name_obj) {
-               BT_LOGE("Cannot get attribute array value's element by index: "
-                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
-                       (uint64_t) BT_ATTR_NAME_INDEX);
-               goto end;
-       }
-
-       rc = bt_value_string_get(attr_field_name_obj, &ret);
-       if (rc) {
-               BT_LOGE("Cannot get raw value from string value: value-addr=%p",
-                       attr_field_name_obj);
-               ret = NULL;
-       }
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
-               uint64_t index)
-{
-       struct bt_value *value_obj = NULL;
-       struct bt_value *attr_field_obj = NULL;
-
-       if (!attr_obj) {
-               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
-               goto end;
-       }
-
-       if (index >= bt_value_array_size(attr_obj)) {
-               BT_LOGW("Invalid parameter: index is out of bounds: "
-                       "index=%" PRIu64 ", count=%" PRId64,
-                       index, bt_value_array_size(attr_obj));
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_borrow(attr_obj, index);
-       if (!attr_field_obj) {
-               BT_LOGE("Cannot get attributes object's array value's element by index: "
-                       "value-addr=%p, index=%" PRIu64, attr_obj, index);
-               goto end;
-       }
-
-       value_obj = bt_value_array_borrow(attr_field_obj,
-               BT_ATTR_VALUE_INDEX);
-       if (!value_obj) {
-               BT_LOGE("Cannot get attribute array value's element by index: "
-                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
-                       (uint64_t) BT_ATTR_VALUE_INDEX);
-       }
-
-end:
-       return value_obj;
-}
-
-static
-struct bt_value *bt_attributes_borrow_field_by_name(
-               struct bt_value *attr_obj, const char *name)
-{
-       uint64_t i;
-       int64_t attr_size;
-       struct bt_value *value_obj = NULL;
-       struct bt_value *attr_field_name_obj = NULL;
-
-       attr_size = bt_value_array_size(attr_obj);
-       if (attr_size < 0) {
-               BT_LOGE("Cannot get array value's size: value-addr=%p",
-                       attr_obj);
-               goto error;
-       }
-
-       for (i = 0; i < attr_size; ++i) {
-               int ret;
-               const char *field_name;
-
-               value_obj = bt_value_array_borrow(attr_obj, i);
-               if (!value_obj) {
-                       BT_LOGE("Cannot get attributes object's array value's element by index: "
-                               "value-addr=%p, index=%" PRIu64, attr_obj, i);
-                       goto error;
-               }
-
-               attr_field_name_obj = bt_value_array_borrow(value_obj,
-                       BT_ATTR_NAME_INDEX);
-               if (!attr_field_name_obj) {
-                       BT_LOGE("Cannot get attribute array value's element by index: "
-                               "value-addr=%p, index=%" PRIu64,
-                               value_obj, (int64_t) BT_ATTR_NAME_INDEX);
-                       goto error;
-               }
-
-               ret = bt_value_string_get(attr_field_name_obj, &field_name);
-               if (ret) {
-                       BT_LOGE("Cannot get raw value from string value: value-addr=%p",
-                               attr_field_name_obj);
-                       goto error;
-               }
-
-               if (!strcmp(field_name, name)) {
-                       break;
-               }
-
-               value_obj = NULL;
-       }
-
-       return value_obj;
-
-error:
-       value_obj = NULL;
-       return value_obj;
-}
-
-BT_HIDDEN
-int bt_attributes_set_field_value(struct bt_value *attr_obj,
-               const char *name, struct bt_value *value_obj)
-{
-       int ret = 0;
-       struct bt_value *attr_field_obj = NULL;
-
-       if (!attr_obj || !name || !value_obj) {
-               BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
-                       "attr-value-addr=%p, name-addr=%p, value-addr=%p",
-                       attr_obj, name, value_obj);
-               ret = -1;
-               goto end;
-       }
-
-       attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
-       if (attr_field_obj) {
-               ret = bt_value_array_set(attr_field_obj,
-                       BT_ATTR_VALUE_INDEX, value_obj);
-               attr_field_obj = NULL;
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_create();
-       if (!attr_field_obj) {
-               BT_LOGE_STR("Failed to create empty array value.");
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_value_array_append_string(attr_field_obj, name);
-       ret |= bt_value_array_append(attr_field_obj, value_obj);
-       if (ret) {
-               BT_LOGE("Cannot append elements to array value: addr=%p",
-                       attr_field_obj);
-               goto end;
-       }
-
-       ret = bt_value_array_append(attr_obj, attr_field_obj);
-       if (ret) {
-               BT_LOGE("Cannot append element to array value: "
-                       "array-value-addr=%p, element-value-addr=%p",
-                       attr_obj, attr_field_obj);
-       }
-
-end:
-       bt_put(attr_field_obj);
-       return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_attributes_borrow_field_value_by_name(
-               struct bt_value *attr_obj, const char *name)
-{
-       struct bt_value *value_obj = NULL;
-       struct bt_value *attr_field_obj = NULL;
-
-       if (!attr_obj || !name) {
-               BT_LOGW("Invalid parameter: attributes object or name is NULL: "
-                       "value-addr=%p, name-addr=%p", attr_obj, name);
-               goto end;
-       }
-
-       attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
-       if (!attr_field_obj) {
-               BT_LOGD("Cannot find attributes object's field by name: "
-                       "value-addr=%p, name=\"%s\"", attr_obj, name);
-               goto end;
-       }
-
-       value_obj = bt_value_array_borrow(attr_field_obj,
-               BT_ATTR_VALUE_INDEX);
-       if (!value_obj) {
-               BT_LOGE("Cannot get attribute array value's element by index: "
-                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
-                       (uint64_t) BT_ATTR_VALUE_INDEX);
-       }
-
-end:
-       return value_obj;
-}
-
-BT_HIDDEN
-int bt_attributes_freeze(struct bt_value *attr_obj)
-{
-       uint64_t i;
-       int64_t count;
-       int ret = 0;
-
-       if (!attr_obj) {
-               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
-               ret = -1;
-               goto end;
-       }
-
-       BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
-       count = bt_value_array_size(attr_obj);
-       BT_ASSERT(count >= 0);
-
-       /*
-        * We do not freeze the array value object itself here, since
-        * internal stuff could need to modify/add attributes. Each
-        * attribute is frozen one by one.
-        */
-       for (i = 0; i < count; ++i) {
-               struct bt_value *obj = NULL;
-
-               obj = bt_attributes_borrow_field_value(attr_obj, i);
-               if (!obj) {
-                       BT_LOGE("Cannot get attributes object's field value by index: "
-                               "value-addr=%p, index=%" PRIu64,
-                               attr_obj, i);
-                       ret = -1;
-                       goto end;
-               }
-
-               bt_value_freeze(obj);
-       }
-
-end:
-       return ret;
-}
diff --git a/lib/ctf-ir/clock-class.c b/lib/ctf-ir/clock-class.c
deleted file mode 100644 (file)
index e4d5341..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * clock-class.c
- *
- * Babeltrace CTF IR - Clock class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CLOCK-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/compat/string-internal.h>
-#include <inttypes.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-
-#define BT_ASSERT_PRE_CLOCK_CLASS_HOT(_cc) \
-       BT_ASSERT_PRE_HOT((_cc), "Clock class", ": %!+K", (_cc))
-
-static
-void destroy_clock_class(struct bt_object *obj)
-{
-       struct bt_clock_class *clock_class = (void *) obj;
-
-       BT_LIB_LOGD("Destroying clock class: %!+K", clock_class);
-
-       if (clock_class->name.str) {
-               g_string_free(clock_class->name.str, TRUE);
-       }
-
-       if (clock_class->description.str) {
-               g_string_free(clock_class->description.str, TRUE);
-       }
-
-       bt_object_pool_finalize(&clock_class->cv_pool);
-       g_free(clock_class);
-}
-
-static
-void free_clock_value(struct bt_clock_value *clock_value,
-               struct bt_clock_class *clock_class)
-{
-       bt_clock_value_destroy(clock_value);
-}
-
-static inline
-void set_base_offset(struct bt_clock_class *clock_class)
-{
-       uint64_t offset_cycles_ns;
-
-       /* Initialize nanosecond timestamp to clock's offset in seconds */
-       if (clock_class->offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
-                       clock_class->offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
-               /*
-                * Overflow: offset in seconds converted to nanoseconds
-                * is outside the int64_t range. We also subtract 1 here
-                * to leave "space" for the offset in cycles converted
-                * to nanoseconds (which is always less than 1 second by
-                * contract).
-                */
-               clock_class->base_offset.overflows = true;
-               goto end;
-       }
-
-       /* Offset (seconds) to nanoseconds */
-       clock_class->base_offset.value_ns = clock_class->offset_seconds *
-               INT64_C(1000000000);
-
-       /* Add offset in cycles */
-       BT_ASSERT(clock_class->offset_cycles < clock_class->frequency);
-       offset_cycles_ns = bt_util_ns_from_value(clock_class->frequency,
-               clock_class->offset_cycles);
-       BT_ASSERT(offset_cycles_ns < 1000000000);
-       clock_class->base_offset.value_ns += (int64_t) offset_cycles_ns;
-       clock_class->base_offset.overflows = false;
-
-end:
-       return;
-}
-
-struct bt_clock_class *bt_clock_class_create(void)
-{
-       int ret;
-       struct bt_clock_class *clock_class = NULL;
-
-       BT_LOGD_STR("Creating default clock class object");
-
-       clock_class = g_new0(struct bt_clock_class, 1);
-       if (!clock_class) {
-               BT_LOGE_STR("Failed to allocate one clock class.");
-               goto error;
-       }
-
-       bt_object_init_shared(&clock_class->base, destroy_clock_class);
-       clock_class->name.str = g_string_new(NULL);
-       if (!clock_class->name.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               goto error;
-       }
-
-       clock_class->description.str = g_string_new(NULL);
-       if (!clock_class->description.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               goto error;
-       }
-
-       clock_class->frequency = UINT64_C(1000000000);
-       clock_class->is_absolute = BT_TRUE;
-       set_base_offset(clock_class);
-       ret = bt_object_pool_initialize(&clock_class->cv_pool,
-               (bt_object_pool_new_object_func) bt_clock_value_new,
-               (bt_object_pool_destroy_object_func)
-                       free_clock_value,
-               clock_class);
-       if (ret) {
-               BT_LOGE("Failed to initialize clock value pool: ret=%d",
-                       ret);
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created clock class object: %!+K", clock_class);
-       goto end;
-
-error:
-       BT_PUT(clock_class);
-
-end:
-       return clock_class;
-}
-
-const char *bt_clock_class_get_name(
-               struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return clock_class->name.value;
-}
-
-int bt_clock_class_set_name(struct bt_clock_class *clock_class,
-               const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       g_string_assign(clock_class->name.str, name);
-       clock_class->name.value = clock_class->name.str->str;
-       BT_LIB_LOGV("Set clock class's name: %!+K", clock_class);
-       return 0;
-}
-
-const char *bt_clock_class_get_description(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return clock_class->description.value;
-}
-
-int bt_clock_class_set_description(struct bt_clock_class *clock_class,
-               const char *descr)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(descr, "Description");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       g_string_assign(clock_class->description.str, descr);
-       clock_class->description.value = clock_class->description.str->str;
-       BT_LIB_LOGV("Set clock class's description: %!+K",
-               clock_class);
-       return 0;
-}
-
-uint64_t bt_clock_class_get_frequency(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return clock_class->frequency;
-}
-
-int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
-               uint64_t frequency)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       BT_ASSERT_PRE(frequency != UINT64_C(-1) && frequency != 0,
-               "Invalid frequency: %![cc-]+K, new-freq=%" PRIu64,
-               clock_class, frequency);
-       BT_ASSERT_PRE(clock_class->offset_cycles < frequency,
-               "Offset (cycles) is greater than clock class's frequency: "
-               "%![cc-]+K, new-freq=%" PRIu64, clock_class, frequency);
-       clock_class->frequency = frequency;
-       set_base_offset(clock_class);
-       BT_LIB_LOGV("Set clock class's frequency: %!+K", clock_class);
-       return 0;
-}
-
-uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return clock_class->precision;
-}
-
-int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
-               uint64_t precision)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       BT_ASSERT_PRE(precision != UINT64_C(-1),
-               "Invalid precision: %![cc-]+K, new-precision=%" PRIu64,
-               clock_class, precision);
-       clock_class->precision = precision;
-       BT_LIB_LOGV("Set clock class's precision: %!+K", clock_class);
-       return 0;
-}
-
-void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
-               int64_t *seconds, uint64_t *cycles)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(seconds, "Seconds (output)");
-       BT_ASSERT_PRE_NON_NULL(cycles, "Cycles (output)");
-       *seconds = clock_class->offset_seconds;
-       *cycles = clock_class->offset_cycles;
-}
-
-int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
-               int64_t seconds, uint64_t cycles)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       BT_ASSERT_PRE(cycles < clock_class->frequency,
-               "Offset (cycles) is greater than clock class's frequency: "
-               "%![cc-]+K, new-offset-cycles=%" PRIu64, clock_class, cycles);
-       clock_class->offset_seconds = seconds;
-       clock_class->offset_cycles = cycles;
-       set_base_offset(clock_class);
-       BT_LIB_LOGV("Set clock class's offset: %!+K", clock_class);
-       return 0;
-}
-
-bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return (bool) clock_class->is_absolute;
-}
-
-int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
-               bt_bool is_absolute)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       clock_class->is_absolute = (bool) is_absolute;
-       BT_LIB_LOGV("Set clock class's absolute property: %!+K",
-               clock_class);
-       return 0;
-}
-
-bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       return clock_class->uuid.value;
-}
-
-int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
-               bt_uuid uuid)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
-       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
-       memcpy(clock_class->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
-       clock_class->uuid.value = clock_class->uuid.uuid;
-       BT_LIB_LOGV("Set clock class's UUID: %!+K", clock_class);
-       return 0;
-}
-
-BT_HIDDEN
-void _bt_clock_class_freeze(struct bt_clock_class *clock_class)
-{
-       BT_ASSERT(clock_class);
-
-       if (clock_class->frozen) {
-               return;
-       }
-
-       BT_LIB_LOGD("Freezing clock class: %!+K", clock_class);
-       clock_class->frozen = 1;
-}
-
-int bt_clock_class_cycles_to_ns_from_origin(struct bt_clock_class *clock_class,
-               uint64_t cycles, int64_t *ns)
-{
-       int ret;
-
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(ns, "Nanoseconds (output)");
-       ret = bt_util_ns_from_origin(clock_class, cycles, ns);
-       if (ret) {
-               BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
-                       "from origin for given clock class: "
-                       "value overflows the signed 64-bit integer range: "
-                       "%![cc-]+K, cycles=%" PRIu64,
-                       clock_class, cycles);
-       }
-
-       return ret;
-}
diff --git a/lib/ctf-ir/clock-value.c b/lib/ctf-ir/clock-value.c
deleted file mode 100644 (file)
index 51c89dd..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CLOCK-VALUE"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/compat/uuid-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/compat/string-internal.h>
-#include <inttypes.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/assert-internal.h>
-
-BT_HIDDEN
-void bt_clock_value_destroy(struct bt_clock_value *clock_value)
-{
-       BT_LIB_LOGD("Destroying clock value: %!+k", clock_value);
-       bt_put(clock_value->clock_class);
-       g_free(clock_value);
-}
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class)
-{
-       struct bt_clock_value *ret = NULL;
-
-       BT_ASSERT(clock_class);
-       BT_LIB_LOGD("Creating clock value object: %![cc-]+K=",
-               clock_class);
-       ret = g_new0(struct bt_clock_value, 1);
-       if (!ret) {
-               BT_LOGE_STR("Failed to allocate one clock value.");
-               goto end;
-       }
-
-       bt_object_init_unique(&ret->base);
-       ret->clock_class = bt_get(clock_class);
-       bt_clock_class_freeze(clock_class);
-       BT_LIB_LOGD("Created clock value object: %!+k", ret);
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-struct bt_clock_value *bt_clock_value_create(struct bt_clock_class *clock_class)
-{
-       struct bt_clock_value *clock_value = NULL;
-
-       BT_ASSERT(clock_class);
-       clock_value = bt_object_pool_create_object(&clock_class->cv_pool);
-       if (!clock_value) {
-               BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
-                       "%![cc-]+K", clock_class);
-               goto error;
-       }
-
-       if (likely(!clock_value->clock_class)) {
-               clock_value->clock_class = bt_get(clock_class);
-       }
-
-       goto end;
-
-error:
-       if (clock_value) {
-               bt_clock_value_recycle(clock_value);
-               clock_value = NULL;
-       }
-
-end:
-       return clock_value;
-}
-
-BT_HIDDEN
-void bt_clock_value_recycle(struct bt_clock_value *clock_value)
-{
-       struct bt_clock_class *clock_class;
-
-       BT_ASSERT(clock_value);
-       BT_LIB_LOGD("Recycling clock value: %!+k", clock_value);
-
-       /*
-        * Those are the important ordered steps:
-        *
-        * 1. Reset the clock value object, but do NOT put its clock
-        *    class's reference. This clock class contains the pool to
-        *    which we're about to recycle this clock value object, so
-        *    we must guarantee its existence thanks to this existing
-        *    reference.
-        *
-        * 2. Move the clock class reference to our `clock_class`
-        *    variable so that we can set the clock value's clock class
-        *    member to NULL before recycling it. We CANNOT do this
-        *    after we put the clock class reference because this
-        *    bt_put() could destroy the clock class, also destroying
-        *    its clock value pool, thus also destroying our clock value
-        *    object (this would result in an invalid write access).
-        *
-        * 3. Recycle the clock value object.
-        *
-        * 4. Put our clock class reference.
-        */
-       bt_clock_value_reset(clock_value);
-       clock_class = clock_value->clock_class;
-       BT_ASSERT(clock_class);
-       clock_value->clock_class = NULL;
-       bt_object_pool_recycle_object(&clock_class->cv_pool, clock_value);
-       bt_put(clock_class);
-}
-
-uint64_t bt_clock_value_get_value(struct bt_clock_value *clock_value)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
-       BT_ASSERT_PRE(clock_value->is_set,
-               "Clock value is not set: %!+k", clock_value);
-       return clock_value->value_cycles;
-}
-
-int bt_clock_value_get_ns_from_origin(struct bt_clock_value *clock_value,
-               int64_t *ret_value_ns)
-{
-       int ret = 0;
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
-       BT_ASSERT_PRE_NON_NULL(ret_value_ns, "Value (ns) (output)");
-       BT_ASSERT_PRE(clock_value->is_set,
-               "Clock value is not set: %!+k", clock_value);
-
-       if (clock_value->ns_from_origin_overflows) {
-               BT_LIB_LOGD("Clock value, once converted to nanoseconds from origin, "
-                       "overflows the signed 64-bit integer range: "
-                       "%![cv-]+k", clock_value);
-               ret = -1;
-               goto end;
-       }
-
-       *ret_value_ns = clock_value->ns_from_origin;
-
-end:
-       return ret;
-}
-
-struct bt_clock_class *bt_clock_value_borrow_clock_class(
-               struct bt_clock_value *clock_value)
-{
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
-       return clock_value->clock_class;
-}
diff --git a/lib/ctf-ir/event-class.c b/lib/ctf-ir/event-class.c
deleted file mode 100644 (file)
index b882408..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * event-class.c
- *
- * Babeltrace CTF IR - Event class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/values-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-#define BT_ASSERT_PRE_EVENT_CLASS_HOT(_ec) \
-       BT_ASSERT_PRE_HOT((_ec), "Event class", ": %!+E", (_ec))
-
-static
-void destroy_event_class(struct bt_object *obj)
-{
-       struct bt_event_class *event_class = (void *) obj;
-
-       BT_LIB_LOGD("Destroying event class: %!+E", event_class);
-
-       if (event_class->name.str) {
-               g_string_free(event_class->name.str, TRUE);
-       }
-
-       if (event_class->emf_uri.str) {
-               g_string_free(event_class->emf_uri.str, TRUE);
-       }
-
-       BT_LOGD_STR("Putting context field type.");
-       bt_put(event_class->specific_context_ft);
-       BT_LOGD_STR("Putting payload field type.");
-       bt_put(event_class->payload_ft);
-       bt_object_pool_finalize(&event_class->event_pool);
-       g_free(obj);
-}
-
-static
-void free_event(struct bt_event *event,
-               struct bt_event_class *event_class)
-{
-       bt_event_destroy(event);
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool event_class_id_is_unique(struct bt_stream_class *stream_class, uint64_t id)
-{
-       uint64_t i;
-       bool is_unique = true;
-
-       for (i = 0; i < stream_class->event_classes->len; i++) {
-               struct bt_event_class *ec =
-                       stream_class->event_classes->pdata[i];
-
-               if (ec->id == id) {
-                       is_unique = false;
-                       goto end;
-               }
-       }
-
-end:
-       return is_unique;
-}
-
-static
-struct bt_event_class *create_event_class_with_id(
-               struct bt_stream_class *stream_class, uint64_t id)
-{
-       int ret;
-       struct bt_event_class *event_class;
-
-       BT_ASSERT(stream_class);
-       BT_ASSERT_PRE(event_class_id_is_unique(stream_class, id),
-               "Duplicate event class ID: %![sc-]+S, id=%" PRIu64,
-               stream_class, id);
-       BT_LIB_LOGD("Creating event class object: %![sc-]+S, id=%" PRIu64,
-               stream_class, id);
-       event_class = g_new0(struct bt_event_class, 1);
-       if (!event_class) {
-               BT_LOGE_STR("Failed to allocate one event class.");
-               goto error;
-       }
-
-       bt_object_init_shared_with_parent(&event_class->base,
-               destroy_event_class);
-       event_class->id = id;
-       bt_property_uint_init(&event_class->log_level,
-                       BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE, 0);
-       event_class->name.str = g_string_new(NULL);
-       if (!event_class->name.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               ret = -1;
-               goto end;
-       }
-
-       event_class->emf_uri.str = g_string_new(NULL);
-       if (!event_class->emf_uri.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_object_pool_initialize(&event_class->event_pool,
-               (bt_object_pool_new_object_func) bt_event_new,
-               (bt_object_pool_destroy_object_func) free_event,
-               event_class);
-       if (ret) {
-               BT_LOGE("Failed to initialize event pool: ret=%d",
-                       ret);
-               goto error;
-       }
-
-       bt_object_set_parent(&event_class->base, &stream_class->base);
-       g_ptr_array_add(stream_class->event_classes, event_class);
-       bt_stream_class_freeze(stream_class);
-       BT_LIB_LOGD("Created event class object: %!+E", event_class);
-       goto end;
-
-error:
-       BT_PUT(event_class);
-
-end:
-       return event_class;
-}
-
-struct bt_event_class *bt_event_class_create(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE(stream_class->assigns_automatic_event_class_id,
-               "Stream class does not automatically assigns event class IDs: "
-               "%![sc-]+S", stream_class);
-       return create_event_class_with_id(stream_class,
-               (uint64_t) stream_class->event_classes->len);
-}
-
-struct bt_event_class *bt_event_class_create_with_id(
-               struct bt_stream_class *stream_class, uint64_t id)
-{
-       BT_ASSERT_PRE(!stream_class->assigns_automatic_event_class_id,
-               "Stream class automatically assigns event class IDs: "
-               "%![sc-]+S", stream_class);
-       return create_event_class_with_id(stream_class, id);
-}
-
-const char *bt_event_class_get_name(struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return event_class->name.value;
-}
-
-int bt_event_class_set_name(struct bt_event_class *event_class,
-               const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
-       g_string_assign(event_class->name.str, name);
-       event_class->name.value = event_class->name.str->str;
-       BT_LIB_LOGV("Set event class's name: %!+E", event_class);
-       return 0;
-}
-
-uint64_t bt_event_class_get_id(struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return event_class->id;
-}
-
-enum bt_property_availability bt_event_class_get_log_level(
-               struct bt_event_class *event_class,
-               enum bt_event_class_log_level *log_level)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_NON_NULL(log_level, "Log level (output)");
-       *log_level = (enum bt_event_class_log_level)
-               event_class->log_level.value;
-       return event_class->log_level.base.avail;
-}
-
-int bt_event_class_set_log_level(struct bt_event_class *event_class,
-               enum bt_event_class_log_level log_level)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
-       bt_property_uint_set(&event_class->log_level,
-               (uint64_t) log_level);
-       BT_LIB_LOGV("Set event class's log level: %!+E", event_class);
-       return 0;
-}
-
-const char *bt_event_class_get_emf_uri(struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return event_class->emf_uri.value;
-}
-
-int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
-               const char *emf_uri)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_NON_NULL(emf_uri, "EMF URI");
-       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
-       g_string_assign(event_class->emf_uri.str, emf_uri);
-       event_class->emf_uri.value = event_class->emf_uri.str->str;
-       BT_LIB_LOGV("Set event class's EMF URI: %!+E", event_class);
-       return 0;
-}
-
-struct bt_stream_class *bt_event_class_borrow_stream_class(
-               struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return bt_event_class_borrow_stream_class_inline(event_class);
-}
-
-struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
-               struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return event_class->specific_context_ft;
-}
-
-int bt_event_class_set_specific_context_field_type(
-               struct bt_event_class *event_class,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_stream_class *stream_class;
-       struct bt_trace *trace;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = NULL,
-               .packet_context = NULL,
-               .event_header = NULL,
-               .event_common_context = NULL,
-               .event_specific_context = field_type,
-               .event_payload = NULL,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Specific context field type is not a structure field type: "
-               "%!+F", field_type);
-       stream_class = bt_event_class_borrow_stream_class_inline(
-               event_class);
-       trace = bt_stream_class_borrow_trace_inline(stream_class);
-       resolve_ctx.packet_header = trace->packet_header_ft;
-       resolve_ctx.packet_context = stream_class->packet_context_ft;
-       resolve_ctx.event_header = stream_class->event_header_ft;
-       resolve_ctx.event_common_context =
-               stream_class->event_common_context_ft;
-
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(event_class->specific_context_ft);
-       event_class->specific_context_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set event class's specific context field type: %!+E",
-               event_class);
-
-end:
-       return ret;
-}
-
-struct bt_field_type *bt_event_class_borrow_payload_field_type(
-               struct bt_event_class *event_class)
-{
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       return event_class->payload_ft;
-}
-
-int bt_event_class_set_payload_field_type(struct bt_event_class *event_class,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_stream_class *stream_class;
-       struct bt_trace *trace;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = NULL,
-               .packet_context = NULL,
-               .event_header = NULL,
-               .event_common_context = NULL,
-               .event_specific_context = NULL,
-               .event_payload = field_type,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Payload field type is not a structure field type: %!+F",
-               field_type);
-       stream_class = bt_event_class_borrow_stream_class_inline(
-               event_class);
-       trace = bt_stream_class_borrow_trace_inline(stream_class);
-       resolve_ctx.packet_header = trace->packet_header_ft;
-       resolve_ctx.packet_context = stream_class->packet_context_ft;
-       resolve_ctx.event_header = stream_class->event_header_ft;
-       resolve_ctx.event_common_context =
-               stream_class->event_common_context_ft;
-       resolve_ctx.event_specific_context = event_class->specific_context_ft;
-
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(event_class->payload_ft);
-       event_class->payload_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set event class's payload field type: %!+E", event_class);
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void _bt_event_class_freeze(struct bt_event_class *event_class)
-{
-       /* The field types are already frozen */
-       BT_ASSERT(event_class);
-       BT_LIB_LOGD("Freezing event class: %!+E", event_class);
-       event_class->frozen = true;
-}
diff --git a/lib/ctf-ir/event-header-field.c b/lib/ctf-ir/event-header-field.c
deleted file mode 100644 (file)
index dd2b2ff..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT-HEADER-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/event-header-field.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_event_header_field_borrow_field(
-               struct bt_event_header_field *header_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
-       return (void *) field_wrapper->field;
-}
-
-void bt_event_header_field_release(struct bt_event_header_field *header_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
-
-       /*
-        * Do not recycle because the pool could be destroyed at this
-        * point. This function is only called when there's an error
-        * anyway because the goal of an event header field wrapper is
-        * to eventually move it to an event with bt_event_move_header()
-        * after creating it.
-        */
-       bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_event_header_field *bt_event_header_field_create(
-               struct bt_stream_class *stream_class)
-{
-       struct bt_field_wrapper *field_wrapper;
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE(bt_stream_class_borrow_trace_inline(stream_class),
-               "Stream class is not part of a trace: %!+S", stream_class);
-       BT_ASSERT_PRE(stream_class->event_header_ft,
-               "Stream class has no event header field type: %!+S",
-               stream_class);
-       field_wrapper = bt_field_wrapper_create(
-               &stream_class->event_header_field_pool,
-               (void *) stream_class->event_header_ft);
-       if (!field_wrapper) {
-               BT_LIB_LOGE("Cannot allocate one event header field from stream class: "
-                       "%![sc-]+S", stream_class);
-               goto error;
-       }
-
-       BT_ASSERT(field_wrapper->field);
-       bt_stream_class_freeze(stream_class);
-       goto end;
-
-error:
-       if (field_wrapper) {
-               bt_field_wrapper_destroy(field_wrapper);
-               field_wrapper = NULL;
-       }
-
-end:
-       return (void *) field_wrapper;
-}
diff --git a/lib/ctf-ir/event.c b/lib/ctf-ir/event.c
deleted file mode 100644 (file)
index 91e6ed8..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * event.c
- *
- * Babeltrace CTF IR - Event
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "EVENT"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-BT_HIDDEN
-void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen)
-{
-       BT_ASSERT(event);
-       BT_LIB_LOGD("Setting event's frozen state: %!+e, is-frozen=%d",
-               event, is_frozen);
-
-       if (event->header_field) {
-               BT_LOGD_STR("Setting event's header field's frozen state.");
-               bt_field_set_is_frozen(
-                       event->header_field->field, is_frozen);
-       }
-
-       if (event->common_context_field) {
-               BT_LOGD_STR("Setting event's common context field's frozen state.");
-               bt_field_set_is_frozen(
-                       event->common_context_field, is_frozen);
-       }
-
-       if (event->specific_context_field) {
-               BT_LOGD_STR("Setting event's specific context field's frozen state.");
-               bt_field_set_is_frozen(event->specific_context_field,
-                       is_frozen);
-       }
-
-       if (event->payload_field) {
-               BT_LOGD_STR("Setting event's payload field's frozen state.");
-               bt_field_set_is_frozen(event->payload_field,
-                       is_frozen);
-       }
-
-       event->frozen = is_frozen;
-       BT_LOGD_STR("Setting event's packet's frozen state.");
-       bt_packet_set_is_frozen(event->packet, is_frozen);
-}
-
-static
-void recycle_event_header_field(struct bt_field_wrapper *field_wrapper,
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT(field_wrapper);
-       BT_LIB_LOGD("Recycling event header field: "
-               "addr=%p, %![sc-]+S, %![field-]+f", field_wrapper,
-               stream_class, field_wrapper->field);
-       bt_object_pool_recycle_object(
-               &stream_class->event_header_field_pool,
-               field_wrapper);
-}
-
-static inline
-struct bt_field_wrapper *create_event_header_field(
-               struct bt_stream_class *stream_class)
-{
-       struct bt_field_wrapper *field_wrapper = NULL;
-
-       field_wrapper = bt_field_wrapper_create(
-               &stream_class->event_header_field_pool,
-               bt_stream_class_borrow_event_header_field_type(stream_class));
-       if (!field_wrapper) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       if (field_wrapper) {
-               recycle_event_header_field(field_wrapper, stream_class);
-               field_wrapper = NULL;
-       }
-
-end:
-       return field_wrapper;
-}
-
-BT_HIDDEN
-struct bt_event *bt_event_new(struct bt_event_class *event_class)
-{
-       struct bt_event *event = NULL;
-       struct bt_stream_class *stream_class;
-       struct bt_field_type *ft;
-
-       BT_ASSERT(event_class);
-       event = g_new0(struct bt_event, 1);
-       if (!event) {
-               BT_LOGE_STR("Failed to allocate one event.");
-               goto error;
-       }
-
-       bt_object_init_unique(&event->base);
-       stream_class = bt_event_class_borrow_stream_class(event_class);
-       BT_ASSERT(stream_class);
-
-       if (bt_stream_class_borrow_event_header_field_type(stream_class)) {
-               event->header_field = create_event_header_field(stream_class);
-               if (!event->header_field) {
-                       BT_LOGE_STR("Cannot create event header field.");
-                       goto error;
-               }
-       }
-
-       ft = bt_stream_class_borrow_event_common_context_field_type(
-               stream_class);
-       if (ft) {
-               event->common_context_field = bt_field_create(ft);
-               if (!event->common_context_field) {
-                       /* bt_field_create() logs errors */
-                       goto error;
-               }
-       }
-
-       ft = bt_event_class_borrow_specific_context_field_type(event_class);
-       if (ft) {
-               event->specific_context_field = bt_field_create(ft);
-               if (!event->specific_context_field) {
-                       /* bt_field_create() logs errors */
-                       goto error;
-               }
-       }
-
-       ft = bt_event_class_borrow_payload_field_type(event_class);
-       if (ft) {
-               event->payload_field = bt_field_create(ft);
-               if (!event->payload_field) {
-                       /* bt_field_create() logs errors */
-                       goto error;
-               }
-       }
-
-       if (stream_class->default_clock_class) {
-               event->default_cv = bt_clock_value_create(
-                       stream_class->default_clock_class);
-               if (!event->default_cv) {
-                       /* bt_clock_value_create() logs errors */
-                       goto error;
-               }
-       }
-
-       goto end;
-
-error:
-       if (event) {
-               bt_event_destroy(event);
-               event = NULL;
-       }
-
-end:
-       return event;
-}
-
-struct bt_event_class *bt_event_borrow_class(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->class;
-}
-
-struct bt_stream *bt_event_borrow_stream(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->packet ? event->packet->stream : NULL;
-}
-
-struct bt_field *bt_event_borrow_header_field(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->header_field ? event->header_field->field : NULL;
-}
-
-struct bt_field *bt_event_borrow_common_context_field(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->common_context_field;
-}
-
-struct bt_field *bt_event_borrow_specific_context_field(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->specific_context_field;
-}
-
-struct bt_field *bt_event_borrow_payload_field(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->payload_field;
-}
-
-static
-void release_event_header_field(struct bt_field_wrapper *field_wrapper,
-               struct bt_event *event)
-{
-       if (!event->class) {
-               bt_field_wrapper_destroy(field_wrapper);
-       } else {
-               struct bt_stream_class *stream_class =
-                       bt_event_class_borrow_stream_class(event->class);
-
-               BT_ASSERT(stream_class);
-               recycle_event_header_field(field_wrapper, stream_class);
-       }
-}
-
-BT_HIDDEN
-void bt_event_destroy(struct bt_event *event)
-{
-       BT_ASSERT(event);
-       BT_LIB_LOGD("Destroying event: %!+e", event);
-
-       if (event->header_field) {
-               BT_LOGD_STR("Releasing event's header field.");
-               release_event_header_field(event->header_field, event);
-       }
-
-       if (event->common_context_field) {
-               BT_LOGD_STR("Destroying event's stream event context field.");
-               bt_field_destroy(event->common_context_field);
-       }
-
-       if (event->specific_context_field) {
-               BT_LOGD_STR("Destroying event's context field.");
-               bt_field_destroy(event->specific_context_field);
-       }
-
-       if (event->payload_field) {
-               BT_LOGD_STR("Destroying event's payload field.");
-               bt_field_destroy(event->payload_field);
-       }
-
-       BT_LOGD_STR("Putting event's class.");
-       bt_put(event->class);
-
-       if (event->default_cv) {
-               bt_clock_value_recycle(event->default_cv);
-       }
-
-       BT_LOGD_STR("Putting event's packet.");
-       bt_put(event->packet);
-       g_free(event);
-}
-
-int bt_event_set_default_clock_value(struct bt_event *event,
-               uint64_t value_cycles)
-{
-       struct bt_stream_class *sc;
-
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       BT_ASSERT_PRE_EVENT_HOT(event);
-       sc = bt_event_class_borrow_stream_class_inline(event->class);
-       BT_ASSERT(sc);
-       BT_ASSERT_PRE(sc->default_clock_class,
-               "Event's stream class has no default clock class: "
-               "%![ev-]+e, %![sc-]+S", event, sc);
-       BT_ASSERT(event->default_cv);
-       bt_clock_value_set_value_inline(event->default_cv, value_cycles);
-       BT_LIB_LOGV("Set event's default clock value: %![event-]+e, "
-               "value=%" PRIu64, event, value_cycles);
-       return 0;
-}
-
-enum bt_clock_value_status bt_event_borrow_default_clock_value(
-               struct bt_event *event, struct bt_clock_value **clock_value)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
-       *clock_value = event->default_cv;
-       return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-struct bt_packet *bt_event_borrow_packet(struct bt_event *event)
-{
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       return event->packet;
-}
-
-int bt_event_move_header(struct bt_event *event,
-               struct bt_event_header_field *header_field)
-{
-       struct bt_stream_class *stream_class;
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(event, "Event");
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
-       BT_ASSERT_PRE_EVENT_HOT(event);
-       stream_class = bt_event_class_borrow_stream_class_inline(event->class);
-       BT_ASSERT_PRE(stream_class->event_header_ft,
-               "Stream class has no event header field type: %!+S",
-               stream_class);
-
-       /* Recycle current header field: always exists */
-       BT_ASSERT(event->header_field);
-       recycle_event_header_field(event->header_field, stream_class);
-
-       /* Move new field */
-       event->header_field = field_wrapper;
-       return 0;
-}
diff --git a/lib/ctf-ir/field-path.c b/lib/ctf-ir/field-path.c
deleted file mode 100644 (file)
index ceb54bf..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * field-path.c
- *
- * Babeltrace CTF IR - Field path
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-PATH"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <limits.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <babeltrace/assert-internal.h>
-#include <glib.h>
-
-static
-void destroy_field_path(struct bt_object *obj)
-{
-       struct bt_field_path *field_path = (struct bt_field_path *) obj;
-
-       BT_ASSERT(field_path);
-       BT_LIB_LOGD("Destroying field path: %!+P", field_path);
-       g_array_free(field_path->indexes, TRUE);
-       g_free(field_path);
-}
-
-BT_HIDDEN
-struct bt_field_path *bt_field_path_create(void)
-{
-       struct bt_field_path *field_path = NULL;
-
-       BT_LOGD_STR("Creating empty field path object.");
-
-       field_path = g_new0(struct bt_field_path, 1);
-       if (!field_path) {
-               BT_LOGE_STR("Failed to allocate one field path.");
-               goto error;
-       }
-
-       bt_object_init_shared(&field_path->base, destroy_field_path);
-       field_path->indexes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
-       if (!field_path->indexes) {
-               BT_LOGE_STR("Failed to allocate a GArray.");
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created empty field path object: %!+P", field_path);
-       goto end;
-
-error:
-       BT_PUT(field_path);
-
-end:
-       return field_path;
-}
-
-enum bt_scope bt_field_path_get_root_scope(struct bt_field_path *field_path)
-{
-       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
-       return field_path->root;
-}
-
-uint64_t bt_field_path_get_index_count(struct bt_field_path *field_path)
-{
-       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
-       return (uint64_t) field_path->indexes->len;
-}
-
-uint64_t bt_field_path_get_index_by_index(struct bt_field_path *field_path,
-               uint64_t index)
-{
-       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
-       BT_ASSERT_PRE_VALID_INDEX(index, field_path->indexes->len);
-       return bt_field_path_get_index_by_index_inline(field_path, index);
-}
diff --git a/lib/ctf-ir/field-types.c b/lib/ctf-ir/field-types.c
deleted file mode 100644 (file)
index f71cf29..0000000
+++ /dev/null
@@ -1,1164 +0,0 @@
-/*
- * field-types.c
- *
- * Babeltrace CTF IR - Event Types
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-TYPES"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/compat/glib-internal.h>
-#include <float.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-enum bt_field_type_id bt_field_type_get_type_id(struct bt_field_type *ft)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       return ft->id;
-}
-
-static
-void init_field_type(struct bt_field_type *ft, enum bt_field_type_id id,
-               bt_object_release_func release_func)
-{
-       BT_ASSERT(ft);
-       BT_ASSERT(bt_field_type_has_known_id(ft));
-       BT_ASSERT(release_func);
-       bt_object_init_shared(&ft->base, release_func);
-       ft->id = id;
-}
-
-static
-void init_integer_field_type(struct bt_field_type_integer *ft, enum bt_field_type_id id,
-               bt_object_release_func release_func)
-{
-       init_field_type((void *) ft, id, release_func);
-       ft->range = 64;
-       ft->base = BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
-}
-
-static
-void destroy_integer_field_type(struct bt_object *obj)
-{
-       BT_ASSERT(obj);
-       BT_LIB_LOGD("Destroying integer field type object: %!+F", obj);
-       g_free(obj);
-}
-
-static inline
-struct bt_field_type *create_integer_field_type(enum bt_field_type_id id)
-{
-       struct bt_field_type_integer *int_ft = NULL;
-
-       BT_LOGD("Creating default integer field type object: id=%s",
-               bt_common_field_type_id_string(id));
-       int_ft = g_new0(struct bt_field_type_integer, 1);
-       if (!int_ft) {
-               BT_LOGE_STR("Failed to allocate one integer field type.");
-               goto error;
-       }
-
-       init_integer_field_type(int_ft, id, destroy_integer_field_type);
-       BT_LIB_LOGD("Created integer field type object: %!+F", int_ft);
-       goto end;
-
-error:
-       BT_PUT(int_ft);
-
-end:
-       return (void *) int_ft;
-}
-
-struct bt_field_type *bt_field_type_unsigned_integer_create(void)
-{
-       return create_integer_field_type(BT_FIELD_TYPE_ID_UNSIGNED_INTEGER);
-}
-
-struct bt_field_type *bt_field_type_signed_integer_create(void)
-{
-       return create_integer_field_type(BT_FIELD_TYPE_ID_SIGNED_INTEGER);
-}
-
-uint64_t bt_field_type_integer_get_field_value_range(
-               struct bt_field_type *ft)
-{
-       struct bt_field_type_integer *int_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
-       return int_ft->range;
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool size_is_valid_for_enumeration_field_type(struct bt_field_type *ft,
-               uint64_t size)
-{
-       // TODO
-       return true;
-}
-
-int bt_field_type_integer_set_field_value_range(
-               struct bt_field_type *ft, uint64_t size)
-{
-       struct bt_field_type_integer *int_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
-       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
-       BT_ASSERT_PRE(size <= 64,
-               "Unsupported size for integer field type's field value range "
-               "(maximum is 64): size=%" PRIu64, size);
-       BT_ASSERT_PRE(int_ft->common.id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER ||
-               int_ft->common.id == BT_FIELD_TYPE_ID_SIGNED_INTEGER ||
-               size_is_valid_for_enumeration_field_type(ft, size),
-               "Invalid field value range for enumeration field type: "
-               "at least one of the current mapping ranges contains values "
-               "which are outside this range: %!+F, size=%" PRIu64, ft, size);
-       int_ft->range = size;
-       BT_LIB_LOGV("Set integer field type's field value range: %!+F", ft);
-       return 0;
-}
-
-enum bt_field_type_integer_preferred_display_base
-bt_field_type_integer_get_preferred_display_base(struct bt_field_type *ft)
-{
-       struct bt_field_type_integer *int_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
-       return int_ft->base;
-}
-
-int bt_field_type_integer_set_preferred_display_base(struct bt_field_type *ft,
-               enum bt_field_type_integer_preferred_display_base base)
-{
-       struct bt_field_type_integer *int_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
-       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
-       int_ft->base = base;
-       BT_LIB_LOGV("Set integer field type's preferred display base: %!+F", ft);
-       return 0;
-}
-
-static
-void finalize_enumeration_field_type_mapping(
-               struct bt_field_type_enumeration_mapping *mapping)
-{
-       BT_ASSERT(mapping);
-
-       if (mapping->label) {
-               g_string_free(mapping->label, TRUE);
-       }
-
-       if (mapping->ranges) {
-               g_array_free(mapping->ranges, TRUE);
-       }
-}
-
-static
-void destroy_enumeration_field_type(struct bt_object *obj)
-{
-       struct bt_field_type_enumeration *ft = (void *) obj;
-
-       BT_ASSERT(ft);
-       BT_LIB_LOGD("Destroying enumeration field type object: %!+F", ft);
-
-       if (ft->mappings) {
-               uint64_t i;
-
-               for (i = 0; i < ft->mappings->len; i++) {
-                       finalize_enumeration_field_type_mapping(
-                               BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, i));
-               }
-
-               g_array_free(ft->mappings, TRUE);
-       }
-
-       if (ft->label_buf) {
-               g_ptr_array_free(ft->label_buf, TRUE);
-       }
-
-       g_free(ft);
-}
-
-static
-struct bt_field_type *create_enumeration_field_type(enum bt_field_type_id id)
-{
-       struct bt_field_type_enumeration *enum_ft = NULL;
-
-       BT_LOGD("Creating default enumeration field type object: id=%s",
-               bt_common_field_type_id_string(id));
-       enum_ft = g_new0(struct bt_field_type_enumeration, 1);
-       if (!enum_ft) {
-               BT_LOGE_STR("Failed to allocate one enumeration field type.");
-               goto error;
-       }
-
-       init_integer_field_type((void *) enum_ft, id,
-               destroy_enumeration_field_type);
-       enum_ft->mappings = g_array_new(FALSE, TRUE,
-               sizeof(struct bt_field_type_enumeration_mapping));
-       if (!enum_ft->mappings) {
-               BT_LOGE_STR("Failed to allocate a GArray.");
-               goto error;
-       }
-
-       enum_ft->label_buf = g_ptr_array_new();
-       if (!enum_ft->label_buf) {
-               BT_LOGE_STR("Failed to allocate a GArray.");
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created enumeration field type object: %!+F", enum_ft);
-       goto end;
-
-error:
-       BT_PUT(enum_ft);
-
-end:
-       return (void *) enum_ft;
-}
-
-struct bt_field_type *bt_field_type_unsigned_enumeration_create(void)
-{
-       return create_enumeration_field_type(
-               BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION);
-}
-
-struct bt_field_type *bt_field_type_signed_enumeration_create(void)
-{
-       return create_enumeration_field_type(
-               BT_FIELD_TYPE_ID_SIGNED_ENUMERATION);
-}
-
-uint64_t bt_field_type_enumeration_get_mapping_count(struct bt_field_type *ft)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_ENUM(ft, "Field type");
-       return (uint64_t) enum_ft->mappings->len;
-}
-
-void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
-               struct bt_field_type *ft, uint64_t index,
-               const char **name,
-               struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-       struct bt_field_type_enumeration_mapping *mapping;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
-       BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
-       BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
-               "Field type");
-       mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
-       *name = mapping->label->str;
-       *ranges = (void *) mapping;
-}
-
-void bt_field_type_signed_enumeration_borrow_mapping_by_index(
-               struct bt_field_type *ft, uint64_t index,
-               const char **name,
-               struct bt_field_type_signed_enumeration_mapping_ranges **ranges)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-       struct bt_field_type_enumeration_mapping *mapping;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
-       BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
-       BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
-               "Field type");
-       mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
-       *name = mapping->label->str;
-       *ranges = (void *) mapping;
-}
-
-static inline
-uint64_t get_enumeration_field_type_mapping_range_count(
-               struct bt_field_type_enumeration_mapping *mapping)
-{
-       BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
-       return (uint64_t) mapping->ranges->len;
-}
-
-uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges)
-{
-       return get_enumeration_field_type_mapping_range_count((void *) ranges);
-}
-
-uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
-               struct bt_field_type_signed_enumeration_mapping_ranges *ranges)
-{
-       return get_enumeration_field_type_mapping_range_count((void *) ranges);
-}
-
-static inline
-void get_enumeration_field_type_mapping_range_at_index(
-               struct bt_field_type_enumeration_mapping *mapping,
-               uint64_t index, uint64_t *lower, uint64_t *upper)
-{
-       struct bt_field_type_enumeration_mapping_range *range;
-
-       BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
-       BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)");
-       BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)");
-       BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len);
-       range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
-       *lower = range->lower.u;
-       *upper = range->upper.u;
-}
-
-void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
-               uint64_t index, uint64_t *lower, uint64_t *upper)
-{
-       get_enumeration_field_type_mapping_range_at_index((void *) ranges,
-               index, lower, upper);
-}
-
-void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
-               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
-               uint64_t index, int64_t *lower, int64_t *upper)
-{
-       get_enumeration_field_type_mapping_range_at_index((void *) ranges,
-               index, (uint64_t *) lower, (uint64_t *) upper);
-}
-
-
-
-int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
-               struct bt_field_type *ft, uint64_t value,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
-       BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
-               "Field type");
-       g_ptr_array_set_size(enum_ft->label_buf, 0);
-
-       for (i = 0; i < enum_ft->mappings->len; i++) {
-               uint64_t j;
-               struct bt_field_type_enumeration_mapping *mapping =
-                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
-               for (j = 0; j < mapping->ranges->len; j++) {
-                       struct bt_field_type_enumeration_mapping_range *range =
-                               BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
-                                       mapping, j);
-
-                       if (value >= range->lower.u &&
-                                       value <= range->upper.u) {
-                               g_ptr_array_add(enum_ft->label_buf,
-                                       mapping->label->str);
-                               break;
-                       }
-               }
-       }
-
-       *label_array = (void *) enum_ft->label_buf->pdata;
-       *count = (uint64_t) enum_ft->label_buf->len;
-       return 0;
-}
-
-int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
-               struct bt_field_type *ft, int64_t value,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
-       BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
-               "Field type");
-       g_ptr_array_set_size(enum_ft->label_buf, 0);
-
-       for (i = 0; i < enum_ft->mappings->len; i++) {
-               uint64_t j;
-               struct bt_field_type_enumeration_mapping *mapping =
-                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
-               for (j = 0; j < mapping->ranges->len; j++) {
-                       struct bt_field_type_enumeration_mapping_range *range =
-                               BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
-                                       mapping, j);
-
-                       if (value >= range->lower.i &&
-                                       value <= range->upper.i) {
-                               g_ptr_array_add(enum_ft->label_buf,
-                                       mapping->label->str);
-                               break;
-                       }
-               }
-       }
-
-       *label_array = (void *) enum_ft->label_buf->pdata;
-       *count = (uint64_t) enum_ft->label_buf->len;
-       return 0;
-}
-
-static inline
-int add_mapping_to_enumeration_field_type(struct bt_field_type *ft,
-               const char *label, uint64_t lower, uint64_t upper)
-{
-       int ret = 0;
-       uint64_t i;
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-       struct bt_field_type_enumeration_mapping *mapping = NULL;
-       struct bt_field_type_enumeration_mapping_range *range;
-
-       BT_ASSERT(ft);
-       BT_ASSERT_PRE_NON_NULL(label, "Label");
-
-       /* Find existing mapping identified by this label */
-       for (i = 0; i < enum_ft->mappings->len; i++) {
-               struct bt_field_type_enumeration_mapping *mapping_candidate =
-                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
-
-               if (strcmp(mapping_candidate->label->str, label) == 0) {
-                       mapping = mapping_candidate;
-                       break;
-               }
-       }
-
-       if (!mapping) {
-               /* Create new mapping for this label */
-               g_array_set_size(enum_ft->mappings, enum_ft->mappings->len + 1);
-               mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft,
-                       enum_ft->mappings->len - 1);
-               mapping->ranges = g_array_new(FALSE, TRUE,
-                       sizeof(struct bt_field_type_enumeration_mapping_range));
-               if (!mapping->ranges) {
-                       finalize_enumeration_field_type_mapping(mapping);
-                       g_array_set_size(enum_ft->mappings,
-                               enum_ft->mappings->len - 1);
-                       ret = -1;
-                       goto end;
-               }
-
-               mapping->label = g_string_new(label);
-               if (!mapping->label) {
-                       finalize_enumeration_field_type_mapping(mapping);
-                       g_array_set_size(enum_ft->mappings,
-                               enum_ft->mappings->len - 1);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /* Add range */
-       BT_ASSERT(mapping);
-       g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
-       range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
-               mapping->ranges->len - 1);
-       range->lower.u = lower;
-       range->upper.u = upper;
-       BT_LIB_LOGV("Added mapping to enumeration field type: "
-               "%![ft-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
-               "upper-unsigned=%" PRIu64, ft, label, lower, upper);
-
-end:
-       return ret;
-}
-
-int bt_field_type_unsigned_enumeration_map_range(
-               struct bt_field_type *ft, const char *label,
-               uint64_t range_lower, uint64_t range_upper)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
-               "Field type");
-       BT_ASSERT_PRE(range_lower <= range_upper,
-               "Range's upper bound is less than lower bound: "
-               "upper=%" PRIu64 ", lower=%" PRIu64,
-               range_lower, range_upper);
-       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
-               range_lower),
-               "Range's lower bound is outside the enumeration field type's value range: "
-               "%![ft-]+F, lower=%" PRIu64, ft, range_lower);
-       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
-               range_upper),
-               "Range's upper bound is outside the enumeration field type's value range: "
-               "%![ft-]+F, upper=%" PRIu64, ft, range_upper);
-       return add_mapping_to_enumeration_field_type(ft, label, range_lower,
-               range_upper);
-}
-
-int bt_field_type_signed_enumeration_map_range(
-               struct bt_field_type *ft, const char *label,
-               int64_t range_lower, int64_t range_upper)
-{
-       struct bt_field_type_enumeration *enum_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
-               "Field type");
-       BT_ASSERT_PRE(range_lower <= range_upper,
-               "Range's upper bound is less than lower bound: "
-               "upper=%" PRId64 ", lower=%" PRId64,
-               range_lower, range_upper);
-       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
-               range_lower),
-               "Range's lower bound is outside the enumeration field type's value range: "
-               "%![ft-]+F, lower=%" PRId64, ft, range_lower);
-       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
-               range_upper),
-               "Range's upper bound is outside the enumeration field type's value range: "
-               "%![ft-]+F, upper=%" PRId64, ft, range_upper);
-       return add_mapping_to_enumeration_field_type(ft, label, range_lower,
-               range_upper);
-}
-
-static
-void destroy_real_field_type(struct bt_object *obj)
-{
-       BT_ASSERT(obj);
-       BT_LIB_LOGD("Destroying real field type object: %!+F", obj);
-       g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_real_create(void)
-{
-       struct bt_field_type_real *real_ft = NULL;
-
-       BT_LOGD_STR("Creating default real field type object.");
-       real_ft = g_new0(struct bt_field_type_real, 1);
-       if (!real_ft) {
-               BT_LOGE_STR("Failed to allocate one real field type.");
-               goto error;
-       }
-
-       init_field_type((void *) real_ft, BT_FIELD_TYPE_ID_REAL,
-               destroy_real_field_type);
-       BT_LIB_LOGD("Created real field type object: %!+F", real_ft);
-       goto end;
-
-error:
-       BT_PUT(real_ft);
-
-end:
-       return (void *) real_ft;
-}
-
-bt_bool bt_field_type_real_is_single_precision(struct bt_field_type *ft)
-{
-       struct bt_field_type_real *real_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
-       return real_ft->is_single_precision;
-}
-
-int bt_field_type_real_set_is_single_precision(struct bt_field_type *ft,
-               bt_bool is_single_precision)
-{
-       struct bt_field_type_real *real_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
-       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
-       real_ft->is_single_precision = (bool) is_single_precision;
-       BT_LIB_LOGV("Set real field type's \"is single precision\" property: "
-               "%!+F", ft);
-       return 0;
-}
-
-static
-int init_named_field_types_container(
-               struct bt_field_type_named_field_types_container *ft,
-               enum bt_field_type_id id, bt_object_release_func release_func)
-{
-       int ret = 0;
-
-       init_field_type((void *) ft, id, release_func);
-       ft->named_fts = g_array_new(FALSE, TRUE,
-               sizeof(struct bt_named_field_type));
-       if (!ft->named_fts) {
-               BT_LOGE_STR("Failed to allocate a GArray.");
-               ret = -1;
-               goto end;
-       }
-
-       ft->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
-       if (!ft->name_to_index) {
-               BT_LOGE_STR("Failed to allocate a GHashTable.");
-               ret = -1;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-static
-void finalize_named_field_type(struct bt_named_field_type *named_ft)
-{
-       BT_ASSERT(named_ft);
-       BT_LIB_LOGD("Finalizing named field type: "
-               "addr=%p, name=\"%s\", %![ft-]+F",
-               named_ft, named_ft->name ? named_ft->name->str : NULL,
-               named_ft->ft);
-
-       if (named_ft->name) {
-               g_string_free(named_ft->name, TRUE);
-       }
-
-       BT_LOGD_STR("Putting named field type's field type.");
-       bt_put(named_ft->ft);
-}
-
-static
-void finalize_named_field_types_container(
-               struct bt_field_type_named_field_types_container *ft)
-{
-       uint64_t i;
-
-       BT_ASSERT(ft);
-
-       if (ft->named_fts) {
-               for (i = 0; i < ft->named_fts->len; i++) {
-                       finalize_named_field_type(
-                               &g_array_index(ft->named_fts,
-                                       struct bt_named_field_type, i));
-               }
-
-               g_array_free(ft->named_fts, TRUE);
-       }
-
-       if (ft->name_to_index) {
-               g_hash_table_destroy(ft->name_to_index);
-       }
-}
-
-static
-void destroy_structure_field_type(struct bt_object *obj)
-{
-       BT_ASSERT(obj);
-       BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
-       finalize_named_field_types_container((void *) obj);
-       g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_structure_create(void)
-{
-       int ret;
-       struct bt_field_type_structure *struct_ft = NULL;
-
-       BT_LOGD_STR("Creating default structure field type object.");
-       struct_ft = g_new0(struct bt_field_type_structure, 1);
-       if (!struct_ft) {
-               BT_LOGE_STR("Failed to allocate one structure field type.");
-               goto error;
-       }
-
-       ret = init_named_field_types_container((void *) struct_ft,
-               BT_FIELD_TYPE_ID_STRUCTURE, destroy_structure_field_type);
-       if (ret) {
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created structure field type object: %!+F", struct_ft);
-       goto end;
-
-error:
-       BT_PUT(struct_ft);
-
-end:
-       return (void *) struct_ft;
-}
-
-static
-int append_named_field_type_to_container_field_type(
-               struct bt_field_type_named_field_types_container *container_ft,
-               const char *name, struct bt_field_type *ft)
-{
-       int ret = 0;
-       struct bt_named_field_type *named_ft;
-       GString *name_str;
-
-       BT_ASSERT(container_ft);
-       BT_ASSERT_PRE_FT_HOT(container_ft, "Field type");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE(!bt_g_hash_table_contains(container_ft->name_to_index,
-               name),
-               "Duplicate member/option name in structure/variant field type: "
-               "%![container-ft-]+F, name=\"%s\"", container_ft, name);
-       name_str = g_string_new(name);
-       if (!name_str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               ret = -1;
-               goto end;
-       }
-
-       g_array_set_size(container_ft->named_fts,
-               container_ft->named_fts->len + 1);
-       named_ft = &g_array_index(container_ft->named_fts,
-               struct bt_named_field_type, container_ft->named_fts->len - 1);
-       named_ft->name = name_str;
-       named_ft->ft = bt_get(ft);
-       g_hash_table_insert(container_ft->name_to_index, named_ft->name->str,
-               GUINT_TO_POINTER(container_ft->named_fts->len - 1));
-       bt_field_type_freeze(ft);
-
-end:
-       return ret;
-}
-
-int bt_field_type_structure_append_member(struct bt_field_type *ft,
-               const char *name, struct bt_field_type *member_ft)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
-       return append_named_field_type_to_container_field_type((void *) ft,
-               name, member_ft);
-}
-
-uint64_t bt_field_type_structure_get_member_count(struct bt_field_type *ft)
-{
-       struct bt_field_type_structure *struct_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
-       return (uint64_t) struct_ft->common.named_fts->len;
-}
-
-static
-void borrow_named_field_type_from_container_field_type_at_index(
-               struct bt_field_type_named_field_types_container *ft,
-               uint64_t index, const char **name,
-               struct bt_field_type **out_ft)
-{
-       struct bt_named_field_type *named_ft;
-
-       BT_ASSERT(ft);
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_NON_NULL(out_ft, "Field type (output)");
-       BT_ASSERT_PRE_VALID_INDEX(index, ft->named_fts->len);
-       named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, index);
-       *name = named_ft->name->str;
-       *out_ft = named_ft->ft;
-}
-
-void bt_field_type_structure_borrow_member_by_index(
-               struct bt_field_type *ft, uint64_t index,
-               const char **name, struct bt_field_type **out_ft)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
-       borrow_named_field_type_from_container_field_type_at_index((void *) ft,
-               index, name, out_ft);
-}
-
-static
-struct bt_field_type *borrow_field_type_from_container_field_type_by_name(
-               struct bt_field_type_named_field_types_container *ft,
-               const char *name)
-{
-       struct bt_field_type *ret_ft = NULL;
-       struct bt_named_field_type *named_ft;
-       gpointer orig_key;
-       gpointer value;
-
-       BT_ASSERT(ft);
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       if (!g_hash_table_lookup_extended(ft->name_to_index, name, &orig_key,
-                       &value)) {
-               goto end;
-       }
-
-       named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft,
-               GPOINTER_TO_UINT(value));
-       ret_ft = named_ft->ft;
-
-end:
-       return ret_ft;
-}
-
-struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
-               struct bt_field_type *ft, const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
-       return borrow_field_type_from_container_field_type_by_name((void *) ft,
-               name);
-}
-
-static
-void destroy_variant_field_type(struct bt_object *obj)
-{
-       struct bt_field_type_variant *ft = (void *) obj;
-
-       BT_ASSERT(ft);
-       BT_LIB_LOGD("Destroying variant field type object: %!+F", ft);
-       finalize_named_field_types_container((void *) ft);
-       BT_LOGD_STR("Putting selector field path.");
-       bt_put(ft->selector_field_path);
-       g_free(ft);
-}
-
-struct bt_field_type *bt_field_type_variant_create(void)
-{
-       int ret;
-       struct bt_field_type_variant *var_ft = NULL;
-
-       BT_LOGD_STR("Creating default variant field type object.");
-       var_ft = g_new0(struct bt_field_type_variant, 1);
-       if (!var_ft) {
-               BT_LOGE_STR("Failed to allocate one variant field type.");
-               goto error;
-       }
-
-       ret = init_named_field_types_container((void *) var_ft,
-               BT_FIELD_TYPE_ID_VARIANT, destroy_variant_field_type);
-       if (ret) {
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created variant field type object: %!+F", var_ft);
-       goto end;
-
-error:
-       BT_PUT(var_ft);
-
-end:
-       return (void *) var_ft;
-}
-
-int bt_field_type_variant_set_selector_field_type(
-               struct bt_field_type *ft, struct bt_field_type *selector_ft)
-{
-       struct bt_field_type_variant *var_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Variant field type");
-       BT_ASSERT_PRE_NON_NULL(selector_ft, "Selector field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
-       BT_ASSERT_PRE_FT_IS_ENUM(selector_ft, "Selector field type");
-       BT_ASSERT_PRE_FT_HOT(ft, "Variant field type");
-       var_ft->selector_ft = selector_ft;
-       bt_field_type_freeze(selector_ft);
-       return 0;
-}
-
-int bt_field_type_variant_append_option(struct bt_field_type *ft,
-               const char *name, struct bt_field_type *option_ft)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
-       return append_named_field_type_to_container_field_type((void *) ft,
-               name, option_ft);
-}
-
-struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
-               struct bt_field_type *ft, const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
-       return borrow_field_type_from_container_field_type_by_name((void *) ft,
-               name);
-}
-
-uint64_t bt_field_type_variant_get_option_count(struct bt_field_type *ft)
-{
-       struct bt_field_type_variant *var_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
-       return (uint64_t) var_ft->common.named_fts->len;
-}
-
-void bt_field_type_variant_borrow_option_by_index(
-               struct bt_field_type *ft, uint64_t index,
-               const char **name, struct bt_field_type **out_ft)
-{
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
-       borrow_named_field_type_from_container_field_type_at_index((void *) ft,
-               index, name, out_ft);
-}
-
-struct bt_field_path *bt_field_type_variant_borrow_selector_field_path(
-               struct bt_field_type *ft)
-{
-       struct bt_field_type_variant *var_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
-               "Field type");
-       return var_ft->selector_field_path;
-}
-
-static
-void init_array_field_type(struct bt_field_type_array *ft,
-               enum bt_field_type_id id, bt_object_release_func release_func,
-               struct bt_field_type *element_ft)
-{
-       BT_ASSERT(element_ft);
-       init_field_type((void *) ft, id, release_func);
-       ft->element_ft = bt_get(element_ft);
-       bt_field_type_freeze(element_ft);
-}
-
-static
-void finalize_array_field_type(struct bt_field_type_array *array_ft)
-{
-       BT_ASSERT(array_ft);
-       BT_LOGD_STR("Putting element field type.");
-       bt_put(array_ft->element_ft);
-}
-
-static
-void destroy_static_array_field_type(struct bt_object *obj)
-{
-       BT_ASSERT(obj);
-       BT_LIB_LOGD("Destroying static array field type object: %!+F", obj);
-       finalize_array_field_type((void *) obj);
-       g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_static_array_create(
-               struct bt_field_type *element_ft, uint64_t length)
-{
-       struct bt_field_type_static_array *array_ft = NULL;
-
-       BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
-       BT_LOGD_STR("Creating default static array field type object.");
-       array_ft = g_new0(struct bt_field_type_static_array, 1);
-       if (!array_ft) {
-               BT_LOGE_STR("Failed to allocate one static array field type.");
-               goto error;
-       }
-
-       init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
-               destroy_static_array_field_type, element_ft);
-       array_ft->length = length;
-       BT_LIB_LOGD("Created static array field type object: %!+F", array_ft);
-       goto end;
-
-error:
-       BT_PUT(array_ft);
-
-end:
-       return (void *) array_ft;
-}
-
-struct bt_field_type *bt_field_type_array_borrow_element_field_type(
-               struct bt_field_type *ft)
-{
-       struct bt_field_type_array *array_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_IS_ARRAY(ft, "Field type");
-       return array_ft->element_ft;
-}
-
-uint64_t bt_field_type_static_array_get_length(struct bt_field_type *ft)
-{
-       struct bt_field_type_static_array *array_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
-               "Field type");
-       return (uint64_t) array_ft->length;
-}
-
-static
-void destroy_dynamic_array_field_type(struct bt_object *obj)
-{
-       struct bt_field_type_dynamic_array *ft = (void *) obj;
-
-       BT_ASSERT(ft);
-       BT_LIB_LOGD("Destroying dynamic array field type object: %!+F", ft);
-       finalize_array_field_type((void *) ft);
-       BT_LOGD_STR("Putting length field path.");
-       bt_put(ft->length_field_path);
-       g_free(ft);
-}
-
-struct bt_field_type *bt_field_type_dynamic_array_create(
-               struct bt_field_type *element_ft)
-{
-       struct bt_field_type_dynamic_array *array_ft = NULL;
-
-       BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
-       BT_LOGD_STR("Creating default dynamic array field type object.");
-       array_ft = g_new0(struct bt_field_type_dynamic_array, 1);
-       if (!array_ft) {
-               BT_LOGE_STR("Failed to allocate one dynamic array field type.");
-               goto error;
-       }
-
-       init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
-               destroy_dynamic_array_field_type, element_ft);
-       BT_LIB_LOGD("Created dynamic array field type object: %!+F", array_ft);
-       goto end;
-
-error:
-       BT_PUT(array_ft);
-
-end:
-       return (void *) array_ft;
-}
-
-int bt_field_type_dynamic_array_set_length_field_type(struct bt_field_type *ft,
-               struct bt_field_type *length_ft)
-{
-       struct bt_field_type_dynamic_array *array_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Dynamic array field type");
-       BT_ASSERT_PRE_NON_NULL(length_ft, "Length field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
-               "Field type");
-       BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(length_ft, "Length field type");
-       BT_ASSERT_PRE_FT_HOT(ft, "Dynamic array field type");
-       array_ft->length_ft = length_ft;
-       bt_field_type_freeze(length_ft);
-       return 0;
-}
-
-struct bt_field_path *bt_field_type_dynamic_array_borrow_length_field_path(
-               struct bt_field_type *ft)
-{
-       struct bt_field_type_dynamic_array *seq_ft = (void *) ft;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
-               "Field type");
-       return seq_ft->length_field_path;
-}
-
-static
-void destroy_string_field_type(struct bt_object *obj)
-{
-       BT_ASSERT(obj);
-       BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
-       g_free(obj);
-}
-
-struct bt_field_type *bt_field_type_string_create(void)
-{
-       struct bt_field_type_string *string_ft = NULL;
-
-       BT_LOGD_STR("Creating default string field type object.");
-       string_ft = g_new0(struct bt_field_type_string, 1);
-       if (!string_ft) {
-               BT_LOGE_STR("Failed to allocate one string field type.");
-               goto error;
-       }
-
-       init_field_type((void *) string_ft, BT_FIELD_TYPE_ID_STRING,
-               destroy_string_field_type);
-       BT_LIB_LOGD("Created string field type object: %!+F", string_ft);
-       goto end;
-
-error:
-       BT_PUT(string_ft);
-
-end:
-       return (void *) string_ft;
-}
-
-BT_HIDDEN
-void _bt_field_type_freeze(struct bt_field_type *ft)
-{
-       /*
-        * Element/member/option field types are frozen when added to
-        * their owner.
-        */
-       BT_ASSERT(ft);
-       ft->frozen = true;
-}
-
-BT_HIDDEN
-void _bt_field_type_make_part_of_trace(struct bt_field_type *ft)
-{
-       BT_ASSERT(ft);
-       BT_ASSERT_PRE(!ft->part_of_trace,
-               "Field type is already part of a trace: %!+F", ft);
-       ft->part_of_trace = true;
-
-       switch (ft->id) {
-       case BT_FIELD_TYPE_ID_STRUCTURE:
-       case BT_FIELD_TYPE_ID_VARIANT:
-       {
-               struct bt_field_type_named_field_types_container *container_ft =
-                       (void *) ft;
-               uint64_t i;
-
-               for (i = 0; i < container_ft->named_fts->len; i++) {
-                       struct bt_named_field_type *named_ft =
-                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
-                                       container_ft, i);
-
-                       bt_field_type_make_part_of_trace(named_ft->ft);
-               }
-
-               break;
-       }
-       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
-       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
-       {
-               struct bt_field_type_array *array_ft = (void *) ft;
-
-               bt_field_type_make_part_of_trace(array_ft->element_ft);
-               break;
-       }
-       default:
-               break;
-       }
-}
diff --git a/lib/ctf-ir/field-wrapper.c b/lib/ctf-ir/field-wrapper.c
deleted file mode 100644 (file)
index ee28705..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELD-WRAPPER"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/object-pool-internal.h>
-#include <babeltrace/object-internal.h>
-#include <glib.h>
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_new(void *data)
-{
-       struct bt_field_wrapper *field_wrapper =
-               g_new0(struct bt_field_wrapper, 1);
-
-       BT_LOGD_STR("Creating empty field wrapper object.");
-
-       if (!field_wrapper) {
-               BT_LOGE("Failed to allocate one field wrapper.");
-               goto end;
-       }
-
-       bt_object_init_unique(&field_wrapper->base);
-       BT_LOGD("Created empty field wrapper object: addr=%p",
-               field_wrapper);
-
-end:
-       return field_wrapper;
-}
-
-BT_HIDDEN
-void bt_field_wrapper_destroy(struct bt_field_wrapper *field_wrapper)
-{
-       BT_LOGD("Destroying field wrapper: addr=%p", field_wrapper);
-
-       if (field_wrapper->field) {
-               BT_LOGD_STR("Destroying field.");
-               bt_field_destroy((void *) field_wrapper->field);
-       }
-
-       BT_LOGD_STR("Putting stream class.");
-       g_free(field_wrapper);
-}
-
-BT_HIDDEN
-struct bt_field_wrapper *bt_field_wrapper_create(
-               struct bt_object_pool *pool, struct bt_field_type *ft)
-{
-       struct bt_field_wrapper *field_wrapper = NULL;
-
-       BT_ASSERT(pool);
-       BT_ASSERT(ft);
-       field_wrapper = bt_object_pool_create_object(pool);
-       if (!field_wrapper) {
-               BT_LIB_LOGE("Cannot allocate one field wrapper from field wrapper pool: "
-                       "%![pool-]+o", pool);
-               goto error;
-       }
-
-       if (!field_wrapper->field) {
-               field_wrapper->field = (void *) bt_field_create(ft);
-               if (!field_wrapper->field) {
-                       BT_LIB_LOGE("Cannot create field wrapper from field type: "
-                               "%![ft-]+F", ft);
-                       goto error;
-               }
-
-               BT_LIB_LOGD("Created initial field wrapper object: "
-                       "wrapper-addr=%p, %![field-]+f", field_wrapper,
-                       field_wrapper->field);
-       }
-
-       goto end;
-
-error:
-       if (field_wrapper) {
-               bt_field_wrapper_destroy(field_wrapper);
-               field_wrapper = NULL;
-       }
-
-end:
-       return field_wrapper;
-}
diff --git a/lib/ctf-ir/fields.c b/lib/ctf-ir/fields.c
deleted file mode 100644 (file)
index c0bd86b..0000000
+++ /dev/null
@@ -1,1104 +0,0 @@
-/*
- * fields.c
- *
- * Babeltrace CTF IR - Event Fields
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "FIELDS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/compat/fcntl-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-static
-void reset_single_field(struct bt_field *field);
-
-static
-void reset_array_field(struct bt_field *field);
-
-static
-void reset_structure_field(struct bt_field *field);
-
-static
-void reset_variant_field(struct bt_field *field);
-
-static
-void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
-
-static
-bool single_field_is_set(struct bt_field *field);
-
-static
-bool array_field_is_set(struct bt_field *field);
-
-static
-bool structure_field_is_set(struct bt_field *field);
-
-static
-bool variant_field_is_set(struct bt_field *field);
-
-static
-struct bt_field_methods integer_field_methods = {
-       .set_is_frozen = set_single_field_is_frozen,
-       .is_set = single_field_is_set,
-       .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods real_field_methods = {
-       .set_is_frozen = set_single_field_is_frozen,
-       .is_set = single_field_is_set,
-       .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods string_field_methods = {
-       .set_is_frozen = set_single_field_is_frozen,
-       .is_set = single_field_is_set,
-       .reset = reset_single_field,
-};
-
-static
-struct bt_field_methods structure_field_methods = {
-       .set_is_frozen = set_structure_field_is_frozen,
-       .is_set = structure_field_is_set,
-       .reset = reset_structure_field,
-};
-
-static
-struct bt_field_methods array_field_methods = {
-       .set_is_frozen = set_array_field_is_frozen,
-       .is_set = array_field_is_set,
-       .reset = reset_array_field,
-};
-
-static
-struct bt_field_methods variant_field_methods = {
-       .set_is_frozen = set_variant_field_is_frozen,
-       .is_set = variant_field_is_set,
-       .reset = reset_variant_field,
-};
-
-static
-struct bt_field *create_integer_field(struct bt_field_type *);
-
-static
-struct bt_field *create_real_field(struct bt_field_type *);
-
-static
-struct bt_field *create_string_field(struct bt_field_type *);
-
-static
-struct bt_field *create_structure_field(struct bt_field_type *);
-
-static
-struct bt_field *create_static_array_field(struct bt_field_type *);
-
-static
-struct bt_field *create_dynamic_array_field(struct bt_field_type *);
-
-static
-struct bt_field *create_variant_field(struct bt_field_type *);
-
-static
-struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
-       [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER]     = create_integer_field,
-       [BT_FIELD_TYPE_ID_SIGNED_INTEGER]       = create_integer_field,
-       [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = create_integer_field,
-       [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION]   = create_integer_field,
-       [BT_FIELD_TYPE_ID_REAL]                 = create_real_field,
-       [BT_FIELD_TYPE_ID_STRING]               = create_string_field,
-       [BT_FIELD_TYPE_ID_STRUCTURE]            = create_structure_field,
-       [BT_FIELD_TYPE_ID_STATIC_ARRAY]         = create_static_array_field,
-       [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY]        = create_dynamic_array_field,
-       [BT_FIELD_TYPE_ID_VARIANT]              = create_variant_field,
-};
-
-static
-void destroy_integer_field(struct bt_field *field);
-
-static
-void destroy_real_field(struct bt_field *field);
-
-static
-void destroy_string_field(struct bt_field *field);
-
-static
-void destroy_structure_field(struct bt_field *field);
-
-static
-void destroy_array_field(struct bt_field *field);
-
-static
-void destroy_variant_field(struct bt_field *field);
-
-static
-void (* const field_destroy_funcs[])(struct bt_field *) = {
-       [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER]     = destroy_integer_field,
-       [BT_FIELD_TYPE_ID_SIGNED_INTEGER]       = destroy_integer_field,
-       [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = destroy_integer_field,
-       [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION]   = destroy_integer_field,
-       [BT_FIELD_TYPE_ID_REAL]                 = destroy_real_field,
-       [BT_FIELD_TYPE_ID_STRING]               = destroy_string_field,
-       [BT_FIELD_TYPE_ID_STRUCTURE]            = destroy_structure_field,
-       [BT_FIELD_TYPE_ID_STATIC_ARRAY]         = destroy_array_field,
-       [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY]        = destroy_array_field,
-       [BT_FIELD_TYPE_ID_VARIANT]              = destroy_variant_field,
-};
-
-struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
-{
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       return field->type;
-}
-
-enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
-{
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       return field->type->id;
-}
-
-BT_HIDDEN
-struct bt_field *bt_field_create(struct bt_field_type *ft)
-{
-       struct bt_field *field = NULL;
-
-       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
-       BT_ASSERT(bt_field_type_has_known_id(ft));
-       field = field_create_funcs[ft->id](ft);
-       if (!field) {
-               BT_LIB_LOGE("Cannot create field object from field type: "
-                       "%![ft-]+F", ft);
-               goto end;
-       }
-
-end:
-       return field;
-}
-
-static inline
-void init_field(struct bt_field *field, struct bt_field_type *ft,
-               struct bt_field_methods *methods)
-{
-       BT_ASSERT(field);
-       BT_ASSERT(ft);
-       bt_object_init_unique(&field->base);
-       field->methods = methods;
-       field->type = bt_get(ft);
-}
-
-static
-struct bt_field *create_integer_field(struct bt_field_type *ft)
-{
-       struct bt_field_integer *int_field;
-
-       BT_LIB_LOGD("Creating integer field object: %![ft-]+F", ft);
-       int_field = g_new0(struct bt_field_integer, 1);
-       if (!int_field) {
-               BT_LOGE_STR("Failed to allocate one integer field.");
-               goto end;
-       }
-
-       init_field((void *) int_field, ft, &integer_field_methods);
-       BT_LIB_LOGD("Created integer field object: %!+f", int_field);
-
-end:
-       return (void *) int_field;
-}
-
-static
-struct bt_field *create_real_field(struct bt_field_type *ft)
-{
-       struct bt_field_real *real_field;
-
-       BT_LIB_LOGD("Creating real field object: %![ft-]+F", ft);
-       real_field = g_new0(struct bt_field_real, 1);
-       if (!real_field) {
-               BT_LOGE_STR("Failed to allocate one real field.");
-               goto end;
-       }
-
-       init_field((void *) real_field, ft, &real_field_methods);
-       BT_LIB_LOGD("Created real field object: %!+f", real_field);
-
-end:
-       return (void *) real_field;
-}
-
-static
-struct bt_field *create_string_field(struct bt_field_type *ft)
-{
-       struct bt_field_string *string_field;
-
-       BT_LIB_LOGD("Creating string field object: %![ft-]+F", ft);
-       string_field = g_new0(struct bt_field_string, 1);
-       if (!string_field) {
-               BT_LOGE_STR("Failed to allocate one string field.");
-               goto end;
-       }
-
-       init_field((void *) string_field, ft, &string_field_methods);
-       string_field->buf = g_array_sized_new(FALSE, FALSE,
-               sizeof(char), 1);
-       if (!string_field->buf) {
-               BT_LOGE_STR("Failed to allocate a GArray.");
-               BT_PUT(string_field);
-               goto end;
-       }
-
-       g_array_index(string_field->buf, char, 0) = '\0';
-       BT_LIB_LOGD("Created string field object: %!+f", string_field);
-
-end:
-       return (void *) string_field;
-}
-
-static inline
-int create_fields_from_named_field_types(
-               struct bt_field_type_named_field_types_container *ft,
-               GPtrArray **fields)
-{
-       int ret = 0;
-       uint64_t i;
-
-       *fields = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_field_destroy);
-       if (!*fields) {
-               BT_LOGE_STR("Failed to allocate a GPtrArray.");
-               ret = -1;
-               goto end;
-       }
-
-       g_ptr_array_set_size(*fields, ft->named_fts->len);
-
-       for (i = 0; i < ft->named_fts->len; i++) {
-               struct bt_field *field;
-               struct bt_named_field_type *named_ft =
-                       BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, i);
-
-               field = bt_field_create(named_ft->ft);
-               if (!field) {
-                       BT_LIB_LOGE("Failed to create structure member or variant option field: "
-                               "name=\"%s\", %![ft-]+F",
-                               named_ft->name->str, named_ft->ft);
-                       ret = -1;
-                       goto end;
-               }
-
-               g_ptr_array_index(*fields, i) = field;
-       }
-
-end:
-       return ret;
-}
-
-static
-struct bt_field *create_structure_field(struct bt_field_type *ft)
-{
-       struct bt_field_structure *struct_field;
-
-       BT_LIB_LOGD("Creating structure field object: %![ft-]+F", ft);
-       struct_field = g_new0(struct bt_field_structure, 1);
-       if (!struct_field) {
-               BT_LOGE_STR("Failed to allocate one structure field.");
-               goto end;
-       }
-
-       init_field((void *) struct_field, ft, &structure_field_methods);
-
-       if (create_fields_from_named_field_types((void *) ft,
-                       &struct_field->fields)) {
-               BT_LIB_LOGE("Cannot create structure member fields: "
-                       "%![ft-]+F", ft);
-               BT_PUT(struct_field);
-               goto end;
-       }
-
-       BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
-
-end:
-       return (void *) struct_field;
-}
-
-static
-struct bt_field *create_variant_field(struct bt_field_type *ft)
-{
-       struct bt_field_variant *var_field;
-
-       BT_LIB_LOGD("Creating variant field object: %![ft-]+F", ft);
-       var_field = g_new0(struct bt_field_variant, 1);
-       if (!var_field) {
-               BT_LOGE_STR("Failed to allocate one variant field.");
-               goto end;
-       }
-
-       init_field((void *) var_field, ft, &variant_field_methods);
-
-       if (create_fields_from_named_field_types((void *) ft,
-                       &var_field->fields)) {
-               BT_LIB_LOGE("Cannot create variant member fields: "
-                       "%![ft-]+F", ft);
-               BT_PUT(var_field);
-               goto end;
-       }
-
-       BT_LIB_LOGD("Created variant field object: %!+f", var_field);
-
-end:
-       return (void *) var_field;
-}
-
-static inline
-int init_array_field_fields(struct bt_field_array *array_field)
-{
-       int ret = 0;
-       uint64_t i;
-       struct bt_field_type_array *array_ft;
-
-       BT_ASSERT(array_field);
-       array_ft = (void *) array_field->common.type;
-       array_field->fields = g_ptr_array_sized_new(array_field->length);
-       if (!array_field->fields) {
-               BT_LOGE_STR("Failed to allocate a GPtrArray.");
-               ret = -1;
-               goto end;
-       }
-
-       g_ptr_array_set_free_func(array_field->fields,
-               (GDestroyNotify) bt_field_destroy);
-       g_ptr_array_set_size(array_field->fields, array_field->length);
-
-       for (i = 0; i < array_field->length; i++) {
-               array_field->fields->pdata[i] = bt_field_create(
-                       array_ft->element_ft);
-               if (!array_field->fields->pdata[i]) {
-                       BT_LIB_LOGE("Cannot create array field's element field: "
-                               "index=%" PRIu64 ", %![ft-]+F", i, array_ft);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-static
-struct bt_field *create_static_array_field(struct bt_field_type *ft)
-{
-       struct bt_field_type_static_array *array_ft = (void *) ft;
-       struct bt_field_array *array_field;
-
-       BT_LIB_LOGD("Creating static array field object: %![ft-]+F", ft);
-       array_field = g_new0(struct bt_field_array, 1);
-       if (!array_field) {
-               BT_LOGE_STR("Failed to allocate one static array field.");
-               goto end;
-       }
-
-       init_field((void *) array_field, ft, &array_field_methods);
-       array_field->length = array_ft->length;
-
-       if (init_array_field_fields(array_field)) {
-               BT_LIB_LOGE("Cannot create static array fields: "
-                       "%![ft-]+F", ft);
-               BT_PUT(array_field);
-               goto end;
-       }
-
-       BT_LIB_LOGD("Created static array field object: %!+f", array_field);
-
-end:
-       return (void *) array_field;
-}
-
-static
-struct bt_field *create_dynamic_array_field(struct bt_field_type *ft)
-{
-       struct bt_field_array *array_field;
-
-       BT_LIB_LOGD("Creating dynamic array field object: %![ft-]+F", ft);
-       array_field = g_new0(struct bt_field_array, 1);
-       if (!array_field) {
-               BT_LOGE_STR("Failed to allocate one dynamic array field.");
-               goto end;
-       }
-
-       init_field((void *) array_field, ft, &array_field_methods);
-
-       if (init_array_field_fields(array_field)) {
-               BT_LIB_LOGE("Cannot create dynamic array fields: "
-                       "%![ft-]+F", ft);
-               BT_PUT(array_field);
-               goto end;
-       }
-
-       BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
-
-end:
-       return (void *) array_field;
-}
-
-int64_t bt_field_signed_integer_get_value(struct bt_field *field)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
-       return int_field->value.i;
-}
-
-void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(
-               ((struct bt_field_type_integer *) field->type)->range, value),
-               "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
-               "%![ft-]+F", value, field, field->type);
-       int_field->value.i = value;
-       bt_field_set_single(field, true);
-}
-
-uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
-       return int_field->value.u;
-}
-
-void bt_field_unsigned_integer_set_value(struct bt_field *field,
-               uint64_t value)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(
-               ((struct bt_field_type_integer *) field->type)->range, value),
-               "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
-               "%![ft-]+F", value, field, field->type);
-       int_field->value.u = value;
-       bt_field_set_single(field, true);
-}
-
-double bt_field_real_get_value(struct bt_field *field)
-{
-       struct bt_field_real *real_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
-       return real_field->value;
-}
-
-void bt_field_real_set_value(struct bt_field *field, double value)
-{
-       struct bt_field_real *real_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE(
-               !((struct bt_field_type_real *) field->type)->is_single_precision ||
-               (double) (float) value == value,
-               "Invalid value for a single-precision real number: value=%f, "
-               "%![ft-]+F", value, field->type);
-       real_field->value = value;
-       bt_field_set_single(field, true);
-}
-
-int bt_field_unsigned_enumeration_get_mapping_labels(struct bt_field *field,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, "Field");
-       return bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
-               field->type, int_field->value.u, label_array, count);
-}
-
-int bt_field_signed_enumeration_get_mapping_labels(struct bt_field *field,
-               bt_field_type_enumeration_mapping_label_array *label_array,
-               uint64_t *count)
-{
-       struct bt_field_integer *int_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
-       BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, "Field");
-       return bt_field_type_signed_enumeration_get_mapping_labels_by_value(
-               field->type, int_field->value.i, label_array, count);
-}
-
-const char *bt_field_string_get_value(struct bt_field *field)
-{
-       struct bt_field_string *string_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
-               "Field");
-       return (const char *) string_field->buf->data;
-}
-
-uint64_t bt_field_string_get_length(struct bt_field *field)
-{
-       struct bt_field_string *string_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
-               "Field");
-       return string_field->length;
-}
-
-int bt_field_string_set_value(struct bt_field *field, const char *value)
-{
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_NON_NULL(value, "Value");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
-               "Field");
-       bt_field_string_clear(field);
-       return bt_field_string_append_with_length(field, value,
-               (uint64_t) strlen(value));
-}
-
-int bt_field_string_append(struct bt_field *field, const char *value)
-{
-       return bt_field_string_append_with_length(field, value,
-               (uint64_t) strlen(value));
-}
-
-int bt_field_string_append_with_length(struct bt_field *field,
-               const char *value, uint64_t length)
-{
-       struct bt_field_string *string_field = (void *) field;
-       char *data;
-       uint64_t new_length;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_NON_NULL(value, "Value");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_STRING, "Field");
-
-       /* Make sure no null bytes are appended */
-       BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
-               "String value to append contains a null character: "
-               "partial-value=\"%.32s\", length=%" PRIu64, value, length);
-
-       new_length = length + string_field->length;
-
-       if (unlikely(new_length + 1 > string_field->buf->len)) {
-               g_array_set_size(string_field->buf, new_length + 1);
-       }
-
-       data = string_field->buf->data;
-       memcpy(data + string_field->length, value, length);
-       ((char *) string_field->buf->data)[new_length] = '\0';
-       string_field->length = new_length;
-       bt_field_set_single(field, true);
-       return 0;
-}
-
-int bt_field_string_clear(struct bt_field *field)
-{
-       struct bt_field_string *string_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_STRING, "Field");
-       string_field->length = 0;
-       bt_field_set_single(field, true);
-       return 0;
-}
-
-uint64_t bt_field_array_get_length(struct bt_field *field)
-{
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
-       return array_field->length;
-}
-
-int bt_field_dynamic_array_set_length(struct bt_field *field,
-               uint64_t length)
-{
-       int ret = 0;
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-
-       if (unlikely(length > array_field->fields->len)) {
-               /* Make more room */
-               struct bt_field_type_array *array_ft;
-               uint64_t cur_len = array_field->fields->len;
-               uint64_t i;
-
-               g_ptr_array_set_size(array_field->fields, length);
-               array_ft = (void *) field->type;
-
-               for (i = cur_len; i < array_field->fields->len; i++) {
-                       struct bt_field *elem_field = bt_field_create(
-                               array_ft->element_ft);
-
-                       if (!elem_field) {
-                               BT_LIB_LOGE("Cannot create element field for "
-                                       "dynamic array field: "
-                                       "index=%" PRIu64 ", "
-                                       "%![array-field-]+f", i, field);
-                               ret = -1;
-                               goto end;
-                       }
-
-                       BT_ASSERT(!array_field->fields->pdata[i]);
-                       array_field->fields->pdata[i] = elem_field;
-               }
-       }
-
-       array_field->length = length;
-
-end:
-       return ret;
-}
-
-struct bt_field *bt_field_array_borrow_element_field_by_index(
-               struct bt_field *field, uint64_t index)
-{
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
-       BT_ASSERT_PRE_VALID_INDEX(index, array_field->length);
-       return array_field->fields->pdata[index];
-}
-
-struct bt_field *bt_field_structure_borrow_member_field_by_index(
-               struct bt_field *field, uint64_t index)
-{
-       struct bt_field_structure *struct_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_STRUCTURE, "Field");
-       BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len);
-       return struct_field->fields->pdata[index];
-}
-
-struct bt_field *bt_field_structure_borrow_member_field_by_name(
-               struct bt_field *field, const char *name)
-{
-       struct bt_field *ret_field = NULL;
-       struct bt_field_type_structure *struct_ft;
-       struct bt_field_structure *struct_field = (void *) field;
-       gpointer orig_key;
-       gpointer index;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_NON_NULL(name, "Field name");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_STRUCTURE, "Field");
-       struct_ft = (void *) field->type;
-
-       if (!g_hash_table_lookup_extended(struct_ft->common.name_to_index, name,
-                       &orig_key, &index)) {
-               goto end;
-       }
-
-       ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
-       BT_ASSERT(ret_field);
-
-end:
-       return ret_field;
-}
-
-struct bt_field *bt_field_variant_borrow_selected_option_field(
-               struct bt_field *field)
-{
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_VARIANT, "Field");
-       BT_ASSERT_PRE(var_field->selected_field,
-               "Variant field has no selected field: %!+f", field);
-       return var_field->selected_field;
-}
-
-int bt_field_variant_select_option_field(struct bt_field *field,
-               uint64_t index)
-{
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_VARIANT, "Field");
-       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
-       BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len);
-       var_field->selected_field = var_field->fields->pdata[index];
-       var_field->selected_index = index;
-       return 0;
-}
-
-uint64_t bt_field_variant_get_selected_option_field_index(
-               struct bt_field *field)
-{
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_ASSERT_PRE_NON_NULL(field, "Field");
-       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
-               BT_FIELD_TYPE_ID_VARIANT, "Field");
-       BT_ASSERT_PRE(var_field->selected_field,
-               "Variant field has no selected field: %!+f", field);
-       return var_field->selected_index;
-}
-
-static inline
-void bt_field_finalize(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       BT_LOGD_STR("Putting field's type.");
-       bt_put(field->type);
-}
-
-static
-void destroy_integer_field(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying integer field object: %!+f", field);
-       bt_field_finalize(field);
-       g_free(field);
-}
-
-static
-void destroy_real_field(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying real field object: %!+f", field);
-       bt_field_finalize(field);
-       g_free(field);
-}
-
-static
-void destroy_structure_field(struct bt_field *field)
-{
-       struct bt_field_structure *struct_field = (void *) field;
-
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying structure field object: %!+f", field);
-       bt_field_finalize(field);
-
-       if (struct_field->fields) {
-               g_ptr_array_free(struct_field->fields, TRUE);
-       }
-
-       g_free(field);
-}
-
-static
-void destroy_variant_field(struct bt_field *field)
-{
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying variant field object: %!+f", field);
-       bt_field_finalize(field);
-
-       if (var_field->fields) {
-               g_ptr_array_free(var_field->fields, TRUE);
-       }
-
-       g_free(field);
-}
-
-static
-void destroy_array_field(struct bt_field *field)
-{
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying array field object: %!+f", field);
-       bt_field_finalize(field);
-
-       if (array_field->fields) {
-               g_ptr_array_free(array_field->fields, TRUE);
-       }
-
-       g_free(field);
-}
-
-static
-void destroy_string_field(struct bt_field *field)
-{
-       struct bt_field_string *string_field = (void *) field;
-
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Destroying string field object: %!+f", field);
-       bt_field_finalize(field);
-
-       if (string_field->buf) {
-               g_array_free(string_field->buf, TRUE);
-       }
-
-       g_free(field);
-}
-
-BT_HIDDEN
-void bt_field_destroy(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       BT_ASSERT(bt_field_type_has_known_id(field->type));
-       field_destroy_funcs[field->type->id](field);
-}
-
-static
-void reset_single_field(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       field->is_set = false;
-}
-
-static
-void reset_structure_field(struct bt_field *field)
-{
-       uint64_t i;
-       struct bt_field_structure *struct_field = (void *) field;
-
-       BT_ASSERT(field);
-
-       for (i = 0; i < struct_field->fields->len; i++) {
-               bt_field_reset(struct_field->fields->pdata[i]);
-       }
-}
-
-static
-void reset_variant_field(struct bt_field *field)
-{
-       uint64_t i;
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_ASSERT(field);
-
-       for (i = 0; i < var_field->fields->len; i++) {
-               bt_field_reset(var_field->fields->pdata[i]);
-       }
-}
-
-static
-void reset_array_field(struct bt_field *field)
-{
-       uint64_t i;
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT(field);
-
-       for (i = 0; i < array_field->fields->len; i++) {
-               bt_field_reset(array_field->fields->pdata[i]);
-       }
-}
-
-static
-void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
-       field->frozen = is_frozen;
-}
-
-static
-void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
-       uint64_t i;
-       struct bt_field_structure *struct_field = (void *) field;
-
-       BT_LIB_LOGD("Setting structure field's frozen state: "
-               "%![field-]+f, is-frozen=%d", field, is_frozen);
-
-       for (i = 0; i < struct_field->fields->len; i++) {
-               struct bt_field *member_field = struct_field->fields->pdata[i];
-
-               BT_LIB_LOGD("Setting structure field's member field's "
-                       "frozen state: %![field-]+f, index=%" PRIu64,
-                       member_field, i);
-               bt_field_set_is_frozen(member_field, is_frozen);
-       }
-
-       set_single_field_is_frozen(field, is_frozen);
-}
-
-static
-void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
-       uint64_t i;
-       struct bt_field_variant *var_field = (void *) field;
-
-       BT_LIB_LOGD("Setting variant field's frozen state: "
-               "%![field-]+f, is-frozen=%d", field, is_frozen);
-
-       for (i = 0; i < var_field->fields->len; i++) {
-               struct bt_field *option_field = var_field->fields->pdata[i];
-
-               BT_LIB_LOGD("Setting variant field's option field's "
-                       "frozen state: %![field-]+f, index=%" PRIu64,
-                       option_field, i);
-               bt_field_set_is_frozen(option_field, is_frozen);
-       }
-
-       set_single_field_is_frozen(field, is_frozen);
-}
-
-static
-void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
-{
-       uint64_t i;
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_LIB_LOGD("Setting array field's frozen state: "
-               "%![field-]+f, is-frozen=%d", field, is_frozen);
-
-       for (i = 0; i < array_field->fields->len; i++) {
-               struct bt_field *elem_field = array_field->fields->pdata[i];
-
-               BT_LIB_LOGD("Setting array field's element field's "
-                       "frozen state: %![field-]+f, index=%" PRIu64,
-                       elem_field, i);
-               bt_field_set_is_frozen(elem_field, is_frozen);
-       }
-
-       set_single_field_is_frozen(field, is_frozen);
-}
-
-BT_HIDDEN
-void _bt_field_set_is_frozen(struct bt_field *field,
-               bool is_frozen)
-{
-       BT_ASSERT(field);
-       BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
-               field, is_frozen);
-       BT_ASSERT(field->methods->set_is_frozen);
-       field->methods->set_is_frozen(field, is_frozen);
-}
-
-static
-bool single_field_is_set(struct bt_field *field)
-{
-       BT_ASSERT(field);
-       return field->is_set;
-}
-
-static
-bool structure_field_is_set(struct bt_field *field)
-{
-       bool is_set = true;
-       uint64_t i;
-       struct bt_field_structure *struct_field = (void *) field;
-
-       BT_ASSERT(field);
-
-       for (i = 0; i < struct_field->fields->len; i++) {
-               is_set = bt_field_is_set(struct_field->fields->pdata[i]);
-               if (!is_set) {
-                       goto end;
-               }
-       }
-
-end:
-       return is_set;
-}
-
-static
-bool variant_field_is_set(struct bt_field *field)
-{
-       struct bt_field_variant *var_field = (void *) field;
-       bool is_set = false;
-
-       BT_ASSERT(field);
-
-       if (var_field->selected_field) {
-               is_set = bt_field_is_set(var_field->selected_field);
-       }
-
-       return is_set;
-}
-
-static
-bool array_field_is_set(struct bt_field *field)
-{
-       bool is_set = true;
-       uint64_t i;
-       struct bt_field_array *array_field = (void *) field;
-
-       BT_ASSERT(field);
-
-       for (i = 0; i < array_field->length; i++) {
-               is_set = bt_field_is_set(array_field->fields->pdata[i]);
-               if (!is_set) {
-                       goto end;
-               }
-       }
-
-end:
-       return is_set;
-}
diff --git a/lib/ctf-ir/packet-context-field.c b/lib/ctf-ir/packet-context-field.c
deleted file mode 100644 (file)
index 55fdb7f..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET-CONTEXT-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/packet-context-field.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_packet_context_field_borrow_field(
-               struct bt_packet_context_field *context_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
-       return field_wrapper->field;
-}
-
-void bt_packet_context_field_release(struct bt_packet_context_field *context_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
-
-       /*
-        * Do not recycle because the pool could be destroyed at this
-        * point. This function is only called when there's an error
-        * anyway because the goal of a packet context field wrapper is
-        * to eventually move it to a packet with
-        * bt_packet_move_context() after creating it.
-        */
-       bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_packet_context_field *bt_packet_context_field_create(
-               struct bt_stream_class *stream_class)
-{
-       struct bt_field_wrapper *field_wrapper;
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE(stream_class->frozen,
-               "Stream class is not part of a trace: %!+S", stream_class);
-       BT_ASSERT_PRE(stream_class->packet_context_ft,
-               "Stream class has no packet context field type: %!+S",
-               stream_class);
-       field_wrapper = bt_field_wrapper_create(
-               &stream_class->packet_context_field_pool,
-               (void *) stream_class->packet_context_ft);
-       if (!field_wrapper) {
-               BT_LIB_LOGE("Cannot allocate one packet context field from stream class: "
-                       "%![sc-]+S", stream_class);
-               goto error;
-       }
-
-       BT_ASSERT(field_wrapper->field);
-       bt_stream_class_freeze(stream_class);
-       goto end;
-
-error:
-       if (field_wrapper) {
-               bt_field_wrapper_destroy(field_wrapper);
-               field_wrapper = NULL;
-       }
-
-end:
-       return (void *) field_wrapper;
-}
diff --git a/lib/ctf-ir/packet-header-field.c b/lib/ctf-ir/packet-header-field.c
deleted file mode 100644 (file)
index 17d88ad..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET-HEADER-FIELD"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-header-field.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <glib.h>
-
-struct bt_field *bt_packet_header_field_borrow_field(
-               struct bt_packet_header_field *header_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
-       return (void *) field_wrapper->field;
-}
-
-void bt_packet_header_field_release(struct bt_packet_header_field *header_field)
-{
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
-
-       /*
-        * Do not recycle because the pool could be destroyed at this
-        * point. This function is only called when there's an error
-        * anyway because the goal of a packet header field wrapper is
-        * to eventually move it to a packet with
-        * bt_packet_move_header() after creating it.
-        */
-       bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_packet_header_field *bt_packet_header_field_create(
-               struct bt_trace *trace)
-{
-       struct bt_field_wrapper *field_wrapper;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE(trace->packet_header_ft,
-               "Trace has no packet header field type: %!+t", trace);
-       field_wrapper = bt_field_wrapper_create(
-               &trace->packet_header_field_pool,
-               (void *) trace->packet_header_ft);
-       if (!field_wrapper) {
-               BT_LIB_LOGE("Cannot allocate one packet header field from trace: "
-                       "%![trace-]+t", trace);
-               goto error;
-       }
-
-       BT_ASSERT(field_wrapper->field);
-       bt_trace_freeze(trace);
-       goto end;
-
-error:
-       if (field_wrapper) {
-               bt_field_wrapper_destroy(field_wrapper);
-               field_wrapper = NULL;
-       }
-
-end:
-       return (void *) field_wrapper;
-}
diff --git a/lib/ctf-ir/packet.c b/lib/ctf-ir/packet.c
deleted file mode 100644 (file)
index d3fce47..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * packet.c
- *
- * Babeltrace CTF IR - Stream packet
- *
- * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "PACKET"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/assert-internal.h>
-#include <inttypes.h>
-
-#define BT_ASSERT_PRE_PACKET_HOT(_packet) \
-       BT_ASSERT_PRE_HOT((_packet), "Packet", ": %!+a", (_packet))
-
-struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       return packet->stream;
-}
-
-struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       return packet->header_field ? packet->header_field->field : NULL;
-}
-
-struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       return packet->context_field ? packet->context_field->field : NULL;
-}
-
-BT_HIDDEN
-void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen)
-{
-       if (!packet) {
-               return;
-       }
-
-       BT_LIB_LOGD("Setting packet's frozen state: %![packet-]+a, "
-               "is-frozen=%d", packet, is_frozen);
-
-       if (packet->header_field) {
-               BT_LOGD_STR("Setting packet's header field's frozen state.");
-               bt_field_set_is_frozen(packet->header_field->field,
-                       is_frozen);
-       }
-
-       if (packet->context_field) {
-               BT_LOGD_STR("Setting packet's context field's frozen state.");
-               bt_field_set_is_frozen(packet->context_field->field,
-                       is_frozen);
-       }
-
-       packet->frozen = is_frozen;
-}
-
-static inline
-void reset_counter_snapshots(struct bt_packet *packet)
-{
-       packet->discarded_event_counter_snapshot.base.avail =
-               BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
-       packet->packet_counter_snapshot.base.avail =
-               BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
-}
-
-static inline
-void reset_packet(struct bt_packet *packet)
-{
-       BT_ASSERT(packet);
-       BT_LIB_LOGD("Resetting packet: %!+a", packet);
-       bt_packet_set_is_frozen(packet, false);
-
-       if (packet->header_field) {
-               bt_field_set_is_frozen(packet->header_field->field, false);
-               bt_field_reset(packet->header_field->field);
-       }
-
-       if (packet->context_field) {
-               bt_field_set_is_frozen(packet->context_field->field, false);
-               bt_field_reset(packet->context_field->field);
-       }
-
-       if (packet->default_beginning_cv) {
-               bt_clock_value_reset(packet->default_beginning_cv);
-       }
-
-       if (packet->default_end_cv) {
-               bt_clock_value_reset(packet->default_end_cv);
-       }
-
-       reset_counter_snapshots(packet);
-}
-
-static
-void recycle_header_field(struct bt_field_wrapper *header_field,
-               struct bt_trace *trace)
-{
-       BT_ASSERT(header_field);
-       BT_LIB_LOGD("Recycling packet header field: "
-               "addr=%p, %![trace-]+t, %![field-]+f", header_field,
-               trace, header_field->field);
-       bt_object_pool_recycle_object(&trace->packet_header_field_pool,
-               header_field);
-}
-
-static
-void recycle_context_field(struct bt_field_wrapper *context_field,
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT(context_field);
-       BT_LIB_LOGD("Recycling packet context field: "
-               "addr=%p, %![sc-]+S, %![field-]+f", context_field,
-               stream_class, context_field->field);
-       bt_object_pool_recycle_object(&stream_class->packet_context_field_pool,
-               context_field);
-}
-
-BT_HIDDEN
-void bt_packet_recycle(struct bt_packet *packet)
-{
-       struct bt_stream *stream;
-
-       BT_ASSERT(packet);
-       BT_LIB_LOGD("Recycling packet: %!+a", packet);
-
-       /*
-        * Those are the important ordered steps:
-        *
-        * 1. Reset the packet object (put any permanent reference it
-        *    has, unfreeze it and its fields in developer mode, etc.),
-        *    but do NOT put its stream's reference. This stream
-        *    contains the pool to which we're about to recycle this
-        *    packet object, so we must guarantee its existence thanks
-        *    to this existing reference.
-        *
-        * 2. Move the stream reference to our `stream`
-        *    variable so that we can set the packet's stream member
-        *    to NULL before recycling it. We CANNOT do this after
-        *    we put the stream reference because this bt_put()
-        *    could destroy the stream, also destroying its
-        *    packet pool, thus also destroying our packet object (this
-        *    would result in an invalid write access).
-        *
-        * 3. Recycle the packet object.
-        *
-        * 4. Put our stream reference.
-        */
-       reset_packet(packet);
-       stream = packet->stream;
-       BT_ASSERT(stream);
-       packet->stream = NULL;
-       bt_object_pool_recycle_object(&stream->packet_pool, packet);
-       bt_object_put_no_null_check(&stream->base);
-}
-
-BT_HIDDEN
-void bt_packet_destroy(struct bt_packet *packet)
-{
-       BT_LIB_LOGD("Destroying packet: %!+a", packet);
-
-       if (packet->header_field) {
-               if (packet->stream) {
-                       BT_LOGD_STR("Recycling packet's header field.");
-                       recycle_header_field(packet->header_field,
-                               bt_stream_class_borrow_trace_inline(
-                                       packet->stream->class));
-               } else {
-                       bt_field_wrapper_destroy(packet->header_field);
-               }
-       }
-
-       if (packet->context_field) {
-               if (packet->stream) {
-                       BT_LOGD_STR("Recycling packet's context field.");
-                       recycle_context_field(packet->context_field,
-                               packet->stream->class);
-               } else {
-                       bt_field_wrapper_destroy(packet->context_field);
-               }
-       }
-
-       if (packet->default_beginning_cv) {
-               BT_LOGD_STR("Recycling beginning clock value.");
-               bt_clock_value_recycle(packet->default_beginning_cv);
-       }
-
-       if (packet->default_end_cv) {
-               BT_LOGD_STR("Recycling end clock value.");
-               bt_clock_value_recycle(packet->default_end_cv);
-       }
-
-       BT_LOGD_STR("Putting packet's stream.");
-       bt_put(packet->stream);
-       g_free(packet);
-}
-
-BT_HIDDEN
-struct bt_packet *bt_packet_new(struct bt_stream *stream)
-{
-       struct bt_packet *packet = NULL;
-       struct bt_trace *trace = NULL;
-
-       BT_ASSERT(stream);
-       BT_LIB_LOGD("Creating packet object: %![stream-]+s", stream);
-       packet = g_new0(struct bt_packet, 1);
-       if (!packet) {
-               BT_LOGE_STR("Failed to allocate one packet object.");
-               goto error;
-       }
-
-       bt_object_init_shared(&packet->base,
-               (bt_object_release_func) bt_packet_recycle);
-       packet->stream = bt_get(stream);
-       trace = bt_stream_class_borrow_trace_inline(stream->class);
-       BT_ASSERT(trace);
-
-       if (trace->packet_header_ft) {
-               BT_LOGD_STR("Creating initial packet header field.");
-               packet->header_field = bt_field_wrapper_create(
-                       &trace->packet_header_field_pool,
-                       trace->packet_header_ft);
-               if (!packet->header_field) {
-                       BT_LOGE_STR("Cannot create packet header field wrapper.");
-                       goto error;
-               }
-       }
-
-       if (stream->class->packet_context_ft) {
-               BT_LOGD_STR("Creating initial packet context field.");
-               packet->context_field = bt_field_wrapper_create(
-                       &stream->class->packet_context_field_pool,
-                       stream->class->packet_context_ft);
-               if (!packet->context_field) {
-                       BT_LOGE_STR("Cannot create packet context field wrapper.");
-                       goto error;
-               }
-       }
-
-       if (stream->class->default_clock_class) {
-               if (stream->class->packets_have_default_beginning_cv) {
-                       packet->default_beginning_cv = bt_clock_value_create(
-                               stream->class->default_clock_class);
-                       if (!packet->default_beginning_cv) {
-                               /* bt_clock_value_create() logs errors */
-                               goto error;
-                       }
-               }
-
-               if (stream->class->packets_have_default_end_cv) {
-                       packet->default_end_cv = bt_clock_value_create(
-                               stream->class->default_clock_class);
-                       if (!packet->default_end_cv) {
-                               /* bt_clock_value_create() logs errors */
-                               goto error;
-                       }
-               }
-       }
-
-       reset_counter_snapshots(packet);
-       BT_LIB_LOGD("Created packet object: %!+a", packet);
-       goto end;
-
-error:
-       BT_PUT(packet);
-
-end:
-       return packet;
-}
-
-struct bt_packet *bt_packet_create(struct bt_stream *stream)
-{
-       struct bt_packet *packet = NULL;
-
-       BT_ASSERT_PRE_NON_NULL(stream, "Stream");
-       packet = bt_object_pool_create_object(&stream->packet_pool);
-       if (unlikely(!packet)) {
-               BT_LIB_LOGE("Cannot allocate one packet from stream's packet pool: "
-                       "%![stream-]+s", stream);
-               goto end;
-       }
-
-       if (likely(!packet->stream)) {
-               packet->stream = stream;
-               bt_object_get_no_null_check_no_parent_check(
-                       &packet->stream->base);
-       }
-
-end:
-       return packet;
-}
-
-int bt_packet_move_header_field(struct bt_packet *packet,
-               struct bt_packet_header_field *header_field)
-{
-       struct bt_trace *trace;
-       struct bt_field_wrapper *field_wrapper = (void *) header_field;
-
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
-       BT_ASSERT_PRE_PACKET_HOT(packet);
-       trace = bt_stream_class_borrow_trace_inline(packet->stream->class);
-       BT_ASSERT_PRE(trace->packet_header_ft,
-               "Trace has no packet header field type: %!+t",
-               trace);
-       BT_ASSERT_PRE(field_wrapper->field->type ==
-               trace->packet_header_ft,
-               "Unexpected packet header field's type: "
-               "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
-               trace->packet_header_ft);
-
-       /* Recycle current header field: always exists */
-       BT_ASSERT(packet->header_field);
-       recycle_header_field(packet->header_field, trace);
-
-       /* Move new field */
-       packet->header_field = field_wrapper;
-       return 0;
-}
-
-int bt_packet_move_context_field(struct bt_packet *packet,
-               struct bt_packet_context_field *context_field)
-{
-       struct bt_stream_class *stream_class;
-       struct bt_field_wrapper *field_wrapper = (void *) context_field;
-
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Context field");
-       BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
-       stream_class = packet->stream->class;
-       BT_ASSERT_PRE(stream_class->packet_context_ft,
-               "Stream class has no packet context field type: %!+S",
-               stream_class);
-       BT_ASSERT_PRE(field_wrapper->field->type ==
-               stream_class->packet_context_ft,
-               "Unexpected packet header field's type: "
-               "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
-               stream_class->packet_context_ft);
-
-       /* Recycle current context field: always exists */
-       BT_ASSERT(packet->context_field);
-       recycle_context_field(packet->context_field, stream_class);
-
-       /* Move new field */
-       packet->context_field = field_wrapper;
-       return 0;
-}
-
-int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
-               uint64_t value_cycles)
-{
-       struct bt_stream_class *sc;
-
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_PACKET_HOT(packet);
-       sc = packet->stream->class;
-       BT_ASSERT(sc);
-       BT_ASSERT_PRE(sc->default_clock_class,
-               "Packet's stream class has no default clock class: "
-               "%![packet-]+a, %![sc-]+S", packet, sc);
-       BT_ASSERT_PRE(sc->packets_have_default_beginning_cv,
-               "Packet's stream class indicates that its packets have "
-               "no default beginning clock value: %![packet-]+a, %![sc-]+S",
-               packet, sc);
-       BT_ASSERT(packet->default_beginning_cv);
-       bt_clock_value_set_value_inline(packet->default_beginning_cv, value_cycles);
-       BT_LIB_LOGV("Set packet's default beginning clock value: "
-               "%![packet-]+a, value=%" PRIu64, value_cycles);
-       return 0;
-}
-
-enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
-               struct bt_packet *packet, struct bt_clock_value **clock_value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
-       *clock_value = packet->default_beginning_cv;
-       return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
-               uint64_t value_cycles)
-{
-       struct bt_stream_class *sc;
-
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_PACKET_HOT(packet);
-       sc = packet->stream->class;
-       BT_ASSERT(sc);
-       BT_ASSERT_PRE(sc->default_clock_class,
-               "Packet's stream class has no default clock class: "
-               "%![packet-]+a, %![sc-]+S", packet, sc);
-       BT_ASSERT_PRE(sc->packets_have_default_end_cv,
-               "Packet's stream class indicates that its packets have "
-               "no default end clock value: %![packet-]+a, %![sc-]+S",
-               packet, sc);
-       BT_ASSERT(packet->default_end_cv);
-       bt_clock_value_set_value_inline(packet->default_end_cv, value_cycles);
-       BT_LIB_LOGV("Set packet's default end clock value: "
-               "%![packet-]+a, value=%" PRIu64, value_cycles);
-       return 0;
-}
-
-enum bt_clock_value_status bt_packet_borrow_default_end_clock_value(
-               struct bt_packet *packet, struct bt_clock_value **clock_value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
-       *clock_value = packet->default_end_cv;
-       return BT_CLOCK_VALUE_STATUS_KNOWN;
-}
-
-enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
-               struct bt_packet *packet, uint64_t *value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
-       *value = packet->discarded_event_counter_snapshot.value;
-       return packet->discarded_event_counter_snapshot.base.avail;
-}
-
-int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
-               uint64_t value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_PACKET_HOT(packet);
-       BT_ASSERT_PRE(packet->stream->class->packets_have_discarded_event_counter_snapshot,
-               "Packet's stream's discarded event counter is not enabled: "
-               "%![packet-]+a", packet);
-       bt_property_uint_set(&packet->discarded_event_counter_snapshot, value);
-       return 0;
-}
-
-enum bt_property_availability bt_packet_get_packet_counter_snapshot(
-               struct bt_packet *packet, uint64_t *value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
-       *value = packet->packet_counter_snapshot.value;
-       return packet->packet_counter_snapshot.base.avail;
-}
-
-int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
-               uint64_t value)
-{
-       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
-       BT_ASSERT_PRE_PACKET_HOT(packet);
-       BT_ASSERT_PRE(packet->stream->class->packets_have_packet_counter_snapshot,
-               "Packet's stream's packet counter is not enabled: "
-               "%![packet-]+a", packet);
-       bt_property_uint_set(&packet->packet_counter_snapshot, value);
-       return 0;
-}
diff --git a/lib/ctf-ir/resolve-field-path.c b/lib/ctf-ir/resolve-field-path.c
deleted file mode 100644 (file)
index 6036758..0000000
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "RESOLVE-FIELD-PATH"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <limits.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <glib.h>
-
-static
-bool find_field_type_recursive(struct bt_field_type *ft,
-               struct bt_field_type *tgt_ft, struct bt_field_path *field_path)
-{
-       bool found = false;
-
-       if (tgt_ft == ft) {
-               found = true;
-               goto end;
-       }
-
-       switch (ft->id) {
-       case BT_FIELD_TYPE_ID_STRUCTURE:
-       case BT_FIELD_TYPE_ID_VARIANT:
-       {
-               struct bt_field_type_named_field_types_container *container_ft =
-                       (void *) ft;
-               uint64_t i;
-
-               for (i = 0; i < container_ft->named_fts->len; i++) {
-                       struct bt_named_field_type *named_ft =
-                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
-                                       container_ft, i);
-
-                       g_array_append_val(field_path->indexes, i);
-                       found = find_field_type_recursive(named_ft->ft,
-                               tgt_ft, field_path);
-                       if (found) {
-                               goto end;
-                       }
-
-                       g_array_set_size(field_path->indexes,
-                               field_path->indexes->len - 1);
-               }
-
-               break;
-       }
-       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
-       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
-       {
-               struct bt_field_type_array *array_ft = (void *) ft;
-
-               found = find_field_type_recursive(array_ft->element_ft,
-                       tgt_ft, field_path);
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return found;
-}
-
-static
-int find_field_type(struct bt_field_type *root_ft,
-               enum bt_scope root_scope, struct bt_field_type *tgt_ft,
-               struct bt_field_path **ret_field_path)
-{
-       int ret = 0;
-       struct bt_field_path *field_path = NULL;
-
-       if (!root_ft) {
-               goto end;
-       }
-
-       field_path = bt_field_path_create();
-       if (!field_path) {
-               ret = -1;
-               goto end;
-       }
-
-       field_path->root = root_scope;
-       if (!find_field_type_recursive(root_ft, tgt_ft, field_path)) {
-               /* Not found here */
-               BT_PUT(field_path);
-       }
-
-end:
-       *ret_field_path = field_path;
-       return ret;
-}
-
-static
-struct bt_field_path *find_field_type_in_ctx(struct bt_field_type *ft,
-               struct bt_resolve_field_path_context *ctx)
-{
-       struct bt_field_path *field_path = NULL;
-       int ret;
-
-       ret = find_field_type(ctx->packet_header, BT_SCOPE_PACKET_HEADER,
-               ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-       ret = find_field_type(ctx->packet_context, BT_SCOPE_PACKET_CONTEXT,
-               ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-       ret = find_field_type(ctx->event_header, BT_SCOPE_EVENT_HEADER,
-               ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-       ret = find_field_type(ctx->event_common_context,
-               BT_SCOPE_EVENT_COMMON_CONTEXT, ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-       ret = find_field_type(ctx->event_specific_context,
-               BT_SCOPE_EVENT_SPECIFIC_CONTEXT, ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-       ret = find_field_type(ctx->event_payload, BT_SCOPE_EVENT_PAYLOAD,
-               ft, &field_path);
-       if (ret || field_path) {
-               goto end;
-       }
-
-end:
-       return field_path;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool target_is_before_source(struct bt_field_path *src_field_path,
-               struct bt_field_path *tgt_field_path)
-{
-       bool is_valid = true;
-       uint64_t src_i = 0, tgt_i = 0;
-
-       if (tgt_field_path->root < src_field_path->root) {
-               goto end;
-       }
-
-       if (tgt_field_path->root > src_field_path->root) {
-               is_valid = false;
-               goto end;
-       }
-
-       BT_ASSERT(tgt_field_path->root == src_field_path->root);
-
-       while (src_i < src_field_path->indexes->len &&
-                       tgt_i < tgt_field_path->indexes->len) {
-               uint64_t src_index = bt_field_path_get_index_by_index_inline(
-                       src_field_path, src_i);
-               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
-                       tgt_field_path, tgt_i);
-
-               if (tgt_index > src_index) {
-                       is_valid = false;
-                       goto end;
-               }
-
-               src_i++;
-               tgt_i++;
-       }
-
-end:
-       return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-struct bt_field_type *borrow_root_field_type(
-               struct bt_resolve_field_path_context *ctx, enum bt_scope scope)
-{
-       switch (scope) {
-       case BT_SCOPE_PACKET_HEADER:
-               return ctx->packet_header;
-       case BT_SCOPE_PACKET_CONTEXT:
-               return ctx->packet_context;
-       case BT_SCOPE_EVENT_HEADER:
-               return ctx->event_header;
-       case BT_SCOPE_EVENT_COMMON_CONTEXT:
-               return ctx->event_common_context;
-       case BT_SCOPE_EVENT_SPECIFIC_CONTEXT:
-               return ctx->event_specific_context;
-       case BT_SCOPE_EVENT_PAYLOAD:
-               return ctx->event_payload;
-       default:
-               abort();
-       }
-
-       return NULL;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-struct bt_field_type *borrow_child_field_type(struct bt_field_type *parent_ft,
-               uint64_t index, bool *advance)
-{
-       struct bt_field_type *child_ft = NULL;
-
-       switch (parent_ft->id) {
-       case BT_FIELD_TYPE_ID_STRUCTURE:
-       case BT_FIELD_TYPE_ID_VARIANT:
-       {
-               struct bt_named_field_type *named_ft =
-                       BT_FIELD_TYPE_NAMED_FT_AT_INDEX(parent_ft, index);
-
-               child_ft = named_ft->ft;
-               *advance = true;
-               break;
-       }
-       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
-       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
-       {
-               struct bt_field_type_array *array_ft = (void *) parent_ft;
-
-               child_ft = array_ft->element_ft;
-               *advance = false;
-               break;
-       }
-       default:
-               break;
-       }
-
-       return child_ft;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool target_field_path_in_different_scope_has_struct_ft_only(
-               struct bt_field_path *src_field_path,
-               struct bt_field_path *tgt_field_path,
-               struct bt_resolve_field_path_context *ctx)
-{
-       bool is_valid = true;
-       uint64_t i = 0;
-       struct bt_field_type *ft;
-
-       if (src_field_path->root == tgt_field_path->root) {
-               goto end;
-       }
-
-       ft = borrow_root_field_type(ctx, tgt_field_path->root);
-
-       while (i < tgt_field_path->indexes->len) {
-               uint64_t index = bt_field_path_get_index_by_index_inline(
-                       tgt_field_path, i);
-               bool advance;
-
-               if (ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
-                               ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
-                               ft->id == BT_FIELD_TYPE_ID_VARIANT) {
-                       is_valid = false;
-                       goto end;
-               }
-
-               ft = borrow_child_field_type(ft, index, &advance);
-
-               if (advance) {
-                       i++;
-               }
-       }
-
-end:
-       return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool lca_is_structure_field_type(struct bt_field_path *src_field_path,
-               struct bt_field_path *tgt_field_path,
-               struct bt_resolve_field_path_context *ctx)
-{
-       bool is_valid = true;
-       struct bt_field_type *src_ft;
-       struct bt_field_type *tgt_ft;
-       struct bt_field_type *prev_ft = NULL;
-       uint64_t src_i = 0, tgt_i = 0;
-
-       if (src_field_path->root != tgt_field_path->root) {
-               goto end;
-       }
-
-       src_ft = borrow_root_field_type(ctx, src_field_path->root);
-       tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
-       BT_ASSERT(src_ft);
-       BT_ASSERT(tgt_ft);
-
-       while (src_i < src_field_path->indexes->len &&
-                       tgt_i < tgt_field_path->indexes->len) {
-               bool advance;
-               uint64_t src_index = bt_field_path_get_index_by_index_inline(
-                       src_field_path, src_i);
-               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
-                       tgt_field_path, tgt_i);
-
-               if (src_ft != tgt_ft) {
-                       if (!prev_ft) {
-                               /*
-                                * This is correct: the LCA is the root
-                                * scope field type, which must be a
-                                * structure field type.
-                                */
-                               break;
-                       }
-
-                       if (prev_ft->id != BT_FIELD_TYPE_ID_STRUCTURE) {
-                               is_valid = false;
-                       }
-
-                       break;
-               }
-
-               prev_ft = src_ft;
-               src_ft = borrow_child_field_type(src_ft, src_index, &advance);
-
-               if (advance) {
-                       src_i++;
-               }
-
-               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
-               if (advance) {
-                       tgt_i++;
-               }
-       }
-
-end:
-       return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool lca_to_target_has_struct_ft_only(struct bt_field_path *src_field_path,
-               struct bt_field_path *tgt_field_path,
-               struct bt_resolve_field_path_context *ctx)
-{
-       bool is_valid = true;
-       struct bt_field_type *src_ft;
-       struct bt_field_type *tgt_ft;
-       uint64_t src_i = 0, tgt_i = 0;
-
-       if (src_field_path->root != tgt_field_path->root) {
-               goto end;
-       }
-
-       src_ft = borrow_root_field_type(ctx, src_field_path->root);
-       tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
-       BT_ASSERT(src_ft);
-       BT_ASSERT(tgt_ft);
-       BT_ASSERT(src_ft == tgt_ft);
-
-       /* Find LCA */
-       while (src_i < src_field_path->indexes->len &&
-                       tgt_i < tgt_field_path->indexes->len) {
-               bool advance;
-               uint64_t src_index = bt_field_path_get_index_by_index_inline(
-                       src_field_path, src_i);
-               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
-                       tgt_field_path, tgt_i);
-
-               if (src_i != tgt_i) {
-                       /* Next FT is different: LCA is `tgt_ft` */
-                       break;
-               }
-
-               src_ft = borrow_child_field_type(src_ft, src_index, &advance);
-
-               if (advance) {
-                       src_i++;
-               }
-
-               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
-               if (advance) {
-                       tgt_i++;
-               }
-       }
-
-       /* Only structure field types to the target */
-       while (tgt_i < tgt_field_path->indexes->len) {
-               bool advance;
-               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
-                       tgt_field_path, tgt_i);
-
-               if (tgt_ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
-                               tgt_ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
-                               tgt_ft->id == BT_FIELD_TYPE_ID_VARIANT) {
-                       is_valid = false;
-                       goto end;
-               }
-
-               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
-
-               if (advance) {
-                       tgt_i++;
-               }
-       }
-
-end:
-       return is_valid;
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool field_path_is_valid(struct bt_field_type *src_ft,
-               struct bt_field_type *tgt_ft,
-               struct bt_resolve_field_path_context *ctx)
-{
-       bool is_valid = true;
-       struct bt_field_path *src_field_path = find_field_type_in_ctx(
-               src_ft, ctx);
-       struct bt_field_path *tgt_field_path = find_field_type_in_ctx(
-               tgt_ft, ctx);
-
-       if (!src_field_path) {
-               BT_ASSERT_PRE_MSG("Cannot find requesting field type in "
-                       "resolving context: %!+F", src_ft);
-               is_valid = false;
-               goto end;
-       }
-
-       if (!tgt_field_path) {
-               BT_ASSERT_PRE_MSG("Cannot find target field type in "
-                       "resolving context: %!+F", tgt_ft);
-               is_valid = false;
-               goto end;
-       }
-
-       /* Target must be before source */
-       if (!target_is_before_source(src_field_path, tgt_field_path)) {
-               BT_ASSERT_PRE_MSG("Target field type is located after "
-                       "requesting field type: %![req-ft-]+F, %![tgt-ft-]+F",
-                       src_ft, tgt_ft);
-               is_valid = false;
-               goto end;
-       }
-
-       /*
-        * If target is in a different scope than source, there are no
-        * array or variant field types on the way to the target.
-        */
-       if (!target_field_path_in_different_scope_has_struct_ft_only(
-                       src_field_path, tgt_field_path, ctx)) {
-               BT_ASSERT_PRE_MSG("Target field type is located in a "
-                       "different scope than requesting field type, "
-                       "but within an array or a variant field type: "
-                       "%![req-ft-]+F, %![tgt-ft-]+F",
-                       src_ft, tgt_ft);
-               is_valid = false;
-               goto end;
-       }
-
-       /* Same scope: LCA must be a structure field type */
-       if (!lca_is_structure_field_type(src_field_path, tgt_field_path, ctx)) {
-               BT_ASSERT_PRE_MSG("Lowest common ancestor of target and "
-                       "requesting field types is not a structure field type: "
-                       "%![req-ft-]+F, %![tgt-ft-]+F",
-                       src_ft, tgt_ft);
-               is_valid = false;
-               goto end;
-       }
-
-       /* Same scope: path from LCA to target has no array/variant FTs */
-       if (!lca_to_target_has_struct_ft_only(src_field_path, tgt_field_path,
-                       ctx)) {
-               BT_ASSERT_PRE_MSG("Path from lowest common ancestor of target "
-                       "and requesting field types to target field type "
-                       "contains an array or a variant field type: "
-                       "%![req-ft-]+F, %![tgt-ft-]+F", src_ft, tgt_ft);
-               is_valid = false;
-               goto end;
-       }
-
-end:
-       bt_put(src_field_path);
-       bt_put(tgt_field_path);
-       return is_valid;
-}
-
-static
-struct bt_field_path *resolve_field_path(struct bt_field_type *src_ft,
-               struct bt_field_type *tgt_ft,
-               struct bt_resolve_field_path_context *ctx)
-{
-       BT_ASSERT_PRE(field_path_is_valid(src_ft, tgt_ft, ctx),
-               "Invalid target field type: %![req-ft-]+F, %![tgt-ft-]+F",
-               src_ft, tgt_ft);
-       return find_field_type_in_ctx(tgt_ft, ctx);
-}
-
-BT_HIDDEN
-int bt_resolve_field_paths(struct bt_field_type *ft,
-               struct bt_resolve_field_path_context *ctx)
-{
-       int ret = 0;
-
-       BT_ASSERT(ft);
-
-       /* Resolving part for dynamic array and variant field types */
-       switch (ft->id) {
-       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
-       {
-               struct bt_field_type_dynamic_array *dyn_array_ft = (void *) ft;
-
-               if (dyn_array_ft->length_ft) {
-                       BT_ASSERT(!dyn_array_ft->length_field_path);
-                       dyn_array_ft->length_field_path = resolve_field_path(
-                               ft, dyn_array_ft->length_ft, ctx);
-                       if (!dyn_array_ft->length_field_path) {
-                               ret = -1;
-                               goto end;
-                       }
-               }
-
-               break;
-       }
-       case BT_FIELD_TYPE_ID_VARIANT:
-       {
-               struct bt_field_type_variant *var_ft = (void *) ft;
-
-               if (var_ft->selector_ft) {
-                       BT_ASSERT(!var_ft->selector_field_path);
-                       var_ft->selector_field_path =
-                               resolve_field_path(ft,
-                                       var_ft->selector_ft, ctx);
-                       if (!var_ft->selector_field_path) {
-                               ret = -1;
-                               goto end;
-                       }
-               }
-       }
-       default:
-               break;
-       }
-
-       /* Recursive part */
-       switch (ft->id) {
-       case BT_FIELD_TYPE_ID_STRUCTURE:
-       case BT_FIELD_TYPE_ID_VARIANT:
-       {
-               struct bt_field_type_named_field_types_container *container_ft =
-                       (void *) ft;
-               uint64_t i;
-
-               for (i = 0; i < container_ft->named_fts->len; i++) {
-                       struct bt_named_field_type *named_ft =
-                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
-                                       container_ft, i);
-
-                       ret = bt_resolve_field_paths(named_ft->ft, ctx);
-                       if (ret) {
-                               goto end;
-                       }
-               }
-
-               break;
-       }
-       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
-       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
-       {
-               struct bt_field_type_array *array_ft = (void *) ft;
-
-               ret = bt_resolve_field_paths(array_ft->element_ft, ctx);
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return ret;
-}
diff --git a/lib/ctf-ir/stream-class.c b/lib/ctf-ir/stream-class.c
deleted file mode 100644 (file)
index 69b9d5c..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * stream-class.c
- *
- * Babeltrace CTF IR - Stream Class
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "STREAM-CLASS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/property-internal.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define BT_ASSERT_PRE_STREAM_CLASS_HOT(_sc) \
-       BT_ASSERT_PRE_HOT((_sc), "Stream class", ": %!+S", (_sc))
-
-static
-void destroy_stream_class(struct bt_object *obj)
-{
-       struct bt_stream_class *stream_class = (void *) obj;
-
-       BT_LIB_LOGD("Destroying stream class: %!+S", stream_class);
-       BT_LOGD_STR("Putting default clock class.");
-       bt_put(stream_class->default_clock_class);
-
-       if (stream_class->event_classes) {
-               BT_LOGD_STR("Destroying event classes.");
-               g_ptr_array_free(stream_class->event_classes, TRUE);
-       }
-
-       if (stream_class->name.str) {
-               g_string_free(stream_class->name.str, TRUE);
-       }
-
-       BT_LOGD_STR("Putting event header field type.");
-       bt_put(stream_class->event_header_ft);
-       BT_LOGD_STR("Putting packet context field type.");
-       bt_put(stream_class->packet_context_ft);
-       BT_LOGD_STR("Putting event common context field type.");
-       bt_put(stream_class->event_common_context_ft);
-       bt_object_pool_finalize(&stream_class->event_header_field_pool);
-       bt_object_pool_finalize(&stream_class->packet_context_field_pool);
-       g_free(stream_class);
-}
-
-static
-void free_field_wrapper(struct bt_field_wrapper *field_wrapper,
-               struct bt_stream_class *stream_class)
-{
-       bt_field_wrapper_destroy((void *) field_wrapper);
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool stream_class_id_is_unique(struct bt_trace *trace, uint64_t id)
-{
-       uint64_t i;
-       bool is_unique = true;
-
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               struct bt_stream_class *sc =
-                       trace->stream_classes->pdata[i];
-
-               if (sc->id == id) {
-                       is_unique = false;
-                       goto end;
-               }
-       }
-
-end:
-       return is_unique;
-}
-
-static
-struct bt_stream_class *create_stream_class_with_id(struct bt_trace *trace,
-               uint64_t id)
-{
-       struct bt_stream_class *stream_class = NULL;
-       int ret;
-
-       BT_ASSERT(trace);
-       BT_ASSERT_PRE(stream_class_id_is_unique(trace, id),
-               "Duplicate stream class ID: %![trace-]+t, id=%" PRIu64,
-               trace, id);
-       BT_LIB_LOGD("Creating stream class object: %![trace-]+t, id=%" PRIu64,
-               trace, id);
-       stream_class = g_new0(struct bt_stream_class, 1);
-       if (!stream_class) {
-               BT_LOGE_STR("Failed to allocate one stream class.");
-               goto error;
-       }
-
-       bt_object_init_shared_with_parent(&stream_class->base,
-               destroy_stream_class);
-
-       stream_class->name.str = g_string_new(NULL);
-       if (!stream_class->name.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               ret = -1;
-               goto end;
-       }
-
-       stream_class->id = id;
-       stream_class->assigns_automatic_event_class_id = true;
-       stream_class->assigns_automatic_stream_id = true;
-       stream_class->event_classes = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_try_spec_release);
-       if (!stream_class->event_classes) {
-               BT_LOGE_STR("Failed to allocate a GPtrArray.");
-               goto error;
-       }
-
-       ret = bt_object_pool_initialize(&stream_class->event_header_field_pool,
-               (bt_object_pool_new_object_func) bt_field_wrapper_new,
-               (bt_object_pool_destroy_object_func) free_field_wrapper,
-               stream_class);
-       if (ret) {
-               BT_LOGE("Failed to initialize event header field pool: ret=%d",
-                       ret);
-               goto error;
-       }
-
-       ret = bt_object_pool_initialize(&stream_class->packet_context_field_pool,
-               (bt_object_pool_new_object_func) bt_field_wrapper_new,
-               (bt_object_pool_destroy_object_func) free_field_wrapper,
-               stream_class);
-       if (ret) {
-               BT_LOGE("Failed to initialize packet context field pool: ret=%d",
-                       ret);
-               goto error;
-       }
-
-       bt_object_set_parent(&stream_class->base, &trace->base);
-       g_ptr_array_add(trace->stream_classes, stream_class);
-       bt_trace_freeze(trace);
-       BT_LIB_LOGD("Created stream class object: %!+S", stream_class);
-       goto end;
-
-error:
-       BT_PUT(stream_class);
-
-end:
-       return stream_class;
-}
-
-struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE(trace->assigns_automatic_stream_class_id,
-               "Trace does not automatically assigns stream class IDs: "
-               "%![sc-]+t", trace);
-       return create_stream_class_with_id(trace,
-               (uint64_t) trace->stream_classes->len);
-}
-
-struct bt_stream_class *bt_stream_class_create_with_id(
-               struct bt_trace *trace, uint64_t id)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE(!trace->assigns_automatic_stream_class_id,
-               "Trace automatically assigns stream class IDs: "
-               "%![sc-]+t", trace);
-       return create_stream_class_with_id(trace, id);
-}
-
-struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return bt_stream_class_borrow_trace_inline(stream_class);
-}
-
-const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->name.value;
-}
-
-int bt_stream_class_set_name(struct bt_stream_class *stream_class,
-               const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       g_string_assign(stream_class->name.str, name);
-       stream_class->name.value = stream_class->name.str->str;
-       BT_LIB_LOGV("Set stream class's name: %!+S", stream_class);
-       return 0;
-}
-
-uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->id;
-}
-
-uint64_t bt_stream_class_get_event_class_count(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (uint64_t) stream_class->event_classes->len;
-}
-
-struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
-               struct bt_stream_class *stream_class, uint64_t index)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_VALID_INDEX(index, stream_class->event_classes->len);
-       return g_ptr_array_index(stream_class->event_classes, index);
-}
-
-struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
-               struct bt_stream_class *trace, uint64_t id)
-{
-       struct bt_event_class *event_class = NULL;
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
-       for (i = 0; i < trace->event_classes->len; i++) {
-               struct bt_event_class *event_class_candidate =
-                       g_ptr_array_index(trace->event_classes, i);
-
-               if (event_class_candidate->id == id) {
-                       event_class = event_class_candidate;
-                       goto end;
-               }
-       }
-
-end:
-       return event_class;
-}
-
-struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->packet_context_ft;
-}
-
-int bt_stream_class_set_packet_context_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = NULL,
-               .packet_context = field_type,
-               .event_header = NULL,
-               .event_common_context = NULL,
-               .event_specific_context = NULL,
-               .event_payload = NULL,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Packet context field type is not a structure field type: %!+F",
-               field_type);
-       resolve_ctx.packet_header =
-               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(stream_class->packet_context_ft);
-       stream_class->packet_context_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set stream class's packet context field type: %!+S",
-               stream_class);
-
-end:
-       return ret;
-}
-
-struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->event_header_ft;
-}
-
-int bt_stream_class_set_event_header_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = NULL,
-               .packet_context = NULL,
-               .event_header = field_type,
-               .event_common_context = NULL,
-               .event_specific_context = NULL,
-               .event_payload = NULL,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Event header field type is not a structure field type: %!+F",
-               field_type);
-       resolve_ctx.packet_header =
-               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
-       resolve_ctx.packet_context = stream_class->packet_context_ft;
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(stream_class->event_header_ft);
-       stream_class->event_header_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set stream class's event header field type: %!+S",
-               stream_class);
-
-end:
-       return ret;
-}
-
-struct bt_field_type *bt_stream_class_borrow_event_common_context_field_type(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->event_common_context_ft;
-}
-
-int bt_stream_class_set_event_common_context_field_type(
-               struct bt_stream_class *stream_class,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = NULL,
-               .packet_context = NULL,
-               .event_header = NULL,
-               .event_common_context = field_type,
-               .event_specific_context = NULL,
-               .event_payload = NULL,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Event common context field type is not a structure field type: %!+F",
-               field_type);
-       resolve_ctx.packet_header =
-               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
-       resolve_ctx.packet_context = stream_class->packet_context_ft;
-       resolve_ctx.event_header = stream_class->event_header_ft;
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(stream_class->event_common_context_ft);
-       stream_class->event_common_context_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set stream class's event common context field type: %!+S",
-               stream_class);
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void _bt_stream_class_freeze(struct bt_stream_class *stream_class)
-{
-       /* The field types and default clock class are already frozen */
-       BT_ASSERT(stream_class);
-       BT_LIB_LOGD("Freezing stream class: %!+S", stream_class);
-       stream_class->frozen = true;
-}
-
-int bt_stream_class_set_default_clock_class(
-               struct bt_stream_class *stream_class,
-               struct bt_clock_class *clock_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       bt_put(stream_class->default_clock_class);
-       stream_class->default_clock_class = bt_get(clock_class);
-       bt_clock_class_freeze(clock_class);
-       BT_LIB_LOGV("Set stream class's default clock class: %!+S",
-               stream_class);
-       return 0;
-}
-
-struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return stream_class->default_clock_class;
-}
-
-bt_bool bt_stream_class_assigns_automatic_event_class_id(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->assigns_automatic_event_class_id;
-}
-
-int bt_stream_class_set_assigns_automatic_event_class_id(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       stream_class->assigns_automatic_event_class_id = (bool) value;
-       BT_LIB_LOGV("Set stream class's automatic event class ID "
-               "assignment property: %!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_assigns_automatic_stream_id(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->assigns_automatic_stream_id;
-}
-
-int bt_stream_class_set_assigns_automatic_stream_id(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       stream_class->assigns_automatic_stream_id = (bool) value;
-       BT_LIB_LOGV("Set stream class's automatic stream ID "
-               "assignment property: %!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->packets_have_discarded_event_counter_snapshot;
-}
-
-int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       stream_class->packets_have_discarded_event_counter_snapshot =
-               (bool) value;
-       BT_LIB_LOGV("Set stream class's "
-               "\"packets have discarded event counter snapshot\" property: "
-               "%!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->packets_have_packet_counter_snapshot;
-}
-
-int bt_stream_class_set_packets_have_packet_counter_snapshot(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       stream_class->packets_have_packet_counter_snapshot =
-               (bool) value;
-       BT_LIB_LOGV("Set stream class's "
-               "\"packets have packet counter snapshot\" property: "
-               "%!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->packets_have_default_beginning_cv;
-}
-
-int bt_stream_class_set_packets_have_default_beginning_clock_value(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       BT_ASSERT_PRE(!value || stream_class->default_clock_class,
-               "Stream class does not have a default clock class: %!+S",
-               stream_class);
-       stream_class->packets_have_default_beginning_cv = (bool) value;
-       BT_LIB_LOGV("Set stream class's "
-               "\"packets have default beginning clock value\" property: "
-               "%!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_packets_have_default_end_clock_value(
-               struct bt_stream_class *stream_class)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       return (bt_bool) stream_class->packets_have_default_end_cv;
-}
-
-int bt_stream_class_set_packets_have_default_end_clock_value(
-               struct bt_stream_class *stream_class, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
-       BT_ASSERT_PRE(!value || stream_class->default_clock_class,
-               "Stream class does not have a default clock class: %!+S",
-               stream_class);
-       stream_class->packets_have_default_end_cv = (bool) value;
-       BT_LIB_LOGV("Set stream class's "
-               "\"packets have default end clock value\" property: "
-               "%!+S", stream_class);
-       return 0;
-}
-
-bt_bool bt_stream_class_default_clock_is_always_known(
-               struct bt_stream_class *stream_class)
-{
-       /* BT_CLOCK_VALUE_STATUS_UNKNOWN is not supported as of 2.0 */
-       return BT_TRUE;
-}
diff --git a/lib/ctf-ir/stream.c b/lib/ctf-ir/stream.c
deleted file mode 100644 (file)
index 665347a..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * stream.c
- *
- * Babeltrace CTF IR - Stream
- *
- * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "STREAM"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/align-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/property-internal.h>
-#include <inttypes.h>
-#include <unistd.h>
-
-#define BT_ASSERT_PRE_STREAM_HOT(_stream) \
-       BT_ASSERT_PRE_HOT((_stream), "Stream", ": %!+s", (_stream))
-
-static
-void destroy_stream(struct bt_object *obj)
-{
-       struct bt_stream *stream = (void *) obj;
-
-       BT_LIB_LOGD("Destroying stream object: %!+s", stream);
-
-       if (stream->name.str) {
-               g_string_free(stream->name.str, TRUE);
-       }
-
-       bt_object_pool_finalize(&stream->packet_pool);
-       g_free(stream);
-}
-
-static
-void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
-{
-       bt_packet_destroy(packet);
-}
-
-BT_ASSERT_PRE_FUNC
-static inline
-bool stream_id_is_unique(struct bt_trace *trace,
-               struct bt_stream_class *stream_class, uint64_t id)
-{
-       uint64_t i;
-       bool is_unique = true;
-
-       for (i = 0; i < trace->streams->len; i++) {
-               struct bt_stream *stream = trace->streams->pdata[i];
-
-               if (stream->class != stream_class) {
-                       continue;
-               }
-
-               if (stream->id == id) {
-                       is_unique = false;
-                       goto end;
-               }
-       }
-
-end:
-       return is_unique;
-}
-
-static
-struct bt_stream *create_stream_with_id(struct bt_stream_class *stream_class,
-                 uint64_t id)
-{
-       int ret;
-       struct bt_stream *stream;
-       struct bt_trace *trace;
-
-       BT_ASSERT(stream_class);
-       trace = bt_stream_class_borrow_trace_inline(stream_class);
-       BT_ASSERT_PRE(stream_id_is_unique(trace, stream_class, id),
-               "Duplicate stream ID: %![trace-]+t, id=%" PRIu64, trace, id);
-       BT_ASSERT_PRE(!trace->is_static,
-               "Trace is static: %![trace-]+t", trace);
-       BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64,
-               trace, id);
-       stream = g_new0(struct bt_stream, 1);
-       if (!stream) {
-               BT_LOGE_STR("Failed to allocate one stream.");
-               goto error;
-       }
-
-       bt_object_init_shared_with_parent(&stream->base, destroy_stream);
-       stream->name.str = g_string_new(NULL);
-       if (!stream->name.str) {
-               BT_LOGE_STR("Failed to allocate a GString.");
-               goto error;
-       }
-
-       stream->id = id;
-       ret = bt_object_pool_initialize(&stream->packet_pool,
-               (bt_object_pool_new_object_func) bt_packet_new,
-               (bt_object_pool_destroy_object_func) bt_stream_free_packet,
-               stream);
-       if (ret) {
-               BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
-               goto error;
-       }
-
-       stream->class = stream_class;
-       bt_trace_add_stream(trace, stream);
-       bt_stream_class_freeze(stream_class);
-       BT_LIB_LOGD("Created stream object: %!+s", stream);
-       goto end;
-
-error:
-       BT_PUT(stream);
-
-end:
-       return stream;
-}
-
-struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class)
-{
-       uint64_t id;
-
-       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
-       BT_ASSERT_PRE(stream_class->assigns_automatic_stream_id,
-               "Stream class does not automatically assigns stream IDs: "
-               "%![sc-]+S", stream_class);
-       id = bt_trace_get_automatic_stream_id(
-                       bt_stream_class_borrow_trace_inline(stream_class),
-                       stream_class);
-       return create_stream_with_id(stream_class, id);
-}
-
-struct bt_stream *bt_stream_create_with_id(struct bt_stream_class *stream_class,
-               uint64_t id)
-{
-       BT_ASSERT_PRE(!stream_class->assigns_automatic_stream_id,
-               "Stream class automatically assigns stream IDs: "
-               "%![sc-]+S", stream_class);
-       return create_stream_with_id(stream_class, id);
-}
-
-struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
-{
-       BT_ASSERT_PRE_NON_NULL(stream, "Stream");
-       return stream->class;
-}
-
-const char *bt_stream_get_name(struct bt_stream *stream)
-{
-       BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
-       return stream->name.value;
-}
-
-int bt_stream_set_name(struct bt_stream *stream, const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(stream, "Clock class");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_STREAM_HOT(stream);
-       g_string_assign(stream->name.str, name);
-       stream->name.value = stream->name.str->str;
-       BT_LIB_LOGV("Set stream class's name: %!+S", stream);
-       return 0;
-}
-
-uint64_t bt_stream_get_id(struct bt_stream *stream)
-{
-       BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
-       return stream->id;
-}
-
-BT_HIDDEN
-void _bt_stream_freeze(struct bt_stream *stream)
-{
-       /* The field types and default clock class are already frozen */
-       BT_ASSERT(stream);
-       BT_LIB_LOGD("Freezing stream: %!+s", stream);
-       stream->frozen = true;
-}
diff --git a/lib/ctf-ir/trace.c b/lib/ctf-ir/trace.c
deleted file mode 100644 (file)
index 69189c4..0000000
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * trace.c
- *
- * Babeltrace CTF IR - Trace
- *
- * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "TRACE"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-ir/field-wrapper-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
-#include <babeltrace/ctf-ir/resolve-field-path-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/values-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/types.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/compat/glib-internal.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-
-struct bt_trace_is_static_listener_elem {
-       bt_trace_is_static_listener func;
-       bt_trace_listener_removed removed;
-       void *data;
-};
-
-#define BT_ASSERT_PRE_TRACE_HOT(_trace) \
-       BT_ASSERT_PRE_HOT((_trace), "Trace", ": %!+t", (_trace))
-
-static
-void destroy_trace(struct bt_object *obj)
-{
-       struct bt_trace *trace = (void *) obj;
-
-       BT_LIB_LOGD("Destroying trace object: %!+t", trace);
-
-       /*
-        * Call remove listeners first so that everything else still
-        * exists in the trace.
-        */
-       if (trace->is_static_listeners) {
-               size_t i;
-
-               for (i = 0; i < trace->is_static_listeners->len; i++) {
-                       struct bt_trace_is_static_listener_elem elem =
-                               g_array_index(trace->is_static_listeners,
-                                       struct bt_trace_is_static_listener_elem, i);
-
-                       if (elem.removed) {
-                               elem.removed(trace, elem.data);
-                       }
-               }
-
-               g_array_free(trace->is_static_listeners, TRUE);
-       }
-
-       bt_object_pool_finalize(&trace->packet_header_field_pool);
-
-       if (trace->environment) {
-               BT_LOGD_STR("Destroying environment attributes.");
-               bt_attributes_destroy(trace->environment);
-       }
-
-       if (trace->name.str) {
-               g_string_free(trace->name.str, TRUE);
-       }
-
-       if (trace->streams) {
-               BT_LOGD_STR("Destroying streams.");
-               g_ptr_array_free(trace->streams, TRUE);
-       }
-
-       if (trace->stream_classes) {
-               BT_LOGD_STR("Destroying stream classes.");
-               g_ptr_array_free(trace->stream_classes, TRUE);
-       }
-
-       if (trace->stream_classes_stream_count) {
-               g_hash_table_destroy(trace->stream_classes_stream_count);
-       }
-
-       BT_LOGD_STR("Putting packet header field type.");
-       bt_put(trace->packet_header_ft);
-       g_free(trace);
-}
-
-static
-void free_packet_header_field(struct bt_field_wrapper *field_wrapper,
-               struct bt_trace *trace)
-{
-       bt_field_wrapper_destroy(field_wrapper);
-}
-
-struct bt_trace *bt_trace_create(void)
-{
-       struct bt_trace *trace = NULL;
-       int ret;
-
-       BT_LOGD_STR("Creating default trace object.");
-       trace = g_new0(struct bt_trace, 1);
-       if (!trace) {
-               BT_LOGE_STR("Failed to allocate one trace.");
-               goto error;
-       }
-
-       bt_object_init_shared_with_parent(&trace->base, destroy_trace);
-       trace->streams = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_try_spec_release);
-       if (!trace->streams) {
-               BT_LOGE_STR("Failed to allocate one GPtrArray.");
-               goto error;
-       }
-
-       trace->stream_classes = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_try_spec_release);
-       if (!trace->stream_classes) {
-               BT_LOGE_STR("Failed to allocate one GPtrArray.");
-               goto error;
-       }
-
-       trace->stream_classes_stream_count = g_hash_table_new(g_direct_hash,
-               g_direct_equal);
-       if (!trace->stream_classes_stream_count) {
-               BT_LOGE_STR("Failed to allocate one GHashTable.");
-               goto error;
-       }
-
-       trace->name.str = g_string_new(NULL);
-       if (!trace->name.str) {
-               BT_LOGE_STR("Failed to allocate one GString.");
-               goto error;
-       }
-
-       trace->environment = bt_attributes_create();
-       if (!trace->environment) {
-               BT_LOGE_STR("Cannot create empty attributes object.");
-               goto error;
-       }
-
-       trace->is_static_listeners = g_array_new(FALSE, TRUE,
-               sizeof(struct bt_trace_is_static_listener_elem));
-       if (!trace->is_static_listeners) {
-               BT_LOGE_STR("Failed to allocate one GArray.");
-               goto error;
-       }
-
-       trace->assigns_automatic_stream_class_id = true;
-       ret = bt_object_pool_initialize(&trace->packet_header_field_pool,
-               (bt_object_pool_new_object_func) bt_field_wrapper_new,
-               (bt_object_pool_destroy_object_func) free_packet_header_field,
-               trace);
-       if (ret) {
-               BT_LOGE("Failed to initialize packet header field pool: ret=%d",
-                       ret);
-               goto error;
-       }
-
-       BT_LIB_LOGD("Created trace object: %!+t", trace);
-       goto end;
-
-error:
-       BT_PUT(trace);
-
-end:
-       return trace;
-}
-
-const char *bt_trace_get_name(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return trace->name.value;
-}
-
-int bt_trace_set_name(struct bt_trace *trace, const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_TRACE_HOT(trace);
-       g_string_assign(trace->name.str, name);
-       trace->name.value = trace->name.str->str;
-       BT_LIB_LOGV("Set trace's name: %!+t", trace);
-       return 0;
-}
-
-bt_uuid bt_trace_get_uuid(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return trace->uuid.value;
-}
-
-int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
-       BT_ASSERT_PRE_TRACE_HOT(trace);
-       memcpy(trace->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
-       trace->uuid.value = trace->uuid.uuid;
-       BT_LIB_LOGV("Set trace's UUID: %!+t", trace);
-       return 0;
-}
-
-BT_ASSERT_FUNC
-static
-bool trace_has_environment_entry(struct bt_trace *trace, const char *name)
-{
-       struct bt_value *attribute;
-
-       BT_ASSERT(trace);
-
-       attribute = bt_attributes_borrow_field_value_by_name(
-               trace->environment, name);
-       return attribute != NULL;
-}
-
-static
-int set_environment_entry(struct bt_trace *trace, const char *name,
-               struct bt_value *value)
-{
-       int ret;
-
-       BT_ASSERT(trace);
-       BT_ASSERT(name);
-       BT_ASSERT(value);
-       BT_ASSERT_PRE(!trace->frozen ||
-               !trace_has_environment_entry(trace, name),
-               "Trace is frozen: cannot replace environment entry: "
-               "%![trace-]+t, entry-name=\"%s\"", trace, name);
-       ret = bt_attributes_set_field_value(trace->environment, name,
-               value);
-       bt_value_freeze(value);
-       if (ret) {
-               BT_LIB_LOGE("Cannot set trace's environment entry: "
-                       "%![trace-]+t, entry-name=\"%s\"", trace, name);
-       } else {
-               BT_LIB_LOGV("Set trace's environment entry: "
-                       "%![trace-]+t, entry-name=\"%s\"", trace, name);
-       }
-
-       return ret;
-}
-
-int bt_trace_set_environment_entry_string(struct bt_trace *trace,
-               const char *name, const char *value)
-{
-       int ret;
-       struct bt_value *value_obj;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_NON_NULL(value, "Value");
-       value_obj = bt_value_string_create_init(value);
-       if (!value_obj) {
-               BT_LOGE_STR("Cannot create a string value object.");
-               ret = -1;
-               goto end;
-       }
-
-       /* set_environment_entry() logs errors */
-       ret = set_environment_entry(trace, name, value_obj);
-
-end:
-       bt_put(value_obj);
-       return ret;
-}
-
-int bt_trace_set_environment_entry_integer(
-               struct bt_trace *trace, const char *name, int64_t value)
-{
-       int ret;
-       struct bt_value *value_obj;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       value_obj = bt_value_integer_create_init(value);
-       if (!value_obj) {
-               BT_LOGE_STR("Cannot create an integer value object.");
-               ret = -1;
-               goto end;
-       }
-
-       /* set_environment_entry() logs errors */
-       ret = set_environment_entry(trace, name, value_obj);
-
-end:
-       bt_put(value_obj);
-       return ret;
-}
-
-uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace)
-{
-       int64_t ret;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       ret = bt_attributes_get_count(trace->environment);
-       BT_ASSERT(ret >= 0);
-       return (uint64_t) ret;
-}
-
-void bt_trace_borrow_environment_entry_by_index(
-               struct bt_trace *trace, uint64_t index,
-               const char **name, struct bt_value **value)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       BT_ASSERT_PRE_NON_NULL(value, "Value");
-       BT_ASSERT_PRE_VALID_INDEX(index,
-               bt_attributes_get_count(trace->environment));
-       *value = bt_attributes_borrow_field_value(trace->environment, index);
-       BT_ASSERT(*value);
-       *name = bt_attributes_get_field_name(trace->environment, index);
-       BT_ASSERT(*name);
-}
-
-struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
-               struct bt_trace *trace, const char *name)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(name, "Name");
-       return bt_attributes_borrow_field_value_by_name(trace->environment,
-               name);
-}
-
-uint64_t bt_trace_get_stream_count(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return (uint64_t) trace->streams->len;
-}
-
-struct bt_stream *bt_trace_borrow_stream_by_index(
-               struct bt_trace *trace, uint64_t index)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_VALID_INDEX(index, trace->streams->len);
-       return g_ptr_array_index(trace->streams, index);
-}
-
-struct bt_stream *bt_trace_borrow_stream_by_id(
-               struct bt_trace *trace, uint64_t id)
-{
-       struct bt_stream *stream = NULL;
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
-       for (i = 0; i < trace->streams->len; i++) {
-               struct bt_stream *stream_candidate =
-                       g_ptr_array_index(trace->streams, i);
-
-               if (stream_candidate->id == id) {
-                       stream = stream_candidate;
-                       goto end;
-               }
-       }
-
-end:
-       return stream;
-}
-
-uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return (uint64_t) trace->stream_classes->len;
-}
-
-struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
-               struct bt_trace *trace, uint64_t index)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_VALID_INDEX(index, trace->stream_classes->len);
-       return g_ptr_array_index(trace->stream_classes, index);
-}
-
-struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
-               struct bt_trace *trace, uint64_t id)
-{
-       struct bt_stream_class *stream_class = NULL;
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               struct bt_stream_class *stream_class_candidate =
-                       g_ptr_array_index(trace->stream_classes, i);
-
-               if (stream_class_candidate->id == id) {
-                       stream_class = stream_class_candidate;
-                       goto end;
-               }
-       }
-
-end:
-       return stream_class;
-}
-
-struct bt_field_type *bt_trace_borrow_packet_header_field_type(
-               struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return trace->packet_header_ft;
-}
-
-int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
-               struct bt_field_type *field_type)
-{
-       int ret;
-       struct bt_resolve_field_path_context resolve_ctx = {
-               .packet_header = field_type,
-               .packet_context = NULL,
-               .event_header = NULL,
-               .event_common_context = NULL,
-               .event_specific_context = NULL,
-               .event_payload = NULL,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
-       BT_ASSERT_PRE_TRACE_HOT(trace);
-       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
-               BT_FIELD_TYPE_ID_STRUCTURE,
-               "Packet header field type is not a structure field type: %!+F",
-               field_type);
-       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
-       if (ret) {
-               goto end;
-       }
-
-       bt_field_type_make_part_of_trace(field_type);
-       bt_put(trace->packet_header_ft);
-       trace->packet_header_ft = bt_get(field_type);
-       bt_field_type_freeze(field_type);
-       BT_LIB_LOGV("Set trace's packet header field type: %!+t", trace);
-
-end:
-       return ret;
-}
-
-bt_bool bt_trace_is_static(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return (bt_bool) trace->is_static;
-}
-
-int bt_trace_make_static(struct bt_trace *trace)
-{
-       uint64_t i;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       trace->is_static = true;
-       bt_trace_freeze(trace);
-       BT_LIB_LOGV("Trace is now static: %!+t", trace);
-
-       /* Call all the "trace is static" listeners */
-       for (i = 0; i < trace->is_static_listeners->len; i++) {
-               struct bt_trace_is_static_listener_elem elem =
-                       g_array_index(trace->is_static_listeners,
-                               struct bt_trace_is_static_listener_elem, i);
-
-               if (elem.func) {
-                       elem.func(trace, elem.data);
-               }
-       }
-
-       return 0;
-}
-
-int bt_trace_add_is_static_listener(struct bt_trace *trace,
-               bt_trace_is_static_listener listener,
-               bt_trace_listener_removed listener_removed, void *data,
-               uint64_t *listener_id)
-{
-       uint64_t i;
-       struct bt_trace_is_static_listener_elem new_elem = {
-               .func = listener,
-               .removed = listener_removed,
-               .data = data,
-       };
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_NON_NULL(listener, "Listener");
-       BT_ASSERT_PRE(!trace->is_static,
-               "Trace is already static: %!+t", trace);
-       BT_ASSERT_PRE(trace->in_remove_listener,
-               "Cannot call this function while executing a "
-               "remove listener: %!+t", trace);
-
-       /* Find the next available spot */
-       for (i = 0; i < trace->is_static_listeners->len; i++) {
-               struct bt_trace_is_static_listener_elem elem =
-                       g_array_index(trace->is_static_listeners,
-                               struct bt_trace_is_static_listener_elem, i);
-
-               if (!elem.func) {
-                       break;
-               }
-       }
-
-       if (i == trace->is_static_listeners->len) {
-               g_array_append_val(trace->is_static_listeners, new_elem);
-       } else {
-               g_array_insert_val(trace->is_static_listeners, i, new_elem);
-       }
-
-       if (listener_id) {
-               *listener_id = i;
-       }
-
-       BT_LIB_LOGV("Added \"trace is static\" listener: "
-               "%![trace-]+t, listener-id=%" PRIu64, trace, i);
-       return 0;
-}
-
-BT_ASSERT_PRE_FUNC
-static
-bool has_listener_id(struct bt_trace *trace, uint64_t listener_id)
-{
-       BT_ASSERT(listener_id < trace->is_static_listeners->len);
-       return (&g_array_index(trace->is_static_listeners,
-                       struct bt_trace_is_static_listener_elem,
-                       listener_id))->func != NULL;
-}
-
-int bt_trace_remove_is_static_listener(
-               struct bt_trace *trace, uint64_t listener_id)
-{
-       struct bt_trace_is_static_listener_elem *elem;
-
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE(!trace->is_static,
-               "Trace is already static: %!+t", trace);
-       BT_ASSERT_PRE(trace->in_remove_listener,
-               "Cannot call this function while executing a "
-               "remove listener: %!+t", trace);
-       BT_ASSERT_PRE(has_listener_id(trace, listener_id),
-               "Trace has no such \"trace is static\" listener ID: "
-               "%![trace-]+t, %" PRIu64, trace, listener_id);
-       elem = &g_array_index(trace->is_static_listeners,
-                       struct bt_trace_is_static_listener_elem,
-                       listener_id);
-       BT_ASSERT(elem->func);
-
-       if (elem->removed) {
-               /* Call remove listener */
-               BT_LIB_LOGV("Calling remove listener: "
-                       "%![trace-]+t, listener-id=%" PRIu64,
-                       trace, listener_id);
-               trace->in_remove_listener = true;
-               elem->removed(trace, elem->data);
-               trace->in_remove_listener = false;
-       }
-
-       elem->func = NULL;
-       elem->removed = NULL;
-       elem->data = NULL;
-       BT_LIB_LOGV("Removed \"trace is static\" listener: "
-               "%![trace-]+t, listener-id=%" PRIu64,
-               trace, listener_id);
-       return 0;
-}
-
-BT_HIDDEN
-void _bt_trace_freeze(struct bt_trace *trace)
-{
-       /* The packet header field type is already frozen */
-       BT_ASSERT(trace);
-       BT_LIB_LOGD("Freezing trace: %!+t", trace);
-       trace->frozen = true;
-}
-
-bt_bool bt_trace_assigns_automatic_stream_class_id(struct bt_trace *trace)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       return (bt_bool) trace->assigns_automatic_stream_class_id;
-}
-
-int bt_trace_set_assigns_automatic_stream_class_id(
-               struct bt_trace *trace, bt_bool value)
-{
-       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
-       BT_ASSERT_PRE_TRACE_HOT(trace);
-       trace->assigns_automatic_stream_class_id = (bool) value;
-       BT_LIB_LOGV("Set trace's automatic stream class ID "
-               "assignment property: %!+t", trace);
-       return 0;
-}
-
-BT_HIDDEN
-void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream)
-{
-       guint count = 0;
-
-       bt_object_set_parent(&stream->base, &trace->base);
-       g_ptr_array_add(trace->streams, stream);
-       bt_trace_freeze(trace);
-
-       if (bt_g_hash_table_contains(trace->stream_classes_stream_count,
-                       stream->class)) {
-               count = GPOINTER_TO_UINT(g_hash_table_lookup(
-                       trace->stream_classes_stream_count, stream->class));
-       }
-
-       g_hash_table_insert(trace->stream_classes_stream_count,
-               stream->class, GUINT_TO_POINTER(count + 1));
-}
-
-BT_HIDDEN
-uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
-               struct bt_stream_class *stream_class)
-{
-       gpointer orig_key;
-       gpointer value;
-       uint64_t id = 0;
-
-       BT_ASSERT(stream_class);
-       BT_ASSERT(trace);
-       if (g_hash_table_lookup_extended(trace->stream_classes_stream_count,
-                       stream_class, &orig_key, &value)) {
-               id = (uint64_t) GPOINTER_TO_UINT(value);
-       }
-
-       return id;
-}
diff --git a/lib/ctf-ir/utils.c b/lib/ctf-ir/utils.c
deleted file mode 100644 (file)
index 41337cf..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * utils.c
- *
- * Babeltrace CTF IR - Utilities
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#define BT_LOG_TAG "CTF-IR-UTILS"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <stdlib.h>
-#include <glib.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/assert-internal.h>
index fcc001004bc0f9632a8ab549c6d31b35d3e76052..a2111746793fa71a8def54e06bbc022a37cc66d7 100644 (file)
 
 #include <babeltrace/compiler-internal.h>
 #include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
 #include <babeltrace/graph/connection.h>
 #include <babeltrace/graph/connection-internal.h>
 #include <babeltrace/graph/component.h>
index 4b50d7fefe5496135eff1ad29b69d75ab273d6e5..d8178eca6fea9e62a4c1f5813704513a7667aea3 100644 (file)
 
 #include <babeltrace/compiler-internal.h>
 #include <babeltrace/object-internal.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace.h>
 #include <babeltrace/graph/graph-internal.h>
 #include <babeltrace/graph/notification-event-internal.h>
 #include <babeltrace/graph/private-connection-private-notification-iterator.h>
index 9523bb86bc77993a13847a710f7592b020819bd3..becf17e017e0e124730b640fc84270f6c3746982 100644 (file)
@@ -25,8 +25,8 @@
 
 #include <babeltrace/object-internal.h>
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
 #include <babeltrace/graph/notification-internal.h>
 #include <babeltrace/graph/notification-inactivity-internal.h>
 #include <babeltrace/graph/private-connection-private-notification-iterator.h>
index 70694e963bbfcc8645f236cafcaa2d309fe09c4a..8e02201d4539038b5a995da8557ebe6a8dcae6d7 100644 (file)
 #include <babeltrace/lib-logging-internal.h>
 
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
 #include <babeltrace/graph/graph-internal.h>
 #include <babeltrace/graph/notification-packet-internal.h>
 #include <babeltrace/graph/private-connection-private-notification-iterator.h>
index e6015c250d15b06b2b632e8881c6ecc2be8cdcbf..fbb0cc78489cc70a362656017bf5eed012c00a3e 100644 (file)
@@ -29,9 +29,9 @@
 
 #include <babeltrace/assert-pre-internal.h>
 #include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
 #include <babeltrace/graph/notification-stream-internal.h>
 #include <babeltrace/graph/private-connection-private-notification-iterator.h>
 #include <babeltrace/assert-internal.h>
index d09b176d41dde24d38995f96a75c6e45f8adc73c..56b41fc66fafe7e022fc62a865a0a40708cca810 100644 (file)
 #include <babeltrace/lib-logging-internal.h>
 #include <babeltrace/values-internal.h>
 #include <babeltrace/object-pool-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/clock-value-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/utils-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
 #include <babeltrace/graph/component-class-internal.h>
 #include <babeltrace/graph/component-class-sink-colander-internal.h>
 #include <babeltrace/graph/component-filter-internal.h>
diff --git a/lib/trace-ir/Makefile.am b/lib/trace-ir/Makefile.am
new file mode 100644 (file)
index 0000000..f2e1c3d
--- /dev/null
@@ -0,0 +1,23 @@
+noinst_LTLIBRARIES = libtrace-ir.la
+
+libtrace_ir_la_SOURCES = \
+       attributes.c \
+       clock-class.c \
+       clock-value.c \
+       event.c \
+       event-class.c \
+       event-header-field.c \
+       field-wrapper.c \
+       fields.c \
+       field-types.c \
+       field-path.c \
+       packet.c \
+       packet-context-field.c \
+       packet-header-field.c \
+       resolve-field-path.c \
+       stream.c \
+       stream-class.c \
+       trace.c \
+       utils.c
+
+libtrace_ir_la_LIBADD = $(UUID_LIBS)
diff --git a/lib/trace-ir/attributes.c b/lib/trace-ir/attributes.c
new file mode 100644 (file)
index 0000000..d43fd64
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * attributes.c
+ *
+ * Babeltrace trace IR - Attributes
+ *
+ * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "ATTRS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/ref.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/values-internal.h>
+#include <inttypes.h>
+#include <babeltrace/compat/string-internal.h>
+#include <babeltrace/assert-internal.h>
+
+#define BT_ATTR_NAME_INDEX             0
+#define BT_ATTR_VALUE_INDEX            1
+
+BT_HIDDEN
+struct bt_value *bt_attributes_create(void)
+{
+       struct bt_value *attr_obj;
+
+       /*
+        * Attributes: array value object of array value objects, each one
+        * containing two entries: a string value object (attributes
+        * field name), and a value object (attributes field value).
+        *
+        * Example (JSON representation):
+        *
+        *     [
+        *         ["hostname", "eeppdesk"],
+        *         ["sysname", "Linux"],
+        *         ["tracer_major", 2],
+        *         ["tracer_minor", 5]
+        *     ]
+        */
+       BT_LOGD_STR("Creating attributes object.");
+       attr_obj = bt_value_array_create();
+       if (!attr_obj) {
+               BT_LOGE_STR("Failed to create array value.");
+       } else {
+               BT_LOGD("Created attributes object: addr=%p",
+                       attr_obj);
+       }
+
+       return attr_obj;
+}
+
+BT_HIDDEN
+void bt_attributes_destroy(struct bt_value *attr_obj)
+{
+       BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
+       bt_put(attr_obj);
+}
+
+BT_HIDDEN
+int64_t bt_attributes_get_count(struct bt_value *attr_obj)
+{
+       return bt_value_array_size(attr_obj);
+}
+
+BT_HIDDEN
+const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
+               uint64_t index)
+{
+       int rc;
+       const char *ret = NULL;
+       struct bt_value *attr_field_obj = NULL;
+       struct bt_value *attr_field_name_obj = NULL;
+
+       if (!attr_obj) {
+               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+               goto end;
+       }
+
+       if (index >= bt_value_array_size(attr_obj)) {
+               BT_LOGW("Invalid parameter: index is out of bounds: "
+                       "index=%" PRIu64 ", count=%" PRId64,
+                       index, bt_value_array_size(attr_obj));
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_borrow(attr_obj, index);
+       if (!attr_field_obj) {
+               BT_LOGE("Cannot get attributes object's array value's element by index: "
+                       "value-addr=%p, index=%" PRIu64, attr_obj, index);
+               goto end;
+       }
+
+       attr_field_name_obj = bt_value_array_borrow(attr_field_obj,
+               BT_ATTR_NAME_INDEX);
+       if (!attr_field_name_obj) {
+               BT_LOGE("Cannot get attribute array value's element by index: "
+                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
+                       (uint64_t) BT_ATTR_NAME_INDEX);
+               goto end;
+       }
+
+       rc = bt_value_string_get(attr_field_name_obj, &ret);
+       if (rc) {
+               BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+                       attr_field_name_obj);
+               ret = NULL;
+       }
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value(struct bt_value *attr_obj,
+               uint64_t index)
+{
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
+
+       if (!attr_obj) {
+               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+               goto end;
+       }
+
+       if (index >= bt_value_array_size(attr_obj)) {
+               BT_LOGW("Invalid parameter: index is out of bounds: "
+                       "index=%" PRIu64 ", count=%" PRId64,
+                       index, bt_value_array_size(attr_obj));
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_borrow(attr_obj, index);
+       if (!attr_field_obj) {
+               BT_LOGE("Cannot get attributes object's array value's element by index: "
+                       "value-addr=%p, index=%" PRIu64, attr_obj, index);
+               goto end;
+       }
+
+       value_obj = bt_value_array_borrow(attr_field_obj,
+               BT_ATTR_VALUE_INDEX);
+       if (!value_obj) {
+               BT_LOGE("Cannot get attribute array value's element by index: "
+                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
+                       (uint64_t) BT_ATTR_VALUE_INDEX);
+       }
+
+end:
+       return value_obj;
+}
+
+static
+struct bt_value *bt_attributes_borrow_field_by_name(
+               struct bt_value *attr_obj, const char *name)
+{
+       uint64_t i;
+       int64_t attr_size;
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_name_obj = NULL;
+
+       attr_size = bt_value_array_size(attr_obj);
+       if (attr_size < 0) {
+               BT_LOGE("Cannot get array value's size: value-addr=%p",
+                       attr_obj);
+               goto error;
+       }
+
+       for (i = 0; i < attr_size; ++i) {
+               int ret;
+               const char *field_name;
+
+               value_obj = bt_value_array_borrow(attr_obj, i);
+               if (!value_obj) {
+                       BT_LOGE("Cannot get attributes object's array value's element by index: "
+                               "value-addr=%p, index=%" PRIu64, attr_obj, i);
+                       goto error;
+               }
+
+               attr_field_name_obj = bt_value_array_borrow(value_obj,
+                       BT_ATTR_NAME_INDEX);
+               if (!attr_field_name_obj) {
+                       BT_LOGE("Cannot get attribute array value's element by index: "
+                               "value-addr=%p, index=%" PRIu64,
+                               value_obj, (int64_t) BT_ATTR_NAME_INDEX);
+                       goto error;
+               }
+
+               ret = bt_value_string_get(attr_field_name_obj, &field_name);
+               if (ret) {
+                       BT_LOGE("Cannot get raw value from string value: value-addr=%p",
+                               attr_field_name_obj);
+                       goto error;
+               }
+
+               if (!strcmp(field_name, name)) {
+                       break;
+               }
+
+               value_obj = NULL;
+       }
+
+       return value_obj;
+
+error:
+       value_obj = NULL;
+       return value_obj;
+}
+
+BT_HIDDEN
+int bt_attributes_set_field_value(struct bt_value *attr_obj,
+               const char *name, struct bt_value *value_obj)
+{
+       int ret = 0;
+       struct bt_value *attr_field_obj = NULL;
+
+       if (!attr_obj || !name || !value_obj) {
+               BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
+                       "attr-value-addr=%p, name-addr=%p, value-addr=%p",
+                       attr_obj, name, value_obj);
+               ret = -1;
+               goto end;
+       }
+
+       attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
+       if (attr_field_obj) {
+               ret = bt_value_array_set(attr_field_obj,
+                       BT_ATTR_VALUE_INDEX, value_obj);
+               attr_field_obj = NULL;
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_create();
+       if (!attr_field_obj) {
+               BT_LOGE_STR("Failed to create empty array value.");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_value_array_append_string(attr_field_obj, name);
+       ret |= bt_value_array_append(attr_field_obj, value_obj);
+       if (ret) {
+               BT_LOGE("Cannot append elements to array value: addr=%p",
+                       attr_field_obj);
+               goto end;
+       }
+
+       ret = bt_value_array_append(attr_obj, attr_field_obj);
+       if (ret) {
+               BT_LOGE("Cannot append element to array value: "
+                       "array-value-addr=%p, element-value-addr=%p",
+                       attr_obj, attr_field_obj);
+       }
+
+end:
+       bt_put(attr_field_obj);
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_attributes_borrow_field_value_by_name(
+               struct bt_value *attr_obj, const char *name)
+{
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
+
+       if (!attr_obj || !name) {
+               BT_LOGW("Invalid parameter: attributes object or name is NULL: "
+                       "value-addr=%p, name-addr=%p", attr_obj, name);
+               goto end;
+       }
+
+       attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name);
+       if (!attr_field_obj) {
+               BT_LOGD("Cannot find attributes object's field by name: "
+                       "value-addr=%p, name=\"%s\"", attr_obj, name);
+               goto end;
+       }
+
+       value_obj = bt_value_array_borrow(attr_field_obj,
+               BT_ATTR_VALUE_INDEX);
+       if (!value_obj) {
+               BT_LOGE("Cannot get attribute array value's element by index: "
+                       "value-addr=%p, index=%" PRIu64, attr_field_obj,
+                       (uint64_t) BT_ATTR_VALUE_INDEX);
+       }
+
+end:
+       return value_obj;
+}
+
+BT_HIDDEN
+int bt_attributes_freeze(struct bt_value *attr_obj)
+{
+       uint64_t i;
+       int64_t count;
+       int ret = 0;
+
+       if (!attr_obj) {
+               BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
+               ret = -1;
+               goto end;
+       }
+
+       BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
+       count = bt_value_array_size(attr_obj);
+       BT_ASSERT(count >= 0);
+
+       /*
+        * We do not freeze the array value object itself here, since
+        * internal stuff could need to modify/add attributes. Each
+        * attribute is frozen one by one.
+        */
+       for (i = 0; i < count; ++i) {
+               struct bt_value *obj = NULL;
+
+               obj = bt_attributes_borrow_field_value(attr_obj, i);
+               if (!obj) {
+                       BT_LOGE("Cannot get attributes object's field value by index: "
+                               "value-addr=%p, index=%" PRIu64,
+                               attr_obj, i);
+                       ret = -1;
+                       goto end;
+               }
+
+               bt_value_freeze(obj);
+       }
+
+end:
+       return ret;
+}
diff --git a/lib/trace-ir/clock-class.c b/lib/trace-ir/clock-class.c
new file mode 100644 (file)
index 0000000..c8e5f3f
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * clock-class.c
+ *
+ * Babeltrace trace IR - Clock class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "CLOCK-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/compat/string-internal.h>
+#include <inttypes.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+
+#define BT_ASSERT_PRE_CLOCK_CLASS_HOT(_cc) \
+       BT_ASSERT_PRE_HOT((_cc), "Clock class", ": %!+K", (_cc))
+
+static
+void destroy_clock_class(struct bt_object *obj)
+{
+       struct bt_clock_class *clock_class = (void *) obj;
+
+       BT_LIB_LOGD("Destroying clock class: %!+K", clock_class);
+
+       if (clock_class->name.str) {
+               g_string_free(clock_class->name.str, TRUE);
+       }
+
+       if (clock_class->description.str) {
+               g_string_free(clock_class->description.str, TRUE);
+       }
+
+       bt_object_pool_finalize(&clock_class->cv_pool);
+       g_free(clock_class);
+}
+
+static
+void free_clock_value(struct bt_clock_value *clock_value,
+               struct bt_clock_class *clock_class)
+{
+       bt_clock_value_destroy(clock_value);
+}
+
+static inline
+void set_base_offset(struct bt_clock_class *clock_class)
+{
+       uint64_t offset_cycles_ns;
+
+       /* Initialize nanosecond timestamp to clock's offset in seconds */
+       if (clock_class->offset_seconds <= (INT64_MIN / INT64_C(1000000000) - 1) ||
+                       clock_class->offset_seconds >= (INT64_MAX / INT64_C(1000000000)) - 1) {
+               /*
+                * Overflow: offset in seconds converted to nanoseconds
+                * is outside the int64_t range. We also subtract 1 here
+                * to leave "space" for the offset in cycles converted
+                * to nanoseconds (which is always less than 1 second by
+                * contract).
+                */
+               clock_class->base_offset.overflows = true;
+               goto end;
+       }
+
+       /* Offset (seconds) to nanoseconds */
+       clock_class->base_offset.value_ns = clock_class->offset_seconds *
+               INT64_C(1000000000);
+
+       /* Add offset in cycles */
+       BT_ASSERT(clock_class->offset_cycles < clock_class->frequency);
+       offset_cycles_ns = bt_util_ns_from_value(clock_class->frequency,
+               clock_class->offset_cycles);
+       BT_ASSERT(offset_cycles_ns < 1000000000);
+       clock_class->base_offset.value_ns += (int64_t) offset_cycles_ns;
+       clock_class->base_offset.overflows = false;
+
+end:
+       return;
+}
+
+struct bt_clock_class *bt_clock_class_create(void)
+{
+       int ret;
+       struct bt_clock_class *clock_class = NULL;
+
+       BT_LOGD_STR("Creating default clock class object");
+
+       clock_class = g_new0(struct bt_clock_class, 1);
+       if (!clock_class) {
+               BT_LOGE_STR("Failed to allocate one clock class.");
+               goto error;
+       }
+
+       bt_object_init_shared(&clock_class->base, destroy_clock_class);
+       clock_class->name.str = g_string_new(NULL);
+       if (!clock_class->name.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               goto error;
+       }
+
+       clock_class->description.str = g_string_new(NULL);
+       if (!clock_class->description.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               goto error;
+       }
+
+       clock_class->frequency = UINT64_C(1000000000);
+       clock_class->is_absolute = BT_TRUE;
+       set_base_offset(clock_class);
+       ret = bt_object_pool_initialize(&clock_class->cv_pool,
+               (bt_object_pool_new_object_func) bt_clock_value_new,
+               (bt_object_pool_destroy_object_func)
+                       free_clock_value,
+               clock_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize clock value pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created clock class object: %!+K", clock_class);
+       goto end;
+
+error:
+       BT_PUT(clock_class);
+
+end:
+       return clock_class;
+}
+
+const char *bt_clock_class_get_name(
+               struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return clock_class->name.value;
+}
+
+int bt_clock_class_set_name(struct bt_clock_class *clock_class,
+               const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       g_string_assign(clock_class->name.str, name);
+       clock_class->name.value = clock_class->name.str->str;
+       BT_LIB_LOGV("Set clock class's name: %!+K", clock_class);
+       return 0;
+}
+
+const char *bt_clock_class_get_description(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return clock_class->description.value;
+}
+
+int bt_clock_class_set_description(struct bt_clock_class *clock_class,
+               const char *descr)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(descr, "Description");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       g_string_assign(clock_class->description.str, descr);
+       clock_class->description.value = clock_class->description.str->str;
+       BT_LIB_LOGV("Set clock class's description: %!+K",
+               clock_class);
+       return 0;
+}
+
+uint64_t bt_clock_class_get_frequency(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return clock_class->frequency;
+}
+
+int bt_clock_class_set_frequency(struct bt_clock_class *clock_class,
+               uint64_t frequency)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       BT_ASSERT_PRE(frequency != UINT64_C(-1) && frequency != 0,
+               "Invalid frequency: %![cc-]+K, new-freq=%" PRIu64,
+               clock_class, frequency);
+       BT_ASSERT_PRE(clock_class->offset_cycles < frequency,
+               "Offset (cycles) is greater than clock class's frequency: "
+               "%![cc-]+K, new-freq=%" PRIu64, clock_class, frequency);
+       clock_class->frequency = frequency;
+       set_base_offset(clock_class);
+       BT_LIB_LOGV("Set clock class's frequency: %!+K", clock_class);
+       return 0;
+}
+
+uint64_t bt_clock_class_get_precision(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return clock_class->precision;
+}
+
+int bt_clock_class_set_precision(struct bt_clock_class *clock_class,
+               uint64_t precision)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       BT_ASSERT_PRE(precision != UINT64_C(-1),
+               "Invalid precision: %![cc-]+K, new-precision=%" PRIu64,
+               clock_class, precision);
+       clock_class->precision = precision;
+       BT_LIB_LOGV("Set clock class's precision: %!+K", clock_class);
+       return 0;
+}
+
+void bt_clock_class_get_offset(struct bt_clock_class *clock_class,
+               int64_t *seconds, uint64_t *cycles)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(seconds, "Seconds (output)");
+       BT_ASSERT_PRE_NON_NULL(cycles, "Cycles (output)");
+       *seconds = clock_class->offset_seconds;
+       *cycles = clock_class->offset_cycles;
+}
+
+int bt_clock_class_set_offset(struct bt_clock_class *clock_class,
+               int64_t seconds, uint64_t cycles)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       BT_ASSERT_PRE(cycles < clock_class->frequency,
+               "Offset (cycles) is greater than clock class's frequency: "
+               "%![cc-]+K, new-offset-cycles=%" PRIu64, clock_class, cycles);
+       clock_class->offset_seconds = seconds;
+       clock_class->offset_cycles = cycles;
+       set_base_offset(clock_class);
+       BT_LIB_LOGV("Set clock class's offset: %!+K", clock_class);
+       return 0;
+}
+
+bt_bool bt_clock_class_is_absolute(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return (bool) clock_class->is_absolute;
+}
+
+int bt_clock_class_set_is_absolute(struct bt_clock_class *clock_class,
+               bt_bool is_absolute)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       clock_class->is_absolute = (bool) is_absolute;
+       BT_LIB_LOGV("Set clock class's absolute property: %!+K",
+               clock_class);
+       return 0;
+}
+
+bt_uuid bt_clock_class_get_uuid(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       return clock_class->uuid.value;
+}
+
+int bt_clock_class_set_uuid(struct bt_clock_class *clock_class,
+               bt_uuid uuid)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
+       BT_ASSERT_PRE_CLOCK_CLASS_HOT(clock_class);
+       memcpy(clock_class->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
+       clock_class->uuid.value = clock_class->uuid.uuid;
+       BT_LIB_LOGV("Set clock class's UUID: %!+K", clock_class);
+       return 0;
+}
+
+BT_HIDDEN
+void _bt_clock_class_freeze(struct bt_clock_class *clock_class)
+{
+       BT_ASSERT(clock_class);
+
+       if (clock_class->frozen) {
+               return;
+       }
+
+       BT_LIB_LOGD("Freezing clock class: %!+K", clock_class);
+       clock_class->frozen = 1;
+}
+
+int bt_clock_class_cycles_to_ns_from_origin(struct bt_clock_class *clock_class,
+               uint64_t cycles, int64_t *ns)
+{
+       int ret;
+
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(ns, "Nanoseconds (output)");
+       ret = bt_util_ns_from_origin(clock_class, cycles, ns);
+       if (ret) {
+               BT_LIB_LOGW("Cannot convert cycles to nanoseconds "
+                       "from origin for given clock class: "
+                       "value overflows the signed 64-bit integer range: "
+                       "%![cc-]+K, cycles=%" PRIu64,
+                       clock_class, cycles);
+       }
+
+       return ret;
+}
diff --git a/lib/trace-ir/clock-value.c b/lib/trace-ir/clock-value.c
new file mode 100644 (file)
index 0000000..9724211
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "CLOCK-VALUE"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/compat/uuid-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/compat/string-internal.h>
+#include <inttypes.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/assert-internal.h>
+
+BT_HIDDEN
+void bt_clock_value_destroy(struct bt_clock_value *clock_value)
+{
+       BT_LIB_LOGD("Destroying clock value: %!+k", clock_value);
+       bt_put(clock_value->clock_class);
+       g_free(clock_value);
+}
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_new(struct bt_clock_class *clock_class)
+{
+       struct bt_clock_value *ret = NULL;
+
+       BT_ASSERT(clock_class);
+       BT_LIB_LOGD("Creating clock value object: %![cc-]+K=",
+               clock_class);
+       ret = g_new0(struct bt_clock_value, 1);
+       if (!ret) {
+               BT_LOGE_STR("Failed to allocate one clock value.");
+               goto end;
+       }
+
+       bt_object_init_unique(&ret->base);
+       ret->clock_class = bt_get(clock_class);
+       bt_clock_class_freeze(clock_class);
+       BT_LIB_LOGD("Created clock value object: %!+k", ret);
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_clock_value *bt_clock_value_create(struct bt_clock_class *clock_class)
+{
+       struct bt_clock_value *clock_value = NULL;
+
+       BT_ASSERT(clock_class);
+       clock_value = bt_object_pool_create_object(&clock_class->cv_pool);
+       if (!clock_value) {
+               BT_LIB_LOGE("Cannot allocate one clock value from clock class's clock value pool: "
+                       "%![cc-]+K", clock_class);
+               goto error;
+       }
+
+       if (likely(!clock_value->clock_class)) {
+               clock_value->clock_class = bt_get(clock_class);
+       }
+
+       goto end;
+
+error:
+       if (clock_value) {
+               bt_clock_value_recycle(clock_value);
+               clock_value = NULL;
+       }
+
+end:
+       return clock_value;
+}
+
+BT_HIDDEN
+void bt_clock_value_recycle(struct bt_clock_value *clock_value)
+{
+       struct bt_clock_class *clock_class;
+
+       BT_ASSERT(clock_value);
+       BT_LIB_LOGD("Recycling clock value: %!+k", clock_value);
+
+       /*
+        * Those are the important ordered steps:
+        *
+        * 1. Reset the clock value object, but do NOT put its clock
+        *    class's reference. This clock class contains the pool to
+        *    which we're about to recycle this clock value object, so
+        *    we must guarantee its existence thanks to this existing
+        *    reference.
+        *
+        * 2. Move the clock class reference to our `clock_class`
+        *    variable so that we can set the clock value's clock class
+        *    member to NULL before recycling it. We CANNOT do this
+        *    after we put the clock class reference because this
+        *    bt_put() could destroy the clock class, also destroying
+        *    its clock value pool, thus also destroying our clock value
+        *    object (this would result in an invalid write access).
+        *
+        * 3. Recycle the clock value object.
+        *
+        * 4. Put our clock class reference.
+        */
+       bt_clock_value_reset(clock_value);
+       clock_class = clock_value->clock_class;
+       BT_ASSERT(clock_class);
+       clock_value->clock_class = NULL;
+       bt_object_pool_recycle_object(&clock_class->cv_pool, clock_value);
+       bt_put(clock_class);
+}
+
+uint64_t bt_clock_value_get_value(struct bt_clock_value *clock_value)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+       BT_ASSERT_PRE(clock_value->is_set,
+               "Clock value is not set: %!+k", clock_value);
+       return clock_value->value_cycles;
+}
+
+int bt_clock_value_get_ns_from_origin(struct bt_clock_value *clock_value,
+               int64_t *ret_value_ns)
+{
+       int ret = 0;
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+       BT_ASSERT_PRE_NON_NULL(ret_value_ns, "Value (ns) (output)");
+       BT_ASSERT_PRE(clock_value->is_set,
+               "Clock value is not set: %!+k", clock_value);
+
+       if (clock_value->ns_from_origin_overflows) {
+               BT_LIB_LOGD("Clock value, once converted to nanoseconds from origin, "
+                       "overflows the signed 64-bit integer range: "
+                       "%![cv-]+k", clock_value);
+               ret = -1;
+               goto end;
+       }
+
+       *ret_value_ns = clock_value->ns_from_origin;
+
+end:
+       return ret;
+}
+
+struct bt_clock_class *bt_clock_value_borrow_clock_class(
+               struct bt_clock_value *clock_value)
+{
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value");
+       return clock_value->clock_class;
+}
diff --git a/lib/trace-ir/event-class.c b/lib/trace-ir/event-class.c
new file mode 100644 (file)
index 0000000..18a72f7
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * event-class.c
+ *
+ * Babeltrace trace IR - Event class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/types.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#define BT_ASSERT_PRE_EVENT_CLASS_HOT(_ec) \
+       BT_ASSERT_PRE_HOT((_ec), "Event class", ": %!+E", (_ec))
+
+static
+void destroy_event_class(struct bt_object *obj)
+{
+       struct bt_event_class *event_class = (void *) obj;
+
+       BT_LIB_LOGD("Destroying event class: %!+E", event_class);
+
+       if (event_class->name.str) {
+               g_string_free(event_class->name.str, TRUE);
+       }
+
+       if (event_class->emf_uri.str) {
+               g_string_free(event_class->emf_uri.str, TRUE);
+       }
+
+       BT_LOGD_STR("Putting context field type.");
+       bt_put(event_class->specific_context_ft);
+       BT_LOGD_STR("Putting payload field type.");
+       bt_put(event_class->payload_ft);
+       bt_object_pool_finalize(&event_class->event_pool);
+       g_free(obj);
+}
+
+static
+void free_event(struct bt_event *event,
+               struct bt_event_class *event_class)
+{
+       bt_event_destroy(event);
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool event_class_id_is_unique(struct bt_stream_class *stream_class, uint64_t id)
+{
+       uint64_t i;
+       bool is_unique = true;
+
+       for (i = 0; i < stream_class->event_classes->len; i++) {
+               struct bt_event_class *ec =
+                       stream_class->event_classes->pdata[i];
+
+               if (ec->id == id) {
+                       is_unique = false;
+                       goto end;
+               }
+       }
+
+end:
+       return is_unique;
+}
+
+static
+struct bt_event_class *create_event_class_with_id(
+               struct bt_stream_class *stream_class, uint64_t id)
+{
+       int ret;
+       struct bt_event_class *event_class;
+
+       BT_ASSERT(stream_class);
+       BT_ASSERT_PRE(event_class_id_is_unique(stream_class, id),
+               "Duplicate event class ID: %![sc-]+S, id=%" PRIu64,
+               stream_class, id);
+       BT_LIB_LOGD("Creating event class object: %![sc-]+S, id=%" PRIu64,
+               stream_class, id);
+       event_class = g_new0(struct bt_event_class, 1);
+       if (!event_class) {
+               BT_LOGE_STR("Failed to allocate one event class.");
+               goto error;
+       }
+
+       bt_object_init_shared_with_parent(&event_class->base,
+               destroy_event_class);
+       event_class->id = id;
+       bt_property_uint_init(&event_class->log_level,
+                       BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE, 0);
+       event_class->name.str = g_string_new(NULL);
+       if (!event_class->name.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               ret = -1;
+               goto end;
+       }
+
+       event_class->emf_uri.str = g_string_new(NULL);
+       if (!event_class->emf_uri.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_object_pool_initialize(&event_class->event_pool,
+               (bt_object_pool_new_object_func) bt_event_new,
+               (bt_object_pool_destroy_object_func) free_event,
+               event_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize event pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       bt_object_set_parent(&event_class->base, &stream_class->base);
+       g_ptr_array_add(stream_class->event_classes, event_class);
+       bt_stream_class_freeze(stream_class);
+       BT_LIB_LOGD("Created event class object: %!+E", event_class);
+       goto end;
+
+error:
+       BT_PUT(event_class);
+
+end:
+       return event_class;
+}
+
+struct bt_event_class *bt_event_class_create(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(stream_class->assigns_automatic_event_class_id,
+               "Stream class does not automatically assigns event class IDs: "
+               "%![sc-]+S", stream_class);
+       return create_event_class_with_id(stream_class,
+               (uint64_t) stream_class->event_classes->len);
+}
+
+struct bt_event_class *bt_event_class_create_with_id(
+               struct bt_stream_class *stream_class, uint64_t id)
+{
+       BT_ASSERT_PRE(!stream_class->assigns_automatic_event_class_id,
+               "Stream class automatically assigns event class IDs: "
+               "%![sc-]+S", stream_class);
+       return create_event_class_with_id(stream_class, id);
+}
+
+const char *bt_event_class_get_name(struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return event_class->name.value;
+}
+
+int bt_event_class_set_name(struct bt_event_class *event_class,
+               const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+       g_string_assign(event_class->name.str, name);
+       event_class->name.value = event_class->name.str->str;
+       BT_LIB_LOGV("Set event class's name: %!+E", event_class);
+       return 0;
+}
+
+uint64_t bt_event_class_get_id(struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return event_class->id;
+}
+
+enum bt_property_availability bt_event_class_get_log_level(
+               struct bt_event_class *event_class,
+               enum bt_event_class_log_level *log_level)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_NON_NULL(log_level, "Log level (output)");
+       *log_level = (enum bt_event_class_log_level)
+               event_class->log_level.value;
+       return event_class->log_level.base.avail;
+}
+
+int bt_event_class_set_log_level(struct bt_event_class *event_class,
+               enum bt_event_class_log_level log_level)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+       bt_property_uint_set(&event_class->log_level,
+               (uint64_t) log_level);
+       BT_LIB_LOGV("Set event class's log level: %!+E", event_class);
+       return 0;
+}
+
+const char *bt_event_class_get_emf_uri(struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return event_class->emf_uri.value;
+}
+
+int bt_event_class_set_emf_uri(struct bt_event_class *event_class,
+               const char *emf_uri)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_NON_NULL(emf_uri, "EMF URI");
+       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+       g_string_assign(event_class->emf_uri.str, emf_uri);
+       event_class->emf_uri.value = event_class->emf_uri.str->str;
+       BT_LIB_LOGV("Set event class's EMF URI: %!+E", event_class);
+       return 0;
+}
+
+struct bt_stream_class *bt_event_class_borrow_stream_class(
+               struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return bt_event_class_borrow_stream_class_inline(event_class);
+}
+
+struct bt_field_type *bt_event_class_borrow_specific_context_field_type(
+               struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return event_class->specific_context_ft;
+}
+
+int bt_event_class_set_specific_context_field_type(
+               struct bt_event_class *event_class,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_stream_class *stream_class;
+       struct bt_trace *trace;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = NULL,
+               .packet_context = NULL,
+               .event_header = NULL,
+               .event_common_context = NULL,
+               .event_specific_context = field_type,
+               .event_payload = NULL,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Specific context field type is not a structure field type: "
+               "%!+F", field_type);
+       stream_class = bt_event_class_borrow_stream_class_inline(
+               event_class);
+       trace = bt_stream_class_borrow_trace_inline(stream_class);
+       resolve_ctx.packet_header = trace->packet_header_ft;
+       resolve_ctx.packet_context = stream_class->packet_context_ft;
+       resolve_ctx.event_header = stream_class->event_header_ft;
+       resolve_ctx.event_common_context =
+               stream_class->event_common_context_ft;
+
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(event_class->specific_context_ft);
+       event_class->specific_context_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set event class's specific context field type: %!+E",
+               event_class);
+
+end:
+       return ret;
+}
+
+struct bt_field_type *bt_event_class_borrow_payload_field_type(
+               struct bt_event_class *event_class)
+{
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       return event_class->payload_ft;
+}
+
+int bt_event_class_set_payload_field_type(struct bt_event_class *event_class,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_stream_class *stream_class;
+       struct bt_trace *trace;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = NULL,
+               .packet_context = NULL,
+               .event_header = NULL,
+               .event_common_context = NULL,
+               .event_specific_context = NULL,
+               .event_payload = field_type,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(event_class, "Event class");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_EVENT_CLASS_HOT(event_class);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Payload field type is not a structure field type: %!+F",
+               field_type);
+       stream_class = bt_event_class_borrow_stream_class_inline(
+               event_class);
+       trace = bt_stream_class_borrow_trace_inline(stream_class);
+       resolve_ctx.packet_header = trace->packet_header_ft;
+       resolve_ctx.packet_context = stream_class->packet_context_ft;
+       resolve_ctx.event_header = stream_class->event_header_ft;
+       resolve_ctx.event_common_context =
+               stream_class->event_common_context_ft;
+       resolve_ctx.event_specific_context = event_class->specific_context_ft;
+
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(event_class->payload_ft);
+       event_class->payload_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set event class's payload field type: %!+E", event_class);
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void _bt_event_class_freeze(struct bt_event_class *event_class)
+{
+       /* The field types are already frozen */
+       BT_ASSERT(event_class);
+       BT_LIB_LOGD("Freezing event class: %!+E", event_class);
+       event_class->frozen = true;
+}
diff --git a/lib/trace-ir/event-header-field.c b/lib/trace-ir/event-header-field.c
new file mode 100644 (file)
index 0000000..a84e999
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT-HEADER-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/event-header-field.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_event_header_field_borrow_field(
+               struct bt_event_header_field *header_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
+       return (void *) field_wrapper->field;
+}
+
+void bt_event_header_field_release(struct bt_event_header_field *header_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Event header field");
+
+       /*
+        * Do not recycle because the pool could be destroyed at this
+        * point. This function is only called when there's an error
+        * anyway because the goal of an event header field wrapper is
+        * to eventually move it to an event with bt_event_move_header()
+        * after creating it.
+        */
+       bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_event_header_field *bt_event_header_field_create(
+               struct bt_stream_class *stream_class)
+{
+       struct bt_field_wrapper *field_wrapper;
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(bt_stream_class_borrow_trace_inline(stream_class),
+               "Stream class is not part of a trace: %!+S", stream_class);
+       BT_ASSERT_PRE(stream_class->event_header_ft,
+               "Stream class has no event header field type: %!+S",
+               stream_class);
+       field_wrapper = bt_field_wrapper_create(
+               &stream_class->event_header_field_pool,
+               (void *) stream_class->event_header_ft);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one event header field from stream class: "
+                       "%![sc-]+S", stream_class);
+               goto error;
+       }
+
+       BT_ASSERT(field_wrapper->field);
+       bt_stream_class_freeze(stream_class);
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return (void *) field_wrapper;
+}
diff --git a/lib/trace-ir/event.c b/lib/trace-ir/event.c
new file mode 100644 (file)
index 0000000..b997f20
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * event.c
+ *
+ * Babeltrace trace IR - Event
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "EVENT"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-value.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+BT_HIDDEN
+void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen)
+{
+       BT_ASSERT(event);
+       BT_LIB_LOGD("Setting event's frozen state: %!+e, is-frozen=%d",
+               event, is_frozen);
+
+       if (event->header_field) {
+               BT_LOGD_STR("Setting event's header field's frozen state.");
+               bt_field_set_is_frozen(
+                       event->header_field->field, is_frozen);
+       }
+
+       if (event->common_context_field) {
+               BT_LOGD_STR("Setting event's common context field's frozen state.");
+               bt_field_set_is_frozen(
+                       event->common_context_field, is_frozen);
+       }
+
+       if (event->specific_context_field) {
+               BT_LOGD_STR("Setting event's specific context field's frozen state.");
+               bt_field_set_is_frozen(event->specific_context_field,
+                       is_frozen);
+       }
+
+       if (event->payload_field) {
+               BT_LOGD_STR("Setting event's payload field's frozen state.");
+               bt_field_set_is_frozen(event->payload_field,
+                       is_frozen);
+       }
+
+       event->frozen = is_frozen;
+       BT_LOGD_STR("Setting event's packet's frozen state.");
+       bt_packet_set_is_frozen(event->packet, is_frozen);
+}
+
+static
+void recycle_event_header_field(struct bt_field_wrapper *field_wrapper,
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT(field_wrapper);
+       BT_LIB_LOGD("Recycling event header field: "
+               "addr=%p, %![sc-]+S, %![field-]+f", field_wrapper,
+               stream_class, field_wrapper->field);
+       bt_object_pool_recycle_object(
+               &stream_class->event_header_field_pool,
+               field_wrapper);
+}
+
+static inline
+struct bt_field_wrapper *create_event_header_field(
+               struct bt_stream_class *stream_class)
+{
+       struct bt_field_wrapper *field_wrapper = NULL;
+
+       field_wrapper = bt_field_wrapper_create(
+               &stream_class->event_header_field_pool,
+               bt_stream_class_borrow_event_header_field_type(stream_class));
+       if (!field_wrapper) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       if (field_wrapper) {
+               recycle_event_header_field(field_wrapper, stream_class);
+               field_wrapper = NULL;
+       }
+
+end:
+       return field_wrapper;
+}
+
+BT_HIDDEN
+struct bt_event *bt_event_new(struct bt_event_class *event_class)
+{
+       struct bt_event *event = NULL;
+       struct bt_stream_class *stream_class;
+       struct bt_field_type *ft;
+
+       BT_ASSERT(event_class);
+       event = g_new0(struct bt_event, 1);
+       if (!event) {
+               BT_LOGE_STR("Failed to allocate one event.");
+               goto error;
+       }
+
+       bt_object_init_unique(&event->base);
+       stream_class = bt_event_class_borrow_stream_class(event_class);
+       BT_ASSERT(stream_class);
+
+       if (bt_stream_class_borrow_event_header_field_type(stream_class)) {
+               event->header_field = create_event_header_field(stream_class);
+               if (!event->header_field) {
+                       BT_LOGE_STR("Cannot create event header field.");
+                       goto error;
+               }
+       }
+
+       ft = bt_stream_class_borrow_event_common_context_field_type(
+               stream_class);
+       if (ft) {
+               event->common_context_field = bt_field_create(ft);
+               if (!event->common_context_field) {
+                       /* bt_field_create() logs errors */
+                       goto error;
+               }
+       }
+
+       ft = bt_event_class_borrow_specific_context_field_type(event_class);
+       if (ft) {
+               event->specific_context_field = bt_field_create(ft);
+               if (!event->specific_context_field) {
+                       /* bt_field_create() logs errors */
+                       goto error;
+               }
+       }
+
+       ft = bt_event_class_borrow_payload_field_type(event_class);
+       if (ft) {
+               event->payload_field = bt_field_create(ft);
+               if (!event->payload_field) {
+                       /* bt_field_create() logs errors */
+                       goto error;
+               }
+       }
+
+       if (stream_class->default_clock_class) {
+               event->default_cv = bt_clock_value_create(
+                       stream_class->default_clock_class);
+               if (!event->default_cv) {
+                       /* bt_clock_value_create() logs errors */
+                       goto error;
+               }
+       }
+
+       goto end;
+
+error:
+       if (event) {
+               bt_event_destroy(event);
+               event = NULL;
+       }
+
+end:
+       return event;
+}
+
+struct bt_event_class *bt_event_borrow_class(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->class;
+}
+
+struct bt_stream *bt_event_borrow_stream(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->packet ? event->packet->stream : NULL;
+}
+
+struct bt_field *bt_event_borrow_header_field(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->header_field ? event->header_field->field : NULL;
+}
+
+struct bt_field *bt_event_borrow_common_context_field(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->common_context_field;
+}
+
+struct bt_field *bt_event_borrow_specific_context_field(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->specific_context_field;
+}
+
+struct bt_field *bt_event_borrow_payload_field(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->payload_field;
+}
+
+static
+void release_event_header_field(struct bt_field_wrapper *field_wrapper,
+               struct bt_event *event)
+{
+       if (!event->class) {
+               bt_field_wrapper_destroy(field_wrapper);
+       } else {
+               struct bt_stream_class *stream_class =
+                       bt_event_class_borrow_stream_class(event->class);
+
+               BT_ASSERT(stream_class);
+               recycle_event_header_field(field_wrapper, stream_class);
+       }
+}
+
+BT_HIDDEN
+void bt_event_destroy(struct bt_event *event)
+{
+       BT_ASSERT(event);
+       BT_LIB_LOGD("Destroying event: %!+e", event);
+
+       if (event->header_field) {
+               BT_LOGD_STR("Releasing event's header field.");
+               release_event_header_field(event->header_field, event);
+       }
+
+       if (event->common_context_field) {
+               BT_LOGD_STR("Destroying event's stream event context field.");
+               bt_field_destroy(event->common_context_field);
+       }
+
+       if (event->specific_context_field) {
+               BT_LOGD_STR("Destroying event's context field.");
+               bt_field_destroy(event->specific_context_field);
+       }
+
+       if (event->payload_field) {
+               BT_LOGD_STR("Destroying event's payload field.");
+               bt_field_destroy(event->payload_field);
+       }
+
+       BT_LOGD_STR("Putting event's class.");
+       bt_put(event->class);
+
+       if (event->default_cv) {
+               bt_clock_value_recycle(event->default_cv);
+       }
+
+       BT_LOGD_STR("Putting event's packet.");
+       bt_put(event->packet);
+       g_free(event);
+}
+
+int bt_event_set_default_clock_value(struct bt_event *event,
+               uint64_t value_cycles)
+{
+       struct bt_stream_class *sc;
+
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       BT_ASSERT_PRE_EVENT_HOT(event);
+       sc = bt_event_class_borrow_stream_class_inline(event->class);
+       BT_ASSERT(sc);
+       BT_ASSERT_PRE(sc->default_clock_class,
+               "Event's stream class has no default clock class: "
+               "%![ev-]+e, %![sc-]+S", event, sc);
+       BT_ASSERT(event->default_cv);
+       bt_clock_value_set_value_inline(event->default_cv, value_cycles);
+       BT_LIB_LOGV("Set event's default clock value: %![event-]+e, "
+               "value=%" PRIu64, event, value_cycles);
+       return 0;
+}
+
+enum bt_clock_value_status bt_event_borrow_default_clock_value(
+               struct bt_event *event, struct bt_clock_value **clock_value)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+       *clock_value = event->default_cv;
+       return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+struct bt_packet *bt_event_borrow_packet(struct bt_event *event)
+{
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       return event->packet;
+}
+
+int bt_event_move_header(struct bt_event *event,
+               struct bt_event_header_field *header_field)
+{
+       struct bt_stream_class *stream_class;
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(event, "Event");
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
+       BT_ASSERT_PRE_EVENT_HOT(event);
+       stream_class = bt_event_class_borrow_stream_class_inline(event->class);
+       BT_ASSERT_PRE(stream_class->event_header_ft,
+               "Stream class has no event header field type: %!+S",
+               stream_class);
+
+       /* Recycle current header field: always exists */
+       BT_ASSERT(event->header_field);
+       recycle_event_header_field(event->header_field, stream_class);
+
+       /* Move new field */
+       event->header_field = field_wrapper;
+       return 0;
+}
diff --git a/lib/trace-ir/field-path.c b/lib/trace-ir/field-path.c
new file mode 100644 (file)
index 0000000..65d2f72
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * field-path.c
+ *
+ * Babeltrace trace IR - Field path
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-PATH"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <limits.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <babeltrace/assert-internal.h>
+#include <glib.h>
+
+static
+void destroy_field_path(struct bt_object *obj)
+{
+       struct bt_field_path *field_path = (struct bt_field_path *) obj;
+
+       BT_ASSERT(field_path);
+       BT_LIB_LOGD("Destroying field path: %!+P", field_path);
+       g_array_free(field_path->indexes, TRUE);
+       g_free(field_path);
+}
+
+BT_HIDDEN
+struct bt_field_path *bt_field_path_create(void)
+{
+       struct bt_field_path *field_path = NULL;
+
+       BT_LOGD_STR("Creating empty field path object.");
+
+       field_path = g_new0(struct bt_field_path, 1);
+       if (!field_path) {
+               BT_LOGE_STR("Failed to allocate one field path.");
+               goto error;
+       }
+
+       bt_object_init_shared(&field_path->base, destroy_field_path);
+       field_path->indexes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
+       if (!field_path->indexes) {
+               BT_LOGE_STR("Failed to allocate a GArray.");
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created empty field path object: %!+P", field_path);
+       goto end;
+
+error:
+       BT_PUT(field_path);
+
+end:
+       return field_path;
+}
+
+enum bt_scope bt_field_path_get_root_scope(struct bt_field_path *field_path)
+{
+       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+       return field_path->root;
+}
+
+uint64_t bt_field_path_get_index_count(struct bt_field_path *field_path)
+{
+       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+       return (uint64_t) field_path->indexes->len;
+}
+
+uint64_t bt_field_path_get_index_by_index(struct bt_field_path *field_path,
+               uint64_t index)
+{
+       BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
+       BT_ASSERT_PRE_VALID_INDEX(index, field_path->indexes->len);
+       return bt_field_path_get_index_by_index_inline(field_path, index);
+}
diff --git a/lib/trace-ir/field-types.c b/lib/trace-ir/field-types.c
new file mode 100644 (file)
index 0000000..3953d85
--- /dev/null
@@ -0,0 +1,1164 @@
+/*
+ * field-types.c
+ *
+ * Babeltrace trace IR - Event Types
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-TYPES"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/glib-internal.h>
+#include <float.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+enum bt_field_type_id bt_field_type_get_type_id(struct bt_field_type *ft)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       return ft->id;
+}
+
+static
+void init_field_type(struct bt_field_type *ft, enum bt_field_type_id id,
+               bt_object_release_func release_func)
+{
+       BT_ASSERT(ft);
+       BT_ASSERT(bt_field_type_has_known_id(ft));
+       BT_ASSERT(release_func);
+       bt_object_init_shared(&ft->base, release_func);
+       ft->id = id;
+}
+
+static
+void init_integer_field_type(struct bt_field_type_integer *ft, enum bt_field_type_id id,
+               bt_object_release_func release_func)
+{
+       init_field_type((void *) ft, id, release_func);
+       ft->range = 64;
+       ft->base = BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+}
+
+static
+void destroy_integer_field_type(struct bt_object *obj)
+{
+       BT_ASSERT(obj);
+       BT_LIB_LOGD("Destroying integer field type object: %!+F", obj);
+       g_free(obj);
+}
+
+static inline
+struct bt_field_type *create_integer_field_type(enum bt_field_type_id id)
+{
+       struct bt_field_type_integer *int_ft = NULL;
+
+       BT_LOGD("Creating default integer field type object: id=%s",
+               bt_common_field_type_id_string(id));
+       int_ft = g_new0(struct bt_field_type_integer, 1);
+       if (!int_ft) {
+               BT_LOGE_STR("Failed to allocate one integer field type.");
+               goto error;
+       }
+
+       init_integer_field_type(int_ft, id, destroy_integer_field_type);
+       BT_LIB_LOGD("Created integer field type object: %!+F", int_ft);
+       goto end;
+
+error:
+       BT_PUT(int_ft);
+
+end:
+       return (void *) int_ft;
+}
+
+struct bt_field_type *bt_field_type_unsigned_integer_create(void)
+{
+       return create_integer_field_type(BT_FIELD_TYPE_ID_UNSIGNED_INTEGER);
+}
+
+struct bt_field_type *bt_field_type_signed_integer_create(void)
+{
+       return create_integer_field_type(BT_FIELD_TYPE_ID_SIGNED_INTEGER);
+}
+
+uint64_t bt_field_type_integer_get_field_value_range(
+               struct bt_field_type *ft)
+{
+       struct bt_field_type_integer *int_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+       return int_ft->range;
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool size_is_valid_for_enumeration_field_type(struct bt_field_type *ft,
+               uint64_t size)
+{
+       // TODO
+       return true;
+}
+
+int bt_field_type_integer_set_field_value_range(
+               struct bt_field_type *ft, uint64_t size)
+{
+       struct bt_field_type_integer *int_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+       BT_ASSERT_PRE(size <= 64,
+               "Unsupported size for integer field type's field value range "
+               "(maximum is 64): size=%" PRIu64, size);
+       BT_ASSERT_PRE(int_ft->common.id == BT_FIELD_TYPE_ID_UNSIGNED_INTEGER ||
+               int_ft->common.id == BT_FIELD_TYPE_ID_SIGNED_INTEGER ||
+               size_is_valid_for_enumeration_field_type(ft, size),
+               "Invalid field value range for enumeration field type: "
+               "at least one of the current mapping ranges contains values "
+               "which are outside this range: %!+F, size=%" PRIu64, ft, size);
+       int_ft->range = size;
+       BT_LIB_LOGV("Set integer field type's field value range: %!+F", ft);
+       return 0;
+}
+
+enum bt_field_type_integer_preferred_display_base
+bt_field_type_integer_get_preferred_display_base(struct bt_field_type *ft)
+{
+       struct bt_field_type_integer *int_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+       return int_ft->base;
+}
+
+int bt_field_type_integer_set_preferred_display_base(struct bt_field_type *ft,
+               enum bt_field_type_integer_preferred_display_base base)
+{
+       struct bt_field_type_integer *int_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_INT(ft, "Field type");
+       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+       int_ft->base = base;
+       BT_LIB_LOGV("Set integer field type's preferred display base: %!+F", ft);
+       return 0;
+}
+
+static
+void finalize_enumeration_field_type_mapping(
+               struct bt_field_type_enumeration_mapping *mapping)
+{
+       BT_ASSERT(mapping);
+
+       if (mapping->label) {
+               g_string_free(mapping->label, TRUE);
+       }
+
+       if (mapping->ranges) {
+               g_array_free(mapping->ranges, TRUE);
+       }
+}
+
+static
+void destroy_enumeration_field_type(struct bt_object *obj)
+{
+       struct bt_field_type_enumeration *ft = (void *) obj;
+
+       BT_ASSERT(ft);
+       BT_LIB_LOGD("Destroying enumeration field type object: %!+F", ft);
+
+       if (ft->mappings) {
+               uint64_t i;
+
+               for (i = 0; i < ft->mappings->len; i++) {
+                       finalize_enumeration_field_type_mapping(
+                               BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, i));
+               }
+
+               g_array_free(ft->mappings, TRUE);
+       }
+
+       if (ft->label_buf) {
+               g_ptr_array_free(ft->label_buf, TRUE);
+       }
+
+       g_free(ft);
+}
+
+static
+struct bt_field_type *create_enumeration_field_type(enum bt_field_type_id id)
+{
+       struct bt_field_type_enumeration *enum_ft = NULL;
+
+       BT_LOGD("Creating default enumeration field type object: id=%s",
+               bt_common_field_type_id_string(id));
+       enum_ft = g_new0(struct bt_field_type_enumeration, 1);
+       if (!enum_ft) {
+               BT_LOGE_STR("Failed to allocate one enumeration field type.");
+               goto error;
+       }
+
+       init_integer_field_type((void *) enum_ft, id,
+               destroy_enumeration_field_type);
+       enum_ft->mappings = g_array_new(FALSE, TRUE,
+               sizeof(struct bt_field_type_enumeration_mapping));
+       if (!enum_ft->mappings) {
+               BT_LOGE_STR("Failed to allocate a GArray.");
+               goto error;
+       }
+
+       enum_ft->label_buf = g_ptr_array_new();
+       if (!enum_ft->label_buf) {
+               BT_LOGE_STR("Failed to allocate a GArray.");
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created enumeration field type object: %!+F", enum_ft);
+       goto end;
+
+error:
+       BT_PUT(enum_ft);
+
+end:
+       return (void *) enum_ft;
+}
+
+struct bt_field_type *bt_field_type_unsigned_enumeration_create(void)
+{
+       return create_enumeration_field_type(
+               BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION);
+}
+
+struct bt_field_type *bt_field_type_signed_enumeration_create(void)
+{
+       return create_enumeration_field_type(
+               BT_FIELD_TYPE_ID_SIGNED_ENUMERATION);
+}
+
+uint64_t bt_field_type_enumeration_get_mapping_count(struct bt_field_type *ft)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_ENUM(ft, "Field type");
+       return (uint64_t) enum_ft->mappings->len;
+}
+
+void bt_field_type_unsigned_enumeration_borrow_mapping_by_index(
+               struct bt_field_type *ft, uint64_t index,
+               const char **name,
+               struct bt_field_type_unsigned_enumeration_mapping_ranges **ranges)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+       struct bt_field_type_enumeration_mapping *mapping;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
+       BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
+       BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+               "Field type");
+       mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
+       *name = mapping->label->str;
+       *ranges = (void *) mapping;
+}
+
+void bt_field_type_signed_enumeration_borrow_mapping_by_index(
+               struct bt_field_type *ft, uint64_t index,
+               const char **name,
+               struct bt_field_type_signed_enumeration_mapping_ranges **ranges)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+       struct bt_field_type_enumeration_mapping *mapping;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_NON_NULL(name, "Name (output)");
+       BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)");
+       BT_ASSERT_PRE_VALID_INDEX(index, enum_ft->mappings->len);
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+               "Field type");
+       mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(ft, index);
+       *name = mapping->label->str;
+       *ranges = (void *) mapping;
+}
+
+static inline
+uint64_t get_enumeration_field_type_mapping_range_count(
+               struct bt_field_type_enumeration_mapping *mapping)
+{
+       BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
+       return (uint64_t) mapping->ranges->len;
+}
+
+uint64_t bt_field_type_unsigned_enumeration_mapping_ranges_get_range_count(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges)
+{
+       return get_enumeration_field_type_mapping_range_count((void *) ranges);
+}
+
+uint64_t bt_field_type_signed_enumeration_mapping_ranges_get_range_count(
+               struct bt_field_type_signed_enumeration_mapping_ranges *ranges)
+{
+       return get_enumeration_field_type_mapping_range_count((void *) ranges);
+}
+
+static inline
+void get_enumeration_field_type_mapping_range_at_index(
+               struct bt_field_type_enumeration_mapping *mapping,
+               uint64_t index, uint64_t *lower, uint64_t *upper)
+{
+       struct bt_field_type_enumeration_mapping_range *range;
+
+       BT_ASSERT_PRE_NON_NULL(mapping, "Ranges");
+       BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)");
+       BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)");
+       BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len);
+       range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
+       *lower = range->lower.u;
+       *upper = range->upper.u;
+}
+
+void bt_field_type_unsigned_enumeration_mapping_ranges_get_range_by_index(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+               uint64_t index, uint64_t *lower, uint64_t *upper)
+{
+       get_enumeration_field_type_mapping_range_at_index((void *) ranges,
+               index, lower, upper);
+}
+
+void bt_field_type_signed_enumeration_mapping_ranges_get_range_by_index(
+               struct bt_field_type_unsigned_enumeration_mapping_ranges *ranges,
+               uint64_t index, int64_t *lower, int64_t *upper)
+{
+       get_enumeration_field_type_mapping_range_at_index((void *) ranges,
+               index, (uint64_t *) lower, (uint64_t *) upper);
+}
+
+
+
+int bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+               struct bt_field_type *ft, uint64_t value,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+       BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+               "Field type");
+       g_ptr_array_set_size(enum_ft->label_buf, 0);
+
+       for (i = 0; i < enum_ft->mappings->len; i++) {
+               uint64_t j;
+               struct bt_field_type_enumeration_mapping *mapping =
+                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+               for (j = 0; j < mapping->ranges->len; j++) {
+                       struct bt_field_type_enumeration_mapping_range *range =
+                               BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
+                                       mapping, j);
+
+                       if (value >= range->lower.u &&
+                                       value <= range->upper.u) {
+                               g_ptr_array_add(enum_ft->label_buf,
+                                       mapping->label->str);
+                               break;
+                       }
+               }
+       }
+
+       *label_array = (void *) enum_ft->label_buf->pdata;
+       *count = (uint64_t) enum_ft->label_buf->len;
+       return 0;
+}
+
+int bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+               struct bt_field_type *ft, int64_t value,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+       BT_ASSERT_PRE_NON_NULL(count, "Count (output)");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+               "Field type");
+       g_ptr_array_set_size(enum_ft->label_buf, 0);
+
+       for (i = 0; i < enum_ft->mappings->len; i++) {
+               uint64_t j;
+               struct bt_field_type_enumeration_mapping *mapping =
+                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+               for (j = 0; j < mapping->ranges->len; j++) {
+                       struct bt_field_type_enumeration_mapping_range *range =
+                               BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(
+                                       mapping, j);
+
+                       if (value >= range->lower.i &&
+                                       value <= range->upper.i) {
+                               g_ptr_array_add(enum_ft->label_buf,
+                                       mapping->label->str);
+                               break;
+                       }
+               }
+       }
+
+       *label_array = (void *) enum_ft->label_buf->pdata;
+       *count = (uint64_t) enum_ft->label_buf->len;
+       return 0;
+}
+
+static inline
+int add_mapping_to_enumeration_field_type(struct bt_field_type *ft,
+               const char *label, uint64_t lower, uint64_t upper)
+{
+       int ret = 0;
+       uint64_t i;
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+       struct bt_field_type_enumeration_mapping *mapping = NULL;
+       struct bt_field_type_enumeration_mapping_range *range;
+
+       BT_ASSERT(ft);
+       BT_ASSERT_PRE_NON_NULL(label, "Label");
+
+       /* Find existing mapping identified by this label */
+       for (i = 0; i < enum_ft->mappings->len; i++) {
+               struct bt_field_type_enumeration_mapping *mapping_candidate =
+                       BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft, i);
+
+               if (strcmp(mapping_candidate->label->str, label) == 0) {
+                       mapping = mapping_candidate;
+                       break;
+               }
+       }
+
+       if (!mapping) {
+               /* Create new mapping for this label */
+               g_array_set_size(enum_ft->mappings, enum_ft->mappings->len + 1);
+               mapping = BT_FIELD_TYPE_ENUM_MAPPING_AT_INDEX(enum_ft,
+                       enum_ft->mappings->len - 1);
+               mapping->ranges = g_array_new(FALSE, TRUE,
+                       sizeof(struct bt_field_type_enumeration_mapping_range));
+               if (!mapping->ranges) {
+                       finalize_enumeration_field_type_mapping(mapping);
+                       g_array_set_size(enum_ft->mappings,
+                               enum_ft->mappings->len - 1);
+                       ret = -1;
+                       goto end;
+               }
+
+               mapping->label = g_string_new(label);
+               if (!mapping->label) {
+                       finalize_enumeration_field_type_mapping(mapping);
+                       g_array_set_size(enum_ft->mappings,
+                               enum_ft->mappings->len - 1);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       /* Add range */
+       BT_ASSERT(mapping);
+       g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
+       range = BT_FIELD_TYPE_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
+               mapping->ranges->len - 1);
+       range->lower.u = lower;
+       range->upper.u = upper;
+       BT_LIB_LOGV("Added mapping to enumeration field type: "
+               "%![ft-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
+               "upper-unsigned=%" PRIu64, ft, label, lower, upper);
+
+end:
+       return ret;
+}
+
+int bt_field_type_unsigned_enumeration_map_range(
+               struct bt_field_type *ft, const char *label,
+               uint64_t range_lower, uint64_t range_upper)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION,
+               "Field type");
+       BT_ASSERT_PRE(range_lower <= range_upper,
+               "Range's upper bound is less than lower bound: "
+               "upper=%" PRIu64 ", lower=%" PRIu64,
+               range_lower, range_upper);
+       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
+               range_lower),
+               "Range's lower bound is outside the enumeration field type's value range: "
+               "%![ft-]+F, lower=%" PRIu64, ft, range_lower);
+       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_ft->common.range,
+               range_upper),
+               "Range's upper bound is outside the enumeration field type's value range: "
+               "%![ft-]+F, upper=%" PRIu64, ft, range_upper);
+       return add_mapping_to_enumeration_field_type(ft, label, range_lower,
+               range_upper);
+}
+
+int bt_field_type_signed_enumeration_map_range(
+               struct bt_field_type *ft, const char *label,
+               int64_t range_lower, int64_t range_upper)
+{
+       struct bt_field_type_enumeration *enum_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_SIGNED_ENUMERATION,
+               "Field type");
+       BT_ASSERT_PRE(range_lower <= range_upper,
+               "Range's upper bound is less than lower bound: "
+               "upper=%" PRId64 ", lower=%" PRId64,
+               range_lower, range_upper);
+       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
+               range_lower),
+               "Range's lower bound is outside the enumeration field type's value range: "
+               "%![ft-]+F, lower=%" PRId64, ft, range_lower);
+       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_ft->common.range,
+               range_upper),
+               "Range's upper bound is outside the enumeration field type's value range: "
+               "%![ft-]+F, upper=%" PRId64, ft, range_upper);
+       return add_mapping_to_enumeration_field_type(ft, label, range_lower,
+               range_upper);
+}
+
+static
+void destroy_real_field_type(struct bt_object *obj)
+{
+       BT_ASSERT(obj);
+       BT_LIB_LOGD("Destroying real field type object: %!+F", obj);
+       g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_real_create(void)
+{
+       struct bt_field_type_real *real_ft = NULL;
+
+       BT_LOGD_STR("Creating default real field type object.");
+       real_ft = g_new0(struct bt_field_type_real, 1);
+       if (!real_ft) {
+               BT_LOGE_STR("Failed to allocate one real field type.");
+               goto error;
+       }
+
+       init_field_type((void *) real_ft, BT_FIELD_TYPE_ID_REAL,
+               destroy_real_field_type);
+       BT_LIB_LOGD("Created real field type object: %!+F", real_ft);
+       goto end;
+
+error:
+       BT_PUT(real_ft);
+
+end:
+       return (void *) real_ft;
+}
+
+bt_bool bt_field_type_real_is_single_precision(struct bt_field_type *ft)
+{
+       struct bt_field_type_real *real_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
+       return real_ft->is_single_precision;
+}
+
+int bt_field_type_real_set_is_single_precision(struct bt_field_type *ft,
+               bt_bool is_single_precision)
+{
+       struct bt_field_type_real *real_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_REAL, "Field type");
+       BT_ASSERT_PRE_FT_HOT(ft, "Field type");
+       real_ft->is_single_precision = (bool) is_single_precision;
+       BT_LIB_LOGV("Set real field type's \"is single precision\" property: "
+               "%!+F", ft);
+       return 0;
+}
+
+static
+int init_named_field_types_container(
+               struct bt_field_type_named_field_types_container *ft,
+               enum bt_field_type_id id, bt_object_release_func release_func)
+{
+       int ret = 0;
+
+       init_field_type((void *) ft, id, release_func);
+       ft->named_fts = g_array_new(FALSE, TRUE,
+               sizeof(struct bt_named_field_type));
+       if (!ft->named_fts) {
+               BT_LOGE_STR("Failed to allocate a GArray.");
+               ret = -1;
+               goto end;
+       }
+
+       ft->name_to_index = g_hash_table_new(g_str_hash, g_str_equal);
+       if (!ft->name_to_index) {
+               BT_LOGE_STR("Failed to allocate a GHashTable.");
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+void finalize_named_field_type(struct bt_named_field_type *named_ft)
+{
+       BT_ASSERT(named_ft);
+       BT_LIB_LOGD("Finalizing named field type: "
+               "addr=%p, name=\"%s\", %![ft-]+F",
+               named_ft, named_ft->name ? named_ft->name->str : NULL,
+               named_ft->ft);
+
+       if (named_ft->name) {
+               g_string_free(named_ft->name, TRUE);
+       }
+
+       BT_LOGD_STR("Putting named field type's field type.");
+       bt_put(named_ft->ft);
+}
+
+static
+void finalize_named_field_types_container(
+               struct bt_field_type_named_field_types_container *ft)
+{
+       uint64_t i;
+
+       BT_ASSERT(ft);
+
+       if (ft->named_fts) {
+               for (i = 0; i < ft->named_fts->len; i++) {
+                       finalize_named_field_type(
+                               &g_array_index(ft->named_fts,
+                                       struct bt_named_field_type, i));
+               }
+
+               g_array_free(ft->named_fts, TRUE);
+       }
+
+       if (ft->name_to_index) {
+               g_hash_table_destroy(ft->name_to_index);
+       }
+}
+
+static
+void destroy_structure_field_type(struct bt_object *obj)
+{
+       BT_ASSERT(obj);
+       BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
+       finalize_named_field_types_container((void *) obj);
+       g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_structure_create(void)
+{
+       int ret;
+       struct bt_field_type_structure *struct_ft = NULL;
+
+       BT_LOGD_STR("Creating default structure field type object.");
+       struct_ft = g_new0(struct bt_field_type_structure, 1);
+       if (!struct_ft) {
+               BT_LOGE_STR("Failed to allocate one structure field type.");
+               goto error;
+       }
+
+       ret = init_named_field_types_container((void *) struct_ft,
+               BT_FIELD_TYPE_ID_STRUCTURE, destroy_structure_field_type);
+       if (ret) {
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created structure field type object: %!+F", struct_ft);
+       goto end;
+
+error:
+       BT_PUT(struct_ft);
+
+end:
+       return (void *) struct_ft;
+}
+
+static
+int append_named_field_type_to_container_field_type(
+               struct bt_field_type_named_field_types_container *container_ft,
+               const char *name, struct bt_field_type *ft)
+{
+       int ret = 0;
+       struct bt_named_field_type *named_ft;
+       GString *name_str;
+
+       BT_ASSERT(container_ft);
+       BT_ASSERT_PRE_FT_HOT(container_ft, "Field type");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE(!bt_g_hash_table_contains(container_ft->name_to_index,
+               name),
+               "Duplicate member/option name in structure/variant field type: "
+               "%![container-ft-]+F, name=\"%s\"", container_ft, name);
+       name_str = g_string_new(name);
+       if (!name_str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               ret = -1;
+               goto end;
+       }
+
+       g_array_set_size(container_ft->named_fts,
+               container_ft->named_fts->len + 1);
+       named_ft = &g_array_index(container_ft->named_fts,
+               struct bt_named_field_type, container_ft->named_fts->len - 1);
+       named_ft->name = name_str;
+       named_ft->ft = bt_get(ft);
+       g_hash_table_insert(container_ft->name_to_index, named_ft->name->str,
+               GUINT_TO_POINTER(container_ft->named_fts->len - 1));
+       bt_field_type_freeze(ft);
+
+end:
+       return ret;
+}
+
+int bt_field_type_structure_append_member(struct bt_field_type *ft,
+               const char *name, struct bt_field_type *member_ft)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+       return append_named_field_type_to_container_field_type((void *) ft,
+               name, member_ft);
+}
+
+uint64_t bt_field_type_structure_get_member_count(struct bt_field_type *ft)
+{
+       struct bt_field_type_structure *struct_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+       return (uint64_t) struct_ft->common.named_fts->len;
+}
+
+static
+void borrow_named_field_type_from_container_field_type_at_index(
+               struct bt_field_type_named_field_types_container *ft,
+               uint64_t index, const char **name,
+               struct bt_field_type **out_ft)
+{
+       struct bt_named_field_type *named_ft;
+
+       BT_ASSERT(ft);
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_NON_NULL(out_ft, "Field type (output)");
+       BT_ASSERT_PRE_VALID_INDEX(index, ft->named_fts->len);
+       named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, index);
+       *name = named_ft->name->str;
+       *out_ft = named_ft->ft;
+}
+
+void bt_field_type_structure_borrow_member_by_index(
+               struct bt_field_type *ft, uint64_t index,
+               const char **name, struct bt_field_type **out_ft)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+       borrow_named_field_type_from_container_field_type_at_index((void *) ft,
+               index, name, out_ft);
+}
+
+static
+struct bt_field_type *borrow_field_type_from_container_field_type_by_name(
+               struct bt_field_type_named_field_types_container *ft,
+               const char *name)
+{
+       struct bt_field_type *ret_ft = NULL;
+       struct bt_named_field_type *named_ft;
+       gpointer orig_key;
+       gpointer value;
+
+       BT_ASSERT(ft);
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       if (!g_hash_table_lookup_extended(ft->name_to_index, name, &orig_key,
+                       &value)) {
+               goto end;
+       }
+
+       named_ft = BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft,
+               GPOINTER_TO_UINT(value));
+       ret_ft = named_ft->ft;
+
+end:
+       return ret_ft;
+}
+
+struct bt_field_type *bt_field_type_structure_borrow_member_field_type_by_name(
+               struct bt_field_type *ft, const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STRUCTURE, "Field type");
+       return borrow_field_type_from_container_field_type_by_name((void *) ft,
+               name);
+}
+
+static
+void destroy_variant_field_type(struct bt_object *obj)
+{
+       struct bt_field_type_variant *ft = (void *) obj;
+
+       BT_ASSERT(ft);
+       BT_LIB_LOGD("Destroying variant field type object: %!+F", ft);
+       finalize_named_field_types_container((void *) ft);
+       BT_LOGD_STR("Putting selector field path.");
+       bt_put(ft->selector_field_path);
+       g_free(ft);
+}
+
+struct bt_field_type *bt_field_type_variant_create(void)
+{
+       int ret;
+       struct bt_field_type_variant *var_ft = NULL;
+
+       BT_LOGD_STR("Creating default variant field type object.");
+       var_ft = g_new0(struct bt_field_type_variant, 1);
+       if (!var_ft) {
+               BT_LOGE_STR("Failed to allocate one variant field type.");
+               goto error;
+       }
+
+       ret = init_named_field_types_container((void *) var_ft,
+               BT_FIELD_TYPE_ID_VARIANT, destroy_variant_field_type);
+       if (ret) {
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created variant field type object: %!+F", var_ft);
+       goto end;
+
+error:
+       BT_PUT(var_ft);
+
+end:
+       return (void *) var_ft;
+}
+
+int bt_field_type_variant_set_selector_field_type(
+               struct bt_field_type *ft, struct bt_field_type *selector_ft)
+{
+       struct bt_field_type_variant *var_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Variant field type");
+       BT_ASSERT_PRE_NON_NULL(selector_ft, "Selector field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+       BT_ASSERT_PRE_FT_IS_ENUM(selector_ft, "Selector field type");
+       BT_ASSERT_PRE_FT_HOT(ft, "Variant field type");
+       var_ft->selector_ft = selector_ft;
+       bt_field_type_freeze(selector_ft);
+       return 0;
+}
+
+int bt_field_type_variant_append_option(struct bt_field_type *ft,
+               const char *name, struct bt_field_type *option_ft)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+       return append_named_field_type_to_container_field_type((void *) ft,
+               name, option_ft);
+}
+
+struct bt_field_type *bt_field_type_variant_borrow_option_field_type_by_name(
+               struct bt_field_type *ft, const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+       return borrow_field_type_from_container_field_type_by_name((void *) ft,
+               name);
+}
+
+uint64_t bt_field_type_variant_get_option_count(struct bt_field_type *ft)
+{
+       struct bt_field_type_variant *var_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+       return (uint64_t) var_ft->common.named_fts->len;
+}
+
+void bt_field_type_variant_borrow_option_by_index(
+               struct bt_field_type *ft, uint64_t index,
+               const char **name, struct bt_field_type **out_ft)
+{
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT, "Field type");
+       borrow_named_field_type_from_container_field_type_at_index((void *) ft,
+               index, name, out_ft);
+}
+
+struct bt_field_path *bt_field_type_variant_borrow_selector_field_path(
+               struct bt_field_type *ft)
+{
+       struct bt_field_type_variant *var_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_VARIANT,
+               "Field type");
+       return var_ft->selector_field_path;
+}
+
+static
+void init_array_field_type(struct bt_field_type_array *ft,
+               enum bt_field_type_id id, bt_object_release_func release_func,
+               struct bt_field_type *element_ft)
+{
+       BT_ASSERT(element_ft);
+       init_field_type((void *) ft, id, release_func);
+       ft->element_ft = bt_get(element_ft);
+       bt_field_type_freeze(element_ft);
+}
+
+static
+void finalize_array_field_type(struct bt_field_type_array *array_ft)
+{
+       BT_ASSERT(array_ft);
+       BT_LOGD_STR("Putting element field type.");
+       bt_put(array_ft->element_ft);
+}
+
+static
+void destroy_static_array_field_type(struct bt_object *obj)
+{
+       BT_ASSERT(obj);
+       BT_LIB_LOGD("Destroying static array field type object: %!+F", obj);
+       finalize_array_field_type((void *) obj);
+       g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_static_array_create(
+               struct bt_field_type *element_ft, uint64_t length)
+{
+       struct bt_field_type_static_array *array_ft = NULL;
+
+       BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
+       BT_LOGD_STR("Creating default static array field type object.");
+       array_ft = g_new0(struct bt_field_type_static_array, 1);
+       if (!array_ft) {
+               BT_LOGE_STR("Failed to allocate one static array field type.");
+               goto error;
+       }
+
+       init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
+               destroy_static_array_field_type, element_ft);
+       array_ft->length = length;
+       BT_LIB_LOGD("Created static array field type object: %!+F", array_ft);
+       goto end;
+
+error:
+       BT_PUT(array_ft);
+
+end:
+       return (void *) array_ft;
+}
+
+struct bt_field_type *bt_field_type_array_borrow_element_field_type(
+               struct bt_field_type *ft)
+{
+       struct bt_field_type_array *array_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_IS_ARRAY(ft, "Field type");
+       return array_ft->element_ft;
+}
+
+uint64_t bt_field_type_static_array_get_length(struct bt_field_type *ft)
+{
+       struct bt_field_type_static_array *array_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_STATIC_ARRAY,
+               "Field type");
+       return (uint64_t) array_ft->length;
+}
+
+static
+void destroy_dynamic_array_field_type(struct bt_object *obj)
+{
+       struct bt_field_type_dynamic_array *ft = (void *) obj;
+
+       BT_ASSERT(ft);
+       BT_LIB_LOGD("Destroying dynamic array field type object: %!+F", ft);
+       finalize_array_field_type((void *) ft);
+       BT_LOGD_STR("Putting length field path.");
+       bt_put(ft->length_field_path);
+       g_free(ft);
+}
+
+struct bt_field_type *bt_field_type_dynamic_array_create(
+               struct bt_field_type *element_ft)
+{
+       struct bt_field_type_dynamic_array *array_ft = NULL;
+
+       BT_ASSERT_PRE_NON_NULL(element_ft, "Element field type");
+       BT_LOGD_STR("Creating default dynamic array field type object.");
+       array_ft = g_new0(struct bt_field_type_dynamic_array, 1);
+       if (!array_ft) {
+               BT_LOGE_STR("Failed to allocate one dynamic array field type.");
+               goto error;
+       }
+
+       init_array_field_type((void *) array_ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+               destroy_dynamic_array_field_type, element_ft);
+       BT_LIB_LOGD("Created dynamic array field type object: %!+F", array_ft);
+       goto end;
+
+error:
+       BT_PUT(array_ft);
+
+end:
+       return (void *) array_ft;
+}
+
+int bt_field_type_dynamic_array_set_length_field_type(struct bt_field_type *ft,
+               struct bt_field_type *length_ft)
+{
+       struct bt_field_type_dynamic_array *array_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Dynamic array field type");
+       BT_ASSERT_PRE_NON_NULL(length_ft, "Length field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+               "Field type");
+       BT_ASSERT_PRE_FT_IS_UNSIGNED_INT(length_ft, "Length field type");
+       BT_ASSERT_PRE_FT_HOT(ft, "Dynamic array field type");
+       array_ft->length_ft = length_ft;
+       bt_field_type_freeze(length_ft);
+       return 0;
+}
+
+struct bt_field_path *bt_field_type_dynamic_array_borrow_length_field_path(
+               struct bt_field_type *ft)
+{
+       struct bt_field_type_dynamic_array *seq_ft = (void *) ft;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT_PRE_FT_HAS_ID(ft, BT_FIELD_TYPE_ID_DYNAMIC_ARRAY,
+               "Field type");
+       return seq_ft->length_field_path;
+}
+
+static
+void destroy_string_field_type(struct bt_object *obj)
+{
+       BT_ASSERT(obj);
+       BT_LIB_LOGD("Destroying string field type object: %!+F", obj);
+       g_free(obj);
+}
+
+struct bt_field_type *bt_field_type_string_create(void)
+{
+       struct bt_field_type_string *string_ft = NULL;
+
+       BT_LOGD_STR("Creating default string field type object.");
+       string_ft = g_new0(struct bt_field_type_string, 1);
+       if (!string_ft) {
+               BT_LOGE_STR("Failed to allocate one string field type.");
+               goto error;
+       }
+
+       init_field_type((void *) string_ft, BT_FIELD_TYPE_ID_STRING,
+               destroy_string_field_type);
+       BT_LIB_LOGD("Created string field type object: %!+F", string_ft);
+       goto end;
+
+error:
+       BT_PUT(string_ft);
+
+end:
+       return (void *) string_ft;
+}
+
+BT_HIDDEN
+void _bt_field_type_freeze(struct bt_field_type *ft)
+{
+       /*
+        * Element/member/option field types are frozen when added to
+        * their owner.
+        */
+       BT_ASSERT(ft);
+       ft->frozen = true;
+}
+
+BT_HIDDEN
+void _bt_field_type_make_part_of_trace(struct bt_field_type *ft)
+{
+       BT_ASSERT(ft);
+       BT_ASSERT_PRE(!ft->part_of_trace,
+               "Field type is already part of a trace: %!+F", ft);
+       ft->part_of_trace = true;
+
+       switch (ft->id) {
+       case BT_FIELD_TYPE_ID_STRUCTURE:
+       case BT_FIELD_TYPE_ID_VARIANT:
+       {
+               struct bt_field_type_named_field_types_container *container_ft =
+                       (void *) ft;
+               uint64_t i;
+
+               for (i = 0; i < container_ft->named_fts->len; i++) {
+                       struct bt_named_field_type *named_ft =
+                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+                                       container_ft, i);
+
+                       bt_field_type_make_part_of_trace(named_ft->ft);
+               }
+
+               break;
+       }
+       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+       {
+               struct bt_field_type_array *array_ft = (void *) ft;
+
+               bt_field_type_make_part_of_trace(array_ft->element_ft);
+               break;
+       }
+       default:
+               break;
+       }
+}
diff --git a/lib/trace-ir/field-wrapper.c b/lib/trace-ir/field-wrapper.c
new file mode 100644 (file)
index 0000000..7b13202
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELD-WRAPPER"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/object-pool-internal.h>
+#include <babeltrace/object-internal.h>
+#include <glib.h>
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_new(void *data)
+{
+       struct bt_field_wrapper *field_wrapper =
+               g_new0(struct bt_field_wrapper, 1);
+
+       BT_LOGD_STR("Creating empty field wrapper object.");
+
+       if (!field_wrapper) {
+               BT_LOGE("Failed to allocate one field wrapper.");
+               goto end;
+       }
+
+       bt_object_init_unique(&field_wrapper->base);
+       BT_LOGD("Created empty field wrapper object: addr=%p",
+               field_wrapper);
+
+end:
+       return field_wrapper;
+}
+
+BT_HIDDEN
+void bt_field_wrapper_destroy(struct bt_field_wrapper *field_wrapper)
+{
+       BT_LOGD("Destroying field wrapper: addr=%p", field_wrapper);
+
+       if (field_wrapper->field) {
+               BT_LOGD_STR("Destroying field.");
+               bt_field_destroy((void *) field_wrapper->field);
+       }
+
+       BT_LOGD_STR("Putting stream class.");
+       g_free(field_wrapper);
+}
+
+BT_HIDDEN
+struct bt_field_wrapper *bt_field_wrapper_create(
+               struct bt_object_pool *pool, struct bt_field_type *ft)
+{
+       struct bt_field_wrapper *field_wrapper = NULL;
+
+       BT_ASSERT(pool);
+       BT_ASSERT(ft);
+       field_wrapper = bt_object_pool_create_object(pool);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one field wrapper from field wrapper pool: "
+                       "%![pool-]+o", pool);
+               goto error;
+       }
+
+       if (!field_wrapper->field) {
+               field_wrapper->field = (void *) bt_field_create(ft);
+               if (!field_wrapper->field) {
+                       BT_LIB_LOGE("Cannot create field wrapper from field type: "
+                               "%![ft-]+F", ft);
+                       goto error;
+               }
+
+               BT_LIB_LOGD("Created initial field wrapper object: "
+                       "wrapper-addr=%p, %![field-]+f", field_wrapper,
+                       field_wrapper->field);
+       }
+
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return field_wrapper;
+}
diff --git a/lib/trace-ir/fields.c b/lib/trace-ir/fields.c
new file mode 100644 (file)
index 0000000..ee37ede
--- /dev/null
@@ -0,0 +1,1104 @@
+/*
+ * fields.c
+ *
+ * Babeltrace trace IR - Event Fields
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "FIELDS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/compat/fcntl-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+static
+void reset_single_field(struct bt_field *field);
+
+static
+void reset_array_field(struct bt_field *field);
+
+static
+void reset_structure_field(struct bt_field *field);
+
+static
+void reset_variant_field(struct bt_field *field);
+
+static
+void set_single_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
+
+static
+bool single_field_is_set(struct bt_field *field);
+
+static
+bool array_field_is_set(struct bt_field *field);
+
+static
+bool structure_field_is_set(struct bt_field *field);
+
+static
+bool variant_field_is_set(struct bt_field *field);
+
+static
+struct bt_field_methods integer_field_methods = {
+       .set_is_frozen = set_single_field_is_frozen,
+       .is_set = single_field_is_set,
+       .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods real_field_methods = {
+       .set_is_frozen = set_single_field_is_frozen,
+       .is_set = single_field_is_set,
+       .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods string_field_methods = {
+       .set_is_frozen = set_single_field_is_frozen,
+       .is_set = single_field_is_set,
+       .reset = reset_single_field,
+};
+
+static
+struct bt_field_methods structure_field_methods = {
+       .set_is_frozen = set_structure_field_is_frozen,
+       .is_set = structure_field_is_set,
+       .reset = reset_structure_field,
+};
+
+static
+struct bt_field_methods array_field_methods = {
+       .set_is_frozen = set_array_field_is_frozen,
+       .is_set = array_field_is_set,
+       .reset = reset_array_field,
+};
+
+static
+struct bt_field_methods variant_field_methods = {
+       .set_is_frozen = set_variant_field_is_frozen,
+       .is_set = variant_field_is_set,
+       .reset = reset_variant_field,
+};
+
+static
+struct bt_field *create_integer_field(struct bt_field_type *);
+
+static
+struct bt_field *create_real_field(struct bt_field_type *);
+
+static
+struct bt_field *create_string_field(struct bt_field_type *);
+
+static
+struct bt_field *create_structure_field(struct bt_field_type *);
+
+static
+struct bt_field *create_static_array_field(struct bt_field_type *);
+
+static
+struct bt_field *create_dynamic_array_field(struct bt_field_type *);
+
+static
+struct bt_field *create_variant_field(struct bt_field_type *);
+
+static
+struct bt_field *(* const field_create_funcs[])(struct bt_field_type *) = {
+       [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER]     = create_integer_field,
+       [BT_FIELD_TYPE_ID_SIGNED_INTEGER]       = create_integer_field,
+       [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = create_integer_field,
+       [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION]   = create_integer_field,
+       [BT_FIELD_TYPE_ID_REAL]                 = create_real_field,
+       [BT_FIELD_TYPE_ID_STRING]               = create_string_field,
+       [BT_FIELD_TYPE_ID_STRUCTURE]            = create_structure_field,
+       [BT_FIELD_TYPE_ID_STATIC_ARRAY]         = create_static_array_field,
+       [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY]        = create_dynamic_array_field,
+       [BT_FIELD_TYPE_ID_VARIANT]              = create_variant_field,
+};
+
+static
+void destroy_integer_field(struct bt_field *field);
+
+static
+void destroy_real_field(struct bt_field *field);
+
+static
+void destroy_string_field(struct bt_field *field);
+
+static
+void destroy_structure_field(struct bt_field *field);
+
+static
+void destroy_array_field(struct bt_field *field);
+
+static
+void destroy_variant_field(struct bt_field *field);
+
+static
+void (* const field_destroy_funcs[])(struct bt_field *) = {
+       [BT_FIELD_TYPE_ID_UNSIGNED_INTEGER]     = destroy_integer_field,
+       [BT_FIELD_TYPE_ID_SIGNED_INTEGER]       = destroy_integer_field,
+       [BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION] = destroy_integer_field,
+       [BT_FIELD_TYPE_ID_SIGNED_ENUMERATION]   = destroy_integer_field,
+       [BT_FIELD_TYPE_ID_REAL]                 = destroy_real_field,
+       [BT_FIELD_TYPE_ID_STRING]               = destroy_string_field,
+       [BT_FIELD_TYPE_ID_STRUCTURE]            = destroy_structure_field,
+       [BT_FIELD_TYPE_ID_STATIC_ARRAY]         = destroy_array_field,
+       [BT_FIELD_TYPE_ID_DYNAMIC_ARRAY]        = destroy_array_field,
+       [BT_FIELD_TYPE_ID_VARIANT]              = destroy_variant_field,
+};
+
+struct bt_field_type *bt_field_borrow_type(struct bt_field *field)
+{
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       return field->type;
+}
+
+enum bt_field_type_id bt_field_get_type_id(struct bt_field *field)
+{
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       return field->type->id;
+}
+
+BT_HIDDEN
+struct bt_field *bt_field_create(struct bt_field_type *ft)
+{
+       struct bt_field *field = NULL;
+
+       BT_ASSERT_PRE_NON_NULL(ft, "Field type");
+       BT_ASSERT(bt_field_type_has_known_id(ft));
+       field = field_create_funcs[ft->id](ft);
+       if (!field) {
+               BT_LIB_LOGE("Cannot create field object from field type: "
+                       "%![ft-]+F", ft);
+               goto end;
+       }
+
+end:
+       return field;
+}
+
+static inline
+void init_field(struct bt_field *field, struct bt_field_type *ft,
+               struct bt_field_methods *methods)
+{
+       BT_ASSERT(field);
+       BT_ASSERT(ft);
+       bt_object_init_unique(&field->base);
+       field->methods = methods;
+       field->type = bt_get(ft);
+}
+
+static
+struct bt_field *create_integer_field(struct bt_field_type *ft)
+{
+       struct bt_field_integer *int_field;
+
+       BT_LIB_LOGD("Creating integer field object: %![ft-]+F", ft);
+       int_field = g_new0(struct bt_field_integer, 1);
+       if (!int_field) {
+               BT_LOGE_STR("Failed to allocate one integer field.");
+               goto end;
+       }
+
+       init_field((void *) int_field, ft, &integer_field_methods);
+       BT_LIB_LOGD("Created integer field object: %!+f", int_field);
+
+end:
+       return (void *) int_field;
+}
+
+static
+struct bt_field *create_real_field(struct bt_field_type *ft)
+{
+       struct bt_field_real *real_field;
+
+       BT_LIB_LOGD("Creating real field object: %![ft-]+F", ft);
+       real_field = g_new0(struct bt_field_real, 1);
+       if (!real_field) {
+               BT_LOGE_STR("Failed to allocate one real field.");
+               goto end;
+       }
+
+       init_field((void *) real_field, ft, &real_field_methods);
+       BT_LIB_LOGD("Created real field object: %!+f", real_field);
+
+end:
+       return (void *) real_field;
+}
+
+static
+struct bt_field *create_string_field(struct bt_field_type *ft)
+{
+       struct bt_field_string *string_field;
+
+       BT_LIB_LOGD("Creating string field object: %![ft-]+F", ft);
+       string_field = g_new0(struct bt_field_string, 1);
+       if (!string_field) {
+               BT_LOGE_STR("Failed to allocate one string field.");
+               goto end;
+       }
+
+       init_field((void *) string_field, ft, &string_field_methods);
+       string_field->buf = g_array_sized_new(FALSE, FALSE,
+               sizeof(char), 1);
+       if (!string_field->buf) {
+               BT_LOGE_STR("Failed to allocate a GArray.");
+               BT_PUT(string_field);
+               goto end;
+       }
+
+       g_array_index(string_field->buf, char, 0) = '\0';
+       BT_LIB_LOGD("Created string field object: %!+f", string_field);
+
+end:
+       return (void *) string_field;
+}
+
+static inline
+int create_fields_from_named_field_types(
+               struct bt_field_type_named_field_types_container *ft,
+               GPtrArray **fields)
+{
+       int ret = 0;
+       uint64_t i;
+
+       *fields = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_field_destroy);
+       if (!*fields) {
+               BT_LOGE_STR("Failed to allocate a GPtrArray.");
+               ret = -1;
+               goto end;
+       }
+
+       g_ptr_array_set_size(*fields, ft->named_fts->len);
+
+       for (i = 0; i < ft->named_fts->len; i++) {
+               struct bt_field *field;
+               struct bt_named_field_type *named_ft =
+                       BT_FIELD_TYPE_NAMED_FT_AT_INDEX(ft, i);
+
+               field = bt_field_create(named_ft->ft);
+               if (!field) {
+                       BT_LIB_LOGE("Failed to create structure member or variant option field: "
+                               "name=\"%s\", %![ft-]+F",
+                               named_ft->name->str, named_ft->ft);
+                       ret = -1;
+                       goto end;
+               }
+
+               g_ptr_array_index(*fields, i) = field;
+       }
+
+end:
+       return ret;
+}
+
+static
+struct bt_field *create_structure_field(struct bt_field_type *ft)
+{
+       struct bt_field_structure *struct_field;
+
+       BT_LIB_LOGD("Creating structure field object: %![ft-]+F", ft);
+       struct_field = g_new0(struct bt_field_structure, 1);
+       if (!struct_field) {
+               BT_LOGE_STR("Failed to allocate one structure field.");
+               goto end;
+       }
+
+       init_field((void *) struct_field, ft, &structure_field_methods);
+
+       if (create_fields_from_named_field_types((void *) ft,
+                       &struct_field->fields)) {
+               BT_LIB_LOGE("Cannot create structure member fields: "
+                       "%![ft-]+F", ft);
+               BT_PUT(struct_field);
+               goto end;
+       }
+
+       BT_LIB_LOGD("Created structure field object: %!+f", struct_field);
+
+end:
+       return (void *) struct_field;
+}
+
+static
+struct bt_field *create_variant_field(struct bt_field_type *ft)
+{
+       struct bt_field_variant *var_field;
+
+       BT_LIB_LOGD("Creating variant field object: %![ft-]+F", ft);
+       var_field = g_new0(struct bt_field_variant, 1);
+       if (!var_field) {
+               BT_LOGE_STR("Failed to allocate one variant field.");
+               goto end;
+       }
+
+       init_field((void *) var_field, ft, &variant_field_methods);
+
+       if (create_fields_from_named_field_types((void *) ft,
+                       &var_field->fields)) {
+               BT_LIB_LOGE("Cannot create variant member fields: "
+                       "%![ft-]+F", ft);
+               BT_PUT(var_field);
+               goto end;
+       }
+
+       BT_LIB_LOGD("Created variant field object: %!+f", var_field);
+
+end:
+       return (void *) var_field;
+}
+
+static inline
+int init_array_field_fields(struct bt_field_array *array_field)
+{
+       int ret = 0;
+       uint64_t i;
+       struct bt_field_type_array *array_ft;
+
+       BT_ASSERT(array_field);
+       array_ft = (void *) array_field->common.type;
+       array_field->fields = g_ptr_array_sized_new(array_field->length);
+       if (!array_field->fields) {
+               BT_LOGE_STR("Failed to allocate a GPtrArray.");
+               ret = -1;
+               goto end;
+       }
+
+       g_ptr_array_set_free_func(array_field->fields,
+               (GDestroyNotify) bt_field_destroy);
+       g_ptr_array_set_size(array_field->fields, array_field->length);
+
+       for (i = 0; i < array_field->length; i++) {
+               array_field->fields->pdata[i] = bt_field_create(
+                       array_ft->element_ft);
+               if (!array_field->fields->pdata[i]) {
+                       BT_LIB_LOGE("Cannot create array field's element field: "
+                               "index=%" PRIu64 ", %![ft-]+F", i, array_ft);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+static
+struct bt_field *create_static_array_field(struct bt_field_type *ft)
+{
+       struct bt_field_type_static_array *array_ft = (void *) ft;
+       struct bt_field_array *array_field;
+
+       BT_LIB_LOGD("Creating static array field object: %![ft-]+F", ft);
+       array_field = g_new0(struct bt_field_array, 1);
+       if (!array_field) {
+               BT_LOGE_STR("Failed to allocate one static array field.");
+               goto end;
+       }
+
+       init_field((void *) array_field, ft, &array_field_methods);
+       array_field->length = array_ft->length;
+
+       if (init_array_field_fields(array_field)) {
+               BT_LIB_LOGE("Cannot create static array fields: "
+                       "%![ft-]+F", ft);
+               BT_PUT(array_field);
+               goto end;
+       }
+
+       BT_LIB_LOGD("Created static array field object: %!+f", array_field);
+
+end:
+       return (void *) array_field;
+}
+
+static
+struct bt_field *create_dynamic_array_field(struct bt_field_type *ft)
+{
+       struct bt_field_array *array_field;
+
+       BT_LIB_LOGD("Creating dynamic array field object: %![ft-]+F", ft);
+       array_field = g_new0(struct bt_field_array, 1);
+       if (!array_field) {
+               BT_LOGE_STR("Failed to allocate one dynamic array field.");
+               goto end;
+       }
+
+       init_field((void *) array_field, ft, &array_field_methods);
+
+       if (init_array_field_fields(array_field)) {
+               BT_LIB_LOGE("Cannot create dynamic array fields: "
+                       "%![ft-]+F", ft);
+               BT_PUT(array_field);
+               goto end;
+       }
+
+       BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field);
+
+end:
+       return (void *) array_field;
+}
+
+int64_t bt_field_signed_integer_get_value(struct bt_field *field)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
+       return int_field->value.i;
+}
+
+void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE(bt_util_value_is_in_range_signed(
+               ((struct bt_field_type_integer *) field->type)->range, value),
+               "Value is out of bounds: value=%" PRId64 ", %![field-]+f, "
+               "%![ft-]+F", value, field, field->type);
+       int_field->value.i = value;
+       bt_field_set_single(field, true);
+}
+
+uint64_t bt_field_unsigned_integer_get_value(struct bt_field *field)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
+       return int_field->value.u;
+}
+
+void bt_field_unsigned_integer_set_value(struct bt_field *field,
+               uint64_t value)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(
+               ((struct bt_field_type_integer *) field->type)->range, value),
+               "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, "
+               "%![ft-]+F", value, field, field->type);
+       int_field->value.u = value;
+       bt_field_set_single(field, true);
+}
+
+double bt_field_real_get_value(struct bt_field *field)
+{
+       struct bt_field_real *real_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
+       return real_field->value;
+}
+
+void bt_field_real_set_value(struct bt_field *field, double value)
+{
+       struct bt_field_real *real_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_REAL, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE(
+               !((struct bt_field_type_real *) field->type)->is_single_precision ||
+               (double) (float) value == value,
+               "Invalid value for a single-precision real number: value=%f, "
+               "%![ft-]+F", value, field->type);
+       real_field->value = value;
+       bt_field_set_single(field, true);
+}
+
+int bt_field_unsigned_enumeration_get_mapping_labels(struct bt_field *field,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION, "Field");
+       return bt_field_type_unsigned_enumeration_get_mapping_labels_by_value(
+               field->type, int_field->value.u, label_array, count);
+}
+
+int bt_field_signed_enumeration_get_mapping_labels(struct bt_field *field,
+               bt_field_type_enumeration_mapping_label_array *label_array,
+               uint64_t *count)
+{
+       struct bt_field_integer *int_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)");
+       BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_SIGNED_ENUMERATION, "Field");
+       return bt_field_type_signed_enumeration_get_mapping_labels_by_value(
+               field->type, int_field->value.i, label_array, count);
+}
+
+const char *bt_field_string_get_value(struct bt_field *field)
+{
+       struct bt_field_string *string_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+               "Field");
+       return (const char *) string_field->buf->data;
+}
+
+uint64_t bt_field_string_get_length(struct bt_field *field)
+{
+       struct bt_field_string *string_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_SET(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+               "Field");
+       return string_field->length;
+}
+
+int bt_field_string_set_value(struct bt_field *field, const char *value)
+{
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_NON_NULL(value, "Value");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field, BT_FIELD_TYPE_ID_STRING,
+               "Field");
+       bt_field_string_clear(field);
+       return bt_field_string_append_with_length(field, value,
+               (uint64_t) strlen(value));
+}
+
+int bt_field_string_append(struct bt_field *field, const char *value)
+{
+       return bt_field_string_append_with_length(field, value,
+               (uint64_t) strlen(value));
+}
+
+int bt_field_string_append_with_length(struct bt_field *field,
+               const char *value, uint64_t length)
+{
+       struct bt_field_string *string_field = (void *) field;
+       char *data;
+       uint64_t new_length;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_NON_NULL(value, "Value");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_STRING, "Field");
+
+       /* Make sure no null bytes are appended */
+       BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
+               "String value to append contains a null character: "
+               "partial-value=\"%.32s\", length=%" PRIu64, value, length);
+
+       new_length = length + string_field->length;
+
+       if (unlikely(new_length + 1 > string_field->buf->len)) {
+               g_array_set_size(string_field->buf, new_length + 1);
+       }
+
+       data = string_field->buf->data;
+       memcpy(data + string_field->length, value, length);
+       ((char *) string_field->buf->data)[new_length] = '\0';
+       string_field->length = new_length;
+       bt_field_set_single(field, true);
+       return 0;
+}
+
+int bt_field_string_clear(struct bt_field *field)
+{
+       struct bt_field_string *string_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_STRING, "Field");
+       string_field->length = 0;
+       bt_field_set_single(field, true);
+       return 0;
+}
+
+uint64_t bt_field_array_get_length(struct bt_field *field)
+{
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
+       return array_field->length;
+}
+
+int bt_field_dynamic_array_set_length(struct bt_field *field,
+               uint64_t length)
+{
+       int ret = 0;
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_DYNAMIC_ARRAY, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+
+       if (unlikely(length > array_field->fields->len)) {
+               /* Make more room */
+               struct bt_field_type_array *array_ft;
+               uint64_t cur_len = array_field->fields->len;
+               uint64_t i;
+
+               g_ptr_array_set_size(array_field->fields, length);
+               array_ft = (void *) field->type;
+
+               for (i = cur_len; i < array_field->fields->len; i++) {
+                       struct bt_field *elem_field = bt_field_create(
+                               array_ft->element_ft);
+
+                       if (!elem_field) {
+                               BT_LIB_LOGE("Cannot create element field for "
+                                       "dynamic array field: "
+                                       "index=%" PRIu64 ", "
+                                       "%![array-field-]+f", i, field);
+                               ret = -1;
+                               goto end;
+                       }
+
+                       BT_ASSERT(!array_field->fields->pdata[i]);
+                       array_field->fields->pdata[i] = elem_field;
+               }
+       }
+
+       array_field->length = length;
+
+end:
+       return ret;
+}
+
+struct bt_field *bt_field_array_borrow_element_field_by_index(
+               struct bt_field *field, uint64_t index)
+{
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field");
+       BT_ASSERT_PRE_VALID_INDEX(index, array_field->length);
+       return array_field->fields->pdata[index];
+}
+
+struct bt_field *bt_field_structure_borrow_member_field_by_index(
+               struct bt_field *field, uint64_t index)
+{
+       struct bt_field_structure *struct_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_STRUCTURE, "Field");
+       BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len);
+       return struct_field->fields->pdata[index];
+}
+
+struct bt_field *bt_field_structure_borrow_member_field_by_name(
+               struct bt_field *field, const char *name)
+{
+       struct bt_field *ret_field = NULL;
+       struct bt_field_type_structure *struct_ft;
+       struct bt_field_structure *struct_field = (void *) field;
+       gpointer orig_key;
+       gpointer index;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_NON_NULL(name, "Field name");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_STRUCTURE, "Field");
+       struct_ft = (void *) field->type;
+
+       if (!g_hash_table_lookup_extended(struct_ft->common.name_to_index, name,
+                       &orig_key, &index)) {
+               goto end;
+       }
+
+       ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)];
+       BT_ASSERT(ret_field);
+
+end:
+       return ret_field;
+}
+
+struct bt_field *bt_field_variant_borrow_selected_option_field(
+               struct bt_field *field)
+{
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_VARIANT, "Field");
+       BT_ASSERT_PRE(var_field->selected_field,
+               "Variant field has no selected field: %!+f", field);
+       return var_field->selected_field;
+}
+
+int bt_field_variant_select_option_field(struct bt_field *field,
+               uint64_t index)
+{
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_VARIANT, "Field");
+       BT_ASSERT_PRE_FIELD_HOT(field, "Field");
+       BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len);
+       var_field->selected_field = var_field->fields->pdata[index];
+       var_field->selected_index = index;
+       return 0;
+}
+
+uint64_t bt_field_variant_get_selected_option_field_index(
+               struct bt_field *field)
+{
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_ASSERT_PRE_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_FIELD_HAS_TYPE_ID(field,
+               BT_FIELD_TYPE_ID_VARIANT, "Field");
+       BT_ASSERT_PRE(var_field->selected_field,
+               "Variant field has no selected field: %!+f", field);
+       return var_field->selected_index;
+}
+
+static inline
+void bt_field_finalize(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       BT_LOGD_STR("Putting field's type.");
+       bt_put(field->type);
+}
+
+static
+void destroy_integer_field(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying integer field object: %!+f", field);
+       bt_field_finalize(field);
+       g_free(field);
+}
+
+static
+void destroy_real_field(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying real field object: %!+f", field);
+       bt_field_finalize(field);
+       g_free(field);
+}
+
+static
+void destroy_structure_field(struct bt_field *field)
+{
+       struct bt_field_structure *struct_field = (void *) field;
+
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying structure field object: %!+f", field);
+       bt_field_finalize(field);
+
+       if (struct_field->fields) {
+               g_ptr_array_free(struct_field->fields, TRUE);
+       }
+
+       g_free(field);
+}
+
+static
+void destroy_variant_field(struct bt_field *field)
+{
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying variant field object: %!+f", field);
+       bt_field_finalize(field);
+
+       if (var_field->fields) {
+               g_ptr_array_free(var_field->fields, TRUE);
+       }
+
+       g_free(field);
+}
+
+static
+void destroy_array_field(struct bt_field *field)
+{
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying array field object: %!+f", field);
+       bt_field_finalize(field);
+
+       if (array_field->fields) {
+               g_ptr_array_free(array_field->fields, TRUE);
+       }
+
+       g_free(field);
+}
+
+static
+void destroy_string_field(struct bt_field *field)
+{
+       struct bt_field_string *string_field = (void *) field;
+
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying string field object: %!+f", field);
+       bt_field_finalize(field);
+
+       if (string_field->buf) {
+               g_array_free(string_field->buf, TRUE);
+       }
+
+       g_free(field);
+}
+
+BT_HIDDEN
+void bt_field_destroy(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       BT_ASSERT(bt_field_type_has_known_id(field->type));
+       field_destroy_funcs[field->type->id](field);
+}
+
+static
+void reset_single_field(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       field->is_set = false;
+}
+
+static
+void reset_structure_field(struct bt_field *field)
+{
+       uint64_t i;
+       struct bt_field_structure *struct_field = (void *) field;
+
+       BT_ASSERT(field);
+
+       for (i = 0; i < struct_field->fields->len; i++) {
+               bt_field_reset(struct_field->fields->pdata[i]);
+       }
+}
+
+static
+void reset_variant_field(struct bt_field *field)
+{
+       uint64_t i;
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_ASSERT(field);
+
+       for (i = 0; i < var_field->fields->len; i++) {
+               bt_field_reset(var_field->fields->pdata[i]);
+       }
+}
+
+static
+void reset_array_field(struct bt_field *field)
+{
+       uint64_t i;
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT(field);
+
+       for (i = 0; i < array_field->fields->len; i++) {
+               bt_field_reset(array_field->fields->pdata[i]);
+       }
+}
+
+static
+void set_single_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+       field->frozen = is_frozen;
+}
+
+static
+void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+       uint64_t i;
+       struct bt_field_structure *struct_field = (void *) field;
+
+       BT_LIB_LOGD("Setting structure field's frozen state: "
+               "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+       for (i = 0; i < struct_field->fields->len; i++) {
+               struct bt_field *member_field = struct_field->fields->pdata[i];
+
+               BT_LIB_LOGD("Setting structure field's member field's "
+                       "frozen state: %![field-]+f, index=%" PRIu64,
+                       member_field, i);
+               bt_field_set_is_frozen(member_field, is_frozen);
+       }
+
+       set_single_field_is_frozen(field, is_frozen);
+}
+
+static
+void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+       uint64_t i;
+       struct bt_field_variant *var_field = (void *) field;
+
+       BT_LIB_LOGD("Setting variant field's frozen state: "
+               "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+       for (i = 0; i < var_field->fields->len; i++) {
+               struct bt_field *option_field = var_field->fields->pdata[i];
+
+               BT_LIB_LOGD("Setting variant field's option field's "
+                       "frozen state: %![field-]+f, index=%" PRIu64,
+                       option_field, i);
+               bt_field_set_is_frozen(option_field, is_frozen);
+       }
+
+       set_single_field_is_frozen(field, is_frozen);
+}
+
+static
+void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+       uint64_t i;
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_LIB_LOGD("Setting array field's frozen state: "
+               "%![field-]+f, is-frozen=%d", field, is_frozen);
+
+       for (i = 0; i < array_field->fields->len; i++) {
+               struct bt_field *elem_field = array_field->fields->pdata[i];
+
+               BT_LIB_LOGD("Setting array field's element field's "
+                       "frozen state: %![field-]+f, index=%" PRIu64,
+                       elem_field, i);
+               bt_field_set_is_frozen(elem_field, is_frozen);
+       }
+
+       set_single_field_is_frozen(field, is_frozen);
+}
+
+BT_HIDDEN
+void _bt_field_set_is_frozen(struct bt_field *field,
+               bool is_frozen)
+{
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d",
+               field, is_frozen);
+       BT_ASSERT(field->methods->set_is_frozen);
+       field->methods->set_is_frozen(field, is_frozen);
+}
+
+static
+bool single_field_is_set(struct bt_field *field)
+{
+       BT_ASSERT(field);
+       return field->is_set;
+}
+
+static
+bool structure_field_is_set(struct bt_field *field)
+{
+       bool is_set = true;
+       uint64_t i;
+       struct bt_field_structure *struct_field = (void *) field;
+
+       BT_ASSERT(field);
+
+       for (i = 0; i < struct_field->fields->len; i++) {
+               is_set = bt_field_is_set(struct_field->fields->pdata[i]);
+               if (!is_set) {
+                       goto end;
+               }
+       }
+
+end:
+       return is_set;
+}
+
+static
+bool variant_field_is_set(struct bt_field *field)
+{
+       struct bt_field_variant *var_field = (void *) field;
+       bool is_set = false;
+
+       BT_ASSERT(field);
+
+       if (var_field->selected_field) {
+               is_set = bt_field_is_set(var_field->selected_field);
+       }
+
+       return is_set;
+}
+
+static
+bool array_field_is_set(struct bt_field *field)
+{
+       bool is_set = true;
+       uint64_t i;
+       struct bt_field_array *array_field = (void *) field;
+
+       BT_ASSERT(field);
+
+       for (i = 0; i < array_field->length; i++) {
+               is_set = bt_field_is_set(array_field->fields->pdata[i]);
+               if (!is_set) {
+                       goto end;
+               }
+       }
+
+end:
+       return is_set;
+}
diff --git a/lib/trace-ir/packet-context-field.c b/lib/trace-ir/packet-context-field.c
new file mode 100644 (file)
index 0000000..b382743
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET-CONTEXT-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/packet-context-field.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_packet_context_field_borrow_field(
+               struct bt_packet_context_field *context_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
+       return field_wrapper->field;
+}
+
+void bt_packet_context_field_release(struct bt_packet_context_field *context_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet context field");
+
+       /*
+        * Do not recycle because the pool could be destroyed at this
+        * point. This function is only called when there's an error
+        * anyway because the goal of a packet context field wrapper is
+        * to eventually move it to a packet with
+        * bt_packet_move_context() after creating it.
+        */
+       bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_packet_context_field *bt_packet_context_field_create(
+               struct bt_stream_class *stream_class)
+{
+       struct bt_field_wrapper *field_wrapper;
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(stream_class->frozen,
+               "Stream class is not part of a trace: %!+S", stream_class);
+       BT_ASSERT_PRE(stream_class->packet_context_ft,
+               "Stream class has no packet context field type: %!+S",
+               stream_class);
+       field_wrapper = bt_field_wrapper_create(
+               &stream_class->packet_context_field_pool,
+               (void *) stream_class->packet_context_ft);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one packet context field from stream class: "
+                       "%![sc-]+S", stream_class);
+               goto error;
+       }
+
+       BT_ASSERT(field_wrapper->field);
+       bt_stream_class_freeze(stream_class);
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return (void *) field_wrapper;
+}
diff --git a/lib/trace-ir/packet-header-field.c b/lib/trace-ir/packet-header-field.c
new file mode 100644 (file)
index 0000000..7f9519e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET-HEADER-FIELD"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-header-field.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <glib.h>
+
+struct bt_field *bt_packet_header_field_borrow_field(
+               struct bt_packet_header_field *header_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
+       return (void *) field_wrapper->field;
+}
+
+void bt_packet_header_field_release(struct bt_packet_header_field *header_field)
+{
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Packet header field");
+
+       /*
+        * Do not recycle because the pool could be destroyed at this
+        * point. This function is only called when there's an error
+        * anyway because the goal of a packet header field wrapper is
+        * to eventually move it to a packet with
+        * bt_packet_move_header() after creating it.
+        */
+       bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_packet_header_field *bt_packet_header_field_create(
+               struct bt_trace *trace)
+{
+       struct bt_field_wrapper *field_wrapper;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE(trace->packet_header_ft,
+               "Trace has no packet header field type: %!+t", trace);
+       field_wrapper = bt_field_wrapper_create(
+               &trace->packet_header_field_pool,
+               (void *) trace->packet_header_ft);
+       if (!field_wrapper) {
+               BT_LIB_LOGE("Cannot allocate one packet header field from trace: "
+                       "%![trace-]+t", trace);
+               goto error;
+       }
+
+       BT_ASSERT(field_wrapper->field);
+       bt_trace_freeze(trace);
+       goto end;
+
+error:
+       if (field_wrapper) {
+               bt_field_wrapper_destroy(field_wrapper);
+               field_wrapper = NULL;
+       }
+
+end:
+       return (void *) field_wrapper;
+}
diff --git a/lib/trace-ir/packet.c b/lib/trace-ir/packet.c
new file mode 100644 (file)
index 0000000..d667721
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * packet.c
+ *
+ * Babeltrace trace IR - Stream packet
+ *
+ * Copyright 2016 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "PACKET"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/clock-value-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/assert-internal.h>
+#include <inttypes.h>
+
+#define BT_ASSERT_PRE_PACKET_HOT(_packet) \
+       BT_ASSERT_PRE_HOT((_packet), "Packet", ": %!+a", (_packet))
+
+struct bt_stream *bt_packet_borrow_stream(struct bt_packet *packet)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       return packet->stream;
+}
+
+struct bt_field *bt_packet_borrow_header_field(struct bt_packet *packet)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       return packet->header_field ? packet->header_field->field : NULL;
+}
+
+struct bt_field *bt_packet_borrow_context_field(struct bt_packet *packet)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       return packet->context_field ? packet->context_field->field : NULL;
+}
+
+BT_HIDDEN
+void _bt_packet_set_is_frozen(struct bt_packet *packet, bool is_frozen)
+{
+       if (!packet) {
+               return;
+       }
+
+       BT_LIB_LOGD("Setting packet's frozen state: %![packet-]+a, "
+               "is-frozen=%d", packet, is_frozen);
+
+       if (packet->header_field) {
+               BT_LOGD_STR("Setting packet's header field's frozen state.");
+               bt_field_set_is_frozen(packet->header_field->field,
+                       is_frozen);
+       }
+
+       if (packet->context_field) {
+               BT_LOGD_STR("Setting packet's context field's frozen state.");
+               bt_field_set_is_frozen(packet->context_field->field,
+                       is_frozen);
+       }
+
+       packet->frozen = is_frozen;
+}
+
+static inline
+void reset_counter_snapshots(struct bt_packet *packet)
+{
+       packet->discarded_event_counter_snapshot.base.avail =
+               BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+       packet->packet_counter_snapshot.base.avail =
+               BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE;
+}
+
+static inline
+void reset_packet(struct bt_packet *packet)
+{
+       BT_ASSERT(packet);
+       BT_LIB_LOGD("Resetting packet: %!+a", packet);
+       bt_packet_set_is_frozen(packet, false);
+
+       if (packet->header_field) {
+               bt_field_set_is_frozen(packet->header_field->field, false);
+               bt_field_reset(packet->header_field->field);
+       }
+
+       if (packet->context_field) {
+               bt_field_set_is_frozen(packet->context_field->field, false);
+               bt_field_reset(packet->context_field->field);
+       }
+
+       if (packet->default_beginning_cv) {
+               bt_clock_value_reset(packet->default_beginning_cv);
+       }
+
+       if (packet->default_end_cv) {
+               bt_clock_value_reset(packet->default_end_cv);
+       }
+
+       reset_counter_snapshots(packet);
+}
+
+static
+void recycle_header_field(struct bt_field_wrapper *header_field,
+               struct bt_trace *trace)
+{
+       BT_ASSERT(header_field);
+       BT_LIB_LOGD("Recycling packet header field: "
+               "addr=%p, %![trace-]+t, %![field-]+f", header_field,
+               trace, header_field->field);
+       bt_object_pool_recycle_object(&trace->packet_header_field_pool,
+               header_field);
+}
+
+static
+void recycle_context_field(struct bt_field_wrapper *context_field,
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT(context_field);
+       BT_LIB_LOGD("Recycling packet context field: "
+               "addr=%p, %![sc-]+S, %![field-]+f", context_field,
+               stream_class, context_field->field);
+       bt_object_pool_recycle_object(&stream_class->packet_context_field_pool,
+               context_field);
+}
+
+BT_HIDDEN
+void bt_packet_recycle(struct bt_packet *packet)
+{
+       struct bt_stream *stream;
+
+       BT_ASSERT(packet);
+       BT_LIB_LOGD("Recycling packet: %!+a", packet);
+
+       /*
+        * Those are the important ordered steps:
+        *
+        * 1. Reset the packet object (put any permanent reference it
+        *    has, unfreeze it and its fields in developer mode, etc.),
+        *    but do NOT put its stream's reference. This stream
+        *    contains the pool to which we're about to recycle this
+        *    packet object, so we must guarantee its existence thanks
+        *    to this existing reference.
+        *
+        * 2. Move the stream reference to our `stream`
+        *    variable so that we can set the packet's stream member
+        *    to NULL before recycling it. We CANNOT do this after
+        *    we put the stream reference because this bt_put()
+        *    could destroy the stream, also destroying its
+        *    packet pool, thus also destroying our packet object (this
+        *    would result in an invalid write access).
+        *
+        * 3. Recycle the packet object.
+        *
+        * 4. Put our stream reference.
+        */
+       reset_packet(packet);
+       stream = packet->stream;
+       BT_ASSERT(stream);
+       packet->stream = NULL;
+       bt_object_pool_recycle_object(&stream->packet_pool, packet);
+       bt_object_put_no_null_check(&stream->base);
+}
+
+BT_HIDDEN
+void bt_packet_destroy(struct bt_packet *packet)
+{
+       BT_LIB_LOGD("Destroying packet: %!+a", packet);
+
+       if (packet->header_field) {
+               if (packet->stream) {
+                       BT_LOGD_STR("Recycling packet's header field.");
+                       recycle_header_field(packet->header_field,
+                               bt_stream_class_borrow_trace_inline(
+                                       packet->stream->class));
+               } else {
+                       bt_field_wrapper_destroy(packet->header_field);
+               }
+       }
+
+       if (packet->context_field) {
+               if (packet->stream) {
+                       BT_LOGD_STR("Recycling packet's context field.");
+                       recycle_context_field(packet->context_field,
+                               packet->stream->class);
+               } else {
+                       bt_field_wrapper_destroy(packet->context_field);
+               }
+       }
+
+       if (packet->default_beginning_cv) {
+               BT_LOGD_STR("Recycling beginning clock value.");
+               bt_clock_value_recycle(packet->default_beginning_cv);
+       }
+
+       if (packet->default_end_cv) {
+               BT_LOGD_STR("Recycling end clock value.");
+               bt_clock_value_recycle(packet->default_end_cv);
+       }
+
+       BT_LOGD_STR("Putting packet's stream.");
+       bt_put(packet->stream);
+       g_free(packet);
+}
+
+BT_HIDDEN
+struct bt_packet *bt_packet_new(struct bt_stream *stream)
+{
+       struct bt_packet *packet = NULL;
+       struct bt_trace *trace = NULL;
+
+       BT_ASSERT(stream);
+       BT_LIB_LOGD("Creating packet object: %![stream-]+s", stream);
+       packet = g_new0(struct bt_packet, 1);
+       if (!packet) {
+               BT_LOGE_STR("Failed to allocate one packet object.");
+               goto error;
+       }
+
+       bt_object_init_shared(&packet->base,
+               (bt_object_release_func) bt_packet_recycle);
+       packet->stream = bt_get(stream);
+       trace = bt_stream_class_borrow_trace_inline(stream->class);
+       BT_ASSERT(trace);
+
+       if (trace->packet_header_ft) {
+               BT_LOGD_STR("Creating initial packet header field.");
+               packet->header_field = bt_field_wrapper_create(
+                       &trace->packet_header_field_pool,
+                       trace->packet_header_ft);
+               if (!packet->header_field) {
+                       BT_LOGE_STR("Cannot create packet header field wrapper.");
+                       goto error;
+               }
+       }
+
+       if (stream->class->packet_context_ft) {
+               BT_LOGD_STR("Creating initial packet context field.");
+               packet->context_field = bt_field_wrapper_create(
+                       &stream->class->packet_context_field_pool,
+                       stream->class->packet_context_ft);
+               if (!packet->context_field) {
+                       BT_LOGE_STR("Cannot create packet context field wrapper.");
+                       goto error;
+               }
+       }
+
+       if (stream->class->default_clock_class) {
+               if (stream->class->packets_have_default_beginning_cv) {
+                       packet->default_beginning_cv = bt_clock_value_create(
+                               stream->class->default_clock_class);
+                       if (!packet->default_beginning_cv) {
+                               /* bt_clock_value_create() logs errors */
+                               goto error;
+                       }
+               }
+
+               if (stream->class->packets_have_default_end_cv) {
+                       packet->default_end_cv = bt_clock_value_create(
+                               stream->class->default_clock_class);
+                       if (!packet->default_end_cv) {
+                               /* bt_clock_value_create() logs errors */
+                               goto error;
+                       }
+               }
+       }
+
+       reset_counter_snapshots(packet);
+       BT_LIB_LOGD("Created packet object: %!+a", packet);
+       goto end;
+
+error:
+       BT_PUT(packet);
+
+end:
+       return packet;
+}
+
+struct bt_packet *bt_packet_create(struct bt_stream *stream)
+{
+       struct bt_packet *packet = NULL;
+
+       BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+       packet = bt_object_pool_create_object(&stream->packet_pool);
+       if (unlikely(!packet)) {
+               BT_LIB_LOGE("Cannot allocate one packet from stream's packet pool: "
+                       "%![stream-]+s", stream);
+               goto end;
+       }
+
+       if (likely(!packet->stream)) {
+               packet->stream = stream;
+               bt_object_get_no_null_check_no_parent_check(
+                       &packet->stream->base);
+       }
+
+end:
+       return packet;
+}
+
+int bt_packet_move_header_field(struct bt_packet *packet,
+               struct bt_packet_header_field *header_field)
+{
+       struct bt_trace *trace;
+       struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
+       BT_ASSERT_PRE_PACKET_HOT(packet);
+       trace = bt_stream_class_borrow_trace_inline(packet->stream->class);
+       BT_ASSERT_PRE(trace->packet_header_ft,
+               "Trace has no packet header field type: %!+t",
+               trace);
+       BT_ASSERT_PRE(field_wrapper->field->type ==
+               trace->packet_header_ft,
+               "Unexpected packet header field's type: "
+               "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
+               trace->packet_header_ft);
+
+       /* Recycle current header field: always exists */
+       BT_ASSERT(packet->header_field);
+       recycle_header_field(packet->header_field, trace);
+
+       /* Move new field */
+       packet->header_field = field_wrapper;
+       return 0;
+}
+
+int bt_packet_move_context_field(struct bt_packet *packet,
+               struct bt_packet_context_field *context_field)
+{
+       struct bt_stream_class *stream_class;
+       struct bt_field_wrapper *field_wrapper = (void *) context_field;
+
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(field_wrapper, "Context field");
+       BT_ASSERT_PRE_HOT(packet, "Packet", ": %!+a", packet);
+       stream_class = packet->stream->class;
+       BT_ASSERT_PRE(stream_class->packet_context_ft,
+               "Stream class has no packet context field type: %!+S",
+               stream_class);
+       BT_ASSERT_PRE(field_wrapper->field->type ==
+               stream_class->packet_context_ft,
+               "Unexpected packet header field's type: "
+               "%![ft-]+F, %![expected-ft-]+F", field_wrapper->field->type,
+               stream_class->packet_context_ft);
+
+       /* Recycle current context field: always exists */
+       BT_ASSERT(packet->context_field);
+       recycle_context_field(packet->context_field, stream_class);
+
+       /* Move new field */
+       packet->context_field = field_wrapper;
+       return 0;
+}
+
+int bt_packet_set_default_beginning_clock_value(struct bt_packet *packet,
+               uint64_t value_cycles)
+{
+       struct bt_stream_class *sc;
+
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_PACKET_HOT(packet);
+       sc = packet->stream->class;
+       BT_ASSERT(sc);
+       BT_ASSERT_PRE(sc->default_clock_class,
+               "Packet's stream class has no default clock class: "
+               "%![packet-]+a, %![sc-]+S", packet, sc);
+       BT_ASSERT_PRE(sc->packets_have_default_beginning_cv,
+               "Packet's stream class indicates that its packets have "
+               "no default beginning clock value: %![packet-]+a, %![sc-]+S",
+               packet, sc);
+       BT_ASSERT(packet->default_beginning_cv);
+       bt_clock_value_set_value_inline(packet->default_beginning_cv, value_cycles);
+       BT_LIB_LOGV("Set packet's default beginning clock value: "
+               "%![packet-]+a, value=%" PRIu64, value_cycles);
+       return 0;
+}
+
+enum bt_clock_value_status bt_packet_borrow_default_beginning_clock_value(
+               struct bt_packet *packet, struct bt_clock_value **clock_value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+       *clock_value = packet->default_beginning_cv;
+       return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+int bt_packet_set_default_end_clock_value(struct bt_packet *packet,
+               uint64_t value_cycles)
+{
+       struct bt_stream_class *sc;
+
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_PACKET_HOT(packet);
+       sc = packet->stream->class;
+       BT_ASSERT(sc);
+       BT_ASSERT_PRE(sc->default_clock_class,
+               "Packet's stream class has no default clock class: "
+               "%![packet-]+a, %![sc-]+S", packet, sc);
+       BT_ASSERT_PRE(sc->packets_have_default_end_cv,
+               "Packet's stream class indicates that its packets have "
+               "no default end clock value: %![packet-]+a, %![sc-]+S",
+               packet, sc);
+       BT_ASSERT(packet->default_end_cv);
+       bt_clock_value_set_value_inline(packet->default_end_cv, value_cycles);
+       BT_LIB_LOGV("Set packet's default end clock value: "
+               "%![packet-]+a, value=%" PRIu64, value_cycles);
+       return 0;
+}
+
+enum bt_clock_value_status bt_packet_borrow_default_end_clock_value(
+               struct bt_packet *packet, struct bt_clock_value **clock_value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(clock_value, "Clock value (output)");
+       *clock_value = packet->default_end_cv;
+       return BT_CLOCK_VALUE_STATUS_KNOWN;
+}
+
+enum bt_property_availability bt_packet_get_discarded_event_counter_snapshot(
+               struct bt_packet *packet, uint64_t *value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
+       *value = packet->discarded_event_counter_snapshot.value;
+       return packet->discarded_event_counter_snapshot.base.avail;
+}
+
+int bt_packet_set_discarded_event_counter_snapshot(struct bt_packet *packet,
+               uint64_t value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_PACKET_HOT(packet);
+       BT_ASSERT_PRE(packet->stream->class->packets_have_discarded_event_counter_snapshot,
+               "Packet's stream's discarded event counter is not enabled: "
+               "%![packet-]+a", packet);
+       bt_property_uint_set(&packet->discarded_event_counter_snapshot, value);
+       return 0;
+}
+
+enum bt_property_availability bt_packet_get_packet_counter_snapshot(
+               struct bt_packet *packet, uint64_t *value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_NON_NULL(value, "Value (output)");
+       *value = packet->packet_counter_snapshot.value;
+       return packet->packet_counter_snapshot.base.avail;
+}
+
+int bt_packet_set_packet_counter_snapshot(struct bt_packet *packet,
+               uint64_t value)
+{
+       BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+       BT_ASSERT_PRE_PACKET_HOT(packet);
+       BT_ASSERT_PRE(packet->stream->class->packets_have_packet_counter_snapshot,
+               "Packet's stream's packet counter is not enabled: "
+               "%![packet-]+a", packet);
+       bt_property_uint_set(&packet->packet_counter_snapshot, value);
+       return 0;
+}
diff --git a/lib/trace-ir/resolve-field-path.c b/lib/trace-ir/resolve-field-path.c
new file mode 100644 (file)
index 0000000..02150f4
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+ * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "RESOLVE-FIELD-PATH"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/field-path-internal.h>
+#include <babeltrace/trace-ir/field-path.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <limits.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <glib.h>
+
+static
+bool find_field_type_recursive(struct bt_field_type *ft,
+               struct bt_field_type *tgt_ft, struct bt_field_path *field_path)
+{
+       bool found = false;
+
+       if (tgt_ft == ft) {
+               found = true;
+               goto end;
+       }
+
+       switch (ft->id) {
+       case BT_FIELD_TYPE_ID_STRUCTURE:
+       case BT_FIELD_TYPE_ID_VARIANT:
+       {
+               struct bt_field_type_named_field_types_container *container_ft =
+                       (void *) ft;
+               uint64_t i;
+
+               for (i = 0; i < container_ft->named_fts->len; i++) {
+                       struct bt_named_field_type *named_ft =
+                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+                                       container_ft, i);
+
+                       g_array_append_val(field_path->indexes, i);
+                       found = find_field_type_recursive(named_ft->ft,
+                               tgt_ft, field_path);
+                       if (found) {
+                               goto end;
+                       }
+
+                       g_array_set_size(field_path->indexes,
+                               field_path->indexes->len - 1);
+               }
+
+               break;
+       }
+       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+       {
+               struct bt_field_type_array *array_ft = (void *) ft;
+
+               found = find_field_type_recursive(array_ft->element_ft,
+                       tgt_ft, field_path);
+               break;
+       }
+       default:
+               break;
+       }
+
+end:
+       return found;
+}
+
+static
+int find_field_type(struct bt_field_type *root_ft,
+               enum bt_scope root_scope, struct bt_field_type *tgt_ft,
+               struct bt_field_path **ret_field_path)
+{
+       int ret = 0;
+       struct bt_field_path *field_path = NULL;
+
+       if (!root_ft) {
+               goto end;
+       }
+
+       field_path = bt_field_path_create();
+       if (!field_path) {
+               ret = -1;
+               goto end;
+       }
+
+       field_path->root = root_scope;
+       if (!find_field_type_recursive(root_ft, tgt_ft, field_path)) {
+               /* Not found here */
+               BT_PUT(field_path);
+       }
+
+end:
+       *ret_field_path = field_path;
+       return ret;
+}
+
+static
+struct bt_field_path *find_field_type_in_ctx(struct bt_field_type *ft,
+               struct bt_resolve_field_path_context *ctx)
+{
+       struct bt_field_path *field_path = NULL;
+       int ret;
+
+       ret = find_field_type(ctx->packet_header, BT_SCOPE_PACKET_HEADER,
+               ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+       ret = find_field_type(ctx->packet_context, BT_SCOPE_PACKET_CONTEXT,
+               ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+       ret = find_field_type(ctx->event_header, BT_SCOPE_EVENT_HEADER,
+               ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+       ret = find_field_type(ctx->event_common_context,
+               BT_SCOPE_EVENT_COMMON_CONTEXT, ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+       ret = find_field_type(ctx->event_specific_context,
+               BT_SCOPE_EVENT_SPECIFIC_CONTEXT, ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+       ret = find_field_type(ctx->event_payload, BT_SCOPE_EVENT_PAYLOAD,
+               ft, &field_path);
+       if (ret || field_path) {
+               goto end;
+       }
+
+end:
+       return field_path;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool target_is_before_source(struct bt_field_path *src_field_path,
+               struct bt_field_path *tgt_field_path)
+{
+       bool is_valid = true;
+       uint64_t src_i = 0, tgt_i = 0;
+
+       if (tgt_field_path->root < src_field_path->root) {
+               goto end;
+       }
+
+       if (tgt_field_path->root > src_field_path->root) {
+               is_valid = false;
+               goto end;
+       }
+
+       BT_ASSERT(tgt_field_path->root == src_field_path->root);
+
+       while (src_i < src_field_path->indexes->len &&
+                       tgt_i < tgt_field_path->indexes->len) {
+               uint64_t src_index = bt_field_path_get_index_by_index_inline(
+                       src_field_path, src_i);
+               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+                       tgt_field_path, tgt_i);
+
+               if (tgt_index > src_index) {
+                       is_valid = false;
+                       goto end;
+               }
+
+               src_i++;
+               tgt_i++;
+       }
+
+end:
+       return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+struct bt_field_type *borrow_root_field_type(
+               struct bt_resolve_field_path_context *ctx, enum bt_scope scope)
+{
+       switch (scope) {
+       case BT_SCOPE_PACKET_HEADER:
+               return ctx->packet_header;
+       case BT_SCOPE_PACKET_CONTEXT:
+               return ctx->packet_context;
+       case BT_SCOPE_EVENT_HEADER:
+               return ctx->event_header;
+       case BT_SCOPE_EVENT_COMMON_CONTEXT:
+               return ctx->event_common_context;
+       case BT_SCOPE_EVENT_SPECIFIC_CONTEXT:
+               return ctx->event_specific_context;
+       case BT_SCOPE_EVENT_PAYLOAD:
+               return ctx->event_payload;
+       default:
+               abort();
+       }
+
+       return NULL;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+struct bt_field_type *borrow_child_field_type(struct bt_field_type *parent_ft,
+               uint64_t index, bool *advance)
+{
+       struct bt_field_type *child_ft = NULL;
+
+       switch (parent_ft->id) {
+       case BT_FIELD_TYPE_ID_STRUCTURE:
+       case BT_FIELD_TYPE_ID_VARIANT:
+       {
+               struct bt_named_field_type *named_ft =
+                       BT_FIELD_TYPE_NAMED_FT_AT_INDEX(parent_ft, index);
+
+               child_ft = named_ft->ft;
+               *advance = true;
+               break;
+       }
+       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+       {
+               struct bt_field_type_array *array_ft = (void *) parent_ft;
+
+               child_ft = array_ft->element_ft;
+               *advance = false;
+               break;
+       }
+       default:
+               break;
+       }
+
+       return child_ft;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool target_field_path_in_different_scope_has_struct_ft_only(
+               struct bt_field_path *src_field_path,
+               struct bt_field_path *tgt_field_path,
+               struct bt_resolve_field_path_context *ctx)
+{
+       bool is_valid = true;
+       uint64_t i = 0;
+       struct bt_field_type *ft;
+
+       if (src_field_path->root == tgt_field_path->root) {
+               goto end;
+       }
+
+       ft = borrow_root_field_type(ctx, tgt_field_path->root);
+
+       while (i < tgt_field_path->indexes->len) {
+               uint64_t index = bt_field_path_get_index_by_index_inline(
+                       tgt_field_path, i);
+               bool advance;
+
+               if (ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
+                               ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
+                               ft->id == BT_FIELD_TYPE_ID_VARIANT) {
+                       is_valid = false;
+                       goto end;
+               }
+
+               ft = borrow_child_field_type(ft, index, &advance);
+
+               if (advance) {
+                       i++;
+               }
+       }
+
+end:
+       return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool lca_is_structure_field_type(struct bt_field_path *src_field_path,
+               struct bt_field_path *tgt_field_path,
+               struct bt_resolve_field_path_context *ctx)
+{
+       bool is_valid = true;
+       struct bt_field_type *src_ft;
+       struct bt_field_type *tgt_ft;
+       struct bt_field_type *prev_ft = NULL;
+       uint64_t src_i = 0, tgt_i = 0;
+
+       if (src_field_path->root != tgt_field_path->root) {
+               goto end;
+       }
+
+       src_ft = borrow_root_field_type(ctx, src_field_path->root);
+       tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
+       BT_ASSERT(src_ft);
+       BT_ASSERT(tgt_ft);
+
+       while (src_i < src_field_path->indexes->len &&
+                       tgt_i < tgt_field_path->indexes->len) {
+               bool advance;
+               uint64_t src_index = bt_field_path_get_index_by_index_inline(
+                       src_field_path, src_i);
+               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+                       tgt_field_path, tgt_i);
+
+               if (src_ft != tgt_ft) {
+                       if (!prev_ft) {
+                               /*
+                                * This is correct: the LCA is the root
+                                * scope field type, which must be a
+                                * structure field type.
+                                */
+                               break;
+                       }
+
+                       if (prev_ft->id != BT_FIELD_TYPE_ID_STRUCTURE) {
+                               is_valid = false;
+                       }
+
+                       break;
+               }
+
+               prev_ft = src_ft;
+               src_ft = borrow_child_field_type(src_ft, src_index, &advance);
+
+               if (advance) {
+                       src_i++;
+               }
+
+               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+               if (advance) {
+                       tgt_i++;
+               }
+       }
+
+end:
+       return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool lca_to_target_has_struct_ft_only(struct bt_field_path *src_field_path,
+               struct bt_field_path *tgt_field_path,
+               struct bt_resolve_field_path_context *ctx)
+{
+       bool is_valid = true;
+       struct bt_field_type *src_ft;
+       struct bt_field_type *tgt_ft;
+       uint64_t src_i = 0, tgt_i = 0;
+
+       if (src_field_path->root != tgt_field_path->root) {
+               goto end;
+       }
+
+       src_ft = borrow_root_field_type(ctx, src_field_path->root);
+       tgt_ft = borrow_root_field_type(ctx, tgt_field_path->root);
+       BT_ASSERT(src_ft);
+       BT_ASSERT(tgt_ft);
+       BT_ASSERT(src_ft == tgt_ft);
+
+       /* Find LCA */
+       while (src_i < src_field_path->indexes->len &&
+                       tgt_i < tgt_field_path->indexes->len) {
+               bool advance;
+               uint64_t src_index = bt_field_path_get_index_by_index_inline(
+                       src_field_path, src_i);
+               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+                       tgt_field_path, tgt_i);
+
+               if (src_i != tgt_i) {
+                       /* Next FT is different: LCA is `tgt_ft` */
+                       break;
+               }
+
+               src_ft = borrow_child_field_type(src_ft, src_index, &advance);
+
+               if (advance) {
+                       src_i++;
+               }
+
+               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+               if (advance) {
+                       tgt_i++;
+               }
+       }
+
+       /* Only structure field types to the target */
+       while (tgt_i < tgt_field_path->indexes->len) {
+               bool advance;
+               uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
+                       tgt_field_path, tgt_i);
+
+               if (tgt_ft->id == BT_FIELD_TYPE_ID_STATIC_ARRAY ||
+                               tgt_ft->id == BT_FIELD_TYPE_ID_DYNAMIC_ARRAY ||
+                               tgt_ft->id == BT_FIELD_TYPE_ID_VARIANT) {
+                       is_valid = false;
+                       goto end;
+               }
+
+               tgt_ft = borrow_child_field_type(tgt_ft, tgt_index, &advance);
+
+               if (advance) {
+                       tgt_i++;
+               }
+       }
+
+end:
+       return is_valid;
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool field_path_is_valid(struct bt_field_type *src_ft,
+               struct bt_field_type *tgt_ft,
+               struct bt_resolve_field_path_context *ctx)
+{
+       bool is_valid = true;
+       struct bt_field_path *src_field_path = find_field_type_in_ctx(
+               src_ft, ctx);
+       struct bt_field_path *tgt_field_path = find_field_type_in_ctx(
+               tgt_ft, ctx);
+
+       if (!src_field_path) {
+               BT_ASSERT_PRE_MSG("Cannot find requesting field type in "
+                       "resolving context: %!+F", src_ft);
+               is_valid = false;
+               goto end;
+       }
+
+       if (!tgt_field_path) {
+               BT_ASSERT_PRE_MSG("Cannot find target field type in "
+                       "resolving context: %!+F", tgt_ft);
+               is_valid = false;
+               goto end;
+       }
+
+       /* Target must be before source */
+       if (!target_is_before_source(src_field_path, tgt_field_path)) {
+               BT_ASSERT_PRE_MSG("Target field type is located after "
+                       "requesting field type: %![req-ft-]+F, %![tgt-ft-]+F",
+                       src_ft, tgt_ft);
+               is_valid = false;
+               goto end;
+       }
+
+       /*
+        * If target is in a different scope than source, there are no
+        * array or variant field types on the way to the target.
+        */
+       if (!target_field_path_in_different_scope_has_struct_ft_only(
+                       src_field_path, tgt_field_path, ctx)) {
+               BT_ASSERT_PRE_MSG("Target field type is located in a "
+                       "different scope than requesting field type, "
+                       "but within an array or a variant field type: "
+                       "%![req-ft-]+F, %![tgt-ft-]+F",
+                       src_ft, tgt_ft);
+               is_valid = false;
+               goto end;
+       }
+
+       /* Same scope: LCA must be a structure field type */
+       if (!lca_is_structure_field_type(src_field_path, tgt_field_path, ctx)) {
+               BT_ASSERT_PRE_MSG("Lowest common ancestor of target and "
+                       "requesting field types is not a structure field type: "
+                       "%![req-ft-]+F, %![tgt-ft-]+F",
+                       src_ft, tgt_ft);
+               is_valid = false;
+               goto end;
+       }
+
+       /* Same scope: path from LCA to target has no array/variant FTs */
+       if (!lca_to_target_has_struct_ft_only(src_field_path, tgt_field_path,
+                       ctx)) {
+               BT_ASSERT_PRE_MSG("Path from lowest common ancestor of target "
+                       "and requesting field types to target field type "
+                       "contains an array or a variant field type: "
+                       "%![req-ft-]+F, %![tgt-ft-]+F", src_ft, tgt_ft);
+               is_valid = false;
+               goto end;
+       }
+
+end:
+       bt_put(src_field_path);
+       bt_put(tgt_field_path);
+       return is_valid;
+}
+
+static
+struct bt_field_path *resolve_field_path(struct bt_field_type *src_ft,
+               struct bt_field_type *tgt_ft,
+               struct bt_resolve_field_path_context *ctx)
+{
+       BT_ASSERT_PRE(field_path_is_valid(src_ft, tgt_ft, ctx),
+               "Invalid target field type: %![req-ft-]+F, %![tgt-ft-]+F",
+               src_ft, tgt_ft);
+       return find_field_type_in_ctx(tgt_ft, ctx);
+}
+
+BT_HIDDEN
+int bt_resolve_field_paths(struct bt_field_type *ft,
+               struct bt_resolve_field_path_context *ctx)
+{
+       int ret = 0;
+
+       BT_ASSERT(ft);
+
+       /* Resolving part for dynamic array and variant field types */
+       switch (ft->id) {
+       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+       {
+               struct bt_field_type_dynamic_array *dyn_array_ft = (void *) ft;
+
+               if (dyn_array_ft->length_ft) {
+                       BT_ASSERT(!dyn_array_ft->length_field_path);
+                       dyn_array_ft->length_field_path = resolve_field_path(
+                               ft, dyn_array_ft->length_ft, ctx);
+                       if (!dyn_array_ft->length_field_path) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               break;
+       }
+       case BT_FIELD_TYPE_ID_VARIANT:
+       {
+               struct bt_field_type_variant *var_ft = (void *) ft;
+
+               if (var_ft->selector_ft) {
+                       BT_ASSERT(!var_ft->selector_field_path);
+                       var_ft->selector_field_path =
+                               resolve_field_path(ft,
+                                       var_ft->selector_ft, ctx);
+                       if (!var_ft->selector_field_path) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+       }
+       default:
+               break;
+       }
+
+       /* Recursive part */
+       switch (ft->id) {
+       case BT_FIELD_TYPE_ID_STRUCTURE:
+       case BT_FIELD_TYPE_ID_VARIANT:
+       {
+               struct bt_field_type_named_field_types_container *container_ft =
+                       (void *) ft;
+               uint64_t i;
+
+               for (i = 0; i < container_ft->named_fts->len; i++) {
+                       struct bt_named_field_type *named_ft =
+                               BT_FIELD_TYPE_NAMED_FT_AT_INDEX(
+                                       container_ft, i);
+
+                       ret = bt_resolve_field_paths(named_ft->ft, ctx);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+
+               break;
+       }
+       case BT_FIELD_TYPE_ID_STATIC_ARRAY:
+       case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
+       {
+               struct bt_field_type_array *array_ft = (void *) ft;
+
+               ret = bt_resolve_field_paths(array_ft->element_ft, ctx);
+               break;
+       }
+       default:
+               break;
+       }
+
+end:
+       return ret;
+}
diff --git a/lib/trace-ir/stream-class.c b/lib/trace-ir/stream-class.c
new file mode 100644 (file)
index 0000000..7fd1a80
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * stream-class.c
+ *
+ * Babeltrace trace IR - Stream Class
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "STREAM-CLASS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/fields-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/property-internal.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define BT_ASSERT_PRE_STREAM_CLASS_HOT(_sc) \
+       BT_ASSERT_PRE_HOT((_sc), "Stream class", ": %!+S", (_sc))
+
+static
+void destroy_stream_class(struct bt_object *obj)
+{
+       struct bt_stream_class *stream_class = (void *) obj;
+
+       BT_LIB_LOGD("Destroying stream class: %!+S", stream_class);
+       BT_LOGD_STR("Putting default clock class.");
+       bt_put(stream_class->default_clock_class);
+
+       if (stream_class->event_classes) {
+               BT_LOGD_STR("Destroying event classes.");
+               g_ptr_array_free(stream_class->event_classes, TRUE);
+       }
+
+       if (stream_class->name.str) {
+               g_string_free(stream_class->name.str, TRUE);
+       }
+
+       BT_LOGD_STR("Putting event header field type.");
+       bt_put(stream_class->event_header_ft);
+       BT_LOGD_STR("Putting packet context field type.");
+       bt_put(stream_class->packet_context_ft);
+       BT_LOGD_STR("Putting event common context field type.");
+       bt_put(stream_class->event_common_context_ft);
+       bt_object_pool_finalize(&stream_class->event_header_field_pool);
+       bt_object_pool_finalize(&stream_class->packet_context_field_pool);
+       g_free(stream_class);
+}
+
+static
+void free_field_wrapper(struct bt_field_wrapper *field_wrapper,
+               struct bt_stream_class *stream_class)
+{
+       bt_field_wrapper_destroy((void *) field_wrapper);
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool stream_class_id_is_unique(struct bt_trace *trace, uint64_t id)
+{
+       uint64_t i;
+       bool is_unique = true;
+
+       for (i = 0; i < trace->stream_classes->len; i++) {
+               struct bt_stream_class *sc =
+                       trace->stream_classes->pdata[i];
+
+               if (sc->id == id) {
+                       is_unique = false;
+                       goto end;
+               }
+       }
+
+end:
+       return is_unique;
+}
+
+static
+struct bt_stream_class *create_stream_class_with_id(struct bt_trace *trace,
+               uint64_t id)
+{
+       struct bt_stream_class *stream_class = NULL;
+       int ret;
+
+       BT_ASSERT(trace);
+       BT_ASSERT_PRE(stream_class_id_is_unique(trace, id),
+               "Duplicate stream class ID: %![trace-]+t, id=%" PRIu64,
+               trace, id);
+       BT_LIB_LOGD("Creating stream class object: %![trace-]+t, id=%" PRIu64,
+               trace, id);
+       stream_class = g_new0(struct bt_stream_class, 1);
+       if (!stream_class) {
+               BT_LOGE_STR("Failed to allocate one stream class.");
+               goto error;
+       }
+
+       bt_object_init_shared_with_parent(&stream_class->base,
+               destroy_stream_class);
+
+       stream_class->name.str = g_string_new(NULL);
+       if (!stream_class->name.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               ret = -1;
+               goto end;
+       }
+
+       stream_class->id = id;
+       stream_class->assigns_automatic_event_class_id = true;
+       stream_class->assigns_automatic_stream_id = true;
+       stream_class->event_classes = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_try_spec_release);
+       if (!stream_class->event_classes) {
+               BT_LOGE_STR("Failed to allocate a GPtrArray.");
+               goto error;
+       }
+
+       ret = bt_object_pool_initialize(&stream_class->event_header_field_pool,
+               (bt_object_pool_new_object_func) bt_field_wrapper_new,
+               (bt_object_pool_destroy_object_func) free_field_wrapper,
+               stream_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize event header field pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       ret = bt_object_pool_initialize(&stream_class->packet_context_field_pool,
+               (bt_object_pool_new_object_func) bt_field_wrapper_new,
+               (bt_object_pool_destroy_object_func) free_field_wrapper,
+               stream_class);
+       if (ret) {
+               BT_LOGE("Failed to initialize packet context field pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       bt_object_set_parent(&stream_class->base, &trace->base);
+       g_ptr_array_add(trace->stream_classes, stream_class);
+       bt_trace_freeze(trace);
+       BT_LIB_LOGD("Created stream class object: %!+S", stream_class);
+       goto end;
+
+error:
+       BT_PUT(stream_class);
+
+end:
+       return stream_class;
+}
+
+struct bt_stream_class *bt_stream_class_create(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE(trace->assigns_automatic_stream_class_id,
+               "Trace does not automatically assigns stream class IDs: "
+               "%![sc-]+t", trace);
+       return create_stream_class_with_id(trace,
+               (uint64_t) trace->stream_classes->len);
+}
+
+struct bt_stream_class *bt_stream_class_create_with_id(
+               struct bt_trace *trace, uint64_t id)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE(!trace->assigns_automatic_stream_class_id,
+               "Trace automatically assigns stream class IDs: "
+               "%![sc-]+t", trace);
+       return create_stream_class_with_id(trace, id);
+}
+
+struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return bt_stream_class_borrow_trace_inline(stream_class);
+}
+
+const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->name.value;
+}
+
+int bt_stream_class_set_name(struct bt_stream_class *stream_class,
+               const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       g_string_assign(stream_class->name.str, name);
+       stream_class->name.value = stream_class->name.str->str;
+       BT_LIB_LOGV("Set stream class's name: %!+S", stream_class);
+       return 0;
+}
+
+uint64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->id;
+}
+
+uint64_t bt_stream_class_get_event_class_count(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (uint64_t) stream_class->event_classes->len;
+}
+
+struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
+               struct bt_stream_class *stream_class, uint64_t index)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_VALID_INDEX(index, stream_class->event_classes->len);
+       return g_ptr_array_index(stream_class->event_classes, index);
+}
+
+struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
+               struct bt_stream_class *trace, uint64_t id)
+{
+       struct bt_event_class *event_class = NULL;
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+       for (i = 0; i < trace->event_classes->len; i++) {
+               struct bt_event_class *event_class_candidate =
+                       g_ptr_array_index(trace->event_classes, i);
+
+               if (event_class_candidate->id == id) {
+                       event_class = event_class_candidate;
+                       goto end;
+               }
+       }
+
+end:
+       return event_class;
+}
+
+struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->packet_context_ft;
+}
+
+int bt_stream_class_set_packet_context_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = NULL,
+               .packet_context = field_type,
+               .event_header = NULL,
+               .event_common_context = NULL,
+               .event_specific_context = NULL,
+               .event_payload = NULL,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Packet context field type is not a structure field type: %!+F",
+               field_type);
+       resolve_ctx.packet_header =
+               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(stream_class->packet_context_ft);
+       stream_class->packet_context_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set stream class's packet context field type: %!+S",
+               stream_class);
+
+end:
+       return ret;
+}
+
+struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->event_header_ft;
+}
+
+int bt_stream_class_set_event_header_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = NULL,
+               .packet_context = NULL,
+               .event_header = field_type,
+               .event_common_context = NULL,
+               .event_specific_context = NULL,
+               .event_payload = NULL,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Event header field type is not a structure field type: %!+F",
+               field_type);
+       resolve_ctx.packet_header =
+               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+       resolve_ctx.packet_context = stream_class->packet_context_ft;
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(stream_class->event_header_ft);
+       stream_class->event_header_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set stream class's event header field type: %!+S",
+               stream_class);
+
+end:
+       return ret;
+}
+
+struct bt_field_type *bt_stream_class_borrow_event_common_context_field_type(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->event_common_context_ft;
+}
+
+int bt_stream_class_set_event_common_context_field_type(
+               struct bt_stream_class *stream_class,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = NULL,
+               .packet_context = NULL,
+               .event_header = NULL,
+               .event_common_context = field_type,
+               .event_specific_context = NULL,
+               .event_payload = NULL,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Event common context field type is not a structure field type: %!+F",
+               field_type);
+       resolve_ctx.packet_header =
+               bt_stream_class_borrow_trace_inline(stream_class)->packet_header_ft;
+       resolve_ctx.packet_context = stream_class->packet_context_ft;
+       resolve_ctx.event_header = stream_class->event_header_ft;
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(stream_class->event_common_context_ft);
+       stream_class->event_common_context_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set stream class's event common context field type: %!+S",
+               stream_class);
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void _bt_stream_class_freeze(struct bt_stream_class *stream_class)
+{
+       /* The field types and default clock class are already frozen */
+       BT_ASSERT(stream_class);
+       BT_LIB_LOGD("Freezing stream class: %!+S", stream_class);
+       stream_class->frozen = true;
+}
+
+int bt_stream_class_set_default_clock_class(
+               struct bt_stream_class *stream_class,
+               struct bt_clock_class *clock_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_NON_NULL(clock_class, "Clock class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       bt_put(stream_class->default_clock_class);
+       stream_class->default_clock_class = bt_get(clock_class);
+       bt_clock_class_freeze(clock_class);
+       BT_LIB_LOGV("Set stream class's default clock class: %!+S",
+               stream_class);
+       return 0;
+}
+
+struct bt_clock_class *bt_stream_class_borrow_default_clock_class(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return stream_class->default_clock_class;
+}
+
+bt_bool bt_stream_class_assigns_automatic_event_class_id(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->assigns_automatic_event_class_id;
+}
+
+int bt_stream_class_set_assigns_automatic_event_class_id(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       stream_class->assigns_automatic_event_class_id = (bool) value;
+       BT_LIB_LOGV("Set stream class's automatic event class ID "
+               "assignment property: %!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_assigns_automatic_stream_id(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->assigns_automatic_stream_id;
+}
+
+int bt_stream_class_set_assigns_automatic_stream_id(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       stream_class->assigns_automatic_stream_id = (bool) value;
+       BT_LIB_LOGV("Set stream class's automatic stream ID "
+               "assignment property: %!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_packets_have_discarded_event_counter_snapshot(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->packets_have_discarded_event_counter_snapshot;
+}
+
+int bt_stream_class_set_packets_have_discarded_event_counter_snapshot(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       stream_class->packets_have_discarded_event_counter_snapshot =
+               (bool) value;
+       BT_LIB_LOGV("Set stream class's "
+               "\"packets have discarded event counter snapshot\" property: "
+               "%!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_packets_have_packet_counter_snapshot(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->packets_have_packet_counter_snapshot;
+}
+
+int bt_stream_class_set_packets_have_packet_counter_snapshot(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       stream_class->packets_have_packet_counter_snapshot =
+               (bool) value;
+       BT_LIB_LOGV("Set stream class's "
+               "\"packets have packet counter snapshot\" property: "
+               "%!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_packets_have_default_beginning_clock_value(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->packets_have_default_beginning_cv;
+}
+
+int bt_stream_class_set_packets_have_default_beginning_clock_value(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       BT_ASSERT_PRE(!value || stream_class->default_clock_class,
+               "Stream class does not have a default clock class: %!+S",
+               stream_class);
+       stream_class->packets_have_default_beginning_cv = (bool) value;
+       BT_LIB_LOGV("Set stream class's "
+               "\"packets have default beginning clock value\" property: "
+               "%!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_packets_have_default_end_clock_value(
+               struct bt_stream_class *stream_class)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       return (bt_bool) stream_class->packets_have_default_end_cv;
+}
+
+int bt_stream_class_set_packets_have_default_end_clock_value(
+               struct bt_stream_class *stream_class, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class);
+       BT_ASSERT_PRE(!value || stream_class->default_clock_class,
+               "Stream class does not have a default clock class: %!+S",
+               stream_class);
+       stream_class->packets_have_default_end_cv = (bool) value;
+       BT_LIB_LOGV("Set stream class's "
+               "\"packets have default end clock value\" property: "
+               "%!+S", stream_class);
+       return 0;
+}
+
+bt_bool bt_stream_class_default_clock_is_always_known(
+               struct bt_stream_class *stream_class)
+{
+       /* BT_CLOCK_VALUE_STATUS_UNKNOWN is not supported as of 2.0 */
+       return BT_TRUE;
+}
diff --git a/lib/trace-ir/stream.c b/lib/trace-ir/stream.c
new file mode 100644 (file)
index 0000000..7d37f4e
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * stream.c
+ *
+ * Babeltrace trace IR - Stream
+ *
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "STREAM"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/packet-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/align-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/property-internal.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#define BT_ASSERT_PRE_STREAM_HOT(_stream) \
+       BT_ASSERT_PRE_HOT((_stream), "Stream", ": %!+s", (_stream))
+
+static
+void destroy_stream(struct bt_object *obj)
+{
+       struct bt_stream *stream = (void *) obj;
+
+       BT_LIB_LOGD("Destroying stream object: %!+s", stream);
+
+       if (stream->name.str) {
+               g_string_free(stream->name.str, TRUE);
+       }
+
+       bt_object_pool_finalize(&stream->packet_pool);
+       g_free(stream);
+}
+
+static
+void bt_stream_free_packet(struct bt_packet *packet, struct bt_stream *stream)
+{
+       bt_packet_destroy(packet);
+}
+
+BT_ASSERT_PRE_FUNC
+static inline
+bool stream_id_is_unique(struct bt_trace *trace,
+               struct bt_stream_class *stream_class, uint64_t id)
+{
+       uint64_t i;
+       bool is_unique = true;
+
+       for (i = 0; i < trace->streams->len; i++) {
+               struct bt_stream *stream = trace->streams->pdata[i];
+
+               if (stream->class != stream_class) {
+                       continue;
+               }
+
+               if (stream->id == id) {
+                       is_unique = false;
+                       goto end;
+               }
+       }
+
+end:
+       return is_unique;
+}
+
+static
+struct bt_stream *create_stream_with_id(struct bt_stream_class *stream_class,
+                 uint64_t id)
+{
+       int ret;
+       struct bt_stream *stream;
+       struct bt_trace *trace;
+
+       BT_ASSERT(stream_class);
+       trace = bt_stream_class_borrow_trace_inline(stream_class);
+       BT_ASSERT_PRE(stream_id_is_unique(trace, stream_class, id),
+               "Duplicate stream ID: %![trace-]+t, id=%" PRIu64, trace, id);
+       BT_ASSERT_PRE(!trace->is_static,
+               "Trace is static: %![trace-]+t", trace);
+       BT_LIB_LOGD("Creating stream object: %![trace-]+t, id=%" PRIu64,
+               trace, id);
+       stream = g_new0(struct bt_stream, 1);
+       if (!stream) {
+               BT_LOGE_STR("Failed to allocate one stream.");
+               goto error;
+       }
+
+       bt_object_init_shared_with_parent(&stream->base, destroy_stream);
+       stream->name.str = g_string_new(NULL);
+       if (!stream->name.str) {
+               BT_LOGE_STR("Failed to allocate a GString.");
+               goto error;
+       }
+
+       stream->id = id;
+       ret = bt_object_pool_initialize(&stream->packet_pool,
+               (bt_object_pool_new_object_func) bt_packet_new,
+               (bt_object_pool_destroy_object_func) bt_stream_free_packet,
+               stream);
+       if (ret) {
+               BT_LOGE("Failed to initialize packet pool: ret=%d", ret);
+               goto error;
+       }
+
+       stream->class = stream_class;
+       bt_trace_add_stream(trace, stream);
+       bt_stream_class_freeze(stream_class);
+       BT_LIB_LOGD("Created stream object: %!+s", stream);
+       goto end;
+
+error:
+       BT_PUT(stream);
+
+end:
+       return stream;
+}
+
+struct bt_stream *bt_stream_create(struct bt_stream_class *stream_class)
+{
+       uint64_t id;
+
+       BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
+       BT_ASSERT_PRE(stream_class->assigns_automatic_stream_id,
+               "Stream class does not automatically assigns stream IDs: "
+               "%![sc-]+S", stream_class);
+       id = bt_trace_get_automatic_stream_id(
+                       bt_stream_class_borrow_trace_inline(stream_class),
+                       stream_class);
+       return create_stream_with_id(stream_class, id);
+}
+
+struct bt_stream *bt_stream_create_with_id(struct bt_stream_class *stream_class,
+               uint64_t id)
+{
+       BT_ASSERT_PRE(!stream_class->assigns_automatic_stream_id,
+               "Stream class automatically assigns stream IDs: "
+               "%![sc-]+S", stream_class);
+       return create_stream_with_id(stream_class, id);
+}
+
+struct bt_stream_class *bt_stream_borrow_class(struct bt_stream *stream)
+{
+       BT_ASSERT_PRE_NON_NULL(stream, "Stream");
+       return stream->class;
+}
+
+const char *bt_stream_get_name(struct bt_stream *stream)
+{
+       BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
+       return stream->name.value;
+}
+
+int bt_stream_set_name(struct bt_stream *stream, const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(stream, "Clock class");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_STREAM_HOT(stream);
+       g_string_assign(stream->name.str, name);
+       stream->name.value = stream->name.str->str;
+       BT_LIB_LOGV("Set stream class's name: %!+S", stream);
+       return 0;
+}
+
+uint64_t bt_stream_get_id(struct bt_stream *stream)
+{
+       BT_ASSERT_PRE_NON_NULL(stream, "Stream class");
+       return stream->id;
+}
+
+BT_HIDDEN
+void _bt_stream_freeze(struct bt_stream *stream)
+{
+       /* The field types and default clock class are already frozen */
+       BT_ASSERT(stream);
+       BT_LIB_LOGD("Freezing stream: %!+s", stream);
+       stream->frozen = true;
+}
diff --git a/lib/trace-ir/trace.c b/lib/trace-ir/trace.c
new file mode 100644 (file)
index 0000000..e5ae513
--- /dev/null
@@ -0,0 +1,660 @@
+/*
+ * trace.c
+ *
+ * Babeltrace trace IR - Trace
+ *
+ * Copyright 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "TRACE"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <babeltrace/assert-pre-internal.h>
+#include <babeltrace/trace-ir/trace-internal.h>
+#include <babeltrace/trace-ir/clock-class-internal.h>
+#include <babeltrace/trace-ir/stream-internal.h>
+#include <babeltrace/trace-ir/stream-class-internal.h>
+#include <babeltrace/trace-ir/event-internal.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event-class-internal.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/trace-ir/field-wrapper-internal.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/attributes-internal.h>
+#include <babeltrace/trace-ir/utils-internal.h>
+#include <babeltrace/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/values-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/types.h>
+#include <babeltrace/endian-internal.h>
+#include <babeltrace/assert-internal.h>
+#include <babeltrace/compat/glib-internal.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct bt_trace_is_static_listener_elem {
+       bt_trace_is_static_listener func;
+       bt_trace_listener_removed removed;
+       void *data;
+};
+
+#define BT_ASSERT_PRE_TRACE_HOT(_trace) \
+       BT_ASSERT_PRE_HOT((_trace), "Trace", ": %!+t", (_trace))
+
+static
+void destroy_trace(struct bt_object *obj)
+{
+       struct bt_trace *trace = (void *) obj;
+
+       BT_LIB_LOGD("Destroying trace object: %!+t", trace);
+
+       /*
+        * Call remove listeners first so that everything else still
+        * exists in the trace.
+        */
+       if (trace->is_static_listeners) {
+               size_t i;
+
+               for (i = 0; i < trace->is_static_listeners->len; i++) {
+                       struct bt_trace_is_static_listener_elem elem =
+                               g_array_index(trace->is_static_listeners,
+                                       struct bt_trace_is_static_listener_elem, i);
+
+                       if (elem.removed) {
+                               elem.removed(trace, elem.data);
+                       }
+               }
+
+               g_array_free(trace->is_static_listeners, TRUE);
+       }
+
+       bt_object_pool_finalize(&trace->packet_header_field_pool);
+
+       if (trace->environment) {
+               BT_LOGD_STR("Destroying environment attributes.");
+               bt_attributes_destroy(trace->environment);
+       }
+
+       if (trace->name.str) {
+               g_string_free(trace->name.str, TRUE);
+       }
+
+       if (trace->streams) {
+               BT_LOGD_STR("Destroying streams.");
+               g_ptr_array_free(trace->streams, TRUE);
+       }
+
+       if (trace->stream_classes) {
+               BT_LOGD_STR("Destroying stream classes.");
+               g_ptr_array_free(trace->stream_classes, TRUE);
+       }
+
+       if (trace->stream_classes_stream_count) {
+               g_hash_table_destroy(trace->stream_classes_stream_count);
+       }
+
+       BT_LOGD_STR("Putting packet header field type.");
+       bt_put(trace->packet_header_ft);
+       g_free(trace);
+}
+
+static
+void free_packet_header_field(struct bt_field_wrapper *field_wrapper,
+               struct bt_trace *trace)
+{
+       bt_field_wrapper_destroy(field_wrapper);
+}
+
+struct bt_trace *bt_trace_create(void)
+{
+       struct bt_trace *trace = NULL;
+       int ret;
+
+       BT_LOGD_STR("Creating default trace object.");
+       trace = g_new0(struct bt_trace, 1);
+       if (!trace) {
+               BT_LOGE_STR("Failed to allocate one trace.");
+               goto error;
+       }
+
+       bt_object_init_shared_with_parent(&trace->base, destroy_trace);
+       trace->streams = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_try_spec_release);
+       if (!trace->streams) {
+               BT_LOGE_STR("Failed to allocate one GPtrArray.");
+               goto error;
+       }
+
+       trace->stream_classes = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_try_spec_release);
+       if (!trace->stream_classes) {
+               BT_LOGE_STR("Failed to allocate one GPtrArray.");
+               goto error;
+       }
+
+       trace->stream_classes_stream_count = g_hash_table_new(g_direct_hash,
+               g_direct_equal);
+       if (!trace->stream_classes_stream_count) {
+               BT_LOGE_STR("Failed to allocate one GHashTable.");
+               goto error;
+       }
+
+       trace->name.str = g_string_new(NULL);
+       if (!trace->name.str) {
+               BT_LOGE_STR("Failed to allocate one GString.");
+               goto error;
+       }
+
+       trace->environment = bt_attributes_create();
+       if (!trace->environment) {
+               BT_LOGE_STR("Cannot create empty attributes object.");
+               goto error;
+       }
+
+       trace->is_static_listeners = g_array_new(FALSE, TRUE,
+               sizeof(struct bt_trace_is_static_listener_elem));
+       if (!trace->is_static_listeners) {
+               BT_LOGE_STR("Failed to allocate one GArray.");
+               goto error;
+       }
+
+       trace->assigns_automatic_stream_class_id = true;
+       ret = bt_object_pool_initialize(&trace->packet_header_field_pool,
+               (bt_object_pool_new_object_func) bt_field_wrapper_new,
+               (bt_object_pool_destroy_object_func) free_packet_header_field,
+               trace);
+       if (ret) {
+               BT_LOGE("Failed to initialize packet header field pool: ret=%d",
+                       ret);
+               goto error;
+       }
+
+       BT_LIB_LOGD("Created trace object: %!+t", trace);
+       goto end;
+
+error:
+       BT_PUT(trace);
+
+end:
+       return trace;
+}
+
+const char *bt_trace_get_name(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return trace->name.value;
+}
+
+int bt_trace_set_name(struct bt_trace *trace, const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_TRACE_HOT(trace);
+       g_string_assign(trace->name.str, name);
+       trace->name.value = trace->name.str->str;
+       BT_LIB_LOGV("Set trace's name: %!+t", trace);
+       return 0;
+}
+
+bt_uuid bt_trace_get_uuid(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return trace->uuid.value;
+}
+
+int bt_trace_set_uuid(struct bt_trace *trace, bt_uuid uuid)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(uuid, "UUID");
+       BT_ASSERT_PRE_TRACE_HOT(trace);
+       memcpy(trace->uuid.uuid, uuid, BABELTRACE_UUID_LEN);
+       trace->uuid.value = trace->uuid.uuid;
+       BT_LIB_LOGV("Set trace's UUID: %!+t", trace);
+       return 0;
+}
+
+BT_ASSERT_FUNC
+static
+bool trace_has_environment_entry(struct bt_trace *trace, const char *name)
+{
+       struct bt_value *attribute;
+
+       BT_ASSERT(trace);
+
+       attribute = bt_attributes_borrow_field_value_by_name(
+               trace->environment, name);
+       return attribute != NULL;
+}
+
+static
+int set_environment_entry(struct bt_trace *trace, const char *name,
+               struct bt_value *value)
+{
+       int ret;
+
+       BT_ASSERT(trace);
+       BT_ASSERT(name);
+       BT_ASSERT(value);
+       BT_ASSERT_PRE(!trace->frozen ||
+               !trace_has_environment_entry(trace, name),
+               "Trace is frozen: cannot replace environment entry: "
+               "%![trace-]+t, entry-name=\"%s\"", trace, name);
+       ret = bt_attributes_set_field_value(trace->environment, name,
+               value);
+       bt_value_freeze(value);
+       if (ret) {
+               BT_LIB_LOGE("Cannot set trace's environment entry: "
+                       "%![trace-]+t, entry-name=\"%s\"", trace, name);
+       } else {
+               BT_LIB_LOGV("Set trace's environment entry: "
+                       "%![trace-]+t, entry-name=\"%s\"", trace, name);
+       }
+
+       return ret;
+}
+
+int bt_trace_set_environment_entry_string(struct bt_trace *trace,
+               const char *name, const char *value)
+{
+       int ret;
+       struct bt_value *value_obj;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_NON_NULL(value, "Value");
+       value_obj = bt_value_string_create_init(value);
+       if (!value_obj) {
+               BT_LOGE_STR("Cannot create a string value object.");
+               ret = -1;
+               goto end;
+       }
+
+       /* set_environment_entry() logs errors */
+       ret = set_environment_entry(trace, name, value_obj);
+
+end:
+       bt_put(value_obj);
+       return ret;
+}
+
+int bt_trace_set_environment_entry_integer(
+               struct bt_trace *trace, const char *name, int64_t value)
+{
+       int ret;
+       struct bt_value *value_obj;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       value_obj = bt_value_integer_create_init(value);
+       if (!value_obj) {
+               BT_LOGE_STR("Cannot create an integer value object.");
+               ret = -1;
+               goto end;
+       }
+
+       /* set_environment_entry() logs errors */
+       ret = set_environment_entry(trace, name, value_obj);
+
+end:
+       bt_put(value_obj);
+       return ret;
+}
+
+uint64_t bt_trace_get_environment_entry_count(struct bt_trace *trace)
+{
+       int64_t ret;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       ret = bt_attributes_get_count(trace->environment);
+       BT_ASSERT(ret >= 0);
+       return (uint64_t) ret;
+}
+
+void bt_trace_borrow_environment_entry_by_index(
+               struct bt_trace *trace, uint64_t index,
+               const char **name, struct bt_value **value)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       BT_ASSERT_PRE_NON_NULL(value, "Value");
+       BT_ASSERT_PRE_VALID_INDEX(index,
+               bt_attributes_get_count(trace->environment));
+       *value = bt_attributes_borrow_field_value(trace->environment, index);
+       BT_ASSERT(*value);
+       *name = bt_attributes_get_field_name(trace->environment, index);
+       BT_ASSERT(*name);
+}
+
+struct bt_value *bt_trace_borrow_environment_entry_value_by_name(
+               struct bt_trace *trace, const char *name)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(name, "Name");
+       return bt_attributes_borrow_field_value_by_name(trace->environment,
+               name);
+}
+
+uint64_t bt_trace_get_stream_count(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return (uint64_t) trace->streams->len;
+}
+
+struct bt_stream *bt_trace_borrow_stream_by_index(
+               struct bt_trace *trace, uint64_t index)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_VALID_INDEX(index, trace->streams->len);
+       return g_ptr_array_index(trace->streams, index);
+}
+
+struct bt_stream *bt_trace_borrow_stream_by_id(
+               struct bt_trace *trace, uint64_t id)
+{
+       struct bt_stream *stream = NULL;
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+       for (i = 0; i < trace->streams->len; i++) {
+               struct bt_stream *stream_candidate =
+                       g_ptr_array_index(trace->streams, i);
+
+               if (stream_candidate->id == id) {
+                       stream = stream_candidate;
+                       goto end;
+               }
+       }
+
+end:
+       return stream;
+}
+
+uint64_t bt_trace_get_stream_class_count(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return (uint64_t) trace->stream_classes->len;
+}
+
+struct bt_stream_class *bt_trace_borrow_stream_class_by_index(
+               struct bt_trace *trace, uint64_t index)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_VALID_INDEX(index, trace->stream_classes->len);
+       return g_ptr_array_index(trace->stream_classes, index);
+}
+
+struct bt_stream_class *bt_trace_borrow_stream_class_by_id(
+               struct bt_trace *trace, uint64_t id)
+{
+       struct bt_stream_class *stream_class = NULL;
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+
+       for (i = 0; i < trace->stream_classes->len; i++) {
+               struct bt_stream_class *stream_class_candidate =
+                       g_ptr_array_index(trace->stream_classes, i);
+
+               if (stream_class_candidate->id == id) {
+                       stream_class = stream_class_candidate;
+                       goto end;
+               }
+       }
+
+end:
+       return stream_class;
+}
+
+struct bt_field_type *bt_trace_borrow_packet_header_field_type(
+               struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return trace->packet_header_ft;
+}
+
+int bt_trace_set_packet_header_field_type(struct bt_trace *trace,
+               struct bt_field_type *field_type)
+{
+       int ret;
+       struct bt_resolve_field_path_context resolve_ctx = {
+               .packet_header = field_type,
+               .packet_context = NULL,
+               .event_header = NULL,
+               .event_common_context = NULL,
+               .event_specific_context = NULL,
+               .event_payload = NULL,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(field_type, "Field type");
+       BT_ASSERT_PRE_TRACE_HOT(trace);
+       BT_ASSERT_PRE(bt_field_type_get_type_id(field_type) ==
+               BT_FIELD_TYPE_ID_STRUCTURE,
+               "Packet header field type is not a structure field type: %!+F",
+               field_type);
+       ret = bt_resolve_field_paths(field_type, &resolve_ctx);
+       if (ret) {
+               goto end;
+       }
+
+       bt_field_type_make_part_of_trace(field_type);
+       bt_put(trace->packet_header_ft);
+       trace->packet_header_ft = bt_get(field_type);
+       bt_field_type_freeze(field_type);
+       BT_LIB_LOGV("Set trace's packet header field type: %!+t", trace);
+
+end:
+       return ret;
+}
+
+bt_bool bt_trace_is_static(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return (bt_bool) trace->is_static;
+}
+
+int bt_trace_make_static(struct bt_trace *trace)
+{
+       uint64_t i;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       trace->is_static = true;
+       bt_trace_freeze(trace);
+       BT_LIB_LOGV("Trace is now static: %!+t", trace);
+
+       /* Call all the "trace is static" listeners */
+       for (i = 0; i < trace->is_static_listeners->len; i++) {
+               struct bt_trace_is_static_listener_elem elem =
+                       g_array_index(trace->is_static_listeners,
+                               struct bt_trace_is_static_listener_elem, i);
+
+               if (elem.func) {
+                       elem.func(trace, elem.data);
+               }
+       }
+
+       return 0;
+}
+
+int bt_trace_add_is_static_listener(struct bt_trace *trace,
+               bt_trace_is_static_listener listener,
+               bt_trace_listener_removed listener_removed, void *data,
+               uint64_t *listener_id)
+{
+       uint64_t i;
+       struct bt_trace_is_static_listener_elem new_elem = {
+               .func = listener,
+               .removed = listener_removed,
+               .data = data,
+       };
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_NON_NULL(listener, "Listener");
+       BT_ASSERT_PRE(!trace->is_static,
+               "Trace is already static: %!+t", trace);
+       BT_ASSERT_PRE(trace->in_remove_listener,
+               "Cannot call this function while executing a "
+               "remove listener: %!+t", trace);
+
+       /* Find the next available spot */
+       for (i = 0; i < trace->is_static_listeners->len; i++) {
+               struct bt_trace_is_static_listener_elem elem =
+                       g_array_index(trace->is_static_listeners,
+                               struct bt_trace_is_static_listener_elem, i);
+
+               if (!elem.func) {
+                       break;
+               }
+       }
+
+       if (i == trace->is_static_listeners->len) {
+               g_array_append_val(trace->is_static_listeners, new_elem);
+       } else {
+               g_array_insert_val(trace->is_static_listeners, i, new_elem);
+       }
+
+       if (listener_id) {
+               *listener_id = i;
+       }
+
+       BT_LIB_LOGV("Added \"trace is static\" listener: "
+               "%![trace-]+t, listener-id=%" PRIu64, trace, i);
+       return 0;
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool has_listener_id(struct bt_trace *trace, uint64_t listener_id)
+{
+       BT_ASSERT(listener_id < trace->is_static_listeners->len);
+       return (&g_array_index(trace->is_static_listeners,
+                       struct bt_trace_is_static_listener_elem,
+                       listener_id))->func != NULL;
+}
+
+int bt_trace_remove_is_static_listener(
+               struct bt_trace *trace, uint64_t listener_id)
+{
+       struct bt_trace_is_static_listener_elem *elem;
+
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE(!trace->is_static,
+               "Trace is already static: %!+t", trace);
+       BT_ASSERT_PRE(trace->in_remove_listener,
+               "Cannot call this function while executing a "
+               "remove listener: %!+t", trace);
+       BT_ASSERT_PRE(has_listener_id(trace, listener_id),
+               "Trace has no such \"trace is static\" listener ID: "
+               "%![trace-]+t, %" PRIu64, trace, listener_id);
+       elem = &g_array_index(trace->is_static_listeners,
+                       struct bt_trace_is_static_listener_elem,
+                       listener_id);
+       BT_ASSERT(elem->func);
+
+       if (elem->removed) {
+               /* Call remove listener */
+               BT_LIB_LOGV("Calling remove listener: "
+                       "%![trace-]+t, listener-id=%" PRIu64,
+                       trace, listener_id);
+               trace->in_remove_listener = true;
+               elem->removed(trace, elem->data);
+               trace->in_remove_listener = false;
+       }
+
+       elem->func = NULL;
+       elem->removed = NULL;
+       elem->data = NULL;
+       BT_LIB_LOGV("Removed \"trace is static\" listener: "
+               "%![trace-]+t, listener-id=%" PRIu64,
+               trace, listener_id);
+       return 0;
+}
+
+BT_HIDDEN
+void _bt_trace_freeze(struct bt_trace *trace)
+{
+       /* The packet header field type is already frozen */
+       BT_ASSERT(trace);
+       BT_LIB_LOGD("Freezing trace: %!+t", trace);
+       trace->frozen = true;
+}
+
+bt_bool bt_trace_assigns_automatic_stream_class_id(struct bt_trace *trace)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       return (bt_bool) trace->assigns_automatic_stream_class_id;
+}
+
+int bt_trace_set_assigns_automatic_stream_class_id(
+               struct bt_trace *trace, bt_bool value)
+{
+       BT_ASSERT_PRE_NON_NULL(trace, "Trace");
+       BT_ASSERT_PRE_TRACE_HOT(trace);
+       trace->assigns_automatic_stream_class_id = (bool) value;
+       BT_LIB_LOGV("Set trace's automatic stream class ID "
+               "assignment property: %!+t", trace);
+       return 0;
+}
+
+BT_HIDDEN
+void bt_trace_add_stream(struct bt_trace *trace, struct bt_stream *stream)
+{
+       guint count = 0;
+
+       bt_object_set_parent(&stream->base, &trace->base);
+       g_ptr_array_add(trace->streams, stream);
+       bt_trace_freeze(trace);
+
+       if (bt_g_hash_table_contains(trace->stream_classes_stream_count,
+                       stream->class)) {
+               count = GPOINTER_TO_UINT(g_hash_table_lookup(
+                       trace->stream_classes_stream_count, stream->class));
+       }
+
+       g_hash_table_insert(trace->stream_classes_stream_count,
+               stream->class, GUINT_TO_POINTER(count + 1));
+}
+
+BT_HIDDEN
+uint64_t bt_trace_get_automatic_stream_id(struct bt_trace *trace,
+               struct bt_stream_class *stream_class)
+{
+       gpointer orig_key;
+       gpointer value;
+       uint64_t id = 0;
+
+       BT_ASSERT(stream_class);
+       BT_ASSERT(trace);
+       if (g_hash_table_lookup_extended(trace->stream_classes_stream_count,
+                       stream_class, &orig_key, &value)) {
+               id = (uint64_t) GPOINTER_TO_UINT(value);
+       }
+
+       return id;
+}
diff --git a/lib/trace-ir/utils.c b/lib/trace-ir/utils.c
new file mode 100644 (file)
index 0000000..76906a6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * utils.c
+ *
+ * Babeltrace trace IR - Utilities
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_TAG "TRACE-IR-UTILS"
+#include <babeltrace/lib-logging-internal.h>
+
+#include <stdlib.h>
+#include <glib.h>
+#include <babeltrace/trace-ir/field-types-internal.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/assert-internal.h>
index c72be5e03dd3000b065ef1521384be843d7a5cfc..26e796a73bedeaf1dc263879233e3954da9c92c3 100644 (file)
@@ -106,7 +106,7 @@ struct ctf_fs_ds_file_group {
         * belong to this group (a single stream instance).
         *
         * You can call ctf_fs_ds_file_create() with one of those paths
-        * and the CTF IR stream below.
+        * and the trace IR stream below.
         */
        GPtrArray *ds_file_infos;
 
index 05e9439e8eb9b6b3fec2f9dc07e0f4bc50cadbcb..c5ac2d77e4209a34879c787c574cbe9094ac84f0 100644 (file)
@@ -26,7 +26,7 @@ TESTS_CLI = \
 TESTS_LIB = \
        lib/test_ctf_writer_complete \
        lib/test_bt_values \
-       lib/test_ctf_ir_ref \
+       lib/test_trace_ir_ref \
        lib/test_bt_ctf_field_type_validation \
        lib/test_ir_visit \
        lib/test_graph_topo \
@@ -38,7 +38,7 @@ TESTS_LIB += lib/test_plugin_complete
 endif
 
 if ENABLE_PYTHON_BINDINGS
-TESTS_LIB += lib/ctf-ir/test_ctf_ir
+TESTS_LIB += lib/trace-ir/test_trace_ir
 TESTS_LIB += lib/ctf-writer/test_ctf_writer
 endif
 
index b2b34642e07fea6c54d8beced4bf5faa73f9a581..39ad76e0fd9b0decb5d91119a7a73a962feada7f 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = ctf-ir ctf-writer
+SUBDIRS = trace-ir ctf-writer
 
 AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
 
@@ -19,19 +19,19 @@ test_ctf_writer_LDADD = $(COMMON_TEST_LDADD)
 
 test_bt_values_LDADD = $(COMMON_TEST_LDADD)
 
-test_ctf_ir_ref_LDADD = $(COMMON_TEST_LDADD)
+test_trace_ir_ref_LDADD = $(COMMON_TEST_LDADD)
 
 test_graph_topo_LDADD = $(COMMON_TEST_LDADD)
 
 test_bt_notification_iterator_LDADD = $(COMMON_TEST_LDADD)
 
 noinst_PROGRAMS = test_bitfield test_ctf_writer test_bt_values \
-       test_ctf_ir_ref test_graph_topo test_bt_notification_iterator
+       test_trace_ir_ref test_graph_topo test_bt_notification_iterator
 
 test_bitfield_SOURCES = test_bitfield.c
 test_ctf_writer_SOURCES = test_ctf_writer.c
 test_bt_values_SOURCES = test_bt_values.c
-test_ctf_ir_ref_SOURCES = test_ctf_ir_ref.c
+test_trace_ir_ref_SOURCES = test_trace_ir_ref.c
 test_graph_topo_SOURCES = test_graph_topo.c
 test_bt_notification_iterator_SOURCES = test_bt_notification_iterator.c
 
diff --git a/tests/lib/ctf-ir/Makefile.am b/tests/lib/ctf-ir/Makefile.am
deleted file mode 100644 (file)
index 0c4adbe..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-if ENABLE_PYTHON_BINDINGS
-check_SCRIPTS = test_ctf_ir
-endif
-
-EXTRA_DIST = test_trace.py test_stream_class.py
diff --git a/tests/lib/ctf-ir/test_ctf_ir.in b/tests/lib/ctf-ir/test_ctf_ir.in
deleted file mode 100644 (file)
index c3ff375..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2017 - Philippe Proulx <pproulx@efficios.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; only version 2
-# of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-
-NO_SH_TAP=1
-. "@abs_top_builddir@/tests/utils/common.sh"
-
-PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib"
-TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python"
-TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py"
-THIS_DIR="${BT_SRC_PATH}/tests/lib/ctf-ir"
-
-if [ "x${MSYSTEM}" != "x" ]; then
-       export PATH="${BT_BUILD_PATH}/lib/.libs:${PATH}"
-else
-       export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs:${LD_LIBRARY_PATH}"
-fi
-
-PYTHONPATH="${PYTHON_BUILD_DIR}:${TESTS_UTILS_PYTHON_DIR}" \
-       "@PYTHON@" "${TESTRUNNER_PY}" "${THIS_DIR}"
-exit $?
diff --git a/tests/lib/ctf-ir/test_stream_class.py b/tests/lib/ctf-ir/test_stream_class.py
deleted file mode 100644 (file)
index 0841848..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-import unittest
-import bt2
-
-
-class StreamClassSingleClockClassTestCase(unittest.TestCase):
-    def setUp(self):
-        self._sc = bt2.StreamClass()
-
-    def tearDown(self):
-        del self._sc
-
-    def _test_add_sc_ft_vs_event_class(self, set_ft_func):
-        cc = bt2.ClockClass('first_cc', 1000)
-        scft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        scft.append_field('salut', ft)
-        set_ft_func(scft)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec)
-        trace = bt2.Trace()
-
-        with self.assertRaises(bt2.Error):
-            trace.add_stream_class(self._sc)
-
-    def test_add_sc_packet_context_vs_event_class(self):
-        def func(ft):
-            self._sc.packet_context_field_type = ft
-
-        self._test_add_sc_ft_vs_event_class(func)
-
-    def test_add_sc_event_context_vs_event_class(self):
-        def func(ft):
-            self._sc.event_context_field_type = ft
-
-        self._test_add_sc_ft_vs_event_class(func)
-
-    def test_add_sc_event_header_vs_event_class(self):
-        def func(ft):
-            self._sc.event_header_field_type = ft
-
-        self._test_add_sc_ft_vs_event_class(func)
-
-    def test_add_sc_event_class_vs_event_class(self):
-        ehft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32)
-        ehft.append_field('id', ft)
-        self._sc.event_header_field_type = ehft
-        cc = bt2.ClockClass('first_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('logi', ft)
-        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec1)
-        self._sc.add_event_class(ec2)
-        trace = bt2.Trace()
-
-        with self.assertRaises(bt2.Error):
-            trace.add_stream_class(self._sc)
-
-    def _test_create_event_ft_vs_event_class(self, set_ft_func):
-        cc = bt2.ClockClass('first_cc', 1000)
-        scft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        scft.append_field('salut', ft)
-        set_ft_func(scft)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec)
-
-        with self.assertRaises(bt2.Error):
-            ev = ec()
-
-    def test_create_event_packet_context_vs_event_class(self):
-        def func(ft):
-            self._sc.packet_context_field_type = ft
-
-        self._test_create_event_ft_vs_event_class(func)
-
-    def test_create_event_event_context_vs_event_class(self):
-        def func(ft):
-            self._sc.event_context_field_type = ft
-
-        self._test_create_event_ft_vs_event_class(func)
-
-    def test_create_event_event_header_vs_event_class(self):
-        def func(ft):
-            self._sc.event_header_field_type = ft
-
-        self._test_create_event_ft_vs_event_class(func)
-
-    def test_create_event_event_class_vs_event_class(self):
-        ehft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32)
-        ehft.append_field('id', ft)
-        self._sc.event_header_field_type = ehft
-        cc = bt2.ClockClass('first_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('logi', ft)
-        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec1)
-        self._sc.add_event_class(ec2)
-
-        with self.assertRaises(bt2.Error):
-            ev = ec1()
-
-    def test_add_ec_after_add_sc(self):
-        cc = bt2.ClockClass('first_cc', 1000)
-        scft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        scft.append_field('salut', ft)
-        self._sc.packet_context_field_type = scft
-        trace = bt2.Trace()
-        trace.add_stream_class(self._sc)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
-        with self.assertRaises(bt2.Error):
-            self._sc.add_event_class(ec)
-
-    def test_add_ec_after_add_sc_single_cc(self):
-        ehft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32)
-        ehft.append_field('id', ft)
-        self._sc.event_header_field_type = ehft
-        trace = bt2.Trace()
-        trace.add_stream_class(self._sc)
-        cc = bt2.ClockClass('first_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec)
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('lel', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
-        with self.assertRaises(bt2.Error):
-            self._sc.add_event_class(ec)
-
-    def test_add_ec_after_create_event(self):
-        ehft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32)
-        ehft.append_field('id', ft)
-        self._sc.event_header_field_type = ehft
-        cc = bt2.ClockClass('first_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
-        self._sc.add_event_class(ec1)
-        ev = ec1()
-        cc = bt2.ClockClass('second_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('logi', ft)
-        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
-
-        with self.assertRaises(bt2.Error):
-            self._sc.add_event_class(ec2)
-
-    def test_sc_clock_matches_expected_clock_class(self):
-        clock = bt2.CtfWriterClock('sc_clock')
-        self._sc.clock = clock
-        writer = bt2.CtfWriter('/tmp')
-        writer.add_clock(clock)
-        writer.trace.add_stream_class(self._sc)
-        cc = bt2.ClockClass('other_cc', 1000)
-        payloadft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        payloadft.append_field('zorg', ft)
-        ec = bt2.EventClass('ec', payload_field_type=payloadft)
-
-        with self.assertRaises(bt2.Error):
-            self._sc.add_event_class(ec)
diff --git a/tests/lib/ctf-ir/test_trace.py b/tests/lib/ctf-ir/test_trace.py
deleted file mode 100644 (file)
index 116f7ba..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-import unittest
-import bt2
-
-
-class TraceTestCase(unittest.TestCase):
-    def setUp(self):
-        self._trace = bt2.Trace()
-
-    def tearDown(self):
-        del self._trace
-
-    def _add_stream_class(self):
-        sc = bt2.StreamClass()
-        self._trace.add_stream_class(sc)
-
-    def test_packet_header_ft_no_clock_class_simple(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        phft.append_field('salut', ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._add_stream_class()
-
-    def test_packet_header_ft_no_clock_class_struct(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        struct_ft = bt2.StructureFieldType()
-        struct_ft.append_field('salut', ft)
-        phft.append_field('boucane', struct_ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._add_stream_class()
-
-    def test_packet_header_ft_no_clock_class_variant(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        tag_ft = bt2.EnumerationFieldType(size=32)
-        tag_ft.add_mapping('heille', 12)
-        variant_ft = bt2.VariantFieldType('tag', tag_ft)
-        variant_ft.append_field('heille', ft)
-        phft.append_field('tag', tag_ft)
-        phft.append_field('boucane', variant_ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._add_stream_class()
-
-    def test_packet_header_ft_no_clock_class_array(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        array_ft = bt2.ArrayFieldType(ft, 23)
-        phft.append_field('boucane', array_ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._add_stream_class()
-
-    def test_packet_header_ft_no_clock_class_sequence(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        len_ft = bt2.IntegerFieldType(32)
-        seq_ft = bt2.SequenceFieldType(ft, 'len')
-        phft.append_field('len', len_ft)
-        phft.append_field('boucane', seq_ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._add_stream_class()
-
-    def test_packet_header_ft_no_clock_class_set_static(self):
-        cc = bt2.ClockClass('hello', 1000)
-        phft = bt2.StructureFieldType()
-        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
-        phft.append_field('salut', ft)
-        self._trace.add_clock_class(cc)
-        self._trace.packet_header_field_type = phft
-
-        with self.assertRaises(bt2.Error):
-            self._trace.set_is_static()
index 3cfa474597cebdb0cb8fb791330b246b6a64adb4..645b8850609cc559720a28144eb9752dd86d84af 100644 (file)
 #include <inttypes.h>
 #include <string.h>
 #include <babeltrace/assert-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/packet.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/packet.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
 #include <babeltrace/graph/component-class-filter.h>
 #include <babeltrace/graph/component-class-sink.h>
 #include <babeltrace/graph/component-class-source.h>
diff --git a/tests/lib/test_ctf_ir_ref.c b/tests/lib/test_ctf_ir_ref.c
deleted file mode 100644 (file)
index e618a26..0000000
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * test_ctf_ir_ref.c
- *
- * CTF IR Reference Count test
- *
- * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "tap/tap.h"
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-writer/fields.h>
-#include <babeltrace/ctf-writer/stream-class.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-writer/trace.h>
-#include <babeltrace/ctf-writer/writer.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/fields.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compat/stdlib-internal.h>
-#include <babeltrace/assert-internal.h>
-#include "common.h"
-
-#define NR_TESTS 37
-
-struct user {
-       struct bt_trace *tc;
-       struct bt_stream_class *sc;
-       struct bt_event_class *ec;
-       struct bt_stream *stream;
-       struct bt_event *event;
-};
-
-struct writer_user {
-       struct bt_ctf_writer *writer;
-       struct bt_ctf_trace *tc;
-       struct bt_ctf_stream_class *sc;
-       struct bt_ctf_event_class *ec;
-       struct bt_ctf_stream *stream;
-       struct bt_ctf_event *event;
-};
-
-const char *writer_user_names[] = {
-       "writer",
-       "trace",
-       "stream class",
-       "event class",
-       "stream",
-       "event",
-};
-
-static const size_t WRITER_USER_NR_ELEMENTS =
-       sizeof(struct writer_user) / sizeof(void *);
-
-/**
- * Returns a structure containing the following fields:
- *     - uint8_t payload_8;
- *     - uint16_t payload_16;
- *     - uint32_t payload_32;
- */
-static struct bt_field_type *create_integer_struct(void)
-{
-       int ret;
-       struct bt_field_type *structure = NULL;
-       struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
-       structure = bt_field_type_structure_create();
-       BT_ASSERT(structure);
-       ui8 = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ui8);
-       ret = bt_field_type_integer_set_field_value_range(ui8, 8);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(structure,
-               "payload_8", ui8);
-       BT_ASSERT(ret == 0);
-       ui16 = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ui16);
-       ret = bt_field_type_integer_set_field_value_range(ui16, 16);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(structure,
-               "payload_16", ui16);
-       BT_ASSERT(ret == 0);
-       ui32 = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ui32);
-       ret = bt_field_type_integer_set_field_value_range(ui32, 32);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(structure,
-               "payload_32", ui32);
-       BT_ASSERT(ret == 0);
-       BT_PUT(ui8);
-       BT_PUT(ui16);
-       BT_PUT(ui32);
-       return structure;
-}
-
-static struct bt_ctf_field_type *create_writer_integer_struct(void)
-{
-       int ret;
-       struct bt_ctf_field_type *structure = NULL;
-       struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
-       structure = bt_ctf_field_type_structure_create();
-       BT_ASSERT(structure);
-       ui8 = bt_ctf_field_type_integer_create(8);
-       BT_ASSERT(ui8);
-       ret = bt_ctf_field_type_structure_add_field(structure, ui8,
-                       "payload_8");
-       BT_ASSERT(ret == 0);
-       ui16 = bt_ctf_field_type_integer_create(16);
-       BT_ASSERT(ui16);
-       ret = bt_ctf_field_type_structure_add_field(structure, ui16,
-                       "payload_16");
-       BT_ASSERT(ret == 0);
-       ui32 = bt_ctf_field_type_integer_create(32);
-       BT_ASSERT(ui32);
-       ret = bt_ctf_field_type_structure_add_field(structure, ui32,
-                       "payload_32");
-       BT_ASSERT(ret == 0);
-       BT_PUT(ui8);
-       BT_PUT(ui16);
-       BT_PUT(ui32);
-       return structure;
-}
-
-/**
- * A simple event has the following payload:
- *     - uint8_t payload_8;
- *     - uint16_t payload_16;
- *     - uint32_t payload_32;
- */
-static struct bt_event_class *create_simple_event(struct bt_stream_class *sc,
-               const char *name)
-{
-       int ret;
-       struct bt_event_class *event = NULL;
-       struct bt_field_type *payload = NULL;
-
-       BT_ASSERT(name);
-       event = bt_event_class_create(sc);
-       BT_ASSERT(event);
-       ret = bt_event_class_set_name(event, name);
-       BT_ASSERT(ret == 0);
-       payload = create_integer_struct();
-       BT_ASSERT(payload);
-       ret = bt_event_class_set_payload_field_type(event, payload);
-       BT_ASSERT(ret == 0);
-       BT_PUT(payload);
-       return event;
-}
-
-/**
- * A complex event has the following payload:
- *     - uint8_t payload_8;
- *     - uint16_t payload_16;
- *     - uint32_t payload_32;
- *     - struct payload_struct:
- *           - uint8_t payload_8;
- *           - uint16_t payload_16;
- *           - uint32_t payload_32;
- */
-static struct bt_event_class *create_complex_event(struct bt_stream_class *sc,
-               const char *name)
-{
-       int ret;
-       struct bt_event_class *event = NULL;
-       struct bt_field_type *inner = NULL, *outer = NULL;
-
-       BT_ASSERT(name);
-       event = bt_event_class_create(sc);
-       BT_ASSERT(event);
-       ret = bt_event_class_set_name(event, name);
-       BT_ASSERT(ret == 0);
-       outer = create_integer_struct();
-       BT_ASSERT(outer);
-       inner = create_integer_struct();
-       BT_ASSERT(inner);
-       ret = bt_field_type_structure_append_member(outer,
-               "payload_struct", inner);
-       BT_ASSERT(ret == 0);
-       ret = bt_event_class_set_payload_field_type(event, outer);
-       BT_ASSERT(ret == 0);
-       BT_PUT(inner);
-       BT_PUT(outer);
-       return event;
-}
-
-static void set_stream_class_field_types(
-               struct bt_stream_class *stream_class)
-{
-       struct bt_field_type *packet_context_type;
-       struct bt_field_type *event_header_type;
-       struct bt_field_type *ft;
-       int ret;
-
-       packet_context_type = bt_field_type_structure_create();
-       BT_ASSERT(packet_context_type);
-       ft = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ft);
-       ret = bt_field_type_integer_set_field_value_range(ft, 32);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(packet_context_type,
-               "packet_size", ft);
-       BT_ASSERT(ret == 0);
-       bt_put(ft);
-       ft = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ft);
-       ret = bt_field_type_integer_set_field_value_range(ft, 32);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(packet_context_type,
-               "content_size", ft);
-       BT_ASSERT(ret == 0);
-       bt_put(ft);
-       event_header_type = bt_field_type_structure_create();
-       BT_ASSERT(event_header_type);
-       ft = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ft);
-       ret = bt_field_type_integer_set_field_value_range(ft, 32);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(event_header_type,
-               "id", ft);
-       BT_ASSERT(ret == 0);
-       bt_put(ft);
-       ret = bt_stream_class_set_packet_context_field_type(stream_class,
-               packet_context_type);
-       BT_ASSERT(ret == 0);
-       ret = bt_stream_class_set_event_header_field_type(stream_class,
-               event_header_type);
-       BT_ASSERT(ret == 0);
-       bt_put(packet_context_type);
-       bt_put(event_header_type);
-}
-
-static void create_sc1(struct bt_trace *trace)
-{
-       int ret;
-       struct bt_event_class *ec1 = NULL, *ec2 = NULL;
-       struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
-
-       sc1 = bt_stream_class_create(trace);
-       BT_ASSERT(sc1);
-       ret = bt_stream_class_set_name(sc1, "sc1");
-       BT_ASSERT(ret == 0);
-       set_stream_class_field_types(sc1);
-       ec1 = create_complex_event(sc1, "ec1");
-       BT_ASSERT(ec1);
-       ec2 = create_simple_event(sc1, "ec2");
-       BT_ASSERT(ec2);
-       ret_stream = bt_event_class_borrow_stream_class(ec1);
-       ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
-       ret_stream = bt_event_class_borrow_stream_class(ec2);
-       ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
-       BT_PUT(ec1);
-       BT_PUT(ec2);
-       BT_PUT(sc1);
-}
-
-static void create_sc2(struct bt_trace *trace)
-{
-       int ret;
-       struct bt_event_class *ec3 = NULL;
-       struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
-
-       sc2 = bt_stream_class_create(trace);
-       BT_ASSERT(sc2);
-       ret = bt_stream_class_set_name(sc2, "sc2");
-       BT_ASSERT(ret == 0);
-       set_stream_class_field_types(sc2);
-       ec3 = create_simple_event(sc2, "ec3");
-       ret_stream = bt_event_class_borrow_stream_class(ec3);
-       ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
-       BT_PUT(ec3);
-       BT_PUT(sc2);
-}
-
-static void set_trace_packet_header(struct bt_trace *trace)
-{
-       struct bt_field_type *packet_header_type;
-       struct bt_field_type *ft;
-       int ret;
-
-       packet_header_type = bt_field_type_structure_create();
-       BT_ASSERT(packet_header_type);
-       ft = bt_field_type_unsigned_integer_create();
-       BT_ASSERT(ft);
-       ret = bt_field_type_integer_set_field_value_range(ft, 32);
-       BT_ASSERT(ret == 0);
-       ret = bt_field_type_structure_append_member(packet_header_type,
-               "stream_id", ft);
-       BT_ASSERT(ret == 0);
-       bt_put(ft);
-       ret = bt_trace_set_packet_header_field_type(trace,
-               packet_header_type);
-       BT_ASSERT(ret == 0);
-
-       bt_put(packet_header_type);
-}
-
-static struct bt_trace *create_tc1(void)
-{
-       struct bt_trace *tc1 = NULL;
-
-       tc1 = bt_trace_create();
-       BT_ASSERT(tc1);
-       set_trace_packet_header(tc1);
-       create_sc1(tc1);
-       create_sc2(tc1);
-       return tc1;
-}
-
-static void init_weak_refs(struct bt_trace *tc,
-               struct bt_trace **tc1,
-               struct bt_stream_class **sc1,
-               struct bt_stream_class **sc2,
-               struct bt_event_class **ec1,
-               struct bt_event_class **ec2,
-               struct bt_event_class **ec3)
-{
-       *tc1 = tc;
-       *sc1 = bt_trace_borrow_stream_class_by_index(tc, 0);
-       *sc2 = bt_trace_borrow_stream_class_by_index(tc, 1);
-       *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
-       *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
-       *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
-}
-
-static void test_example_scenario(void)
-{
-       /**
-        * Weak pointers to CTF-IR objects are to be used very carefully.
-        * This is NOT a good practice and is strongly discouraged; this
-        * is only done to facilitate the validation of expected reference
-        * counts without affecting them by taking "real" references to the
-        * objects.
-        */
-       struct bt_trace *tc1 = NULL, *weak_tc1 = NULL;
-       struct bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
-       struct bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
-                       *weak_ec3 = NULL;
-       struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
-
-       /* The only reference which exists at this point is on TC1. */
-       tc1 = create_tc1();
-       ok(tc1, "Initialize trace");
-       BT_ASSERT(tc1);
-       init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
-                       &weak_ec2, &weak_ec3);
-       ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
-                       "Initial SC1 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
-                       "Initial SC2 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
-                       "Initial EC1 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
-                       "Initial EC2 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
-                       "Initial EC3 reference count is 0");
-
-       /* User A has ownership of the trace. */
-       BT_MOVE(user_a.tc, tc1);
-       ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
-                       "TC1 reference count is 1");
-
-       /* User A acquires a reference to SC2 from TC1. */
-       user_a.sc = bt_get(bt_trace_borrow_stream_class_by_index(user_a.tc, 1));
-       ok(user_a.sc, "User A acquires SC2 from TC1");
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
-                       "TC1 reference count is 2");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
-                       "SC2 reference count is 1");
-
-       /* User A acquires a reference to EC3 from SC2. */
-       user_a.ec = bt_get(
-               bt_stream_class_borrow_event_class_by_index(user_a.sc, 0));
-       ok(user_a.ec, "User A acquires EC3 from SC2");
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
-                       "TC1 reference count is 2");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
-                       "SC2 reference count is 2");
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
-                       "EC3 reference count is 1");
-
-       /* User A releases its reference to SC2. */
-       diag("User A releases SC2");
-       BT_PUT(user_a.sc);
-       /*
-        * We keep the pointer to SC2 around to validate its reference
-        * count.
-        */
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
-                       "TC1 reference count is 2");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
-                       "SC2 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
-                       "EC3 reference count is 1");
-
-       /* User A releases its reference to TC1. */
-       diag("User A releases TC1");
-       BT_PUT(user_a.tc);
-       /*
-        * We keep the pointer to TC1 around to validate its reference
-        * count.
-        */
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
-                       "TC1 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
-                       "SC2 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
-                       "EC3 reference count is 1");
-
-       /* User B acquires a reference to SC1. */
-       diag("User B acquires a reference to SC1");
-       user_b.sc = bt_get(weak_sc1);
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
-                       "TC1 reference count is 2");
-       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
-                       "SC1 reference count is 1");
-
-       /* User C acquires a reference to EC1. */
-       diag("User C acquires a reference to EC1");
-       user_c.ec = bt_get(
-               bt_stream_class_borrow_event_class_by_index(user_b.sc, 0));
-       ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
-                       "EC1 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
-                       "SC1 reference count is 2");
-
-       /* User A releases its reference on EC3. */
-       diag("User A releases its reference on EC3");
-       BT_PUT(user_a.ec);
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
-                       "EC3 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
-                       "SC2 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
-                       "TC1 reference count is 1");
-
-       /* User B releases its reference on SC1. */
-       diag("User B releases its reference on SC1");
-       BT_PUT(user_b.sc);
-       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
-                       "SC1 reference count is 1");
-
-       /*
-        * User C is the sole owner of an object and is keeping the whole
-        * trace hierarchy "alive" by holding a reference to EC1.
-        */
-       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
-                       "TC1 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
-                       "SC1 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
-                       "SC2 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
-                       "EC1 reference count is 1");
-       ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
-                       "EC2 reference count is 0");
-       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
-                       "EC3 reference count is 0");
-
-       /* Reclaim last reference held by User C. */
-       BT_PUT(user_c.ec);
-}
-
-static void create_writer_user_full(struct writer_user *user)
-{
-       gchar *trace_path;
-       struct bt_ctf_field_type *ft;
-       struct bt_ctf_field *field;
-       struct bt_ctf_clock *clock;
-       int ret;
-
-       trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
-       if (!bt_mkdtemp(trace_path)) {
-               perror("# perror");
-       }
-
-       user->writer = bt_ctf_writer_create(trace_path);
-       BT_ASSERT(user->writer);
-       ret = bt_ctf_writer_set_byte_order(user->writer,
-               BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
-       BT_ASSERT(ret == 0);
-       user->tc = bt_ctf_writer_get_trace(user->writer);
-       BT_ASSERT(user->tc);
-       user->sc = bt_ctf_stream_class_create("sc");
-       BT_ASSERT(user->sc);
-       clock = bt_ctf_clock_create("the_clock");
-       BT_ASSERT(clock);
-       ret = bt_ctf_writer_add_clock(user->writer, clock);
-       BT_ASSERT(!ret);
-       ret = bt_ctf_stream_class_set_clock(user->sc, clock);
-       BT_ASSERT(!ret);
-       BT_PUT(clock);
-       user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
-       BT_ASSERT(user->stream);
-       user->ec = bt_ctf_event_class_create("ec");
-       BT_ASSERT(user->ec);
-       ft = create_writer_integer_struct();
-       BT_ASSERT(ft);
-       ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
-       BT_PUT(ft);
-       BT_ASSERT(!ret);
-       ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
-       BT_ASSERT(!ret);
-       user->event = bt_ctf_event_create(user->ec);
-       BT_ASSERT(user->event);
-       field = bt_ctf_event_get_payload(user->event, "payload_8");
-       BT_ASSERT(field);
-       ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
-       BT_ASSERT(!ret);
-       BT_PUT(field);
-       field = bt_ctf_event_get_payload(user->event, "payload_16");
-       BT_ASSERT(field);
-       ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
-       BT_ASSERT(!ret);
-       BT_PUT(field);
-       field = bt_ctf_event_get_payload(user->event, "payload_32");
-       BT_ASSERT(field);
-       ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
-       BT_ASSERT(!ret);
-       BT_PUT(field);
-       ret = bt_ctf_stream_append_event(user->stream, user->event);
-       BT_ASSERT(!ret);
-       recursive_rmdir(trace_path);
-       g_free(trace_path);
-}
-
-static void test_put_order_swap(size_t *array, size_t a, size_t b)
-{
-       size_t temp = array[a];
-
-       array[a] = array[b];
-       array[b] = temp;
-}
-
-static void test_put_order_put_objects(size_t *array, size_t size)
-{
-       size_t i;
-       struct writer_user user = { 0 };
-       void **objects = (void *) &user;
-
-       create_writer_user_full(&user);
-       printf("# ");
-
-       for (i = 0; i < size; ++i) {
-               void *obj = objects[array[i]];
-
-               printf("%s", writer_user_names[array[i]]);
-               BT_PUT(obj);
-
-               if (i < size - 1) {
-                       printf(" -> ");
-               }
-       }
-
-       puts("");
-}
-
-static void test_put_order_permute(size_t *array, int k, size_t size)
-{
-       if (k == 0) {
-               test_put_order_put_objects(array, size);
-       } else {
-               int i;
-
-               for (i = k - 1; i >= 0; i--) {
-                       size_t next_k = k - 1;
-
-                       test_put_order_swap(array, i, next_k);
-                       test_put_order_permute(array, next_k, size);
-                       test_put_order_swap(array, i, next_k);
-               }
-       }
-}
-
-static void test_put_order(void)
-{
-       size_t i;
-       size_t array[WRITER_USER_NR_ELEMENTS];
-
-       /* Initialize array of indexes */
-       for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
-               array[i] = i;
-       }
-
-       test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
-               WRITER_USER_NR_ELEMENTS);
-}
-
-/**
- * The objective of this test is to implement and expand upon the scenario
- * described in the reference counting documentation and ensure that any node of
- * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
- * other "alive" and reachable.
- *
- * External tools (e.g. valgrind) should be used to confirm that this
- * known-good test does not leak memory.
- */
-int main(int argc, char **argv)
-{
-       /* Initialize tap harness before any tests */
-       plan_tests(NR_TESTS);
-
-       test_example_scenario();
-       test_put_order();
-
-       return exit_status();
-}
index bc2da8e73abf9d2a0770921d3a48bec4445d2993..fa2046bbee4bd6814abba04328f4f8f57267bb11 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * test_ir_visit.c
  *
- * CTF IR visitor interface test
+ * Trace IR visitor interface test
  *
  * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
 
 #include "tap/tap.h"
 #include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/visitor.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/field-types.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/trace-ir/visitor.h>
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
index c8578827b32e2418e90be6fda6072e1bee19a21d..2cba95476ea7cfd06b917dfe3d65a6b96ca1de8c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * test_plugin.c
  *
- * CTF IR Reference Count test
+ * Trace IR Reference Count test
  *
  * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
  *
diff --git a/tests/lib/test_trace_ir_ref.c b/tests/lib/test_trace_ir_ref.c
new file mode 100644 (file)
index 0000000..bf97024
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * test_trace_ir_ref.c
+ *
+ * Trace IR Reference Count test
+ *
+ * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tap/tap.h"
+#include <babeltrace/ctf-writer/clock.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-writer/fields.h>
+#include <babeltrace/ctf-writer/stream-class.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-writer/trace.h>
+#include <babeltrace/ctf-writer/writer.h>
+#include <babeltrace/trace-ir/clock-class.h>
+#include <babeltrace/trace-ir/event.h>
+#include <babeltrace/trace-ir/event-class.h>
+#include <babeltrace/trace-ir/fields.h>
+#include <babeltrace/trace-ir/stream-class.h>
+#include <babeltrace/trace-ir/stream.h>
+#include <babeltrace/trace-ir/trace.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compat/stdlib-internal.h>
+#include <babeltrace/assert-internal.h>
+#include "common.h"
+
+#define NR_TESTS 37
+
+struct user {
+       struct bt_trace *tc;
+       struct bt_stream_class *sc;
+       struct bt_event_class *ec;
+       struct bt_stream *stream;
+       struct bt_event *event;
+};
+
+struct writer_user {
+       struct bt_ctf_writer *writer;
+       struct bt_ctf_trace *tc;
+       struct bt_ctf_stream_class *sc;
+       struct bt_ctf_event_class *ec;
+       struct bt_ctf_stream *stream;
+       struct bt_ctf_event *event;
+};
+
+const char *writer_user_names[] = {
+       "writer",
+       "trace",
+       "stream class",
+       "event class",
+       "stream",
+       "event",
+};
+
+static const size_t WRITER_USER_NR_ELEMENTS =
+       sizeof(struct writer_user) / sizeof(void *);
+
+/**
+ * Returns a structure containing the following fields:
+ *     - uint8_t payload_8;
+ *     - uint16_t payload_16;
+ *     - uint32_t payload_32;
+ */
+static struct bt_field_type *create_integer_struct(void)
+{
+       int ret;
+       struct bt_field_type *structure = NULL;
+       struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+       structure = bt_field_type_structure_create();
+       BT_ASSERT(structure);
+       ui8 = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ui8);
+       ret = bt_field_type_integer_set_field_value_range(ui8, 8);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(structure,
+               "payload_8", ui8);
+       BT_ASSERT(ret == 0);
+       ui16 = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ui16);
+       ret = bt_field_type_integer_set_field_value_range(ui16, 16);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(structure,
+               "payload_16", ui16);
+       BT_ASSERT(ret == 0);
+       ui32 = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ui32);
+       ret = bt_field_type_integer_set_field_value_range(ui32, 32);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(structure,
+               "payload_32", ui32);
+       BT_ASSERT(ret == 0);
+       BT_PUT(ui8);
+       BT_PUT(ui16);
+       BT_PUT(ui32);
+       return structure;
+}
+
+static struct bt_ctf_field_type *create_writer_integer_struct(void)
+{
+       int ret;
+       struct bt_ctf_field_type *structure = NULL;
+       struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+       structure = bt_ctf_field_type_structure_create();
+       BT_ASSERT(structure);
+       ui8 = bt_ctf_field_type_integer_create(8);
+       BT_ASSERT(ui8);
+       ret = bt_ctf_field_type_structure_add_field(structure, ui8,
+                       "payload_8");
+       BT_ASSERT(ret == 0);
+       ui16 = bt_ctf_field_type_integer_create(16);
+       BT_ASSERT(ui16);
+       ret = bt_ctf_field_type_structure_add_field(structure, ui16,
+                       "payload_16");
+       BT_ASSERT(ret == 0);
+       ui32 = bt_ctf_field_type_integer_create(32);
+       BT_ASSERT(ui32);
+       ret = bt_ctf_field_type_structure_add_field(structure, ui32,
+                       "payload_32");
+       BT_ASSERT(ret == 0);
+       BT_PUT(ui8);
+       BT_PUT(ui16);
+       BT_PUT(ui32);
+       return structure;
+}
+
+/**
+ * A simple event has the following payload:
+ *     - uint8_t payload_8;
+ *     - uint16_t payload_16;
+ *     - uint32_t payload_32;
+ */
+static struct bt_event_class *create_simple_event(struct bt_stream_class *sc,
+               const char *name)
+{
+       int ret;
+       struct bt_event_class *event = NULL;
+       struct bt_field_type *payload = NULL;
+
+       BT_ASSERT(name);
+       event = bt_event_class_create(sc);
+       BT_ASSERT(event);
+       ret = bt_event_class_set_name(event, name);
+       BT_ASSERT(ret == 0);
+       payload = create_integer_struct();
+       BT_ASSERT(payload);
+       ret = bt_event_class_set_payload_field_type(event, payload);
+       BT_ASSERT(ret == 0);
+       BT_PUT(payload);
+       return event;
+}
+
+/**
+ * A complex event has the following payload:
+ *     - uint8_t payload_8;
+ *     - uint16_t payload_16;
+ *     - uint32_t payload_32;
+ *     - struct payload_struct:
+ *           - uint8_t payload_8;
+ *           - uint16_t payload_16;
+ *           - uint32_t payload_32;
+ */
+static struct bt_event_class *create_complex_event(struct bt_stream_class *sc,
+               const char *name)
+{
+       int ret;
+       struct bt_event_class *event = NULL;
+       struct bt_field_type *inner = NULL, *outer = NULL;
+
+       BT_ASSERT(name);
+       event = bt_event_class_create(sc);
+       BT_ASSERT(event);
+       ret = bt_event_class_set_name(event, name);
+       BT_ASSERT(ret == 0);
+       outer = create_integer_struct();
+       BT_ASSERT(outer);
+       inner = create_integer_struct();
+       BT_ASSERT(inner);
+       ret = bt_field_type_structure_append_member(outer,
+               "payload_struct", inner);
+       BT_ASSERT(ret == 0);
+       ret = bt_event_class_set_payload_field_type(event, outer);
+       BT_ASSERT(ret == 0);
+       BT_PUT(inner);
+       BT_PUT(outer);
+       return event;
+}
+
+static void set_stream_class_field_types(
+               struct bt_stream_class *stream_class)
+{
+       struct bt_field_type *packet_context_type;
+       struct bt_field_type *event_header_type;
+       struct bt_field_type *ft;
+       int ret;
+
+       packet_context_type = bt_field_type_structure_create();
+       BT_ASSERT(packet_context_type);
+       ft = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ft);
+       ret = bt_field_type_integer_set_field_value_range(ft, 32);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(packet_context_type,
+               "packet_size", ft);
+       BT_ASSERT(ret == 0);
+       bt_put(ft);
+       ft = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ft);
+       ret = bt_field_type_integer_set_field_value_range(ft, 32);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(packet_context_type,
+               "content_size", ft);
+       BT_ASSERT(ret == 0);
+       bt_put(ft);
+       event_header_type = bt_field_type_structure_create();
+       BT_ASSERT(event_header_type);
+       ft = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ft);
+       ret = bt_field_type_integer_set_field_value_range(ft, 32);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(event_header_type,
+               "id", ft);
+       BT_ASSERT(ret == 0);
+       bt_put(ft);
+       ret = bt_stream_class_set_packet_context_field_type(stream_class,
+               packet_context_type);
+       BT_ASSERT(ret == 0);
+       ret = bt_stream_class_set_event_header_field_type(stream_class,
+               event_header_type);
+       BT_ASSERT(ret == 0);
+       bt_put(packet_context_type);
+       bt_put(event_header_type);
+}
+
+static void create_sc1(struct bt_trace *trace)
+{
+       int ret;
+       struct bt_event_class *ec1 = NULL, *ec2 = NULL;
+       struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
+
+       sc1 = bt_stream_class_create(trace);
+       BT_ASSERT(sc1);
+       ret = bt_stream_class_set_name(sc1, "sc1");
+       BT_ASSERT(ret == 0);
+       set_stream_class_field_types(sc1);
+       ec1 = create_complex_event(sc1, "ec1");
+       BT_ASSERT(ec1);
+       ec2 = create_simple_event(sc1, "ec2");
+       BT_ASSERT(ec2);
+       ret_stream = bt_event_class_borrow_stream_class(ec1);
+       ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
+       ret_stream = bt_event_class_borrow_stream_class(ec2);
+       ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
+       BT_PUT(ec1);
+       BT_PUT(ec2);
+       BT_PUT(sc1);
+}
+
+static void create_sc2(struct bt_trace *trace)
+{
+       int ret;
+       struct bt_event_class *ec3 = NULL;
+       struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
+
+       sc2 = bt_stream_class_create(trace);
+       BT_ASSERT(sc2);
+       ret = bt_stream_class_set_name(sc2, "sc2");
+       BT_ASSERT(ret == 0);
+       set_stream_class_field_types(sc2);
+       ec3 = create_simple_event(sc2, "ec3");
+       ret_stream = bt_event_class_borrow_stream_class(ec3);
+       ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
+       BT_PUT(ec3);
+       BT_PUT(sc2);
+}
+
+static void set_trace_packet_header(struct bt_trace *trace)
+{
+       struct bt_field_type *packet_header_type;
+       struct bt_field_type *ft;
+       int ret;
+
+       packet_header_type = bt_field_type_structure_create();
+       BT_ASSERT(packet_header_type);
+       ft = bt_field_type_unsigned_integer_create();
+       BT_ASSERT(ft);
+       ret = bt_field_type_integer_set_field_value_range(ft, 32);
+       BT_ASSERT(ret == 0);
+       ret = bt_field_type_structure_append_member(packet_header_type,
+               "stream_id", ft);
+       BT_ASSERT(ret == 0);
+       bt_put(ft);
+       ret = bt_trace_set_packet_header_field_type(trace,
+               packet_header_type);
+       BT_ASSERT(ret == 0);
+
+       bt_put(packet_header_type);
+}
+
+static struct bt_trace *create_tc1(void)
+{
+       struct bt_trace *tc1 = NULL;
+
+       tc1 = bt_trace_create();
+       BT_ASSERT(tc1);
+       set_trace_packet_header(tc1);
+       create_sc1(tc1);
+       create_sc2(tc1);
+       return tc1;
+}
+
+static void init_weak_refs(struct bt_trace *tc,
+               struct bt_trace **tc1,
+               struct bt_stream_class **sc1,
+               struct bt_stream_class **sc2,
+               struct bt_event_class **ec1,
+               struct bt_event_class **ec2,
+               struct bt_event_class **ec3)
+{
+       *tc1 = tc;
+       *sc1 = bt_trace_borrow_stream_class_by_index(tc, 0);
+       *sc2 = bt_trace_borrow_stream_class_by_index(tc, 1);
+       *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
+       *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
+       *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
+}
+
+static void test_example_scenario(void)
+{
+       /*
+        * Weak pointers to trace IR objects are to be used very
+        * carefully. This is NOT a good practice and is strongly
+        * discouraged; this is only done to facilitate the validation
+        * of expected reference counts without affecting them by taking
+        * "real" references to the objects.
+        */
+       struct bt_trace *tc1 = NULL, *weak_tc1 = NULL;
+       struct bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
+       struct bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
+                       *weak_ec3 = NULL;
+       struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
+
+       /* The only reference which exists at this point is on TC1. */
+       tc1 = create_tc1();
+       ok(tc1, "Initialize trace");
+       BT_ASSERT(tc1);
+       init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
+                       &weak_ec2, &weak_ec3);
+       ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
+                       "Initial SC1 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+                       "Initial SC2 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
+                       "Initial EC1 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+                       "Initial EC2 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+                       "Initial EC3 reference count is 0");
+
+       /* User A has ownership of the trace. */
+       BT_MOVE(user_a.tc, tc1);
+       ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
+                       "TC1 reference count is 1");
+
+       /* User A acquires a reference to SC2 from TC1. */
+       user_a.sc = bt_get(bt_trace_borrow_stream_class_by_index(user_a.tc, 1));
+       ok(user_a.sc, "User A acquires SC2 from TC1");
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+                       "TC1 reference count is 2");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+                       "SC2 reference count is 1");
+
+       /* User A acquires a reference to EC3 from SC2. */
+       user_a.ec = bt_get(
+               bt_stream_class_borrow_event_class_by_index(user_a.sc, 0));
+       ok(user_a.ec, "User A acquires EC3 from SC2");
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+                       "TC1 reference count is 2");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
+                       "SC2 reference count is 2");
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+                       "EC3 reference count is 1");
+
+       /* User A releases its reference to SC2. */
+       diag("User A releases SC2");
+       BT_PUT(user_a.sc);
+       /*
+        * We keep the pointer to SC2 around to validate its reference
+        * count.
+        */
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+                       "TC1 reference count is 2");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+                       "SC2 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+                       "EC3 reference count is 1");
+
+       /* User A releases its reference to TC1. */
+       diag("User A releases TC1");
+       BT_PUT(user_a.tc);
+       /*
+        * We keep the pointer to TC1 around to validate its reference
+        * count.
+        */
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+                       "TC1 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+                       "SC2 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+                       "EC3 reference count is 1");
+
+       /* User B acquires a reference to SC1. */
+       diag("User B acquires a reference to SC1");
+       user_b.sc = bt_get(weak_sc1);
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+                       "TC1 reference count is 2");
+       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+                       "SC1 reference count is 1");
+
+       /* User C acquires a reference to EC1. */
+       diag("User C acquires a reference to EC1");
+       user_c.ec = bt_get(
+               bt_stream_class_borrow_event_class_by_index(user_b.sc, 0));
+       ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+                       "EC1 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
+                       "SC1 reference count is 2");
+
+       /* User A releases its reference on EC3. */
+       diag("User A releases its reference on EC3");
+       BT_PUT(user_a.ec);
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+                       "EC3 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+                       "SC2 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+                       "TC1 reference count is 1");
+
+       /* User B releases its reference on SC1. */
+       diag("User B releases its reference on SC1");
+       BT_PUT(user_b.sc);
+       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+                       "SC1 reference count is 1");
+
+       /*
+        * User C is the sole owner of an object and is keeping the whole
+        * trace hierarchy "alive" by holding a reference to EC1.
+        */
+       ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+                       "TC1 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+                       "SC1 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+                       "SC2 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+                       "EC1 reference count is 1");
+       ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+                       "EC2 reference count is 0");
+       ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+                       "EC3 reference count is 0");
+
+       /* Reclaim last reference held by User C. */
+       BT_PUT(user_c.ec);
+}
+
+static void create_writer_user_full(struct writer_user *user)
+{
+       gchar *trace_path;
+       struct bt_ctf_field_type *ft;
+       struct bt_ctf_field *field;
+       struct bt_ctf_clock *clock;
+       int ret;
+
+       trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
+       if (!bt_mkdtemp(trace_path)) {
+               perror("# perror");
+       }
+
+       user->writer = bt_ctf_writer_create(trace_path);
+       BT_ASSERT(user->writer);
+       ret = bt_ctf_writer_set_byte_order(user->writer,
+               BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+       BT_ASSERT(ret == 0);
+       user->tc = bt_ctf_writer_get_trace(user->writer);
+       BT_ASSERT(user->tc);
+       user->sc = bt_ctf_stream_class_create("sc");
+       BT_ASSERT(user->sc);
+       clock = bt_ctf_clock_create("the_clock");
+       BT_ASSERT(clock);
+       ret = bt_ctf_writer_add_clock(user->writer, clock);
+       BT_ASSERT(!ret);
+       ret = bt_ctf_stream_class_set_clock(user->sc, clock);
+       BT_ASSERT(!ret);
+       BT_PUT(clock);
+       user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
+       BT_ASSERT(user->stream);
+       user->ec = bt_ctf_event_class_create("ec");
+       BT_ASSERT(user->ec);
+       ft = create_writer_integer_struct();
+       BT_ASSERT(ft);
+       ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
+       BT_PUT(ft);
+       BT_ASSERT(!ret);
+       ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
+       BT_ASSERT(!ret);
+       user->event = bt_ctf_event_create(user->ec);
+       BT_ASSERT(user->event);
+       field = bt_ctf_event_get_payload(user->event, "payload_8");
+       BT_ASSERT(field);
+       ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
+       BT_ASSERT(!ret);
+       BT_PUT(field);
+       field = bt_ctf_event_get_payload(user->event, "payload_16");
+       BT_ASSERT(field);
+       ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
+       BT_ASSERT(!ret);
+       BT_PUT(field);
+       field = bt_ctf_event_get_payload(user->event, "payload_32");
+       BT_ASSERT(field);
+       ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
+       BT_ASSERT(!ret);
+       BT_PUT(field);
+       ret = bt_ctf_stream_append_event(user->stream, user->event);
+       BT_ASSERT(!ret);
+       recursive_rmdir(trace_path);
+       g_free(trace_path);
+}
+
+static void test_put_order_swap(size_t *array, size_t a, size_t b)
+{
+       size_t temp = array[a];
+
+       array[a] = array[b];
+       array[b] = temp;
+}
+
+static void test_put_order_put_objects(size_t *array, size_t size)
+{
+       size_t i;
+       struct writer_user user = { 0 };
+       void **objects = (void *) &user;
+
+       create_writer_user_full(&user);
+       printf("# ");
+
+       for (i = 0; i < size; ++i) {
+               void *obj = objects[array[i]];
+
+               printf("%s", writer_user_names[array[i]]);
+               BT_PUT(obj);
+
+               if (i < size - 1) {
+                       printf(" -> ");
+               }
+       }
+
+       puts("");
+}
+
+static void test_put_order_permute(size_t *array, int k, size_t size)
+{
+       if (k == 0) {
+               test_put_order_put_objects(array, size);
+       } else {
+               int i;
+
+               for (i = k - 1; i >= 0; i--) {
+                       size_t next_k = k - 1;
+
+                       test_put_order_swap(array, i, next_k);
+                       test_put_order_permute(array, next_k, size);
+                       test_put_order_swap(array, i, next_k);
+               }
+       }
+}
+
+static void test_put_order(void)
+{
+       size_t i;
+       size_t array[WRITER_USER_NR_ELEMENTS];
+
+       /* Initialize array of indexes */
+       for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
+               array[i] = i;
+       }
+
+       test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
+               WRITER_USER_NR_ELEMENTS);
+}
+
+/**
+ * The objective of this test is to implement and expand upon the scenario
+ * described in the reference counting documentation and ensure that any node of
+ * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
+ * other "alive" and reachable.
+ *
+ * External tools (e.g. valgrind) should be used to confirm that this
+ * known-good test does not leak memory.
+ */
+int main(int argc, char **argv)
+{
+       /* Initialize tap harness before any tests */
+       plan_tests(NR_TESTS);
+
+       test_example_scenario();
+       test_put_order();
+
+       return exit_status();
+}
diff --git a/tests/lib/trace-ir/Makefile.am b/tests/lib/trace-ir/Makefile.am
new file mode 100644 (file)
index 0000000..3c946c1
--- /dev/null
@@ -0,0 +1,5 @@
+if ENABLE_PYTHON_BINDINGS
+check_SCRIPTS = test_trace_ir
+endif
+
+EXTRA_DIST = test_trace.py test_stream_class.py
diff --git a/tests/lib/trace-ir/test_stream_class.py b/tests/lib/trace-ir/test_stream_class.py
new file mode 100644 (file)
index 0000000..0841848
--- /dev/null
@@ -0,0 +1,197 @@
+import unittest
+import bt2
+
+
+class StreamClassSingleClockClassTestCase(unittest.TestCase):
+    def setUp(self):
+        self._sc = bt2.StreamClass()
+
+    def tearDown(self):
+        del self._sc
+
+    def _test_add_sc_ft_vs_event_class(self, set_ft_func):
+        cc = bt2.ClockClass('first_cc', 1000)
+        scft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        scft.append_field('salut', ft)
+        set_ft_func(scft)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec)
+        trace = bt2.Trace()
+
+        with self.assertRaises(bt2.Error):
+            trace.add_stream_class(self._sc)
+
+    def test_add_sc_packet_context_vs_event_class(self):
+        def func(ft):
+            self._sc.packet_context_field_type = ft
+
+        self._test_add_sc_ft_vs_event_class(func)
+
+    def test_add_sc_event_context_vs_event_class(self):
+        def func(ft):
+            self._sc.event_context_field_type = ft
+
+        self._test_add_sc_ft_vs_event_class(func)
+
+    def test_add_sc_event_header_vs_event_class(self):
+        def func(ft):
+            self._sc.event_header_field_type = ft
+
+        self._test_add_sc_ft_vs_event_class(func)
+
+    def test_add_sc_event_class_vs_event_class(self):
+        ehft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32)
+        ehft.append_field('id', ft)
+        self._sc.event_header_field_type = ehft
+        cc = bt2.ClockClass('first_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('logi', ft)
+        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec1)
+        self._sc.add_event_class(ec2)
+        trace = bt2.Trace()
+
+        with self.assertRaises(bt2.Error):
+            trace.add_stream_class(self._sc)
+
+    def _test_create_event_ft_vs_event_class(self, set_ft_func):
+        cc = bt2.ClockClass('first_cc', 1000)
+        scft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        scft.append_field('salut', ft)
+        set_ft_func(scft)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec)
+
+        with self.assertRaises(bt2.Error):
+            ev = ec()
+
+    def test_create_event_packet_context_vs_event_class(self):
+        def func(ft):
+            self._sc.packet_context_field_type = ft
+
+        self._test_create_event_ft_vs_event_class(func)
+
+    def test_create_event_event_context_vs_event_class(self):
+        def func(ft):
+            self._sc.event_context_field_type = ft
+
+        self._test_create_event_ft_vs_event_class(func)
+
+    def test_create_event_event_header_vs_event_class(self):
+        def func(ft):
+            self._sc.event_header_field_type = ft
+
+        self._test_create_event_ft_vs_event_class(func)
+
+    def test_create_event_event_class_vs_event_class(self):
+        ehft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32)
+        ehft.append_field('id', ft)
+        self._sc.event_header_field_type = ehft
+        cc = bt2.ClockClass('first_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('logi', ft)
+        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec1)
+        self._sc.add_event_class(ec2)
+
+        with self.assertRaises(bt2.Error):
+            ev = ec1()
+
+    def test_add_ec_after_add_sc(self):
+        cc = bt2.ClockClass('first_cc', 1000)
+        scft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        scft.append_field('salut', ft)
+        self._sc.packet_context_field_type = scft
+        trace = bt2.Trace()
+        trace.add_stream_class(self._sc)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+        with self.assertRaises(bt2.Error):
+            self._sc.add_event_class(ec)
+
+    def test_add_ec_after_add_sc_single_cc(self):
+        ehft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32)
+        ehft.append_field('id', ft)
+        self._sc.event_header_field_type = ehft
+        trace = bt2.Trace()
+        trace.add_stream_class(self._sc)
+        cc = bt2.ClockClass('first_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec)
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('lel', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+        with self.assertRaises(bt2.Error):
+            self._sc.add_event_class(ec)
+
+    def test_add_ec_after_create_event(self):
+        ehft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32)
+        ehft.append_field('id', ft)
+        self._sc.event_header_field_type = ehft
+        cc = bt2.ClockClass('first_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec1 = bt2.EventClass('ec', payload_field_type=payloadft)
+        self._sc.add_event_class(ec1)
+        ev = ec1()
+        cc = bt2.ClockClass('second_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('logi', ft)
+        ec2 = bt2.EventClass('ec', payload_field_type=payloadft)
+
+        with self.assertRaises(bt2.Error):
+            self._sc.add_event_class(ec2)
+
+    def test_sc_clock_matches_expected_clock_class(self):
+        clock = bt2.CtfWriterClock('sc_clock')
+        self._sc.clock = clock
+        writer = bt2.CtfWriter('/tmp')
+        writer.add_clock(clock)
+        writer.trace.add_stream_class(self._sc)
+        cc = bt2.ClockClass('other_cc', 1000)
+        payloadft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        payloadft.append_field('zorg', ft)
+        ec = bt2.EventClass('ec', payload_field_type=payloadft)
+
+        with self.assertRaises(bt2.Error):
+            self._sc.add_event_class(ec)
diff --git a/tests/lib/trace-ir/test_trace.py b/tests/lib/trace-ir/test_trace.py
new file mode 100644 (file)
index 0000000..116f7ba
--- /dev/null
@@ -0,0 +1,91 @@
+import unittest
+import bt2
+
+
+class TraceTestCase(unittest.TestCase):
+    def setUp(self):
+        self._trace = bt2.Trace()
+
+    def tearDown(self):
+        del self._trace
+
+    def _add_stream_class(self):
+        sc = bt2.StreamClass()
+        self._trace.add_stream_class(sc)
+
+    def test_packet_header_ft_no_clock_class_simple(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        phft.append_field('salut', ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._add_stream_class()
+
+    def test_packet_header_ft_no_clock_class_struct(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        struct_ft = bt2.StructureFieldType()
+        struct_ft.append_field('salut', ft)
+        phft.append_field('boucane', struct_ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._add_stream_class()
+
+    def test_packet_header_ft_no_clock_class_variant(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        tag_ft = bt2.EnumerationFieldType(size=32)
+        tag_ft.add_mapping('heille', 12)
+        variant_ft = bt2.VariantFieldType('tag', tag_ft)
+        variant_ft.append_field('heille', ft)
+        phft.append_field('tag', tag_ft)
+        phft.append_field('boucane', variant_ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._add_stream_class()
+
+    def test_packet_header_ft_no_clock_class_array(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        array_ft = bt2.ArrayFieldType(ft, 23)
+        phft.append_field('boucane', array_ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._add_stream_class()
+
+    def test_packet_header_ft_no_clock_class_sequence(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        len_ft = bt2.IntegerFieldType(32)
+        seq_ft = bt2.SequenceFieldType(ft, 'len')
+        phft.append_field('len', len_ft)
+        phft.append_field('boucane', seq_ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._add_stream_class()
+
+    def test_packet_header_ft_no_clock_class_set_static(self):
+        cc = bt2.ClockClass('hello', 1000)
+        phft = bt2.StructureFieldType()
+        ft = bt2.IntegerFieldType(32, mapped_clock_class=cc)
+        phft.append_field('salut', ft)
+        self._trace.add_clock_class(cc)
+        self._trace.packet_header_field_type = phft
+
+        with self.assertRaises(bt2.Error):
+            self._trace.set_is_static()
diff --git a/tests/lib/trace-ir/test_trace_ir.in b/tests/lib/trace-ir/test_trace_ir.in
new file mode 100644 (file)
index 0000000..e78b344
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 - Philippe Proulx <pproulx@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+NO_SH_TAP=1
+. "@abs_top_builddir@/tests/utils/common.sh"
+
+PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib"
+TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python"
+TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py"
+THIS_DIR="${BT_SRC_PATH}/tests/lib/trace-ir"
+
+if [ "x${MSYSTEM}" != "x" ]; then
+       export PATH="${BT_BUILD_PATH}/lib/.libs:${PATH}"
+else
+       export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs:${LD_LIBRARY_PATH}"
+fi
+
+PYTHONPATH="${PYTHON_BUILD_DIR}:${TESTS_UTILS_PYTHON_DIR}" \
+       "@PYTHON@" "${TESTRUNNER_PY}" "${THIS_DIR}"
+exit $?
This page took 0.305019 seconds and 4 git commands to generate.