Remove Babeltrace 1 files and reorganize the tree
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Sat, 1 Apr 2017 01:29:42 +0000 (21:29 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:39 +0000 (12:57 -0400)
This is one of the patches that you won't easily forget.

This patch removes the remaining legacy files, moving them if we still
need them, and reorganizes the tree as such:

* formats/ is removed
* formats/ctf/ir/ is moved to lib/ctf-ir/
* formats/ctf/writer/ is moved to lib/ctf-writer/
* types/ is removed

Because some of the CTF IR and CTF writer objects are so coupled, both
components are in libbabeltrace now. The build system creates a symbolic
link from libbabeltrace-ctf (where CTF writer used to reside) to
libbabeltrace, so that `-lbabeltrace-ctf` still works for the current
users of CTF writer.

converter/babeltrace-log.c still exists, but it's not build as of this
patch because it uses the legacy API. We need to change this to use CTF
writer and add it to the Makefile again.

Some debug info files are gone because they also use the legacy API.
They are updated anyway as part of the upcoming debug info component
class.

The Python bindings are not covered by this patch: a subsequent patch
should fix them at once.

Some tests which used the legacy API are removed.

The legacy include files are removed, except for
include/babeltrace/ctf/event.h which could be included by CTF writer
users. The file simply includes all the CTF writer header files now.

The functions to serialize integer and floating point number fields
are moved to lib/ctf-writer/serialize.c where a light
`struct bt_ctf_stream_pos` exists along with a few helper functions
for this renamed legacy object. The serialization functions use BT 2
objects now so that the dependency on the legacy API can be dropped.

The serialization functions accept a native byte order parameter now.
When a field type has a "native" byte order, the real (passed) native
byte order must be used. This ensures that:

* CTF IR objects do not need to propagate the trace's native byte order
  to all the contained field types.

* Two references to the same field type which are part of two different
  trace objects can have a native byte order without causing byte order
  overwriting bugs.

The CTF IR code is simplified with this change. Also the
bt_ctf_trace_set_byte_order() function refuses the
BT_CTF_BYTE_ORDER_NATIVE byte order.

I also added internal inline functions to quickly access the parent
of some CTF IR object without getting a new reference:

* bt_ctf_event_borrow_event_class()
* bt_ctf_event_class_borrow_stream_class()
* bt_ctf_stream_class_borrow_trace()

Since the CTF parser test in formats/ctf/metadata/ was a legacy tool,
it's removed in this patch. It's not used anymore by test_ctf_writer
(only the converter runs to validate the generated trace).

Leaks are fixed in test_ctf_ir_ref and test_trace_listener.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
205 files changed:
.gitignore
Makefile.am
configure.ac
converter/Makefile.am
converter/babeltrace.c
ctf-reader-proto/Makefile.am [deleted file]
ctf-reader-proto/ctf-fs.c [deleted file]
ctf-reader-proto/ctf-fs.h [deleted file]
ctf-reader-proto/ctf-notif-iter.gdb [deleted file]
ctf-reader-proto/protorectoral.c [deleted file]
formats/Makefile.am [deleted file]
formats/bt-dummy/Makefile.am [deleted file]
formats/bt-dummy/bt-dummy.c [deleted file]
formats/ctf-metadata/Makefile.am [deleted file]
formats/ctf-metadata/ctf-metadata.c [deleted file]
formats/ctf-text/Makefile.am [deleted file]
formats/ctf-text/ctf-text.c [deleted file]
formats/ctf-text/types/Makefile.am [deleted file]
formats/ctf-text/types/array.c [deleted file]
formats/ctf-text/types/enum.c [deleted file]
formats/ctf-text/types/float.c [deleted file]
formats/ctf-text/types/integer.c [deleted file]
formats/ctf-text/types/sequence.c [deleted file]
formats/ctf-text/types/string.c [deleted file]
formats/ctf-text/types/struct.c [deleted file]
formats/ctf-text/types/variant.c [deleted file]
formats/ctf/Makefile.am [deleted file]
formats/ctf/callbacks.c [deleted file]
formats/ctf/ctf.c [deleted file]
formats/ctf/events-private.h [deleted file]
formats/ctf/events.c [deleted file]
formats/ctf/ir/Makefile.am [deleted file]
formats/ctf/ir/attributes.c [deleted file]
formats/ctf/ir/clock-class.c [deleted file]
formats/ctf/ir/event-class.c [deleted file]
formats/ctf/ir/event.c [deleted file]
formats/ctf/ir/field-path.c [deleted file]
formats/ctf/ir/field-types.c [deleted file]
formats/ctf/ir/fields.c [deleted file]
formats/ctf/ir/packet.c [deleted file]
formats/ctf/ir/resolve.c [deleted file]
formats/ctf/ir/stream-class.c [deleted file]
formats/ctf/ir/stream.c [deleted file]
formats/ctf/ir/trace.c [deleted file]
formats/ctf/ir/utils.c [deleted file]
formats/ctf/ir/validation.c [deleted file]
formats/ctf/ir/visitor.c [deleted file]
formats/ctf/iterator.c [deleted file]
formats/ctf/metadata/Makefile.am [deleted file]
formats/ctf/metadata/ctf-ast.h [deleted file]
formats/ctf/metadata/ctf-lexer.l [deleted file]
formats/ctf/metadata/ctf-parser-test.c [deleted file]
formats/ctf/metadata/ctf-parser.y [deleted file]
formats/ctf/metadata/ctf-scanner-symbols.h [deleted file]
formats/ctf/metadata/ctf-scanner.h [deleted file]
formats/ctf/metadata/ctf-test/development/ctf-embedded-1.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/array-negative-len.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/array-unexisting-elem-type.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/enum-with-non-numeric-range.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/event-with-non-text-left.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/sequence-incorrect-elem-type.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type-signedness.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/stream-with-non-text-left.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-unexisting-field-type.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-duplicate-field-name.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-2.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-3.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-4.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-5.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/struct-with-right-range.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/trace-with-non-text-left.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/typealias-left-abstract-array.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/typealias-no-array-alias.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/typedef-untagged-variant.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/variant-unexisting-field-type.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/variant-with-duplicate-field-name.txt [deleted file]
formats/ctf/metadata/ctf-test/fail/variant-with-non-text-left.txt [deleted file]
formats/ctf/metadata/ctf-test/readme.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-embedded-1.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-embedded-2.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-single-stream-with-packet-context.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-single-stream.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt [deleted file]
formats/ctf/metadata/ctf-test/succeed/ctf-test.txt [deleted file]
formats/ctf/metadata/ctf-test/tofix/ctf-path.txt [deleted file]
formats/ctf/metadata/ctf-test/tofix/ctf-redefine-type.txt [deleted file]
formats/ctf/metadata/ctf-test/tofix/ctf-typedef-ambiguity.txt [deleted file]
formats/ctf/metadata/ctf-visitor-generate-io-struct.c [deleted file]
formats/ctf/metadata/ctf-visitor-parent-links.c [deleted file]
formats/ctf/metadata/ctf-visitor-semantic-validator.c [deleted file]
formats/ctf/metadata/ctf-visitor-xml.c [deleted file]
formats/ctf/metadata/objstack.c [deleted file]
formats/ctf/metadata/objstack.h [deleted file]
formats/ctf/types/Makefile.am [deleted file]
formats/ctf/types/array.c [deleted file]
formats/ctf/types/enum.c [deleted file]
formats/ctf/types/float.c [deleted file]
formats/ctf/types/integer.c [deleted file]
formats/ctf/types/sequence.c [deleted file]
formats/ctf/types/string.c [deleted file]
formats/ctf/types/struct.c [deleted file]
formats/ctf/types/variant.c [deleted file]
formats/ctf/writer/Makefile.am [deleted file]
formats/ctf/writer/clock.c [deleted file]
formats/ctf/writer/functor.c [deleted file]
formats/ctf/writer/writer.c [deleted file]
formats/lttng-live/Makefile.am [deleted file]
formats/lttng-live/lttng-live-comm.c [deleted file]
formats/lttng-live/lttng-live-plugin.c [deleted file]
formats/lttng-live/lttng-live.h [deleted file]
formats/lttng-live/lttng-viewer-abi.h [deleted file]
include/Makefile.am
include/babeltrace/clock-internal.h [deleted file]
include/babeltrace/clock-types.h [deleted file]
include/babeltrace/context-internal.h [deleted file]
include/babeltrace/context.h [deleted file]
include/babeltrace/ctf-ir/event-class-internal.h
include/babeltrace/ctf-ir/event-internal.h
include/babeltrace/ctf-ir/field-types-internal.h
include/babeltrace/ctf-ir/fields-internal.h
include/babeltrace/ctf-ir/metadata.h [deleted file]
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-text/types.h [deleted file]
include/babeltrace/ctf-writer/serialize-internal.h [new file with mode: 0644]
include/babeltrace/ctf/callbacks-internal.h [deleted file]
include/babeltrace/ctf/callbacks.h [deleted file]
include/babeltrace/ctf/ctf-index.h [deleted file]
include/babeltrace/ctf/events-internal.h [deleted file]
include/babeltrace/ctf/events.h
include/babeltrace/ctf/iterator.h [deleted file]
include/babeltrace/ctf/metadata.h [deleted file]
include/babeltrace/ctf/types.h [deleted file]
include/babeltrace/debug-info.h [deleted file]
include/babeltrace/format-internal.h [deleted file]
include/babeltrace/format.h [deleted file]
include/babeltrace/iterator-internal.h [deleted file]
include/babeltrace/iterator.h [deleted file]
include/babeltrace/object-internal.h
include/babeltrace/trace-collection.h [deleted file]
include/babeltrace/trace-debug-info.h [deleted file]
include/babeltrace/trace-handle-internal.h [deleted file]
include/babeltrace/trace-handle.h [deleted file]
include/babeltrace/types.h [deleted file]
lib/Makefile.am
lib/babeltrace.c
lib/context.c [deleted file]
lib/ctf-ir/Makefile.am [new file with mode: 0644]
lib/ctf-ir/attributes.c [new file with mode: 0644]
lib/ctf-ir/clock-class.c [new file with mode: 0644]
lib/ctf-ir/event-class.c [new file with mode: 0644]
lib/ctf-ir/event.c [new file with mode: 0644]
lib/ctf-ir/field-path.c [new file with mode: 0644]
lib/ctf-ir/field-types.c [new file with mode: 0644]
lib/ctf-ir/fields.c [new file with mode: 0644]
lib/ctf-ir/packet.c [new file with mode: 0644]
lib/ctf-ir/resolve.c [new file with mode: 0644]
lib/ctf-ir/stream-class.c [new file with mode: 0644]
lib/ctf-ir/stream.c [new file with mode: 0644]
lib/ctf-ir/trace.c [new file with mode: 0644]
lib/ctf-ir/utils.c [new file with mode: 0644]
lib/ctf-ir/validation.c [new file with mode: 0644]
lib/ctf-ir/visitor.c [new file with mode: 0644]
lib/ctf-writer/Makefile.am [new file with mode: 0644]
lib/ctf-writer/clock.c [new file with mode: 0644]
lib/ctf-writer/functor.c [new file with mode: 0644]
lib/ctf-writer/serialize.c [new file with mode: 0644]
lib/ctf-writer/writer.c [new file with mode: 0644]
lib/debug-info.c [deleted file]
lib/iterator.c [deleted file]
lib/registry.c [deleted file]
lib/trace-collection.c [deleted file]
lib/trace-handle.c [deleted file]
plugins/ctf/Makefile.am
plugins/ctf/common/metadata/parser.y
plugins/ctf/common/metadata/visitor-generate-ir.c
plugins/muxer/Makefile.am
plugins/text/Makefile.am
plugins/utils/Makefile.am
plugins/writer/Makefile.am
tests/Makefile.am
tests/bin/Makefile.am
tests/lib/Makefile.am
tests/lib/common.c
tests/lib/common.h
tests/lib/test-plugin-plugins/Makefile.am
tests/lib/test_ctf_ir_ref.c
tests/lib/test_ctf_writer.c
tests/lib/test_ctf_writer_complete.in
tests/lib/test_seek.c [deleted file]
tests/lib/test_trace_listener.c
types/Makefile.am [deleted file]
types/array.c [deleted file]
types/enum.c [deleted file]
types/float.c [deleted file]
types/integer.c [deleted file]
types/sequence.c [deleted file]
types/string.c [deleted file]
types/struct.c [deleted file]
types/types.c [deleted file]
types/variant.c [deleted file]

index 9505e1e3e1ba90cc7239816b92798b43b61c8d66..b268cc4d3ce289f05ef734eac792a306d2489585 100644 (file)
@@ -1,7 +1,6 @@
 *~
 /tests/bin/intersection/bt_python_helper.py
 /tests/bin/intersection/test_intersection
-/tests/bin/test_formats
 /tests/bin/test_packet_seq_num
 /tests/bin/test_trace_read
 /tests/lib/test_bin_info
@@ -17,9 +16,6 @@
 /tests/lib/test_dwarf
 /tests/lib/test_dwarf_complete
 /tests/lib/test_ir_visit
-/tests/lib/test_seek
-/tests/lib/test_seek_big_trace
-/tests/lib/test_seek_empty_packet
 /tests/lib/test_trace_listener
 /tests/lib/test_plugin
 /tests/lib/test_plugin_complete
@@ -61,7 +57,6 @@ autom4te.cache/
 config/
 converter/babeltrace-log
 core
-formats/ctf/metadata/ctf-parser.output
 stamp-h1
 bindings/python/__init__.py
 bindings/python/nativebt.py
index 1d66b1d4ce6c81a88fc8208410e2f2a3b9fb01f8..a7fecfead89f407e361de1718bb91d6641ba00df 100644 (file)
@@ -5,7 +5,6 @@ ACLOCAL_AMFLAGS = -I m4
 SUBDIRS =                      \
        include                 \
        common                  \
-       types                   \
        compat
 
 if WITH_PYTHON_PLUGINS
@@ -14,7 +13,6 @@ endif
 
 SUBDIRS +=                     \
        lib                     \
-       formats                 \
        plugins                 \
        converter               \
        bindings                \
@@ -29,3 +27,10 @@ dist_noinst_DATA = CodingStyle
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = babeltrace.pc babeltrace-ctf.pc
+
+# Create a symlink from libbabeltrace-ctf to libbabeltrace.
+# CTF writer used to be in libbabeltrace-ctf in Babeltrace 1, so this
+# file must still exist. As of Babeltrace 2, CTF writer is implemented
+# in libbabeltrace, hence the symlink.
+install-exec-hook:
+       $(LN_S) -f libbabeltrace.so $(DESTDIR)$(libdir)/libbabeltrace-ctf.so
index 51e229d8756ffab6857511bbe8271fc3f532a216..0e0ddbef53db930faeb402b8de8d1441bd680d84 100644 (file)
@@ -61,7 +61,7 @@ AC_CHECK_HEADERS([ \
        sys/socket.h \
 ])
 
-if test ! -f "$srcdir/formats/ctf/metadata/ctf-parser.h"; then
+if test ! -f "$srcdir/plugins/ctf/common/metadata/parser.h"; then
         if test x"$(basename "$YACC")" != "xbison -y"; then
                 AC_MSG_ERROR([[bison not found and is required when building from git.
                 Please install bison]])
@@ -72,7 +72,7 @@ if test ! -f "$srcdir/formats/ctf/metadata/ctf-parser.h"; then
         ])
 fi
 
-if test ! -f "$srcdir/formats/ctf/metadata/ctf-lexer.c"; then
+if test ! -f "$srcdir/plugins/ctf/common/metadata/lexer.c"; then
         if test x"$LEX" != "xflex"; then
                 AC_MSG_ERROR([[flex not found and is required when building from git.
                 Please install flex]])
@@ -398,12 +398,12 @@ AC_SUBST(DEFAULT_INCLUDES)
 babeltraceincludedir="${includedir}/babeltrace"
 AC_SUBST(babeltraceincludedir)
 
-babeltracectfincludedir="${includedir}/babeltrace/ctf"
-AC_SUBST(babeltracectfincludedir)
-
 babeltracectfwriterincludedir="${includedir}/babeltrace/ctf-writer"
 AC_SUBST(babeltracectfwriterincludedir)
 
+babeltracectfincludedir="${includedir}/babeltrace/ctf"
+AC_SUBST(babeltracectfincludedir)
+
 babeltracectfirincludedir="${includedir}/babeltrace/ctf-ir"
 AC_SUBST(babeltracectfirincludedir)
 
@@ -444,24 +444,12 @@ AS_IF([test "x$enable_api_doc" = "xyes"], [
 
 AC_CONFIG_FILES([
        Makefile
-       types/Makefile
        common/Makefile
        compat/Makefile
-       formats/Makefile
-       formats/ctf/Makefile
-       formats/ctf/types/Makefile
-       formats/ctf-text/Makefile
-       formats/ctf-text/types/Makefile
-       formats/ctf-metadata/Makefile
-       formats/bt-dummy/Makefile
-       formats/lttng-live/Makefile
-       formats/ctf/metadata/Makefile
-       formats/ctf/writer/Makefile
-       formats/ctf/ir/Makefile
        converter/Makefile
        doc/Makefile
-        doc/api/Makefile
-        doc/api/Doxyfile
+       doc/api/Makefile
+       doc/api/Doxyfile
        doc/bindings/Makefile
        doc/bindings/python/Makefile
        doc/images/Makefile
@@ -470,6 +458,8 @@ AC_CONFIG_FILES([
        lib/plugin/Makefile
         lib/component/Makefile
        lib/component/notification/Makefile
+       lib/ctf-ir/Makefile
+       lib/ctf-writer/Makefile
        include/Makefile
        bindings/Makefile
        bindings/python/Makefile
@@ -521,7 +511,6 @@ AC_CONFIG_FILES([tests/bin/intersection/test_intersection], [chmod +x tests/bin/
 AC_CONFIG_FILES([tests/bin/intersection/bt_python_helper.py])
 AC_CONFIG_FILES([tests/lib/writer/bt_python_helper.py])
 AC_CONFIG_FILES([tests/bin/test_packet_seq_num], [chmod +x tests/bin/test_packet_seq_num])
-AC_CONFIG_FILES([tests/bin/test_formats], [chmod +x tests/bin/test_formats])
 
 AS_IF([test "x$enable_python" = "xyes"], [
        AC_CONFIG_FILES(
index 5e88fb0ba70039962cf6dc0703b511b24cb00c8f..c1fce34ec5f8aa484e2ba1ab5f6e6e4b2417f509 100644 (file)
@@ -3,7 +3,7 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include \
                -DCONFIG_IN_TREE_PLUGIN_PATH=\"$(PLUGINS_PATH)/ctf:$(PLUGINS_PATH)/text:$(PLUGINS_PATH)/muxer:$(PLUGINS_PATH)/writer:$(PLUGINS_PATH)/utils\"
 AM_LDFLAGS = -lpopt
 
-bin_PROGRAMS = babeltrace.bin babeltrace-log
+bin_PROGRAMS = babeltrace.bin
 noinst_PROGRAMS = babeltrace
 #check_PROGRAMS = babeltrace
 
@@ -22,12 +22,7 @@ babeltrace_bin_SOURCES = \
 babeltrace_bin_LDFLAGS = -Wl, $(LD_NO_AS_NEEDED), -export-dynamic
 babeltrace_bin_LDADD = \
        $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
        $(top_builddir)/compat/libcompat.la \
-       $(top_builddir)/formats/ctf-text/libbabeltrace-ctf-text.la \
-       $(top_builddir)/formats/ctf-metadata/libbabeltrace-ctf-metadata.la \
-       $(top_builddir)/formats/bt-dummy/libbabeltrace-dummy.la \
-       $(top_builddir)/formats/lttng-live/libbabeltrace-lttng-live.la \
        $(top_builddir)/common/libbabeltrace-common.la
 
 if ENABLE_DEBUG_INFO
@@ -38,22 +33,7 @@ if BUILT_IN_PLUGINS
 babeltrace_bin_LDFLAGS += -Wl,--whole-archive,$(top_builddir)/plugins/ctf/.libs/libbabeltrace-plugin-ctf.a,$(top_builddir)/plugins/text/.libs/libbabeltrace-plugin-ctf-text.a,$(top_builddir)/plugins/muxer/.libs/libbabeltrace-plugin-muxer.a,$(top_builddir)/plugins/writer/.libs/libbabeltrace-plugin-ctf-writer.a,--no-whole-archive
 endif
 
-babeltrace_log_SOURCES = babeltrace-log.c
-
-babeltrace_log_LDADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
-       $(top_builddir)/compat/libcompat.la
-
-if BABELTRACE_BUILD_WITH_LIBUUID
-babeltrace_log_LDADD += -luuid
-endif
-if BABELTRACE_BUILD_WITH_LIBC_UUID
-babeltrace_log_LDADD += -lc
-endif
-
 if BABELTRACE_BUILD_WITH_MINGW
-babeltrace_log_LDADD += -lrpcrt4 -lintl -liconv -lole32 -lpopt -lpthread
 babeltrace_bin_LDADD += -lrpcrt4 -lintl -liconv -lole32 -lpopt -lpthread
 endif
 
index 5cbd51ff18e4cb86334b495350549bfe30a5ec31..cb8492f2acfd9630f1b5d1feb8c8d5653ac2f075 100644 (file)
 #include <babeltrace/ref.h>
 #include <babeltrace/values.h>
 #include <stdlib.h>
-#include <babeltrace/ctf-ir/metadata.h>        /* for clocks */
 #include <popt.h>
 #include <string.h>
 #include <stdio.h>
 #include <glib.h>
+#include <inttypes.h>
 #include "babeltrace-cfg.h"
 #include "babeltrace-cfg-connect.h"
 #include "default-cfg.h"
diff --git a/ctf-reader-proto/Makefile.am b/ctf-reader-proto/Makefile.am
deleted file mode 100644 (file)
index 567114e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-SUBDIRS = metadata-parsing ctf-notif-iter ctf-btr
-
-AM_CFLAGS = $(PACKAGE_CFLAGS)
-AM_CPPFLAGS =  -I$(top_srcdir)/include
-
-noinst_PROGRAMS = protorectoral
-
-protorectoral_SOURCES = \
-               protorectoral.c \
-               ctf-fs.c \
-               ctf-fs-file.c \
-               ctf-fs-metadata.c \
-               ctf-fs-data-stream.c
-protorectoral_LDADD = \
-               metadata-parsing/libctf-parser.la \
-               metadata-parsing/libctf-ast.la \
-               ctf-notif-iter/libctf-notif-iter.la \
-               ctf-btr/libctf-btr.la \
-               $(top_builddir)/lib/libbabeltrace.la \
-               $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
diff --git a/ctf-reader-proto/ctf-fs.c b/ctf-reader-proto/ctf-fs.c
deleted file mode 100644 (file)
index 5bb022d..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <glib.h>
-
-#define PRINT_ERR_STREAM       ctf_fs->error_fp
-#define PRINT_PREFIX           "ctf-fs"
-#include "print.h"
-
-#include "ctf-fs.h"
-#include "ctf-fs-file.h"
-#include "ctf-fs-metadata.h"
-#include "ctf-fs-data-stream.h"
-
-bool ctf_fs_debug = false;
-
-static void ctf_fs_destroy(struct ctf_fs *ctf_fs)
-{
-       if (!ctf_fs) {
-               return;
-       }
-
-       if (ctf_fs->trace_path) {
-               g_string_free(ctf_fs->trace_path, TRUE);
-       }
-
-       ctf_fs_metadata_deinit(&ctf_fs->metadata);
-       ctf_fs_data_stream_deinit(&ctf_fs->data_stream);
-       g_free(ctf_fs);
-}
-
-static struct ctf_fs *ctf_fs_create(const char *trace_path)
-{
-       struct ctf_fs *ctf_fs = g_new0(struct ctf_fs, 1);
-
-       if (!ctf_fs) {
-               goto error;
-       }
-
-       ctf_fs->trace_path = g_string_new(trace_path);
-       if (!ctf_fs->trace_path) {
-               goto error;
-       }
-
-       ctf_fs->error_fp = stderr;
-       ctf_fs->page_size = getpagesize();
-
-       if (ctf_fs_metadata_init(&ctf_fs->metadata)) {
-               PERR("Cannot initialize metadata structure\n");
-               goto error;
-       }
-
-       if (ctf_fs_data_stream_init(ctf_fs, &ctf_fs->data_stream)) {
-               PERR("Cannot initialize data stream structure\n");
-               goto error;
-       }
-
-       goto end;
-
-error:
-       ctf_fs_destroy(ctf_fs);
-       ctf_fs = NULL;
-
-end:
-       return ctf_fs;
-}
-
-void ctf_fs_init(void)
-{
-       if (g_strcmp0(getenv("CTF_FS_DEBUG"), "1") == 0) {
-               ctf_fs_debug = true;
-       }
-}
-
-void ctf_fs_test(const char *trace_path)
-{
-       ctf_fs_init();
-
-       struct ctf_fs *ctf_fs = ctf_fs_create(trace_path);
-       struct bt_ctf_notif_iter_notif *notification;
-
-       if (!ctf_fs) {
-               return;
-       }
-
-       /* Set trace from metadata file */
-       ctf_fs_metadata_set_trace(ctf_fs);
-       ctf_fs_data_stream_open_streams(ctf_fs);
-
-       while (true) {
-               int ret = ctf_fs_data_stream_get_next_notification(ctf_fs, &notification);
-               assert(ret == 0);
-
-               if (!notification) {
-                       goto end;
-               }
-
-               switch (notification->type) {
-               case BT_CTF_NOTIF_ITER_NOTIF_NEW_PACKET:
-               {
-                       struct bt_ctf_notif_iter_notif_new_packet *notif =
-                               (struct bt_ctf_notif_iter_notif_new_packet *) notification;
-                       break;
-               }
-               case BT_CTF_NOTIF_ITER_NOTIF_EVENT:
-               {
-                       struct bt_ctf_notif_iter_notif_event *notif =
-                               (struct bt_ctf_notif_iter_notif_event *) notification;
-                       break;
-               }
-               case BT_CTF_NOTIF_ITER_NOTIF_END_OF_PACKET:
-               {
-                       struct bt_ctf_notif_iter_notif_end_of_packet *notif =
-                               (struct bt_ctf_notif_iter_notif_end_of_packet *) notification;
-                       break;
-               }
-               default:
-                       break;
-               }
-
-               bt_ctf_notif_iter_notif_destroy(notification);
-       }
-
-end:
-       ctf_fs_destroy(ctf_fs);
-}
diff --git a/ctf-reader-proto/ctf-fs.h b/ctf-reader-proto/ctf-fs.h
deleted file mode 100644 (file)
index 3206e9e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef CTF_FS_H
-#define CTF_FS_H
-
-/*
- * 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 <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <glib.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf-ir/trace.h>
-
-#include "ctf-fs-metadata.h"
-#include "ctf-fs-data-stream.h"
-
-extern bool ctf_fs_debug;
-
-struct ctf_fs {
-       GString *trace_path;
-       FILE *error_fp;
-       int page_size;
-       struct ctf_fs_metadata metadata;
-       struct ctf_fs_data_stream data_stream;
-};
-
-void ctf_fs_test(const char *trace_path);
-
-#endif /* CTF_FS_H */
diff --git a/ctf-reader-proto/ctf-notif-iter.gdb b/ctf-reader-proto/ctf-notif-iter.gdb
deleted file mode 100644 (file)
index b536943..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-define ctf-notif-iter-show-stack
-    if (stack_empty($arg0))
-        printf "stack is empty!\n"
-    else
-        set $stack_size = stack_size($arg0)
-        set $stack_at = (int) ($stack_size - 1)
-        printf "%3s    %10s    %3s\n", "pos", "base addr", "idx"
-
-        while ($stack_at >= 0)
-            set $stack_entry = (struct stack_entry *) g_ptr_array_index($arg0->entries, $stack_at)
-
-            if ($stack_at == $stack_size - 1)
-                printf "%3d    %10p    %3d  <-- top\n", $stack_at, \
-                    $stack_entry->base, $stack_entry->index
-            else
-                printf "%3d    %10p    %3d\n", $stack_at, \
-                    $stack_entry->base, $stack_entry->index
-            end
-            set $stack_at = $stack_at - 1
-        end
-    end
-end
diff --git a/ctf-reader-proto/protorectoral.c b/ctf-reader-proto/protorectoral.c
deleted file mode 100644 (file)
index 2844ee8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-
-#include "ctf-fs.h"
-
-int main(int main, char *argv[])
-{
-       ctf_fs_test(argv[1]);
-
-       return 0;
-}
diff --git a/formats/Makefile.am b/formats/Makefile.am
deleted file mode 100644 (file)
index f36744a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-SUBDIRS = . ctf ctf-text ctf-metadata bt-dummy lttng-live
diff --git a/formats/bt-dummy/Makefile.am b/formats/bt-dummy/Makefile.am
deleted file mode 100644 (file)
index e8ae4de..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-lib_LTLIBRARIES = libbabeltrace-dummy.la
-
-libbabeltrace_dummy_la_SOURCES = \
-       bt-dummy.c
-
-# Request that the linker keeps all static libraries objects.
-libbabeltrace_dummy_la_LDFLAGS = \
-       $(LD_NO_AS_NEEDED) -version-info $(BABELTRACE_LIBRARY_VERSION)
-
-libbabeltrace_dummy_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
diff --git a/formats/bt-dummy/bt-dummy.c b/formats/bt-dummy/bt-dummy.c
deleted file mode 100644 (file)
index fd10cca..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * BabelTrace - Dummy Output
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <babeltrace/format.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-void bt_dummy_hook(void)
-{
-       /*
-        * Dummy function to prevent the linker from discarding this format as
-        * "unused" in static builds.
-        */
-}
-
-static
-int bt_dummy_write_event(struct bt_stream_pos *ppos, struct ctf_stream_definition *stream)
-{
-       return 0;
-}
-
-static
-struct bt_trace_descriptor *bt_dummy_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_text_stream_pos *pos;
-
-       pos = g_new0(struct ctf_text_stream_pos, 1);
-       pos->parent.rw_table = NULL;
-       pos->parent.event_cb = bt_dummy_write_event;
-       pos->parent.trace = &pos->trace_descriptor;
-       return &pos->trace_descriptor;
-}
-
-static
-int bt_dummy_close_trace(struct bt_trace_descriptor *td)
-{
-       struct ctf_text_stream_pos *pos =
-               container_of(td, struct ctf_text_stream_pos,
-                       trace_descriptor);
-       free(pos);
-       return 0;
-}
-
-static
-struct bt_format bt_dummy_format = {
-       .open_trace = bt_dummy_open_trace,
-       .close_trace = bt_dummy_close_trace,
-};
-
-static
-void __attribute__((constructor)) bt_dummy_init(void)
-{
-       int ret;
-
-       bt_dummy_format.name = g_quark_from_string("dummy");
-       ret = bt_register_format(&bt_dummy_format);
-       assert(!ret);
-}
-
-static
-void __attribute__((destructor)) bt_dummy_exit(void)
-{
-       bt_unregister_format(&bt_dummy_format);
-}
diff --git a/formats/ctf-metadata/Makefile.am b/formats/ctf-metadata/Makefile.am
deleted file mode 100644 (file)
index 252d9af..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-lib_LTLIBRARIES = libbabeltrace-ctf-metadata.la
-
-libbabeltrace_ctf_metadata_la_SOURCES = \
-       ctf-metadata.c
-
-# Request that the linker keeps all static libraries objects.
-libbabeltrace_ctf_metadata_la_LDFLAGS = \
-       $(LD_NO_AS_NEEDED) -version-info $(BABELTRACE_LIBRARY_VERSION)
-
-libbabeltrace_ctf_metadata_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
diff --git a/formats/ctf-metadata/ctf-metadata.c b/formats/ctf-metadata/ctf-metadata.c
deleted file mode 100644 (file)
index a6397ec..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * BabelTrace - Common Trace Format (CTF)
- *
- * CTF Metadata Dump.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <babeltrace/ctf-text/types.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-static
-struct bt_trace_descriptor *ctf_metadata_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp);
-static
-int ctf_metadata_close_trace(struct bt_trace_descriptor *descriptor);
-
-static
-struct bt_format ctf_metadata_format = {
-       .open_trace = ctf_metadata_open_trace,
-       .close_trace = ctf_metadata_close_trace,
-};
-
-void bt_ctf_metadata_hook(void)
-{
-       /*
-        * Dummy function to prevent the linker from discarding this format as
-        * "unused" in static builds.
-        */
-}
-
-static
-int ctf_metadata_trace_pre_handler(struct bt_stream_pos *ppos,
-                       struct bt_trace_descriptor *td)
-{
-       struct ctf_text_stream_pos *pos =
-               container_of(ppos, struct ctf_text_stream_pos, parent);
-       struct ctf_trace *trace;
-
-       trace = container_of(td, struct ctf_trace, parent);
-       if (!trace->metadata_string)
-               return -EINVAL;
-       if (trace->metadata_packetized) {
-               fprintf(pos->fp, "/* CTF %u.%u */\n",
-                       BT_CTF_MAJOR, BT_CTF_MINOR);
-       }
-       fprintf(pos->fp, "%s", trace->metadata_string);
-       return 0;
-}
-
-static
-struct bt_trace_descriptor *ctf_metadata_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_text_stream_pos *pos;
-       FILE *fp;
-
-       pos = g_new0(struct ctf_text_stream_pos, 1);
-
-       pos->last_real_timestamp = -1ULL;
-       pos->last_cycles_timestamp = -1ULL;
-       switch (flags & O_ACCMODE) {
-       case O_RDWR:
-               if (!path)
-                       fp = stdout;
-               else
-                       fp = fopen(path, "w");
-               if (!fp)
-                       goto error;
-               pos->fp = fp;
-               pos->parent.pre_trace_cb = ctf_metadata_trace_pre_handler;
-               pos->parent.trace = &pos->trace_descriptor;
-               pos->print_names = 0;
-               break;
-       case O_RDONLY:
-       default:
-               fprintf(stderr, "[error] Incorrect open flags.\n");
-               goto error;
-       }
-
-       return &pos->trace_descriptor;
-error:
-       g_free(pos);
-       return NULL;
-}
-
-static
-int ctf_metadata_close_trace(struct bt_trace_descriptor *td)
-{
-       int ret;
-       struct ctf_text_stream_pos *pos =
-               container_of(td, struct ctf_text_stream_pos, trace_descriptor);
-       if (pos->fp != stdout) {
-               ret = fclose(pos->fp);
-               if (ret) {
-                       perror("Error on fclose");
-                       return -1;
-               }
-       }
-       g_free(pos);
-       return 0;
-}
-
-static
-void __attribute__((constructor)) ctf_metadata_init(void)
-{
-       int ret;
-
-       ctf_metadata_format.name = g_quark_from_string("ctf-metadata");
-       ret = bt_register_format(&ctf_metadata_format);
-       assert(!ret);
-}
-
-static
-void __attribute__((destructor)) ctf_metadata_exit(void)
-{
-       bt_unregister_format(&ctf_metadata_format);
-}
diff --git a/formats/ctf-text/Makefile.am b/formats/ctf-text/Makefile.am
deleted file mode 100644 (file)
index f913de7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-SUBDIRS = types .
-
-lib_LTLIBRARIES = libbabeltrace-ctf-text.la
-
-libbabeltrace_ctf_text_la_SOURCES = \
-       ctf-text.c
-
-libbabeltrace_ctf_text_la_LDFLAGS = \
-       $(LD_NO_AS_NEEDED) -version-info $(BABELTRACE_LIBRARY_VERSION) \
-       types/libctf-text-types.la
-
-libbabeltrace_ctf_text_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
-
-if ENABLE_DEBUG_INFO
-libbabeltrace_ctf_text_la_LIBADD += $(top_builddir)/lib/libdebug-info.la
-endif
diff --git a/formats/ctf-text/ctf-text.c b/formats/ctf-text/ctf-text.c
deleted file mode 100644 (file)
index f4cdf10..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * BabelTrace - Common Trace Format (CTF)
- *
- * CTF Text Format registration.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <babeltrace/ctf-text/types.h>
-#include <babeltrace/ctf/metadata.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/trace-debug-info.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#define NSEC_PER_SEC 1000000000LL
-
-int opt_all_field_names,
-       opt_scope_field_names,
-       opt_header_field_names,
-       opt_context_field_names,
-       opt_payload_field_names,
-       opt_all_fields,
-       opt_trace_field,
-       opt_trace_domain_field,
-       opt_trace_procname_field,
-       opt_trace_vpid_field,
-       opt_trace_hostname_field,
-       opt_trace_default_fields = 1,
-       opt_loglevel_field,
-       opt_emf_field,
-       opt_callsite_field,
-       opt_delta_field = 1,
-       opt_debug_info_full_path;
-
-enum field_item {
-       ITEM_SCOPE,
-       ITEM_HEADER,
-       ITEM_CONTEXT,
-       ITEM_PAYLOAD,
-};
-
-enum bt_loglevel {
-        BT_LOGLEVEL_EMERG                  = 0,
-        BT_LOGLEVEL_ALERT                  = 1,
-        BT_LOGLEVEL_CRIT                   = 2,
-        BT_LOGLEVEL_ERR                    = 3,
-        BT_LOGLEVEL_WARNING                = 4,
-        BT_LOGLEVEL_NOTICE                 = 5,
-        BT_LOGLEVEL_INFO                   = 6,
-        BT_LOGLEVEL_DEBUG_SYSTEM           = 7,
-        BT_LOGLEVEL_DEBUG_PROGRAM          = 8,
-        BT_LOGLEVEL_DEBUG_PROCESS          = 9,
-        BT_LOGLEVEL_DEBUG_MODULE           = 10,
-        BT_LOGLEVEL_DEBUG_UNIT             = 11,
-        BT_LOGLEVEL_DEBUG_FUNCTION         = 12,
-        BT_LOGLEVEL_DEBUG_LINE             = 13,
-        BT_LOGLEVEL_DEBUG                  = 14,
-};
-
-static
-struct bt_trace_descriptor *ctf_text_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp);
-static
-int ctf_text_close_trace(struct bt_trace_descriptor *descriptor);
-
-static
-rw_dispatch write_dispatch_table[] = {
-       [ CTF_TYPE_INTEGER ] = ctf_text_integer_write,
-       [ CTF_TYPE_FLOAT ] = ctf_text_float_write,
-       [ CTF_TYPE_ENUM ] = ctf_text_enum_write,
-       [ CTF_TYPE_STRING ] = ctf_text_string_write,
-       [ CTF_TYPE_STRUCT ] = ctf_text_struct_write,
-       [ CTF_TYPE_VARIANT ] = ctf_text_variant_write,
-       [ CTF_TYPE_ARRAY ] = ctf_text_array_write,
-       [ CTF_TYPE_SEQUENCE ] = ctf_text_sequence_write,
-};
-
-static
-struct bt_format ctf_text_format = {
-       .open_trace = ctf_text_open_trace,
-       .close_trace = ctf_text_close_trace,
-};
-
-static GQuark Q_STREAM_PACKET_CONTEXT_TIMESTAMP_BEGIN,
-       Q_STREAM_PACKET_CONTEXT_TIMESTAMP_END,
-       Q_STREAM_PACKET_CONTEXT_EVENTS_DISCARDED,
-       Q_STREAM_PACKET_CONTEXT_CONTENT_SIZE,
-       Q_STREAM_PACKET_CONTEXT_PACKET_SIZE,
-       Q_STREAM_PACKET_CONTEXT_PACKET_SEQ_NUM;
-
-static
-void __attribute__((constructor)) init_quarks(void)
-{
-       Q_STREAM_PACKET_CONTEXT_TIMESTAMP_BEGIN = g_quark_from_string("stream.packet.context.timestamp_begin");
-       Q_STREAM_PACKET_CONTEXT_TIMESTAMP_END = g_quark_from_string("stream.packet.context.timestamp_end");
-       Q_STREAM_PACKET_CONTEXT_EVENTS_DISCARDED = g_quark_from_string("stream.packet.context.events_discarded");
-       Q_STREAM_PACKET_CONTEXT_CONTENT_SIZE = g_quark_from_string("stream.packet.context.content_size");
-       Q_STREAM_PACKET_CONTEXT_PACKET_SIZE = g_quark_from_string("stream.packet.context.packet_size");
-       Q_STREAM_PACKET_CONTEXT_PACKET_SEQ_NUM = g_quark_from_string("stream.packet.context.packet_seq_num");
-}
-
-static
-struct ctf_callsite_dups *ctf_trace_callsite_lookup(struct ctf_trace *trace,
-                       GQuark callsite_name)
-{
-       return g_hash_table_lookup(trace->callsites,
-                       GUINT_TO_POINTER(callsite_name));
-}
-
-void bt_ctf_text_hook(void)
-{
-       /*
-        * Dummy function to prevent the linker from discarding this format as
-        * "unused" in static builds.
-        */
-}
-
-int print_field(struct bt_definition *definition)
-{
-       /* Print all fields in verbose mode */
-       if (babeltrace_verbose)
-               return 1;
-
-       /* Filter out part of the packet context */
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_TIMESTAMP_BEGIN)
-               return 0;
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_TIMESTAMP_END)
-               return 0;
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_EVENTS_DISCARDED)
-               return 0;
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_CONTENT_SIZE)
-               return 0;
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_PACKET_SIZE)
-               return 0;
-       if (definition->path == Q_STREAM_PACKET_CONTEXT_PACKET_SEQ_NUM)
-               return 0;
-
-       return 1;
-}
-
-static
-void set_field_names_print(struct ctf_text_stream_pos *pos, enum field_item item)
-{
-       switch (item) {
-       case ITEM_SCOPE:
-               if (opt_all_field_names || opt_scope_field_names)
-                       pos->print_names = 1;
-               else
-                       pos->print_names = 0;
-               break;
-       case ITEM_HEADER:
-               if (opt_all_field_names || opt_header_field_names)
-                       pos->print_names = 1;
-               else
-                       pos->print_names = 0;
-               break;
-       case ITEM_CONTEXT:
-               if (opt_all_field_names || opt_context_field_names)
-                       pos->print_names = 1;
-               else
-                       pos->print_names = 0;
-               break;
-       case ITEM_PAYLOAD:
-               if (opt_all_field_names || opt_payload_field_names)
-                       pos->print_names = 1;
-               else
-                       pos->print_names = 0;
-
-               break;
-       default:
-               assert(0);
-       }
-}
-
-static
-const char *print_loglevel(int value)
-{
-       switch (value) {
-       case -1:
-               return "";
-       case BT_LOGLEVEL_EMERG:
-               return "TRACE_EMERG";
-       case BT_LOGLEVEL_ALERT:
-               return "TRACE_ALERT";
-       case BT_LOGLEVEL_CRIT:
-               return "TRACE_CRIT";
-       case BT_LOGLEVEL_ERR:
-               return "TRACE_ERR";
-       case BT_LOGLEVEL_WARNING:
-               return "TRACE_WARNING";
-       case BT_LOGLEVEL_NOTICE:
-               return "TRACE_NOTICE";
-       case BT_LOGLEVEL_INFO:
-               return "TRACE_INFO";
-       case BT_LOGLEVEL_DEBUG_SYSTEM:
-               return "TRACE_DEBUG_SYSTEM";
-       case BT_LOGLEVEL_DEBUG_PROGRAM:
-               return "TRACE_DEBUG_PROGRAM";
-       case BT_LOGLEVEL_DEBUG_PROCESS:
-               return "TRACE_DEBUG_PROCESS";
-       case BT_LOGLEVEL_DEBUG_MODULE:
-               return "TRACE_DEBUG_MODULE";
-       case BT_LOGLEVEL_DEBUG_UNIT:
-               return "TRACE_DEBUG_UNIT";
-       case BT_LOGLEVEL_DEBUG_FUNCTION:
-               return "TRACE_DEBUG_FUNCTION";
-       case BT_LOGLEVEL_DEBUG_LINE:
-               return "TRACE_DEBUG_LINE";
-       case BT_LOGLEVEL_DEBUG:
-               return "TRACE_DEBUG";
-       default:
-               return "<<UNKNOWN>>";
-       }
-}
-
-static
-int ctf_text_write_event(struct bt_stream_pos *ppos, struct ctf_stream_definition *stream)
-{
-       struct ctf_text_stream_pos *pos =
-               container_of(ppos, struct ctf_text_stream_pos, parent);
-       struct ctf_stream_declaration *stream_class = stream->stream_class;
-       int field_nr_saved;
-       struct ctf_event_declaration *event_class;
-       struct ctf_event_definition *event;
-       uint64_t id;
-       int ret;
-       int dom_print = 0;
-
-       id = stream->event_id;
-
-       if (id >= stream_class->events_by_id->len) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id);
-               return -EINVAL;
-       }
-       event = g_ptr_array_index(stream->events_by_id, id);
-       if (!event) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
-               return -EINVAL;
-       }
-       event_class = g_ptr_array_index(stream_class->events_by_id, id);
-       if (!event_class) {
-               fprintf(stderr, "[error] Event class id %" PRIu64 " is unknown.\n", id);
-               return -EINVAL;
-       }
-
-       handle_debug_info_event(stream_class, event);
-
-       if (stream->has_timestamp) {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names)
-                       fprintf(pos->fp, "timestamp = ");
-               else
-                       fprintf(pos->fp, "[");
-               if (opt_clock_cycles) {
-                       ctf_print_timestamp(pos->fp, stream, stream->cycles_timestamp);
-               } else {
-                       ctf_print_timestamp(pos->fp, stream, stream->real_timestamp);
-               }
-               if (!pos->print_names)
-                       fprintf(pos->fp, "]");
-
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               else
-                       fprintf(pos->fp, " ");
-       }
-       if (opt_delta_field && stream->has_timestamp) {
-               uint64_t delta, delta_sec, delta_nsec;
-
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names)
-                       fprintf(pos->fp, "delta = ");
-               else
-                       fprintf(pos->fp, "(");
-               if (pos->last_real_timestamp != -1ULL) {
-                       delta = stream->real_timestamp - pos->last_real_timestamp;
-                       delta_sec = delta / NSEC_PER_SEC;
-                       delta_nsec = delta % NSEC_PER_SEC;
-                       fprintf(pos->fp, "+%" PRIu64 ".%09" PRIu64,
-                               delta_sec, delta_nsec);
-               } else {
-                       fprintf(pos->fp, "+?.?????????");
-               }
-               if (!pos->print_names)
-                       fprintf(pos->fp, ")");
-
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               else
-                       fprintf(pos->fp, " ");
-               pos->last_real_timestamp = stream->real_timestamp;
-               pos->last_cycles_timestamp = stream->cycles_timestamp;
-       }
-
-       if ((opt_trace_field || opt_all_fields) && stream_class->trace->parent.path[0] != '\0') {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "trace = ");
-               }
-               fprintf(pos->fp, "%s", stream_class->trace->parent.path);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               else
-                       fprintf(pos->fp, " ");
-       }
-       if ((opt_trace_hostname_field || opt_all_fields || opt_trace_default_fields)
-                       && stream_class->trace->env.hostname[0] != '\0') {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "trace:hostname = ");
-               }
-               fprintf(pos->fp, "%s", stream_class->trace->env.hostname);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_trace_domain_field || opt_all_fields) && stream_class->trace->env.domain[0] != '\0') {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "trace:domain = ");
-               } else if (dom_print) {
-                       fprintf(pos->fp, ":");
-               }
-               fprintf(pos->fp, "%s", stream_class->trace->env.domain);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_trace_procname_field || opt_all_fields || opt_trace_default_fields)
-                       && stream_class->trace->env.procname[0] != '\0') {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "trace:procname = ");
-               } else if (dom_print) {
-                       fprintf(pos->fp, ":");
-               }
-               fprintf(pos->fp, "%s", stream_class->trace->env.procname);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_trace_vpid_field || opt_all_fields || opt_trace_default_fields)
-                       && stream_class->trace->env.vpid != -1) {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "trace:vpid = ");
-               } else if (dom_print) {
-                       fprintf(pos->fp, ":");
-               }
-               fprintf(pos->fp, "%d", stream_class->trace->env.vpid);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_loglevel_field || opt_all_fields) && event_class->loglevel != -1) {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "loglevel = ");
-               } else if (dom_print) {
-                       fprintf(pos->fp, ":");
-               }
-               fprintf(pos->fp, "%s (%d)",
-                       print_loglevel(event_class->loglevel),
-                       event_class->loglevel);
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_emf_field || opt_all_fields) && event_class->model_emf_uri) {
-               set_field_names_print(pos, ITEM_HEADER);
-               if (pos->print_names) {
-                       fprintf(pos->fp, "model.emf.uri = ");
-               } else if (dom_print) {
-                       fprintf(pos->fp, ":");
-               }
-               fprintf(pos->fp, "\"%s\"",
-                       g_quark_to_string(event_class->model_emf_uri));
-               if (pos->print_names)
-                       fprintf(pos->fp, ", ");
-               dom_print = 1;
-       }
-       if ((opt_callsite_field || opt_all_fields)) {
-               struct ctf_callsite_dups *cs_dups;
-               struct ctf_callsite *callsite;
-
-               cs_dups = ctf_trace_callsite_lookup(stream_class->trace,
-                               event_class->name);
-               if (cs_dups) {
-                       int i = 0;
-
-                       set_field_names_print(pos, ITEM_HEADER);
-                       if (pos->print_names) {
-                               fprintf(pos->fp, "callsite = ");
-                       } else if (dom_print) {
-                               fprintf(pos->fp, ":");
-                       }
-                       fprintf(pos->fp, "[");
-                       bt_list_for_each_entry(callsite, &cs_dups->head, node) {
-                               if (i != 0)
-                                       fprintf(pos->fp, ",");
-                               if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) {
-                                       fprintf(pos->fp, "%s@0x%" PRIx64 ":%s:%" PRIu64 "",
-                                               callsite->func, callsite->ip, callsite->file,
-                                               callsite->line);
-                               } else {
-                                       fprintf(pos->fp, "%s:%s:%" PRIu64 "",
-                                               callsite->func, callsite->file,
-                                               callsite->line);
-                               }
-                               i++;
-                       }
-                       fprintf(pos->fp, "]");
-                       if (pos->print_names)
-                               fprintf(pos->fp, ", ");
-                       dom_print = 1;
-               }
-       }
-       if (dom_print && !pos->print_names)
-               fprintf(pos->fp, " ");
-       set_field_names_print(pos, ITEM_HEADER);
-       if (pos->print_names)
-               fprintf(pos->fp, "name = ");
-       fprintf(pos->fp, "%s", g_quark_to_string(event_class->name));
-       if (pos->print_names)
-               pos->field_nr++;
-       else
-               fprintf(pos->fp, ":");
-
-       /* print cpuid field from packet context */
-       if (stream->stream_packet_context) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               set_field_names_print(pos, ITEM_SCOPE);
-               if (pos->print_names)
-                       fprintf(pos->fp, " stream.packet.context =");
-               field_nr_saved = pos->field_nr;
-               pos->field_nr = 0;
-               set_field_names_print(pos, ITEM_CONTEXT);
-               ret = generic_rw(ppos, &stream->stream_packet_context->p);
-               if (ret)
-                       goto error;
-               pos->field_nr = field_nr_saved;
-       }
-
-       /* Only show the event header in verbose mode */
-       if (babeltrace_verbose && stream->stream_event_header) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               set_field_names_print(pos, ITEM_SCOPE);
-               if (pos->print_names)
-                       fprintf(pos->fp, " stream.event.header =");
-               field_nr_saved = pos->field_nr;
-               pos->field_nr = 0;
-               set_field_names_print(pos, ITEM_CONTEXT);
-               ret = generic_rw(ppos, &stream->stream_event_header->p);
-               if (ret)
-                       goto error;
-               pos->field_nr = field_nr_saved;
-       }
-
-       /* print stream-declared event context */
-       if (stream->stream_event_context) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               set_field_names_print(pos, ITEM_SCOPE);
-               if (pos->print_names)
-                       fprintf(pos->fp, " stream.event.context =");
-               field_nr_saved = pos->field_nr;
-               pos->field_nr = 0;
-               set_field_names_print(pos, ITEM_CONTEXT);
-               ret = generic_rw(ppos, &stream->stream_event_context->p);
-               if (ret)
-                       goto error;
-               pos->field_nr = field_nr_saved;
-       }
-
-       /* print event-declared event context */
-       if (event->event_context) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               set_field_names_print(pos, ITEM_SCOPE);
-               if (pos->print_names)
-                       fprintf(pos->fp, " event.context =");
-               field_nr_saved = pos->field_nr;
-               pos->field_nr = 0;
-               set_field_names_print(pos, ITEM_CONTEXT);
-               ret = generic_rw(ppos, &event->event_context->p);
-               if (ret)
-                       goto error;
-               pos->field_nr = field_nr_saved;
-       }
-
-       /* Read and print event payload */
-       if (event->event_fields) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               set_field_names_print(pos, ITEM_SCOPE);
-               if (pos->print_names)
-                       fprintf(pos->fp, " event.fields =");
-               field_nr_saved = pos->field_nr;
-               pos->field_nr = 0;
-               set_field_names_print(pos, ITEM_PAYLOAD);
-               ret = generic_rw(ppos, &event->event_fields->p);
-               if (ret)
-                       goto error;
-               pos->field_nr = field_nr_saved;
-       }
-       /* newline */
-       fprintf(pos->fp, "\n");
-       pos->field_nr = 0;
-
-       return 0;
-
-error:
-       fprintf(stderr, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
-       return ret;
-}
-
-static
-struct bt_trace_descriptor *ctf_text_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_text_stream_pos *pos;
-       FILE *fp;
-
-       pos = g_new0(struct ctf_text_stream_pos, 1);
-       if (!pos) {
-               goto error;
-       }
-       init_trace_descriptor(&pos->trace_descriptor);
-
-       pos->last_real_timestamp = -1ULL;
-       pos->last_cycles_timestamp = -1ULL;
-       switch (flags & O_ACCMODE) {
-       case O_RDWR:
-               if (!path)
-                       fp = stdout;
-               else
-                       fp = fopen(path, "w");
-               if (!fp)
-                       goto error;
-               pos->fp = fp;
-               pos->parent.rw_table = write_dispatch_table;
-               pos->parent.event_cb = ctf_text_write_event;
-               pos->parent.trace = &pos->trace_descriptor;
-               pos->print_names = 0;
-               babeltrace_ctf_console_output++;
-               break;
-       case O_RDONLY:
-       default:
-               fprintf(stderr, "[error] Incorrect open flags.\n");
-               goto error;
-       }
-
-       return &pos->trace_descriptor;
-error:
-       g_free(pos);
-       return NULL;
-}
-
-static
-int ctf_text_close_trace(struct bt_trace_descriptor *td)
-{
-       int ret;
-       struct ctf_text_stream_pos *pos =
-               container_of(td, struct ctf_text_stream_pos, trace_descriptor);
-
-       babeltrace_ctf_console_output--;
-       if (pos->fp != stdout) {
-               ret = fclose(pos->fp);
-               if (ret) {
-                       perror("Error on fclose");
-                       return -1;
-               }
-       }
-       g_free(pos);
-       return 0;
-}
-
-static
-void __attribute__((constructor)) ctf_text_init(void)
-{
-       int ret;
-
-       ctf_text_format.name = g_quark_from_string("text");
-       ret = bt_register_format(&ctf_text_format);
-       assert(!ret);
-}
-
-static
-void __attribute__((destructor)) ctf_text_exit(void)
-{
-       bt_unregister_format(&ctf_text_format);
-}
diff --git a/formats/ctf-text/types/Makefile.am b/formats/ctf-text/types/Makefile.am
deleted file mode 100644 (file)
index 71796f9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libctf-text-types.la
-
-libctf_text_types_la_SOURCES = \
-       array.c \
-       enum.c \
-       float.c \
-       integer.c \
-       sequence.c \
-       string.c \
-       struct.c \
-       variant.c
-
-libctf_text_types_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
diff --git a/formats/ctf-text/types/array.c b/formats/ctf-text/types/array.c
deleted file mode 100644 (file)
index ff2ca5e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Common Trace Format
- *
- * Array format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-
-int ctf_text_array_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       struct definition_array *array_definition =
-               container_of(definition, struct definition_array, p);
-       struct declaration_array *array_declaration =
-               array_definition->declaration;
-       struct bt_declaration *elem = array_declaration->elem;
-       int field_nr_saved;
-       int ret = 0;
-
-       if (!print_field(definition))
-               return 0;
-
-       if (!pos->dummy) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               fprintf(pos->fp, " ");
-               if (pos->print_names)
-                       fprintf(pos->fp, "%s = ",
-                               rem_(g_quark_to_string(definition->name)));
-       }
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (!(integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT)) {
-                               pos->string = array_definition->string;
-                               g_string_assign(array_definition->string, "");
-                               ret = bt_array_rw(ppos, definition);
-                               pos->string = NULL;
-                       }
-                       fprintf(pos->fp, "\"%s\"", array_definition->string->str);
-                       return ret;
-               }
-       }
-
-       if (!pos->dummy) {
-               fprintf(pos->fp, "[");
-               pos->depth++;
-       }
-       field_nr_saved = pos->field_nr;
-       pos->field_nr = 0;
-       ret = bt_array_rw(ppos, definition);
-       if (!pos->dummy) {
-               pos->depth--;
-               fprintf(pos->fp, " ]");
-       }
-       pos->field_nr = field_nr_saved;
-       return ret;
-}
diff --git a/formats/ctf-text/types/enum.c b/formats/ctf-text/types/enum.c
deleted file mode 100644 (file)
index 5ab13fb..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Common Trace Format
- *
- * Enumeration mapping strings (quarks) from/to integers.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-#include <stdint.h>
-
-int ctf_text_enum_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_enum *enum_definition =
-               container_of(definition, struct definition_enum, p);
-       struct definition_integer *integer_definition =
-               enum_definition->integer;
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       GArray *qs;
-       int ret;
-       int field_nr_saved;
-
-       if (!print_field(definition))
-               return 0;
-
-       if (pos->dummy)
-               return 0;
-
-       if (pos->field_nr++ != 0)
-               fprintf(pos->fp, ",");
-       fprintf(pos->fp, " ");
-       if (pos->print_names)
-               fprintf(pos->fp, "%s = ",
-                       rem_(g_quark_to_string(definition->name)));
-
-       field_nr_saved = pos->field_nr;
-       pos->field_nr = 0;
-       fprintf(pos->fp, "(");
-       pos->depth++;
-       qs = enum_definition->value;
-
-       if (qs) {
-               int i;
-
-               for (i = 0; i < qs->len; i++) {
-                       GQuark q = g_array_index(qs, GQuark, i);
-                       const char *str = g_quark_to_string(q);
-
-                       assert(str);
-                       if (pos->field_nr++ != 0)
-                               fprintf(pos->fp, ",");
-                       fprintf(pos->fp, " ");
-                       fprintf(pos->fp, "\"%s\"", str);
-               }
-       } else {
-               fprintf(pos->fp, " <unknown>");
-       }
-
-       pos->field_nr = 0;
-       fprintf(pos->fp, " :");
-       ret = generic_rw(ppos, &integer_definition->p);
-
-       pos->depth--;
-       fprintf(pos->fp, " )");
-       pos->field_nr = field_nr_saved;
-       return ret;
-}
diff --git a/formats/ctf-text/types/float.c b/formats/ctf-text/types/float.c
deleted file mode 100644 (file)
index a4946f9..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Common Trace Format
- *
- * Floating point read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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.
- *
- * Reference: ISO C99 standard 5.2.4
- */
-
-#include <babeltrace/ctf-text/types.h>
-#include <stdio.h>
-
-int ctf_text_float_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_float *float_definition =
-               container_of(definition, struct definition_float, p);
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-
-       if (!print_field(definition))
-               return 0;
-
-       if (pos->dummy)
-               return 0;
-
-       if (pos->field_nr++ != 0)
-               fprintf(pos->fp, ",");
-       fprintf(pos->fp, " ");
-       if (pos->print_names)
-               fprintf(pos->fp, "%s = ",
-                       rem_(g_quark_to_string(definition->name)));
-
-       fprintf(pos->fp, "%g", float_definition->value);
-       return 0;
-}
diff --git a/formats/ctf-text/types/integer.c b/formats/ctf-text/types/integer.c
deleted file mode 100644 (file)
index c08aa4b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Common Trace Format
- *
- * Integers read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <babeltrace/bitfield.h>
-#include <babeltrace/trace-debug-info.h>
-
-int ctf_text_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-               container_of(definition, struct definition_integer, p);
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-
-       if (!print_field(definition))
-               return 0;
-
-       if (pos->dummy)
-               return 0;
-
-       if (pos->field_nr++ != 0)
-               fprintf(pos->fp, ",");
-       fprintf(pos->fp, " ");
-       if (pos->print_names)
-               fprintf(pos->fp, "%s = ",
-                       rem_(g_quark_to_string(definition->name)));
-
-       if (pos->string
-           && (integer_declaration->encoding == CTF_STRING_ASCII
-             || integer_declaration->encoding == CTF_STRING_UTF8)) {
-
-               if (!integer_declaration->signedness) {
-                       g_string_append_c(pos->string,
-                               (int) integer_definition->value._unsigned);
-               } else {
-                       g_string_append_c(pos->string,
-                               (int) integer_definition->value._signed);
-               }
-               return 0;
-       }
-
-       switch (integer_declaration->base) {
-       case 0: /* default */
-       case 10:
-               if (!integer_declaration->signedness) {
-                       fprintf(pos->fp, "%" PRIu64,
-                               integer_definition->value._unsigned);
-               } else {
-                       fprintf(pos->fp, "%" PRId64,
-                               integer_definition->value._signed);
-               }
-               break;
-       case 2:
-       {
-               int bitnr;
-               uint64_t v;
-
-               if (!integer_declaration->signedness)
-                       v = integer_definition->value._unsigned;
-               else
-                       v = (uint64_t) integer_definition->value._signed;
-
-               fprintf(pos->fp, "0b");
-               v = _bt_piecewise_lshift(v, 64 - integer_declaration->len);
-               for (bitnr = 0; bitnr < integer_declaration->len; bitnr++) {
-                       fprintf(pos->fp, "%u", (v & (1ULL << 63)) ? 1 : 0);
-                       v = _bt_piecewise_lshift(v, 1);
-               }
-               break;
-       }
-       case 8:
-       {
-               uint64_t v;
-
-               if (!integer_declaration->signedness) {
-                       v = integer_definition->value._unsigned;
-               } else {
-                       v = (uint64_t) integer_definition->value._signed;
-                       if (integer_declaration->len < 64) {
-                               size_t len = integer_declaration->len;
-                               size_t rounded_len;
-
-                               assert(len != 0);
-                               /* Round length to the nearest 3-bit */
-                               rounded_len = (((len - 1) / 3) + 1) * 3;
-                               v &= ((uint64_t) 1 << rounded_len) - 1;
-                       }
-               }
-
-               fprintf(pos->fp, "0%" PRIo64, v);
-               break;
-       }
-       case 16:
-       {
-               uint64_t v;
-
-               if (!integer_declaration->signedness) {
-                       v = integer_definition->value._unsigned;
-               } else {
-                       v = (uint64_t) integer_definition->value._signed;
-                       if (integer_declaration->len < 64) {
-                               /* Round length to the nearest nibble */
-                               uint8_t rounded_len =
-                                       ((integer_declaration->len + 3) & ~0x3);
-
-                               v &= ((uint64_t) 1 << rounded_len) - 1;
-                       }
-               }
-
-               fprintf(pos->fp, "0x%" PRIX64, v);
-               break;
-       }
-       default:
-               return -EINVAL;
-       }
-
-       ctf_text_integer_write_debug_info(ppos, definition);
-
-       return 0;
-}
diff --git a/formats/ctf-text/types/sequence.c b/formats/ctf-text/types/sequence.c
deleted file mode 100644 (file)
index 659f87d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Common Trace Format
- *
- * Sequence format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-
-int ctf_text_sequence_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       struct definition_sequence *sequence_definition =
-               container_of(definition, struct definition_sequence, p);
-       struct declaration_sequence *sequence_declaration =
-               sequence_definition->declaration;
-       struct bt_declaration *elem = sequence_declaration->elem;
-       int field_nr_saved;
-       int ret = 0;
-
-       if (!print_field(definition))
-               return 0;
-
-       if (!pos->dummy) {
-               if (pos->field_nr++ != 0)
-                       fprintf(pos->fp, ",");
-               fprintf(pos->fp, " ");
-               if (pos->print_names)
-                       fprintf(pos->fp, "%s = ",
-                               rem_(g_quark_to_string(definition->name)));
-       }
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (!(integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT)) {
-                               pos->string = sequence_definition->string;
-                               g_string_assign(sequence_definition->string, "");
-                               ret = bt_sequence_rw(ppos, definition);
-                               pos->string = NULL;
-                       }
-                       fprintf(pos->fp, "\"%s\"", sequence_definition->string->str);
-                       return ret;
-               }
-       }
-
-       if (!pos->dummy) {
-               fprintf(pos->fp, "[");
-               pos->depth++;
-       }
-       field_nr_saved = pos->field_nr;
-       pos->field_nr = 0;
-       ret = bt_sequence_rw(ppos, definition);
-       if (!pos->dummy) {
-               pos->depth--;
-               fprintf(pos->fp, " ]");
-       }
-       pos->field_nr = field_nr_saved;
-       return ret;
-}
diff --git a/formats/ctf-text/types/string.c b/formats/ctf-text/types/string.c
deleted file mode 100644 (file)
index df7f5f7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Common Trace Format
- *
- * Strings read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-#include <babeltrace/compat/limits.h>          /* C99 limits */
-#include <string.h>
-
-int ctf_text_string_write(struct bt_stream_pos *ppos,
-                         struct bt_definition *definition)
-{
-       struct definition_string *string_definition =
-               container_of(definition, struct definition_string, p);
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-
-       assert(string_definition->value != NULL);
-
-       if (!print_field(definition))
-               return 0;
-
-       if (pos->dummy)
-               return 0;
-
-       if (pos->field_nr++ != 0)
-               fprintf(pos->fp, ",");
-       fprintf(pos->fp, " ");
-       if (pos->print_names)
-               fprintf(pos->fp, "%s = ",
-                       rem_(g_quark_to_string(definition->name)));
-
-       fprintf(pos->fp, "\"%s\"", string_definition->value);
-       return 0;
-}
diff --git a/formats/ctf-text/types/struct.c b/formats/ctf-text/types/struct.c
deleted file mode 100644 (file)
index a2aee3a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Common Trace Format
- *
- * Structure format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-
-int ctf_text_struct_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       int field_nr_saved;
-       int ret;
-
-       if (!print_field(definition))
-               return 0;
-
-       if (!pos->dummy) {
-               if (pos->depth >= 0) {
-                       if (pos->field_nr++ != 0)
-                               fprintf(pos->fp, ",");
-                       fprintf(pos->fp, " ");
-                       if (pos->print_names && definition->name != 0)
-                               fprintf(pos->fp, "%s = ",
-                                       rem_(g_quark_to_string(definition->name)));
-                       fprintf(pos->fp, "{");
-               }
-               pos->depth++;
-       }
-       field_nr_saved = pos->field_nr;
-       pos->field_nr = 0;
-       ret = bt_struct_rw(ppos, definition);
-       if (!pos->dummy) {
-               pos->depth--;
-               if (pos->depth >= 0) {
-                       fprintf(pos->fp, " }");
-               }
-       }
-       pos->field_nr = field_nr_saved;
-       return ret;
-}
diff --git a/formats/ctf-text/types/variant.c b/formats/ctf-text/types/variant.c
deleted file mode 100644 (file)
index 3aeb6ec..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Common Trace Format
- *
- * Variant format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <stdio.h>
-
-int ctf_text_variant_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       int field_nr_saved;
-       int ret;
-
-       if (!print_field(definition))
-               return 0;
-
-       if (!pos->dummy) {
-               if (pos->depth >= 0) {
-                       if (pos->field_nr++ != 0)
-                               fprintf(pos->fp, ",");
-                       fprintf(pos->fp, " ");
-                       if (pos->print_names)
-                               fprintf(pos->fp, "%s = ",
-                                       rem_(g_quark_to_string(definition->name)));
-                       fprintf(pos->fp, "{");
-               }
-               pos->depth++;
-       }
-       field_nr_saved = pos->field_nr;
-       pos->field_nr = 0;
-       ret = bt_variant_rw(ppos, definition);
-       if (!pos->dummy) {
-               pos->depth--;
-               if (pos->depth >= 0) {
-                       fprintf(pos->fp, " }");
-               }
-       }
-       pos->field_nr = field_nr_saved;
-       return ret;
-}
diff --git a/formats/ctf/Makefile.am b/formats/ctf/Makefile.am
deleted file mode 100644 (file)
index 2eb526d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I$(builddir)
-
-SUBDIRS = types metadata writer ir .
-
-lib_LTLIBRARIES = libbabeltrace-ctf.la
-
-libbabeltrace_ctf_la_SOURCES = \
-       ctf.c \
-       events.c \
-       iterator.c \
-       callbacks.c \
-       events-private.h
-
-# Request that the linker keeps all static libraries objects.
-libbabeltrace_ctf_la_LDFLAGS = \
-       $(LD_NO_AS_NEEDED) -version-info $(BABELTRACE_LIBRARY_VERSION)
-
-libbabeltrace_ctf_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       types/libctf-types.la \
-       metadata/libctf-parser.la \
-       metadata/libctf-ast.la \
-       writer/libctf-writer.la \
-       ir/libctf-ir.la
-
-if ENABLE_DEBUG_INFO
-libbabeltrace_ctf_la_LIBADD += $(top_builddir)/lib/libdebug-info.la
-endif
diff --git a/formats/ctf/callbacks.c b/formats/ctf/callbacks.c
deleted file mode 100644 (file)
index a8c376f..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * callbacks.c
- *
- * Babeltrace Library
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/context.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/iterator-internal.h>
-#include <babeltrace/ctf/events.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/ctf/callbacks-internal.h>
-#include <inttypes.h>
-
-static
-struct bt_dependencies *_bt_dependencies_create(const char *first,
-                                                       va_list ap)
-{
-       const char *iter;
-       struct bt_dependencies *dep;
-
-       dep = g_new0(struct bt_dependencies, 1);
-       dep->refcount = 1;
-       dep->deps = g_array_new(FALSE, TRUE, sizeof(GQuark));
-       iter = first;
-       while (iter) {
-               GQuark q = g_quark_from_string(iter);
-               g_array_append_val(dep->deps, q);
-               iter = va_arg(ap, const char *);
-       }
-       return dep;
-}
-
-struct bt_dependencies *bt_dependencies_create(const char *first, ...)
-{
-       va_list ap;
-       struct bt_dependencies *deps;
-
-       va_start(ap, first);
-       deps = _bt_dependencies_create(first, ap);
-       va_end(ap);
-       return deps;
-}
-
-/*
- * bt_ctf_iter_add_callback: Add a callback to CTF iterator.
- */
-int bt_ctf_iter_add_callback(struct bt_ctf_iter *iter,
-               bt_intern_str event, void *private_data, int flags,
-               enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data,
-                                          void *private_data),
-               struct bt_dependencies *depends,
-               struct bt_dependencies *weak_depends,
-               struct bt_dependencies *provides)
-{
-       int i, stream_id;
-       gpointer *event_id_ptr;
-       unsigned long event_id;
-       struct trace_collection *tc;
-
-       if (!iter || !callback)
-               return -EINVAL;
-
-       tc = iter->parent.ctx->tc;
-       for (i = 0; i < tc->array->len; i++) {
-               struct ctf_trace *tin;
-               struct bt_trace_descriptor *td_read;
-
-               td_read = g_ptr_array_index(tc->array, i);
-               tin = container_of(td_read, struct ctf_trace, parent);
-
-               for (stream_id = 0; stream_id < tin->streams->len; stream_id++) {
-                       struct ctf_stream_declaration *stream;
-                       struct bt_stream_callbacks *bt_stream_cb = NULL;
-                       struct bt_callback_chain *bt_chain = NULL;
-                       struct bt_callback new_callback;
-
-                       stream = g_ptr_array_index(tin->streams, stream_id);
-
-                       if (stream_id >= iter->callbacks->len) {
-                               g_array_set_size(iter->callbacks, stream->stream_id + 1);
-                       }
-                       bt_stream_cb = &g_array_index(iter->callbacks,
-                                       struct bt_stream_callbacks, stream->stream_id);
-                       if (!bt_stream_cb->per_id_callbacks) {
-                               bt_stream_cb->per_id_callbacks = g_array_new(FALSE, TRUE,
-                                               sizeof(struct bt_callback_chain));
-                       }
-
-                       if (event) {
-                               /* find the event id */
-                               event_id_ptr = g_hash_table_lookup(stream->event_quark_to_id,
-                                               (gconstpointer) GUINT_TO_POINTER(event));
-                               /* event not found in this stream class */
-                               if (!event_id_ptr) {
-                                       fprintf(stderr, "[error] Event ID not found in stream class\n");
-                                       continue;
-                               }
-                               event_id = GPOINTER_TO_UINT(*event_id_ptr);
-
-                               /* find or create the bt_callback_chain for this event */
-                               if (event_id >= bt_stream_cb->per_id_callbacks->len) {
-                                       g_array_set_size(bt_stream_cb->per_id_callbacks, event_id + 1);
-                               }
-                               bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
-                                               struct bt_callback_chain, event_id);
-                               if (!bt_chain->callback) {
-                                       bt_chain->callback = g_array_new(FALSE, TRUE,
-                                               sizeof(struct bt_callback));
-                               }
-                       } else {
-                               /* callback for all events */
-                               if (!iter->main_callbacks.callback) {
-                                       iter->main_callbacks.callback = g_array_new(FALSE, TRUE,
-                                                       sizeof(struct bt_callback));
-                               }
-                               bt_chain = &iter->main_callbacks;
-                       }
-
-                       new_callback.private_data = private_data;
-                       new_callback.flags = flags;
-                       new_callback.callback = callback;
-                       new_callback.depends = depends;
-                       new_callback.weak_depends = weak_depends;
-                       new_callback.provides = provides;
-
-                       /* TODO : take care of priority, for now just FIFO */
-                       g_array_append_val(bt_chain->callback, new_callback);
-               }
-       }
-
-       return 0;
-}
-
-static
-int extract_ctf_stream_event(struct ctf_stream_definition *stream,
-               struct bt_ctf_event *event)
-{
-       struct ctf_stream_declaration *stream_class = stream->stream_class;
-       struct ctf_event_declaration *event_class;
-       uint64_t id = stream->event_id;
-
-       if (id >= stream_class->events_by_id->len) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id);
-               return -1;
-       }
-       event->parent = g_ptr_array_index(stream->events_by_id, id);
-       if (!event->parent) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
-               return -1;
-       }
-       event_class = g_ptr_array_index(stream_class->events_by_id, id);
-       if (!event_class) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
-               return -1;
-       }
-
-       return 0;
-}
-
-void process_callbacks(struct bt_ctf_iter *iter,
-                      struct ctf_stream_definition *stream)
-{
-       struct bt_stream_callbacks *bt_stream_cb;
-       struct bt_callback_chain *bt_chain;
-       struct bt_callback *cb;
-       int i;
-       enum bt_cb_ret ret;
-       struct bt_ctf_event ctf_data;
-
-       assert(iter && stream);
-
-       ret = extract_ctf_stream_event(stream, &ctf_data);
-       if (ret)
-               goto end;
-
-       /* process all events callback first */
-       if (iter->main_callbacks.callback) {
-               for (i = 0; i < iter->main_callbacks.callback->len; i++) {
-                       cb = &g_array_index(iter->main_callbacks.callback, struct bt_callback, i);
-                       ret = cb->callback(&ctf_data, cb->private_data);
-                       switch (ret) {
-                       case BT_CB_OK_STOP:
-                       case BT_CB_ERROR_STOP:
-                               goto end;
-                       default:
-                               break;
-                       }
-               }
-       }
-
-       /* process per event callbacks */
-       bt_stream_cb = &g_array_index(iter->callbacks,
-                       struct bt_stream_callbacks, stream->stream_id);
-       if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
-               goto end;
-
-       if (stream->event_id >= bt_stream_cb->per_id_callbacks->len)
-               goto end;
-       bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
-                       struct bt_callback_chain, stream->event_id);
-       if (!bt_chain || !bt_chain->callback)
-               goto end;
-
-       for (i = 0; i < bt_chain->callback->len; i++) {
-               cb = &g_array_index(bt_chain->callback, struct bt_callback, i);
-               ret = cb->callback(&ctf_data, cb->private_data);
-               switch (ret) {
-               case BT_CB_OK_STOP:
-               case BT_CB_ERROR_STOP:
-                       goto end;
-               default:
-                       break;
-               }
-       }
-
-end:
-       return;
-}
diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c
deleted file mode 100644 (file)
index 475d6f7..0000000
+++ /dev/null
@@ -1,2868 +0,0 @@
-/*
- * BabelTrace - Common Trace Format (CTF)
- *
- * Format registration.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <babeltrace/format-internal.h>
-#include <babeltrace/ctf/types.h>
-#include <babeltrace/ctf/metadata.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/trace-handle-internal.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/compat/uuid.h>
-#include <babeltrace/endian.h>
-#include <babeltrace/trace-debug-info.h>
-#include <babeltrace/ctf/ctf-index.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "metadata/ctf-scanner.h"
-#include "metadata/ctf-parser.h"
-#include "metadata/ctf-ast.h"
-#include "events-private.h"
-#include <babeltrace/compat/memstream.h>
-#include <babeltrace/compat/fcntl.h>
-
-#define LOG2_CHAR_BIT  3
-
-/*
- * Length of first attempt at mapping a packet header, in bits.
- */
-#define DEFAULT_HEADER_LEN     (getpagesize() * CHAR_BIT)
-
-/*
- * Lenght of packet to write, in bits.
- */
-#define WRITE_PACKET_LEN       (getpagesize() * 8 * CHAR_BIT)
-
-#define NSEC_PER_SEC 1000000000LL
-
-#define INDEX_PATH "./index/%s.idx"
-
-int opt_clock_cycles,
-       opt_clock_seconds,
-       opt_clock_date,
-       opt_clock_gmt;
-
-int64_t opt_clock_offset;
-int64_t opt_clock_offset_ns;
-
-extern int yydebug;
-char *opt_debug_info_dir;
-char *opt_debug_info_target_prefix;
-
-/*
- * TODO: babeltrace_ctf_console_output ensures that we only print
- * discarded events when ctf-text plugin is used. Should be cleaned up
- * with the plugin system redesign.
- */
-int babeltrace_ctf_console_output;
-
-static
-struct bt_trace_descriptor *ctf_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence),
-               FILE *metadata_fp);
-static
-struct bt_trace_descriptor *ctf_open_mmap_trace(
-               struct bt_mmap_stream_list *mmap_list,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence),
-               FILE *metadata_fp);
-static
-void ctf_set_context(struct bt_trace_descriptor *descriptor,
-               struct bt_context *ctx);
-static
-void ctf_set_handle(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle);
-
-static
-int ctf_close_trace(struct bt_trace_descriptor *descriptor);
-static
-int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle, enum bt_clock_type type,
-               int64_t *timestamp);
-static
-int ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle, enum bt_clock_type type,
-               int64_t *timestamp);
-static
-int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp);
-
-static
-rw_dispatch read_dispatch_table[] = {
-       [ BT_CTF_TYPE_ID_INTEGER ] = ctf_integer_read,
-       [ BT_CTF_TYPE_ID_FLOAT ] = ctf_float_read,
-       [ BT_CTF_TYPE_ID_ENUM ] = ctf_enum_read,
-       [ BT_CTF_TYPE_ID_STRING ] = ctf_string_read,
-       [ BT_CTF_TYPE_ID_STRUCT ] = ctf_struct_rw,
-       [ BT_CTF_TYPE_ID_VARIANT ] = ctf_variant_rw,
-       [ BT_CTF_TYPE_ID_ARRAY ] = ctf_array_read,
-       [ BT_CTF_TYPE_ID_SEQUENCE ] = ctf_sequence_read,
-};
-
-static
-rw_dispatch write_dispatch_table[] = {
-       [ BT_CTF_TYPE_ID_INTEGER ] = ctf_integer_write,
-       [ BT_CTF_TYPE_ID_FLOAT ] = ctf_float_write,
-       [ BT_CTF_TYPE_ID_ENUM ] = ctf_enum_write,
-       [ BT_CTF_TYPE_ID_STRING ] = ctf_string_write,
-       [ BT_CTF_TYPE_ID_STRUCT ] = ctf_struct_rw,
-       [ BT_CTF_TYPE_ID_VARIANT ] = ctf_variant_rw,
-       [ BT_CTF_TYPE_ID_ARRAY ] = ctf_array_write,
-       [ BT_CTF_TYPE_ID_SEQUENCE ] = ctf_sequence_write,
-};
-
-static
-struct bt_format ctf_format = {
-       .open_trace = ctf_open_trace,
-       .open_mmap_trace = ctf_open_mmap_trace,
-       .close_trace = ctf_close_trace,
-       .set_context = ctf_set_context,
-       .set_handle = ctf_set_handle,
-       .timestamp_begin = ctf_timestamp_begin,
-       .timestamp_end = ctf_timestamp_end,
-       .convert_index_timestamp = ctf_convert_index_timestamp,
-};
-
-void bt_ctf_hook(void)
-{
-       /*
-        * Dummy function to prevent the linker from discarding this format as
-        * "unused" in static builds.
-        */
-}
-
-static
-int ctf_timestamp_begin(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle, enum bt_clock_type type,
-               int64_t *timestamp)
-{
-       struct ctf_trace *tin;
-       int64_t begin = LLONG_MAX;
-       int i, j, ret;
-
-       tin = container_of(descriptor, struct ctf_trace, parent);
-
-       if (!tin || !timestamp) {
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* for each stream_class */
-       for (i = 0; i < tin->streams->len; i++) {
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(tin->streams, i);
-               if (!stream_class)
-                       continue;
-               /* for each file_stream */
-               for (j = 0; j < stream_class->streams->len; j++) {
-                       struct ctf_stream_definition *stream;
-                       struct ctf_file_stream *cfs;
-                       struct ctf_stream_pos *stream_pos;
-                       struct packet_index *index;
-
-                       stream = g_ptr_array_index(stream_class->streams, j);
-                       cfs = container_of(stream, struct ctf_file_stream,
-                                       parent);
-                       stream_pos = &cfs->pos;
-
-                       if (!stream_pos->packet_index) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-
-                       if (stream_pos->packet_index->len <= 0)
-                               continue;
-
-                       index = &g_array_index(stream_pos->packet_index,
-                                       struct packet_index,
-                                       stream_pos->packet_index->len - 1);
-                       if (type == BT_CLOCK_REAL) {
-                               if (index->ts_real.timestamp_begin < begin)
-                                       begin = index->ts_real.timestamp_begin;
-                       } else if (type == BT_CLOCK_CYCLES) {
-                               if (index->ts_cycles.timestamp_begin < begin)
-                                       begin = index->ts_cycles.timestamp_begin;
-                       } else {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-               }
-       }
-       if (begin == LLONG_MAX) {
-               ret = -ENOENT;
-               goto error;
-       }
-       *timestamp = begin;
-       return 0;
-
-error:
-       return ret;
-}
-
-static
-int ctf_timestamp_end(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle, enum bt_clock_type type,
-               int64_t *timestamp)
-{
-       struct ctf_trace *tin;
-       int64_t end = LLONG_MIN;
-       int i, j, ret;
-
-       tin = container_of(descriptor, struct ctf_trace, parent);
-
-       if (!tin || !timestamp) {
-               ret = -EINVAL;
-               goto error;
-       }
-
-       /* for each stream_class */
-       for (i = 0; i < tin->streams->len; i++) {
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(tin->streams, i);
-               if (!stream_class)
-                       continue;
-               /* for each file_stream */
-               for (j = 0; j < stream_class->streams->len; j++) {
-                       struct ctf_stream_definition *stream;
-                       struct ctf_file_stream *cfs;
-                       struct ctf_stream_pos *stream_pos;
-                       struct packet_index *index;
-
-                       stream = g_ptr_array_index(stream_class->streams, j);
-                       cfs = container_of(stream, struct ctf_file_stream,
-                                       parent);
-                       stream_pos = &cfs->pos;
-
-                       if (!stream_pos->packet_index) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-
-                       if (stream_pos->packet_index->len <= 0)
-                               continue;
-
-                       index = &g_array_index(stream_pos->packet_index,
-                                       struct packet_index,
-                                       stream_pos->packet_index->len - 1);
-                       if (type == BT_CLOCK_REAL) {
-                               if (index->ts_real.timestamp_end > end)
-                                       end = index->ts_real.timestamp_end;
-                       } else if (type == BT_CLOCK_CYCLES) {
-                               if (index->ts_cycles.timestamp_end > end)
-                                       end = index->ts_cycles.timestamp_end;
-                       } else {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-               }
-       }
-       if (end == LLONG_MIN) {
-               ret = -ENOENT;
-               goto error;
-       }
-       *timestamp = end;
-       return 0;
-
-error:
-       return ret;
-}
-
-/*
- * Update stream current timestamp
- */
-static
-void ctf_update_timestamp(struct ctf_stream_definition *stream,
-                         struct definition_integer *integer_definition)
-{
-       struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       uint64_t oldval, newval, updateval;
-
-       if (unlikely(integer_declaration->len == 64)) {
-               stream->cycles_timestamp = integer_definition->value._unsigned;
-               stream->real_timestamp = ctf_get_real_timestamp(stream,
-                               stream->cycles_timestamp);
-               return;
-       }
-       /* keep low bits */
-       oldval = stream->cycles_timestamp;
-       oldval &= (1ULL << integer_declaration->len) - 1;
-       newval = integer_definition->value._unsigned;
-       /* Test for overflow by comparing low bits */
-       if (newval < oldval)
-               newval += 1ULL << integer_declaration->len;
-       /* updateval contains old high bits, and new low bits (sum) */
-       updateval = stream->cycles_timestamp;
-       updateval &= ~((1ULL << integer_declaration->len) - 1);
-       updateval += newval;
-       stream->cycles_timestamp = updateval;
-
-       /* convert to real timestamp */
-       stream->real_timestamp = ctf_get_real_timestamp(stream,
-                       stream->cycles_timestamp);
-}
-
-/*
- * Print timestamp, rescaling clock frequency to nanoseconds and
- * applying offsets as needed (unix time).
- */
-static
-void ctf_print_timestamp_real(FILE *fp,
-                       struct ctf_stream_definition *stream,
-                       int64_t timestamp)
-{
-       int64_t ts_sec = 0, ts_nsec;
-       uint64_t ts_sec_abs, ts_nsec_abs;
-       bool is_negative;
-
-       ts_nsec = timestamp;
-
-       /* Add command-line offset in ns */
-        ts_nsec += opt_clock_offset_ns;
-
-       /* Add command-line offset */
-       ts_sec += opt_clock_offset;
-
-       ts_sec += ts_nsec / NSEC_PER_SEC;
-       ts_nsec = ts_nsec % NSEC_PER_SEC;
-       if (ts_sec >= 0 && ts_nsec >= 0) {
-               is_negative = false;
-               ts_sec_abs = ts_sec;
-               ts_nsec_abs = ts_nsec;
-       } else if (ts_sec > 0 && ts_nsec < 0) {
-               is_negative = false;
-               ts_sec_abs = ts_sec - 1;
-               ts_nsec_abs = NSEC_PER_SEC + ts_nsec;
-       } else if (ts_sec == 0 && ts_nsec < 0) {
-               is_negative = true;
-               ts_sec_abs = ts_sec;
-               ts_nsec_abs = -ts_nsec;
-       } else if (ts_sec < 0 && ts_nsec > 0) {
-               is_negative = true;
-               ts_sec_abs = -(ts_sec + 1);
-               ts_nsec_abs = NSEC_PER_SEC - ts_nsec;
-       } else if (ts_sec < 0 && ts_nsec == 0) {
-               is_negative = true;
-               ts_sec_abs = -ts_sec;
-               ts_nsec_abs = ts_nsec;
-       } else {        /* (ts_sec < 0 && ts_nsec < 0) */
-               is_negative = true;
-               ts_sec_abs = -ts_sec;
-               ts_nsec_abs = -ts_nsec;
-       }
-
-       if (!opt_clock_seconds) {
-               struct tm tm;
-               time_t time_s = (time_t) ts_sec_abs;
-
-               if (is_negative) {
-                       fprintf(stderr, "[warning] Fallback to [sec.ns] to print negative time value. Use --clock-seconds.\n");
-                       goto seconds;
-               }
-
-               if (!opt_clock_gmt) {
-                       struct tm *res;
-
-                       res = localtime_r(&time_s, &tm);
-                       if (!res) {
-                               fprintf(stderr, "[warning] Unable to get localtime.\n");
-                               goto seconds;
-                       }
-               } else {
-                       struct tm *res;
-
-                       res = gmtime_r(&time_s, &tm);
-                       if (!res) {
-                               fprintf(stderr, "[warning] Unable to get gmtime.\n");
-                               goto seconds;
-                       }
-               }
-               if (opt_clock_date) {
-                       char timestr[26];
-                       size_t res;
-
-                       /* Print date and time */
-                       res = strftime(timestr, sizeof(timestr),
-                               "%F ", &tm);
-                       if (!res) {
-                               fprintf(stderr, "[warning] Unable to print ascii time.\n");
-                               goto seconds;
-                       }
-                       fprintf(fp, "%s", timestr);
-               }
-               /* Print time in HH:MM:SS.ns */
-               fprintf(fp, "%02d:%02d:%02d.%09" PRIu64,
-                       tm.tm_hour, tm.tm_min, tm.tm_sec, ts_nsec_abs);
-               goto end;
-       }
-seconds:
-       fprintf(fp, "%s%" PRId64 ".%09" PRIu64,
-               is_negative ? "-" : "", ts_sec_abs, ts_nsec_abs);
-
-end:
-       return;
-}
-
-/*
- * Print timestamp, in cycles
- */
-static
-void ctf_print_timestamp_cycles(FILE *fp,
-               struct ctf_stream_definition *stream,
-               uint64_t timestamp)
-{
-       fprintf(fp, "%020" PRIu64, timestamp);
-}
-
-void ctf_print_timestamp(FILE *fp,
-               struct ctf_stream_definition *stream,
-               int64_t timestamp)
-{
-       if (opt_clock_cycles) {
-               ctf_print_timestamp_cycles(fp, stream, timestamp);
-       } else {
-               ctf_print_timestamp_real(fp, stream, timestamp);
-       }
-}
-
-static
-void print_uuid(FILE *fp, unsigned char *uuid)
-{
-       int i;
-
-       for (i = 0; i < BABELTRACE_UUID_LEN; i++)
-               fprintf(fp, "%x", (unsigned int) uuid[i]);
-}
-
-/*
- * Discarded events can be either:
- * - discarded after end of previous buffer due to buffer full:
- *     happened within range: [ prev_timestamp_end, timestamp_begin ]
- * - discarded within current buffer due to either event too large or
- *   nested wrap-around:
- *     happened within range: [ timestamp_begin, timestamp_end ]
- *
- * Given we have discarded counters of those two types merged into the
- * events_discarded counter, we need to use the union of those ranges:
- *   [ prev_timestamp_end, timestamp_end ]
- *
- * Lost packets occur if the tracer overwrote some subbuffer(s) before the
- * consumer had time to extract them. We keep track of those gaps with the
- * packet sequence number in each packet.
- */
-static
-void ctf_print_discarded_lost(FILE *fp, struct ctf_stream_definition *stream)
-{
-       if ((!stream->events_discarded && !stream->packets_lost) ||
-                       !babeltrace_ctf_console_output) {
-               return;
-       }
-       fflush(stdout);
-       if (stream->events_discarded) {
-               fprintf(fp, "[warning] Tracer discarded %" PRIu64 " events between [",
-                               stream->events_discarded);
-       } else if (stream->packets_lost) {
-               fprintf(fp, "[warning] Tracer lost %" PRIu64 " trace packets between [",
-                               stream->packets_lost);
-       }
-       if (opt_clock_cycles) {
-               ctf_print_timestamp(fp, stream,
-                               stream->prev.cycles.end);
-               fprintf(fp, "] and [");
-               ctf_print_timestamp(fp, stream,
-                               stream->current.cycles.end);
-       } else {
-               ctf_print_timestamp(fp, stream,
-                               stream->prev.real.end);
-               fprintf(fp, "] and [");
-               ctf_print_timestamp(fp, stream,
-                               stream->current.real.end);
-       }
-       fprintf(fp, "] in trace UUID ");
-       print_uuid(fp, stream->stream_class->trace->uuid);
-       if (stream->stream_class->trace->parent.path[0])
-               fprintf(fp, ", at path: \"%s\"",
-                       stream->stream_class->trace->parent.path);
-
-       fprintf(fp, ", within stream id %" PRIu64, stream->stream_id);
-       if (stream->path[0])
-               fprintf(fp, ", at relative path: \"%s\"", stream->path);
-       fprintf(fp, ". ");
-       fprintf(fp, "You should consider recording a new trace with larger "
-               "buffers or with fewer events enabled.\n");
-       fflush(fp);
-}
-
-static
-int ctf_read_event(struct bt_stream_pos *ppos, struct ctf_stream_definition *stream)
-{
-       struct ctf_stream_pos *pos =
-               container_of(ppos, struct ctf_stream_pos, parent);
-       struct ctf_stream_declaration *stream_class = stream->stream_class;
-       struct ctf_event_definition *event;
-       uint64_t id = 0;
-       int ret;
-
-       /* We need to check for EOF here for empty files. */
-       if (unlikely(pos->offset == EOF))
-               return EOF;
-
-       ctf_pos_get_event(pos);
-
-       /* save the current position as a restore point */
-       pos->last_offset = pos->offset;
-
-       /*
-        * This is the EOF check after we've advanced the position in
-        * ctf_pos_get_event.
-        */
-       if (unlikely(pos->offset == EOF))
-               return EOF;
-
-       /* Stream is inactive for now (live reading). */
-       if (unlikely(pos->content_size == 0))
-               return EAGAIN;
-
-       /*
-        * Packet seeked to by ctf_pos_get_event() only contains
-        * headers, no event. Consider stream as inactive (live
-        * reading).
-        */
-       if (unlikely(pos->data_offset == pos->content_size))
-               return EAGAIN;
-
-       assert(pos->offset < pos->content_size);
-
-       /* Read event header */
-       if (likely(stream->stream_event_header)) {
-               struct definition_integer *integer_definition;
-               struct bt_definition *variant;
-
-               ret = generic_rw(ppos, &stream->stream_event_header->p);
-               if (unlikely(ret))
-                       goto error;
-               /* lookup event id */
-               integer_definition = bt_lookup_integer(&stream->stream_event_header->p, "id", FALSE);
-               if (integer_definition) {
-                       id = integer_definition->value._unsigned;
-               } else {
-                       struct definition_enum *enum_definition;
-
-                       enum_definition = bt_lookup_enum(&stream->stream_event_header->p, "id", FALSE);
-                       if (enum_definition) {
-                               id = enum_definition->integer->value._unsigned;
-                       }
-               }
-
-               variant = bt_lookup_variant(&stream->stream_event_header->p, "v");
-               if (variant) {
-                       integer_definition = bt_lookup_integer(variant, "id", FALSE);
-                       if (integer_definition) {
-                               id = integer_definition->value._unsigned;
-                       }
-               }
-               stream->event_id = id;
-
-               /* lookup timestamp */
-               stream->has_timestamp = 0;
-               integer_definition = bt_lookup_integer(&stream->stream_event_header->p, "timestamp", FALSE);
-               if (integer_definition) {
-                       ctf_update_timestamp(stream, integer_definition);
-                       stream->has_timestamp = 1;
-               } else {
-                       if (variant) {
-                               integer_definition = bt_lookup_integer(variant, "timestamp", FALSE);
-                               if (integer_definition) {
-                                       ctf_update_timestamp(stream, integer_definition);
-                                       stream->has_timestamp = 1;
-                               }
-                       }
-               }
-       }
-
-       /* Read stream-declared event context */
-       if (stream->stream_event_context) {
-               ret = generic_rw(ppos, &stream->stream_event_context->p);
-               if (ret)
-                       goto error;
-       }
-
-       if (unlikely(id >= stream_class->events_by_id->len)) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id);
-               return -EINVAL;
-       }
-       event = g_ptr_array_index(stream->events_by_id, id);
-       if (unlikely(!event)) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
-               return -EINVAL;
-       }
-
-       /* Read event-declared event context */
-       if (event->event_context) {
-               ret = generic_rw(ppos, &event->event_context->p);
-               if (ret)
-                       goto error;
-       }
-
-       /* Read event payload */
-       if (likely(event->event_fields)) {
-               ret = generic_rw(ppos, &event->event_fields->p);
-               if (ret)
-                       goto error;
-       }
-
-       if (pos->last_offset == pos->offset) {
-               fprintf(stderr, "[error] Invalid 0 byte event encountered.\n");
-               return -EINVAL;
-       }
-
-       return 0;
-
-error:
-       fprintf(stderr, "[error] Unexpected end of packet. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
-       return ret;
-}
-
-static
-int ctf_write_event(struct bt_stream_pos *pos, struct ctf_stream_definition *stream)
-{
-       struct ctf_stream_declaration *stream_class = stream->stream_class;
-       struct ctf_event_definition *event;
-       uint64_t id;
-       int ret;
-
-       id = stream->event_id;
-
-       /* print event header */
-       if (likely(stream->stream_event_header)) {
-               ret = generic_rw(pos, &stream->stream_event_header->p);
-               if (ret)
-                       goto error;
-       }
-
-       /* print stream-declared event context */
-       if (stream->stream_event_context) {
-               ret = generic_rw(pos, &stream->stream_event_context->p);
-               if (ret)
-                       goto error;
-       }
-
-       if (unlikely(id >= stream_class->events_by_id->len)) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is outside range.\n", id);
-               return -EINVAL;
-       }
-       event = g_ptr_array_index(stream->events_by_id, id);
-       if (unlikely(!event)) {
-               fprintf(stderr, "[error] Event id %" PRIu64 " is unknown.\n", id);
-               return -EINVAL;
-       }
-
-       /* print event-declared event context */
-       if (event->event_context) {
-               ret = generic_rw(pos, &event->event_context->p);
-               if (ret)
-                       goto error;
-       }
-
-       /* Read and print event payload */
-       if (likely(event->event_fields)) {
-               ret = generic_rw(pos, &event->event_fields->p);
-               if (ret)
-                       goto error;
-       }
-
-       return 0;
-
-error:
-       fprintf(stderr, "[error] Unexpected end of stream. Either the trace data stream is corrupted or metadata description does not match data layout.\n");
-       return ret;
-}
-
-/*
- * One side-effect of this function is to unmap pos mmap base if one is
- * mapped.
- */
-static
-int find_data_offset(struct ctf_stream_pos *pos,
-               struct ctf_file_stream *file_stream,
-               struct packet_index *packet_index)
-{
-       uint64_t packet_map_len = DEFAULT_HEADER_LEN, tmp_map_len;
-       struct stat filestats;
-       size_t filesize;
-       int ret;
-
-       pos = &file_stream->pos;
-
-       ret = fstat(pos->fd, &filestats);
-       if (ret < 0)
-               return ret;
-       filesize = filestats.st_size;
-
-       /* Deal with empty files */
-       if (!filesize) {
-               return 0;
-       }
-
-begin:
-       if (filesize - pos->mmap_offset < (packet_map_len >> LOG2_CHAR_BIT)) {
-               packet_map_len = (filesize - pos->mmap_offset) << LOG2_CHAR_BIT;
-       }
-
-       if (pos->base_mma) {
-               /* unmap old base */
-               ret = munmap_align(pos->base_mma);
-               if (ret) {
-                       fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
-                                       strerror(errno));
-                       return ret;
-               }
-               pos->base_mma = NULL;
-       }
-       /* map new base. Need mapping length from header. */
-       pos->base_mma = mmap_align(packet_map_len >> LOG2_CHAR_BIT, PROT_READ,
-                       MAP_PRIVATE, pos->fd, pos->mmap_offset);
-       assert(pos->base_mma != MAP_FAILED);
-
-       pos->content_size = packet_map_len;
-       pos->packet_size = packet_map_len;
-       pos->offset = 0;        /* Position of the packet header */
-
-       /* update trace_packet_header and stream_packet_context */
-       if (pos->prot == PROT_READ && file_stream->parent.trace_packet_header) {
-               /* Read packet header */
-               ret = generic_rw(&pos->parent, &file_stream->parent.trace_packet_header->p);
-               if (ret) {
-                       if (ret == -EFAULT)
-                               goto retry;
-               }
-       }
-       if (pos->prot == PROT_READ && file_stream->parent.stream_packet_context) {
-               /* Read packet context */
-               ret = generic_rw(&pos->parent, &file_stream->parent.stream_packet_context->p);
-               if (ret) {
-                       if (ret == -EFAULT)
-                               goto retry;
-               }
-       }
-       packet_index->data_offset = pos->offset;
-
-       /* unmap old base */
-       ret = munmap_align(pos->base_mma);
-       if (ret) {
-               fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
-                               strerror(errno));
-               return ret;
-       }
-       pos->base_mma = NULL;
-
-       return 0;
-
-       /* Retry with larger mapping */
-retry:
-       if (packet_map_len == ((filesize - pos->mmap_offset) << LOG2_CHAR_BIT)) {
-               /*
-                * Reached EOF, but still expecting header/context data.
-                */
-               fprintf(stderr, "[error] Reached end of file, but still expecting header or context fields.\n");
-               return -EFAULT;
-       }
-       /* Double the mapping len, and retry */
-       tmp_map_len = packet_map_len << 1;
-       if (tmp_map_len >> 1 != packet_map_len) {
-               /* Overflow */
-               fprintf(stderr, "[error] Packet mapping length overflow\n");
-               return -EFAULT;
-       }
-       packet_map_len = tmp_map_len;
-       goto begin;
-}
-
-
-int ctf_init_pos(struct ctf_stream_pos *pos, struct bt_trace_descriptor *trace,
-               int fd, int open_flags)
-{
-       pos->fd = fd;
-       if (fd >= 0) {
-               pos->packet_index = g_array_new(FALSE, TRUE,
-                               sizeof(struct packet_index));
-       } else {
-               pos->packet_index = NULL;
-       }
-       switch (open_flags & O_ACCMODE) {
-       case O_RDONLY:
-               pos->prot = PROT_READ;
-               pos->flags = MAP_PRIVATE;
-               pos->parent.rw_table = read_dispatch_table;
-               pos->parent.event_cb = ctf_read_event;
-               pos->parent.trace = trace;
-               break;
-       case O_RDWR:
-               pos->prot = PROT_READ | PROT_WRITE;
-               pos->flags = MAP_SHARED;
-               pos->parent.rw_table = write_dispatch_table;
-               pos->parent.event_cb = ctf_write_event;
-               pos->parent.trace = trace;
-               break;
-       default:
-               assert(0);
-       }
-       return 0;
-}
-
-int ctf_fini_pos(struct ctf_stream_pos *pos)
-{
-       if ((pos->prot & PROT_WRITE) && pos->content_size_loc)
-               *pos->content_size_loc = pos->offset;
-       if (pos->base_mma) {
-               int ret;
-
-               /* unmap old base */
-               ret = munmap_align(pos->base_mma);
-               if (ret) {
-                       fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
-                               strerror(errno));
-                       return -1;
-               }
-       }
-       if (pos->packet_index)
-               (void) g_array_free(pos->packet_index, TRUE);
-       return 0;
-}
-
-void ctf_update_current_packet_index(struct ctf_stream_definition *stream,
-               struct packet_index *prev_index,
-               struct packet_index *cur_index)
-{
-       uint64_t events_discarded_diff;
-       uint64_t packets_lost_diff = 0;
-
-       /* Update packet index time information */
-
-       /* Current packet begin/end */
-       stream->current.real.begin =
-               cur_index->ts_real.timestamp_begin;
-       stream->current.cycles.begin =
-               cur_index->ts_cycles.timestamp_begin;
-       stream->current.real.end =
-               cur_index->ts_real.timestamp_end;
-       stream->current.cycles.end =
-               cur_index->ts_cycles.timestamp_end;
-
-       /* Update packet index discarded event information */
-       events_discarded_diff = cur_index->events_discarded;
-       if (prev_index) {
-               /* Previous packet begin/end */
-               stream->prev.cycles.begin =
-                       prev_index->ts_cycles.timestamp_begin;
-               stream->prev.real.begin =
-                       prev_index->ts_real.timestamp_begin;
-               stream->prev.cycles.end =
-                       prev_index->ts_cycles.timestamp_end;
-               stream->prev.real.end =
-                       prev_index->ts_real.timestamp_end;
-
-               events_discarded_diff -= prev_index->events_discarded;
-               /* packet_seq_num stays at 0 if not produced by the tracer */
-               if (cur_index->packet_seq_num) {
-                       packets_lost_diff = cur_index->packet_seq_num -
-                               prev_index->packet_seq_num - 1;
-               }
-               /*
-                * Deal with 32-bit wrap-around if the tracer provided a
-                * 32-bit field.
-                */
-               if (prev_index->events_discarded_len == 32) {
-                       events_discarded_diff = (uint32_t) events_discarded_diff;
-               }
-       } else {
-               /*
-                * First packet: use current packet info as limits for
-                * previous packet.
-                */
-               stream->prev.cycles.begin =
-                       stream->prev.cycles.end =
-                               stream->current.cycles.begin;
-               stream->prev.real.begin =
-                       stream->prev.real.end =
-                               stream->current.real.begin;
-       }
-       stream->events_discarded = events_discarded_diff;
-       stream->packets_lost = packets_lost_diff;
-}
-
-/*
- * Find the timerange where all the streams in the trace are active
- * simultaneously.
- *
- * Return 0 and update begin/end if necessary on success, return 1 for
- * empty streams and return a negative value on error.
- */
-static
-int ctf_find_stream_intersection(struct bt_trace_descriptor *td_read,
-               struct packet_index_time *_real,
-               struct packet_index_time *_cycles)
-{
-       int stream_id, ret = 0;
-       struct packet_index_time real = { INT64_MIN, INT64_MAX },
-                       cycles = { INT64_MIN, INT64_MAX };
-       struct ctf_trace *tin = container_of(td_read, struct ctf_trace, parent);
-
-       /* At least one of the two return args must be provided. */
-       if (!_real && !_cycles) {
-               ret = -1;
-               goto end;
-       }
-
-       if (tin->streams->len == 0) {
-               ret = 1;
-               goto end;
-       }
-
-       for (stream_id = 0; stream_id < tin->streams->len;
-                       stream_id++) {
-               int filenr;
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(tin->streams, stream_id);
-               if (!stream_class) {
-                       continue;
-               }
-               for (filenr = 0; filenr < stream_class->streams->len; filenr++) {
-                       struct ctf_file_stream *file_stream;
-                       struct ctf_stream_pos *stream_pos;
-                       struct packet_index *index;
-
-                       file_stream = g_ptr_array_index(stream_class->streams,
-                                       filenr);
-                       if (!file_stream) {
-                               continue;
-                       }
-                       stream_pos = &file_stream->pos;
-                       if (!stream_pos->packet_index ||
-                                       stream_pos->packet_index->len <= 0) {
-                               ret = 1;
-                               goto end;
-                       }
-                       index = &g_array_index(stream_pos->packet_index,
-                                       struct packet_index, 0);
-                       real.timestamp_begin = max(real.timestamp_begin,
-                                       index->ts_real.timestamp_begin);
-                       cycles.timestamp_begin = max(cycles.timestamp_begin,
-                                       index->ts_cycles.timestamp_begin);
-
-                       index = &g_array_index(stream_pos->packet_index,
-                                       struct packet_index,
-                                       stream_pos->packet_index->len - 1);
-                       real.timestamp_end = min(real.timestamp_end,
-                                       index->ts_real.timestamp_end);
-                       cycles.timestamp_end = min(cycles.timestamp_end,
-                                       index->ts_cycles.timestamp_end);
-               }
-       }
-end:
-       if (ret == 0) {
-               if (_real) {
-                       *_real = real;
-               }
-               if (_cycles) {
-                       *_cycles = cycles;
-               }
-       }
-       return ret;
-}
-
-/*
- * Find the union of all active regions in the trace collection's traces.
- * Returns "real" timestamps.
- *
- * Return 0 on success.
- * Return 1 if no intersections are found.
- * Return a negative value on error.
- */
-int ctf_find_tc_stream_packet_intersection_union(struct bt_context *ctx,
-               int64_t *_ts_begin, int64_t *_ts_end)
-{
-       int ret = 0, i;
-       int64_t ts_begin = INT64_MAX, ts_end = INT64_MIN;
-
-       if (!ctx || !ctx->tc || !ctx->tc->array || !_ts_begin || !_ts_end) {
-               ret = -EINVAL;
-               goto end;
-       }
-
-       for (i = 0; i < ctx->tc->array->len; i++) {
-               struct bt_trace_descriptor *td_read;
-               struct packet_index_time intersection_real;
-
-               td_read = g_ptr_array_index(ctx->tc->array, i);
-               if (!td_read) {
-                       continue;
-               }
-               ret = ctf_find_stream_intersection(td_read, &intersection_real,
-                               NULL);
-               if (ret == 1) {
-                       /* Empty trace or no stream intersection. */
-                       continue;
-               } else if (ret < 0) {
-                       goto end;
-               }
-
-               ts_begin = min(intersection_real.timestamp_begin, ts_begin);
-               ts_end = max(intersection_real.timestamp_end, ts_end);
-       }
-
-       if (ts_end < ts_begin) {
-               ret = 1;
-               goto end;
-       }
-       *_ts_begin = ts_begin;
-       *_ts_end = ts_end;
-end:
-       return ret;
-}
-
-int ctf_tc_set_stream_intersection_mode(struct bt_context *ctx)
-{
-       int ret = 0, i;
-
-       if (!ctx || !ctx->tc || !ctx->tc->array) {
-               ret = -EINVAL;
-               goto end;
-       }
-
-       for (i = 0; i < ctx->tc->array->len; i++) {
-               struct bt_trace_descriptor *td_read;
-               struct packet_index_time intersection_real;
-
-               td_read = g_ptr_array_index(ctx->tc->array, i);
-               if (!td_read) {
-                       continue;
-               }
-
-               ret = ctf_find_stream_intersection(td_read, &intersection_real,
-                               NULL);
-               if (ret == 1) {
-                       /* Empty trace or no stream intersection. */
-                       continue;
-               } else if (ret < 0) {
-                       goto end;
-               }
-
-               td_read->interval_real = intersection_real;
-               td_read->interval_set = true;
-       }
-end:
-       return ret;
-}
-
-/*
- * for SEEK_CUR: go to next packet.
- * for SEEK_SET: go to packet numer (index).
- */
-void ctf_packet_seek(struct bt_stream_pos *stream_pos, size_t index, int whence)
-{
-       struct ctf_stream_pos *pos =
-               container_of(stream_pos, struct ctf_stream_pos, parent);
-       struct ctf_file_stream *file_stream =
-               container_of(pos, struct ctf_file_stream, pos);
-       int ret;
-       struct packet_index *packet_index, *prev_index;
-
-       switch (whence) {
-       case SEEK_CUR:
-       case SEEK_SET:  /* Fall-through */
-               break;  /* OK */
-       default:
-               assert(0);
-       }
-
-       if ((pos->prot & PROT_WRITE) && pos->content_size_loc)
-               *pos->content_size_loc = pos->offset;
-
-       if (pos->base_mma) {
-               /* unmap old base */
-               ret = munmap_align(pos->base_mma);
-               if (ret) {
-                       fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
-                               strerror(errno));
-                       assert(0);
-               }
-               pos->base_mma = NULL;
-       }
-
-       /*
-        * The caller should never ask for ctf_move_pos across packets,
-        * except to get exactly at the beginning of the next packet.
-        */
-       if (pos->prot & PROT_WRITE) {
-               switch (whence) {
-               case SEEK_CUR:
-                       /* The writer will add padding */
-                       pos->mmap_offset += pos->packet_size / CHAR_BIT;
-                       break;
-               case SEEK_SET:
-                       assert(index == 0);     /* only seek supported for now */
-                       pos->cur_index = 0;
-                       break;
-               default:
-                       assert(0);
-               }
-               pos->content_size = -1U;        /* Unknown at this point */
-               pos->packet_size = WRITE_PACKET_LEN;
-               do {
-                       ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
-                                             pos->packet_size / CHAR_BIT);
-               } while (ret == EINTR);
-               assert(ret == 0);
-               pos->offset = 0;
-       } else {
-       read_next_packet:
-               switch (whence) {
-               case SEEK_CUR:
-               {
-                       if (pos->offset == EOF) {
-                               return;
-                       }
-                       assert(pos->cur_index < pos->packet_index->len);
-                       /* The reader will expect us to skip padding */
-                       ++pos->cur_index;
-                       break;
-               }
-               case SEEK_SET:
-                       if (index >= pos->packet_index->len) {
-                               pos->offset = EOF;
-                               return;
-                       }
-                       pos->cur_index = index;
-                       break;
-               default:
-                       assert(0);
-               }
-
-               if (pos->cur_index >= pos->packet_index->len) {
-                       pos->offset = EOF;
-                       return;
-               }
-
-               packet_index = &g_array_index(pos->packet_index,
-                               struct packet_index, pos->cur_index);
-               if (pos->cur_index > 0) {
-                       prev_index = &g_array_index(pos->packet_index,
-                                       struct packet_index,
-                                       pos->cur_index - 1);
-               } else {
-                       prev_index = NULL;
-               }
-               ctf_update_current_packet_index(&file_stream->parent,
-                               prev_index, packet_index);
-
-               /*
-                * We need to check if we are in trace read or called
-                * from packet indexing.  In this last case, the
-                * collection is not there, so we cannot print the
-                * timestamps.
-                */
-               if ((&file_stream->parent)->stream_class->trace->parent.collection) {
-                       ctf_print_discarded_lost(stderr, &file_stream->parent);
-               }
-
-               packet_index = &g_array_index(pos->packet_index,
-                               struct packet_index,
-                               pos->cur_index);
-               file_stream->parent.cycles_timestamp = packet_index->ts_cycles.timestamp_begin;
-
-               file_stream->parent.real_timestamp = packet_index->ts_real.timestamp_begin;
-
-               /* Lookup context/packet size in index */
-               if (packet_index->data_offset == -1) {
-                       ret = find_data_offset(pos, file_stream, packet_index);
-                       if (ret < 0) {
-                               return;
-                       }
-               }
-               pos->content_size = packet_index->content_size;
-               pos->packet_size = packet_index->packet_size;
-               pos->mmap_offset = packet_index->offset;
-               pos->data_offset = packet_index->data_offset;
-               if (pos->data_offset < packet_index->content_size) {
-                       pos->offset = 0;        /* will read headers */
-               } else if (pos->data_offset == packet_index->content_size) {
-                       /* empty packet */
-                       pos->offset = packet_index->data_offset;
-                       whence = SEEK_CUR;
-                       goto read_next_packet;
-               } else {
-                       pos->offset = EOF;
-                       return;
-               }
-       }
-       /* map new base. Need mapping length from header. */
-       pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
-                       pos->flags, pos->fd, pos->mmap_offset);
-       if (pos->base_mma == MAP_FAILED) {
-               fprintf(stderr, "[error] mmap error %s.\n",
-                       strerror(errno));
-               assert(0);
-       }
-
-       /* update trace_packet_header and stream_packet_context */
-       if (!(pos->prot & PROT_WRITE) &&
-               file_stream->parent.trace_packet_header) {
-               /* Read packet header */
-               ret = generic_rw(&pos->parent, &file_stream->parent.trace_packet_header->p);
-               assert(!ret);
-       }
-       if (!(pos->prot & PROT_WRITE) &&
-               file_stream->parent.stream_packet_context) {
-               /* Read packet context */
-               ret = generic_rw(&pos->parent, &file_stream->parent.stream_packet_context->p);
-               assert(!ret);
-       }
-}
-
-static
-int packet_metadata(struct ctf_trace *td, FILE *fp)
-{
-       uint32_t magic;
-       size_t len;
-       int ret = 0;
-
-       len = fread(&magic, sizeof(magic), 1, fp);
-       if (len != 1) {
-               goto end;
-       }
-       if (magic == TSDL_MAGIC) {
-               ret = 1;
-               td->byte_order = BYTE_ORDER;
-               CTF_TRACE_SET_FIELD(td, byte_order);
-       } else if (magic == GUINT32_SWAP_LE_BE(TSDL_MAGIC)) {
-               ret = 1;
-               td->byte_order = (BYTE_ORDER == BIG_ENDIAN) ?
-                                       LITTLE_ENDIAN : BIG_ENDIAN;
-               CTF_TRACE_SET_FIELD(td, byte_order);
-       }
-end:
-       rewind(fp);
-       return ret;
-}
-
-/*
- * Returns 0 on success, -1 on error.
- */
-static
-int check_version(unsigned int major, unsigned int minor)
-{
-       switch (major) {
-       case 1:
-               switch (minor) {
-               case 8:
-                       return 0;
-               default:
-                       goto warning;
-               }
-       default:
-               goto warning;
-
-       }
-
-       /* eventually return an error instead of warning */
-warning:
-       fprintf(stderr, "[warning] Unsupported CTF specification version %u.%u. Trying anyway.\n",
-               major, minor);
-       return 0;
-}
-
-static
-int ctf_trace_metadata_packet_read(struct ctf_trace *td, FILE *in,
-                                       FILE *out)
-{
-       struct metadata_packet_header header;
-       size_t readlen, writelen, toread;
-       char buf[4096 + 1];     /* + 1 for debug-mode \0 */
-       int ret = 0;
-
-       readlen = fread(&header, header_sizeof(header), 1, in);
-       if (readlen < 1)
-               return -EINVAL;
-
-       if (td->byte_order != BYTE_ORDER) {
-               header.magic = GUINT32_SWAP_LE_BE(header.magic);
-               header.checksum = GUINT32_SWAP_LE_BE(header.checksum);
-               header.content_size = GUINT32_SWAP_LE_BE(header.content_size);
-               header.packet_size = GUINT32_SWAP_LE_BE(header.packet_size);
-       }
-       if (header.checksum)
-               fprintf(stderr, "[warning] checksum verification not supported yet.\n");
-       if (header.compression_scheme) {
-               fprintf(stderr, "[error] compression (%u) not supported yet.\n",
-                       header.compression_scheme);
-               return -EINVAL;
-       }
-       if (header.encryption_scheme) {
-               fprintf(stderr, "[error] encryption (%u) not supported yet.\n",
-                       header.encryption_scheme);
-               return -EINVAL;
-       }
-       if (header.checksum_scheme) {
-               fprintf(stderr, "[error] checksum (%u) not supported yet.\n",
-                       header.checksum_scheme);
-               return -EINVAL;
-       }
-       if (check_version(header.major, header.minor) < 0)
-               return -EINVAL;
-       if (!CTF_TRACE_FIELD_IS_SET(td, uuid)) {
-               memcpy(td->uuid, header.uuid, sizeof(header.uuid));
-               CTF_TRACE_SET_FIELD(td, uuid);
-       } else {
-               if (bt_uuid_compare(header.uuid, td->uuid))
-                       return -EINVAL;
-       }
-
-       if ((header.content_size / CHAR_BIT) < header_sizeof(header))
-               return -EINVAL;
-
-       toread = (header.content_size / CHAR_BIT) - header_sizeof(header);
-
-       for (;;) {
-               readlen = fread(buf, sizeof(char), min(sizeof(buf) - 1, toread), in);
-               if (ferror(in)) {
-                       ret = -EINVAL;
-                       break;
-               }
-               if (babeltrace_debug) {
-                       buf[readlen] = '\0';
-                       fprintf(stderr, "[debug] metadata packet read: %s\n",
-                               buf);
-               }
-
-               writelen = fwrite(buf, sizeof(char), readlen, out);
-               if (writelen < readlen) {
-                       ret = -EIO;
-                       break;
-               }
-               if (ferror(out)) {
-                       ret = -EINVAL;
-                       break;
-               }
-               toread -= readlen;
-               if (!toread) {
-                       ret = 0;        /* continue reading next packet */
-                       goto read_padding;
-               }
-       }
-       return ret;
-
-read_padding:
-       toread = (header.packet_size - header.content_size) / CHAR_BIT;
-       ret = fseek(in, toread, SEEK_CUR);
-       if (ret < 0) {
-               fprintf(stderr, "[warning] Missing padding at end of file\n");
-               ret = 0;
-       }
-       return ret;
-}
-
-static
-int ctf_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp,
-                                       char **buf)
-{
-       FILE *in, *out;
-       size_t size, buflen;
-       int ret;
-
-       in = *fp;
-       /*
-        * Using strlen on *buf instead of size of open_memstream
-        * because its size includes garbage at the end (after final
-        * \0). This is the allocated size, not the actual string size.
-        */
-       out = bt_open_memstream(buf, &size);
-       if (out == NULL) {
-               perror("Metadata open_memstream");
-               return -errno;
-       }
-       for (;;) {
-               ret = ctf_trace_metadata_packet_read(td, in, out);
-               if (ret) {
-                       break;
-               }
-               if (feof(in)) {
-                       ret = 0;
-                       break;
-               }
-       }
-       /* close to flush the buffer */
-       ret = bt_close_memstream(buf, &size, out);
-       if (ret < 0) {
-               int closeret;
-
-               perror("babeltrace_flush_memstream");
-               ret = -errno;
-               closeret = fclose(in);
-               if (closeret) {
-                       perror("Error in fclose");
-               }
-               return ret;
-       }
-       ret = fclose(in);
-       if (ret) {
-               perror("Error in fclose");
-       }
-       /* open for reading */
-       buflen = strlen(*buf);
-       if (!buflen) {
-               *fp = NULL;
-               return -ENOENT;
-       }
-       *fp = bt_fmemopen(*buf, buflen, "rb");
-       if (!*fp) {
-               perror("Metadata fmemopen");
-               return -errno;
-       }
-       return 0;
-}
-
-static
-int ctf_trace_metadata_read(struct ctf_trace *td, FILE *metadata_fp,
-               struct ctf_scanner *scanner, int append)
-{
-       struct ctf_file_stream *metadata_stream;
-       FILE *fp;
-       char *buf = NULL;
-       int ret = 0, closeret;
-
-       metadata_stream = g_new0(struct ctf_file_stream, 1);
-       metadata_stream->pos.last_offset = LAST_OFFSET_POISON;
-
-       if (metadata_fp) {
-               fp = metadata_fp;
-               metadata_stream->pos.fd = -1;
-       } else {
-               td->metadata = &metadata_stream->parent;
-               metadata_stream->pos.fd = openat(td->dirfd, "metadata", O_RDONLY);
-               if (metadata_stream->pos.fd < 0) {
-                       fprintf(stderr, "Unable to open metadata.\n");
-                       ret = -1;
-                       goto end_free;
-               }
-
-               fp = fdopen(metadata_stream->pos.fd, "r");
-               if (!fp) {
-                       fprintf(stderr, "[error] Unable to open metadata stream.\n");
-                       perror("Metadata stream open");
-                       ret = -errno;
-                       goto end_stream;
-               }
-               /* fd now belongs to fp */
-               metadata_stream->pos.fd = -1;
-       }
-       if (babeltrace_debug)
-               yydebug = 1;
-
-       if (packet_metadata(td, fp)) {
-               ret = ctf_trace_metadata_stream_read(td, &fp, &buf);
-               if (ret) {
-                       goto end;
-               }
-               td->metadata_string = buf;
-               td->metadata_packetized = 1;
-       } else {
-               if (!append) {
-                       unsigned int major, minor;
-                       ssize_t nr_items;
-
-                       td->byte_order = BYTE_ORDER;
-
-                       /* Check text-only metadata header and version */
-                       nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor);
-                       if (nr_items < 2)
-                               fprintf(stderr, "[warning] Ill-shapen or missing \"/* CTF x.y\" header for text-only metadata.\n");
-                       if (check_version(major, minor) < 0) {
-                               ret = -EINVAL;
-                               goto end;
-                       }
-                       rewind(fp);
-               }
-       }
-
-       ret = ctf_scanner_append_ast(scanner, fp);
-       if (ret) {
-               fprintf(stderr, "[error] Error creating AST\n");
-               goto end;
-       }
-
-       if (babeltrace_debug) {
-               ret = ctf_visitor_print_xml(stderr, 0, &scanner->ast->root);
-               if (ret) {
-                       fprintf(stderr, "[error] Error visiting AST for XML output\n");
-                       goto end;
-               }
-       }
-
-       ret = ctf_visitor_semantic_check(stderr, 0, &scanner->ast->root);
-       if (ret) {
-               fprintf(stderr, "[error] Error in CTF semantic validation %d\n", ret);
-               goto end;
-       }
-       ret = ctf_visitor_construct_metadata(stderr, 0, &scanner->ast->root,
-                       td, td->byte_order);
-       if (ret) {
-               fprintf(stderr, "[error] Error in CTF metadata constructor %d\n", ret);
-               goto end;
-       }
-end:
-       if (fp) {
-               closeret = fclose(fp);
-               if (closeret) {
-                       perror("Error on fclose");
-               }
-       }
-end_stream:
-       if (metadata_stream->pos.fd >= 0) {
-               closeret = close(metadata_stream->pos.fd);
-               if (closeret) {
-                       perror("Error on metadata stream fd close");
-               }
-       }
-end_free:
-       if (ret)
-               g_free(metadata_stream);
-       return ret;
-}
-
-static
-struct ctf_event_definition *create_event_definitions(struct ctf_trace *td,
-                                                 struct ctf_stream_definition *stream,
-                                                 struct ctf_event_declaration *event)
-{
-       struct ctf_event_definition *stream_event = g_new0(struct ctf_event_definition, 1);
-
-       if (event->context_decl) {
-               struct bt_definition *definition =
-                       event->context_decl->p.definition_new(&event->context_decl->p,
-                               stream->parent_def_scope, 0, 0, "event.context");
-               if (!definition) {
-                       goto error;
-               }
-               stream_event->event_context = container_of(definition,
-                                       struct definition_struct, p);
-               stream->parent_def_scope = stream_event->event_context->p.scope;
-       }
-       if (event->fields_decl) {
-               struct bt_definition *definition =
-                       event->fields_decl->p.definition_new(&event->fields_decl->p,
-                               stream->parent_def_scope, 0, 0, "event.fields");
-               if (!definition) {
-                       goto error;
-               }
-               stream_event->event_fields = container_of(definition,
-                                       struct definition_struct, p);
-               stream->parent_def_scope = stream_event->event_fields->p.scope;
-       }
-       stream_event->stream = stream;
-       return stream_event;
-
-error:
-       if (stream_event->event_fields)
-               bt_definition_unref(&stream_event->event_fields->p);
-       if (stream_event->event_context)
-               bt_definition_unref(&stream_event->event_context->p);
-       fprintf(stderr, "[error] Unable to create event definition for event \"%s\".\n",
-               g_quark_to_string(event->name));
-       return NULL;
-}
-
-static
-int copy_event_declarations_stream_class_to_stream(struct ctf_trace *td,
-               struct ctf_stream_declaration *stream_class,
-               struct ctf_stream_definition *stream)
-{
-       size_t def_size, class_size, i;
-       int ret = 0;
-
-       def_size = stream->events_by_id->len;
-       class_size = stream_class->events_by_id->len;
-
-       g_ptr_array_set_size(stream->events_by_id, class_size);
-       for (i = def_size; i < class_size; i++) {
-               struct ctf_event_declaration *event =
-                       g_ptr_array_index(stream_class->events_by_id, i);
-               struct ctf_event_definition *stream_event;
-
-               if (!event)
-                       continue;
-               stream_event = create_event_definitions(td, stream, event);
-               if (!stream_event) {
-                       ret = -EINVAL;
-                       goto error;
-               }
-               g_ptr_array_index(stream->events_by_id, i) = stream_event;
-       }
-error:
-       return ret;
-}
-
-static
-int create_stream_definitions(struct ctf_trace *td, struct ctf_stream_definition *stream)
-{
-       struct ctf_stream_declaration *stream_class;
-       int ret;
-       int i;
-
-       if (stream->stream_definitions_created)
-               return 0;
-
-       stream_class = stream->stream_class;
-
-       if (stream_class->packet_context_decl) {
-               struct bt_definition *definition =
-                       stream_class->packet_context_decl->p.definition_new(&stream_class->packet_context_decl->p,
-                               stream->parent_def_scope, 0, 0, "stream.packet.context");
-               if (!definition) {
-                       ret = -EINVAL;
-                       goto error;
-               }
-               stream->stream_packet_context = container_of(definition,
-                                               struct definition_struct, p);
-               stream->parent_def_scope = stream->stream_packet_context->p.scope;
-       }
-       if (stream_class->event_header_decl) {
-               struct bt_definition *definition =
-                       stream_class->event_header_decl->p.definition_new(&stream_class->event_header_decl->p,
-                               stream->parent_def_scope, 0, 0, "stream.event.header");
-               if (!definition) {
-                       ret = -EINVAL;
-                       goto error;
-               }
-               stream->stream_event_header =
-                       container_of(definition, struct definition_struct, p);
-               stream->parent_def_scope = stream->stream_event_header->p.scope;
-       }
-       if (stream_class->event_context_decl) {
-               struct bt_definition *definition =
-                       stream_class->event_context_decl->p.definition_new(&stream_class->event_context_decl->p,
-                               stream->parent_def_scope, 0, 0, "stream.event.context");
-               if (!definition) {
-                       ret = -EINVAL;
-                       goto error;
-               }
-               stream->stream_event_context =
-                       container_of(definition, struct definition_struct, p);
-               stream->parent_def_scope = stream->stream_event_context->p.scope;
-       }
-       stream->events_by_id = g_ptr_array_new();
-       ret = copy_event_declarations_stream_class_to_stream(td,
-                       stream_class, stream);
-       if (ret)
-               goto error_event;
-       return 0;
-
-error_event:
-       for (i = 0; i < stream->events_by_id->len; i++) {
-               struct ctf_event_definition *stream_event = g_ptr_array_index(stream->events_by_id, i);
-               if (stream_event)
-                       g_free(stream_event);
-       }
-       g_ptr_array_free(stream->events_by_id, TRUE);
-error:
-       if (stream->stream_event_context)
-               bt_definition_unref(&stream->stream_event_context->p);
-       if (stream->stream_event_header)
-               bt_definition_unref(&stream->stream_event_header->p);
-       if (stream->stream_packet_context)
-               bt_definition_unref(&stream->stream_packet_context->p);
-       fprintf(stderr, "[error] Unable to create stream (%" PRIu64 ") definitions: %s\n",
-               stream_class->stream_id, strerror(-ret));
-       return ret;
-}
-
-static
-int stream_assign_class(struct ctf_trace *td,
-               struct ctf_file_stream *file_stream,
-               uint64_t stream_id)
-{
-       struct ctf_stream_declaration *stream;
-       int ret;
-
-       file_stream->parent.stream_id = stream_id;
-       if (stream_id >= td->streams->len) {
-               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
-               return -EINVAL;
-       }
-       stream = g_ptr_array_index(td->streams, stream_id);
-       if (!stream) {
-               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared in metadata.\n", stream_id);
-               return -EINVAL;
-       }
-       file_stream->parent.stream_class = stream;
-       ret = create_stream_definitions(td, &file_stream->parent);
-       if (ret)
-               return ret;
-       return 0;
-}
-
-static
-int create_stream_one_packet_index(struct ctf_stream_pos *pos,
-                       struct ctf_trace *td,
-                       struct ctf_file_stream *file_stream,
-                       size_t filesize)
-{
-       struct packet_index packet_index;
-       uint64_t stream_id = 0;
-       uint64_t packet_map_len = DEFAULT_HEADER_LEN, tmp_map_len;
-       int first_packet = 0;
-       int len_index;
-       int ret;
-
-begin:
-       memset(&packet_index, 0, sizeof(packet_index));
-       if (!pos->mmap_offset) {
-               first_packet = 1;
-       }
-
-       if (filesize - pos->mmap_offset < (packet_map_len >> LOG2_CHAR_BIT)) {
-               packet_map_len = (filesize - pos->mmap_offset) << LOG2_CHAR_BIT;
-       }
-
-       if (pos->base_mma) {
-               /* unmap old base */
-               ret = munmap_align(pos->base_mma);
-               if (ret) {
-                       fprintf(stderr, "[error] Unable to unmap old base: %s.\n",
-                               strerror(errno));
-                       return ret;
-               }
-               pos->base_mma = NULL;
-       }
-       /* map new base. Need mapping length from header. */
-       pos->base_mma = mmap_align(packet_map_len >> LOG2_CHAR_BIT, PROT_READ,
-                        MAP_PRIVATE, pos->fd, pos->mmap_offset);
-       assert(pos->base_mma != MAP_FAILED);
-       /*
-        * Use current mapping size as temporary content and packet
-        * size.
-        */
-       pos->content_size = packet_map_len;
-       pos->packet_size = packet_map_len;
-       pos->offset = 0;        /* Position of the packet header */
-
-       packet_index.offset = pos->mmap_offset;
-
-       /* read and check header, set stream id (and check) */
-       if (file_stream->parent.trace_packet_header) {
-               /* Read packet header */
-               ret = generic_rw(&pos->parent, &file_stream->parent.trace_packet_header->p);
-               if (ret) {
-                       if (ret == -EFAULT)
-                               goto retry;
-                       fprintf(stderr, "[error] Unable to read packet header: %s\n", strerror(-ret));
-                       return ret;
-               }
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_string("magic"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-                       uint64_t magic;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index);
-                       magic = bt_get_unsigned_int(field);
-                       if (magic != CTF_MAGIC) {
-                               fprintf(stderr, "[error] Invalid magic number 0x%" PRIX64 " at packet %u (file offset %zd).\n",
-                                               magic,
-                                               file_stream->pos.packet_index->len,
-                                               (ssize_t) pos->mmap_offset);
-                               return -EINVAL;
-                       }
-               }
-
-               /* check uuid */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_string("uuid"));
-               if (len_index >= 0) {
-                       struct definition_array *defarray;
-                       struct bt_definition *field;
-                       uint64_t i;
-                       uint8_t uuidval[BABELTRACE_UUID_LEN];
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index);
-                       assert(field->declaration->id == BT_CTF_TYPE_ID_ARRAY);
-                       defarray = container_of(field, struct definition_array, p);
-                       assert(bt_array_len(defarray) == BABELTRACE_UUID_LEN);
-
-                       for (i = 0; i < BABELTRACE_UUID_LEN; i++) {
-                               struct bt_definition *elem;
-
-                               elem = bt_array_index(defarray, i);
-                               uuidval[i] = bt_get_unsigned_int(elem);
-                       }
-                       ret = bt_uuid_compare(td->uuid, uuidval);
-                       if (ret) {
-                               fprintf(stderr, "[error] Unique Universal Identifiers do not match.\n");
-                               return -EINVAL;
-                       }
-               }
-
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.trace_packet_header->declaration, g_quark_from_string("stream_id"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.trace_packet_header, len_index);
-                       stream_id = bt_get_unsigned_int(field);
-               }
-       }
-
-       if (!first_packet && file_stream->parent.stream_id != stream_id) {
-               fprintf(stderr, "[error] Stream ID is changing within a stream: expecting %" PRIu64 ", but packet has %" PRIu64 "\n",
-                       stream_id,
-                       file_stream->parent.stream_id);
-               return -EINVAL;
-       }
-       if (first_packet) {
-               ret = stream_assign_class(td, file_stream, stream_id);
-               if (ret)
-                       return ret;
-       }
-
-       if (file_stream->parent.stream_packet_context) {
-               /* Read packet context */
-               ret = generic_rw(&pos->parent, &file_stream->parent.stream_packet_context->p);
-               if (ret) {
-                       if (ret == -EFAULT)
-                               goto retry;
-                       fprintf(stderr, "[error] Unable to read packet context: %s\n", strerror(-ret));
-                       return ret;
-               }
-               /* read packet size from header */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_string("packet_size"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index);
-                       packet_index.packet_size = bt_get_unsigned_int(field);
-               } else {
-                       /* Use file size for packet size */
-                       packet_index.packet_size = filesize * CHAR_BIT;
-               }
-
-               /* read content size from header */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_string("content_size"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index);
-                       packet_index.content_size = bt_get_unsigned_int(field);
-               } else {
-                       /* Use packet size if non-zero, else file size */
-                       packet_index.content_size = packet_index.packet_size ? : filesize * CHAR_BIT;
-               }
-
-               /* read timestamp begin from header */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_string("timestamp_begin"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index);
-                       packet_index.ts_cycles.timestamp_begin = bt_get_unsigned_int(field);
-                       if (file_stream->parent.stream_class->trace->parent.collection) {
-                               packet_index.ts_real.timestamp_begin =
-                                       ctf_get_real_timestamp(
-                                               &file_stream->parent,
-                                               packet_index.ts_cycles.timestamp_begin);
-                       }
-               }
-
-               /* read timestamp end from header */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_string("timestamp_end"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index);
-                       packet_index.ts_cycles.timestamp_end = bt_get_unsigned_int(field);
-                       if (file_stream->parent.stream_class->trace->parent.collection) {
-                               packet_index.ts_real.timestamp_end =
-                                       ctf_get_real_timestamp(
-                                               &file_stream->parent,
-                                               packet_index.ts_cycles.timestamp_end);
-                       }
-               }
-
-               /* read events discarded from header */
-               len_index = bt_struct_declaration_lookup_field_index(file_stream->parent.stream_packet_context->declaration, g_quark_from_string("events_discarded"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(file_stream->parent.stream_packet_context, len_index);
-                       packet_index.events_discarded = bt_get_unsigned_int(field);
-                       packet_index.events_discarded_len = bt_get_int_len(field);
-               }
-
-               /* read packet_seq_num from header */
-               len_index = bt_struct_declaration_lookup_field_index(
-                               file_stream->parent.stream_packet_context->declaration,
-                               g_quark_from_string("packet_seq_num"));
-               if (len_index >= 0) {
-                       struct bt_definition *field;
-
-                       field = bt_struct_definition_get_field_from_index(
-                                       file_stream->parent.stream_packet_context,
-                                       len_index);
-                       packet_index.packet_seq_num = bt_get_unsigned_int(field);
-               }
-       } else {
-               /* Use file size for packet size */
-               packet_index.packet_size = filesize * CHAR_BIT;
-               /* Use packet size if non-zero, else file size */
-               packet_index.content_size = packet_index.packet_size ? : filesize * CHAR_BIT;
-       }
-
-       /* Validate content size and packet size values */
-       if (packet_index.content_size > packet_index.packet_size) {
-               fprintf(stderr, "[error] Content size (%" PRIu64 " bits) is larger than packet size (%" PRIu64 " bits).\n",
-                       packet_index.content_size, packet_index.packet_size);
-               return -EINVAL;
-       }
-
-       if (packet_index.packet_size > ((uint64_t) filesize - packet_index.offset) * CHAR_BIT) {
-               fprintf(stderr, "[error] Packet size (%" PRIu64 " bits) is larger than remaining file size (%" PRIu64 " bits).\n",
-                       packet_index.packet_size, ((uint64_t) filesize - packet_index.offset) * CHAR_BIT);
-               return -EINVAL;
-       }
-
-       if (packet_index.content_size < pos->offset) {
-               fprintf(stderr, "[error] Invalid CTF stream: content size is smaller than packet headers.\n");
-               return -EINVAL;
-       }
-
-       if ((packet_index.packet_size >> LOG2_CHAR_BIT) == 0) {
-               fprintf(stderr, "[error] Invalid CTF stream: packet size needs to be at least one byte\n");
-               return -EINVAL;
-       }
-
-       /* Save position after header and context */
-       packet_index.data_offset = pos->offset;
-
-       /* add index to packet array */
-       g_array_append_val(file_stream->pos.packet_index, packet_index);
-
-       pos->mmap_offset += packet_index.packet_size >> LOG2_CHAR_BIT;
-
-       return 0;
-
-       /* Retry with larger mapping */
-retry:
-       if (packet_map_len == ((filesize - pos->mmap_offset) << LOG2_CHAR_BIT)) {
-               /*
-                * Reached EOF, but still expecting header/context data.
-                */
-               fprintf(stderr, "[error] Reached end of file, but still expecting header or context fields.\n");
-               return -EFAULT;
-       }
-       /* Double the mapping len, and retry */
-       tmp_map_len = packet_map_len << 1;
-       if (tmp_map_len >> 1 != packet_map_len) {
-               /* Overflow */
-               fprintf(stderr, "[error] Packet mapping length overflow\n");
-               return -EFAULT;
-       }
-       packet_map_len = tmp_map_len;
-       goto begin;
-}
-
-static
-int create_stream_packet_index(struct ctf_trace *td,
-                       struct ctf_file_stream *file_stream)
-{
-       struct ctf_stream_pos *pos;
-       struct stat filestats;
-       int ret;
-
-       pos = &file_stream->pos;
-
-       ret = fstat(pos->fd, &filestats);
-       if (ret < 0)
-               return ret;
-
-       /* Deal with empty files */
-       if (!filestats.st_size) {
-               if (file_stream->parent.trace_packet_header
-                               || file_stream->parent.stream_packet_context) {
-                       /*
-                        * We expect a trace packet header and/or stream packet
-                        * context. Since a trace needs to have at least one
-                        * packet, empty files are therefore not accepted.
-                        */
-                       fprintf(stderr, "[error] Encountered an empty file, but expecting a trace packet header.\n");
-                       return -EINVAL;
-               } else {
-                       /*
-                        * Without trace packet header nor stream packet
-                        * context, a one-packet trace can indeed be empty. This
-                        * is only valid if there is only one stream class: 0.
-                        */
-                       ret = stream_assign_class(td, file_stream, 0);
-                       if (ret)
-                               return ret;
-                       return 0;
-               }
-       }
-
-       for (pos->mmap_offset = 0; pos->mmap_offset < filestats.st_size; ) {
-               ret = create_stream_one_packet_index(pos, td, file_stream,
-                       filestats.st_size);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static
-int create_trace_definitions(struct ctf_trace *td, struct ctf_stream_definition *stream)
-{
-       int ret;
-
-       if (td->packet_header_decl) {
-               struct bt_definition *definition =
-                       td->packet_header_decl->p.definition_new(&td->packet_header_decl->p,
-                               stream->parent_def_scope, 0, 0, "trace.packet.header");
-               if (!definition) {
-                       ret = -EINVAL;
-                       goto error;
-               }
-               stream->trace_packet_header =
-                       container_of(definition, struct definition_struct, p);
-               stream->parent_def_scope = stream->trace_packet_header->p.scope;
-       }
-
-       return 0;
-
-error:
-       fprintf(stderr, "[error] Unable to create trace definitions: %s\n", strerror(-ret));
-       return ret;
-}
-
-static
-int import_stream_packet_index(struct ctf_trace *td,
-               struct ctf_file_stream *file_stream)
-{
-       struct ctf_stream_pos *pos;
-       struct ctf_packet_index *ctf_index = NULL;
-       struct ctf_packet_index_file_hdr index_hdr;
-       struct packet_index index;
-       uint32_t packet_index_len, index_minor;
-       int ret = 0;
-       int first_packet = 1;
-       size_t len;
-
-       pos = &file_stream->pos;
-
-       len = fread(&index_hdr, sizeof(index_hdr), 1, pos->index_fp);
-       if (len != 1) {
-               perror("read index file header");
-               goto error;
-       }
-
-       /* Check the index header */
-       if (be32toh(index_hdr.magic) != CTF_INDEX_MAGIC) {
-               fprintf(stderr, "[error] wrong index magic\n");
-               ret = -1;
-               goto error;
-       }
-       if (be32toh(index_hdr.index_major) != CTF_INDEX_MAJOR) {
-               fprintf(stderr, "[error] Incompatible index file %" PRIu32
-                               ".%" PRIu32 ", supported %d.%d\n",
-                               be32toh(index_hdr.index_major),
-                               be32toh(index_hdr.index_minor), CTF_INDEX_MAJOR,
-                               CTF_INDEX_MINOR);
-               ret = -1;
-               goto error;
-       }
-       index_minor = be32toh(index_hdr.index_minor);
-
-       packet_index_len = be32toh(index_hdr.packet_index_len);
-       if (packet_index_len == 0) {
-               fprintf(stderr, "[error] Packet index length cannot be 0.\n");
-               ret = -1;
-               goto error;
-       }
-       /*
-        * Allocate the index length found in header, not internal
-        * representation.
-        */
-       ctf_index = g_malloc0(packet_index_len);
-       while (fread(ctf_index, packet_index_len, 1,
-                       pos->index_fp) == 1) {
-               uint64_t stream_id;
-               struct ctf_stream_declaration *stream = NULL;
-
-               memset(&index, 0, sizeof(index));
-               index.offset = be64toh(ctf_index->offset);
-               index.packet_size = be64toh(ctf_index->packet_size);
-               index.content_size = be64toh(ctf_index->content_size);
-               index.ts_cycles.timestamp_begin = be64toh(ctf_index->timestamp_begin);
-               index.ts_cycles.timestamp_end = be64toh(ctf_index->timestamp_end);
-               index.events_discarded = be64toh(ctf_index->events_discarded);
-               index.events_discarded_len = 64;
-               index.data_offset = -1;
-               stream_id = be64toh(ctf_index->stream_id);
-               if (index_minor >= 1) {
-                       index.stream_instance_id = be64toh(ctf_index->stream_instance_id);
-                       index.packet_seq_num = be64toh(ctf_index->packet_seq_num);
-               }
-
-               if (!first_packet) {
-                       /* add index to packet array */
-                       g_array_append_val(file_stream->pos.packet_index, index);
-                       continue;
-               }
-
-               file_stream->parent.stream_id = stream_id;
-               if (stream_id < td->streams->len) {
-                       stream = g_ptr_array_index(td->streams, stream_id);
-               }
-               if (!stream) {
-                       fprintf(stderr, "[error] Stream %" PRIu64
-                                       " is not declared in metadata.\n",
-                                       stream_id);
-                       ret = -EINVAL;
-                       goto error;
-               }
-               file_stream->parent.stream_class = stream;
-               ret = create_stream_definitions(td, &file_stream->parent);
-               if (ret)
-                       goto error;
-               first_packet = 0;
-               /* add index to packet array */
-               g_array_append_val(file_stream->pos.packet_index, index);
-       }
-
-       /* Index containing only the header. */
-       if (!file_stream->parent.stream_class) {
-               ret = -1;
-               goto error;
-       }
-
-       ret = 0;
-
-error:
-       g_free(ctf_index);
-       return ret;
-}
-
-/*
- * Note: many file streams can inherit from the same stream class
- * description (metadata).
- */
-static
-int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence))
-{
-       int ret, fd, closeret;
-       struct ctf_file_stream *file_stream;
-       struct stat statbuf;
-       char *index_name;
-
-       fd = openat(td->dirfd, path, flags);
-       if (fd < 0) {
-               perror("File stream openat()");
-               ret = fd;
-               goto error;
-       }
-
-       /* Don't try to mmap subdirectories. Skip them, return success. */
-       ret = fstat(fd, &statbuf);
-       if (ret) {
-               perror("File stream fstat()");
-               goto fstat_error;
-       }
-       if (S_ISDIR(statbuf.st_mode)) {
-               if (strncmp(path, "index", 5) != 0) {
-                       fprintf(stderr, "[warning] Skipping directory '%s' "
-                                       "found in trace\n", path);
-               }
-               ret = 0;
-               goto fd_is_dir_ok;
-       }
-       if (!statbuf.st_size) {
-               /** Skip empty files. */
-               ret = 0;
-               goto fd_is_empty_file;
-       }
-
-       file_stream = g_new0(struct ctf_file_stream, 1);
-       file_stream->pos.last_offset = LAST_OFFSET_POISON;
-       file_stream->pos.fd = -1;
-       file_stream->pos.index_fp = NULL;
-
-       strncpy(file_stream->parent.path, path, PATH_MAX);
-       file_stream->parent.path[PATH_MAX - 1] = '\0';
-
-       if (packet_seek) {
-               file_stream->pos.packet_seek = packet_seek;
-       } else {
-               fprintf(stderr, "[error] packet_seek function undefined.\n");
-               ret = -1;
-               goto error_def;
-       }
-
-       ret = ctf_init_pos(&file_stream->pos, &td->parent, fd, flags);
-       if (ret)
-               goto error_def;
-       ret = create_trace_definitions(td, &file_stream->parent);
-       if (ret)
-               goto error_def;
-       /*
-        * For now, only a single clock per trace is supported.
-        */
-       file_stream->parent.current_clock = td->parent.single_clock;
-
-       /*
-        * Allocate the index name for this stream and try to open it.
-        */
-       index_name = malloc((strlen(path) + sizeof(INDEX_PATH)) * sizeof(char));
-       if (!index_name) {
-               fprintf(stderr, "[error] Cannot allocate index filename\n");
-               ret = -ENOMEM;
-               goto error_def;
-       }
-       snprintf(index_name, strlen(path) + sizeof(INDEX_PATH),
-                       INDEX_PATH, path);
-
-       if (bt_faccessat(td->dirfd, td->parent.path, index_name, O_RDONLY, 0) < 0) {
-               ret = create_stream_packet_index(td, file_stream);
-               if (ret) {
-                       fprintf(stderr, "[error] Stream index creation error.\n");
-                       goto error_index;
-               }
-       } else {
-               ret = openat(td->dirfd, index_name, flags);
-               if (ret < 0) {
-                       perror("Index file openat()");
-                       ret = -1;
-                       goto error_free;
-               }
-               file_stream->pos.index_fp = fdopen(ret, "r");
-               if (!file_stream->pos.index_fp) {
-                       perror("fdopen() error");
-                       goto error_free;
-               }
-               ret = import_stream_packet_index(td, file_stream);
-               if (ret) {
-                       ret = -1;
-                       goto error_index;
-               }
-               ret = fclose(file_stream->pos.index_fp);
-               if (ret < 0) {
-                       perror("close index");
-                       goto error_free;
-               }
-       }
-       free(index_name);
-
-       /* Add stream file to stream class */
-       g_ptr_array_add(file_stream->parent.stream_class->streams,
-                       &file_stream->parent);
-       return 0;
-
-error_index:
-       if (file_stream->pos.index_fp) {
-               ret = fclose(file_stream->pos.index_fp);
-               if (ret < 0) {
-                       perror("close index");
-               }
-       }
-       if (file_stream->parent.trace_packet_header)
-               bt_definition_unref(&file_stream->parent.trace_packet_header->p);
-error_free:
-       free(index_name);
-error_def:
-       closeret = ctf_fini_pos(&file_stream->pos);
-       if (closeret) {
-               fprintf(stderr, "Error on ctf_fini_pos\n");
-       }
-       g_free(file_stream);
-fd_is_empty_file:
-fd_is_dir_ok:
-fstat_error:
-       closeret = close(fd);
-       if (closeret) {
-               perror("Error on fd close");
-       }
-error:
-       return ret;
-}
-
-static
-int ctf_open_trace_read(struct ctf_trace *td,
-               const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_scanner *scanner;
-       int ret, closeret;
-       struct dirent *dirent;
-       struct dirent *diriter;
-       size_t dirent_len;
-       int pc_name_max;
-       char *ext;
-
-       td->flags = flags;
-
-       /* Open trace directory */
-       td->dir = opendir(path);
-       if (!td->dir) {
-               fprintf(stderr, "[error] Unable to open trace directory \"%s\".\n", path);
-               ret = -ENOENT;
-               goto error;
-       }
-
-       td->dirfd = open(path, 0);
-       if (td->dirfd < 0) {
-               fprintf(stderr, "[error] Unable to open trace directory file descriptor for path \"%s\".\n", path);
-               perror("Trace directory open");
-               ret = -errno;
-               goto error_dirfd;
-       }
-       strncpy(td->parent.path, path, sizeof(td->parent.path));
-       td->parent.path[sizeof(td->parent.path) - 1] = '\0';
-
-       /*
-        * Keep the metadata file separate.
-        * Keep scanner object local to the open. We don't support
-        * incremental metadata append for on-disk traces.
-        */
-       scanner = ctf_scanner_alloc();
-       if (!scanner) {
-               fprintf(stderr, "[error] Error allocating scanner\n");
-               ret = -ENOMEM;
-               goto error_metadata;
-       }
-       ret = ctf_trace_metadata_read(td, metadata_fp, scanner, 0);
-       ctf_scanner_free(scanner);
-       if (ret) {
-               if (ret == -ENOENT) {
-                       fprintf(stderr, "[warning] Empty metadata.\n");
-               }
-               fprintf(stderr, "[warning] Unable to open trace metadata for path \"%s\".\n", path);
-               goto error_metadata;
-       }
-
-       /*
-        * Open each stream: for each file, try to open, check magic
-        * number, and get the stream ID to add to the right location in
-        * the stream array.
-        */
-
-       pc_name_max = fpathconf(td->dirfd, _PC_NAME_MAX);
-       if (pc_name_max < 0) {
-               perror("Error on fpathconf");
-               fprintf(stderr, "[error] Failed to get _PC_NAME_MAX for path \"%s\".\n", path);
-               ret = -1;
-               goto error_metadata;
-       }
-
-       dirent_len = offsetof(struct dirent, d_name) + pc_name_max + 1;
-
-       dirent = malloc(dirent_len);
-
-       for (;;) {
-               ret = readdir_r(td->dir, dirent, &diriter);
-               if (ret) {
-                       fprintf(stderr, "[error] Readdir error.\n");
-                       goto readdir_error;
-               }
-               if (!diriter)
-                       break;
-               /* Ignore hidden files, ., .. and metadata. */
-               if (!strncmp(diriter->d_name, ".", 1)
-                               || !strcmp(diriter->d_name, "..")
-                               || !strcmp(diriter->d_name, "metadata"))
-                       continue;
-
-               /* Ignore index files : *.idx */
-               ext = strrchr(diriter->d_name, '.');
-               if (ext && (!strcmp(ext, ".idx"))) {
-                       continue;
-               }
-
-               ret = ctf_open_file_stream_read(td, diriter->d_name,
-                                       flags, packet_seek);
-               if (ret) {
-                       fprintf(stderr, "[error] Open file stream error.\n");
-                       goto readdir_error;
-               }
-       }
-
-       free(dirent);
-       return 0;
-
-readdir_error:
-       free(dirent);
-error_metadata:
-       closeret = close(td->dirfd);
-       if (closeret) {
-               perror("Error on fd close");
-       }
-error_dirfd:
-       closeret = closedir(td->dir);
-       if (closeret) {
-               perror("Error on closedir");
-       }
-error:
-       return ret;
-}
-
-/*
- * ctf_open_trace: Open a CTF trace and index it.
- * Note that the user must seek the trace after the open (using the iterator)
- * since the index creation read it entirely.
- */
-static
-struct bt_trace_descriptor *ctf_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_trace *td;
-       int ret;
-
-       /*
-        * If packet_seek is NULL, we provide our default version.
-        */
-       if (!packet_seek)
-               packet_seek = ctf_packet_seek;
-
-       td = g_new0(struct ctf_trace, 1);
-       if (!td) {
-               goto error;
-       }
-       init_trace_descriptor(&td->parent);
-
-       switch (flags & O_ACCMODE) {
-       case O_RDONLY:
-               if (!path) {
-                       fprintf(stderr, "[error] Path missing for input CTF trace.\n");
-                       goto error;
-               }
-               ret = ctf_open_trace_read(td, path, flags, packet_seek, metadata_fp);
-               if (ret)
-                       goto error;
-               break;
-       case O_RDWR:
-               fprintf(stderr, "[error] Opening CTF traces for output is not supported yet.\n");
-               goto error;
-       default:
-               fprintf(stderr, "[error] Incorrect open flags.\n");
-               goto error;
-       }
-
-       ret = trace_debug_info_create(td);
-       if (ret) {
-               goto error;
-       }
-
-       return &td->parent;
-error:
-       if (td) {
-               trace_debug_info_destroy(td);
-               g_free(td);
-       }
-       return NULL;
-}
-
-static
-void ctf_init_mmap_pos(struct ctf_stream_pos *pos,
-               struct bt_mmap_stream *mmap_info)
-{
-       pos->mmap_offset = 0;
-       pos->packet_size = 0;
-       pos->content_size = 0;
-       pos->content_size_loc = NULL;
-       pos->fd = mmap_info->fd;
-       pos->base_mma = NULL;
-       pos->offset = 0;
-       pos->dummy = false;
-       pos->cur_index = 0;
-       pos->prot = PROT_READ;
-       pos->flags = MAP_PRIVATE;
-       pos->parent.rw_table = read_dispatch_table;
-       pos->parent.event_cb = ctf_read_event;
-       pos->priv = mmap_info->priv;
-       pos->packet_index = g_array_new(FALSE, TRUE,
-                       sizeof(struct packet_index));
-}
-
-static
-int prepare_mmap_stream_definition(struct ctf_trace *td,
-               struct ctf_file_stream *file_stream,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence))
-{
-       struct ctf_stream_declaration *stream;
-       uint64_t stream_id;
-       int ret;
-
-       /* Ask for the first packet to get the stream_id. */
-       packet_seek(&file_stream->pos.parent, 0, SEEK_SET);
-       stream_id = file_stream->parent.stream_id;
-       if (stream_id >= td->streams->len) {
-               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared "
-                               "in metadata.\n", stream_id);
-               ret = -EINVAL;
-               goto end;
-       }
-       stream = g_ptr_array_index(td->streams, stream_id);
-       if (!stream) {
-               fprintf(stderr, "[error] Stream %" PRIu64 " is not declared "
-                               "in metadata.\n", stream_id);
-               ret = -EINVAL;
-               goto end;
-       }
-       file_stream->parent.stream_class = stream;
-       ret = create_stream_definitions(td, &file_stream->parent);
-end:
-       return ret;
-}
-
-static
-int ctf_open_mmap_stream_read(struct ctf_trace *td,
-               struct bt_mmap_stream *mmap_info,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence))
-{
-       int ret;
-       struct ctf_file_stream *file_stream;
-
-       file_stream = g_new0(struct ctf_file_stream, 1);
-       file_stream->parent.stream_id = -1ULL;
-       file_stream->pos.last_offset = LAST_OFFSET_POISON;
-       ctf_init_mmap_pos(&file_stream->pos, mmap_info);
-
-       file_stream->pos.packet_seek = packet_seek;
-
-       ret = create_trace_definitions(td, &file_stream->parent);
-       if (ret) {
-               goto error_def;
-       }
-
-       ret = prepare_mmap_stream_definition(td, file_stream, packet_seek);
-       if (ret)
-               goto error_index;
-
-       /*
-        * For now, only a single clock per trace is supported.
-        */
-       file_stream->parent.current_clock = td->parent.single_clock;
-
-       /* Add stream file to stream class */
-       g_ptr_array_add(file_stream->parent.stream_class->streams,
-                       &file_stream->parent);
-       return 0;
-
-error_index:
-       if (file_stream->parent.trace_packet_header)
-               bt_definition_unref(&file_stream->parent.trace_packet_header->p);
-error_def:
-       g_free(file_stream);
-       return ret;
-}
-
-static
-int ctf_open_mmap_trace_read(struct ctf_trace *td,
-               struct bt_mmap_stream_list *mmap_list,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence),
-               FILE *metadata_fp)
-{
-       int ret;
-       struct bt_mmap_stream *mmap_info;
-
-       td->scanner = ctf_scanner_alloc();
-       if (!td->scanner) {
-               fprintf(stderr, "[error] Error allocating scanner\n");
-               ret = -ENOMEM;
-               goto error;
-       }
-       ret = ctf_trace_metadata_read(td, metadata_fp, td->scanner, 0);
-       if (ret) {
-               if (ret == -ENOENT) {
-                       fprintf(stderr, "[warning] Empty metadata.\n");
-               }
-               goto error;
-       }
-
-       /*
-        * for each stream, try to open, check magic number, and get the
-        * stream ID to add to the right location in the stream array.
-        */
-       bt_list_for_each_entry(mmap_info, &mmap_list->head, list) {
-               ret = ctf_open_mmap_stream_read(td, mmap_info, packet_seek);
-               if (ret) {
-                       fprintf(stderr, "[error] Open file mmap stream error.\n");
-                       goto error;
-               }
-       }
-       return 0;
-
-error:
-       ctf_scanner_free(td->scanner);
-       return ret;
-}
-
-static
-struct bt_trace_descriptor *ctf_open_mmap_trace(
-               struct bt_mmap_stream_list *mmap_list,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence),
-               FILE *metadata_fp)
-{
-       struct ctf_trace *td;
-       int ret;
-
-       if (!metadata_fp) {
-               fprintf(stderr, "[error] No metadata file pointer associated, "
-                               "required for mmap parsing\n");
-               goto error;
-       }
-       if (!packet_seek) {
-               fprintf(stderr, "[error] packet_seek function undefined.\n");
-               goto error;
-       }
-       td = g_new0(struct ctf_trace, 1);
-       td->dirfd = -1;
-       ret = ctf_open_mmap_trace_read(td, mmap_list, packet_seek, metadata_fp);
-       if (ret)
-               goto error_free;
-
-       ret = trace_debug_info_create(td);
-       if (ret) {
-               goto error_free;
-       }
-
-       return &td->parent;
-
-error_free:
-       g_free(td);
-error:
-       return NULL;
-}
-
-int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp,
-               FILE *metadata_fp)
-{
-       struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent);
-       int i, j;
-       int ret;
-
-       if (!td->scanner)
-               return -EINVAL;
-       ret = ctf_trace_metadata_read(td, metadata_fp, td->scanner, 1);
-       if (ret)
-               return ret;
-       /* for each stream_class */
-       for (i = 0; i < td->streams->len; i++) {
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(td->streams, i);
-               if (!stream_class)
-                       continue;
-               /* for each stream */
-               for (j = 0; j < stream_class->streams->len; j++) {
-                       struct ctf_stream_definition *stream;
-
-                       stream = g_ptr_array_index(stream_class->streams, j);
-                       if (!stream)
-                               continue;
-                       ret = copy_event_declarations_stream_class_to_stream(td,
-                               stream_class, stream);
-                       if (ret)
-                               return ret;
-               }
-       }
-       return 0;
-}
-
-static
-int ctf_convert_index_timestamp(struct bt_trace_descriptor *tdp)
-{
-       int i, j, k;
-       struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent);
-
-       /* for each stream_class */
-       for (i = 0; i < td->streams->len; i++) {
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(td->streams, i);
-               if (!stream_class)
-                       continue;
-               /* for each file_stream */
-               for (j = 0; j < stream_class->streams->len; j++) {
-                       struct ctf_stream_definition *stream;
-                       struct ctf_stream_pos *stream_pos;
-                       struct ctf_file_stream *cfs;
-
-                       stream = g_ptr_array_index(stream_class->streams, j);
-                       if (!stream)
-                               continue;
-                       cfs = container_of(stream, struct ctf_file_stream,
-                                       parent);
-                       stream_pos = &cfs->pos;
-                       if (!stream_pos->packet_index)
-                               continue;
-
-                       for (k = 0; k < stream_pos->packet_index->len; k++) {
-                               struct packet_index *index;
-
-                               index = &g_array_index(stream_pos->packet_index,
-                                               struct packet_index, k);
-                               index->ts_real.timestamp_begin =
-                                       ctf_get_real_timestamp(stream,
-                                                       index->ts_cycles.timestamp_begin);
-                               index->ts_real.timestamp_end =
-                                       ctf_get_real_timestamp(stream,
-                                                       index->ts_cycles.timestamp_end);
-                       }
-               }
-       }
-       return 0;
-}
-
-static
-int ctf_close_file_stream(struct ctf_file_stream *file_stream)
-{
-       int ret;
-
-       ret = ctf_fini_pos(&file_stream->pos);
-       if (ret) {
-               fprintf(stderr, "Error on ctf_fini_pos\n");
-               return -1;
-       }
-       if (file_stream->pos.fd >= 0) {
-               ret = close(file_stream->pos.fd);
-               if (ret) {
-                       perror("Error closing file fd");
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static
-int ctf_close_trace(struct bt_trace_descriptor *tdp)
-{
-       struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent);
-       int ret;
-
-       if (td->streams) {
-               int i;
-
-               for (i = 0; i < td->streams->len; i++) {
-                       struct ctf_stream_declaration *stream;
-                       int j;
-
-                       stream = g_ptr_array_index(td->streams, i);
-                       if (!stream)
-                               continue;
-                       for (j = 0; j < stream->streams->len; j++) {
-                               struct ctf_file_stream *file_stream;
-                               file_stream = container_of(g_ptr_array_index(stream->streams, j),
-                                               struct ctf_file_stream, parent);
-                               ret = ctf_close_file_stream(file_stream);
-                               if (ret)
-                                       return ret;
-                       }
-               }
-       }
-       ctf_destroy_metadata(td);
-       ctf_scanner_free(td->scanner);
-       if (td->dirfd >= 0) {
-               ret = close(td->dirfd);
-               if (ret) {
-                       perror("Error closing dirfd");
-                       return ret;
-               }
-       }
-       if (td->dir) {
-               ret = closedir(td->dir);
-               if (ret) {
-                       perror("Error closedir");
-                       return ret;
-               }
-       }
-       free(td->metadata_string);
-       trace_debug_info_destroy(td);
-       g_free(td);
-       return 0;
-}
-
-static
-void ctf_set_context(struct bt_trace_descriptor *descriptor,
-               struct bt_context *ctx)
-{
-       struct ctf_trace *td = container_of(descriptor, struct ctf_trace,
-                       parent);
-
-       td->parent.ctx = ctx;
-}
-
-static
-void ctf_set_handle(struct bt_trace_descriptor *descriptor,
-               struct bt_trace_handle *handle)
-{
-       struct ctf_trace *td = container_of(descriptor, struct ctf_trace,
-                       parent);
-
-       td->parent.handle = handle;
-}
-
-static
-void __attribute__((constructor)) ctf_init(void)
-{
-       int ret;
-
-       ctf_format.name = g_quark_from_string("ctf");
-       ret = bt_register_format(&ctf_format);
-       assert(!ret);
-}
-
-static
-void __attribute__((destructor)) ctf_exit(void)
-{
-       bt_unregister_format(&ctf_format);
-}
diff --git a/formats/ctf/events-private.h b/formats/ctf/events-private.h
deleted file mode 100644 (file)
index c47fd7d..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _CTF_EVENTS_PRIVATE_H
-#define _CTF_EVENTS_PRIVATE_H
-
-/*
- * ctf/events-private.h
- *
- * Babeltrace Library
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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/events.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/clock-internal.h>
-
-static inline
-int64_t ctf_get_real_timestamp(struct ctf_stream_definition *stream,
-                       uint64_t ts_cycles)
-{
-       int64_t ts_nsec;
-       struct ctf_trace *trace = stream->stream_class->trace;
-       struct trace_collection *tc = trace->parent.collection;
-       int64_t tc_offset;
-
-       if (tc->clock_use_offset_avg)
-               tc_offset = tc->single_clock_offset_avg;
-       else
-               tc_offset = clock_offset_ns(trace->parent.single_clock);
-
-       ts_nsec = clock_cycles_to_ns(stream->current_clock, ts_cycles);
-       ts_nsec += tc_offset;   /* Add offset */
-       return ts_nsec;
-}
-
-#endif /* _CTF_EVENTS_PRIVATE_H */
diff --git a/formats/ctf/events.c b/formats/ctf/events.c
deleted file mode 100644 (file)
index 0eb688a..0000000
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * ctf/events.c
- *
- * Babeltrace Library
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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.h>
-#include <babeltrace/format.h>
-#include <babeltrace/ctf/events.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/prio_heap.h>
-#include <babeltrace/iterator-internal.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/ctf/metadata.h>
-#include <glib.h>
-
-#include "events-private.h"
-
-/*
- * thread local storage to store the last error that occured
- * while reading a field, this variable must be accessed by
- * bt_ctf_field_get_error only
- */
-__thread int bt_ctf_last_field_error = 0;
-
-const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event,
-               enum ctf_scope scope)
-{
-       const struct bt_definition *tmp = NULL;
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event)
-               return NULL;
-
-       event = ctf_event->parent;
-       switch (scope) {
-       case BT_TRACE_PACKET_HEADER:
-               if (!event->stream)
-                       goto error;
-               if (event->stream->trace_packet_header)
-                       tmp = &event->stream->trace_packet_header->p;
-               break;
-       case BT_STREAM_PACKET_CONTEXT:
-               if (!event->stream)
-                       goto error;
-               if (event->stream->stream_packet_context)
-                       tmp = &event->stream->stream_packet_context->p;
-               break;
-       case BT_STREAM_EVENT_HEADER:
-               if (!event->stream)
-                       goto error;
-               if (event->stream->stream_event_header)
-                       tmp = &event->stream->stream_event_header->p;
-               break;
-       case BT_STREAM_EVENT_CONTEXT:
-               if (!event->stream)
-                       goto error;
-               if (event->stream->stream_event_context)
-                       tmp = &event->stream->stream_event_context->p;
-               break;
-       case BT_EVENT_CONTEXT:
-               if (event->event_context)
-                       tmp = &event->event_context->p;
-               break;
-       case BT_EVENT_FIELDS:
-               if (event->event_fields)
-                       tmp = &event->event_fields->p;
-               break;
-       }
-       return tmp;
-
-error:
-       return NULL;
-}
-
-const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
-               const struct bt_definition *scope,
-               const char *field)
-{
-       const struct bt_definition *def;
-       char *field_underscore;
-
-       if (!ctf_event || !scope || !field)
-               return NULL;
-
-       def = bt_lookup_definition(scope, field);
-       /*
-        * optionally a field can have an underscore prefix, try
-        * to lookup the field with this prefix if it failed
-        */
-       if (!def) {
-               field_underscore = g_new(char, strlen(field) + 2);
-               field_underscore[0] = '_';
-               strcpy(&field_underscore[1], field);
-               def = bt_lookup_definition(scope, field_underscore);
-               g_free(field_underscore);
-       }
-       if (bt_ctf_field_type(bt_ctf_get_decl_from_def(def)) == CTF_TYPE_VARIANT) {
-               const struct definition_variant *variant_definition;
-               variant_definition = container_of(def,
-                               const struct definition_variant, p);
-               return variant_definition->current_field;
-       }
-       return def;
-}
-
-const struct bt_definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
-               const struct bt_definition *field,
-               unsigned int index)
-{
-       struct bt_definition *ret = NULL;
-
-       if (!ctf_event || !field)
-               return NULL;
-
-       if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) {
-               struct definition_array *array_definition;
-               array_definition = container_of(field,
-                               struct definition_array, p);
-               ret = bt_array_index(array_definition, index);
-       } else if (bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_SEQUENCE) {
-               struct definition_sequence *sequence_definition;
-               sequence_definition = container_of(field,
-                               struct definition_sequence, p);
-               ret = bt_sequence_index(sequence_definition, index);
-       }
-       return ret;
-}
-
-const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event)
-{
-       const struct ctf_event_declaration *event_class;
-       const struct ctf_stream_declaration *stream_class;
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event)
-               return NULL;
-
-       event = ctf_event->parent;
-       stream_class = event->stream->stream_class;
-       event_class = g_ptr_array_index(stream_class->events_by_id,
-                       event->stream->event_id);
-       return g_quark_to_string(event_class->name);
-}
-
-const char *bt_ctf_field_name(const struct bt_definition *def)
-{
-       if (!def || !def->name)
-               return NULL;
-
-       return rem_(g_quark_to_string(def->name));
-}
-
-enum ctf_type_id bt_ctf_field_type(const struct bt_declaration *decl)
-{
-       if (!decl)
-               return CTF_TYPE_UNKNOWN;
-
-       return decl->id;
-}
-
-int bt_ctf_get_field_list(const struct bt_ctf_event *ctf_event,
-               const struct bt_definition *scope,
-               struct bt_definition const * const **list,
-               unsigned int *count)
-{
-       if (!ctf_event || !scope || !list || !count)
-               return -EINVAL;
-
-       switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope))) {
-       case CTF_TYPE_INTEGER:
-       case CTF_TYPE_FLOAT:
-       case CTF_TYPE_STRING:
-       case CTF_TYPE_ENUM:
-               goto error;
-       case CTF_TYPE_STRUCT:
-       {
-               const struct definition_struct *def_struct;
-
-               def_struct = container_of(scope, const struct definition_struct, p);
-               if (!def_struct)
-                       goto error;
-               if (def_struct->fields->pdata) {
-                       *list = (struct bt_definition const* const*) def_struct->fields->pdata;
-                       *count = def_struct->fields->len;
-                       goto end;
-               } else {
-                       goto error;
-               }
-               break;
-       }
-       case CTF_TYPE_UNTAGGED_VARIANT:
-               goto error;
-       case CTF_TYPE_VARIANT:
-       {
-               const struct definition_variant *def_variant;
-
-               def_variant = container_of(scope, const struct definition_variant, p);
-               if (!def_variant)
-                       goto error;
-               if (def_variant->fields->pdata) {
-                       *list = (struct bt_definition const* const*) def_variant->fields->pdata;
-                       *count = def_variant->fields->len;
-                       goto end;
-               } else {
-                       goto error;
-               }
-               break;
-       }
-       case CTF_TYPE_ARRAY:
-       {
-               const struct definition_array *def_array;
-
-               def_array = container_of(scope, const struct definition_array, p);
-               if (!def_array)
-                       goto error;
-               if (def_array->elems->pdata) {
-                       *list = (struct bt_definition const* const*) def_array->elems->pdata;
-                       *count = def_array->elems->len;
-                       goto end;
-               } else {
-                       goto error;
-               }
-               break;
-       }
-       case CTF_TYPE_SEQUENCE:
-       {
-               const struct definition_sequence *def_sequence;
-
-               def_sequence = container_of(scope, const struct definition_sequence, p);
-               if (!def_sequence)
-                       goto error;
-               if (def_sequence->elems->pdata) {
-                       *list = (struct bt_definition const* const*) def_sequence->elems->pdata;
-                       *count = (unsigned int) def_sequence->length->value._unsigned;
-                       goto end;
-               } else {
-                       goto error;
-               }
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return 0;
-
-error:
-       *list = NULL;
-       *count = 0;
-       return -1;
-}
-
-struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event)
-{
-       struct bt_context *ret = NULL;
-       const struct ctf_file_stream *cfs;
-       const struct ctf_trace *trace;
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event)
-               return NULL;
-
-       event = ctf_event->parent;
-       cfs = container_of(event->stream, const struct ctf_file_stream,
-                       parent);
-       trace = cfs->parent.stream_class->trace;
-       if (trace->parent.ctx)
-               ret = trace->parent.ctx;
-
-       return ret;
-}
-
-int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event)
-{
-       int ret = -1;
-       const struct ctf_file_stream *cfs;
-       const struct ctf_trace *trace;
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event)
-               return -EINVAL;
-
-       event = ctf_event->parent;
-       cfs = container_of(event->stream, const struct ctf_file_stream,
-                       parent);
-       trace = cfs->parent.stream_class->trace;
-       if (trace->parent.handle)
-               ret = trace->parent.handle->id;
-
-       return ret;
-}
-
-int bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event, int64_t *timestamp)
-{
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event || !timestamp)
-               return -1;
-
-       event = ctf_event->parent;
-       if (event && event->stream->has_timestamp)
-               *timestamp = event->stream->real_timestamp;
-       else
-               return -1;
-       return 0;
-}
-
-uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event)
-{
-       const struct ctf_event_definition *event;
-
-       if (!ctf_event)
-               return -1ULL;
-
-       event = ctf_event->parent;
-       if (event && event->stream->has_timestamp)
-               return event->stream->cycles_timestamp;
-       else
-               return -1ULL;
-}
-
-static void bt_ctf_field_set_error(int error)
-{
-       bt_ctf_last_field_error = error;
-}
-
-int bt_ctf_field_get_error(void)
-{
-       int ret;
-       ret = bt_ctf_last_field_error;
-       bt_ctf_last_field_error = 0;
-
-       return ret;
-}
-
-static const struct declaration_integer *
-get_declaration_integer(const struct bt_declaration *decl)
-{
-       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER)
-               return NULL;
-       return container_of(decl, const struct declaration_integer, p);
-}
-
-static const struct declaration_string *
-get_declaration_string(const struct bt_declaration *decl)
-{
-       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING)
-               return NULL;
-       return container_of(decl, const struct declaration_string, p);
-}
-
-static const struct declaration_array *
-get_declaration_array(const struct bt_declaration *decl)
-{
-       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY)
-               return NULL;
-       return container_of(decl, const struct declaration_array, p);
-}
-
-static const struct declaration_sequence *
-get_declaration_sequence(const struct bt_declaration *decl)
-{
-       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_SEQUENCE)
-               return NULL;
-       return container_of(decl, const struct declaration_sequence, p);
-}
-
-int bt_ctf_get_int_signedness(const struct bt_declaration *decl)
-{
-       const struct declaration_integer *integer;
-
-       integer = get_declaration_integer(decl);
-       if (!integer) {
-               bt_ctf_field_set_error(-EINVAL);
-               return -EINVAL;
-       }
-       return integer->signedness;
-}
-
-int bt_ctf_get_int_base(const struct bt_declaration *decl)
-{
-       const struct declaration_integer *integer;
-
-       integer = get_declaration_integer(decl);
-       if (!integer) {
-               bt_ctf_field_set_error(-EINVAL);
-               return -EINVAL;
-       }
-       return integer->base;
-}
-
-int bt_ctf_get_int_byte_order(const struct bt_declaration *decl)
-{
-       const struct declaration_integer *integer;
-
-       integer = get_declaration_integer(decl);
-       if (!integer) {
-               bt_ctf_field_set_error(-EINVAL);
-               return -EINVAL;
-       }
-       return integer->byte_order;
-}
-
-ssize_t bt_ctf_get_int_len(const struct bt_declaration *decl)
-{
-       const struct declaration_integer *integer;
-
-       integer = get_declaration_integer(decl);
-       if (!integer) {
-               bt_ctf_field_set_error(-EINVAL);
-               return -EINVAL;
-       }
-       return (ssize_t) integer->len;
-}
-
-const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field)
-{
-       const struct definition_enum *def_enum;
-
-       if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) {
-               bt_ctf_field_set_error(-EINVAL);
-               return NULL;
-       }
-       def_enum = container_of(field, const struct definition_enum, p);
-       return &def_enum->integer->p;
-}
-
-const char *bt_ctf_get_enum_str(const struct bt_definition *field)
-{
-       const struct definition_enum *def_enum;
-       const struct declaration_enum *decl_enum;
-       GArray *array;
-       const char *ret;
-
-       if (!field || bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) != CTF_TYPE_ENUM) {
-               bt_ctf_field_set_error(-EINVAL);
-               return NULL;
-       }
-       def_enum = container_of(field, const struct definition_enum, p);
-       decl_enum = def_enum->declaration;
-       if (bt_get_int_signedness(&def_enum->integer->p)) {
-               array = bt_enum_int_to_quark_set(decl_enum,
-                       bt_get_signed_int(&def_enum->integer->p));
-       } else {
-               array = bt_enum_uint_to_quark_set(decl_enum,
-                       bt_get_unsigned_int(&def_enum->integer->p));
-       }
-       if (!array) {
-               bt_ctf_field_set_error(-ENOENT);
-               return NULL;
-       }
-
-       if (array->len == 0) {
-               g_array_unref(array);
-               bt_ctf_field_set_error(-ENOENT);
-               return NULL;
-       }
-       /* Return first string. Arbitrary choice. */
-       ret = g_quark_to_string(g_array_index(array, GQuark, 0));
-       g_array_unref(array);
-       return ret;
-}
-
-enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *decl)
-{
-       enum ctf_string_encoding ret = 0;
-       enum ctf_type_id type;
-       const struct declaration_integer *integer;
-       const struct declaration_string *string;
-       const struct declaration_array *array;
-       const struct declaration_sequence *sequence;
-
-       if (!decl)
-               goto error;
-
-       type = bt_ctf_field_type(decl);
-
-       switch (type) {
-       case CTF_TYPE_ARRAY:
-               array = get_declaration_array(decl);
-               if (!array)
-                       goto error;
-               integer = get_declaration_integer(array->elem);
-               if (!integer)
-                       goto error;
-               ret = integer->encoding;
-               break;
-       case CTF_TYPE_SEQUENCE:
-               sequence = get_declaration_sequence(decl);
-               if (!sequence)
-                       goto error;
-               integer = get_declaration_integer(sequence->elem);
-               if (!integer)
-                       goto error;
-               ret = integer->encoding;
-               break;
-       case CTF_TYPE_STRING:
-               string = get_declaration_string(decl);
-               if (!string)
-                       goto error;
-               ret = string->encoding;
-               break;
-       case CTF_TYPE_INTEGER:
-               integer = get_declaration_integer(decl);
-               if (!integer)
-                       goto error;
-               ret = integer->encoding;
-               break;
-       default:
-               goto error;
-       }
-       return ret;
-
-error:
-       bt_ctf_field_set_error(-EINVAL);
-       return -1;
-}
-
-int bt_ctf_get_array_len(const struct bt_declaration *decl)
-{
-       const struct declaration_array *array;
-
-       array = get_declaration_array(decl);
-       if (!array)
-               goto error;
-       return array->len;
-
-error:
-       bt_ctf_field_set_error(-EINVAL);
-       return -1;
-}
-
-uint64_t bt_ctf_get_uint64(const struct bt_definition *field)
-{
-       uint64_t ret = 0;
-
-       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
-               ret = bt_get_unsigned_int(field);
-       else
-               bt_ctf_field_set_error(-EINVAL);
-
-       return ret;
-}
-
-int64_t bt_ctf_get_int64(const struct bt_definition *field)
-{
-       int64_t ret = 0;
-
-       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
-               ret = bt_get_signed_int(field);
-       else
-               bt_ctf_field_set_error(-EINVAL);
-
-       return ret;
-}
-
-char *bt_ctf_get_char_array(const struct bt_definition *field)
-{
-       char *ret = NULL;
-       GString *char_array;
-
-       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) {
-               char_array = bt_get_char_array(field);
-               if (char_array) {
-                       ret = char_array->str;
-                       goto end;
-               }
-       }
-       bt_ctf_field_set_error(-EINVAL);
-
-end:
-       return ret;
-}
-
-char *bt_ctf_get_string(const struct bt_definition *field)
-{
-       char *ret = NULL;
-
-       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING)
-               ret = bt_get_string(field);
-       else
-               bt_ctf_field_set_error(-EINVAL);
-
-       return ret;
-}
-
-double bt_ctf_get_float(const struct bt_definition *field)
-{
-       double ret = 0.0;
-
-       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_FLOAT) {
-               ret = bt_get_float(field);
-       } else {
-               bt_ctf_field_set_error(-EINVAL);
-       }
-
-       return ret;
-}
-
-const struct bt_definition *bt_ctf_get_variant(const struct bt_definition *field)
-{
-       const struct bt_definition *ret = NULL;
-
-       if (field && bt_ctf_field_type(
-               bt_ctf_get_decl_from_def(field)) == CTF_TYPE_VARIANT) {
-               struct definition_variant *variant = container_of(field,
-                       struct definition_variant, p);
-
-               ret = bt_variant_get_current_field(variant);
-       } else {
-               bt_ctf_field_set_error(-EINVAL);
-       }
-
-       return ret;
-}
-
-uint64_t bt_ctf_get_struct_field_count(const struct bt_definition *field)
-{
-       uint64_t ret = -1;
-       const struct bt_declaration *declaration =
-               bt_ctf_get_decl_from_def(field);
-
-       if (field && bt_ctf_field_type(declaration) == CTF_TYPE_STRUCT) {
-               const struct declaration_struct *struct_declaration =
-                       container_of(declaration, struct declaration_struct, p);
-
-               ret = bt_struct_declaration_len(struct_declaration);
-       } else {
-               bt_ctf_field_set_error(-EINVAL);
-       }
-
-       return ret;
-}
-
-const struct bt_definition *bt_ctf_get_struct_field_index(
-               const struct bt_definition *field, uint64_t i)
-{
-       const struct bt_definition *ret = NULL;
-
-       if (field && bt_ctf_field_type(
-               bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRUCT &&
-               i < bt_ctf_get_struct_field_count(field)) {
-               const struct definition_struct *structure = container_of(
-                       field, struct definition_struct, p);
-
-               ret = bt_struct_definition_get_field_from_index(structure, i);
-       }
-
-       if (!ret) {
-               bt_ctf_field_set_error(-EINVAL);
-       }
-
-       return ret;
-}
-
-int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx,
-               struct bt_ctf_event_decl * const **list,
-               unsigned int *count)
-{
-       struct bt_trace_handle *handle;
-       struct bt_trace_descriptor *td;
-       struct ctf_trace *tin;
-
-       if (!ctx || !list || !count)
-               goto error;
-
-       handle = g_hash_table_lookup(ctx->trace_handles,
-                       GUINT_TO_POINTER(handle_id));
-       if (!handle)
-               goto error;
-
-       td = handle->td;
-       tin = container_of(td, struct ctf_trace, parent);
-
-       *list = (struct bt_ctf_event_decl * const*) tin->event_declarations->pdata;
-       *count = tin->event_declarations->len;
-       return 0;
-
-error:
-       return -1;
-}
-
-const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event)
-{
-       if (!event)
-               return NULL;
-
-       return g_quark_to_string(event->parent.name);
-}
-
-uint64_t bt_ctf_get_decl_event_id(const struct bt_ctf_event_decl *event)
-{
-       if (!event)
-               return (uint64_t)(-1);
-
-       return event->parent.id;
-}
-
-int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl,
-               enum ctf_scope scope,
-               struct bt_ctf_field_decl const * const **list,
-               unsigned int *count)
-{
-       int i;
-       GArray *fields = NULL;
-       gpointer *ret_list = NULL;
-       GPtrArray *fields_array = NULL;
-       int ret = 0;
-
-       if (!event_decl || !list || !count)
-               return -EINVAL;
-
-       *count = 0;
-       switch (scope) {
-       case BT_EVENT_CONTEXT:
-               if (event_decl->context_decl) {
-                       ret_list = event_decl->context_decl->pdata;
-                       *count = event_decl->context_decl->len;
-                       goto end;
-               }
-               event_decl->context_decl = g_ptr_array_new();
-               if (!event_decl->parent.context_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.context_decl->fields;
-               fields_array = event_decl->context_decl;
-               break;
-       case BT_EVENT_FIELDS:
-               if (event_decl->fields_decl) {
-                       ret_list = event_decl->fields_decl->pdata;
-                       *count = event_decl->fields_decl->len;
-                       goto end;
-               }
-               event_decl->fields_decl = g_ptr_array_new();
-               if (!event_decl->parent.fields_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.fields_decl->fields;
-               fields_array = event_decl->fields_decl;
-               break;
-       case BT_STREAM_PACKET_CONTEXT:
-               if (event_decl->packet_context_decl) {
-                       ret_list = event_decl->packet_context_decl->pdata;
-                       *count = event_decl->packet_context_decl->len;
-                       goto end;
-               }
-               event_decl->packet_context_decl = g_ptr_array_new();
-               if (!event_decl->parent.stream->packet_context_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.stream->packet_context_decl->fields;
-               fields_array = event_decl->packet_context_decl;
-               break;
-       case BT_STREAM_EVENT_CONTEXT:
-               if (event_decl->event_context_decl) {
-                       ret_list = event_decl->event_context_decl->pdata;
-                       *count = event_decl->event_context_decl->len;
-                       goto end;
-               }
-               event_decl->event_context_decl = g_ptr_array_new();
-               if (!event_decl->parent.stream->event_context_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.stream->event_context_decl->fields;
-               fields_array = event_decl->event_context_decl;
-               break;
-       case BT_STREAM_EVENT_HEADER:
-               if (event_decl->event_header_decl) {
-                       ret_list = event_decl->event_header_decl->pdata;
-                       *count = event_decl->event_header_decl->len;
-                       goto end;
-               }
-               event_decl->event_header_decl = g_ptr_array_new();
-               if (!event_decl->parent.stream->event_header_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.stream->event_header_decl->fields;
-               fields_array = event_decl->event_header_decl;
-               break;
-       case BT_TRACE_PACKET_HEADER:
-               if (event_decl->packet_header_decl) {
-                       ret_list = event_decl->packet_header_decl->pdata;
-                       *count = event_decl->packet_header_decl->len;
-                       goto end;
-               }
-               event_decl->packet_header_decl = g_ptr_array_new();
-               if (!event_decl->parent.stream->trace->packet_header_decl) {
-                       ret = -1;
-                       goto end;
-               }
-               fields = event_decl->parent.stream->trace->packet_header_decl->fields;
-               fields_array = event_decl->packet_header_decl;
-               break;
-       }
-
-       for (i = 0; i < fields->len; i++) {
-               g_ptr_array_add(fields_array,
-                               &g_array_index(fields,
-                                       struct declaration_field, i));
-       }
-       ret_list = fields_array->pdata;
-       *count = fields->len;
-
-end:
-       *list = (struct bt_ctf_field_decl const* const*) ret_list;
-
-       return ret;
-}
-
-const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field)
-{
-       if (!field)
-               return NULL;
-
-       return rem_(g_quark_to_string(((struct declaration_field *) field)->name));
-}
-
-const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *def)
-{
-       if (def)
-               return def->declaration;
-
-       return NULL;
-}
-
-const struct bt_declaration *bt_ctf_get_decl_from_field_decl(
-               const struct bt_ctf_field_decl *field)
-{
-       if (field)
-               return ((struct declaration_field *) field)->declaration;
-
-       return NULL;
-}
diff --git a/formats/ctf/ir/Makefile.am b/formats/ctf/ir/Makefile.am
deleted file mode 100644 (file)
index b22fa80..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libctf-ir.la
-
-libctf_ir_la_SOURCES = \
-       attributes.c \
-       clock-class.c \
-       event.c \
-       event-class.c \
-       fields.c \
-       field-types.c \
-       field-path.c \
-       packet.c \
-       stream.c \
-       stream-class.c \
-       trace.c \
-       utils.c \
-       resolve.c \
-       validation.c \
-       visitor.c
-
-libctf_ir_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
-
-if BABELTRACE_BUILD_WITH_LIBUUID
-libctf_ir_la_LIBADD += -luuid
-endif
-if BABELTRACE_BUILD_WITH_LIBC_UUID
-libctf_ir_la_LIBADD += -lc
-endif
diff --git a/formats/ctf/ir/attributes.c b/formats/ctf/ir/attributes.c
deleted file mode 100644 (file)
index c6e8a23..0000000
+++ /dev/null
@@ -1,291 +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.
- */
-
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-
-#define BT_CTF_ATTR_NAME_INDEX         0
-#define BT_CTF_ATTR_VALUE_INDEX                1
-
-BT_HIDDEN
-struct bt_value *bt_ctf_attributes_create(void)
-{
-       /*
-        * 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]
-        *     ]
-        */
-       return bt_value_array_create();
-}
-
-BT_HIDDEN
-void bt_ctf_attributes_destroy(struct bt_value *attr_obj)
-{
-       bt_put(attr_obj);
-}
-
-BT_HIDDEN
-int bt_ctf_attributes_get_count(struct bt_value *attr_obj)
-{
-       return bt_value_array_size(attr_obj);
-}
-
-BT_HIDDEN
-const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
-               int 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 || index < 0) {
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_get(attr_obj, index);
-
-       if (!attr_field_obj) {
-               goto end;
-       }
-
-       attr_field_name_obj = bt_value_array_get(attr_field_obj,
-               BT_CTF_ATTR_NAME_INDEX);
-
-       if (!attr_field_name_obj) {
-               goto end;
-       }
-
-       rc = bt_value_string_get(attr_field_name_obj, &ret);
-
-       if (rc) {
-               ret = NULL;
-       }
-
-end:
-       BT_PUT(attr_field_name_obj);
-       BT_PUT(attr_field_obj);
-       return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_ctf_attributes_get_field_value(struct bt_value *attr_obj,
-               int index)
-{
-       struct bt_value *value_obj = NULL;
-       struct bt_value *attr_field_obj = NULL;
-
-       if (!attr_obj || index < 0) {
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_get(attr_obj, index);
-
-       if (!attr_field_obj) {
-               goto end;
-       }
-
-       value_obj = bt_value_array_get(attr_field_obj,
-               BT_CTF_ATTR_VALUE_INDEX);
-
-end:
-       BT_PUT(attr_field_obj);
-       return value_obj;
-}
-
-static
-struct bt_value *bt_ctf_attributes_get_field_by_name(
-               struct bt_value *attr_obj, const char *name)
-{
-       int i;
-       int 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) {
-               goto error;
-       }
-
-       for (i = 0; i < attr_size; ++i) {
-               int ret;
-               const char *field_name;
-
-               value_obj = bt_value_array_get(attr_obj, i);
-
-               if (!value_obj) {
-                       goto error;
-               }
-
-               attr_field_name_obj = bt_value_array_get(value_obj, 0);
-
-               if (!attr_field_name_obj) {
-                       goto error;
-               }
-
-               ret = bt_value_string_get(attr_field_name_obj, &field_name);
-               if (ret) {
-                       goto error;
-               }
-
-               if (!strcmp(field_name, name)) {
-                       BT_PUT(attr_field_name_obj);
-                       break;
-               }
-
-               BT_PUT(attr_field_name_obj);
-               BT_PUT(value_obj);
-       }
-
-       return value_obj;
-
-error:
-       BT_PUT(attr_field_name_obj);
-       BT_PUT(value_obj);
-
-       return value_obj;
-}
-
-BT_HIDDEN
-int bt_ctf_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) {
-               ret = -1;
-               goto end;
-       }
-
-       attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
-
-       if (attr_field_obj) {
-               ret = bt_value_array_set(attr_field_obj,
-                       BT_CTF_ATTR_VALUE_INDEX, value_obj);
-               goto end;
-       }
-
-       attr_field_obj = bt_value_array_create();
-
-       if (!attr_field_obj) {
-               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) {
-               goto end;
-       }
-
-       ret = bt_value_array_append(attr_obj, attr_field_obj);
-
-end:
-       BT_PUT(attr_field_obj);
-
-       return ret;
-}
-
-BT_HIDDEN
-struct bt_value *bt_ctf_attributes_get_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) {
-               goto end;
-       }
-
-       attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
-
-       if (!attr_field_obj) {
-               goto end;
-       }
-
-       value_obj = bt_value_array_get(attr_field_obj,
-               BT_CTF_ATTR_VALUE_INDEX);
-
-end:
-       BT_PUT(attr_field_obj);
-
-       return value_obj;
-}
-
-BT_HIDDEN
-int bt_ctf_attributes_freeze(struct bt_value *attr_obj)
-{
-       int i;
-       int count;
-       int ret = 0;
-
-       if (!attr_obj) {
-               ret = -1;
-               goto end;
-       }
-
-       count = bt_value_array_size(attr_obj);
-
-       if (count < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * 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_ctf_attributes_get_field_value(attr_obj, i);
-
-               if (!obj) {
-                       ret = -1;
-                       goto end;
-               }
-
-               bt_value_freeze(obj);
-               BT_PUT(obj);
-       }
-
-end:
-       return ret;
-}
diff --git a/formats/ctf/ir/clock-class.c b/formats/ctf/ir/clock-class.c
deleted file mode 100644 (file)
index 66f7f44..0000000
+++ /dev/null
@@ -1,497 +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.
- */
-
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler.h>
-#include <inttypes.h>
-
-static
-void bt_ctf_clock_class_destroy(struct bt_object *obj);
-
-BT_HIDDEN
-bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
-{
-       return clock_class && clock_class->name;
-}
-
-int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
-               const char *name)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_validate_identifier(name)) {
-               ret = -1;
-               goto end;
-       }
-
-       if (clock_class->name) {
-               g_string_assign(clock_class->name, name);
-       } else {
-               clock_class->name = g_string_new(name);
-               if (!clock_class->name) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name)
-{
-       int ret;
-       struct bt_ctf_clock_class *clock_class =
-               g_new0(struct bt_ctf_clock_class, 1);
-
-       if (!clock_class) {
-               goto error;
-       }
-
-       clock_class->precision = 1;
-       clock_class->frequency = 1000000000;
-       bt_object_init(clock_class, bt_ctf_clock_class_destroy);
-
-       if (name) {
-               ret = bt_ctf_clock_class_set_name(clock_class, name);
-               if (ret) {
-                       goto error;
-               }
-       }
-
-       ret = bt_uuid_generate(clock_class->uuid);
-       if (ret) {
-               goto error;
-       }
-
-       clock_class->uuid_set = 1;
-       return clock_class;
-error:
-       BT_PUT(clock_class);
-       return clock_class;
-}
-
-const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
-{
-       const char *ret = NULL;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       if (clock_class->name) {
-               ret = clock_class->name->str;
-       }
-
-end:
-       return ret;
-}
-
-const char *bt_ctf_clock_class_get_description(
-               struct bt_ctf_clock_class *clock_class)
-{
-       const char *ret = NULL;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       if (clock_class->description) {
-               ret = clock_class->description->str;
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
-               const char *desc)
-{
-       int ret = 0;
-
-       if (!clock_class || !desc || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->description = g_string_new(desc);
-       ret = clock_class->description ? 0 : -1;
-end:
-       return ret;
-}
-
-uint64_t bt_ctf_clock_class_get_frequency(
-               struct bt_ctf_clock_class *clock_class)
-{
-       uint64_t ret = -1ULL;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       ret = clock_class->frequency;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
-               uint64_t freq)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->frequency = freq;
-end:
-       return ret;
-}
-
-uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
-{
-       uint64_t ret = -1ULL;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       ret = clock_class->precision;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
-               uint64_t precision)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->precision = precision;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
-               int64_t *offset_s)
-{
-       int ret = 0;
-
-       if (!clock_class || !offset_s) {
-               ret = -1;
-               goto end;
-       }
-
-       *offset_s = clock_class->offset_s;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
-               int64_t offset_s)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->offset_s = offset_s;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
-               int64_t *offset)
-{
-       int ret = 0;
-
-       if (!clock_class || !offset) {
-               ret = -1;
-               goto end;
-       }
-
-       *offset = clock_class->offset;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
-               int64_t offset)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->offset = offset;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_get_is_absolute(struct bt_ctf_clock_class *clock_class)
-{
-       int ret = -1;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       ret = clock_class->absolute;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
-               int is_absolute)
-{
-       int ret = 0;
-
-       if (!clock_class || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       clock_class->absolute = !!is_absolute;
-end:
-       return ret;
-}
-
-const unsigned char *bt_ctf_clock_class_get_uuid(
-               struct bt_ctf_clock_class *clock_class)
-{
-       const unsigned char *ret;
-
-       if (!clock_class || !clock_class->uuid_set) {
-               ret = NULL;
-               goto end;
-       }
-
-       ret = clock_class->uuid;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
-               const unsigned char *uuid)
-{
-       int ret = 0;
-
-       if (!clock_class || !uuid || clock_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       memcpy(clock_class->uuid, uuid, sizeof(uuid_t));
-       clock_class->uuid_set = 1;
-end:
-       return ret;
-}
-
-static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
-{
-       uint64_t ns;
-
-       if (frequency == 1000000000) {
-               ns = value;
-       } else {
-               ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
-       }
-
-       return ns;
-}
-
-BT_HIDDEN
-void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
-{
-       if (!clock_class) {
-               return;
-       }
-
-       clock_class->frozen = 1;
-}
-
-BT_HIDDEN
-void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
-               struct metadata_context *context)
-{
-       unsigned char *uuid;
-
-       if (!clock_class || !context) {
-               return;
-       }
-
-       uuid = clock_class->uuid;
-       g_string_append(context->string, "clock {\n");
-       g_string_append_printf(context->string, "\tname = %s;\n",
-               clock_class->name->str);
-       g_string_append_printf(context->string,
-               "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
-               uuid[0], uuid[1], uuid[2], uuid[3],
-               uuid[4], uuid[5], uuid[6], uuid[7],
-               uuid[8], uuid[9], uuid[10], uuid[11],
-               uuid[12], uuid[13], uuid[14], uuid[15]);
-       if (clock_class->description) {
-               g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
-                       clock_class->description->str);
-       }
-
-       g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
-               clock_class->frequency);
-       g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
-               clock_class->precision);
-       g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
-               clock_class->offset_s);
-       g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
-               clock_class->offset);
-       g_string_append_printf(context->string, "\tabsolute = %s;\n",
-               clock_class->absolute ? "TRUE" : "FALSE");
-       g_string_append(context->string, "};\n\n");
-}
-
-static
-void bt_ctf_clock_class_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_clock_class *clock_class;
-
-       clock_class = container_of(obj, struct bt_ctf_clock_class, base);
-       if (clock_class->name) {
-               g_string_free(clock_class->name, TRUE);
-       }
-       if (clock_class->description) {
-               g_string_free(clock_class->description, TRUE);
-       }
-
-       g_free(clock_class);
-}
-
-static
-void bt_ctf_clock_value_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_clock_value *value;
-
-       if (!obj) {
-               return;
-       }
-
-       value = container_of(obj, struct bt_ctf_clock_value, base);
-       bt_put(value->clock_class);
-       g_free(value);
-}
-
-struct bt_ctf_clock_value *bt_ctf_clock_value_create(
-               struct bt_ctf_clock_class *clock_class, uint64_t value)
-{
-       struct bt_ctf_clock_value *ret = NULL;
-
-       if (!clock_class) {
-               goto end;
-       }
-
-       ret = g_new0(struct bt_ctf_clock_value, 1);
-       if (!ret) {
-               goto end;
-       }
-
-       bt_object_init(ret, bt_ctf_clock_value_destroy);
-       ret->clock_class = bt_get(clock_class);
-       ret->value = value;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_value_get_value(
-               struct bt_ctf_clock_value *clock_value, uint64_t *raw_value)
-{
-       int ret = 0;
-
-       if (!clock_value || !raw_value) {
-               ret = -1;
-               goto end;
-       }
-
-       *raw_value = clock_value->value;
-end:
-       return ret;
-}
-
-int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value,
-               int64_t *ret_value_ns)
-{
-       int ret = 0;
-       int64_t ns;
-
-       if (!value || !ret_value_ns) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Initialize nanosecond timestamp to clock's offset in seconds. */
-       ns = value->clock_class->offset_s * 1000000000;
-
-       /* Add offset in cycles, converted to nanoseconds. */
-       ns += ns_from_value(value->clock_class->frequency,
-                       value->clock_class->offset);
-
-       /* Add given value, converter to nanoseconds. */
-       ns += ns_from_value(value->clock_class->frequency, value->value);
-
-       *ret_value_ns = ns;
-end:
-       return ret;
-}
-
-struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
-               struct bt_ctf_clock_value *clock_value)
-{
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!clock_value) {
-               goto end;
-       }
-
-       clock_class = bt_get(clock_value->clock_class);
-
-end:
-       return clock_class;
-}
diff --git a/formats/ctf/ir/event-class.c b/formats/ctf/ir/event-class.c
deleted file mode 100644 (file)
index 3747a5c..0000000
+++ /dev/null
@@ -1,689 +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.
- */
-
-#include <babeltrace/ctf-ir/fields-internal.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/stream-class.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/validation-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/endian.h>
-
-static
-void bt_ctf_event_class_destroy(struct bt_object *obj);
-
-struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
-{
-       int ret;
-       struct bt_value *obj = NULL;
-       struct bt_ctf_event_class *event_class = NULL;
-
-       if (bt_ctf_validate_identifier(name)) {
-               goto error;
-       }
-
-       event_class = g_new0(struct bt_ctf_event_class, 1);
-       if (!event_class) {
-               goto error;
-       }
-
-       event_class->id = -1;
-       bt_object_init(event_class, bt_ctf_event_class_destroy);
-       event_class->fields = bt_ctf_field_type_structure_create();
-       if (!event_class->fields) {
-               goto error;
-       }
-
-       event_class->attributes = bt_ctf_attributes_create();
-       if (!event_class->attributes) {
-               goto error;
-       }
-
-       obj = bt_value_integer_create_init(-1);
-       if (!obj) {
-               goto error;
-       }
-
-       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
-               "id", obj);
-       if (ret) {
-               goto error;
-       }
-
-       BT_PUT(obj);
-
-       obj = bt_value_string_create_init(name);
-       if (!obj) {
-               goto error;
-       }
-
-       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
-               "name", obj);
-       if (ret) {
-               goto error;
-       }
-
-       BT_PUT(obj);
-
-       return event_class;
-
-error:
-        BT_PUT(event_class);
-       BT_PUT(obj);
-       return event_class;
-}
-
-const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
-{
-       struct bt_value *obj = NULL;
-       const char *name = NULL;
-
-       if (!event_class) {
-               goto end;
-       }
-
-       if (event_class->name) {
-               name = event_class->name;
-               goto end;
-       }
-
-       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
-               BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
-       if (!obj) {
-               goto end;
-       }
-
-       if (bt_value_string_get(obj, &name)) {
-               name = NULL;
-       }
-
-end:
-       BT_PUT(obj);
-       return name;
-}
-
-int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
-{
-       struct bt_value *obj = NULL;
-       int64_t ret = 0;
-
-       if (!event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       if (event_class->id >= 0) {
-               ret = event_class->id;
-               goto end;
-       }
-
-       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
-               BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
-       if (!obj) {
-               goto end;
-       }
-
-       if (bt_value_integer_get(obj, &ret)) {
-               ret = -1;
-       }
-
-       if (ret < 0) {
-               /* means ID is not set */
-               ret = -1;
-               goto end;
-       }
-
-end:
-       BT_PUT(obj);
-       return ret;
-}
-
-int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
-               uint32_t id)
-{
-       int ret = 0;
-       struct bt_value *obj = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-
-       if (!event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       stream_class = bt_ctf_event_class_get_stream_class(event_class);
-       if (stream_class) {
-               /*
-                * We don't allow changing the id if the event class has already
-                * been added to a stream class.
-                */
-               ret = -1;
-               goto end;
-       }
-
-       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
-               BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
-       if (!obj) {
-               goto end;
-       }
-
-       if (bt_value_integer_set(obj, id)) {
-               ret = -1;
-               goto end;
-       }
-
-end:
-       BT_PUT(obj);
-       BT_PUT(stream_class);
-       return ret;
-}
-
-int bt_ctf_event_class_set_attribute(
-               struct bt_ctf_event_class *event_class, const char *name,
-               struct bt_value *value)
-{
-       int ret = 0;
-
-       if (!event_class || !name || !value || event_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
-                       !strcmp(name, "stream_id")) {
-               if (!bt_value_is_integer(value)) {
-                       ret = -1;
-                       goto end;
-               }
-       } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
-                       !strcmp(name, "loglevel_string")) {
-               if (!bt_value_is_string(value)) {
-                       ret = -1;
-                       goto end;
-               }
-       } else {
-               /* unknown attribute */
-               ret = -1;
-               goto end;
-       }
-
-       /* "id" special case: >= 0 */
-       if (!strcmp(name, "id")) {
-               int64_t val;
-
-               ret = bt_value_integer_get(value, &val);
-
-               if (ret) {
-                       goto end;
-               }
-
-               if (val < 0) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
-                       name, value);
-
-end:
-       return ret;
-}
-
-int bt_ctf_event_class_get_attribute_count(
-               struct bt_ctf_event_class *event_class)
-{
-       int ret = 0;
-
-       if (!event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_count(event_class->attributes);
-
-end:
-       return ret;
-}
-
-const char *
-bt_ctf_event_class_get_attribute_name(
-               struct bt_ctf_event_class *event_class, int index)
-{
-       const char *ret;
-
-       if (!event_class) {
-               ret = NULL;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
-
-end:
-       return ret;
-}
-
-struct bt_value *
-bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
-               int index)
-{
-       struct bt_value *ret;
-
-       if (!event_class) {
-               ret = NULL;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
-
-end:
-       return ret;
-}
-
-struct bt_value *
-bt_ctf_event_class_get_attribute_value_by_name(
-               struct bt_ctf_event_class *event_class, const char *name)
-{
-       struct bt_value *ret;
-
-       if (!event_class || !name) {
-               ret = NULL;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
-               name);
-
-end:
-       return ret;
-
-}
-
-struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
-               struct bt_ctf_event_class *event_class)
-{
-       return (struct bt_ctf_stream_class *) bt_object_get_parent(event_class);
-}
-
-struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
-               struct bt_ctf_event_class *event_class)
-{
-       struct bt_ctf_field_type *payload = NULL;
-
-       if (!event_class) {
-               goto end;
-       }
-
-       bt_get(event_class->fields);
-       payload = event_class->fields;
-end:
-       return payload;
-}
-
-int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
-               struct bt_ctf_field_type *payload)
-{
-       int ret = 0;
-
-       if (!event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       if (payload && bt_ctf_field_type_get_type_id(payload) !=
-                       BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(event_class->fields);
-       event_class->fields = bt_get(payload);
-end:
-       return ret;
-}
-
-int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
-               struct bt_ctf_field_type *type,
-               const char *name)
-{
-       int ret = 0;
-
-       if (!event_class || !type || bt_ctf_validate_identifier(name) ||
-               event_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
-               BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(event_class->fields,
-               type, name);
-end:
-       return ret;
-}
-
-int bt_ctf_event_class_get_field_count(
-               struct bt_ctf_event_class *event_class)
-{
-       int ret;
-
-       if (!event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
-               BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
-end:
-       return ret;
-}
-
-int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
-               const char **field_name, struct bt_ctf_field_type **field_type,
-               int index)
-{
-       int ret;
-
-       if (!event_class || index < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
-               BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_get_field(event_class->fields,
-               field_name, field_type, index);
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
-               struct bt_ctf_event_class *event_class, const char *name)
-{
-       GQuark name_quark;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!event_class || !name) {
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
-               BT_CTF_TYPE_ID_STRUCT) {
-               goto end;
-       }
-
-       name_quark = g_quark_try_string(name);
-       if (!name_quark) {
-               goto end;
-       }
-
-       /*
-        * No need to increment field_type's reference count since getting it
-        * from the structure already does.
-        */
-       field_type = bt_ctf_field_type_structure_get_field_type_by_name(
-               event_class->fields, name);
-end:
-       return field_type;
-}
-
-struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
-               struct bt_ctf_event_class *event_class)
-{
-       struct bt_ctf_field_type *context_type = NULL;
-
-       if (!event_class || !event_class->context) {
-               goto end;
-       }
-
-       bt_get(event_class->context);
-       context_type = event_class->context;
-end:
-       return context_type;
-}
-
-int bt_ctf_event_class_set_context_type(
-               struct bt_ctf_event_class *event_class,
-               struct bt_ctf_field_type *context)
-{
-       int ret = 0;
-
-       if (!event_class || event_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (context && bt_ctf_field_type_get_type_id(context) !=
-                       BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(event_class->context);
-       event_class->context = bt_get(context);
-end:
-       return ret;
-
-}
-
-void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
-{
-       bt_get(event_class);
-}
-
-void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
-{
-       bt_put(event_class);
-}
-
-BT_HIDDEN
-int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
-               uint32_t stream_id)
-{
-       int ret = 0;
-       struct bt_value *obj;
-
-       obj = bt_value_integer_create_init(stream_id);
-
-       if (!obj) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
-               "stream_id", obj);
-
-       if (event_class->frozen) {
-               bt_ctf_attributes_freeze(event_class->attributes);
-       }
-
-end:
-       BT_PUT(obj);
-       return ret;
-}
-
-static
-void bt_ctf_event_class_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_event_class *event_class;
-
-       event_class = container_of(obj, struct bt_ctf_event_class, base);
-       bt_ctf_attributes_destroy(event_class->attributes);
-       bt_put(event_class->context);
-       bt_put(event_class->fields);
-       g_free(event_class);
-}
-
-BT_HIDDEN
-void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
-{
-       assert(event_class);
-       event_class->frozen = 1;
-       event_class->name = bt_ctf_event_class_get_name(event_class);
-       event_class->id = bt_ctf_event_class_get_id(event_class);
-       bt_ctf_field_type_freeze(event_class->context);
-       bt_ctf_field_type_freeze(event_class->fields);
-       bt_ctf_attributes_freeze(event_class->attributes);
-}
-
-BT_HIDDEN
-int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
-               struct metadata_context *context)
-{
-       int i;
-       int count;
-       int ret = 0;
-       struct bt_value *attr_value = NULL;
-
-       assert(event_class);
-       assert(context);
-
-       context->current_indentation_level = 1;
-       g_string_assign(context->field_name, "");
-       g_string_append(context->string, "event {\n");
-       count = bt_ctf_event_class_get_attribute_count(event_class);
-
-       if (count < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       for (i = 0; i < count; ++i) {
-               const char *attr_name = NULL;
-
-               attr_name = bt_ctf_event_class_get_attribute_name(
-                       event_class, i);
-               attr_value = bt_ctf_event_class_get_attribute_value(
-                       event_class, i);
-
-               if (!attr_name || !attr_value) {
-                       ret = -1;
-                       goto end;
-               }
-
-               switch (bt_value_get_type(attr_value)) {
-               case BT_VALUE_TYPE_INTEGER:
-               {
-                       int64_t value;
-
-                       ret = bt_value_integer_get(attr_value, &value);
-
-                       if (ret) {
-                               goto end;
-                       }
-
-                       g_string_append_printf(context->string,
-                               "\t%s = %" PRId64 ";\n", attr_name, value);
-                       break;
-               }
-
-               case BT_VALUE_TYPE_STRING:
-               {
-                       const char *value;
-
-                       ret = bt_value_string_get(attr_value, &value);
-
-                       if (ret) {
-                               goto end;
-                       }
-
-                       g_string_append_printf(context->string,
-                               "\t%s = \"%s\";\n", attr_name, value);
-                       break;
-               }
-
-               default:
-                       /* should never happen */
-                       assert(false);
-                       break;
-               }
-
-               BT_PUT(attr_value);
-       }
-
-       if (event_class->context) {
-               g_string_append(context->string, "\tcontext := ");
-               ret = bt_ctf_field_type_serialize(event_class->context,
-                       context);
-               if (ret) {
-                       goto end;
-               }
-               g_string_append(context->string, ";\n");
-       }
-
-       if (event_class->fields) {
-               g_string_append(context->string, "\tfields := ");
-               ret = bt_ctf_field_type_serialize(event_class->fields, context);
-               if (ret) {
-                       goto end;
-               }
-               g_string_append(context->string, ";\n");
-       }
-
-       g_string_append(context->string, "};\n\n");
-end:
-       context->current_indentation_level = 0;
-       BT_PUT(attr_value);
-       return ret;
-}
-
-void bt_ctf_event_class_set_native_byte_order(
-               struct bt_ctf_event_class *event_class,
-               int byte_order)
-{
-       if (!event_class) {
-               return;
-       }
-
-       assert(byte_order == 0 || byte_order == LITTLE_ENDIAN ||
-               byte_order == BIG_ENDIAN);
-
-       bt_ctf_field_type_set_native_byte_order(event_class->context,
-               byte_order);
-       bt_ctf_field_type_set_native_byte_order(event_class->fields,
-               byte_order);
-}
diff --git a/formats/ctf/ir/event.c b/formats/ctf/ir/event.c
deleted file mode 100644 (file)
index c553f7a..0000000
+++ /dev/null
@@ -1,736 +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.
- */
-
-#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/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-internal.h>
-#include <babeltrace/ctf-ir/validation-internal.h>
-#include <babeltrace/ctf-ir/packet-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/compiler.h>
-
-static
-void bt_ctf_event_destroy(struct bt_object *obj);
-
-struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
-{
-       int ret;
-       enum bt_ctf_validation_flag validation_flags =
-               BT_CTF_VALIDATION_FLAG_STREAM |
-               BT_CTF_VALIDATION_FLAG_EVENT;
-       struct bt_ctf_event *event = NULL;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-       struct bt_ctf_field_type *packet_header_type = NULL;
-       struct bt_ctf_field_type *packet_context_type = NULL;
-       struct bt_ctf_field_type *event_header_type = NULL;
-       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
-       struct bt_ctf_field_type *event_context_type = NULL;
-       struct bt_ctf_field_type *event_payload_type = NULL;
-       struct bt_ctf_field *event_header = NULL;
-       struct bt_ctf_field *stream_event_context = NULL;
-       struct bt_ctf_field *event_context = NULL;
-       struct bt_ctf_field *event_payload = NULL;
-       struct bt_value *environment = NULL;
-       struct bt_ctf_validation_output validation_output = { 0 };
-       int trace_valid = 0;
-
-       if (!event_class) {
-               goto error;
-       }
-
-       stream_class = bt_ctf_event_class_get_stream_class(event_class);
-
-       /*
-        * We disallow the creation of an event if its event class has not been
-        * associated to a stream class.
-        */
-       if (!stream_class) {
-               goto error;
-       }
-
-       /* A stream class should always have an existing event header type */
-       assert(stream_class->event_header_type);
-
-       /* The event class was frozen when added to its stream class */
-       assert(event_class->frozen);
-
-       /* Validate the trace (if any), the stream class, and the event class */
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       if (trace) {
-               packet_header_type = bt_ctf_trace_get_packet_header_type(trace);
-               trace_valid = trace->valid;
-               assert(trace_valid);
-               environment = trace->environment;
-       }
-
-       packet_context_type = bt_ctf_stream_class_get_packet_context_type(
-               stream_class);
-       event_header_type = bt_ctf_stream_class_get_event_header_type(
-               stream_class);
-       stream_event_ctx_type = bt_ctf_stream_class_get_event_context_type(
-               stream_class);
-       event_context_type = bt_ctf_event_class_get_context_type(event_class);
-       event_payload_type = bt_ctf_event_class_get_payload_type(event_class);
-       ret = bt_ctf_validate_class_types(environment, packet_header_type,
-               packet_context_type, event_header_type, stream_event_ctx_type,
-               event_context_type, event_payload_type, trace_valid,
-               stream_class->valid, event_class->valid,
-               &validation_output, validation_flags);
-       BT_PUT(packet_header_type);
-       BT_PUT(packet_context_type);
-       BT_PUT(event_header_type);
-       BT_PUT(stream_event_ctx_type);
-       BT_PUT(event_context_type);
-       BT_PUT(event_payload_type);
-       if (ret) {
-               /*
-                * This means something went wrong during the validation
-                * process, not that the objects are invalid.
-                */
-               goto error;
-       }
-
-       if ((validation_output.valid_flags & validation_flags) !=
-                       validation_flags) {
-               /* Invalid trace/stream class/event class */
-               goto error;
-       }
-
-       /*
-        * At this point we know the trace (if associated to the stream
-        * class), the stream class, and the event class, with their
-        * current types, are valid. We may proceed with creating
-        * the event.
-        */
-       event = g_new0(struct bt_ctf_event, 1);
-       if (!event) {
-               goto error;
-       }
-
-       bt_object_init(event, bt_ctf_event_destroy);
-
-       /*
-        * event does not share a common ancestor with the event class; it has
-        * to guarantee its existence by holding a reference. This reference
-        * shall be released once the event is associated to a stream since,
-        * from that point, the event and its class will share the same
-        * lifetime.
-        */
-       event->event_class = bt_get(event_class);
-       event->clock_values = g_hash_table_new_full(g_direct_hash,
-                       g_direct_equal, bt_put, bt_put);
-       event_header =
-               bt_ctf_field_create(validation_output.event_header_type);
-       if (!event_header) {
-               goto error;
-       }
-
-       if (validation_output.stream_event_ctx_type) {
-               stream_event_context = bt_ctf_field_create(
-                       validation_output.stream_event_ctx_type);
-               if (!stream_event_context) {
-                       goto error;
-               }
-       }
-
-       if (validation_output.event_context_type) {
-               event_context = bt_ctf_field_create(
-                       validation_output.event_context_type);
-               if (!event_context) {
-                       goto error;
-               }
-       }
-
-       if (validation_output.event_payload_type) {
-               event_payload = bt_ctf_field_create(
-                       validation_output.event_payload_type);
-               if (!event_payload) {
-                       goto error;
-               }
-       }
-
-       /*
-        * At this point all the fields are created, potentially from
-        * validated copies of field types, so that the field types and
-        * fields can be replaced in the trace, stream class,
-        * event class, and created event.
-        */
-       bt_ctf_validation_replace_types(trace, stream_class,
-               event_class, &validation_output, validation_flags);
-       BT_MOVE(event->event_header, event_header);
-       BT_MOVE(event->stream_event_context, stream_event_context);
-       BT_MOVE(event->context_payload, event_context);
-       BT_MOVE(event->fields_payload, event_payload);
-
-       /*
-        * Put what was not moved in bt_ctf_validation_replace_types().
-        */
-       bt_ctf_validation_output_put_types(&validation_output);
-
-       /*
-        * Freeze the stream class since the event header must not be changed
-        * anymore.
-        */
-       bt_ctf_stream_class_freeze(stream_class);
-
-       /*
-        * Mark stream class, and event class as valid since
-        * they're all frozen now.
-        */
-       stream_class->valid = 1;
-       event_class->valid = 1;
-
-       /* Put stuff we borrowed from the event class */
-       BT_PUT(stream_class);
-       BT_PUT(trace);
-
-       return event;
-
-error:
-       bt_ctf_validation_output_put_types(&validation_output);
-       BT_PUT(event);
-       BT_PUT(stream_class);
-       BT_PUT(trace);
-       BT_PUT(event_header);
-       BT_PUT(stream_event_context);
-       BT_PUT(event_context);
-       BT_PUT(event_payload);
-       assert(!packet_header_type);
-       assert(!packet_context_type);
-       assert(!event_header_type);
-       assert(!stream_event_ctx_type);
-       assert(!event_context_type);
-       assert(!event_payload_type);
-
-       return event;
-}
-
-struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
-{
-       struct bt_ctf_event_class *event_class = NULL;
-
-       if (!event) {
-               goto end;
-       }
-
-       event_class = event->event_class;
-       bt_get(event_class);
-end:
-       return event_class;
-}
-
-struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
-{
-       struct bt_ctf_stream *stream = NULL;
-
-       if (!event) {
-               goto end;
-       }
-
-       /*
-        * If the event has a parent, then this is its (writer) stream.
-        * If the event has no parent, then if it has a packet, this
-        * is its (non-writer) stream.
-        */
-       if (event->base.parent) {
-               stream = (struct bt_ctf_stream *) bt_object_get_parent(event);
-       } else {
-               if (event->packet) {
-                       stream = bt_get(event->packet->stream);
-               }
-       }
-
-end:
-       return stream;
-}
-
-int bt_ctf_event_set_payload(struct bt_ctf_event *event,
-               const char *name,
-               struct bt_ctf_field *payload)
-{
-       int ret = 0;
-
-       if (!event || !payload || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (name) {
-               ret = bt_ctf_field_structure_set_field(event->fields_payload,
-                       name, payload);
-       } else {
-               struct bt_ctf_field_type *payload_type;
-
-               payload_type = bt_ctf_field_get_type(payload);
-
-               if (bt_ctf_field_type_compare(payload_type,
-                               event->event_class->fields) == 0) {
-                       bt_put(event->fields_payload);
-                       bt_get(payload);
-                       event->fields_payload = payload;
-               } else {
-                       ret = -1;
-               }
-
-               bt_put(payload_type);
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_payload_field(struct bt_ctf_event *event)
-{
-       struct bt_ctf_field *payload = NULL;
-
-       if (!event || !event->fields_payload) {
-               goto end;
-       }
-
-       payload = event->fields_payload;
-       bt_get(payload);
-end:
-       return payload;
-}
-
-int bt_ctf_event_set_payload_field(struct bt_ctf_event *event,
-               struct bt_ctf_field *payload)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *payload_type = NULL;
-
-       if (!event || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       payload_type = bt_ctf_field_get_type(payload);
-       if (!payload_type) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(payload_type) !=
-                       BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(event->fields_payload);
-       event->fields_payload = bt_get(payload);
-end:
-       bt_put(payload_type);
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
-               const char *name)
-{
-       struct bt_ctf_field *field = NULL;
-
-       if (!event) {
-               goto end;
-       }
-
-       if (name) {
-               field = bt_ctf_field_structure_get_field(event->fields_payload,
-                       name);
-       } else {
-               field = event->fields_payload;
-               bt_get(field);
-       }
-end:
-       return field;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
-               struct bt_ctf_event *event, int index)
-{
-       struct bt_ctf_field *field = NULL;
-
-       if (!event || index < 0) {
-               goto end;
-       }
-
-       field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
-               index);
-end:
-       return field;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_header(
-               struct bt_ctf_event *event)
-{
-       struct bt_ctf_field *header = NULL;
-
-       if (!event || !event->event_header) {
-               goto end;
-       }
-
-       header = event->event_header;
-       bt_get(header);
-end:
-       return header;
-}
-
-int bt_ctf_event_set_header(struct bt_ctf_event *event,
-               struct bt_ctf_field *header)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (!event || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       stream_class = (struct bt_ctf_stream_class *) bt_object_get_parent(
-                       event->event_class);
-       /*
-        * Ensure the provided header's type matches the one registered to the
-        * stream class.
-        */
-       field_type = bt_ctf_field_get_type(header);
-       if (bt_ctf_field_type_compare(field_type,
-                       stream_class->event_header_type)) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(event->event_header);
-       event->event_header = bt_get(header);
-end:
-       bt_put(stream_class);
-       bt_put(field_type);
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_event_context(
-               struct bt_ctf_event *event)
-{
-       struct bt_ctf_field *context = NULL;
-
-       if (!event || !event->context_payload) {
-               goto end;
-       }
-
-       context = event->context_payload;
-       bt_get(context);
-end:
-       return context;
-}
-
-int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
-               struct bt_ctf_field *context)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!event || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       field_type = bt_ctf_field_get_type(context);
-       if (bt_ctf_field_type_compare(field_type,
-                       event->event_class->context)) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(event->context_payload);
-       event->context_payload = bt_get(context);
-end:
-       bt_put(field_type);
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
-               struct bt_ctf_event *event)
-{
-       struct bt_ctf_field *stream_event_context = NULL;
-
-       if (!event || !event->stream_event_context) {
-               goto end;
-       }
-
-       stream_event_context = event->stream_event_context;
-end:
-       return bt_get(stream_event_context);
-}
-
-int bt_ctf_event_set_stream_event_context(struct bt_ctf_event *event,
-               struct bt_ctf_field *stream_event_context)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (!event || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
-       /*
-        * We should not have been able to create the event without associating
-        * the event class to a stream class.
-        */
-       assert(stream_class);
-
-       field_type = bt_ctf_field_get_type(stream_event_context);
-       if (bt_ctf_field_type_compare(field_type,
-                       stream_class->event_context_type)) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_get(stream_event_context);
-       BT_MOVE(event->stream_event_context, stream_event_context);
-end:
-       BT_PUT(stream_class);
-       bt_put(field_type);
-       return ret;
-}
-
-void bt_ctf_event_get(struct bt_ctf_event *event)
-{
-       bt_get(event);
-}
-
-void bt_ctf_event_put(struct bt_ctf_event *event)
-{
-       bt_put(event);
-}
-
-void bt_ctf_event_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_event *event;
-
-       event = container_of(obj, struct bt_ctf_event, base);
-       if (!event->base.parent) {
-               /*
-                * Event was keeping a reference to its class since it shared no
-                * common ancestor with it to guarantee they would both have the
-                * same lifetime.
-                */
-               bt_put(event->event_class);
-       }
-       g_hash_table_destroy(event->clock_values);
-       bt_put(event->event_header);
-       bt_put(event->stream_event_context);
-       bt_put(event->context_payload);
-       bt_put(event->fields_payload);
-       bt_put(event->packet);
-       g_free(event);
-}
-
-struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
-               struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class)
-{
-       struct bt_ctf_clock_value *clock_value = NULL;
-
-       if (!event || !clock_class) {
-               goto end;
-       }
-
-       clock_value = g_hash_table_lookup(event->clock_values, clock_class);
-       if (!clock_value) {
-               goto end;
-       }
-
-       bt_get(clock_value);
-end:
-       return clock_value;
-}
-
-int bt_ctf_event_set_clock_value(struct bt_ctf_event *event,
-               struct bt_ctf_clock_value *value)
-{
-       int ret = 0;
-
-       if (!event || !value || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       g_hash_table_insert(event->clock_values,
-               bt_ctf_clock_value_get_class(value), bt_get(value));
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_event_validate(struct bt_ctf_event *event)
-{
-       /* Make sure each field's payload has been set */
-       int ret;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       assert(event);
-       ret = bt_ctf_field_validate(event->event_header);
-       if (ret) {
-               goto end;
-       }
-
-       stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
-       /*
-        * We should not have been able to create the event without associating
-        * the event class to a stream class.
-        */
-       assert(stream_class);
-       if (stream_class->event_context_type) {
-               ret = bt_ctf_field_validate(event->stream_event_context);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       ret = bt_ctf_field_validate(event->fields_payload);
-       if (ret) {
-               goto end;
-       }
-
-       if (event->event_class->context) {
-               ret = bt_ctf_field_validate(event->context_payload);
-       }
-end:
-       bt_put(stream_class);
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_event_serialize(struct bt_ctf_event *event,
-               struct ctf_stream_pos *pos)
-{
-       int ret = 0;
-
-       assert(event);
-       assert(pos);
-       if (event->context_payload) {
-               ret = bt_ctf_field_serialize(event->context_payload, pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       if (event->fields_payload) {
-               ret = bt_ctf_field_serialize(event->fields_payload, pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_packet *bt_ctf_event_get_packet(struct bt_ctf_event *event)
-{
-       struct bt_ctf_packet *packet = NULL;
-
-       if (!event || !event->packet) {
-               goto end;
-       }
-
-       packet = bt_get(event->packet);
-end:
-       return packet;
-}
-
-int bt_ctf_event_set_packet(struct bt_ctf_event *event,
-               struct bt_ctf_packet *packet)
-{
-       struct bt_ctf_stream_class *event_stream_class = NULL;
-       struct bt_ctf_stream_class *packet_stream_class = NULL;
-       struct bt_ctf_stream *stream = NULL;
-       int ret = 0;
-
-       if (!event || !packet || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * Make sure the new packet was created by this event's
-        * stream, if it is set.
-        */
-       stream = bt_ctf_event_get_stream(event);
-       if (stream) {
-               if (packet->stream != stream) {
-                       ret = -1;
-                       goto end;
-               }
-       } else {
-               event_stream_class =
-                       bt_ctf_event_class_get_stream_class(event->event_class);
-               packet_stream_class =
-                       bt_ctf_stream_get_class(packet->stream);
-
-               assert(event_stream_class);
-               assert(packet_stream_class);
-
-               if (event_stream_class != packet_stream_class) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       bt_get(packet);
-       BT_MOVE(event->packet, packet);
-
-end:
-       BT_PUT(stream);
-       BT_PUT(event_stream_class);
-       BT_PUT(packet_stream_class);
-
-       return ret;
-}
-
-BT_HIDDEN
-void bt_ctf_event_freeze(struct bt_ctf_event *event)
-{
-       assert(event);
-       bt_ctf_packet_freeze(event->packet);
-       bt_ctf_field_freeze(event->event_header);
-       bt_ctf_field_freeze(event->stream_event_context);
-       bt_ctf_field_freeze(event->context_payload);
-       bt_ctf_field_freeze(event->fields_payload);
-       event->frozen = 1;
-}
diff --git a/formats/ctf/ir/field-path.c b/formats/ctf/ir/field-path.c
deleted file mode 100644 (file)
index 6c0b248..0000000
+++ /dev/null
@@ -1,146 +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.
- */
-
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <limits.h>
-#include <glib.h>
-
-static
-void field_path_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_field_path *field_path = (struct bt_ctf_field_path *) obj;
-
-       if (!field_path) {
-               return;
-       }
-
-       if (field_path->indexes) {
-               g_array_free(field_path->indexes, TRUE);
-       }
-       g_free(field_path);
-}
-
-BT_HIDDEN
-struct bt_ctf_field_path *bt_ctf_field_path_create(void)
-{
-       struct bt_ctf_field_path *field_path = NULL;
-
-       field_path = g_new0(struct bt_ctf_field_path, 1);
-       if (!field_path) {
-               goto error;
-       }
-
-       bt_object_init(field_path, field_path_destroy);
-       field_path->root = BT_CTF_SCOPE_UNKNOWN;
-       field_path->indexes = g_array_new(TRUE, FALSE, sizeof(int));
-       if (!field_path->indexes) {
-               goto error;
-       }
-
-       return field_path;
-
-error:
-       BT_PUT(field_path);
-       return NULL;
-}
-
-BT_HIDDEN
-void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path)
-{
-       if (field_path->indexes->len > 0) {
-               g_array_remove_range(field_path->indexes, 0,
-                       field_path->indexes->len);
-       }
-}
-
-BT_HIDDEN
-struct bt_ctf_field_path *bt_ctf_field_path_copy(
-               struct bt_ctf_field_path *path)
-{
-       struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
-
-       if (!new_path) {
-               goto end;
-       }
-
-       new_path->root = path->root;
-       g_array_insert_vals(new_path->indexes, 0,
-               path->indexes->data, path->indexes->len);
-end:
-       return new_path;
-}
-
-enum bt_ctf_scope bt_ctf_field_path_get_root_scope(
-               const struct bt_ctf_field_path *field_path)
-{
-       enum bt_ctf_scope scope = BT_CTF_SCOPE_UNKNOWN;
-
-       if (!field_path) {
-               goto end;
-       }
-
-       scope = field_path->root;
-
-end:
-       return scope;
-}
-
-int bt_ctf_field_path_get_index_count(
-               const struct bt_ctf_field_path *field_path)
-{
-       int ret = -1;
-
-       if (!field_path) {
-               goto end;
-       }
-
-       ret = field_path->indexes->len;
-
-end:
-       return ret;
-}
-
-int bt_ctf_field_path_get_index(const struct bt_ctf_field_path *field_path,
-               int index)
-{
-       int ret = INT_MIN;
-
-       if (!field_path || index < 0) {
-               goto end;
-       }
-
-       if (index >= field_path->indexes->len) {
-               goto end;
-       }
-
-       ret = g_array_index(field_path->indexes, int, index);
-
-end:
-       return ret;
-}
diff --git a/formats/ctf/ir/field-types.c b/formats/ctf/ir/field-types.c
deleted file mode 100644 (file)
index 02a47b3..0000000
+++ /dev/null
@@ -1,4334 +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.
- */
-
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/endian.h>
-#include <float.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-struct range_overlap_query {
-       union {
-               uint64_t _unsigned;
-               int64_t _signed;
-       } range_start;
-
-       union {
-               uint64_t _unsigned;
-               int64_t _signed;
-       } range_end;
-       int overlaps;
-       GQuark mapping_name;
-};
-
-static
-void bt_ctf_field_type_destroy(struct bt_object *);
-static
-void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
-
-static
-void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_destroy,
-       [BT_CTF_TYPE_ID_ENUM] =
-               bt_ctf_field_type_enumeration_destroy,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_type_floating_point_destroy,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_destroy,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_destroy,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_destroy,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_destroy,
-};
-
-static
-void generic_field_type_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
-static
-void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
-
-static
-type_freeze_func const type_freeze_funcs[] = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_freeze,
-       [BT_CTF_TYPE_ID_FLOAT] = generic_field_type_freeze,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_freeze,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_freeze,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_freeze,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
-       [BT_CTF_TYPE_ID_STRING] = generic_field_type_freeze,
-};
-
-static
-int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_floating_point_serialize(
-               struct bt_ctf_field_type *, struct metadata_context *);
-static
-int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-static
-int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
-               struct metadata_context *);
-
-static
-type_serialize_func const type_serialize_funcs[] = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_serialize,
-       [BT_CTF_TYPE_ID_ENUM] =
-               bt_ctf_field_type_enumeration_serialize,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_type_floating_point_serialize,
-       [BT_CTF_TYPE_ID_STRUCT] =
-               bt_ctf_field_type_structure_serialize,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_serialize,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_serialize,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_serialize,
-};
-
-static
-void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-static
-void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-static
-void bt_ctf_field_type_floating_point_set_byte_order(
-               struct bt_ctf_field_type *, int byte_order, int set_native);
-static
-void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-static
-void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-static
-void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-static
-void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
-               int byte_order, int set_native);
-
-/* The set_native flag only set the byte order if it is set to native */
-static
-void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
-               int byte_order, int set_native) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
-       [BT_CTF_TYPE_ID_ENUM] =
-               bt_ctf_field_type_enumeration_set_byte_order,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_type_floating_point_set_byte_order,
-       [BT_CTF_TYPE_ID_STRUCT] =
-               bt_ctf_field_type_structure_set_byte_order,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_set_byte_order,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
-       [BT_CTF_TYPE_ID_STRING] = NULL,
-};
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
-               struct bt_ctf_field_type *);
-
-static
-struct bt_ctf_field_type *(* const type_copy_funcs[])(
-               struct bt_ctf_field_type *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_copy,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_copy,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_copy,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_copy,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_copy,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_copy,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_copy,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_copy,
-};
-
-static
-int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *);
-
-static
-int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
-               struct bt_ctf_field_type *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_compare,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_compare,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_compare,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_compare,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_compare,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_compare,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_compare,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_compare,
-};
-
-static
-int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
-static
-int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
-
-static
-int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_validate,
-       [BT_CTF_TYPE_ID_FLOAT] = NULL,
-       [BT_CTF_TYPE_ID_STRING] = NULL,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_validate,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_validate,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_validate,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_validate,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_validate,
-};
-
-static
-void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
-{
-       g_free(mapping);
-}
-
-static
-void destroy_structure_field(struct structure_field *field)
-{
-       bt_put(field->type);
-       g_free(field);
-}
-
-static
-void check_ranges_overlap(gpointer element, gpointer query)
-{
-       struct enumeration_mapping *mapping = element;
-       struct range_overlap_query *overlap_query = query;
-
-       if (mapping->range_start._signed <= overlap_query->range_end._signed
-               && overlap_query->range_start._signed <=
-               mapping->range_end._signed) {
-               overlap_query->overlaps = 1;
-               overlap_query->mapping_name = mapping->string;
-       }
-
-       overlap_query->overlaps |=
-               mapping->string == overlap_query->mapping_name;
-}
-
-static
-void check_ranges_overlap_unsigned(gpointer element, gpointer query)
-{
-       struct enumeration_mapping *mapping = element;
-       struct range_overlap_query *overlap_query = query;
-
-       if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
-               && overlap_query->range_start._unsigned <=
-               mapping->range_end._unsigned) {
-               overlap_query->overlaps = 1;
-               overlap_query->mapping_name = mapping->string;
-       }
-
-       overlap_query->overlaps |=
-               mapping->string == overlap_query->mapping_name;
-}
-
-static
-gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
-               struct enumeration_mapping **b)
-{
-       return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
-}
-
-static
-gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
-               struct enumeration_mapping **b)
-{
-       return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
-}
-
-static
-void bt_ctf_field_type_init(struct bt_ctf_field_type *type, int init_bo)
-{
-       enum bt_ctf_type_id type_id = type->declaration->id;
-
-       assert(type && (type_id > BT_CTF_TYPE_ID_UNKNOWN) &&
-               (type_id < BT_CTF_NR_TYPE_IDS));
-
-       bt_object_init(type, bt_ctf_field_type_destroy);
-       type->freeze = type_freeze_funcs[type_id];
-       type->serialize = type_serialize_funcs[type_id];
-
-       if (init_bo) {
-               int ret = bt_ctf_field_type_set_byte_order(type,
-                       BT_CTF_BYTE_ORDER_NATIVE);
-               assert(!ret);
-       }
-
-       type->declaration->alignment = 1;
-}
-
-static
-int add_structure_field(GPtrArray *fields,
-               GHashTable *field_name_to_index,
-               struct bt_ctf_field_type *field_type,
-               const char *field_name)
-{
-       int ret = 0;
-       GQuark name_quark = g_quark_from_string(field_name);
-       struct structure_field *field;
-
-       /* Make sure structure does not contain a field of the same name */
-       if (g_hash_table_lookup_extended(field_name_to_index,
-               GUINT_TO_POINTER(name_quark), NULL, NULL)) {
-               ret = -1;
-               goto end;
-       }
-
-       field = g_new0(struct structure_field, 1);
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_get(field_type);
-       field->name = name_quark;
-       field->type = field_type;
-       g_hash_table_insert(field_name_to_index,
-               GUINT_TO_POINTER(name_quark),
-               GUINT_TO_POINTER(fields->len));
-       g_ptr_array_add(fields, field);
-end:
-       return ret;
-}
-
-static
-void bt_ctf_field_type_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_field_type *type;
-       enum bt_ctf_type_id type_id;
-
-       type = container_of(obj, struct bt_ctf_field_type, base);
-       type_id = type->declaration->id;
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
-               type_id >= BT_CTF_NR_TYPE_IDS) {
-               return;
-       }
-
-       type_destroy_funcs[type_id](type);
-}
-
-static
-int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-
-       struct bt_ctf_field_type_integer *integer =
-               container_of(type, struct bt_ctf_field_type_integer,
-                       parent);
-
-       if (integer->mapped_clock && integer->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-static
-struct enumeration_mapping *get_enumeration_mapping(
-               struct bt_ctf_field_type *type, int index)
-{
-       struct enumeration_mapping *mapping = NULL;
-       struct bt_ctf_field_type_enumeration *enumeration;
-
-       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
-               parent);
-       if (index >= enumeration->entries->len) {
-               goto end;
-       }
-
-       mapping = g_ptr_array_index(enumeration->entries, index);
-end:
-       return mapping;
-}
-
-/*
- * Note: This algorithm is O(n^2) vs number of enumeration mappings.
- * Only used when freezing an enumeration.
- */
-static
-void set_enumeration_range_overlap(
-               struct bt_ctf_field_type *type)
-{
-       int i, j, len;
-       struct bt_ctf_field_type *container_type;
-       struct bt_ctf_field_type_enumeration *enumeration_type;
-       int is_signed;
-
-       enumeration_type = container_of(type,
-                       struct bt_ctf_field_type_enumeration, parent);
-
-       len = enumeration_type->entries->len;
-       container_type = enumeration_type->container;
-       is_signed = bt_ctf_field_type_integer_get_signed(container_type);
-
-       for (i = 0; i < len; i++) {
-               for (j = i + 1; j < len; j++) {
-                       struct enumeration_mapping *mapping[2];
-
-                       mapping[0] = get_enumeration_mapping(type, i);
-                       mapping[1] = get_enumeration_mapping(type, j);
-                       if (is_signed) {
-                               if (mapping[0]->range_start._signed
-                                                       <= mapping[1]->range_end._signed
-                                               && mapping[0]->range_end._signed
-                                                       >= mapping[1]->range_start._signed) {
-                                       enumeration_type->has_overlapping_ranges = true;
-                                       return;
-                               }
-                       } else {
-                               if (mapping[0]->range_start._unsigned
-                                                       <= mapping[1]->range_end._unsigned
-                                               && mapping[0]->range_end._unsigned
-                                                       >= mapping[1]->range_start._unsigned) {
-                                       enumeration_type->has_overlapping_ranges = true;
-                                       return;
-                               }
-                       }
-               }
-       }
-}
-
-static
-int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-
-       struct bt_ctf_field_type_enumeration *enumeration =
-               container_of(type, struct bt_ctf_field_type_enumeration,
-                       parent);
-       struct bt_ctf_field_type *container_type =
-               bt_ctf_field_type_enumeration_get_container_type(type);
-
-       if (!container_type) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_validate(container_type);
-       if (ret) {
-               goto end;
-       }
-
-       /* Ensure enum has entries */
-       ret = enumeration->entries->len ? 0 : -1;
-
-end:
-       BT_PUT(container_type);
-       return ret;
-}
-
-static
-int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *element_type = NULL;
-       struct bt_ctf_field_type_sequence *sequence =
-               container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-
-       /* Length field name should be set at this point */
-       if (sequence->length_field_name->len == 0) {
-               ret = -1;
-               goto end;
-       }
-
-       element_type = bt_ctf_field_type_sequence_get_element_type(type);
-       if (!element_type) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_validate(element_type);
-
-end:
-       BT_PUT(element_type);
-
-       return ret;
-}
-
-static
-int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *element_type = NULL;
-
-       element_type = bt_ctf_field_type_array_get_element_type(type);
-       if (!element_type) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_validate(element_type);
-
-end:
-       BT_PUT(element_type);
-
-       return ret;
-}
-
-static
-int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *child_type = NULL;
-       int field_count = bt_ctf_field_type_structure_get_field_count(type);
-       int i;
-
-       if (field_count < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       for (i = 0; i < field_count; ++i) {
-               ret = bt_ctf_field_type_structure_get_field(type,
-                       NULL, &child_type, i);
-               if (ret) {
-                       goto end;
-               }
-
-               ret = bt_ctf_field_type_validate(child_type);
-               if (ret) {
-                       goto end;
-               }
-
-               BT_PUT(child_type);
-       }
-
-end:
-       BT_PUT(child_type);
-
-       return ret;
-}
-
-static
-bool bt_ctf_field_type_enumeration_has_overlapping_ranges(
-               struct bt_ctf_field_type_enumeration *enumeration_type)
-{
-       if (!enumeration_type->parent.frozen) {
-               set_enumeration_range_overlap(&enumeration_type->parent);
-       }
-       return enumeration_type->has_overlapping_ranges;
-}
-
-static
-int bt_ctf_field_type_enumeration_get_mapping_name(
-               struct bt_ctf_field_type *enum_field_type,
-               int index,
-               const char **mapping_name)
-{
-       int ret = 0;
-       struct enumeration_mapping *mapping;
-
-       if (!enum_field_type || index < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       mapping = get_enumeration_mapping(enum_field_type, index);
-       if (!mapping) {
-               ret = -1;
-               goto end;
-       }
-
-       if (mapping_name) {
-               *mapping_name = g_quark_to_string(mapping->string);
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       int field_count;
-       struct bt_ctf_field_type *child_type = NULL;
-       struct bt_ctf_field_type_variant *variant =
-               container_of(type, struct bt_ctf_field_type_variant,
-                       parent);
-       int i;
-       int tag_mappings_count;
-
-       if (variant->tag_name->len == 0 || !variant->tag) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_enumeration_has_overlapping_ranges(
-                       variant->tag)) {
-               ret = -1;
-               goto end;
-       }
-
-       tag_mappings_count =
-               bt_ctf_field_type_enumeration_get_mapping_count(
-                       (struct bt_ctf_field_type *) variant->tag);
-
-       if (tag_mappings_count != variant->fields->len) {
-               ret = -1;
-               goto end;
-       }
-
-       for (i = 0; i < tag_mappings_count; ++i) {
-               const char *label;
-               struct bt_ctf_field_type *ft;
-
-               ret = bt_ctf_field_type_enumeration_get_mapping_name(
-                       (struct bt_ctf_field_type *) variant->tag,
-                       i, &label);
-               if (ret) {
-                       goto end;
-               }
-               if (!label) {
-                       ret = -1;
-                       goto end;
-               }
-
-               ft = bt_ctf_field_type_variant_get_field_type_by_name(
-                       type, label);
-               if (!ft) {
-                       ret = -1;
-                       goto end;
-               }
-
-               BT_PUT(ft);
-       }
-
-       field_count = bt_ctf_field_type_variant_get_field_count(type);
-       if (field_count < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       for (i = 0; i < field_count; ++i) {
-               ret = bt_ctf_field_type_variant_get_field(type,
-                       NULL, &child_type, i);
-               if (ret) {
-                       goto end;
-               }
-
-               ret = bt_ctf_field_type_validate(child_type);
-               if (ret) {
-                       goto end;
-               }
-
-               BT_PUT(child_type);
-       }
-
-end:
-       BT_PUT(child_type);
-
-       return ret;
-}
-
-/*
- * This function validates a given field type without considering
- * where this field type is located. It only validates the properties
- * of the given field type and the properties of its children if
- * applicable.
- */
-BT_HIDDEN
-int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       enum bt_ctf_type_id id = bt_ctf_field_type_get_type_id(type);
-
-       if (!type) {
-               ret = -1;
-               goto end;
-       }
-
-       if (type->valid) {
-               /* Already marked as valid */
-               goto end;
-       }
-
-       if (type_validate_funcs[id]) {
-               ret = type_validate_funcs[id](type);
-       }
-
-       if (!ret && type->frozen) {
-               /* Field type is valid */
-               type->valid = 1;
-       }
-
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
-{
-       struct bt_ctf_field_type_integer *integer =
-               g_new0(struct bt_ctf_field_type_integer, 1);
-
-       if (!integer || size == 0 || size > 64) {
-               return NULL;
-       }
-
-       integer->parent.declaration = &integer->declaration.p;
-       integer->parent.declaration->id = BT_CTF_TYPE_ID_INTEGER;
-       integer->declaration.len = size;
-       integer->declaration.base = BT_CTF_INTEGER_BASE_DECIMAL;
-       integer->declaration.encoding = BT_CTF_STRING_ENCODING_NONE;
-       bt_ctf_field_type_init(&integer->parent, TRUE);
-       return &integer->parent;
-}
-
-int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       ret = (int) integer->declaration.len;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       ret = integer->declaration.signedness;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
-               int is_signed)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->frozen ||
-               type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       integer->declaration.signedness = !!is_signed;
-end:
-       return ret;
-}
-
-enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
-               struct bt_ctf_field_type *type)
-{
-       enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       ret = integer->declaration.base;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
-               enum bt_ctf_integer_base base)
-{
-       int ret = 0;
-
-       if (!type || type->frozen ||
-               type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       switch (base) {
-       case BT_CTF_INTEGER_BASE_BINARY:
-       case BT_CTF_INTEGER_BASE_OCTAL:
-       case BT_CTF_INTEGER_BASE_DECIMAL:
-       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
-       {
-               struct bt_ctf_field_type_integer *integer = container_of(type,
-                       struct bt_ctf_field_type_integer, parent);
-               integer->declaration.base = base;
-               break;
-       }
-       default:
-               ret = -1;
-       }
-end:
-       return ret;
-}
-
-enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
-               struct bt_ctf_field_type *type)
-{
-       enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       ret = integer->declaration.encoding;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
-               enum bt_ctf_string_encoding encoding)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_integer *integer;
-
-       if (!type || type->frozen ||
-               (type->declaration->id != BT_CTF_TYPE_ID_INTEGER) ||
-               (encoding < BT_CTF_STRING_ENCODING_NONE) ||
-               (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       integer->declaration.encoding = encoding;
-end:
-       return ret;
-}
-
-struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_integer *integer;
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!type) {
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       clock_class = integer->mapped_clock;
-       bt_get(clock_class);
-end:
-       return clock_class;
-}
-
-int bt_ctf_field_type_integer_set_mapped_clock_class(
-               struct bt_ctf_field_type *type,
-               struct bt_ctf_clock_class *clock_class)
-{
-       struct bt_ctf_field_type_integer *integer;
-       int ret = 0;
-
-       if (!type || type->frozen || !bt_ctf_clock_class_is_valid(clock_class)) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       bt_put(integer->mapped_clock);
-       integer->mapped_clock = bt_get(clock_class);
-end:
-       return ret;
-}
-
-static
-void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
-               container_of(obj,
-                       struct bt_ctf_field_type_enumeration_mapping_iterator,
-                       base);
-
-       bt_put(&iter->enumeration_type->parent);
-       g_free(iter);
-}
-
-static
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_type(
-               struct bt_ctf_field_type *type,
-               enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type)
-{
-       struct bt_ctf_field_type_enumeration *enumeration_type;
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
-               goto end;
-       }
-
-       enumeration_type = container_of(type,
-               struct bt_ctf_field_type_enumeration, parent);
-       iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1);
-       if (!iter) {
-               goto end;
-       }
-
-       bt_object_init(&iter->base, bt_ctf_field_type_enum_iter_destroy);
-       bt_get(type);
-       iter->enumeration_type = enumeration_type;
-       iter->index = -1;
-       iter->type = iterator_type;
-end:
-       return iter;
-}
-
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_name(
-               struct bt_ctf_field_type *type, const char *name)
-{
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
-
-       iter = bt_ctf_field_type_enumeration_find_mappings_type(
-                       type, ITERATOR_BY_NAME);
-       if (!iter) {
-               goto error;
-       }
-
-       iter->u.name_quark = g_quark_try_string(name);
-       if (!iter->u.name_quark) {
-               goto error;
-       }
-
-       /* Advance iterator to first entry, or leave index at -1. */
-       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
-               /* No entry found. */
-               goto error;
-       }
-
-       return iter;
-error:
-       bt_put(iter);
-       return NULL;
-}
-
-int bt_ctf_field_type_enumeration_mapping_iterator_next(
-               struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
-{
-       struct bt_ctf_field_type_enumeration *enumeration;
-       struct bt_ctf_field_type *type;
-       int i, ret = 0, len;
-
-       enumeration = iter->enumeration_type;
-       type = &enumeration->parent;
-       len = enumeration->entries->len;
-       for (i = iter->index + 1; i < len; i++) {
-               struct enumeration_mapping *mapping =
-                       get_enumeration_mapping(type, i);
-
-               switch (iter->type) {
-               case ITERATOR_BY_NAME:
-                       if (mapping->string == iter->u.name_quark) {
-                               iter->index = i;
-                               goto end;
-                       }
-                       break;
-               case ITERATOR_BY_SIGNED_VALUE:
-               {
-                       int64_t value = iter->u.signed_value;
-
-                       if (value >= mapping->range_start._signed &&
-                                       value <= mapping->range_end._signed) {
-                               iter->index = i;
-                               goto end;
-                       }
-                       break;
-               }
-               case ITERATOR_BY_UNSIGNED_VALUE:
-               {
-                       uint64_t value = iter->u.unsigned_value;
-
-                       if (value >= mapping->range_start._unsigned &&
-                                       value <= mapping->range_end._unsigned) {
-                               iter->index = i;
-                               goto end;
-                       }
-                       break;
-               }
-               default:
-                       abort();
-               }
-       }
-
-       ret = -1;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
-               struct bt_ctf_field_type *type, int64_t value)
-{
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
-
-       iter = bt_ctf_field_type_enumeration_find_mappings_type(
-                       type, ITERATOR_BY_SIGNED_VALUE);
-       if (!iter) {
-               goto error;
-       }
-
-       if (bt_ctf_field_type_integer_get_signed(
-                       iter->enumeration_type->container) != 1) {
-               goto error;
-       }
-       iter->u.signed_value = value;
-
-       /* Advance iterator to first entry, or leave index at -1. */
-       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
-               /* No entry found. */
-               goto error;
-       }
-
-       return iter;
-error:
-       bt_put(iter);
-       return NULL;
-}
-
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
-               struct bt_ctf_field_type *type, uint64_t value)
-{
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
-
-       iter = bt_ctf_field_type_enumeration_find_mappings_type(
-                       type, ITERATOR_BY_UNSIGNED_VALUE);
-       if (!iter) {
-               goto error;
-       }
-
-       if (bt_ctf_field_type_integer_get_signed(
-                       iter->enumeration_type->container) != 0) {
-               goto error;
-       }
-       iter->u.unsigned_value = value;
-
-       /* Advance iterator to first entry, or leave index at -1. */
-       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
-               /* No entry found. */
-               goto error;
-       }
-
-       return iter;
-error:
-       bt_put(iter);
-       return NULL;
-}
-
-int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
-               struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
-               const char **mapping_name, int64_t *range_begin,
-               int64_t *range_end)
-{
-       int ret = 0;
-
-       if (!iter) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_enumeration_get_mapping_signed(
-                       &iter->enumeration_type->parent, iter->index,
-                       mapping_name, range_begin, range_end);
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
-               struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
-               const char **mapping_name, uint64_t *range_begin,
-               uint64_t *range_end)
-{
-       int ret = 0;
-
-       if (!iter) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_enumeration_get_mapping_unsigned(
-                       &iter->enumeration_type->parent, iter->index,
-                       mapping_name, range_begin, range_end);
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_enumeration_get_mapping_signed(
-               struct bt_ctf_field_type *enum_field_type,
-               int index,
-               const char **mapping_name, int64_t *range_begin,
-               int64_t *range_end)
-{
-       int ret = 0;
-       struct enumeration_mapping *mapping;
-
-       if (!enum_field_type || index < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       mapping = get_enumeration_mapping(enum_field_type, index);
-       if (!mapping) {
-               ret = -1;
-               goto end;
-       }
-
-       if (mapping_name) {
-               *mapping_name = g_quark_to_string(mapping->string);
-       }
-
-       if (range_begin) {
-               *range_begin = mapping->range_start._signed;
-       }
-
-       if (range_end) {
-               *range_end = mapping->range_end._signed;
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_enumeration_get_mapping_unsigned(
-               struct bt_ctf_field_type *enum_field_type,
-               int index,
-               const char **mapping_name, uint64_t *range_begin,
-               uint64_t *range_end)
-{
-       int ret = 0;
-       struct enumeration_mapping *mapping;
-
-       if (!enum_field_type || index < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       mapping = get_enumeration_mapping(enum_field_type, index);
-       if (!mapping) {
-               ret = -1;
-               goto end;
-       }
-
-       if (mapping_name) {
-               *mapping_name = g_quark_to_string(mapping->string);
-       }
-
-       if (range_begin) {
-               *range_begin = mapping->range_start._unsigned;
-       }
-
-       if (range_end) {
-               *range_end = mapping->range_end._unsigned;
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
-               struct bt_ctf_field_type *integer_container_type)
-{
-       struct bt_ctf_field_type_enumeration *enumeration = NULL;
-
-       if (!integer_container_type) {
-               goto error;
-       }
-
-       if (integer_container_type->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto error;
-       }
-
-       enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
-       if (!enumeration) {
-               goto error;
-       }
-
-       enumeration->parent.declaration = &enumeration->declaration.p;
-       enumeration->parent.declaration->id = BT_CTF_TYPE_ID_ENUM;
-       bt_get(integer_container_type);
-       enumeration->container = integer_container_type;
-       enumeration->entries = g_ptr_array_new_with_free_func(
-               (GDestroyNotify)destroy_enumeration_mapping);
-       bt_ctf_field_type_init(&enumeration->parent, FALSE);
-       return &enumeration->parent;
-error:
-       g_free(enumeration);
-       return NULL;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *container_type = NULL;
-       struct bt_ctf_field_type_enumeration *enumeration_type;
-
-       if (!type) {
-               goto end;
-       }
-
-       if (type->declaration->id != BT_CTF_TYPE_ID_ENUM) {
-               goto end;
-       }
-
-       enumeration_type = container_of(type,
-               struct bt_ctf_field_type_enumeration, parent);
-       container_type = enumeration_type->container;
-       bt_get(container_type);
-end:
-       return container_type;
-}
-
-int bt_ctf_field_type_enumeration_add_mapping(
-               struct bt_ctf_field_type *type, const char *string,
-               int64_t range_start, int64_t range_end)
-{
-       int ret = 0;
-       GQuark mapping_name;
-       struct enumeration_mapping *mapping;
-       struct bt_ctf_field_type_enumeration *enumeration;
-       char *escaped_string;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
-               type->frozen ||
-               (range_end < range_start)) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!string || strlen(string) == 0) {
-               ret = -1;
-               goto end;
-       }
-
-       escaped_string = g_strescape(string, NULL);
-       if (!escaped_string) {
-               ret = -1;
-               goto end;
-       }
-
-       mapping = g_new(struct enumeration_mapping, 1);
-       if (!mapping) {
-               ret = -1;
-               goto error_free;
-       }
-       mapping_name = g_quark_from_string(escaped_string);
-       *mapping = (struct enumeration_mapping) {
-               .range_start._signed = range_start,
-               .range_end._signed = range_end,
-               .string =  mapping_name,
-       };
-       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
-               parent);
-       g_ptr_array_add(enumeration->entries, mapping);
-       g_ptr_array_sort(enumeration->entries,
-               (GCompareFunc)compare_enumeration_mappings_signed);
-error_free:
-       free(escaped_string);
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_enumeration_add_mapping_unsigned(
-               struct bt_ctf_field_type *type, const char *string,
-               uint64_t range_start, uint64_t range_end)
-{
-       int ret = 0;
-       GQuark mapping_name;
-       struct enumeration_mapping *mapping;
-       struct bt_ctf_field_type_enumeration *enumeration;
-       char *escaped_string;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM) ||
-               type->frozen ||
-               (range_end < range_start)) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!string || strlen(string) == 0) {
-               ret = -1;
-               goto end;
-       }
-
-       escaped_string = g_strescape(string, NULL);
-       if (!escaped_string) {
-               ret = -1;
-               goto end;
-       }
-
-       mapping = g_new(struct enumeration_mapping, 1);
-       if (!mapping) {
-               ret = -1;
-               goto error_free;
-       }
-       mapping_name = g_quark_from_string(escaped_string);
-       *mapping = (struct enumeration_mapping) {
-               .range_start._unsigned = range_start,
-               .range_end._unsigned = range_end,
-               .string = mapping_name,
-       };
-       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
-               parent);
-       g_ptr_array_add(enumeration->entries, mapping);
-       g_ptr_array_sort(enumeration->entries,
-               (GCompareFunc)compare_enumeration_mappings_unsigned);
-error_free:
-       free(escaped_string);
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_enumeration_get_mapping_count(
-               struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_enumeration *enumeration;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ENUM)) {
-               ret = -1;
-               goto end;
-       }
-
-       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
-               parent);
-       ret = (int) enumeration->entries->len;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
-{
-       struct bt_ctf_field_type_floating_point *floating_point =
-               g_new0(struct bt_ctf_field_type_floating_point, 1);
-
-       if (!floating_point) {
-               goto end;
-       }
-
-       floating_point->declaration.sign = &floating_point->sign;
-       floating_point->declaration.mantissa = &floating_point->mantissa;
-       floating_point->declaration.exp = &floating_point->exp;
-       floating_point->sign.len = 1;
-       floating_point->parent.declaration = &floating_point->declaration.p;
-       floating_point->parent.declaration->id = BT_CTF_TYPE_ID_FLOAT;
-       floating_point->declaration.exp->len =
-               sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
-       floating_point->declaration.mantissa->len = FLT_MANT_DIG - 1;
-       floating_point->sign.p.alignment = 1;
-       floating_point->mantissa.p.alignment = 1;
-       floating_point->exp.p.alignment = 1;
-
-       bt_ctf_field_type_init(&floating_point->parent, TRUE);
-end:
-       return floating_point ? &floating_point->parent : NULL;
-}
-
-int bt_ctf_field_type_floating_point_get_exponent_digits(
-               struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_floating_point *floating_point;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-       ret = (int) floating_point->declaration.exp->len;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_floating_point_set_exponent_digits(
-               struct bt_ctf_field_type *type,
-               unsigned int exponent_digits)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_floating_point *floating_point;
-
-       if (!type || type->frozen ||
-               (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-       if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
-               (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
-               (exponent_digits !=
-                       sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point->declaration.exp->len = exponent_digits;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_floating_point_get_mantissa_digits(
-               struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_floating_point *floating_point;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-       ret = (int) floating_point->mantissa.len + 1;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_floating_point_set_mantissa_digits(
-               struct bt_ctf_field_type *type,
-               unsigned int mantissa_digits)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_floating_point *floating_point;
-
-       if (!type || type->frozen ||
-               (type->declaration->id != BT_CTF_TYPE_ID_FLOAT)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-
-       if ((mantissa_digits != FLT_MANT_DIG) &&
-               (mantissa_digits != DBL_MANT_DIG) &&
-               (mantissa_digits != LDBL_MANT_DIG)) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point->declaration.mantissa->len = mantissa_digits - 1;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
-{
-       struct bt_ctf_field_type_structure *structure =
-               g_new0(struct bt_ctf_field_type_structure, 1);
-
-       if (!structure) {
-               goto error;
-       }
-
-       structure->parent.declaration = &structure->declaration.p;
-       structure->parent.declaration->id = BT_CTF_TYPE_ID_STRUCT;
-       structure->fields = g_ptr_array_new_with_free_func(
-               (GDestroyNotify)destroy_structure_field);
-       structure->field_name_to_index = g_hash_table_new(NULL, NULL);
-       bt_ctf_field_type_init(&structure->parent, TRUE);
-       return &structure->parent;
-error:
-       return NULL;
-}
-
-int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *field_type,
-               const char *field_name)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_structure *structure;
-
-       /*
-        * TODO: check that `field_type` does not contain `type`,
-        *       recursively.
-        */
-       if (!type || !field_type || type->frozen ||
-               bt_ctf_validate_identifier(field_name) ||
-               (type->declaration->id != BT_CTF_TYPE_ID_STRUCT) ||
-               type == field_type) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(type,
-               struct bt_ctf_field_type_structure, parent);
-       if (add_structure_field(structure->fields,
-               structure->field_name_to_index, field_type, field_name)) {
-               ret = -1;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_structure_get_field_count(
-               struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_structure *structure;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       ret = (int) structure->fields->len;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
-               const char **field_name, struct bt_ctf_field_type **field_type,
-               int index)
-{
-       struct bt_ctf_field_type_structure *structure;
-       struct structure_field *field;
-       int ret = 0;
-
-       if (!type || index < 0 ||
-                       (type->declaration->id != BT_CTF_TYPE_ID_STRUCT)) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       if (index >= structure->fields->len) {
-               ret = -1;
-               goto end;
-       }
-
-       field = g_ptr_array_index(structure->fields, index);
-       if (field_type) {
-               *field_type = field->type;
-               bt_get(field->type);
-       }
-       if (field_name) {
-               *field_name = g_quark_to_string(field->name);
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
-               struct bt_ctf_field_type *type,
-               const char *name)
-{
-       size_t index;
-       GQuark name_quark;
-       struct structure_field *field;
-       struct bt_ctf_field_type_structure *structure;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!type || !name) {
-               goto end;
-       }
-
-       name_quark = g_quark_try_string(name);
-       if (!name_quark) {
-               goto end;
-       }
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
-               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
-               goto end;
-       }
-
-       field = structure->fields->pdata[index];
-       field_type = field->type;
-       bt_get(field_type);
-end:
-       return field_type;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
-       struct bt_ctf_field_type *enum_tag, const char *tag_name)
-{
-       struct bt_ctf_field_type_variant *variant = NULL;
-
-       if (tag_name && bt_ctf_validate_identifier(tag_name)) {
-               goto error;
-       }
-
-       variant = g_new0(struct bt_ctf_field_type_variant, 1);
-       if (!variant) {
-               goto error;
-       }
-
-       variant->parent.declaration = &variant->declaration.p;
-       variant->parent.declaration->id = BT_CTF_TYPE_ID_VARIANT;
-       variant->tag_name = g_string_new(tag_name);
-       variant->field_name_to_index = g_hash_table_new(NULL, NULL);
-       variant->fields = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) destroy_structure_field);
-       if (enum_tag) {
-               bt_get(enum_tag);
-               variant->tag = container_of(enum_tag,
-                       struct bt_ctf_field_type_enumeration, parent);
-       }
-
-       bt_ctf_field_type_init(&variant->parent, TRUE);
-       /* A variant's alignment is undefined */
-       variant->parent.declaration->alignment = 0;
-       return &variant->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_variant *variant;
-       struct bt_ctf_field_type *tag_type = NULL;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
-       if (!variant->tag) {
-               goto end;
-       }
-
-       tag_type = &variant->tag->parent;
-       bt_get(tag_type);
-end:
-       return tag_type;
-}
-
-const char *bt_ctf_field_type_variant_get_tag_name(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_variant *variant;
-       const char *tag_name = NULL;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
-       if (variant->tag_name->len == 0) {
-               goto end;
-       }
-
-       tag_name = variant->tag_name->str;
-end:
-       return tag_name;
-}
-
-int bt_ctf_field_type_variant_set_tag_name(
-               struct bt_ctf_field_type *type, const char *name)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || type->frozen ||
-               (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) ||
-               bt_ctf_validate_identifier(name)) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
-       g_string_assign(variant->tag_name, name);
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *field_type,
-               const char *field_name)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-       GQuark field_name_quark = g_quark_from_string(field_name);
-
-       /*
-        * TODO: check that `field_type` does not contain `type`,
-        *       recursively.
-        */
-       if (!type || !field_type || type->frozen ||
-               bt_ctf_validate_identifier(field_name) ||
-               (type->declaration->id != BT_CTF_TYPE_ID_VARIANT) ||
-               type == field_type) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
-
-       /* The user has explicitly provided a tag; validate against it. */
-       if (variant->tag) {
-               int name_found = 0;
-
-               /* Make sure this name is present in the enum tag */
-               for (i = 0; i < variant->tag->entries->len; i++) {
-                       struct enumeration_mapping *mapping =
-                               g_ptr_array_index(variant->tag->entries, i);
-
-                       if (mapping->string == field_name_quark) {
-                               name_found = 1;
-                               break;
-                       }
-               }
-
-               if (!name_found) {
-                       /* Validation failed */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       if (add_structure_field(variant->fields, variant->field_name_to_index,
-               field_type, field_name)) {
-               ret = -1;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
-               struct bt_ctf_field_type *type,
-               const char *field_name)
-{
-       size_t index;
-       GQuark name_quark;
-       struct structure_field *field;
-       struct bt_ctf_field_type_variant *variant;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!type || !field_name) {
-               goto end;
-       }
-
-       name_quark = g_quark_try_string(field_name);
-       if (!name_quark) {
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
-       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
-               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
-               goto end;
-       }
-
-       field = g_ptr_array_index(variant->fields, index);
-       field_type = field->type;
-       bt_get(field_type);
-end:
-       return field_type;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
-               struct bt_ctf_field_type *type,
-               struct bt_ctf_field *tag)
-{
-       int ret;
-       const char *enum_value;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
-
-       if (!type || !tag || type->declaration->id != BT_CTF_TYPE_ID_VARIANT) {
-               goto end;
-       }
-
-       iter = bt_ctf_field_enumeration_get_mappings(tag);
-       if (!iter) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_enumeration_mapping_iterator_get_signed(iter,
-               &enum_value, NULL, NULL);
-       if (ret) {
-               goto end;
-       }
-
-       field_type = bt_ctf_field_type_variant_get_field_type_by_name(
-               type, enum_value);
-end:
-       bt_put(iter);
-       return field_type;
-}
-
-int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       ret = (int) variant->fields->len;
-end:
-       return ret;
-
-}
-
-int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
-               const char **field_name, struct bt_ctf_field_type **field_type,
-               int index)
-{
-       struct bt_ctf_field_type_variant *variant;
-       struct structure_field *field;
-       int ret = 0;
-
-       if (!type || index < 0 ||
-                       (type->declaration->id != BT_CTF_TYPE_ID_VARIANT)) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       if (index >= variant->fields->len) {
-               ret = -1;
-               goto end;
-       }
-
-       field = g_ptr_array_index(variant->fields, index);
-       if (field_type) {
-               *field_type = field->type;
-               bt_get(field->type);
-       }
-       if (field_name) {
-               *field_name = g_quark_to_string(field->name);
-       }
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_array_create(
-               struct bt_ctf_field_type *element_type,
-               unsigned int length)
-{
-       struct bt_ctf_field_type_array *array = NULL;
-
-       if (!element_type || length == 0) {
-               goto error;
-       }
-
-       array = g_new0(struct bt_ctf_field_type_array, 1);
-       if (!array) {
-               goto error;
-       }
-
-       array->parent.declaration = &array->declaration.p;
-       array->parent.declaration->id = BT_CTF_TYPE_ID_ARRAY;
-
-       bt_get(element_type);
-       array->element_type = element_type;
-       array->length = length;
-       bt_ctf_field_type_init(&array->parent, FALSE);
-       return &array->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *ret = NULL;
-       struct bt_ctf_field_type_array *array;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
-               goto end;
-       }
-
-       array = container_of(type, struct bt_ctf_field_type_array, parent);
-       ret = array->element_type;
-       bt_get(ret);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *element_type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_array *array;
-
-       if (!type || !element_type ||
-                       (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
-               ret = -1;
-               goto end;
-       }
-
-       array = container_of(type, struct bt_ctf_field_type_array, parent);
-
-       if (array->element_type) {
-               BT_PUT(array->element_type);
-       }
-
-       array->element_type = element_type;
-       bt_get(array->element_type);
-
-end:
-       return ret;
-}
-
-int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
-{
-       int64_t ret;
-       struct bt_ctf_field_type_array *array;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_ARRAY)) {
-               ret = -1;
-               goto end;
-       }
-
-       array = container_of(type, struct bt_ctf_field_type_array, parent);
-       ret = (int64_t) array->length;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
-               struct bt_ctf_field_type *element_type,
-               const char *length_field_name)
-{
-       struct bt_ctf_field_type_sequence *sequence = NULL;
-
-       if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
-               goto error;
-       }
-
-       sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
-       if (!sequence) {
-               goto error;
-       }
-
-       sequence->parent.declaration = &sequence->declaration.p;
-       sequence->parent.declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
-       bt_get(element_type);
-       sequence->element_type = element_type;
-       sequence->length_field_name = g_string_new(length_field_name);
-       bt_ctf_field_type_init(&sequence->parent, FALSE);
-       return &sequence->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *ret = NULL;
-       struct bt_ctf_field_type_sequence *sequence;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
-               goto end;
-       }
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-       ret = sequence->element_type;
-       bt_get(ret);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *element_type)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_sequence *sequence;
-
-       if (!type || !element_type ||
-                       (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
-               ret = -1;
-               goto end;
-       }
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
-
-       if (sequence->element_type) {
-               BT_PUT(sequence->element_type);
-       }
-
-       sequence->element_type = element_type;
-       bt_get(sequence->element_type);
-
-end:
-       return ret;
-}
-
-const char *bt_ctf_field_type_sequence_get_length_field_name(
-               struct bt_ctf_field_type *type)
-{
-       const char *ret = NULL;
-       struct bt_ctf_field_type_sequence *sequence;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_SEQUENCE)) {
-               goto end;
-       }
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-       ret = sequence->length_field_name->str;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
-{
-       struct bt_ctf_field_type_string *string =
-               g_new0(struct bt_ctf_field_type_string, 1);
-
-       if (!string) {
-               return NULL;
-       }
-
-       string->parent.declaration = &string->declaration.p;
-       string->parent.declaration->id = BT_CTF_TYPE_ID_STRING;
-       bt_ctf_field_type_init(&string->parent, TRUE);
-       string->declaration.encoding = BT_CTF_STRING_ENCODING_UTF8;
-       string->parent.declaration->alignment = CHAR_BIT;
-       return &string->parent;
-}
-
-enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_string *string;
-       enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
-
-       if (!type || (type->declaration->id != BT_CTF_TYPE_ID_STRING)) {
-               goto end;
-       }
-
-       string = container_of(type, struct bt_ctf_field_type_string,
-               parent);
-       ret = string->declaration.encoding;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
-               enum bt_ctf_string_encoding encoding)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_string *string;
-
-       if (!type || type->declaration->id != BT_CTF_TYPE_ID_STRING ||
-               (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
-               encoding != BT_CTF_STRING_ENCODING_ASCII)) {
-               ret = -1;
-               goto end;
-       }
-
-       string = container_of(type, struct bt_ctf_field_type_string, parent);
-       string->declaration.encoding = encoding;
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
-{
-       int ret;
-       enum bt_ctf_type_id type_id;
-
-       if (!type) {
-               ret = -1;
-               goto end;
-       }
-
-       if (type->frozen) {
-               ret = (int) type->declaration->alignment;
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(type);
-       switch (type_id) {
-       case BT_CTF_TYPE_ID_SEQUENCE:
-       {
-               struct bt_ctf_field_type *element =
-                       bt_ctf_field_type_sequence_get_element_type(type);
-
-               if (!element) {
-                       ret = -1;
-                       goto end;
-               }
-
-               ret = bt_ctf_field_type_get_alignment(element);
-               bt_put(element);
-               break;
-       }
-       case BT_CTF_TYPE_ID_ARRAY:
-       {
-               struct bt_ctf_field_type *element =
-                       bt_ctf_field_type_array_get_element_type(type);
-
-               if (!element) {
-                       ret = -1;
-                       goto end;
-               }
-
-               ret = bt_ctf_field_type_get_alignment(element);
-               bt_put(element);
-               break;
-       }
-       case BT_CTF_TYPE_ID_STRUCT:
-       {
-               int i, element_count;
-
-               element_count = bt_ctf_field_type_structure_get_field_count(
-                       type);
-               if (element_count < 0) {
-                       ret = element_count;
-                       goto end;
-               }
-
-               for (i = 0; i < element_count; i++) {
-                       struct bt_ctf_field_type *field;
-                       int field_alignment;
-
-                       ret = bt_ctf_field_type_structure_get_field(type, NULL,
-                               &field, i);
-                       if (ret) {
-                               goto end;
-                       }
-
-                       assert(field);
-                       field_alignment = bt_ctf_field_type_get_alignment(
-                               field);
-                       bt_put(field);
-                       if (field_alignment < 0) {
-                               ret = field_alignment;
-                               goto end;
-                       }
-
-                       type->declaration->alignment = MAX(field_alignment,
-                               type->declaration->alignment);
-               }
-               ret = (int) type->declaration->alignment;
-               break;
-       }
-       case BT_CTF_TYPE_ID_UNKNOWN:
-               ret = -1;
-               break;
-       default:
-               ret = (int) type->declaration->alignment;
-               break;
-       }
-end:
-       return ret;
-}
-
-static inline
-int is_power_of_two(unsigned int value)
-{
-       return ((value & (value - 1)) == 0) && value > 0;
-}
-
-int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
-               unsigned int alignment)
-{
-       int ret = 0;
-       enum bt_ctf_type_id type_id;
-
-       /* Alignment must be a power of two */
-       if (!type || type->frozen || !is_power_of_two(alignment)) {
-               ret = -1;
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(type);
-       if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
-               ret = -1;
-               goto end;
-       }
-
-       if (type->declaration->id == BT_CTF_TYPE_ID_STRING &&
-               alignment != CHAR_BIT) {
-               ret = -1;
-               goto end;
-       }
-
-       if (type_id == BT_CTF_TYPE_ID_VARIANT ||
-               type_id == BT_CTF_TYPE_ID_SEQUENCE ||
-               type_id == BT_CTF_TYPE_ID_ARRAY) {
-               /* Setting an alignment on these types makes no sense */
-               ret = -1;
-               goto end;
-       }
-
-       type->declaration->alignment = alignment;
-       ret = 0;
-end:
-       return ret;
-}
-
-enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
-               struct bt_ctf_field_type *type)
-{
-       enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
-
-       if (!type) {
-               goto end;
-       }
-
-       switch (type->declaration->id) {
-       case BT_CTF_TYPE_ID_INTEGER:
-       {
-               struct bt_ctf_field_type_integer *integer = container_of(
-                       type, struct bt_ctf_field_type_integer, parent);
-               ret = integer->user_byte_order;
-               break;
-       }
-       case BT_CTF_TYPE_ID_ENUM:
-       {
-               struct bt_ctf_field_type_enumeration *enum_ft = container_of(
-                       type, struct bt_ctf_field_type_enumeration, parent);
-               ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
-               break;
-       }
-       case BT_CTF_TYPE_ID_FLOAT:
-       {
-               struct bt_ctf_field_type_floating_point *floating_point =
-                       container_of(type,
-                               struct bt_ctf_field_type_floating_point,
-                               parent);
-               ret = floating_point->user_byte_order;
-               break;
-       }
-       default:
-               goto end;
-       }
-
-       assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
-               ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
-               ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
-               ret == BT_CTF_BYTE_ORDER_NETWORK);
-
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
-               enum bt_ctf_byte_order byte_order)
-{
-       int ret = 0;
-       int internal_byte_order;
-       enum bt_ctf_type_id type_id;
-
-       if (!type || type->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       switch (byte_order) {
-       case BT_CTF_BYTE_ORDER_NATIVE:
-               /* Leave unset. Will be initialized by parent. */
-               internal_byte_order = 0;
-               break;
-       case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
-               internal_byte_order = LITTLE_ENDIAN;
-               break;
-       case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
-       case BT_CTF_BYTE_ORDER_NETWORK:
-               internal_byte_order = BIG_ENDIAN;
-               break;
-       default:
-               ret = -1;
-               goto end;
-       }
-
-       type_id = type->declaration->id;
-       if (set_byte_order_funcs[type_id]) {
-               set_byte_order_funcs[type_id](type, internal_byte_order, 0);
-       }
-end:
-       return ret;
-}
-
-enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
-               struct bt_ctf_field_type *type)
-{
-       if (!type) {
-               return BT_CTF_TYPE_ID_UNKNOWN;
-       }
-
-       return type->declaration->id;
-}
-
-int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
-}
-
-int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
-}
-
-int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
-}
-
-int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
-}
-
-int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
-}
-
-int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
-}
-
-int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
-}
-
-int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
-{
-       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
-}
-
-void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
-{
-       bt_get(type);
-}
-
-void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
-{
-       bt_put(type);
-}
-
-BT_HIDDEN
-void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
-{
-       if (!type) {
-               return;
-       }
-
-       type->freeze(type);
-}
-
-BT_HIDDEN
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
-               struct bt_ctf_field_type_variant *variant,
-               int64_t tag_value)
-{
-       struct bt_ctf_field_type *type = NULL;
-       GQuark field_name_quark;
-       gpointer index;
-       struct structure_field *field_entry;
-       struct range_overlap_query query = {
-               .range_start._signed = tag_value,
-               .range_end._signed = tag_value,
-               .mapping_name = 0,
-               .overlaps = 0,
-       };
-
-       g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
-               &query);
-       if (!query.overlaps) {
-               goto end;
-       }
-
-       field_name_quark = query.mapping_name;
-       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
-               GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
-               goto end;
-       }
-
-       field_entry = g_ptr_array_index(variant->fields, (size_t) index);
-       type = field_entry->type;
-end:
-       return type;
-}
-
-BT_HIDDEN
-struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
-               struct bt_ctf_field_type_variant *variant,
-               uint64_t tag_value)
-{
-       struct bt_ctf_field_type *type = NULL;
-       GQuark field_name_quark;
-       gpointer index;
-       struct structure_field *field_entry;
-       struct range_overlap_query query = {
-               .range_start._unsigned = tag_value,
-               .range_end._unsigned = tag_value,
-               .mapping_name = 0,
-               .overlaps = 0,
-       };
-
-       g_ptr_array_foreach(variant->tag->entries,
-               check_ranges_overlap_unsigned,
-               &query);
-       if (!query.overlaps) {
-               goto end;
-       }
-
-       field_name_quark = query.mapping_name;
-       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
-               GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
-               goto end;
-       }
-
-       field_entry = g_ptr_array_index(variant->fields, (size_t)index);
-       type = field_entry->type;
-end:
-       return type;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       int ret;
-
-       if (!type || !context) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Make sure field type is valid before serializing it */
-       ret = bt_ctf_field_type_validate(type);
-
-       if (ret) {
-               goto end;
-       }
-
-       ret = type->serialize(type, context);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void bt_ctf_field_type_set_native_byte_order(struct bt_ctf_field_type *type,
-               int byte_order)
-{
-       if (!type) {
-               return;
-       }
-
-       assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
-       if (set_byte_order_funcs[type->declaration->id]) {
-               set_byte_order_funcs[type->declaration->id](type,
-                       byte_order, 1);
-       }
-}
-
-struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy = NULL;
-
-       if (!type) {
-               goto end;
-       }
-
-       copy = type_copy_funcs[type->declaration->id](type);
-end:
-       return copy;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_structure_get_field_name_index(
-               struct bt_ctf_field_type *type, const char *name)
-{
-       int ret;
-       size_t index;
-       GQuark name_quark;
-       struct bt_ctf_field_type_structure *structure;
-
-       if (!type || !name ||
-               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       name_quark = g_quark_try_string(name);
-       if (!name_quark) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
-               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
-               ret = -1;
-               goto end;
-       }
-       ret = (int) index;
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *field, int index)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_structure *structure;
-
-       if (!type || !field ||
-               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       if (index < 0 || index >= structure->fields->len) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_get(field);
-       bt_put(((struct structure_field *)
-               g_ptr_array_index(structure->fields, index))->type);
-       ((struct structure_field *) structure->fields->pdata[index])->type =
-               field;
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_variant_get_field_name_index(
-               struct bt_ctf_field_type *type, const char *name)
-{
-       int ret;
-       size_t index;
-       GQuark name_quark;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || !name ||
-               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
-               ret = -1;
-               goto end;
-       }
-
-       name_quark = g_quark_try_string(name);
-       if (!name_quark) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
-               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
-               ret = -1;
-               goto end;
-       }
-       ret = (int) index;
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_sequence_set_length_field_path(
-               struct bt_ctf_field_type *type,
-               struct bt_ctf_field_path *path)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_sequence *sequence;
-
-       if (!type || bt_ctf_field_type_get_type_id(type) !=
-                       BT_CTF_TYPE_ID_SEQUENCE) {
-               ret = -1;
-               goto end;
-       }
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-       bt_get(path);
-       BT_MOVE(sequence->length_field_path, path);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_path *path)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || bt_ctf_field_type_get_type_id(type) !=
-                       BT_CTF_TYPE_ID_VARIANT) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       bt_get(path);
-       BT_MOVE(variant->tag_field_path, path);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *tag)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || !tag ||
-                       bt_ctf_field_type_get_type_id(tag) !=
-                       BT_CTF_TYPE_ID_ENUM) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       bt_get(tag);
-       if (variant->tag) {
-               bt_put(&variant->tag->parent);
-       }
-       variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
-               parent);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
-               struct bt_ctf_field_type *field, int index)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || !field ||
-               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       if (index < 0 || index >= variant->fields->len) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_get(field);
-       bt_put(((struct structure_field *)
-               g_ptr_array_index(variant->fields, index))->type);
-       ((struct structure_field *) variant->fields->pdata[index])->type =
-               field;
-end:
-       return ret;
-}
-
-static
-void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_integer *integer =
-               (struct bt_ctf_field_type_integer *) type;
-
-       if (!type) {
-               return;
-       }
-
-       bt_put(integer->mapped_clock);
-       g_free(integer);
-}
-
-static
-void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_enumeration *enumeration =
-               (struct bt_ctf_field_type_enumeration *) type;
-
-       if (!type) {
-               return;
-       }
-
-       g_ptr_array_free(enumeration->entries, TRUE);
-       bt_put(enumeration->container);
-       g_free(enumeration);
-}
-
-static
-void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_floating_point *floating_point =
-               (struct bt_ctf_field_type_floating_point *) type;
-
-       if (!type) {
-               return;
-       }
-
-       g_free(floating_point);
-}
-
-static
-void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_structure *structure =
-               (struct bt_ctf_field_type_structure *) type;
-
-       if (!type) {
-               return;
-       }
-
-       g_ptr_array_free(structure->fields, TRUE);
-       g_hash_table_destroy(structure->field_name_to_index);
-       g_free(structure);
-}
-
-static
-void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_variant *variant =
-               (struct bt_ctf_field_type_variant *) type;
-
-       if (!type) {
-               return;
-       }
-
-       g_ptr_array_free(variant->fields, TRUE);
-       g_hash_table_destroy(variant->field_name_to_index);
-       g_string_free(variant->tag_name, TRUE);
-       bt_put(&variant->tag->parent);
-       BT_PUT(variant->tag_field_path);
-       g_free(variant);
-}
-
-static
-void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_array *array =
-               (struct bt_ctf_field_type_array *) type;
-
-       if (!type) {
-               return;
-       }
-
-       bt_put(array->element_type);
-       g_free(array);
-}
-
-static
-void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_sequence *sequence =
-               (struct bt_ctf_field_type_sequence *) type;
-
-       if (!type) {
-               return;
-       }
-
-       bt_put(sequence->element_type);
-       g_string_free(sequence->length_field_name, TRUE);
-       BT_PUT(sequence->length_field_path);
-       g_free(sequence);
-}
-
-static
-void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_string *string =
-               (struct bt_ctf_field_type_string *) type;
-
-       if (!type) {
-               return;
-       }
-
-       g_free(string);
-}
-
-static
-void generic_field_type_freeze(struct bt_ctf_field_type *type)
-{
-       type->frozen = 1;
-}
-
-static
-void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_integer *integer_type = container_of(
-               type, struct bt_ctf_field_type_integer, parent);
-
-       if (integer_type->mapped_clock) {
-               bt_ctf_clock_class_freeze(integer_type->mapped_clock);
-       }
-
-       generic_field_type_freeze(type);
-}
-
-static
-void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
-               type, struct bt_ctf_field_type_enumeration, parent);
-
-       set_enumeration_range_overlap(type);
-
-       generic_field_type_freeze(type);
-       bt_ctf_field_type_freeze(enumeration_type->container);
-}
-
-static
-void freeze_structure_field(struct structure_field *field)
-{
-       bt_ctf_field_type_freeze(field->type);
-}
-
-static
-void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_structure *structure_type = container_of(
-               type, struct bt_ctf_field_type_structure, parent);
-
-       /* Cache the alignment */
-       type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
-       generic_field_type_freeze(type);
-       g_ptr_array_foreach(structure_type->fields,
-               (GFunc) freeze_structure_field, NULL);
-}
-
-static
-void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_variant *variant_type = container_of(
-               type, struct bt_ctf_field_type_variant, parent);
-
-       generic_field_type_freeze(type);
-       g_ptr_array_foreach(variant_type->fields,
-               (GFunc) freeze_structure_field, NULL);
-}
-
-static
-void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_array *array_type = container_of(
-               type, struct bt_ctf_field_type_array, parent);
-
-       /* Cache the alignment */
-       type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
-       generic_field_type_freeze(type);
-       bt_ctf_field_type_freeze(array_type->element_type);
-}
-
-static
-void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_sequence *sequence_type = container_of(
-               type, struct bt_ctf_field_type_sequence, parent);
-
-       /* Cache the alignment */
-       type->declaration->alignment = bt_ctf_field_type_get_alignment(type);
-       generic_field_type_freeze(type);
-       bt_ctf_field_type_freeze(sequence_type->element_type);
-}
-
-static
-const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
-{
-       const char *encoding_string;
-
-       switch (encoding) {
-       case BT_CTF_STRING_ENCODING_NONE:
-               encoding_string = "none";
-               break;
-       case BT_CTF_STRING_ENCODING_ASCII:
-               encoding_string = "ASCII";
-               break;
-       case BT_CTF_STRING_ENCODING_UTF8:
-               encoding_string = "UTF8";
-               break;
-       default:
-               encoding_string = "unknown";
-               break;
-       }
-
-       return encoding_string;
-}
-
-static
-const char *get_integer_base_string(enum bt_ctf_integer_base base)
-{
-       const char *base_string;
-
-       switch (base) {
-       case BT_CTF_INTEGER_BASE_DECIMAL:
-               base_string = "decimal";
-               break;
-       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
-               base_string = "hexadecimal";
-               break;
-       case BT_CTF_INTEGER_BASE_OCTAL:
-               base_string = "octal";
-               break;
-       case BT_CTF_INTEGER_BASE_BINARY:
-               base_string = "binary";
-               break;
-       default:
-               base_string = "unknown";
-               break;
-       }
-
-       return base_string;
-}
-
-static
-int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       struct bt_ctf_field_type_integer *integer = container_of(type,
-               struct bt_ctf_field_type_integer, parent);
-       int ret = 0;
-
-       g_string_append_printf(context->string,
-               "integer { size = %zu; align = %zu; signed = %s; encoding = %s; base = %s; byte_order = %s",
-               integer->declaration.len, type->declaration->alignment,
-               (integer->declaration.signedness ? "true" : "false"),
-               get_encoding_string(integer->declaration.encoding),
-               get_integer_base_string(integer->declaration.base),
-               get_byte_order_string(integer->declaration.byte_order));
-       if (integer->mapped_clock) {
-               const char *clock_name = bt_ctf_clock_class_get_name(
-                       integer->mapped_clock);
-
-               if (!clock_name) {
-                       ret = -1;
-                       goto end;
-               }
-
-               g_string_append_printf(context->string,
-                       "; map = clock.%s.value", clock_name);
-       }
-
-       g_string_append(context->string, "; }");
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       size_t entry;
-       int ret;
-       struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
-               struct bt_ctf_field_type_enumeration, parent);
-       struct bt_ctf_field_type *container_type;
-       int container_signed;
-
-       container_type = bt_ctf_field_type_enumeration_get_container_type(type);
-       if (!container_type) {
-               ret = -1;
-               goto end;
-       }
-
-       container_signed = bt_ctf_field_type_integer_get_signed(container_type);
-       if (container_signed < 0) {
-               ret = container_signed;
-               goto error_put_container_type;
-       }
-
-       g_string_append(context->string, "enum : ");
-       ret = bt_ctf_field_type_serialize(enumeration->container, context);
-       if (ret) {
-               goto error_put_container_type;
-       }
-
-       g_string_append(context->string, " { ");
-       for (entry = 0; entry < enumeration->entries->len; entry++) {
-               struct enumeration_mapping *mapping =
-                       enumeration->entries->pdata[entry];
-
-               if (container_signed) {
-                       if (mapping->range_start._signed ==
-                               mapping->range_end._signed) {
-                               g_string_append_printf(context->string,
-                                       "\"%s\" = %" PRId64,
-                                       g_quark_to_string(mapping->string),
-                                       mapping->range_start._signed);
-                       } else {
-                               g_string_append_printf(context->string,
-                                       "\"%s\" = %" PRId64 " ... %" PRId64,
-                                       g_quark_to_string(mapping->string),
-                                       mapping->range_start._signed,
-                                       mapping->range_end._signed);
-                       }
-               } else {
-                       if (mapping->range_start._unsigned ==
-                               mapping->range_end._unsigned) {
-                               g_string_append_printf(context->string,
-                                       "\"%s\" = %" PRIu64,
-                                       g_quark_to_string(mapping->string),
-                                       mapping->range_start._unsigned);
-                       } else {
-                               g_string_append_printf(context->string,
-                                       "\"%s\" = %" PRIu64 " ... %" PRIu64,
-                                       g_quark_to_string(mapping->string),
-                                       mapping->range_start._unsigned,
-                                       mapping->range_end._unsigned);
-                       }
-               }
-
-               g_string_append(context->string,
-                       ((entry != (enumeration->entries->len - 1)) ?
-                       ", " : " }"));
-       }
-
-       if (context->field_name->len) {
-               g_string_append_printf(context->string, " %s",
-                       context->field_name->str);
-               g_string_assign(context->field_name, "");
-       }
-error_put_container_type:
-       bt_put(container_type);
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       struct bt_ctf_field_type_floating_point *floating_point = container_of(
-               type, struct bt_ctf_field_type_floating_point, parent);
-
-       g_string_append_printf(context->string,
-               "floating_point { exp_dig = %zu; mant_dig = %zu; byte_order = %s; align = %zu; }",
-               floating_point->declaration.exp->len,
-               floating_point->declaration.mantissa->len + 1,
-               get_byte_order_string(floating_point->declaration.byte_order),
-               type->declaration->alignment);
-       return 0;
-}
-
-static
-int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       size_t i;
-       unsigned int indent;
-       int ret = 0;
-       struct bt_ctf_field_type_structure *structure = container_of(type,
-               struct bt_ctf_field_type_structure, parent);
-       GString *structure_field_name = context->field_name;
-
-       context->field_name = g_string_new("");
-
-       context->current_indentation_level++;
-       g_string_append(context->string, "struct {\n");
-
-       for (i = 0; i < structure->fields->len; i++) {
-               struct structure_field *field;
-
-               for (indent = 0; indent < context->current_indentation_level;
-                       indent++) {
-                       g_string_append_c(context->string, '\t');
-               }
-
-               field = structure->fields->pdata[i];
-               g_string_assign(context->field_name,
-                       g_quark_to_string(field->name));
-               ret = bt_ctf_field_type_serialize(field->type, context);
-               if (ret) {
-                       goto end;
-               }
-
-               if (context->field_name->len) {
-                       g_string_append_printf(context->string, " %s",
-                               context->field_name->str);
-               }
-               g_string_append(context->string, ";\n");
-       }
-
-       context->current_indentation_level--;
-       for (indent = 0; indent < context->current_indentation_level;
-               indent++) {
-               g_string_append_c(context->string, '\t');
-       }
-
-       g_string_append_printf(context->string, "} align(%zu)",
-                type->declaration->alignment);
-end:
-       g_string_free(context->field_name, TRUE);
-       context->field_name = structure_field_name;
-       return ret;
-}
-
-static
-int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       size_t i;
-       unsigned int indent;
-       int ret = 0;
-       struct bt_ctf_field_type_variant *variant = container_of(
-               type, struct bt_ctf_field_type_variant, parent);
-       GString *variant_field_name = context->field_name;
-
-       context->field_name = g_string_new("");
-       if (variant->tag_name->len > 0) {
-               g_string_append_printf(context->string,
-                       "variant <%s> {\n", variant->tag_name->str);
-       } else {
-               g_string_append(context->string, "variant {\n");
-       }
-
-       context->current_indentation_level++;
-       for (i = 0; i < variant->fields->len; i++) {
-               struct structure_field *field = variant->fields->pdata[i];
-
-               g_string_assign(context->field_name,
-                       g_quark_to_string(field->name));
-               for (indent = 0; indent < context->current_indentation_level;
-                       indent++) {
-                       g_string_append_c(context->string, '\t');
-               }
-
-               g_string_assign(context->field_name,
-                       g_quark_to_string(field->name));
-               ret = bt_ctf_field_type_serialize(field->type, context);
-               if (ret) {
-                       goto end;
-               }
-
-               if (context->field_name->len) {
-                       g_string_append_printf(context->string, " %s;",
-                               context->field_name->str);
-               }
-
-               g_string_append_c(context->string, '\n');
-       }
-
-       context->current_indentation_level--;
-       for (indent = 0; indent < context->current_indentation_level;
-               indent++) {
-               g_string_append_c(context->string, '\t');
-       }
-
-       g_string_append(context->string, "}");
-end:
-       g_string_free(context->field_name, TRUE);
-       context->field_name = variant_field_name;
-       return ret;
-}
-
-static
-int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_array *array = container_of(type,
-               struct bt_ctf_field_type_array, parent);
-
-       ret = bt_ctf_field_type_serialize(array->element_type, context);
-       if (ret) {
-               goto end;
-       }
-
-       if (context->field_name->len) {
-               g_string_append_printf(context->string, " %s[%u]",
-                       context->field_name->str, array->length);
-               g_string_assign(context->field_name, "");
-       } else {
-               g_string_append_printf(context->string, "[%u]", array->length);
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_sequence *sequence = container_of(
-               type, struct bt_ctf_field_type_sequence, parent);
-
-       ret = bt_ctf_field_type_serialize(sequence->element_type, context);
-       if (ret) {
-               goto end;
-       }
-
-       if (context->field_name->len) {
-               g_string_append_printf(context->string, " %s[%s]",
-                       context->field_name->str,
-                       sequence->length_field_name->str);
-               g_string_assign(context->field_name, "");
-       } else {
-               g_string_append_printf(context->string, "[%s]",
-                       sequence->length_field_name->str);
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
-               struct metadata_context *context)
-{
-       struct bt_ctf_field_type_string *string = container_of(
-               type, struct bt_ctf_field_type_string, parent);
-
-       g_string_append_printf(context->string,
-               "string { encoding = %s; }",
-               get_encoding_string(string->declaration.encoding));
-       return 0;
-}
-
-static
-enum bt_ctf_byte_order get_ctf_ir_byte_order(int byte_order) {
-       enum bt_ctf_byte_order ret;
-
-       switch (byte_order) {
-       case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
-       case LITTLE_ENDIAN:
-               ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
-               break;
-       case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
-       case BIG_ENDIAN:
-               ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
-               break;
-       case BT_CTF_BYTE_ORDER_NETWORK:
-               ret = BT_CTF_BYTE_ORDER_NETWORK;
-               break;
-       case BT_CTF_BYTE_ORDER_NATIVE:
-               ret = BT_CTF_BYTE_ORDER_NATIVE;
-               break;
-       default:
-               ret = BT_CTF_BYTE_ORDER_UNKNOWN;
-               break;
-       }
-
-       return ret;
-}
-
-static
-void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
-               int byte_order, int set_native)
-{
-       struct bt_ctf_field_type_integer *integer_type = container_of(type,
-               struct bt_ctf_field_type_integer, parent);
-
-       if (set_native) {
-               if (integer_type->user_byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
-                       /*
-                        * User byte order is native, so we can set
-                        * the real byte order.
-                        */
-                       integer_type->declaration.byte_order =
-                               byte_order;
-               }
-       } else {
-               integer_type->user_byte_order =
-                       get_ctf_ir_byte_order(byte_order);
-               integer_type->declaration.byte_order = byte_order;
-       }
-}
-
-static
-void bt_ctf_field_type_enumeration_set_byte_order(
-               struct bt_ctf_field_type *type, int byte_order, int set_native)
-{
-       struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
-               struct bt_ctf_field_type_enumeration, parent);
-
-       /* Safe to assume that container is an integer */
-       bt_ctf_field_type_integer_set_byte_order(enum_type->container,
-               byte_order, set_native);
-}
-
-static
-void bt_ctf_field_type_floating_point_set_byte_order(
-               struct bt_ctf_field_type *type, int byte_order, int set_native)
-{
-       struct bt_ctf_field_type_floating_point *floating_point_type =
-               container_of(type, struct bt_ctf_field_type_floating_point,
-               parent);
-
-       if (set_native) {
-               if (floating_point_type->user_byte_order ==
-                               BT_CTF_BYTE_ORDER_NATIVE) {
-                       /*
-                        * User byte order is native, so we can set
-                        * the real byte order.
-                        */
-                       floating_point_type->declaration.byte_order =
-                               byte_order;
-                       floating_point_type->sign.byte_order =
-                               byte_order;
-                       floating_point_type->mantissa.byte_order =
-                               byte_order;
-                       floating_point_type->exp.byte_order =
-                               byte_order;
-               }
-       } else {
-               floating_point_type->user_byte_order =
-                       get_ctf_ir_byte_order(byte_order);
-               floating_point_type->declaration.byte_order = byte_order;
-               floating_point_type->sign.byte_order = byte_order;
-               floating_point_type->mantissa.byte_order = byte_order;
-               floating_point_type->exp.byte_order = byte_order;
-       }
-}
-
-static
-void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
-               int byte_order, int set_native)
-{
-       int i;
-       struct bt_ctf_field_type_structure *structure_type =
-               container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-
-       for (i = 0; i < structure_type->fields->len; i++) {
-               struct structure_field *field = g_ptr_array_index(
-                       structure_type->fields, i);
-               struct bt_ctf_field_type *field_type = field->type;
-
-               if (set_byte_order_funcs[field_type->declaration->id]) {
-                       set_byte_order_funcs[field_type->declaration->id](
-                               field_type, byte_order, set_native);
-               }
-       }
-}
-
-static
-void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
-               int byte_order, int set_native)
-{
-       int i;
-       struct bt_ctf_field_type_variant *variant_type =
-               container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-
-       for (i = 0; i < variant_type->fields->len; i++) {
-               struct structure_field *field = g_ptr_array_index(
-                       variant_type->fields, i);
-               struct bt_ctf_field_type *field_type = field->type;
-
-               if (set_byte_order_funcs[field_type->declaration->id]) {
-                       set_byte_order_funcs[field_type->declaration->id](
-                               field_type, byte_order, set_native);
-               }
-       }
-}
-
-static
-void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
-               int byte_order, int set_native)
-{
-       struct bt_ctf_field_type_array *array_type =
-               container_of(type, struct bt_ctf_field_type_array,
-               parent);
-
-       if (set_byte_order_funcs[array_type->element_type->declaration->id]) {
-               set_byte_order_funcs[array_type->element_type->declaration->id](
-                       array_type->element_type, byte_order, set_native);
-       }
-}
-
-static
-void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
-               int byte_order, int set_native)
-{
-       struct bt_ctf_field_type_sequence *sequence_type =
-               container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-
-       if (set_byte_order_funcs[
-               sequence_type->element_type->declaration->id]) {
-               set_byte_order_funcs[
-                       sequence_type->element_type->declaration->id](
-                       sequence_type->element_type, byte_order, set_native);
-       }
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy;
-       struct bt_ctf_field_type_integer *integer, *copy_integer;
-
-       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
-       copy = bt_ctf_field_type_integer_create(integer->declaration.len);
-       if (!copy) {
-               goto end;
-       }
-
-       copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
-               parent);
-       copy_integer->declaration = integer->declaration;
-       if (integer->mapped_clock) {
-               bt_get(integer->mapped_clock);
-               copy_integer->mapped_clock = integer->mapped_clock;
-       }
-
-       copy_integer->user_byte_order = integer->user_byte_order;
-
-end:
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
-               struct bt_ctf_field_type *type)
-{
-       size_t i;
-       struct bt_ctf_field_type *copy = NULL, *copy_container;
-       struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
-
-       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
-               parent);
-
-       /* Copy the source enumeration's container */
-       copy_container = bt_ctf_field_type_copy(enumeration->container);
-       if (!copy_container) {
-               goto end;
-       }
-
-       copy = bt_ctf_field_type_enumeration_create(copy_container);
-       if (!copy) {
-               goto end;
-       }
-       copy_enumeration = container_of(copy,
-               struct bt_ctf_field_type_enumeration, parent);
-
-       /* Copy all enumaration entries */
-       for (i = 0; i < enumeration->entries->len; i++) {
-               struct enumeration_mapping *mapping = g_ptr_array_index(
-                       enumeration->entries, i);
-               struct enumeration_mapping *copy_mapping = g_new0(
-                       struct enumeration_mapping, 1);
-
-               if (!copy_mapping) {
-                       goto error;
-               }
-
-               *copy_mapping = *mapping;
-               g_ptr_array_add(copy_enumeration->entries, copy_mapping);
-       }
-
-       copy_enumeration->declaration = enumeration->declaration;
-end:
-       bt_put(copy_container);
-       return copy;
-error:
-       bt_put(copy_container);
-        BT_PUT(copy);
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy;
-       struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
-
-       floating_point = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-       copy = bt_ctf_field_type_floating_point_create();
-       if (!copy) {
-               goto end;
-       }
-
-       copy_float = container_of(copy,
-               struct bt_ctf_field_type_floating_point, parent);
-       copy_float->declaration = floating_point->declaration;
-       copy_float->sign = floating_point->sign;
-       copy_float->mantissa = floating_point->mantissa;
-       copy_float->exp = floating_point->exp;
-       copy_float->user_byte_order = floating_point->user_byte_order;
-       copy_float->declaration.sign = &copy_float->sign;
-       copy_float->declaration.mantissa = &copy_float->mantissa;
-       copy_float->declaration.exp = &copy_float->exp;
-end:
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
-               struct bt_ctf_field_type *type)
-{
-       int i;
-       GHashTableIter iter;
-       gpointer key, value;
-       struct bt_ctf_field_type *copy;
-       struct bt_ctf_field_type_structure *structure, *copy_structure;
-
-       structure = container_of(type, struct bt_ctf_field_type_structure,
-               parent);
-       copy = bt_ctf_field_type_structure_create();
-       if (!copy) {
-               goto end;
-       }
-
-       copy_structure = container_of(copy,
-               struct bt_ctf_field_type_structure, parent);
-
-       /* Copy field_name_to_index */
-       g_hash_table_iter_init(&iter, structure->field_name_to_index);
-       while (g_hash_table_iter_next (&iter, &key, &value)) {
-               g_hash_table_insert(copy_structure->field_name_to_index,
-                       key, value);
-       }
-
-       for (i = 0; i < structure->fields->len; i++) {
-               struct structure_field *entry, *copy_entry;
-               struct bt_ctf_field_type *copy_field;
-
-               copy_entry = g_new0(struct structure_field, 1);
-               if (!copy_entry) {
-                       goto error;
-               }
-
-               entry = g_ptr_array_index(structure->fields, i);
-               copy_field = bt_ctf_field_type_copy(entry->type);
-               if (!copy_field) {
-                       g_free(copy_entry);
-                       goto error;
-               }
-
-               copy_entry->name = entry->name;
-               copy_entry->type = copy_field;
-               g_ptr_array_add(copy_structure->fields, copy_entry);
-       }
-
-       copy_structure->declaration = structure->declaration;
-end:
-       return copy;
-error:
-        BT_PUT(copy);
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
-               struct bt_ctf_field_type *type)
-{
-       int i;
-       GHashTableIter iter;
-       gpointer key, value;
-       struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
-       struct bt_ctf_field_type_variant *variant, *copy_variant;
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-               parent);
-       if (variant->tag) {
-               copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
-               if (!copy_tag) {
-                       goto end;
-               }
-       }
-
-       copy = bt_ctf_field_type_variant_create(copy_tag,
-               variant->tag_name->len ? variant->tag_name->str : NULL);
-       if (!copy) {
-               goto end;
-       }
-
-       copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
-               parent);
-
-       /* Copy field_name_to_index */
-       g_hash_table_iter_init(&iter, variant->field_name_to_index);
-       while (g_hash_table_iter_next (&iter, &key, &value)) {
-               g_hash_table_insert(copy_variant->field_name_to_index,
-                       key, value);
-       }
-
-       for (i = 0; i < variant->fields->len; i++) {
-               struct structure_field *entry, *copy_entry;
-               struct bt_ctf_field_type *copy_field;
-
-               copy_entry = g_new0(struct structure_field, 1);
-               if (!copy_entry) {
-                       goto error;
-               }
-
-               entry = g_ptr_array_index(variant->fields, i);
-               copy_field = bt_ctf_field_type_copy(entry->type);
-               if (!copy_field) {
-                       g_free(copy_entry);
-                       goto error;
-               }
-
-               copy_entry->name = entry->name;
-               copy_entry->type = copy_field;
-               g_ptr_array_add(copy_variant->fields, copy_entry);
-       }
-
-       copy_variant->declaration = variant->declaration;
-       if (variant->tag_field_path) {
-               copy_variant->tag_field_path = bt_ctf_field_path_copy(
-                       variant->tag_field_path);
-               if (!copy_variant->tag_field_path) {
-                       goto error;
-               }
-       }
-end:
-       bt_put(copy_tag);
-       return copy;
-error:
-       bt_put(copy_tag);
-        BT_PUT(copy);
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy = NULL, *copy_element;
-       struct bt_ctf_field_type_array *array, *copy_array;
-
-       array = container_of(type, struct bt_ctf_field_type_array,
-               parent);
-       copy_element = bt_ctf_field_type_copy(array->element_type);
-       if (!copy_element) {
-               goto end;
-       }
-
-       copy = bt_ctf_field_type_array_create(copy_element, array->length);
-       if (!copy) {
-               goto end;
-       }
-
-       copy_array = container_of(copy, struct bt_ctf_field_type_array,
-               parent);
-       copy_array->declaration = array->declaration;
-end:
-       bt_put(copy_element);
-       return copy;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy = NULL, *copy_element;
-       struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence,
-               parent);
-       copy_element = bt_ctf_field_type_copy(sequence->element_type);
-       if (!copy_element) {
-               goto end;
-       }
-
-       copy = bt_ctf_field_type_sequence_create(copy_element,
-               sequence->length_field_name->len ?
-                       sequence->length_field_name->str : NULL);
-       if (!copy) {
-               goto end;
-       }
-
-       copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
-               parent);
-       copy_sequence->declaration = sequence->declaration;
-       if (sequence->length_field_path) {
-               copy_sequence->length_field_path = bt_ctf_field_path_copy(
-                       sequence->length_field_path);
-               if (!copy_sequence->length_field_path) {
-                       goto error;
-               }
-       }
-end:
-       bt_put(copy_element);
-       return copy;
-error:
-       BT_PUT(copy);
-       goto end;
-}
-
-static
-struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type *copy;
-       struct bt_ctf_field_type_string *string, *copy_string;
-
-       copy = bt_ctf_field_type_string_create();
-       if (!copy) {
-               goto end;
-       }
-
-       string = container_of(type, struct bt_ctf_field_type_string,
-               parent);
-       copy_string = container_of(type, struct bt_ctf_field_type_string,
-               parent);
-       copy_string->declaration = string->declaration;
-end:
-       return copy;
-}
-
-static
-int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       struct bt_ctf_field_type_integer *integer_a;
-       struct bt_ctf_field_type_integer *integer_b;
-       struct declaration_integer *decl_a;
-       struct declaration_integer *decl_b;
-
-       integer_a = container_of(type_a, struct bt_ctf_field_type_integer,
-               parent);
-       integer_b = container_of(type_b, struct bt_ctf_field_type_integer,
-               parent);
-       decl_a = &integer_a->declaration;
-       decl_b = &integer_b->declaration;
-
-       /* Length */
-       if (decl_a->len != decl_b->len) {
-               goto end;
-       }
-
-       /*
-        * Compare user byte orders only, not the cached,
-        * real byte orders.
-        */
-       if (integer_a->user_byte_order != integer_b->user_byte_order) {
-               goto end;
-       }
-
-       /* Signedness */
-       if (decl_a->signedness != decl_b->signedness) {
-               goto end;
-       }
-
-       /* Base */
-       if (decl_a->base != decl_b->base) {
-               goto end;
-       }
-
-       /* Encoding */
-       if (decl_a->encoding != decl_b->encoding) {
-               goto end;
-       }
-
-       /* Mapped clock */
-       if (integer_a->mapped_clock != integer_b->mapped_clock) {
-               goto end;
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       struct bt_ctf_field_type_floating_point *float_a;
-       struct bt_ctf_field_type_floating_point *float_b;
-
-       float_a = container_of(type_a,
-               struct bt_ctf_field_type_floating_point, parent);
-       float_b = container_of(type_b,
-               struct bt_ctf_field_type_floating_point, parent);
-
-       /* Sign length */
-       if (float_a->sign.len != float_b->sign.len) {
-               goto end;
-       }
-
-       /* Exponent length */
-       if (float_a->exp.len != float_b->exp.len) {
-               goto end;
-       }
-
-       /* Mantissa length */
-       if (float_a->mantissa.len != float_b->mantissa.len) {
-               goto end;
-       }
-
-       /*
-        * Compare user byte orders only, not the cached,
-        * real byte orders.
-        */
-       if (float_a->user_byte_order != float_b->user_byte_order) {
-               goto end;
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
-               struct enumeration_mapping *mapping_b)
-{
-       int ret = 1;
-
-       /* Label */
-       if (mapping_a->string != mapping_b->string) {
-               goto end;
-       }
-
-       /* Range start */
-       if (mapping_a->range_start._unsigned !=
-                       mapping_b->range_start._unsigned) {
-               goto end;
-       }
-
-       /* Range end */
-       if (mapping_a->range_end._unsigned !=
-                       mapping_b->range_end._unsigned) {
-               goto end;
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       int i;
-       struct bt_ctf_field_type_enumeration *enum_a;
-       struct bt_ctf_field_type_enumeration *enum_b;
-
-       enum_a = container_of(type_a,
-               struct bt_ctf_field_type_enumeration, parent);
-       enum_b = container_of(type_b,
-               struct bt_ctf_field_type_enumeration, parent);
-
-       /* Container field type */
-       ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
-       if (ret) {
-               goto end;
-       }
-
-       ret = 1;
-
-       /* Entries */
-       if (enum_a->entries->len != enum_b->entries->len) {
-               goto end;
-       }
-
-       for (i = 0; i < enum_a->entries->len; ++i) {
-               struct enumeration_mapping *mapping_a =
-                       g_ptr_array_index(enum_a->entries, i);
-               struct enumeration_mapping *mapping_b =
-                       g_ptr_array_index(enum_b->entries, i);
-
-               if (compare_enumeration_mappings(mapping_a, mapping_b)) {
-                       goto end;
-               }
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       struct bt_ctf_field_type_string *string_a;
-       struct bt_ctf_field_type_string *string_b;
-
-       string_a = container_of(type_a,
-               struct bt_ctf_field_type_string, parent);
-       string_b = container_of(type_b,
-               struct bt_ctf_field_type_string, parent);
-
-       /* Encoding */
-       if (string_a->declaration.encoding != string_b->declaration.encoding) {
-               goto end;
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int compare_structure_fields(struct structure_field *field_a,
-               struct structure_field *field_b)
-{
-       int ret = 1;
-
-       /* Label */
-       if (field_a->name != field_b->name) {
-               goto end;
-       }
-
-       /* Type */
-       ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       int i;
-       struct bt_ctf_field_type_structure *struct_a;
-       struct bt_ctf_field_type_structure *struct_b;
-
-       struct_a = container_of(type_a,
-               struct bt_ctf_field_type_structure, parent);
-       struct_b = container_of(type_b,
-               struct bt_ctf_field_type_structure, parent);
-
-       /* Alignment */
-       if (bt_ctf_field_type_get_alignment(type_a) !=
-                       bt_ctf_field_type_get_alignment(type_b)) {
-               goto end;
-       }
-
-       /* Fields */
-       if (struct_a->fields->len != struct_b->fields->len) {
-               goto end;
-       }
-
-       for (i = 0; i < struct_a->fields->len; ++i) {
-               struct structure_field *field_a =
-                       g_ptr_array_index(struct_a->fields, i);
-               struct structure_field *field_b =
-                       g_ptr_array_index(struct_b->fields, i);
-
-               ret = compare_structure_fields(field_a, field_b);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       int i;
-       struct bt_ctf_field_type_variant *variant_a;
-       struct bt_ctf_field_type_variant *variant_b;
-
-       variant_a = container_of(type_a,
-               struct bt_ctf_field_type_variant, parent);
-       variant_b = container_of(type_b,
-               struct bt_ctf_field_type_variant, parent);
-
-       /* Tag name */
-       if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
-               goto end;
-       }
-
-       /* Tag type */
-       ret = bt_ctf_field_type_compare(
-               (struct bt_ctf_field_type *) variant_a->tag,
-               (struct bt_ctf_field_type *) variant_b->tag);
-       if (ret) {
-               goto end;
-       }
-
-       ret = 1;
-
-       /* Fields */
-       if (variant_a->fields->len != variant_b->fields->len) {
-               goto end;
-       }
-
-       for (i = 0; i < variant_a->fields->len; ++i) {
-               struct structure_field *field_a =
-                       g_ptr_array_index(variant_a->fields, i);
-               struct structure_field *field_b =
-                       g_ptr_array_index(variant_b->fields, i);
-
-               ret = compare_structure_fields(field_a, field_b);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       /* Equal */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-       struct bt_ctf_field_type_array *array_a;
-       struct bt_ctf_field_type_array *array_b;
-
-       array_a = container_of(type_a,
-               struct bt_ctf_field_type_array, parent);
-       array_b = container_of(type_b,
-               struct bt_ctf_field_type_array, parent);
-
-       /* Length */
-       if (array_a->length != array_b->length) {
-               goto end;
-       }
-
-       /* Element type */
-       ret = bt_ctf_field_type_compare(array_a->element_type,
-               array_b->element_type);
-
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = -1;
-       struct bt_ctf_field_type_sequence *sequence_a;
-       struct bt_ctf_field_type_sequence *sequence_b;
-
-       sequence_a = container_of(type_a,
-               struct bt_ctf_field_type_sequence, parent);
-       sequence_b = container_of(type_b,
-               struct bt_ctf_field_type_sequence, parent);
-
-       /* Length name */
-       if (strcmp(sequence_a->length_field_name->str,
-                       sequence_b->length_field_name->str)) {
-               goto end;
-       }
-
-       /* Element type */
-       ret = bt_ctf_field_type_compare(sequence_a->element_type,
-                       sequence_b->element_type);
-
-end:
-       return ret;
-}
-
-int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
-               struct bt_ctf_field_type *type_b)
-{
-       int ret = 1;
-
-       if (type_a == type_b) {
-               /* Same reference: equal (even if both are NULL) */
-               ret = 0;
-               goto end;
-       }
-
-       if (!type_a || !type_b) {
-               ret = -1;
-               goto end;
-       }
-
-       if (type_a->declaration->id != type_b->declaration->id) {
-               /* Different type IDs */
-               goto end;
-       }
-
-       if (type_a->declaration->id == BT_CTF_TYPE_ID_UNKNOWN) {
-               /* Both have unknown type IDs */
-               goto end;
-       }
-
-       ret = type_compare_funcs[type_a->declaration->id](type_a, type_b);
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
-{
-       int field_count = -1;
-       enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
-
-       switch (type_id) {
-       case CTF_TYPE_STRUCT:
-               field_count =
-                       bt_ctf_field_type_structure_get_field_count(field_type);
-               break;
-       case CTF_TYPE_VARIANT:
-               field_count =
-                       bt_ctf_field_type_variant_get_field_count(field_type);
-               break;
-       case CTF_TYPE_ARRAY:
-       case CTF_TYPE_SEQUENCE:
-               /*
-                * Array and sequence types always contain a single member
-                * (the element type).
-                */
-               field_count = 1;
-               break;
-       default:
-               break;
-       }
-
-       return field_count;
-}
-
-BT_HIDDEN
-struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
-               struct bt_ctf_field_type *field_type, int index)
-{
-       struct bt_ctf_field_type *field = NULL;
-       enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
-
-       switch (type_id) {
-       case CTF_TYPE_STRUCT:
-               bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
-                       index);
-               break;
-       case CTF_TYPE_VARIANT:
-       {
-               int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
-                       &field, index);
-               if (ret) {
-                       field = NULL;
-                       goto end;
-               }
-               break;
-       }
-       case CTF_TYPE_ARRAY:
-               field = bt_ctf_field_type_array_get_element_type(field_type);
-               break;
-       case CTF_TYPE_SEQUENCE:
-               field = bt_ctf_field_type_sequence_get_element_type(field_type);
-               break;
-       default:
-               break;
-       }
-end:
-       return field;
-}
-
-BT_HIDDEN
-int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
-               const char *name)
-{
-       int field_index = -1;
-       enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
-
-       switch (type_id) {
-       case CTF_TYPE_STRUCT:
-               field_index = bt_ctf_field_type_structure_get_field_name_index(
-                       field_type, name);
-               break;
-       case CTF_TYPE_VARIANT:
-               field_index = bt_ctf_field_type_variant_get_field_name_index(
-                       field_type, name);
-               break;
-       default:
-               break;
-       }
-
-       return field_index;
-}
-
-struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_path *field_path = NULL;
-       struct bt_ctf_field_type_variant *variant;
-
-       if (!type || !bt_ctf_field_type_is_variant(type)) {
-               goto end;
-       }
-
-       variant = container_of(type, struct bt_ctf_field_type_variant,
-                       parent);
-       field_path = bt_get(variant->tag_field_path);
-end:
-       return field_path;
-}
-
-struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
-               struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_path *field_path = NULL;
-       struct bt_ctf_field_type_sequence *sequence;
-
-       if (!type || !bt_ctf_field_type_is_sequence(type)) {
-               goto end;
-       }
-
-       sequence = container_of(type, struct bt_ctf_field_type_sequence,
-                       parent);
-       field_path = bt_get(sequence->length_field_path);
-end:
-       return field_path;
-}
diff --git a/formats/ctf/ir/fields.c b/formats/ctf/ir/fields.c
deleted file mode 100644 (file)
index 0ad52a0..0000000
+++ /dev/null
@@ -1,2560 +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.
- */
-
-#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.h>
-#include <babeltrace/compat/fcntl.h>
-
-#define PACKET_LEN_INCREMENT   (getpagesize() * 8 * CHAR_BIT)
-
-static
-struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_enumeration_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_floating_point_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_structure_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_variant_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_array_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_sequence_create(
-               struct bt_ctf_field_type *);
-static
-struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
-
-static
-void bt_ctf_field_destroy(struct bt_object *);
-static
-void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_array_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
-static
-void bt_ctf_field_string_destroy(struct bt_ctf_field *);
-
-static
-int bt_ctf_field_generic_validate(struct bt_ctf_field *);
-static
-int bt_ctf_field_structure_validate(struct bt_ctf_field *);
-static
-int bt_ctf_field_variant_validate(struct bt_ctf_field *);
-static
-int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
-static
-int bt_ctf_field_array_validate(struct bt_ctf_field *);
-static
-int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
-
-static
-int bt_ctf_field_generic_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_structure_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_variant_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_array_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
-static
-int bt_ctf_field_string_reset(struct bt_ctf_field *);
-
-static
-int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_array_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-static
-int bt_ctf_field_string_serialize(struct bt_ctf_field *,
-               struct ctf_stream_pos *);
-
-static
-int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
-               struct bt_ctf_field *);
-static
-int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-static
-int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
-
-static
-void generic_field_freeze(struct bt_ctf_field *);
-static
-void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
-static
-void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
-static
-void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
-static
-void bt_ctf_field_array_freeze(struct bt_ctf_field *);
-static
-void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
-
-static
-bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
-static
-bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
-static
-bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
-static
-bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
-static
-bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
-static
-bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
-
-static
-int increase_packet_size(struct ctf_stream_pos *pos);
-
-static
-struct bt_ctf_field *(* const field_create_funcs[])(
-               struct bt_ctf_field_type *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_floating_point_create,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_create,
-};
-
-static
-void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_floating_point_destroy,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
-};
-
-static
-int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
-};
-
-static
-int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_reset,
-};
-
-static
-int (* const field_serialize_funcs[])(struct bt_ctf_field *,
-               struct ctf_stream_pos *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
-       [BT_CTF_TYPE_ID_FLOAT] =
-               bt_ctf_field_floating_point_serialize,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
-};
-
-static
-int (* const field_copy_funcs[])(struct bt_ctf_field *,
-               struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
-};
-
-static
-void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
-       [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
-       [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
-};
-
-static
-bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
-       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
-       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
-       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
-       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
-       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
-       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
-       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
-       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
-};
-
-struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field *field = NULL;
-       enum bt_ctf_type_id type_id;
-       int ret;
-
-       if (!type) {
-               goto error;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
-                       type_id >= BT_CTF_NR_TYPE_IDS) {
-               goto error;
-       }
-
-       /* Field class MUST be valid */
-       ret = bt_ctf_field_type_validate(type);
-
-       if (ret) {
-               /* Invalid */
-               goto error;
-       }
-
-       field = field_create_funcs[type_id](type);
-       if (!field) {
-               goto error;
-       }
-
-       /* The type's declaration can't change after this point */
-       bt_ctf_field_type_freeze(type);
-       bt_get(type);
-       bt_object_init(field, bt_ctf_field_destroy);
-       field->type = type;
-error:
-       return field;
-}
-
-void bt_ctf_field_get(struct bt_ctf_field *field)
-{
-       bt_get(field);
-}
-
-void bt_ctf_field_put(struct bt_ctf_field *field)
-{
-       bt_put(field);
-}
-
-struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_type *ret = NULL;
-
-       if (!field) {
-               goto end;
-       }
-
-       ret = field->type;
-       bt_get(ret);
-end:
-       return ret;
-}
-
-enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
-{
-       enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
-
-       if (!field) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_get_type_id(field->type);
-end:
-       return ret;
-}
-
-int bt_ctf_field_is_integer(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
-}
-
-int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
-}
-
-int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
-}
-
-int bt_ctf_field_is_string(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
-}
-
-int bt_ctf_field_is_structure(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
-}
-
-int bt_ctf_field_is_array(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
-}
-
-int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
-}
-
-int bt_ctf_field_is_variant(struct bt_ctf_field *field)
-{
-       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
-}
-
-struct bt_ctf_field *bt_ctf_field_sequence_get_length(
-               struct bt_ctf_field *field)
-{
-       struct bt_ctf_field *ret = NULL;
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field) {
-               goto end;
-       }
-
-       if (bt_ctf_field_type_get_type_id(field->type) !=
-               BT_CTF_TYPE_ID_SEQUENCE) {
-               goto end;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       ret = sequence->length;
-       bt_get(ret);
-end:
-       return ret;
-}
-
-int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
-               struct bt_ctf_field *length_field)
-{
-       int ret = 0;
-       struct bt_ctf_field_type_integer *length_type;
-       struct bt_ctf_field_integer *length;
-       struct bt_ctf_field_sequence *sequence;
-       uint64_t sequence_length;
-
-       if (!field || !length_field || field->frozen) {
-               ret = -1;
-               goto end;
-       }
-       if (bt_ctf_field_type_get_type_id(length_field->type) !=
-               BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       length_type = container_of(length_field->type,
-               struct bt_ctf_field_type_integer, parent);
-       /* The length field must be unsigned */
-       if (length_type->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-       length = container_of(length_field, struct bt_ctf_field_integer,
-               parent);
-       sequence_length = length->definition.value._unsigned;
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       if (sequence->elements) {
-               g_ptr_array_free(sequence->elements, TRUE);
-               bt_put(sequence->length);
-       }
-
-       sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
-       if (!sequence->elements) {
-               ret = -1;
-               goto end;
-       }
-
-       g_ptr_array_set_free_func(sequence->elements,
-               (GDestroyNotify) bt_put);
-       g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
-       bt_get(length_field);
-       sequence->length = length_field;
-end:
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_field_structure_get_field(
-               struct bt_ctf_field *field, const char *name)
-{
-       struct bt_ctf_field *new_field = NULL;
-       GQuark field_quark;
-       struct bt_ctf_field_structure *structure;
-       struct bt_ctf_field_type *field_type = NULL;
-       size_t index;
-
-       if (!field || !name ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRUCT) {
-               goto error;
-       }
-
-       field_quark = g_quark_from_string(name);
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       field_type =
-               bt_ctf_field_type_structure_get_field_type_by_name(field->type,
-               name);
-       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
-               GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
-               goto error;
-       }
-
-       if (structure->fields->pdata[index]) {
-               new_field = structure->fields->pdata[index];
-               goto end;
-       }
-
-       /* We don't want to modify this field if it's frozen */
-       if (field->frozen) {
-               goto end;
-       }
-
-       new_field = bt_ctf_field_create(field_type);
-       if (!new_field) {
-               goto error;
-       }
-
-       structure->fields->pdata[index] = new_field;
-end:
-       bt_get(new_field);
-error:
-       if (field_type) {
-               bt_put(field_type);
-       }
-       return new_field;
-}
-
-struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
-               struct bt_ctf_field *field, int index)
-{
-       int ret;
-       const char *field_name;
-       struct bt_ctf_field_structure *structure;
-       struct bt_ctf_field_type *structure_type;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_field *ret_field = NULL;
-
-       if (!field ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-               BT_CTF_TYPE_ID_STRUCT) {
-               goto end;
-       }
-
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       if (index >= structure->fields->len) {
-               goto error;
-       }
-
-       ret_field = structure->fields->pdata[index];
-       if (ret_field) {
-               goto end;
-       }
-
-       /* We don't want to modify this field if it's frozen */
-       if (field->frozen) {
-               goto end;
-       }
-
-       /* Field has not been instanciated yet, create it */
-       structure_type = bt_ctf_field_get_type(field);
-       if (!structure_type) {
-               goto error;
-       }
-
-       ret = bt_ctf_field_type_structure_get_field(structure_type,
-               &field_name, &field_type, index);
-       bt_put(structure_type);
-       if (ret) {
-               goto error;
-       }
-
-       ret_field = bt_ctf_field_create(field_type);
-       if (!ret_field) {
-               goto error;
-       }
-
-       structure->fields->pdata[index] = ret_field;
-end:
-       bt_get(ret_field);
-error:
-       bt_put(field_type);
-       return ret_field;
-}
-
-BT_HIDDEN
-int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
-               const char *name, struct bt_ctf_field *value)
-{
-       int ret = 0;
-       GQuark field_quark;
-       struct bt_ctf_field_structure *structure;
-       struct bt_ctf_field_type *expected_field_type = NULL;
-       size_t index;
-
-       if (!field || !name || !value || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       field_quark = g_quark_from_string(name);
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       expected_field_type =
-               bt_ctf_field_type_structure_get_field_type_by_name(field->type,
-               name);
-
-       if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
-               GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
-               goto end;
-       }
-
-       if (structure->fields->pdata[index]) {
-               bt_put(structure->fields->pdata[index]);
-       }
-
-       structure->fields->pdata[index] = value;
-       bt_get(value);
-end:
-       if (expected_field_type) {
-               bt_put(expected_field_type);
-       }
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
-               uint64_t index)
-{
-       struct bt_ctf_field *new_field = NULL;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_field_array *array;
-
-       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
-               BT_CTF_TYPE_ID_ARRAY) {
-               goto end;
-       }
-
-       array = container_of(field, struct bt_ctf_field_array, parent);
-       if (index >= array->elements->len) {
-               goto end;
-       }
-
-       field_type = bt_ctf_field_type_array_get_element_type(field->type);
-       if (array->elements->pdata[(size_t)index]) {
-               new_field = array->elements->pdata[(size_t)index];
-               goto end;
-       }
-
-       /* We don't want to modify this field if it's frozen */
-       if (field->frozen) {
-               goto end;
-       }
-
-       new_field = bt_ctf_field_create(field_type);
-       array->elements->pdata[(size_t)index] = new_field;
-end:
-       if (field_type) {
-               bt_put(field_type);
-       }
-       if (new_field) {
-               bt_get(new_field);
-       }
-       return new_field;
-}
-
-struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
-               uint64_t index)
-{
-       struct bt_ctf_field *new_field = NULL;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
-               BT_CTF_TYPE_ID_SEQUENCE) {
-               goto end;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       if (!sequence->elements || sequence->elements->len <= index) {
-               goto end;
-       }
-
-       field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
-       if (sequence->elements->pdata[(size_t) index]) {
-               new_field = sequence->elements->pdata[(size_t) index];
-               goto end;
-       }
-
-       /* We don't want to modify this field if it's frozen */
-       if (field->frozen) {
-               goto end;
-       }
-
-       new_field = bt_ctf_field_create(field_type);
-       sequence->elements->pdata[(size_t) index] = new_field;
-end:
-       if (field_type) {
-               bt_put(field_type);
-       }
-       if (new_field) {
-               bt_get(new_field);
-       }
-       return new_field;
-}
-
-struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
-               struct bt_ctf_field *tag_field)
-{
-       struct bt_ctf_field *new_field = NULL;
-       struct bt_ctf_field_variant *variant;
-       struct bt_ctf_field_type_variant *variant_type;
-       struct bt_ctf_field_type *field_type;
-       struct bt_ctf_field *tag_enum = NULL;
-       struct bt_ctf_field_integer *tag_enum_integer;
-       int64_t tag_enum_value;
-
-       if (!field || !tag_field ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_VARIANT ||
-               bt_ctf_field_type_get_type_id(tag_field->type) !=
-                       BT_CTF_TYPE_ID_ENUM) {
-               goto end;
-       }
-
-       variant = container_of(field, struct bt_ctf_field_variant, parent);
-       variant_type = container_of(field->type,
-               struct bt_ctf_field_type_variant, parent);
-       tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
-       if (!tag_enum) {
-               goto end;
-       }
-
-       tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
-               parent);
-
-       if (bt_ctf_field_validate(tag_field) < 0) {
-               goto end;
-       }
-
-       tag_enum_value = tag_enum_integer->definition.value._signed;
-
-       /*
-        * If the variant currently has a tag and a payload, and if the
-        * requested tag value is the same as the current one, return
-        * the current payload instead of creating a fresh one.
-        */
-       if (variant->tag && variant->payload) {
-               struct bt_ctf_field *cur_tag_container = NULL;
-               struct bt_ctf_field_integer *cur_tag_enum_integer;
-               int64_t cur_tag_value;
-
-               cur_tag_container =
-                       bt_ctf_field_enumeration_get_container(variant->tag);
-               assert(cur_tag_container);
-               cur_tag_enum_integer = container_of(cur_tag_container,
-                       struct bt_ctf_field_integer, parent);
-               bt_put(cur_tag_container);
-               cur_tag_value = cur_tag_enum_integer->definition.value._signed;
-
-               if (cur_tag_value == tag_enum_value) {
-                       new_field = variant->payload;
-                       bt_get(new_field);
-                       goto end;
-               }
-       }
-
-       /* We don't want to modify this field if it's frozen */
-       if (field->frozen) {
-               goto end;
-       }
-
-       field_type = bt_ctf_field_type_variant_get_field_type_signed(
-               variant_type, tag_enum_value);
-       if (!field_type) {
-               goto end;
-       }
-
-       new_field = bt_ctf_field_create(field_type);
-       if (!new_field) {
-               goto end;
-       }
-
-       bt_put(variant->tag);
-       bt_put(variant->payload);
-       bt_get(new_field);
-       bt_get(tag_field);
-       variant->tag = tag_field;
-       variant->payload = new_field;
-end:
-       bt_put(tag_enum);
-       return new_field;
-}
-
-struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
-               struct bt_ctf_field *variant_field)
-{
-       struct bt_ctf_field *current_field = NULL;
-       struct bt_ctf_field_variant *variant;
-
-       if (!variant_field ||
-               bt_ctf_field_type_get_type_id(variant_field->type) !=
-                       BT_CTF_TYPE_ID_VARIANT) {
-               goto end;
-       }
-
-       variant = container_of(variant_field, struct bt_ctf_field_variant,
-               parent);
-
-       if (variant->payload) {
-               current_field = variant->payload;
-               bt_get(current_field);
-               goto end;
-       }
-
-end:
-       return current_field;
-}
-
-struct bt_ctf_field *bt_ctf_field_variant_get_tag(
-               struct bt_ctf_field *variant_field)
-{
-       struct bt_ctf_field *tag = NULL;
-       struct bt_ctf_field_variant *variant;
-
-       if (!variant_field ||
-                       bt_ctf_field_type_get_type_id(variant_field->type) !=
-                       BT_CTF_TYPE_ID_VARIANT) {
-               goto end;
-       }
-
-       variant = container_of(variant_field, struct bt_ctf_field_variant,
-                       parent);
-       if (variant->tag) {
-               tag = bt_get(variant->tag);
-       }
-end:
-       return tag;
-}
-
-struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
-       struct bt_ctf_field *field)
-{
-       struct bt_ctf_field *container = NULL;
-       struct bt_ctf_field_enumeration *enumeration;
-
-       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
-               BT_CTF_TYPE_ID_ENUM) {
-               goto end;
-       }
-
-       enumeration = container_of(field, struct bt_ctf_field_enumeration,
-               parent);
-       if (!enumeration->payload) {
-               /* We don't want to modify this field if it's frozen */
-               if (field->frozen) {
-                       goto end;
-               }
-
-               struct bt_ctf_field_type_enumeration *enumeration_type =
-                       container_of(field->type,
-                       struct bt_ctf_field_type_enumeration, parent);
-               enumeration->payload =
-                       bt_ctf_field_create(enumeration_type->container);
-       }
-
-       container = enumeration->payload;
-       bt_get(container);
-end:
-       return container;
-}
-
-struct bt_ctf_field_type_enumeration_mapping_iterator *
-bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
-{
-       int ret;
-       struct bt_ctf_field *container = NULL;
-       struct bt_ctf_field_type *container_type = NULL;
-       struct bt_ctf_field_type_integer *integer_type = NULL;
-       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
-
-       container = bt_ctf_field_enumeration_get_container(field);
-       if (!container) {
-               goto end;
-       }
-
-       container_type = bt_ctf_field_get_type(container);
-       if (!container_type) {
-               goto error_put_container;
-       }
-
-       integer_type = container_of(container_type,
-               struct bt_ctf_field_type_integer, parent);
-
-       if (!integer_type->declaration.signedness) {
-               uint64_t value;
-
-               ret = bt_ctf_field_unsigned_integer_get_value(container,
-                     &value);
-               if (ret) {
-                       goto error_put_container_type;
-               }
-               iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
-                               field->type, value);
-       } else {
-               int64_t value;
-
-               ret = bt_ctf_field_signed_integer_get_value(container,
-                     &value);
-               if (ret) {
-                       goto error_put_container_type;
-               }
-               iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
-                               field->type, value);
-       }
-
-error_put_container_type:
-       bt_put(container_type);
-error_put_container:
-       bt_put(container);
-end:
-       return iter;
-}
-
-int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
-               int64_t *value)
-{
-       int ret = 0;
-       struct bt_ctf_field_integer *integer;
-       struct bt_ctf_field_type_integer *integer_type;
-
-       if (!field || !value || !field->payload_set ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer_type = container_of(field->type,
-               struct bt_ctf_field_type_integer, parent);
-       if (!integer_type->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(field,
-               struct bt_ctf_field_integer, parent);
-       *value = integer->definition.value._signed;
-end:
-       return ret;
-}
-
-int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
-               int64_t value)
-{
-       int ret = 0;
-       struct bt_ctf_field_integer *integer;
-       struct bt_ctf_field_type_integer *integer_type;
-       unsigned int size;
-       int64_t min_value, max_value;
-
-       if (!field || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(field, struct bt_ctf_field_integer, parent);
-       integer_type = container_of(field->type,
-               struct bt_ctf_field_type_integer, parent);
-       if (!integer_type->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-       size = integer_type->declaration.len;
-       min_value = -(1ULL << (size - 1));
-       max_value = (1ULL << (size - 1)) - 1;
-       if (value < min_value || value > max_value) {
-               ret = -1;
-               goto end;
-       }
-
-       integer->definition.value._signed = value;
-       integer->parent.payload_set = 1;
-end:
-       return ret;
-}
-
-int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
-               uint64_t *value)
-{
-       int ret = 0;
-       struct bt_ctf_field_integer *integer;
-       struct bt_ctf_field_type_integer *integer_type;
-
-       if (!field || !value || !field->payload_set ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer_type = container_of(field->type,
-               struct bt_ctf_field_type_integer, parent);
-       if (integer_type->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(field,
-               struct bt_ctf_field_integer, parent);
-       *value = integer->definition.value._unsigned;
-end:
-       return ret;
-}
-
-int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
-               uint64_t value)
-{
-       int ret = 0;
-       struct bt_ctf_field_integer *integer;
-       struct bt_ctf_field_type_integer *integer_type;
-       unsigned int size;
-       uint64_t max_value;
-
-       if (!field || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       integer = container_of(field, struct bt_ctf_field_integer, parent);
-       integer_type = container_of(field->type,
-               struct bt_ctf_field_type_integer, parent);
-       if (integer_type->declaration.signedness) {
-               ret = -1;
-               goto end;
-       }
-
-       size = integer_type->declaration.len;
-       max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
-       if (value > max_value) {
-               ret = -1;
-               goto end;
-       }
-
-       integer->definition.value._unsigned = value;
-       integer->parent.payload_set = 1;
-end:
-       return ret;
-}
-
-int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
-               double *value)
-{
-       int ret = 0;
-       struct bt_ctf_field_floating_point *floating_point;
-
-       if (!field || !value || !field->payload_set ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_FLOAT) {
-               ret = -1;
-               goto end;
-       }
-
-       floating_point = container_of(field,
-               struct bt_ctf_field_floating_point, parent);
-       *value = floating_point->definition.value;
-end:
-       return ret;
-}
-
-int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
-               double value)
-{
-       int ret = 0;
-       struct bt_ctf_field_floating_point *floating_point;
-
-       if (!field || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_FLOAT) {
-               ret = -1;
-               goto end;
-       }
-       floating_point = container_of(field, struct bt_ctf_field_floating_point,
-               parent);
-       floating_point->definition.value = value;
-       floating_point->parent.payload_set = 1;
-end:
-       return ret;
-}
-
-const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
-{
-       const char *ret = NULL;
-       struct bt_ctf_field_string *string;
-
-       if (!field || !field->payload_set ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRING) {
-               goto end;
-       }
-
-       string = container_of(field,
-               struct bt_ctf_field_string, parent);
-       ret = string->payload->str;
-end:
-       return ret;
-}
-
-int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
-               const char *value)
-{
-       int ret = 0;
-       struct bt_ctf_field_string *string;
-
-       if (!field || !value || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRING) {
-               ret = -1;
-               goto end;
-       }
-
-       string = container_of(field, struct bt_ctf_field_string, parent);
-       if (string->payload) {
-               g_string_assign(string->payload, value);
-       } else {
-               string->payload = g_string_new(value);
-       }
-
-       string->parent.payload_set = 1;
-end:
-       return ret;
-}
-
-int bt_ctf_field_string_append(struct bt_ctf_field *field,
-               const char *value)
-{
-       int ret = 0;
-       struct bt_ctf_field_string *string_field;
-
-       if (!field || !value || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRING) {
-               ret = -1;
-               goto end;
-       }
-
-       string_field = container_of(field, struct bt_ctf_field_string, parent);
-
-       if (string_field->payload) {
-               g_string_append(string_field->payload, value);
-       } else {
-               string_field->payload = g_string_new(value);
-       }
-
-       string_field->parent.payload_set = 1;
-
-end:
-       return ret;
-}
-
-int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
-               const char *value, unsigned int length)
-{
-       int i;
-       int ret = 0;
-       unsigned int effective_length = length;
-       struct bt_ctf_field_string *string_field;
-
-       if (!field || !value || field->frozen ||
-               bt_ctf_field_type_get_type_id(field->type) !=
-                       BT_CTF_TYPE_ID_STRING) {
-               ret = -1;
-               goto end;
-       }
-
-       string_field = container_of(field, struct bt_ctf_field_string, parent);
-
-       /* make sure no null bytes are appended */
-       for (i = 0; i < length; ++i) {
-               if (value[i] == '\0') {
-                       effective_length = i;
-                       break;
-               }
-       }
-
-       if (string_field->payload) {
-               g_string_append_len(string_field->payload, value,
-                       effective_length);
-       } else {
-               string_field->payload = g_string_new_len(value,
-                       effective_length);
-       }
-
-       string_field->parent.payload_set = 1;
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_validate(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       enum bt_ctf_type_id type_id;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(field->type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = field_validate_funcs[type_id](field);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_reset(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       enum bt_ctf_type_id type_id;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(field->type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = field_reset_funcs[type_id](field);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_field_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       int ret = 0;
-       enum bt_ctf_type_id type_id;
-
-       if (!field || !pos) {
-               ret = -1;
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(field->type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = field_serialize_funcs[type_id](field, pos);
-end:
-       return ret;
-}
-
-
-BT_HIDDEN
-bool bt_ctf_field_is_set(struct bt_ctf_field *field)
-{
-       bool is_set = false;
-       enum bt_ctf_type_id type_id;
-
-       if (!field) {
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(field->type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
-               goto end;
-       }
-
-       is_set = field_is_set_funcs[type_id](field);
-end:
-       return is_set;
-}
-
-struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
-{
-       int ret;
-       struct bt_ctf_field *copy = NULL;
-       enum bt_ctf_type_id type_id;
-
-       if (!field) {
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(field->type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
-               goto end;
-       }
-
-       copy = bt_ctf_field_create(field->type);
-       if (!copy) {
-               goto end;
-       }
-
-       copy->payload_set = field->payload_set;
-       ret = field_copy_funcs[type_id](field, copy);
-       if (ret) {
-               bt_put(copy);
-               copy = NULL;
-       }
-end:
-       return copy;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_integer *integer_type = container_of(type,
-               struct bt_ctf_field_type_integer, parent);
-       struct bt_ctf_field_integer *integer = g_new0(
-               struct bt_ctf_field_integer, 1);
-
-       if (integer) {
-               integer->definition.declaration = &integer_type->declaration;
-       }
-
-       return integer ? &integer->parent : NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_enumeration_create(
-       struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_enumeration *enumeration = g_new0(
-               struct bt_ctf_field_enumeration, 1);
-
-       return enumeration ? &enumeration->parent : NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_floating_point_create(
-       struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_floating_point *floating_point;
-       struct bt_ctf_field_type_floating_point *floating_point_type;
-
-       floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
-       if (!floating_point) {
-               goto end;
-       }
-
-       floating_point_type = container_of(type,
-               struct bt_ctf_field_type_floating_point, parent);
-       floating_point->definition.declaration = container_of(
-               type->declaration, struct declaration_float, p);
-
-
-       floating_point->definition.sign = &floating_point->sign;
-       floating_point->sign.declaration = &floating_point_type->sign;
-       floating_point->definition.sign->p.declaration =
-               &floating_point_type->sign.p;
-
-       floating_point->definition.mantissa = &floating_point->mantissa;
-       floating_point->mantissa.declaration = &floating_point_type->mantissa;
-       floating_point->definition.mantissa->p.declaration =
-               &floating_point_type->mantissa.p;
-
-       floating_point->definition.exp = &floating_point->exp;
-       floating_point->exp.declaration = &floating_point_type->exp;
-       floating_point->definition.exp->p.declaration =
-               &floating_point_type->exp.p;
-
-end:
-       return floating_point ? &floating_point->parent : NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_structure_create(
-       struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_type_structure *structure_type = container_of(type,
-               struct bt_ctf_field_type_structure, parent);
-       struct bt_ctf_field_structure *structure = g_new0(
-               struct bt_ctf_field_structure, 1);
-       struct bt_ctf_field *field = NULL;
-
-       if (!structure) {
-               goto end;
-       }
-
-       structure->field_name_to_index = structure_type->field_name_to_index;
-       structure->fields = g_ptr_array_new_with_free_func(
-               (GDestroyNotify)bt_ctf_field_put);
-       g_ptr_array_set_size(structure->fields,
-               g_hash_table_size(structure->field_name_to_index));
-       field = &structure->parent;
-end:
-       return field;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_variant *variant = g_new0(
-               struct bt_ctf_field_variant, 1);
-       return variant ? &variant->parent : NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
-       struct bt_ctf_field_type_array *array_type;
-       unsigned int array_length;
-
-       if (!array || !type) {
-               goto error;
-       }
-
-       array_type = container_of(type, struct bt_ctf_field_type_array, parent);
-       array_length = array_type->length;
-       array->elements = g_ptr_array_sized_new(array_length);
-       if (!array->elements) {
-               goto error;
-       }
-
-       g_ptr_array_set_free_func(array->elements,
-               (GDestroyNotify)bt_ctf_field_put);
-       g_ptr_array_set_size(array->elements, array_length);
-       return &array->parent;
-error:
-       g_free(array);
-       return NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_sequence_create(
-       struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_sequence *sequence = g_new0(
-               struct bt_ctf_field_sequence, 1);
-       return sequence ? &sequence->parent : NULL;
-}
-
-static
-struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
-{
-       struct bt_ctf_field_string *string = g_new0(
-               struct bt_ctf_field_string, 1);
-       return string ? &string->parent : NULL;
-}
-
-static
-void bt_ctf_field_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_field *field;
-       struct bt_ctf_field_type *type;
-       enum bt_ctf_type_id type_id;
-
-       field = container_of(obj, struct bt_ctf_field, base);
-       type = field->type;
-       type_id = bt_ctf_field_type_get_type_id(type);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
-               type_id >= BT_CTF_NR_TYPE_IDS) {
-               return;
-       }
-
-       field_destroy_funcs[type_id](field);
-       bt_put(type);
-}
-
-static
-void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_integer *integer;
-
-       if (!field) {
-               return;
-       }
-
-       integer = container_of(field, struct bt_ctf_field_integer, parent);
-       g_free(integer);
-}
-
-static
-void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_enumeration *enumeration;
-
-       if (!field) {
-               return;
-       }
-
-       enumeration = container_of(field, struct bt_ctf_field_enumeration,
-               parent);
-       bt_put(enumeration->payload);
-       g_free(enumeration);
-}
-
-static
-void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_floating_point *floating_point;
-
-       if (!field) {
-               return;
-       }
-
-       floating_point = container_of(field, struct bt_ctf_field_floating_point,
-               parent);
-       g_free(floating_point);
-}
-
-static
-void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_structure *structure;
-
-       if (!field) {
-               return;
-       }
-
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       g_ptr_array_free(structure->fields, TRUE);
-       g_free(structure);
-}
-
-static
-void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_variant *variant;
-
-       if (!field) {
-               return;
-       }
-
-       variant = container_of(field, struct bt_ctf_field_variant, parent);
-       bt_put(variant->tag);
-       bt_put(variant->payload);
-       g_free(variant);
-}
-
-static
-void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_array *array;
-
-       if (!field) {
-               return;
-       }
-
-       array = container_of(field, struct bt_ctf_field_array, parent);
-       g_ptr_array_free(array->elements, TRUE);
-       g_free(array);
-}
-
-static
-void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field) {
-               return;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       if (sequence->elements) {
-               g_ptr_array_free(sequence->elements, TRUE);
-       }
-       bt_put(sequence->length);
-       g_free(sequence);
-}
-
-static
-void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_string *string;
-       if (!field) {
-               return;
-       }
-
-       string = container_of(field, struct bt_ctf_field_string, parent);
-       if (string->payload) {
-               g_string_free(string->payload, TRUE);
-       }
-       g_free(string);
-}
-
-static
-int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
-{
-       return (field && field->payload_set) ? 0 : -1;
-}
-
-static
-int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
-{
-       int ret;
-       struct bt_ctf_field_enumeration *enumeration;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       enumeration = container_of(field, struct bt_ctf_field_enumeration,
-               parent);
-       if (!enumeration->payload) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_validate(enumeration->payload);
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_structure *structure;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       for (i = 0; i < structure->fields->len; i++) {
-               ret = bt_ctf_field_validate(structure->fields->pdata[i]);
-               if (ret) {
-                       const char *name;
-                       struct bt_ctf_field_type *field_type =
-                                       bt_ctf_field_get_type(field);
-
-                       (void) bt_ctf_field_type_structure_get_field(field_type,
-                                       &name, NULL, i);
-                       fprintf(stderr, "Field %s failed validation\n",
-                                       name ? name : "NULL");
-                       bt_put(field_type);
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_field_variant *variant;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(field, struct bt_ctf_field_variant, parent);
-       ret = bt_ctf_field_validate(variant->payload);
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_array_validate(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_array *array;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       array = container_of(field, struct bt_ctf_field_array, parent);
-       for (i = 0; i < array->elements->len; i++) {
-               ret = bt_ctf_field_validate(array->elements->pdata[i]);
-               if (ret) {
-                       fprintf(stderr, "Failed to validate array field #%zu\n", i);
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       for (i = 0; i < sequence->elements->len; i++) {
-               ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
-               if (ret) {
-                       fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
-{
-       int ret = 0;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       field->payload_set = 0;
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_field_enumeration *enumeration;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       enumeration = container_of(field, struct bt_ctf_field_enumeration,
-               parent);
-       if (!enumeration->payload) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_reset(enumeration->payload);
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_structure *structure;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       for (i = 0; i < structure->fields->len; i++) {
-               struct bt_ctf_field *member = structure->fields->pdata[i];
-
-               if (!member) {
-                       /*
-                        * Structure members are lazily initialized; skip if
-                        * this member has not been allocated yet.
-                        */
-                       continue;
-               }
-
-               ret = bt_ctf_field_reset(member);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_field_variant *variant;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       variant = container_of(field, struct bt_ctf_field_variant, parent);
-       if (variant->payload) {
-               ret = bt_ctf_field_reset(variant->payload);
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_array_reset(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_array *array;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       array = container_of(field, struct bt_ctf_field_array, parent);
-       for (i = 0; i < array->elements->len; i++) {
-               struct bt_ctf_field *member = array->elements->pdata[i];
-
-               if (!member) {
-                       /*
-                        * Array elements are lazily initialized; skip if
-                        * this member has not been allocated yet.
-                        */
-                       continue;
-               }
-
-               ret = bt_ctf_field_reset(member);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       for (i = 0; i < sequence->elements->len; i++) {
-               struct bt_ctf_field *member = sequence->elements->pdata[i];
-
-               if (!member) {
-                       /*
-                        * Sequence elements are lazily initialized; skip if
-                        * this member has not been allocated yet.
-                        */
-                       continue;
-               }
-
-               ret = bt_ctf_field_reset(member);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_string_reset(struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_field_string *string;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_generic_reset(field);
-       if (ret) {
-               goto end;
-       }
-
-       string = container_of(field, struct bt_ctf_field_string, parent);
-       if (string->payload) {
-               g_string_truncate(string->payload, 0);
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       int ret = 0;
-       struct bt_ctf_field_integer *integer = container_of(field,
-               struct bt_ctf_field_integer, parent);
-
-       if (!bt_ctf_field_generic_is_set(field)) {
-               ret = -1;
-               goto end;
-       }
-retry:
-       ret = ctf_integer_write(&pos->parent, &integer->definition.p);
-       if (ret == -EFAULT) {
-               /*
-                * The field is too large to fit in the current packet's
-                * remaining space. Bump the packet size and retry.
-                */
-               ret = increase_packet_size(pos);
-               if (ret) {
-                       goto end;
-               }
-               goto retry;
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       struct bt_ctf_field_enumeration *enumeration = container_of(
-               field, struct bt_ctf_field_enumeration, parent);
-
-       return bt_ctf_field_serialize(enumeration->payload, pos);
-}
-
-static
-int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       int ret = 0;
-       struct bt_ctf_field_floating_point *floating_point = container_of(field,
-               struct bt_ctf_field_floating_point, parent);
-
-       if (!bt_ctf_field_generic_is_set(field)) {
-               ret = -1;
-               goto end;
-       }
-retry:
-       ret = ctf_float_write(&pos->parent, &floating_point->definition.p);
-       if (ret == -EFAULT) {
-               /*
-                * The field is too large to fit in the current packet's
-                * remaining space. Bump the packet size and retry.
-                */
-               ret = increase_packet_size(pos);
-               if (ret) {
-                       goto end;
-               }
-               goto retry;
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_structure *structure = container_of(
-               field, struct bt_ctf_field_structure, parent);
-
-       while (!ctf_pos_access_ok(pos,
-               offset_align(pos->offset,
-                       field->type->declaration->alignment))) {
-               ret = increase_packet_size(pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       if (!ctf_align_pos(pos, field->type->declaration->alignment)) {
-               ret = -1;
-               goto end;
-       }
-
-       for (i = 0; i < structure->fields->len; i++) {
-               struct bt_ctf_field *member = g_ptr_array_index(
-                       structure->fields, i);
-
-               ret = bt_ctf_field_serialize(member, pos);
-               if (ret) {
-                       const char *name;
-                       struct bt_ctf_field_type *structure_type =
-                                       bt_ctf_field_get_type(field);
-
-                       (void) bt_ctf_field_type_structure_get_field(
-                                       structure_type, &name, NULL, i);
-                       fprintf(stderr, "Field %s failed to serialize\n",
-                                       name ? name : "NULL");
-                       bt_put(structure_type);
-                       break;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       struct bt_ctf_field_variant *variant = container_of(
-               field, struct bt_ctf_field_variant, parent);
-
-       return bt_ctf_field_serialize(variant->payload, pos);
-}
-
-static
-int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_array *array = container_of(
-               field, struct bt_ctf_field_array, parent);
-
-       for (i = 0; i < array->elements->len; i++) {
-               ret = bt_ctf_field_serialize(
-                       g_ptr_array_index(array->elements, i), pos);
-               if (ret) {
-                       fprintf(stderr, "Failed to serialize array element #%zu\n", i);
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_sequence *sequence = container_of(
-               field, struct bt_ctf_field_sequence, parent);
-
-       for (i = 0; i < sequence->elements->len; i++) {
-               ret = bt_ctf_field_serialize(
-                       g_ptr_array_index(sequence->elements, i), pos);
-               if (ret) {
-                       fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos)
-{
-       size_t i;
-       int ret = 0;
-       struct bt_ctf_field_string *string = container_of(field,
-               struct bt_ctf_field_string, parent);
-       struct bt_ctf_field_type *character_type =
-               get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
-       struct bt_ctf_field *character = bt_ctf_field_create(character_type);
-
-       for (i = 0; i < string->payload->len + 1; i++) {
-               ret = bt_ctf_field_unsigned_integer_set_value(character,
-                       (uint64_t) string->payload->str[i]);
-               if (ret) {
-                       goto end;
-               }
-
-               ret = bt_ctf_field_integer_serialize(character, pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       bt_put(character);
-       bt_put(character_type);
-       return ret;
-}
-
-static
-int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       struct bt_ctf_field_integer *integer_src, *integer_dst;
-
-       integer_src = container_of(src, struct bt_ctf_field_integer, parent);
-       integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
-
-       memcpy(&integer_dst->definition, &integer_src->definition,
-               sizeof(struct definition_integer));
-       return 0;
-}
-
-static
-int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0;
-       struct bt_ctf_field_enumeration *enum_src, *enum_dst;
-
-       enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
-       enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
-
-       if (enum_src->payload) {
-               enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
-               if (!enum_dst->payload) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_floating_point_copy(
-               struct bt_ctf_field *src, struct bt_ctf_field *dst)
-{
-       struct bt_ctf_field_floating_point *float_src, *float_dst;
-
-       float_src = container_of(src, struct bt_ctf_field_floating_point,
-               parent);
-       float_dst = container_of(dst, struct bt_ctf_field_floating_point,
-               parent);
-
-       memcpy(&float_dst->definition, &float_src->definition,
-               sizeof(struct definition_float));
-       memcpy(&float_dst->sign, &float_src->sign,
-               sizeof(struct definition_integer));
-       memcpy(&float_dst->mantissa, &float_src->mantissa,
-               sizeof(struct definition_integer));
-       memcpy(&float_dst->exp, &float_src->exp,
-               sizeof(struct definition_integer));
-       return 0;
-}
-
-static
-int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0, i;
-       struct bt_ctf_field_structure *struct_src, *struct_dst;
-
-       struct_src = container_of(src, struct bt_ctf_field_structure, parent);
-       struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
-
-       /* This field_name_to_index HT is owned by the structure field type */
-       struct_dst->field_name_to_index = struct_src->field_name_to_index;
-       g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
-
-       for (i = 0; i < struct_src->fields->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(struct_src->fields, i);
-               struct bt_ctf_field *field_copy = NULL;
-
-               if (field) {
-                       field_copy = bt_ctf_field_copy(field);
-
-                       if (!field_copy) {
-                               ret = -1;
-                               goto end;
-                       }
-               }
-
-               g_ptr_array_index(struct_dst->fields, i) = field_copy;
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0;
-       struct bt_ctf_field_variant *variant_src, *variant_dst;
-
-       variant_src = container_of(src, struct bt_ctf_field_variant, parent);
-       variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
-
-       if (variant_src->tag) {
-               variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
-               if (!variant_dst->tag) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-       if (variant_src->payload) {
-               variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
-               if (!variant_dst->payload) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_array_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0, i;
-       struct bt_ctf_field_array *array_src, *array_dst;
-
-       array_src = container_of(src, struct bt_ctf_field_array, parent);
-       array_dst = container_of(dst, struct bt_ctf_field_array, parent);
-
-       g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
-       for (i = 0; i < array_src->elements->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(array_src->elements, i);
-               struct bt_ctf_field *field_copy = NULL;
-
-               if (field) {
-                       field_copy = bt_ctf_field_copy(field);
-
-                       if (!field_copy) {
-                               ret = -1;
-                               goto end;
-                       }
-               }
-
-               g_ptr_array_index(array_dst->elements, i) = field_copy;
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0, i;
-       struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
-       struct bt_ctf_field *src_length;
-       struct bt_ctf_field *dst_length;
-
-       sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
-       sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
-
-       src_length = bt_ctf_field_sequence_get_length(src);
-
-       if (!src_length) {
-               /* no length set yet: keep destination sequence empty */
-               goto end;
-       }
-
-       /* copy source length */
-       dst_length = bt_ctf_field_copy(src_length);
-       bt_put(src_length);
-
-       if (!dst_length) {
-               ret = -1;
-               goto end;
-       }
-
-       /* this will initialize the destination sequence's internal array */
-       ret = bt_ctf_field_sequence_set_length(dst, dst_length);
-       bt_put(dst_length);
-
-       if (ret) {
-               goto end;
-       }
-
-       assert(sequence_dst->elements->len == sequence_src->elements->len);
-
-       for (i = 0; i < sequence_src->elements->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(sequence_src->elements, i);
-               struct bt_ctf_field *field_copy = NULL;
-
-               if (field) {
-                       field_copy = bt_ctf_field_copy(field);
-
-                       if (!field_copy) {
-                               ret = -1;
-                               goto end;
-                       }
-               }
-
-               g_ptr_array_index(sequence_dst->elements, i) = field_copy;
-       }
-end:
-       return ret;
-}
-
-static
-int bt_ctf_field_string_copy(struct bt_ctf_field *src,
-               struct bt_ctf_field *dst)
-{
-       int ret = 0;
-       struct bt_ctf_field_string *string_src, *string_dst;
-
-       string_src = container_of(src, struct bt_ctf_field_string, parent);
-       string_dst = container_of(dst, struct bt_ctf_field_string, parent);
-
-       if (string_src->payload) {
-               string_dst->payload = g_string_new(string_src->payload->str);
-               if (!string_dst->payload) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-static
-int increase_packet_size(struct ctf_stream_pos *pos)
-{
-       int ret;
-
-       assert(pos);
-       ret = munmap_align(pos->base_mma);
-       if (ret) {
-               goto end;
-       }
-
-       pos->packet_size += PACKET_LEN_INCREMENT;
-       do {
-               ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
-                       pos->packet_size / CHAR_BIT);
-       } while (ret == EINTR);
-       if (ret) {
-               errno = EINTR;
-               ret = -1;
-               goto end;
-       }
-
-       pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
-               pos->flags, pos->fd, pos->mmap_offset);
-       if (pos->base_mma == MAP_FAILED) {
-               ret = -1;
-       }
-end:
-       return ret;
-}
-
-static
-void generic_field_freeze(struct bt_ctf_field *field)
-{
-       field->frozen = 1;
-}
-
-static
-void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_enumeration *enum_field =
-               container_of(field, struct bt_ctf_field_enumeration, parent);
-
-       bt_ctf_field_freeze(enum_field->payload);
-       generic_field_freeze(field);
-}
-
-static
-void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
-{
-       int i;
-       struct bt_ctf_field_structure *structure_field =
-               container_of(field, struct bt_ctf_field_structure, parent);
-
-       for (i = 0; i < structure_field->fields->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(structure_field->fields, i);
-
-               bt_ctf_field_freeze(field);
-       }
-
-       generic_field_freeze(field);
-}
-
-static
-void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
-{
-       struct bt_ctf_field_variant *variant_field =
-               container_of(field, struct bt_ctf_field_variant, parent);
-
-       bt_ctf_field_freeze(variant_field->tag);
-       bt_ctf_field_freeze(variant_field->payload);
-       generic_field_freeze(field);
-}
-
-static
-void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
-{
-       int i;
-       struct bt_ctf_field_array *array_field =
-               container_of(field, struct bt_ctf_field_array, parent);
-
-       for (i = 0; i < array_field->elements->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(array_field->elements, i);
-
-               bt_ctf_field_freeze(field);
-       }
-
-       generic_field_freeze(field);
-}
-
-static
-void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
-{
-       int i;
-       struct bt_ctf_field_sequence *sequence_field =
-               container_of(field, struct bt_ctf_field_sequence, parent);
-
-       bt_ctf_field_freeze(sequence_field->length);
-
-       for (i = 0; i < sequence_field->elements->len; i++) {
-               struct bt_ctf_field *field =
-                       g_ptr_array_index(sequence_field->elements, i);
-
-               bt_ctf_field_freeze(field);
-       }
-
-       generic_field_freeze(field);
-}
-
-BT_HIDDEN
-void bt_ctf_field_freeze(struct bt_ctf_field *field)
-{
-       enum bt_ctf_type_id type_id;
-
-       if (!field) {
-               goto end;
-       }
-
-       type_id = bt_ctf_field_get_type_id(field);
-       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
-                       type_id >= BT_CTF_NR_TYPE_IDS) {
-               goto end;
-       }
-
-       field_freeze_funcs[type_id](field);
-end:
-       return;
-}
-
-static
-bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
-{
-       return field && field->payload_set;
-}
-
-static
-bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
-{
-       bool is_set = false;
-       struct bt_ctf_field_enumeration *enumeration;
-
-       if (!field) {
-               goto end;
-       }
-
-       enumeration = container_of(field, struct bt_ctf_field_enumeration,
-                       parent);
-       if (!enumeration->payload) {
-               goto end;
-       }
-
-       is_set = bt_ctf_field_is_set(enumeration->payload);
-end:
-       return is_set;
-}
-
-static
-bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
-{
-       bool is_set = false;
-       size_t i;
-       struct bt_ctf_field_structure *structure;
-
-       if (!field) {
-               goto end;
-       }
-
-       structure = container_of(field, struct bt_ctf_field_structure, parent);
-       for (i = 0; i < structure->fields->len; i++) {
-               is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
-               if (!is_set) {
-                       goto end;
-               }
-       }
-end:
-       return is_set;
-}
-
-static
-bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
-{
-       bool is_set = false;
-       struct bt_ctf_field_variant *variant;
-
-       if (!field) {
-               goto end;
-       }
-
-       variant = container_of(field, struct bt_ctf_field_variant, parent);
-       is_set = bt_ctf_field_is_set(variant->payload);
-end:
-       return is_set;
-}
-
-static
-bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
-{
-       size_t i;
-       bool is_set = false;
-       struct bt_ctf_field_array *array;
-
-       if (!field) {
-               goto end;
-       }
-
-       array = container_of(field, struct bt_ctf_field_array, parent);
-       for (i = 0; i < array->elements->len; i++) {
-               is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
-               if (!is_set) {
-                       goto end;
-               }
-       }
-end:
-       return is_set;
-}
-
-static
-bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
-{
-       size_t i;
-       bool is_set = false;
-       struct bt_ctf_field_sequence *sequence;
-
-       if (!field) {
-               goto end;
-       }
-
-       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
-       for (i = 0; i < sequence->elements->len; i++) {
-               is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
-               if (!is_set) {
-                       goto end;
-               }
-       }
-end:
-       return is_set;
-}
diff --git a/formats/ctf/ir/packet.c b/formats/ctf/ir/packet.c
deleted file mode 100644 (file)
index 6236e00..0000000
+++ /dev/null
@@ -1,207 +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.
- */
-
-#include <babeltrace/ctf-ir/fields-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/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/trace-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/ref.h>
-
-struct bt_ctf_stream *bt_ctf_packet_get_stream(struct bt_ctf_packet *packet)
-{
-       return packet ? bt_get(packet->stream) : NULL;
-}
-
-struct bt_ctf_field *bt_ctf_packet_get_header(
-               struct bt_ctf_packet *packet)
-{
-       return packet ? bt_get(packet->header) : NULL;
-}
-
-int bt_ctf_packet_set_header(struct bt_ctf_packet *packet,
-               struct bt_ctf_field *header)
-{
-       int ret = 0;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-       struct bt_ctf_field_type *header_field_type = NULL;
-       struct bt_ctf_field_type *expected_header_field_type = NULL;
-
-       if (!packet || packet->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!header) {
-               goto skip_validation;
-       }
-
-       stream_class = bt_ctf_stream_get_class(packet->stream);
-       assert(stream_class);
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       assert(trace);
-       header_field_type = bt_ctf_field_get_type(header);
-       assert(header_field_type);
-       expected_header_field_type = bt_ctf_trace_get_packet_header_type(trace);
-
-       if (bt_ctf_field_type_compare(header_field_type,
-                       expected_header_field_type)) {
-               ret = -1;
-               goto end;
-       }
-
-skip_validation:
-       bt_put(packet->header);
-       packet->header = bt_get(header);
-
-end:
-       BT_PUT(trace);
-       BT_PUT(stream_class);
-       BT_PUT(header_field_type);
-       BT_PUT(expected_header_field_type);
-
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_packet_get_context(
-               struct bt_ctf_packet *packet)
-{
-       return packet ? bt_get(packet->context) : NULL;
-}
-
-int bt_ctf_packet_set_context(struct bt_ctf_packet *packet,
-               struct bt_ctf_field *context)
-{
-       int ret = 0;
-       struct bt_ctf_stream_class *stream_class = NULL;
-       struct bt_ctf_field_type *context_field_type = NULL;
-       struct bt_ctf_field_type *expected_context_field_type = NULL;
-
-       if (!packet || packet->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!context) {
-               goto skip_validation;
-       }
-
-       stream_class = bt_ctf_stream_get_class(packet->stream);
-       assert(stream_class);
-       context_field_type = bt_ctf_field_get_type(context);
-       assert(context_field_type);
-       expected_context_field_type =
-               bt_ctf_stream_class_get_packet_context_type(stream_class);
-
-       if (bt_ctf_field_type_compare(context_field_type,
-                       expected_context_field_type)) {
-               ret = -1;
-               goto end;
-       }
-
-skip_validation:
-       bt_put(packet->context);
-       packet->context = bt_get(context);
-
-end:
-       BT_PUT(stream_class);
-       BT_PUT(context_field_type);
-       BT_PUT(expected_context_field_type);
-
-       return ret;
-}
-
-BT_HIDDEN
-void bt_ctf_packet_freeze(struct bt_ctf_packet *packet)
-{
-       if (!packet) {
-               return;
-       }
-
-       bt_ctf_field_freeze(packet->header);
-       bt_ctf_field_freeze(packet->context);
-       packet->frozen = 1;
-}
-
-static
-void bt_ctf_packet_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_packet *packet;
-
-       packet = container_of(obj, struct bt_ctf_packet, base);
-       bt_put(packet->header);
-       bt_put(packet->context);
-       bt_put(packet->stream);
-       g_free(packet);
-}
-
-struct bt_ctf_packet *bt_ctf_packet_create(
-               struct bt_ctf_stream *stream)
-{
-       struct bt_ctf_packet *packet = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-       struct bt_ctf_trace *trace = NULL;
-
-       if (!stream || stream->pos.fd >= 0) {
-               goto end;
-       }
-
-       stream_class = bt_ctf_stream_get_class(stream);
-       assert(stream_class);
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       assert(trace);
-       packet = g_new0(struct bt_ctf_packet, 1);
-       if (!packet) {
-               goto end;
-       }
-
-       bt_object_init(packet, bt_ctf_packet_destroy);
-       packet->stream = bt_get(stream);
-       packet->header = bt_ctf_field_create(trace->packet_header_type);
-       if (!packet->header && trace->packet_header_type) {
-               BT_PUT(packet);
-               goto end;
-       }
-
-       packet->context = bt_ctf_field_create(
-               stream->stream_class->packet_context_type);
-       if (!packet->context && stream->stream_class->packet_context_type) {
-               BT_PUT(packet);
-               goto end;
-       }
-
-end:
-       BT_PUT(trace);
-       BT_PUT(stream_class);
-
-       return packet;
-}
diff --git a/formats/ctf/ir/resolve.c b/formats/ctf/ir/resolve.c
deleted file mode 100644 (file)
index 4bc4130..0000000
+++ /dev/null
@@ -1,1193 +0,0 @@
-/*
- * resolve.c
- *
- * 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/event.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/resolve-internal.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <babeltrace/ctf-ir/field-path.h>
-#include <babeltrace/ctf-ir/field-path-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/values.h>
-#include <limits.h>
-#include <glib.h>
-
-#define _printf_error(fmt, args...) \
-       printf_verbose("[resolving] " fmt, ## args)
-
-typedef GPtrArray type_stack;
-
-/*
- * A stack frame.
- *
- * `type` contains a compound field type (structure, variant, array,
- * or sequence) and `index` indicates the index of the field type in
- * the upper frame (-1 for array and sequence field types).
- *
- * `type` is owned by the stack frame.
- */
-struct type_stack_frame {
-       struct bt_ctf_field_type *type;
-       int index;
-};
-
-/*
- * The current context of the resolving engine.
- *
- * `scopes` contain the 6 CTF scope field types (see CTF, sect. 7.3.2)
- * in the following order:
- *
- *   * Packet header
- *   * Packet context
- *   * Event header
- *   * Stream event context
- *   * Event context
- *   * Event payload
- */
-struct resolve_context {
-       struct bt_value *environment;
-       struct bt_ctf_field_type *scopes[6];
-
-       /* Root scope being visited */
-       enum bt_ctf_scope root_scope;
-       type_stack *type_stack;
-       struct bt_ctf_field_type *cur_field_type;
-};
-
-/* TSDL dynamic scope prefixes as defined in CTF Section 7.3.2 */
-static const char * const absolute_path_prefixes[] = {
-       [BT_CTF_SCOPE_ENV]                      = "env.",
-       [BT_CTF_SCOPE_TRACE_PACKET_HEADER]      = "trace.packet.header.",
-       [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT]    = "stream.packet.context.",
-       [BT_CTF_SCOPE_STREAM_EVENT_HEADER]      = "stream.event.header.",
-       [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT]     = "stream.event.context.",
-       [BT_CTF_SCOPE_EVENT_CONTEXT]            = "event.context.",
-       [BT_CTF_SCOPE_EVENT_FIELDS]             = "event.fields.",
-};
-
-/* Number of path tokens used for the absolute prefixes */
-static const int absolute_path_prefix_ptoken_counts[] = {
-       [BT_CTF_SCOPE_ENV]                      = 1,
-       [BT_CTF_SCOPE_TRACE_PACKET_HEADER]      = 3,
-       [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT]    = 3,
-       [BT_CTF_SCOPE_STREAM_EVENT_HEADER]      = 3,
-       [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT]     = 3,
-       [BT_CTF_SCOPE_EVENT_CONTEXT]            = 2,
-       [BT_CTF_SCOPE_EVENT_FIELDS]             = 2,
-};
-
-/*
- * Destroys a type stack frame.
- */
-static
-void type_stack_destroy_notify(gpointer data)
-{
-       struct type_stack_frame *frame = data;
-
-       BT_PUT(frame->type);
-       g_free(frame);
-}
-
-/*
- * Creates a type stack.
- *
- * Return value is owned by the caller.
- */
-static
-type_stack *type_stack_create(void)
-{
-       return g_ptr_array_new_with_free_func(type_stack_destroy_notify);
-}
-
-/*
- * Destroys a type stack.
- */
-static
-void type_stack_destroy(type_stack *stack)
-{
-       g_ptr_array_free(stack, TRUE);
-}
-
-/*
- * Pushes a field type onto a type stack.
- *
- * `type` is owned by the caller (stack frame gets a new reference).
- */
-static
-int type_stack_push(type_stack *stack, struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       struct type_stack_frame *frame = NULL;
-
-       if (!stack || !type) {
-               ret = -1;
-               goto end;
-       }
-
-       frame = g_new0(struct type_stack_frame, 1);
-       if (!frame) {
-               ret = -1;
-               goto end;
-       }
-
-       frame->type = bt_get(type);
-       g_ptr_array_add(stack, frame);
-
-end:
-       return ret;
-}
-
-/*
- * Checks whether or not `stack` is empty.
- */
-static
-bool type_stack_empty(type_stack *stack)
-{
-       return stack->len == 0;
-}
-
-/*
- * Returns the number of frames in `stack`.
- */
-static
-size_t type_stack_size(type_stack *stack)
-{
-       return stack->len;
-}
-
-/*
- * Returns the top frame of `stack`.
- *
- * Return value is owned by `stack`.
- */
-static
-struct type_stack_frame *type_stack_peek(type_stack *stack)
-{
-       struct type_stack_frame *entry = NULL;
-
-       if (!stack || type_stack_empty(stack)) {
-               goto end;
-       }
-
-       entry = g_ptr_array_index(stack, stack->len - 1);
-end:
-       return entry;
-}
-
-/*
- * Returns the frame at index `index` in `stack`.
- *
- * Return value is owned by `stack`.
- */
-static
-struct type_stack_frame *type_stack_at(type_stack *stack,
-               size_t index)
-{
-       struct type_stack_frame *entry = NULL;
-
-       if (!stack || index >= stack->len) {
-               goto end;
-       }
-
-       entry = g_ptr_array_index(stack, index);
-
-end:
-       return entry;
-}
-
-/*
- * Removes the top frame of `stack`.
- */
-static
-void type_stack_pop(type_stack *stack)
-{
-       if (!type_stack_empty(stack)) {
-               /*
-                * This will call the frame's destructor and free it, as
-                * well as put its contained field type.
-                */
-               g_ptr_array_set_size(stack, stack->len - 1);
-       }
-}
-
-/*
- * Returns the scope field type of `scope` in the context `ctx`.
- *
- * Return value is owned by `ctx` on success.
- */
-static
-struct bt_ctf_field_type *get_type_from_ctx(struct resolve_context *ctx,
-               enum bt_ctf_scope scope)
-{
-       assert(scope >= BT_CTF_SCOPE_TRACE_PACKET_HEADER &&
-               scope <= BT_CTF_SCOPE_EVENT_FIELDS);
-
-       return ctx->scopes[scope - BT_CTF_SCOPE_TRACE_PACKET_HEADER];
-}
-
-/*
- * Returns the CTF scope from a path string. May return
- * CTF_NODE_UNKNOWN if the path is found to be relative.
- */
-static
-enum bt_ctf_scope get_root_scope_from_absolute_pathstr(const char *pathstr)
-{
-       enum bt_ctf_scope scope;
-       enum bt_ctf_scope ret = BT_CTF_SCOPE_UNKNOWN;
-       const size_t prefixes_count = sizeof(absolute_path_prefixes) /
-               sizeof(*absolute_path_prefixes);
-
-       for (scope = BT_CTF_SCOPE_ENV; scope < BT_CTF_SCOPE_ENV +
-                       prefixes_count; scope++) {
-               /*
-                * Chech if path string starts with a known absolute
-                * path prefix.
-                *
-                * Refer to CTF 7.3.2 STATIC AND DYNAMIC SCOPES.
-                */
-               if (strncmp(pathstr, absolute_path_prefixes[scope],
-                               strlen(absolute_path_prefixes[scope]))) {
-                       /* Prefix does not match: try the next one */
-                       continue;
-               }
-
-               /* Found it! */
-               ret = scope;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-/*
- * Destroys a path token.
- */
-static
-void ptokens_destroy_func(gpointer ptoken, gpointer data)
-{
-       g_string_free(ptoken, TRUE);
-}
-
-/*
- * Destroys a path token list.
- */
-static
-void ptokens_destroy(GList *ptokens)
-{
-       if (!ptokens) {
-               return;
-       }
-
-       g_list_foreach(ptokens, ptokens_destroy_func, NULL);
-       g_list_free(ptokens);
-}
-
-/*
- * Returns the string contained in a path token.
- */
-static
-const char *ptoken_get_string(GList *ptoken)
-{
-       GString *tokenstr = (GString *) ptoken->data;
-
-       return tokenstr->str;
-}
-
-/*
- * Converts a path string to a path token list, that is, splits the
- * individual words of a path string into a list of individual
- * strings.
- *
- * Return value is owned by the caller on success.
- */
-static
-GList *pathstr_to_ptokens(const char *pathstr)
-{
-       const char *at = pathstr;
-       const char *last = at;
-       GList *ptokens = NULL;
-
-       for (;;) {
-               if (*at == '.' || *at == '\0') {
-                       GString *tokenstr;
-
-                       if (at == last) {
-                               /* Error: empty token */
-                               _printf_error("Empty token in path string at position %d\n",
-                                       (int) (at - pathstr));
-                               goto error;
-                       }
-
-                       tokenstr = g_string_new(NULL);
-                       g_string_append_len(tokenstr, last, at - last);
-                       ptokens = g_list_append(ptokens, tokenstr);
-                       last = at + 1;
-               }
-
-               if (*at == '\0') {
-                       break;
-               }
-
-               at++;
-       }
-
-       return ptokens;
-
-error:
-       ptokens_destroy(ptokens);
-       return NULL;
-}
-
-/*
- * Converts a path token list to a field path object. The path token
- * list is relative from `type`. The index of the source looking for
- * its target within `type` is indicated by `src_index`. This can be
- * `INT_MAX` if the source is contained in `type`.
- *
- * `ptokens` is owned by the caller. `field_path` is an output parameter
- * owned by the caller that must be filled here. `type` is owned by the
- * caller.
- */
-static
-int ptokens_to_field_path(GList *ptokens, struct bt_ctf_field_path *field_path,
-               struct bt_ctf_field_type *type, int src_index)
-{
-       int ret = 0;
-       GList *cur_ptoken = ptokens;
-       bool first_level_done = false;
-
-       /* Get our own reference */
-       bt_get(type);
-
-       /* Locate target */
-       while (cur_ptoken) {
-               int child_index;
-               struct bt_ctf_field_type *child_type;
-               const char *field_name = ptoken_get_string(cur_ptoken);
-               enum ctf_type_id type_id = bt_ctf_field_type_get_type_id(type);
-
-               /* Find to which index corresponds the current path token */
-               if (type_id == CTF_TYPE_ARRAY || type_id == CTF_TYPE_SEQUENCE) {
-                       child_index = -1;
-               } else {
-                       child_index = bt_ctf_field_type_get_field_index(type,
-                               field_name);
-                       if (child_index < 0) {
-                               /*
-                                * Error: field name does not exist or
-                                * wrong current type.
-                                */
-                               _printf_error("Cannot get index of field type named \"%s\"\n",
-                                       field_name);
-                               ret = -1;
-                               goto end;
-                       } else if (child_index > src_index &&
-                                       !first_level_done) {
-                               _printf_error("Child type is located after source index (%d)\n",
-                                       src_index);
-                               ret = -1;
-                               goto end;
-                       }
-
-                       /* Next path token */
-                       cur_ptoken = g_list_next(cur_ptoken);
-                       first_level_done = true;
-               }
-
-               /* Create new field path entry */
-               g_array_append_val(field_path->indexes, child_index);
-
-               /* Get child field type */
-               child_type = bt_ctf_field_type_get_field_at_index(type,
-                       child_index);
-               if (!child_type) {
-                       _printf_error("Cannot get child type at index %d (field \"%s\")\n",
-                               child_index, field_name);
-                       ret = -1;
-                       goto end;
-               }
-
-               /* Move child type to current type */
-               BT_MOVE(type, child_type);
-       }
-
-end:
-       bt_put(type);
-       return ret;
-}
-
-/*
- * Converts a known absolute path token list to a field path object
- * within the resolving context `ctx`.
- *
- * `ptokens` is owned by the caller. `field_path` is an output parameter
- * owned by the caller that must be filled here.
- */
-static
-int absolute_ptokens_to_field_path(GList *ptokens,
-               struct bt_ctf_field_path *field_path,
-               struct resolve_context *ctx)
-{
-       int ret = 0;
-       GList *cur_ptoken;
-       struct bt_ctf_field_type *type;
-
-       /* Skip absolute path tokens */
-       cur_ptoken = g_list_nth(ptokens,
-               absolute_path_prefix_ptoken_counts[field_path->root]);
-
-       /* Start with root type */
-       type = get_type_from_ctx(ctx, field_path->root);
-       if (!type) {
-               /* Error: root type is not available */
-               _printf_error("Root type with scope type %d is not available\n",
-                       field_path->root);
-               ret = -1;
-               goto end;
-       }
-
-       /* Locate target */
-       ret = ptokens_to_field_path(cur_ptoken, field_path, type, INT_MAX);
-
-end:
-       return ret;
-}
-
-/*
- * Converts a known relative path token list to a field path object
- * within the resolving context `ctx`.
- *
- * `ptokens` is owned by the caller. `field_path` is an output parameter
- * owned by the caller that must be filled here.
- */
-static
-int relative_ptokens_to_field_path(GList *ptokens,
-               struct bt_ctf_field_path *field_path,
-               struct resolve_context *ctx)
-{
-       int ret = 0;
-       int parent_pos_in_stack;
-       struct bt_ctf_field_path *tail_field_path = bt_ctf_field_path_create();
-
-       if (!tail_field_path) {
-               _printf_error("Cannot create field path\n");
-               ret = -1;
-               goto end;
-       }
-
-       parent_pos_in_stack = type_stack_size(ctx->type_stack) - 1;
-
-       while (parent_pos_in_stack >= 0) {
-               struct bt_ctf_field_type *parent_type =
-                       type_stack_at(ctx->type_stack,
-                               parent_pos_in_stack)->type;
-               int cur_index = type_stack_at(ctx->type_stack,
-                       parent_pos_in_stack)->index;
-
-               /* Locate target from current parent type */
-               ret = ptokens_to_field_path(ptokens, tail_field_path,
-                       parent_type, cur_index);
-               if (ret) {
-                       /* Not found... yet */
-                       bt_ctf_field_path_clear(tail_field_path);
-               } else {
-                       /* Found: stitch tail field path to head field path */
-                       int i = 0;
-                       int tail_field_path_len =
-                               tail_field_path->indexes->len;
-
-                       while (true) {
-                               struct bt_ctf_field_type *cur_type =
-                                       type_stack_at(ctx->type_stack, i)->type;
-                               int index = type_stack_at(
-                                       ctx->type_stack, i)->index;
-
-                               if (cur_type == parent_type) {
-                                       break;
-                               }
-
-                               g_array_append_val(field_path->indexes,
-                                       index);
-                               i++;
-                       }
-
-                       for (i = 0; i < tail_field_path_len; i++) {
-                               int index = g_array_index(
-                                       tail_field_path->indexes,
-                                       int, i);
-
-                               g_array_append_val(field_path->indexes,
-                                       index);
-                       }
-                       break;
-               }
-
-               parent_pos_in_stack--;
-       }
-
-       if (parent_pos_in_stack < 0) {
-               /* Not found: look in previous scopes */
-               field_path->root--;
-
-               while (field_path->root >= BT_CTF_SCOPE_TRACE_PACKET_HEADER) {
-                       struct bt_ctf_field_type *root_type;
-                       bt_ctf_field_path_clear(field_path);
-
-                       root_type = get_type_from_ctx(ctx, field_path->root);
-                       if (!root_type) {
-                               field_path->root--;
-                               continue;
-                       }
-
-                       /* Locate target in previous scope */
-                       ret = ptokens_to_field_path(ptokens, field_path,
-                               root_type, INT_MAX);
-                       if (ret) {
-                               /* Not found yet */
-                               field_path->root--;
-                               continue;
-                       }
-
-                       /* Found */
-                       break;
-               }
-       }
-
-end:
-       BT_PUT(tail_field_path);
-       return ret;
-}
-
-/*
- * Converts a path string to a field path object within the resolving
- * context `ctx`.
- *
- * Return value is owned by the caller on success.
- */
-static
-struct bt_ctf_field_path *pathstr_to_field_path(const char *pathstr,
-               struct resolve_context *ctx)
-{
-       int ret;
-       enum bt_ctf_scope root_scope;
-       GList *ptokens = NULL;
-       struct bt_ctf_field_path *field_path = NULL;
-
-       /* Create field path */
-       field_path = bt_ctf_field_path_create();
-       if (!field_path) {
-               _printf_error("Cannot create field path\n");
-               ret = -1;
-               goto end;
-       }
-
-       /* Convert path string to path tokens */
-       ptokens = pathstr_to_ptokens(pathstr);
-       if (!ptokens) {
-               _printf_error("Cannot convert path string \"%s\" to path tokens\n",
-                       pathstr);
-               ret = -1;
-               goto end;
-       }
-
-       /* Absolute or relative path? */
-       root_scope = get_root_scope_from_absolute_pathstr(pathstr);
-
-       if (root_scope == BT_CTF_SCOPE_UNKNOWN) {
-               /* Relative path: start with current root scope */
-               field_path->root = ctx->root_scope;
-               ret = relative_ptokens_to_field_path(ptokens, field_path, ctx);
-               if (ret) {
-                       _printf_error("Cannot get relative field path of path string \"%s\"\n",
-                               pathstr);
-                       _printf_error("  Starting at root scope %d, finished at root scope %d\n",
-                               ctx->root_scope, field_path->root);
-                       goto end;
-               }
-       } else if (root_scope == BT_CTF_SCOPE_ENV) {
-               _printf_error("Sequence field types referring the trace environment are not supported as of this version\n");
-               ret = -1;
-               goto end;
-       } else {
-               /* Absolute path: use found root scope */
-               field_path->root = root_scope;
-               ret = absolute_ptokens_to_field_path(ptokens, field_path, ctx);
-               if (ret) {
-                       _printf_error("Cannot get absolute field path of path string \"%s\"\n",
-                               pathstr);
-                       _printf_error("  Looking in root scope %d\n", root_scope);
-                       goto end;
-               }
-       }
-
-end:
-       if (ret) {
-               BT_PUT(field_path);
-       }
-
-       ptokens_destroy(ptokens);
-
-       return field_path;
-}
-
-/*
- * Retrieves a field type by following the field path `field_path` in
- * the resolving context `ctx`.
- *
- * Return value is owned by the caller on success.
- */
-static
-struct bt_ctf_field_type *field_path_to_field_type(
-               struct bt_ctf_field_path *field_path,
-               struct resolve_context *ctx)
-{
-       int i;
-       struct bt_ctf_field_type *type;
-
-       /* Start with root type */
-       type = get_type_from_ctx(ctx, field_path->root);
-       bt_get(type);
-       if (!type) {
-               /* Error: root type is not available */
-               _printf_error("Root type with scope type %d is not available\n",
-                       field_path->root);
-               goto error;
-       }
-
-       /* Locate target */
-       for (i = 0; i < field_path->indexes->len; i++) {
-               struct bt_ctf_field_type *child_type;
-               int child_index =
-                       g_array_index(field_path->indexes, int, i);
-
-               /* Get child field type */
-               child_type = bt_ctf_field_type_get_field_at_index(type,
-                       child_index);
-               if (!child_type) {
-                       _printf_error("Cannot get field type field at index %d\n",
-                               child_index);
-                       goto error;
-               }
-
-               /* Move child type to current type */
-               BT_MOVE(type, child_type);
-       }
-
-       return type;
-
-error:
-       BT_PUT(type);
-       return type;
-}
-
-/*
- * Returns the equivalent field path object of the context type stack.
- *
- * Return value is owned by the caller on success.
- */
-static
-struct bt_ctf_field_path *get_ctx_stack_field_path(struct resolve_context *ctx)
-{
-       int i;
-       struct bt_ctf_field_path *field_path;
-
-       /* Create field path */
-       field_path = bt_ctf_field_path_create();
-       if (!field_path) {
-               _printf_error("Cannot create field path\n");
-               goto error;
-       }
-
-       field_path->root = ctx->root_scope;
-
-       for (i = 0; i < type_stack_size(ctx->type_stack); i++) {
-               struct type_stack_frame *frame;
-
-               frame = type_stack_at(ctx->type_stack, i);
-               g_array_append_val(field_path->indexes, frame->index);
-       }
-
-       return field_path;
-
-error:
-       BT_PUT(field_path);
-       return field_path;
-}
-
-/*
- * Returns the lowest common ancestor of two field path objects
- * having the same root scope.
- *
- * `field_path1` and `field_path2` are owned by the caller.
- */
-int get_field_paths_lca_index(struct bt_ctf_field_path *field_path1,
-               struct bt_ctf_field_path *field_path2)
-{
-       int lca_index = 0;
-       int field_path1_len, field_path2_len;
-
-       /*
-        * Start from both roots and find the first mismatch.
-        */
-       assert(field_path1->root == field_path2->root);
-       field_path1_len = field_path1->indexes->len;
-       field_path2_len = field_path2->indexes->len;
-
-       while (true) {
-               int target_index, ctx_index;
-
-               if (lca_index == field_path2_len ||
-                               lca_index == field_path1_len) {
-                       /*
-                        * This means that both field paths never split.
-                        * This is invalid because the target cannot be
-                        * an ancestor of the source.
-                        */
-                       _printf_error("In source and target: one is an ancestor of the other\n");
-                       lca_index = -1;
-                       break;
-               }
-
-               target_index = g_array_index(field_path1->indexes, int,
-                       lca_index);
-               ctx_index = g_array_index(field_path2->indexes, int,
-                       lca_index);
-
-               if (target_index != ctx_index) {
-                       /* LCA index is the previous */
-                       break;
-               }
-
-               lca_index++;
-       }
-
-       return lca_index;
-}
-
-/*
- * Validates a target field path.
- *
- * `target_field_path` and `target_type` are owned by the caller.
- */
-static
-int validate_target_field_path(struct bt_ctf_field_path *target_field_path,
-               struct bt_ctf_field_type *target_type,
-               struct resolve_context *ctx)
-{
-       int ret = 0;
-       struct bt_ctf_field_path *ctx_field_path;
-       int target_field_path_len = target_field_path->indexes->len;
-       int lca_index;
-       int ctx_cur_field_type_id;
-       int target_type_id;
-
-       /* Get context field path */
-       ctx_field_path = get_ctx_stack_field_path(ctx);
-       if (!ctx_field_path) {
-               _printf_error("Cannot get source field path\n");
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * Make sure the target is not a root.
-        */
-       if (target_field_path_len == 0) {
-               _printf_error("Target field path's length is 0 (targeting the root)\n");
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * Make sure the root of the target field path is not located
-        * after the context field path's root.
-        */
-       if (target_field_path->root > ctx_field_path->root) {
-               _printf_error("Target is located after source\n");
-               ret = -1;
-               goto end;
-       }
-
-       if (target_field_path->root == ctx_field_path->root) {
-               int target_index, ctx_index;
-
-               /*
-                * Find the index of the lowest common ancestor of both field
-                * paths.
-                */
-               lca_index = get_field_paths_lca_index(target_field_path,
-                       ctx_field_path);
-               if (lca_index < 0) {
-                       _printf_error("Cannot get least common ancestor\n");
-                       ret = -1;
-                       goto end;
-               }
-
-               /*
-                * Make sure the target field path is located before the
-                * context field path.
-                */
-               target_index = g_array_index(target_field_path->indexes,
-                       int, lca_index);
-               ctx_index = g_array_index(ctx_field_path->indexes,
-                       int, lca_index);
-
-               if (target_index >= ctx_index) {
-                       _printf_error("Target index (%d) is greater or equal to source index (%d) in LCA\n",
-                               target_index, ctx_index);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /*
-        * Make sure the target type has the right type and properties.
-        */
-       ctx_cur_field_type_id = bt_ctf_field_type_get_type_id(
-               ctx->cur_field_type);
-       target_type_id = bt_ctf_field_type_get_type_id(target_type);
-
-       if (ctx_cur_field_type_id == CTF_TYPE_VARIANT) {
-               if (target_type_id != CTF_TYPE_ENUM) {
-                       _printf_error("Variant type's tag field type is not an enumeration\n");
-                       ret = -1;
-                       goto end;
-               }
-       } else if (ctx_cur_field_type_id == CTF_TYPE_SEQUENCE) {
-               if (target_type_id != CTF_TYPE_INTEGER ||
-                               bt_ctf_field_type_integer_get_signed(
-                                       target_type)) {
-                       _printf_error("Sequence type's length field type is not an unsigned integer\n");
-                       ret = -1;
-                       goto end;
-               }
-       } else {
-               assert(false);
-       }
-
-end:
-       BT_PUT(ctx_field_path);
-       return ret;
-}
-
-/*
- * Resolves a variant or sequence field type `type`.
- *
- * `type` is owned by the caller.
- */
-static
-int resolve_sequence_or_variant_type(struct bt_ctf_field_type *type,
-               struct resolve_context *ctx)
-{
-       int ret = 0;
-       const char *pathstr;
-       int type_id = bt_ctf_field_type_get_type_id(type);
-       struct bt_ctf_field_path *target_field_path = NULL;
-       struct bt_ctf_field_type *target_type = NULL;
-
-       /* Get path string */
-       switch (type_id) {
-       case CTF_TYPE_SEQUENCE:
-               pathstr =
-                       bt_ctf_field_type_sequence_get_length_field_name(type);
-               break;
-       case CTF_TYPE_VARIANT:
-               pathstr =
-                       bt_ctf_field_type_variant_get_tag_name(type);
-               break;
-       default:
-               assert(false);
-               ret = -1;
-               goto end;
-       }
-
-       /* Get target field path out of path string */
-       target_field_path = pathstr_to_field_path(pathstr, ctx);
-       if (!target_field_path) {
-               _printf_error("Cannot get target field path for path string \"%s\"\n",
-                       pathstr);
-               ret = -1;
-               goto end;
-       }
-
-       /* Get target field type */
-       target_type = field_path_to_field_type(target_field_path, ctx);
-       if (!target_type) {
-               _printf_error("Cannot get target field type for path string \"%s\"\n",
-                       pathstr);
-               ret = -1;
-               goto end;
-       }
-
-       ret = validate_target_field_path(target_field_path, target_type, ctx);
-       if (ret) {
-               _printf_error("Invalid target field path for path string \"%s\"\n",
-                       pathstr);
-               goto end;
-       }
-
-       /* Set target field path and target field type */
-       if (type_id == CTF_TYPE_SEQUENCE) {
-               ret = bt_ctf_field_type_sequence_set_length_field_path(
-                       type, target_field_path);
-               if (ret) {
-                       _printf_error("Cannot set sequence field type's length field path\n");
-                       goto end;
-               }
-       } else if (type_id == CTF_TYPE_VARIANT) {
-               ret = bt_ctf_field_type_variant_set_tag_field_path(
-                       type, target_field_path);
-               if (ret) {
-                       _printf_error("Cannot set variant field type's tag field path\n");
-                       goto end;
-               }
-
-               ret = bt_ctf_field_type_variant_set_tag_field_type(
-                       type, target_type);
-               if (ret) {
-                       _printf_error("Cannot set variant field type's tag field type\n");
-                       goto end;
-               }
-       } else {
-               assert(false);
-       }
-
-end:
-       BT_PUT(target_field_path);
-       BT_PUT(target_type);
-       return ret;
-}
-
-/*
- * Resolves a field type `type`.
- *
- * `type` is owned by the caller.
- */
-static
-int resolve_type(struct bt_ctf_field_type *type, struct resolve_context *ctx)
-{
-       int ret = 0;
-       int type_id;
-
-       if (!type) {
-               /* Type is not available; still valid */
-               goto end;
-       }
-
-       type_id = bt_ctf_field_type_get_type_id(type);
-       ctx->cur_field_type = type;
-
-       /* Resolve sequence/variant field type */
-       switch (type_id) {
-       case CTF_TYPE_SEQUENCE:
-       case CTF_TYPE_VARIANT:
-               ret = resolve_sequence_or_variant_type(type, ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve sequence or variant field type's length/tag\n");
-                       goto end;
-               }
-               break;
-       default:
-               break;
-       }
-
-       /* Recurse into compound types */
-       switch (type_id) {
-       case CTF_TYPE_STRUCT:
-       case CTF_TYPE_VARIANT:
-       case CTF_TYPE_SEQUENCE:
-       case CTF_TYPE_ARRAY:
-       {
-               int field_count, f_index;
-
-               ret = type_stack_push(ctx->type_stack, type);
-               if (ret) {
-                       _printf_error("Cannot push field type on type stack\n");
-                       _printf_error("  Stack size: %zu\n",
-                               type_stack_size(ctx->type_stack));
-                       goto end;
-               }
-
-               field_count = bt_ctf_field_type_get_field_count(type);
-               if (field_count < 0) {
-                       _printf_error("Cannot get field type field count\n");
-                       ret = field_count;
-                       goto end;
-               }
-
-               for (f_index = 0; f_index < field_count; f_index++) {
-                       struct bt_ctf_field_type *child_type =
-                               bt_ctf_field_type_get_field_at_index(type,
-                                       f_index);
-
-                       if (!child_type) {
-                               _printf_error("Cannot get field type field at index %d/%d\n",
-                                       f_index, field_count);
-                               ret = -1;
-                               goto end;
-                       }
-
-                       if (type_id == CTF_TYPE_ARRAY ||
-                                       type_id == CTF_TYPE_SEQUENCE) {
-                               type_stack_peek(ctx->type_stack)->index = -1;
-                       } else {
-                               type_stack_peek(ctx->type_stack)->index =
-                                       f_index;
-                       }
-
-                       ret = resolve_type(child_type, ctx);
-                       BT_PUT(child_type);
-                       if (ret) {
-                               goto end;
-                       }
-               }
-
-               type_stack_pop(ctx->type_stack);
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return ret;
-}
-
-/*
- * Resolves the root field type corresponding to the scope `root_scope`.
- */
-static
-int resolve_root_type(enum bt_ctf_scope root_scope, struct resolve_context *ctx)
-{
-       int ret;
-
-       assert(type_stack_size(ctx->type_stack) == 0);
-       ctx->root_scope = root_scope;
-       ret = resolve_type(get_type_from_ctx(ctx, root_scope), ctx);
-       ctx->root_scope = BT_CTF_SCOPE_UNKNOWN;
-
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_resolve_types(
-               struct bt_value *environment,
-               struct bt_ctf_field_type *packet_header_type,
-               struct bt_ctf_field_type *packet_context_type,
-               struct bt_ctf_field_type *event_header_type,
-               struct bt_ctf_field_type *stream_event_ctx_type,
-               struct bt_ctf_field_type *event_context_type,
-               struct bt_ctf_field_type *event_payload_type,
-               enum bt_ctf_resolve_flag flags)
-{
-       int ret = 0;
-       struct resolve_context ctx = {
-               .environment = environment,
-               .scopes = {
-                       packet_header_type,
-                       packet_context_type,
-                       event_header_type,
-                       stream_event_ctx_type,
-                       event_context_type,
-                       event_payload_type,
-               },
-               .root_scope = BT_CTF_SCOPE_UNKNOWN,
-       };
-
-       /* Initialize type stack */
-       ctx.type_stack = type_stack_create();
-       if (!ctx.type_stack) {
-               printf_error("Cannot create type stack\n");
-               ret = -1;
-               goto end;
-       }
-
-       /* Resolve packet header type */
-       if (flags & BT_CTF_RESOLVE_FLAG_PACKET_HEADER) {
-               ret = resolve_root_type(BT_CTF_SCOPE_TRACE_PACKET_HEADER, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve trace packet header type\n");
-                       goto end;
-               }
-       }
-
-       /* Resolve packet context type */
-       if (flags & BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT) {
-               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_PACKET_CONTEXT, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve stream packet context type\n");
-                       goto end;
-               }
-       }
-
-       /* Resolve event header type */
-       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_HEADER) {
-               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_HEADER, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve stream event header type\n");
-                       goto end;
-               }
-       }
-
-       /* Resolve stream event context type */
-       if (flags & BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX) {
-               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_CONTEXT, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve stream event context type\n");
-                       goto end;
-               }
-       }
-
-       /* Resolve event context type */
-       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT) {
-               ret = resolve_root_type(BT_CTF_SCOPE_EVENT_CONTEXT, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve event context type\n");
-                       goto end;
-               }
-       }
-
-       /* Resolve event payload type */
-       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD) {
-               ret = resolve_root_type(BT_CTF_SCOPE_EVENT_FIELDS, &ctx);
-               if (ret) {
-                       _printf_error("Cannot resolve event payload type\n");
-                       goto end;
-               }
-       }
-
-end:
-       type_stack_destroy(ctx.type_stack);
-
-       return ret;
-}
diff --git a/formats/ctf/ir/stream-class.c b/formats/ctf/ir/stream-class.c
deleted file mode 100644 (file)
index 403f5db..0000000
+++ /dev/null
@@ -1,971 +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.
- */
-
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/validation-internal.h>
-#include <babeltrace/ctf-ir/visitor-internal.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/align.h>
-#include <babeltrace/endian.h>
-
-static
-void bt_ctf_stream_class_destroy(struct bt_object *obj);
-static
-int init_event_header(struct bt_ctf_stream_class *stream_class);
-static
-int init_packet_context(struct bt_ctf_stream_class *stream_class);
-
-struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
-{
-       int ret;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (name && bt_ctf_validate_identifier(name)) {
-               goto error;
-       }
-
-       stream_class = g_new0(struct bt_ctf_stream_class, 1);
-       if (!stream_class) {
-               goto error;
-       }
-
-       stream_class->name = g_string_new(name);
-       stream_class->event_classes = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_release);
-       if (!stream_class->event_classes) {
-               goto error;
-       }
-
-       stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
-                       g_int64_equal, g_free, NULL);
-
-       ret = init_event_header(stream_class);
-       if (ret) {
-               goto error;
-       }
-
-       ret = init_packet_context(stream_class);
-       if (ret) {
-               goto error;
-       }
-
-       bt_object_init(stream_class, bt_ctf_stream_class_destroy);
-       return stream_class;
-
-error:
-        BT_PUT(stream_class);
-       return stream_class;
-}
-
-struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
-               struct bt_ctf_stream_class *stream_class)
-{
-       return (struct bt_ctf_trace *) bt_object_get_parent(
-               stream_class);
-}
-
-const char *bt_ctf_stream_class_get_name(
-               struct bt_ctf_stream_class *stream_class)
-{
-       const char *name = NULL;
-
-       if (!stream_class) {
-               goto end;
-       }
-
-       name = stream_class->name->str;
-end:
-       return name;
-}
-
-int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
-               const char *name)
-{
-       int ret = 0;
-
-       if (!stream_class || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       g_string_assign(stream_class->name, name);
-end:
-       return ret;
-}
-
-struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
-               struct bt_ctf_stream_class *stream_class)
-{
-       struct bt_ctf_clock *clock = NULL;
-
-       if (!stream_class || !stream_class->clock) {
-               goto end;
-       }
-
-       clock = bt_get(stream_class->clock);
-end:
-       return clock;
-}
-
-int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_clock *clock)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *timestamp_field = NULL;
-
-       if (!stream_class || !clock || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * Look for a "timestamp" integer field type in the stream
-        * class's event header field type and map the stream class's
-        * clock's class to that field type if there's no current
-        * mapping.
-        */
-       timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
-               stream_class->event_header_type, "timestamp");
-       if (timestamp_field) {
-               struct bt_ctf_clock_class *mapped_clock_class =
-                       bt_ctf_field_type_integer_get_mapped_clock_class(
-                               timestamp_field);
-
-               if (!mapped_clock_class) {
-                       ret = bt_ctf_field_type_integer_set_mapped_clock_class(
-                               timestamp_field, clock->clock_class);
-                       if (ret) {
-                               goto end;
-                       }
-               }
-
-               BT_PUT(mapped_clock_class);
-       }
-
-       /* Replace the current clock of this stream class. */
-       bt_put(stream_class->clock);
-       stream_class->clock = bt_get(clock);
-
-end:
-       bt_put(timestamp_field);
-       return ret;
-}
-
-int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
-{
-       int64_t ret;
-
-       if (!stream_class || !stream_class->id_set) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = (int64_t) stream_class->id;
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int _bt_ctf_stream_class_set_id(
-               struct bt_ctf_stream_class *stream_class, uint32_t id)
-{
-       stream_class->id = id;
-       stream_class->id_set = 1;
-       return 0;
-}
-
-struct event_class_set_stream_id_data {
-       uint32_t stream_id;
-       int ret;
-};
-
-static
-void event_class_set_stream_id(gpointer event_class, gpointer data)
-{
-       struct event_class_set_stream_id_data *typed_data = data;
-
-       typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
-               typed_data->stream_id);
-}
-
-BT_HIDDEN
-int bt_ctf_stream_class_set_id_no_check(
-               struct bt_ctf_stream_class *stream_class, uint32_t id)
-{
-       int ret = 0;
-       struct event_class_set_stream_id_data data =
-               { .stream_id = id, .ret = 0 };
-
-       /*
-        * Make sure all event classes have their "stream_id" attribute
-        * set to this value.
-        */
-       g_ptr_array_foreach(stream_class->event_classes,
-               event_class_set_stream_id, &data);
-       ret = data.ret;
-       if (ret) {
-               goto end;
-       }
-
-       ret = _bt_ctf_stream_class_set_id(stream_class, id);
-       if (ret) {
-               goto end;
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
-               uint32_t id)
-{
-       int ret = 0;
-
-       if (!stream_class || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
-end:
-       return ret;
-}
-
-static
-void event_class_exists(gpointer element, gpointer query)
-{
-       struct bt_ctf_event_class *event_class_a = element;
-       struct search_query *search_query = query;
-       struct bt_ctf_event_class *event_class_b = search_query->value;
-       int64_t id_a, id_b;
-
-       if (search_query->value == element) {
-               search_query->found = 1;
-               goto end;
-       }
-
-       /*
-        * Two event classes cannot share the same name in a given
-        * stream class.
-        */
-       if (!strcmp(bt_ctf_event_class_get_name(event_class_a),
-                       bt_ctf_event_class_get_name(event_class_b))) {
-               search_query->found = 1;
-               goto end;
-       }
-
-       /*
-        * Two event classes cannot share the same ID in a given
-        * stream class.
-        */
-       id_a = bt_ctf_event_class_get_id(event_class_a);
-       id_b = bt_ctf_event_class_get_id(event_class_b);
-
-       if (id_a < 0 || id_b < 0) {
-               /* at least one ID is not set: will be automatically set later */
-               goto end;
-       }
-
-       if (id_a == id_b) {
-               search_query->found = 1;
-               goto end;
-       }
-
-end:
-       return;
-}
-
-int bt_ctf_stream_class_add_event_class(
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_event_class *event_class)
-{
-       int ret = 0;
-       int64_t *event_id = NULL;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_stream_class *old_stream_class = NULL;
-       struct bt_ctf_validation_output validation_output = { 0 };
-       struct bt_ctf_field_type *packet_header_type = NULL;
-       struct bt_ctf_field_type *packet_context_type = NULL;
-       struct bt_ctf_field_type *event_header_type = NULL;
-       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
-       struct bt_ctf_field_type *event_context_type = NULL;
-       struct bt_ctf_field_type *event_payload_type = NULL;
-       const enum bt_ctf_validation_flag validation_flags =
-               BT_CTF_VALIDATION_FLAG_EVENT;
-
-       if (!stream_class || !event_class) {
-               ret = -1;
-               goto end;
-       }
-
-       event_id = g_new(int64_t, 1);
-       if (!event_id) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Check for duplicate event classes */
-       struct search_query query = { .value = event_class, .found = 0 };
-       g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
-               &query);
-       if (query.found) {
-               ret = -1;
-               goto end;
-       }
-
-       old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
-       if (old_stream_class) {
-               /* Event class is already associated to a stream class. */
-               ret = -1;
-               goto end;
-       }
-
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       if (trace) {
-               /*
-                * If the stream class is associated with a trace, then
-                * both those objects are frozen. Also, this event class
-                * is about to be frozen.
-                *
-                * Therefore the event class must be validated here.
-                * The trace and stream class should be valid at this
-                * point.
-                */
-               assert(trace->valid);
-               assert(stream_class->valid);
-               packet_header_type =
-                       bt_ctf_trace_get_packet_header_type(trace);
-               packet_context_type =
-                       bt_ctf_stream_class_get_packet_context_type(
-                               stream_class);
-               event_header_type =
-                       bt_ctf_stream_class_get_event_header_type(stream_class);
-               stream_event_ctx_type =
-                       bt_ctf_stream_class_get_event_context_type(
-                               stream_class);
-               event_context_type =
-                       bt_ctf_event_class_get_context_type(event_class);
-               event_payload_type =
-                       bt_ctf_event_class_get_payload_type(event_class);
-               ret = bt_ctf_validate_class_types(
-                       trace->environment, packet_header_type,
-                       packet_context_type, event_header_type,
-                       stream_event_ctx_type, event_context_type,
-                       event_payload_type, trace->valid,
-                       stream_class->valid, event_class->valid,
-                       &validation_output, validation_flags);
-               BT_PUT(packet_header_type);
-               BT_PUT(packet_context_type);
-               BT_PUT(event_header_type);
-               BT_PUT(stream_event_ctx_type);
-               BT_PUT(event_context_type);
-               BT_PUT(event_payload_type);
-
-               if (ret) {
-                       /*
-                        * This means something went wrong during the
-                        * validation process, not that the objects are
-                        * invalid.
-                        */
-                       goto end;
-               }
-
-               if ((validation_output.valid_flags & validation_flags) !=
-                               validation_flags) {
-                       /* Invalid event class */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /* Only set an event ID if none was explicitly set before */
-       *event_id = bt_ctf_event_class_get_id(event_class);
-       if (*event_id < 0) {
-               if (bt_ctf_event_class_set_id(event_class,
-                       stream_class->next_event_id++)) {
-                       ret = -1;
-                       goto end;
-               }
-               *event_id = stream_class->next_event_id;
-       }
-
-       ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
-       if (ret) {
-               goto end;
-       }
-
-       bt_object_set_parent(event_class, stream_class);
-
-       if (trace) {
-               /*
-                * At this point we know that the function will be
-                * successful. Therefore we can replace the event
-                * class's field types with what's in the validation
-                * output structure and mark this event class as valid.
-                */
-               bt_ctf_validation_replace_types(NULL, NULL, event_class,
-                       &validation_output, validation_flags);
-               event_class->valid = 1;
-
-               /*
-                * Put what was not moved in
-                * bt_ctf_validation_replace_types().
-                */
-               bt_ctf_validation_output_put_types(&validation_output);
-       }
-
-       /* Add to the event classes of the stream class */
-       g_ptr_array_add(stream_class->event_classes, event_class);
-       g_hash_table_insert(stream_class->event_classes_ht, event_id,
-                       event_class);
-       event_id = NULL;
-
-       /* Freeze the event class */
-       bt_ctf_event_class_freeze(event_class);
-
-       if (stream_class->byte_order) {
-               /*
-                * Only set native byte order if it has been initialized
-                * when the stream class was added to a trace.
-                *
-                * If not set here, this will be set when the stream
-                * class is added to a trace.
-                */
-               bt_ctf_event_class_set_native_byte_order(event_class,
-                       stream_class->byte_order);
-       }
-
-       /* Notifiy listeners of the trace's schema modification. */
-       if (trace) {
-               struct bt_ctf_object obj = { .object = event_class,
-                               .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
-
-               (void) bt_ctf_trace_object_modification(&obj, trace);
-       }
-end:
-       BT_PUT(trace);
-       BT_PUT(old_stream_class);
-       bt_ctf_validation_output_put_types(&validation_output);
-       assert(!packet_header_type);
-       assert(!packet_context_type);
-       assert(!event_header_type);
-       assert(!stream_event_ctx_type);
-       assert(!event_context_type);
-       assert(!event_payload_type);
-       g_free(event_id);
-
-       return ret;
-}
-
-int bt_ctf_stream_class_get_event_class_count(
-               struct bt_ctf_stream_class *stream_class)
-{
-       int ret;
-
-       if (!stream_class) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = (int) stream_class->event_classes->len;
-end:
-       return ret;
-}
-
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
-               struct bt_ctf_stream_class *stream_class, int index)
-{
-       struct bt_ctf_event_class *event_class = NULL;
-
-       if (!stream_class || index < 0 ||
-               index >= stream_class->event_classes->len) {
-               goto end;
-       }
-
-       event_class = g_ptr_array_index(stream_class->event_classes, index);
-       bt_get(event_class);
-end:
-       return event_class;
-}
-
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
-               struct bt_ctf_stream_class *stream_class, const char *name)
-{
-       size_t i;
-       struct bt_ctf_event_class *event_class = NULL;
-
-       if (!stream_class || !name) {
-               goto end;
-       }
-
-       for (i = 0; i < stream_class->event_classes->len; i++) {
-               struct bt_ctf_event_class *cur_event_class =
-                       g_ptr_array_index(stream_class->event_classes, i);
-               const char *cur_event_class_name =
-                       bt_ctf_event_class_get_name(cur_event_class);
-
-               if (!strcmp(name, cur_event_class_name)) {
-                       event_class = cur_event_class;
-                       bt_get(event_class);
-                       goto end;
-               }
-       }
-end:
-       return event_class;
-}
-
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
-               struct bt_ctf_stream_class *stream_class, uint32_t id)
-{
-       int64_t id_key = id;
-       struct bt_ctf_event_class *event_class = NULL;
-
-       if (!stream_class) {
-               goto end;
-       }
-
-       event_class = g_hash_table_lookup(stream_class->event_classes_ht,
-                       &id_key);
-       bt_get(event_class);
-end:
-       return event_class;
-}
-
-struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
-               struct bt_ctf_stream_class *stream_class)
-{
-       struct bt_ctf_field_type *ret = NULL;
-
-       if (!stream_class) {
-               goto end;
-       }
-
-       bt_get(stream_class->packet_context_type);
-       ret = stream_class->packet_context_type;
-end:
-       return ret;
-}
-
-int bt_ctf_stream_class_set_packet_context_type(
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_field_type *packet_context_type)
-{
-       int ret = 0;
-
-       if (!stream_class || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (packet_context_type &&
-                       bt_ctf_field_type_get_type_id(packet_context_type) !=
-                               BT_CTF_TYPE_ID_STRUCT) {
-               /* A packet context must be a structure. */
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(stream_class->packet_context_type);
-       bt_get(packet_context_type);
-       stream_class->packet_context_type = packet_context_type;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
-               struct bt_ctf_stream_class *stream_class)
-{
-       struct bt_ctf_field_type *ret = NULL;
-
-       if (!stream_class || !stream_class->event_header_type) {
-               goto end;
-       }
-
-       bt_get(stream_class->event_header_type);
-       ret = stream_class->event_header_type;
-end:
-       return ret;
-}
-
-int bt_ctf_stream_class_set_event_header_type(
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_field_type *event_header_type)
-{
-       int ret = 0;
-
-       if (!stream_class || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (event_header_type &&
-                       bt_ctf_field_type_get_type_id(event_header_type) !=
-                               BT_CTF_TYPE_ID_STRUCT) {
-               /* An event header must be a structure. */
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(stream_class->event_header_type);
-       stream_class->event_header_type = bt_get(event_header_type);
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
-               struct bt_ctf_stream_class *stream_class)
-{
-       struct bt_ctf_field_type *ret = NULL;
-
-       if (!stream_class || !stream_class->event_context_type) {
-               goto end;
-       }
-
-       bt_get(stream_class->event_context_type);
-       ret = stream_class->event_context_type;
-end:
-       return ret;
-}
-
-int bt_ctf_stream_class_set_event_context_type(
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_field_type *event_context_type)
-{
-       int ret = 0;
-
-       if (!stream_class || stream_class->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (event_context_type &&
-                       bt_ctf_field_type_get_type_id(event_context_type) !=
-                               BT_CTF_TYPE_ID_STRUCT) {
-               /* A packet context must be a structure. */
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(stream_class->event_context_type);
-       stream_class->event_context_type = bt_get(event_context_type);
-end:
-       return ret;
-}
-
-void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
-{
-       bt_get(stream_class);
-}
-
-void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
-{
-       bt_put(stream_class);
-}
-
-static
-int get_event_class_count(void *element)
-{
-       return bt_ctf_stream_class_get_event_class_count(
-                       (struct bt_ctf_stream_class *) element);
-}
-
-static
-void *get_event_class(void *element, int i)
-{
-       return bt_ctf_stream_class_get_event_class(
-                       (struct bt_ctf_stream_class *) element, i);
-}
-
-static
-int visit_event_class(void *object, bt_ctf_visitor visitor,void *data)
-{
-       struct bt_ctf_object obj =
-                       { .object = object,
-                       .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
-
-       return visitor(&obj, data);
-}
-
-int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
-               bt_ctf_visitor visitor, void *data)
-{
-       int ret;
-       struct bt_ctf_object obj =
-                       { .object = stream_class,
-                       .type = BT_CTF_OBJECT_TYPE_STREAM_CLASS };
-
-       if (!stream_class || !visitor) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = visitor_helper(&obj, get_event_class_count,
-                       get_event_class,
-                       visit_event_class, visitor, data);
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
-{
-       if (!stream_class) {
-               return;
-       }
-
-       stream_class->frozen = 1;
-       bt_ctf_field_type_freeze(stream_class->event_header_type);
-       bt_ctf_field_type_freeze(stream_class->packet_context_type);
-       bt_ctf_field_type_freeze(stream_class->event_context_type);
-
-       if (stream_class->clock) {
-               bt_ctf_clock_class_freeze(stream_class->clock->clock_class);
-       }
-}
-
-BT_HIDDEN
-void bt_ctf_stream_class_set_byte_order(
-       struct bt_ctf_stream_class *stream_class, int byte_order)
-{
-       int i;
-
-       assert(stream_class);
-       assert(byte_order == LITTLE_ENDIAN || byte_order == BIG_ENDIAN);
-       stream_class->byte_order = byte_order;
-
-       /* Set native byte order to little or big endian */
-       bt_ctf_field_type_set_native_byte_order(
-               stream_class->event_header_type, byte_order);
-       bt_ctf_field_type_set_native_byte_order(
-               stream_class->packet_context_type, byte_order);
-       bt_ctf_field_type_set_native_byte_order(
-               stream_class->event_context_type, byte_order);
-
-       /* Set all events' native byte order */
-       for (i = 0; i < stream_class->event_classes->len; i++) {
-               struct bt_ctf_event_class *event_class =
-                       g_ptr_array_index(stream_class->event_classes, i);
-
-               bt_ctf_event_class_set_native_byte_order(event_class,
-                       byte_order);
-       }
-}
-
-BT_HIDDEN
-int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
-               struct metadata_context *context)
-{
-       int64_t ret = 0;
-       size_t i;
-
-       g_string_assign(context->field_name, "");
-       context->current_indentation_level = 1;
-       if (!stream_class->id_set) {
-               ret = -1;
-               goto end;
-       }
-
-       g_string_append_printf(context->string,
-               "stream {\n\tid = %" PRIu32 ";\n\tevent.header := ",
-               stream_class->id);
-       ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
-               context);
-       if (ret) {
-               goto end;
-       }
-
-       if (stream_class->packet_context_type) {
-               g_string_append(context->string, ";\n\n\tpacket.context := ");
-               ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
-                       context);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       if (stream_class->event_context_type) {
-               g_string_append(context->string, ";\n\n\tevent.context := ");
-               ret = bt_ctf_field_type_serialize(
-                       stream_class->event_context_type, context);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       g_string_append(context->string, ";\n};\n\n");
-       for (i = 0; i < stream_class->event_classes->len; i++) {
-               struct bt_ctf_event_class *event_class =
-                       stream_class->event_classes->pdata[i];
-
-               ret = bt_ctf_event_class_serialize(event_class, context);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       context->current_indentation_level = 0;
-       return ret;
-}
-
-static
-void bt_ctf_stream_class_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_stream_class *stream_class;
-
-       stream_class = container_of(obj, struct bt_ctf_stream_class, base);
-       bt_put(stream_class->clock);
-
-       if (stream_class->event_classes_ht) {
-               g_hash_table_destroy(stream_class->event_classes_ht);
-       }
-       if (stream_class->event_classes) {
-               g_ptr_array_free(stream_class->event_classes, TRUE);
-       }
-
-       if (stream_class->name) {
-               g_string_free(stream_class->name, TRUE);
-       }
-
-       bt_put(stream_class->event_header_type);
-       bt_put(stream_class->packet_context_type);
-       bt_put(stream_class->event_context_type);
-       g_free(stream_class);
-}
-
-static
-int init_event_header(struct bt_ctf_stream_class *stream_class)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *event_header_type =
-               bt_ctf_field_type_structure_create();
-       struct bt_ctf_field_type *_uint32_t =
-               get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
-       struct bt_ctf_field_type *_uint64_t =
-               get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
-
-       if (!event_header_type) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(event_header_type,
-               _uint32_t, "id");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(event_header_type,
-               _uint64_t, "timestamp");
-       if (ret) {
-               goto end;
-       }
-
-       if (stream_class->event_header_type) {
-               bt_put(stream_class->event_header_type);
-       }
-       stream_class->event_header_type = event_header_type;
-end:
-       if (ret) {
-               bt_put(event_header_type);
-       }
-
-       bt_put(_uint32_t);
-       bt_put(_uint64_t);
-       return ret;
-}
-
-static
-int init_packet_context(struct bt_ctf_stream_class *stream_class)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *packet_context_type =
-               bt_ctf_field_type_structure_create();
-       struct bt_ctf_field_type *_uint64_t =
-               get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
-
-       if (!packet_context_type) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * We create a stream packet context as proposed in the CTF
-        * specification.
-        */
-       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               _uint64_t, "timestamp_begin");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               _uint64_t, "timestamp_end");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               _uint64_t, "content_size");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               _uint64_t, "packet_size");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               _uint64_t, "events_discarded");
-       if (ret) {
-               goto end;
-       }
-
-       bt_put(stream_class->packet_context_type);
-       stream_class->packet_context_type = packet_context_type;
-end:
-       if (ret) {
-               bt_put(packet_context_type);
-               goto end;
-       }
-
-       bt_put(_uint64_t);
-       return ret;
-}
diff --git a/formats/ctf/ir/stream.c b/formats/ctf/ir/stream.c
deleted file mode 100644 (file)
index b4d2347..0000000
+++ /dev/null
@@ -1,1222 +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.
- */
-
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-ir/stream.h>
-#include <babeltrace/ctf-ir/stream-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/align.h>
-#include <babeltrace/ctf/ctf-index.h>
-
-static
-void bt_ctf_stream_destroy(struct bt_object *obj);
-static
-int try_set_structure_field_integer(struct bt_ctf_field *, char *, uint64_t);
-static
-int set_structure_field_integer(struct bt_ctf_field *, char *, uint64_t);
-
-static
-int set_integer_field_value(struct bt_ctf_field* field, uint64_t value)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!field) {
-               ret = -1;
-               goto end;
-       }
-
-       field_type = bt_ctf_field_get_type(field);
-       assert(field_type);
-
-       if (bt_ctf_field_type_get_type_id(field_type) !=
-                       BT_CTF_TYPE_ID_INTEGER) {
-               /* Not an integer and the value is unset, error. */
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_integer_get_signed(field_type)) {
-               ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value);
-               if (ret) {
-                       /* Value is out of range, error. */
-                       goto end;
-               }
-       } else {
-               ret = bt_ctf_field_unsigned_integer_set_value(field, value);
-               if (ret) {
-                       /* Value is out of range, error. */
-                       goto end;
-               }
-       }
-end:
-       bt_put(field_type);
-       return ret;
-}
-
-static
-int set_packet_header_magic(struct bt_ctf_stream *stream)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *magic_field_type = NULL;
-       struct bt_ctf_field *magic_field = bt_ctf_field_structure_get_field(
-               stream->packet_header, "magic");
-
-       if (!magic_field) {
-               /* No magic field found. Not an error, skip. */
-               goto end;
-       }
-
-       if (bt_ctf_field_is_set(magic_field)) {
-               /* Value already set. Not an error, skip. */
-               goto end;
-       }
-
-       magic_field_type = bt_ctf_field_get_type(magic_field);
-       assert(magic_field_type);
-
-       if (bt_ctf_field_type_get_type_id(magic_field_type) !=
-               BT_CTF_TYPE_ID_INTEGER) {
-               /* Magic field is not an integer. Not an error, skip. */
-               goto end;
-       }
-
-       if (bt_ctf_field_type_integer_get_size(magic_field_type) != 32) {
-               /*
-                * Magic field is not of the expected size.
-                * Not an error, skip.
-                */
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_integer_get_signed(magic_field_type);
-       assert(ret >= 0);
-       if (ret) {
-               ret = bt_ctf_field_signed_integer_set_value(magic_field,
-                       (int64_t) 0xC1FC1FC1);
-       } else {
-               ret = bt_ctf_field_unsigned_integer_set_value(magic_field,
-                       (uint64_t) 0xC1FC1FC1);
-       }
-end:
-       bt_put(magic_field);
-       bt_put(magic_field_type);
-       return ret;
-}
-
-static
-int set_packet_header_uuid(struct bt_ctf_stream *stream)
-{
-       int i, ret = 0;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_field_type *uuid_field_type = NULL;
-       struct bt_ctf_field_type *element_field_type = NULL;
-       struct bt_ctf_field *uuid_field = bt_ctf_field_structure_get_field(
-               stream->packet_header, "uuid");
-
-       if (!uuid_field) {
-               /* No uuid field found. Not an error, skip. */
-               goto end;
-       }
-
-       if (bt_ctf_field_is_set(uuid_field)) {
-               /* Value already set. Not an error, skip. */
-               goto end;
-       }
-
-       uuid_field_type = bt_ctf_field_get_type(uuid_field);
-       assert(uuid_field_type);
-       if (bt_ctf_field_type_get_type_id(uuid_field_type) !=
-               BT_CTF_TYPE_ID_ARRAY) {
-               /* UUID field is not an array. Not an error, skip. */
-               goto end;
-       }
-
-       if (bt_ctf_field_type_array_get_length(uuid_field_type) != 16) {
-               /*
-                * UUID field is not of the expected size.
-                * Not an error, skip.
-                */
-               goto end;
-       }
-
-       element_field_type = bt_ctf_field_type_array_get_element_type(
-               uuid_field_type);
-       assert(element_field_type);
-       if (bt_ctf_field_type_get_type_id(element_field_type) !=
-               BT_CTF_TYPE_ID_INTEGER) {
-               /* UUID array elements are not integers. Not an error, skip */
-               goto end;
-       }
-
-       trace = (struct bt_ctf_trace *) bt_object_get_parent(stream);
-       for (i = 0; i < 16; i++) {
-               struct bt_ctf_field *uuid_element =
-                       bt_ctf_field_array_get_field(uuid_field, i);
-
-               ret = bt_ctf_field_type_integer_get_signed(element_field_type);
-               assert(ret >= 0);
-
-               if (ret) {
-                       ret = bt_ctf_field_signed_integer_set_value(
-                               uuid_element, (int64_t) trace->uuid[i]);
-               } else {
-                       ret = bt_ctf_field_unsigned_integer_set_value(
-                               uuid_element,
-                               (uint64_t) trace->uuid[i]);
-               }
-               bt_put(uuid_element);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-end:
-       bt_put(uuid_field);
-       bt_put(uuid_field_type);
-       bt_put(element_field_type);
-       BT_PUT(trace);
-       return ret;
-}
-static
-int set_packet_header_stream_id(struct bt_ctf_stream *stream)
-{
-       int ret = 0;
-       uint32_t stream_id;
-       struct bt_ctf_field_type *stream_id_field_type = NULL;
-       struct bt_ctf_field *stream_id_field = bt_ctf_field_structure_get_field(
-               stream->packet_header, "stream_id");
-
-       if (!stream_id_field) {
-               /* No stream_id field found. Not an error, skip. */
-               goto end;
-       }
-
-       if (bt_ctf_field_is_set(stream_id_field)) {
-               /* Value already set. Not an error, skip. */
-               goto end;
-       }
-
-       stream_id_field_type = bt_ctf_field_get_type(stream_id_field);
-       assert(stream_id_field_type);
-       if (bt_ctf_field_type_get_type_id(stream_id_field_type) !=
-               BT_CTF_TYPE_ID_INTEGER) {
-               /* stream_id field is not an integer. Not an error, skip. */
-               goto end;
-       }
-
-       stream_id = stream->stream_class->id;
-       ret = bt_ctf_field_type_integer_get_signed(stream_id_field_type);
-       assert(ret >= 0);
-       if (ret) {
-               ret = bt_ctf_field_signed_integer_set_value(stream_id_field,
-                       (int64_t) stream_id);
-       } else {
-               ret = bt_ctf_field_unsigned_integer_set_value(stream_id_field,
-                       (uint64_t) stream_id);
-       }
-end:
-       bt_put(stream_id_field);
-       bt_put(stream_id_field_type);
-       return ret;
-}
-
-static
-int set_packet_header(struct bt_ctf_stream *stream)
-{
-       int ret;
-
-       ret = set_packet_header_magic(stream);
-       if (ret) {
-               goto end;
-       }
-
-       ret = set_packet_header_uuid(stream);
-       if (ret) {
-               goto end;
-       }
-
-       ret = set_packet_header_stream_id(stream);
-       if (ret) {
-               goto end;
-       }
-end:
-       return ret;
-}
-
-static
-void release_event(struct bt_ctf_event *event)
-{
-       if (bt_object_get_ref_count(event)) {
-               /*
-                * The event is being orphaned, but it must guarantee the
-                * existence of its event class for the duration of its
-                * lifetime.
-                */
-               bt_get(event->event_class);
-               BT_PUT(event->base.parent);
-       } else {
-               bt_object_release(event);
-       }
-}
-
-static
-int create_stream_file(struct bt_ctf_writer *writer,
-               struct bt_ctf_stream *stream)
-{
-       int fd;
-       GString *filename = g_string_new(stream->stream_class->name->str);
-
-       if (stream->stream_class->name->len == 0) {
-               int64_t ret;
-
-               ret = bt_ctf_stream_class_get_id(stream->stream_class);
-               if (ret < 0) {
-                       fd = -1;
-                       goto error;
-               }
-
-               g_string_printf(filename, "stream_%" PRId64, ret);
-       }
-
-       g_string_append_printf(filename, "_%" PRIu32, stream->id);
-       fd = openat(writer->trace_dir_fd, filename->str,
-               O_RDWR | O_CREAT | O_TRUNC,
-               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-error:
-       g_string_free(filename, TRUE);
-       return fd;
-}
-
-static
-int set_stream_fd(struct bt_ctf_stream *stream, int fd)
-{
-       int ret = 0;
-
-       if (stream->pos.fd != -1) {
-               ret = -1;
-               goto end;
-       }
-
-       ctf_init_pos(&stream->pos, NULL, fd, O_RDWR);
-       stream->pos.fd = fd;
-end:
-       return ret;
-}
-
-struct bt_ctf_stream *bt_ctf_stream_create(
-               struct bt_ctf_stream_class *stream_class,
-               const char *name)
-{
-       int ret;
-       struct bt_ctf_stream *stream = NULL;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_writer *writer = NULL;
-
-       if (!stream_class) {
-               goto error;
-       }
-
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       if (!trace) {
-               goto error;
-       }
-
-       stream = g_new0(struct bt_ctf_stream, 1);
-       if (!stream) {
-               goto error;
-       }
-
-       bt_object_init(stream, bt_ctf_stream_destroy);
-       /*
-        * Acquire reference to parent since stream will become publicly
-        * reachable; it needs its parent to remain valid.
-        */
-       bt_object_set_parent(stream, trace);
-       stream->id = stream_class->next_stream_id++;
-       stream->stream_class = stream_class;
-       stream->pos.fd = -1;
-
-       if (name) {
-               stream->name = g_string_new(name);
-               if (!stream->name) {
-                       goto error;
-               }
-       }
-
-       if (trace->is_created_by_writer) {
-               int fd;
-               writer = (struct bt_ctf_writer *)
-                       bt_object_get_parent(trace);
-
-               assert(writer);
-               if (stream_class->packet_context_type) {
-                       stream->packet_context = bt_ctf_field_create(
-                               stream_class->packet_context_type);
-                       if (!stream->packet_context) {
-                               goto error;
-                       }
-
-                       /* Initialize events_discarded */
-                       ret = try_set_structure_field_integer(
-                               stream->packet_context,
-                               "events_discarded", 0);
-                       if (ret != 1) {
-                               goto error;
-                       }
-               }
-
-               stream->events = g_ptr_array_new_with_free_func(
-                       (GDestroyNotify) release_event);
-               if (!stream->events) {
-                       goto error;
-               }
-
-               /* A trace is not allowed to have a NULL packet header */
-               assert(trace->packet_header_type);
-               stream->packet_header =
-                       bt_ctf_field_create(trace->packet_header_type);
-               if (!stream->packet_header) {
-                       goto error;
-               }
-
-               /*
-                * Attempt to populate the default trace packet header fields
-                * (magic, uuid and stream_id). This will _not_ fail shall the
-                * fields not be found or be of an incompatible type; they will
-                * simply not be populated automatically. The user will have to
-                * make sure to set the trace packet header fields himself
-                * before flushing.
-                */
-               ret = set_packet_header(stream);
-               if (ret) {
-                       goto error;
-               }
-
-               /* Create file associated with this stream */
-               fd = create_stream_file(writer, stream);
-               if (fd < 0) {
-                       goto error;
-               }
-
-               ret = set_stream_fd(stream, fd);
-               if (ret) {
-                       goto error;
-               }
-
-               /* Freeze the writer */
-               bt_ctf_writer_freeze(writer);
-       } else {
-               /* Non-writer stream indicated by a negative FD */
-               ret = set_stream_fd(stream, -1);
-               if (ret) {
-                       goto error;
-               }
-       }
-
-       /* Add this stream to the trace's streams */
-       g_ptr_array_add(trace->streams, stream);
-
-       BT_PUT(trace);
-       BT_PUT(writer);
-       return stream;
-error:
-       BT_PUT(stream);
-       BT_PUT(trace);
-       BT_PUT(writer);
-       return stream;
-}
-
-struct bt_ctf_stream_class *bt_ctf_stream_get_class(
-               struct bt_ctf_stream *stream)
-{
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (!stream) {
-               goto end;
-       }
-
-       stream_class = stream->stream_class;
-       bt_get(stream_class);
-end:
-       return stream_class;
-}
-
-int bt_ctf_stream_get_discarded_events_count(
-               struct bt_ctf_stream *stream, uint64_t *count)
-{
-       int64_t ret = 0;
-       int field_signed;
-       struct bt_ctf_field *events_discarded_field = NULL;
-       struct bt_ctf_field_type *events_discarded_field_type = NULL;
-
-       if (!stream || !count || !stream->packet_context ||
-                       stream->pos.fd < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       events_discarded_field = bt_ctf_field_structure_get_field(
-               stream->packet_context, "events_discarded");
-       if (!events_discarded_field) {
-               ret = -1;
-               goto end;
-       }
-
-       events_discarded_field_type = bt_ctf_field_get_type(
-               events_discarded_field);
-       if (!events_discarded_field_type) {
-               ret = -1;
-               goto end;
-       }
-
-       field_signed = bt_ctf_field_type_integer_get_signed(
-               events_discarded_field_type);
-       if (field_signed < 0) {
-               ret = field_signed;
-               goto end;
-       }
-
-       if (field_signed) {
-               int64_t signed_count;
-
-               ret = bt_ctf_field_signed_integer_get_value(
-                       events_discarded_field, &signed_count);
-               if (ret) {
-                       goto end;
-               }
-               if (signed_count < 0) {
-                       /* Invalid value */
-                       ret = -1;
-                       goto end;
-               }
-               *count = (uint64_t) signed_count;
-       } else {
-               ret = bt_ctf_field_unsigned_integer_get_value(
-                       events_discarded_field, count);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       bt_put(events_discarded_field);
-       bt_put(events_discarded_field_type);
-       return ret;
-}
-
-void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream,
-               uint64_t event_count)
-{
-       int ret;
-       int field_signed;
-       uint64_t previous_count;
-       uint64_t new_count;
-       struct bt_ctf_field *events_discarded_field = NULL;
-       struct bt_ctf_field_type *events_discarded_field_type = NULL;
-
-       if (!stream || !stream->packet_context || stream->pos.fd < 0) {
-               goto end;
-       }
-
-       ret = bt_ctf_stream_get_discarded_events_count(stream,
-               &previous_count);
-       if (ret) {
-               goto end;
-       }
-
-       events_discarded_field = bt_ctf_field_structure_get_field(
-               stream->packet_context, "events_discarded");
-       if (!events_discarded_field) {
-               goto end;
-       }
-
-       events_discarded_field_type = bt_ctf_field_get_type(
-               events_discarded_field);
-       if (!events_discarded_field_type) {
-               goto end;
-       }
-
-       field_signed = bt_ctf_field_type_integer_get_signed(
-               events_discarded_field_type);
-       if (field_signed < 0) {
-               goto end;
-       }
-
-       new_count = previous_count + event_count;
-       if (field_signed) {
-               ret = bt_ctf_field_signed_integer_set_value(
-                       events_discarded_field, (int64_t) new_count);
-               if (ret) {
-                       goto end;
-               }
-       } else {
-               ret = bt_ctf_field_unsigned_integer_set_value(
-                       events_discarded_field, new_count);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-end:
-       bt_put(events_discarded_field);
-       bt_put(events_discarded_field_type);
-}
-
-static int auto_populate_event_header(struct bt_ctf_stream *stream,
-               struct bt_ctf_event *event)
-{
-       int ret = 0;
-       struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
-       struct bt_ctf_clock_class *mapped_clock_class = NULL;
-
-       if (!event || event->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * The condition to automatically set the ID are:
-        *
-        * 1. The event header field "id" exists and is an integer
-        *    field.
-        * 2. The event header field "id" is NOT set.
-        */
-       id_field = bt_ctf_field_structure_get_field(event->event_header, "id");
-       if (id_field && !bt_ctf_field_is_set(id_field)) {
-               ret = set_integer_field_value(id_field,
-                       (uint64_t) bt_ctf_event_class_get_id(
-                                       event->event_class));
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       /*
-        * The conditions to automatically set the timestamp are:
-        *
-        * 1. The event header field "timestamp" exists and is an
-        *    integer field.
-        * 2. This stream's class has a registered clock (set with
-        *    bt_ctf_stream_class_set_clock()).
-        * 3. The event header field "timestamp" has its type mapped to
-        *    a clock class which is also the clock class of this
-        *    stream's class's registered clock.
-        * 4. The event header field "timestamp" is NOT set.
-        */
-       timestamp_field = bt_ctf_field_structure_get_field(event->event_header,
-                       "timestamp");
-       if (timestamp_field && !bt_ctf_field_is_set(timestamp_field) &&
-                       stream->stream_class->clock) {
-               struct bt_ctf_clock_class *stream_class_clock_class =
-                       stream->stream_class->clock->clock_class;
-               struct bt_ctf_field_type *timestamp_field_type =
-                       bt_ctf_field_get_type(timestamp_field);
-
-               assert(timestamp_field_type);
-               mapped_clock_class =
-                       bt_ctf_field_type_integer_get_mapped_clock_class(
-                               timestamp_field_type);
-               BT_PUT(timestamp_field_type);
-               if (mapped_clock_class == stream_class_clock_class) {
-                       uint64_t timestamp;
-
-                       ret = bt_ctf_clock_get_value(
-                               stream->stream_class->clock,
-                               &timestamp);
-                       if (ret) {
-                               goto end;
-                       }
-
-                       ret = set_integer_field_value(timestamp_field,
-                                       timestamp);
-                       if (ret) {
-                               goto end;
-                       }
-               }
-       }
-
-end:
-       bt_put(id_field);
-       bt_put(timestamp_field);
-       bt_put(mapped_clock_class);
-       return ret;
-}
-
-int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
-               struct bt_ctf_event *event)
-{
-       int ret = 0;
-
-       if (!stream || !event || stream->pos.fd < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       /*
-        * The event is not supposed to have a parent stream at this
-        * point. The only other way an event can have a parent stream
-        * is if it was assigned when setting a packet to the event,
-        * in which case the packet's stream is not a writer stream,
-        * and thus the user is trying to append an event which belongs
-        * to another stream.
-        */
-       if (event->base.parent) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_object_set_parent(event, stream);
-       ret = auto_populate_event_header(stream, event);
-       if (ret) {
-               goto error;
-       }
-
-       /* Make sure the various scopes of the event are set */
-       ret = bt_ctf_event_validate(event);
-       if (ret) {
-               goto error;
-       }
-
-       /* Save the new event and freeze it */
-       bt_ctf_event_freeze(event);
-       g_ptr_array_add(stream->events, event);
-
-       /*
-        * Event had to hold a reference to its event class as long as it wasn't
-        * part of the same trace hierarchy. From now on, the event and its
-        * class share the same lifetime guarantees and the reference is no
-        * longer needed.
-        */
-       bt_put(event->event_class);
-
-end:
-       return ret;
-
-error:
-       /*
-        * Orphan the event; we were not successful in associating it to
-        * a stream.
-        */
-       bt_object_set_parent(event, NULL);
-
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_stream_get_packet_context(
-               struct bt_ctf_stream *stream)
-{
-       struct bt_ctf_field *packet_context = NULL;
-
-       if (!stream || stream->pos.fd < 0) {
-               goto end;
-       }
-
-       packet_context = stream->packet_context;
-       if (packet_context) {
-               bt_get(packet_context);
-       }
-end:
-       return packet_context;
-}
-
-int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream,
-               struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type;
-
-       if (!stream || stream->pos.fd < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       field_type = bt_ctf_field_get_type(field);
-       if (bt_ctf_field_type_compare(field_type,
-                       stream->stream_class->packet_context_type)) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(field_type);
-       bt_put(stream->packet_context);
-       stream->packet_context = bt_get(field);
-end:
-       return ret;
-}
-
-struct bt_ctf_field *bt_ctf_stream_get_packet_header(
-               struct bt_ctf_stream *stream)
-{
-       struct bt_ctf_field *packet_header = NULL;
-
-       if (!stream || stream->pos.fd < 0) {
-               goto end;
-       }
-
-       packet_header = stream->packet_header;
-       if (packet_header) {
-               bt_get(packet_header);
-       }
-end:
-       return packet_header;
-}
-
-int bt_ctf_stream_set_packet_header(struct bt_ctf_stream *stream,
-               struct bt_ctf_field *field)
-{
-       int ret = 0;
-       struct bt_ctf_trace *trace = NULL;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!stream || stream->pos.fd < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       trace = (struct bt_ctf_trace *) bt_object_get_parent(stream);
-       field_type = bt_ctf_field_get_type(field);
-       if (bt_ctf_field_type_compare(field_type, trace->packet_header_type)) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(stream->packet_header);
-       stream->packet_header = bt_get(field);
-end:
-       BT_PUT(trace);
-       bt_put(field_type);
-       return ret;
-}
-
-static
-int get_event_header_timestamp(struct bt_ctf_field *event_header, uint64_t *timestamp)
-{
-       int ret = 0;
-       struct bt_ctf_field *timestamp_field = NULL;
-       struct bt_ctf_field_type *timestamp_field_type = NULL;
-
-       timestamp_field = bt_ctf_field_structure_get_field(event_header,
-               "timestamp");
-       if (!timestamp_field) {
-               ret = -1;
-               goto end;
-       }
-
-       timestamp_field_type = bt_ctf_field_get_type(timestamp_field);
-       assert(timestamp_field_type);
-       if (bt_ctf_field_type_get_type_id(timestamp_field_type) !=
-               BT_CTF_TYPE_ID_INTEGER) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_integer_get_signed(timestamp_field_type)) {
-               int64_t val;
-
-               ret = bt_ctf_field_signed_integer_get_value(timestamp_field,
-                       &val);
-               if (ret) {
-                       goto end;
-               }
-               *timestamp = (uint64_t) val;
-       } else {
-               ret = bt_ctf_field_unsigned_integer_get_value(timestamp_field,
-                       timestamp);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       bt_put(timestamp_field);
-       bt_put(timestamp_field_type);
-       return ret;
-}
-
-static
-void reset_structure_field(struct bt_ctf_field *structure, const char *name)
-{
-       struct bt_ctf_field *member;
-
-       member = bt_ctf_field_structure_get_field(structure, name);
-       assert(member);
-       (void) bt_ctf_field_reset(member);
-       bt_put(member);
-}
-
-int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
-{
-       int ret = 0;
-       size_t i;
-       uint64_t timestamp_begin, timestamp_end;
-       struct bt_ctf_field *integer = NULL;
-       struct ctf_stream_pos packet_context_pos;
-       bool empty_packet;
-       uint64_t packet_size_bits;
-       struct {
-               bool timestamp_begin;
-               bool timestamp_end;
-               bool content_size;
-               bool packet_size;
-       } auto_set_fields = { 0 };
-
-       if (!stream || stream->pos.fd < 0) {
-               /*
-                * Stream does not have an associated fd. It is,
-                * therefore, not a stream being used to write events.
-                */
-               ret = -1;
-               goto end;
-       }
-
-       if (!stream->packet_context && stream->flushed_packet_count > 0) {
-               /*
-                * A stream without a packet context, and thus without
-                * content and packet size members, can't have more than
-                * one packet.
-                */
-               ret = -1;
-               goto end;
-       }
-
-       empty_packet = (stream->events->len == 0);
-
-       /* mmap the next packet */
-       ctf_packet_seek(&stream->pos.parent, 0, SEEK_CUR);
-       ret = bt_ctf_field_serialize(stream->packet_header, &stream->pos);
-       if (ret) {
-               goto end;
-       }
-
-       if (stream->packet_context) {
-               /* Set the default context attributes if present and unset. */
-               if (!empty_packet && !get_event_header_timestamp(
-                       ((struct bt_ctf_event *) g_ptr_array_index(
-                               stream->events, 0))->event_header, &timestamp_begin)) {
-                       ret = try_set_structure_field_integer(
-                               stream->packet_context,
-                               "timestamp_begin", timestamp_begin);
-                       if (ret < 0) {
-                               goto end;
-                       }
-                       auto_set_fields.timestamp_begin = ret == 1;
-               }
-
-               if (!empty_packet && !get_event_header_timestamp(
-                       ((struct bt_ctf_event *) g_ptr_array_index(
-                               stream->events, stream->events->len - 1))->event_header,
-                               &timestamp_end)) {
-
-                       ret = try_set_structure_field_integer(
-                               stream->packet_context,
-                               "timestamp_end", timestamp_end);
-                       if (ret < 0) {
-                               goto end;
-                       }
-                       auto_set_fields.timestamp_end = ret == 1;
-               }
-               ret = try_set_structure_field_integer(stream->packet_context,
-                       "content_size", UINT64_MAX);
-               if (ret < 0) {
-                       goto end;
-               }
-               auto_set_fields.content_size = ret == 1;
-
-               ret = try_set_structure_field_integer(stream->packet_context,
-                       "packet_size", UINT64_MAX);
-               if (ret < 0) {
-                       goto end;
-               }
-               auto_set_fields.packet_size = ret == 1;
-
-               /* Write packet context */
-               memcpy(&packet_context_pos, &stream->pos,
-                       sizeof(struct ctf_stream_pos));
-               ret = bt_ctf_field_serialize(stream->packet_context,
-                       &stream->pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       for (i = 0; i < stream->events->len; i++) {
-               struct bt_ctf_event *event = g_ptr_array_index(
-                       stream->events, i);
-
-               /* Write event header */
-               ret = bt_ctf_field_serialize(event->event_header,
-                       &stream->pos);
-               if (ret) {
-                       goto end;
-               }
-
-               /* Write stream event context */
-               if (event->stream_event_context) {
-                       ret = bt_ctf_field_serialize(
-                               event->stream_event_context, &stream->pos);
-                       if (ret) {
-                               goto end;
-                       }
-               }
-
-               /* Write event content */
-               ret = bt_ctf_event_serialize(event, &stream->pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       /* Rounded-up in case content_size is not byte-aligned. */
-       packet_size_bits = (stream->pos.offset + (CHAR_BIT - 1)) &
-               ~(CHAR_BIT - 1);
-       stream->pos.packet_size = packet_size_bits;
-
-       if (stream->packet_context) {
-               /*
-                * Update the packet total size and content size and overwrite
-                * the packet context.
-                * Copy base_mma as the packet may have been remapped (e.g. when
-                * a packet is resized).
-                */
-               packet_context_pos.base_mma = stream->pos.base_mma;
-               if (auto_set_fields.content_size) {
-                       ret = set_structure_field_integer(
-                                       stream->packet_context,
-                                       "content_size", stream->pos.offset);
-                       if (ret < 0) {
-                               goto end;
-                       }
-               }
-
-               if (auto_set_fields.packet_size) {
-                       ret = set_structure_field_integer(stream->packet_context,
-                                       "packet_size", packet_size_bits);
-                       if (ret < 0) {
-                               goto end;
-                       }
-               }
-
-               ret = bt_ctf_field_serialize(stream->packet_context,
-                       &packet_context_pos);
-               if (ret) {
-                       goto end;
-               }
-       }
-
-       g_ptr_array_set_size(stream->events, 0);
-       stream->flushed_packet_count++;
-       stream->size += packet_size_bits / CHAR_BIT;
-end:
-       /* Reset automatically-set fields. */
-       if (auto_set_fields.timestamp_begin) {
-               reset_structure_field(stream->packet_context,
-                               "timestamp_begin");
-       }
-       if (auto_set_fields.timestamp_end) {
-               reset_structure_field(stream->packet_context,
-                               "timestamp_end");
-       }
-       if (auto_set_fields.packet_size) {
-               reset_structure_field(stream->packet_context,
-                               "packet_size");
-       }
-       if (auto_set_fields.content_size) {
-               reset_structure_field(stream->packet_context,
-                               "content_size");
-       }
-       bt_put(integer);
-
-       if (ret < 0) {
-               /*
-                * We failed to write the packet. Its size is therefore set to 0
-                * to ensure the next mapping is done in the same place rather
-                * than advancing by "stream->pos.packet_size", which would
-                * leave a corrupted packet in the trace.
-                */
-               stream->pos.packet_size = 0;
-       }
-       return ret;
-}
-
-void bt_ctf_stream_get(struct bt_ctf_stream *stream)
-{
-       bt_get(stream);
-}
-
-void bt_ctf_stream_put(struct bt_ctf_stream *stream)
-{
-       bt_put(stream);
-}
-
-static
-void bt_ctf_stream_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_stream *stream;
-
-       stream = container_of(obj, struct bt_ctf_stream, base);
-       ctf_fini_pos(&stream->pos);
-       if (stream->pos.fd >= 0) {
-               int ret;
-
-               /*
-                * Truncate the file's size to the minimum required to fit the
-                * last packet as we might have grown it too much on the last
-                * mmap.
-                */
-               do {
-                       ret = ftruncate(stream->pos.fd, stream->size);
-               } while (ret == -1 && errno == EINTR);
-               if (ret) {
-                       perror("ftruncate");
-               }
-
-               if (close(stream->pos.fd)) {
-                       perror("close");
-               }
-       }
-
-       if (stream->events) {
-               g_ptr_array_free(stream->events, TRUE);
-       }
-
-       if (stream->name) {
-               g_string_free(stream->name, TRUE);
-       }
-
-       bt_put(stream->packet_header);
-       bt_put(stream->packet_context);
-       g_free(stream);
-}
-
-static
-int _set_structure_field_integer(struct bt_ctf_field *structure, char *name,
-               uint64_t value, bool force)
-{
-       int ret = 0;
-       struct bt_ctf_field_type *field_type = NULL;
-       struct bt_ctf_field *integer =
-               bt_ctf_field_structure_get_field(structure, name);
-
-       if (!structure || !name) {
-               ret = -1;
-               goto end;
-       }
-
-       if (!integer) {
-               /* Field not found, not an error. */
-               goto end;
-       }
-
-       /* Make sure the payload has not already been set. */
-       if (!force && bt_ctf_field_is_set(integer)) {
-               /* Payload already set, not an error */
-               goto end;
-       }
-
-       field_type = bt_ctf_field_get_type(integer);
-       assert(field_type);
-       if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_TYPE_ID_INTEGER) {
-               /*
-                * The user most likely meant for us to populate this field
-                * automatically. However, we can only do this if the field
-                * is an integer. Return an error.
-                */
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_ctf_field_type_integer_get_signed(field_type)) {
-               ret = bt_ctf_field_signed_integer_set_value(integer,
-                       (int64_t) value);
-       } else {
-               ret = bt_ctf_field_unsigned_integer_set_value(integer, value);
-       }
-       ret = !ret ? 1 : ret;
-end:
-       bt_put(integer);
-       bt_put(field_type);
-       return ret;
-}
-
-static
-int set_structure_field_integer(struct bt_ctf_field *structure, char *name,
-               uint64_t value)
-{
-       return _set_structure_field_integer(structure, name, value, true);
-}
-
-/*
- * Returns the following codes:
- * 1 if the field was found and set,
- * 0 if nothing was done (field not found, or was already set),
- * <0 if an error was encoutered
- */
-static
-int try_set_structure_field_integer(struct bt_ctf_field *structure, char *name,
-               uint64_t value)
-{
-       return _set_structure_field_integer(structure, name, value, false);
-}
-
-const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream)
-{
-       const char *name = NULL;
-
-       if (!stream) {
-               goto end;
-       }
-
-       name = stream->name ? stream->name->str : NULL;
-
-end:
-       return name;
-}
-
-int bt_ctf_stream_is_writer(struct bt_ctf_stream *stream)
-{
-       int ret = -1;
-
-       if (!stream) {
-               goto end;
-       }
-
-       ret = (stream->pos.fd >= 0);
-
-end:
-       return ret;
-}
diff --git a/formats/ctf/ir/trace.c b/formats/ctf/ir/trace.c
deleted file mode 100644 (file)
index 32ceca6..0000000
+++ /dev/null
@@ -1,1283 +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.
- */
-
-#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-types-internal.h>
-#include <babeltrace/ctf-ir/attributes-internal.h>
-#include <babeltrace/ctf-ir/validation-internal.h>
-#include <babeltrace/ctf-ir/visitor-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/graph/notification-schema.h>
-#include <babeltrace/compiler.h>
-#include <babeltrace/values.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/endian.h>
-
-#define DEFAULT_IDENTIFIER_SIZE 128
-#define DEFAULT_METADATA_STRING_SIZE 4096
-
-struct listener_wrapper {
-       bt_ctf_listener_cb listener;
-       void *data;
-};
-
-static
-void bt_ctf_trace_destroy(struct bt_object *obj);
-static
-int init_trace_packet_header(struct bt_ctf_trace *trace);
-static
-void bt_ctf_trace_freeze(struct bt_ctf_trace *trace);
-
-static
-const unsigned int field_type_aliases_alignments[] = {
-       [FIELD_TYPE_ALIAS_UINT5_T] = 1,
-       [FIELD_TYPE_ALIAS_UINT8_T ... FIELD_TYPE_ALIAS_UINT16_T] = 8,
-       [FIELD_TYPE_ALIAS_UINT27_T] = 1,
-       [FIELD_TYPE_ALIAS_UINT32_T ... FIELD_TYPE_ALIAS_UINT64_T] = 8,
-};
-
-static
-const unsigned int field_type_aliases_sizes[] = {
-       [FIELD_TYPE_ALIAS_UINT5_T] = 5,
-       [FIELD_TYPE_ALIAS_UINT8_T] = 8,
-       [FIELD_TYPE_ALIAS_UINT16_T] = 16,
-       [FIELD_TYPE_ALIAS_UINT27_T] = 27,
-       [FIELD_TYPE_ALIAS_UINT32_T] = 32,
-       [FIELD_TYPE_ALIAS_UINT64_T] = 64,
-};
-
-struct bt_ctf_trace *bt_ctf_trace_create(void)
-{
-       struct bt_ctf_trace *trace = NULL;
-
-       trace = g_new0(struct bt_ctf_trace, 1);
-       if (!trace) {
-               goto error;
-       }
-
-       bt_ctf_trace_set_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE);
-       bt_object_init(trace, bt_ctf_trace_destroy);
-       trace->clocks = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_put);
-       trace->streams = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_release);
-       trace->stream_classes = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_object_release);
-       if (!trace->clocks || !trace->stream_classes || !trace->streams) {
-               goto error;
-       }
-
-       /* Generate a trace UUID */
-       uuid_generate(trace->uuid);
-       if (init_trace_packet_header(trace)) {
-               goto error;
-       }
-
-       /* Create the environment array object */
-       trace->environment = bt_ctf_attributes_create();
-       if (!trace->environment) {
-               goto error;
-       }
-
-       trace->listeners = g_ptr_array_new_with_free_func(
-                       (GDestroyNotify) g_free);
-       if (!trace->listeners) {
-               goto error;
-       }
-
-       return trace;
-
-error:
-       BT_PUT(trace);
-       return trace;
-}
-
-const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace)
-{
-       const char *name = NULL;
-
-       if (!trace || !trace->name) {
-               goto end;
-       }
-
-       name = trace->name->str;
-end:
-       return name;
-}
-
-int bt_ctf_trace_set_name(struct bt_ctf_trace *trace, const char *name)
-{
-       int ret = 0;
-
-       if (!trace || !name || trace->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       trace->name = trace->name ? g_string_assign(trace->name, name) :
-                       g_string_new(name);
-       if (!trace->name) {
-               ret = -1;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-void bt_ctf_trace_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_trace *trace;
-
-       trace = container_of(obj, struct bt_ctf_trace, base);
-       if (trace->environment) {
-               bt_ctf_attributes_destroy(trace->environment);
-       }
-
-       if (trace->name) {
-               g_string_free(trace->name, TRUE);
-       }
-
-       if (trace->clocks) {
-               g_ptr_array_free(trace->clocks, TRUE);
-       }
-
-       if (trace->streams) {
-               g_ptr_array_free(trace->streams, TRUE);
-       }
-
-       if (trace->stream_classes) {
-               g_ptr_array_free(trace->stream_classes, TRUE);
-       }
-
-       if (trace->listeners) {
-               g_ptr_array_free(trace->listeners, TRUE);
-       }
-
-       bt_put(trace->packet_header_type);
-       g_free(trace);
-}
-
-int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
-               const char *name, struct bt_value *value)
-{
-       int ret = 0;
-
-       if (!trace || !name || !value ||
-               bt_ctf_validate_identifier(name) ||
-               !(bt_value_is_integer(value) || bt_value_is_string(value))) {
-               ret = -1;
-               goto end;
-       }
-
-       if (strchr(name, ' ')) {
-               ret = -1;
-               goto end;
-       }
-
-       if (trace->frozen) {
-               /*
-                * New environment fields may be added to a frozen trace,
-                * but existing fields may not be changed.
-                *
-                * The object passed is frozen like all other attributes.
-                */
-               struct bt_value *attribute =
-                       bt_ctf_attributes_get_field_value_by_name(
-                               trace->environment, name);
-
-               if (attribute) {
-                       BT_PUT(attribute);
-                       ret = -1;
-                       goto end;
-               }
-
-               bt_value_freeze(value);
-       }
-
-       ret = bt_ctf_attributes_set_field_value(trace->environment, name,
-               value);
-
-end:
-       return ret;
-}
-
-int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
-               const char *name, const char *value)
-{
-       int ret = 0;
-       struct bt_value *env_value_string_obj = NULL;
-
-       if (!trace || !name || !value) {
-               ret = -1;
-               goto end;
-       }
-
-       if (trace->frozen) {
-               /*
-                * New environment fields may be added to a frozen trace,
-                * but existing fields may not be changed.
-                */
-               struct bt_value *attribute =
-                       bt_ctf_attributes_get_field_value_by_name(
-                               trace->environment, name);
-
-               if (attribute) {
-                       BT_PUT(attribute);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       env_value_string_obj = bt_value_string_create_init(value);
-
-       if (!env_value_string_obj) {
-               ret = -1;
-               goto end;
-       }
-
-       if (trace->frozen) {
-               bt_value_freeze(env_value_string_obj);
-       }
-       ret = bt_ctf_trace_set_environment_field(trace, name,
-               env_value_string_obj);
-
-end:
-       BT_PUT(env_value_string_obj);
-       return ret;
-}
-
-int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
-               const char *name, int64_t value)
-{
-       int ret = 0;
-       struct bt_value *env_value_integer_obj = NULL;
-
-       if (!trace || !name) {
-               ret = -1;
-               goto end;
-       }
-
-       if (trace->frozen) {
-               /*
-                * New environment fields may be added to a frozen trace,
-                * but existing fields may not be changed.
-                */
-               struct bt_value *attribute =
-                       bt_ctf_attributes_get_field_value_by_name(
-                               trace->environment, name);
-
-               if (attribute) {
-                       BT_PUT(attribute);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       env_value_integer_obj = bt_value_integer_create_init(value);
-       if (!env_value_integer_obj) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_trace_set_environment_field(trace, name,
-               env_value_integer_obj);
-       if (trace->frozen) {
-               bt_value_freeze(env_value_integer_obj);
-       }
-end:
-       BT_PUT(env_value_integer_obj);
-       return ret;
-}
-
-int bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace)
-{
-       int ret = 0;
-
-       if (!trace) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_count(trace->environment);
-
-end:
-       return ret;
-}
-
-const char *
-bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace,
-               int index)
-{
-       const char *ret = NULL;
-
-       if (!trace) {
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_name(trace->environment, index);
-
-end:
-       return ret;
-}
-
-struct bt_value *bt_ctf_trace_get_environment_field_value(
-               struct bt_ctf_trace *trace, int index)
-{
-       struct bt_value *ret = NULL;
-
-       if (!trace) {
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_value(trace->environment, index);
-
-end:
-       return ret;
-}
-
-struct bt_value *bt_ctf_trace_get_environment_field_value_by_name(
-               struct bt_ctf_trace *trace, const char *name)
-{
-       struct bt_value *ret = NULL;
-
-       if (!trace || !name) {
-               goto end;
-       }
-
-       ret = bt_ctf_attributes_get_field_value_by_name(trace->environment,
-               name);
-
-end:
-       return ret;
-}
-
-int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
-               struct bt_ctf_clock_class *clock_class)
-{
-       int ret = 0;
-       struct search_query query = { .value = clock_class, .found = 0 };
-
-       if (!trace || !bt_ctf_clock_class_is_valid(clock_class)) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Check for duplicate clock classes */
-       g_ptr_array_foreach(trace->clocks, value_exists, &query);
-       if (query.found) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_get(clock_class);
-       g_ptr_array_add(trace->clocks, clock_class);
-
-       if (trace->frozen) {
-               bt_ctf_clock_class_freeze(clock_class);
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace)
-{
-       int ret = -1;
-
-       if (!trace) {
-               goto end;
-       }
-
-       ret = trace->clocks->len;
-end:
-       return ret;
-}
-
-struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class(
-               struct bt_ctf_trace *trace, int index)
-{
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!trace || index < 0 || index >= trace->clocks->len) {
-               goto end;
-       }
-
-       clock_class = g_ptr_array_index(trace->clocks, index);
-       bt_get(clock_class);
-end:
-       return clock_class;
-}
-
-int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
-               struct bt_ctf_stream_class *stream_class)
-{
-       int ret, i;
-       int64_t stream_id;
-       struct bt_ctf_validation_output trace_sc_validation_output = { 0 };
-       struct bt_ctf_validation_output *ec_validation_outputs = NULL;
-       const enum bt_ctf_validation_flag trace_sc_validation_flags =
-               BT_CTF_VALIDATION_FLAG_TRACE |
-               BT_CTF_VALIDATION_FLAG_STREAM;
-       const enum bt_ctf_validation_flag ec_validation_flags =
-               BT_CTF_VALIDATION_FLAG_EVENT;
-       struct bt_ctf_field_type *packet_header_type = NULL;
-       struct bt_ctf_field_type *packet_context_type = NULL;
-       struct bt_ctf_field_type *event_header_type = NULL;
-       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
-       int event_class_count;
-       struct bt_ctf_trace *current_parent_trace = NULL;
-
-       if (!trace || !stream_class) {
-               ret = -1;
-               goto end;
-       }
-
-       current_parent_trace = bt_ctf_stream_class_get_trace(stream_class);
-       if (current_parent_trace) {
-               /* Stream class is already associated to a trace, abort. */
-               ret = -1;
-               goto end;
-       }
-
-       event_class_count =
-               bt_ctf_stream_class_get_event_class_count(stream_class);
-       assert(event_class_count >= 0);
-
-       /* Check for duplicate stream classes */
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               if (trace->stream_classes->pdata[i] == stream_class) {
-                       /* Stream class already registered to the trace */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       if (stream_class->clock) {
-               struct bt_ctf_clock_class *stream_clock_class =
-                       stream_class->clock->clock_class;
-
-               if (trace->is_created_by_writer) {
-                       /*
-                        * Make sure this clock was also added to the
-                        * trace (potentially through its CTF writer
-                        * owner).
-                        */
-                       size_t i;
-
-                       for (i = 0; i < trace->clocks->len; i++) {
-                               if (trace->clocks->pdata[i] ==
-                                               stream_clock_class) {
-                                       /* Found! */
-                                       break;
-                               }
-                       }
-
-                       if (i == trace->clocks->len) {
-                               /* Not found */
-                               ret = -1;
-                               goto end;
-                       }
-               } else {
-                       /*
-                        * This trace was NOT created by a CTF writer,
-                        * thus do not allow the stream class to add to
-                        * have a clock at all. Those are two
-                        * independent APIs (non-writer and writer
-                        * APIs), and isolating them simplifies things.
-                        */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /*
-        * We're about to freeze both the trace and the stream class.
-        * Also, each event class contained in this stream class are
-        * already frozen.
-        *
-        * This trace, this stream class, and all its event classes
-        * should be valid at this point.
-        *
-        * Validate trace and stream class first, then each event
-        * class of this stream class can be validated individually.
-        */
-       packet_header_type =
-               bt_ctf_trace_get_packet_header_type(trace);
-       packet_context_type =
-               bt_ctf_stream_class_get_packet_context_type(stream_class);
-       event_header_type =
-               bt_ctf_stream_class_get_event_header_type(stream_class);
-       stream_event_ctx_type =
-               bt_ctf_stream_class_get_event_context_type(stream_class);
-       ret = bt_ctf_validate_class_types(trace->environment,
-               packet_header_type, packet_context_type, event_header_type,
-               stream_event_ctx_type, NULL, NULL, trace->valid,
-               stream_class->valid, 1, &trace_sc_validation_output,
-               trace_sc_validation_flags);
-       BT_PUT(packet_header_type);
-       BT_PUT(packet_context_type);
-       BT_PUT(event_header_type);
-       BT_PUT(stream_event_ctx_type);
-
-       if (ret) {
-               /*
-                * This means something went wrong during the validation
-                * process, not that the objects are invalid.
-                */
-               goto end;
-       }
-
-       if ((trace_sc_validation_output.valid_flags &
-                       trace_sc_validation_flags) !=
-                       trace_sc_validation_flags) {
-               /* Invalid trace/stream class */
-               ret = -1;
-               goto end;
-       }
-
-       if (event_class_count > 0) {
-               ec_validation_outputs = g_new0(struct bt_ctf_validation_output,
-                       event_class_count);
-               if (!ec_validation_outputs) {
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /* Validate each event class individually */
-       for (i = 0; i < event_class_count; i++) {
-               struct bt_ctf_event_class *event_class =
-                       bt_ctf_stream_class_get_event_class(stream_class, i);
-               struct bt_ctf_field_type *event_context_type = NULL;
-               struct bt_ctf_field_type *event_payload_type = NULL;
-
-               event_context_type =
-                       bt_ctf_event_class_get_context_type(event_class);
-               event_payload_type =
-                       bt_ctf_event_class_get_payload_type(event_class);
-
-               /*
-                * It is important to use the field types returned by
-                * the previous trace and stream class validation here
-                * because copies could have been made.
-                */
-               ret = bt_ctf_validate_class_types(trace->environment,
-                       trace_sc_validation_output.packet_header_type,
-                       trace_sc_validation_output.packet_context_type,
-                       trace_sc_validation_output.event_header_type,
-                       trace_sc_validation_output.stream_event_ctx_type,
-                       event_context_type, event_payload_type,
-                       1, 1, event_class->valid, &ec_validation_outputs[i],
-                       ec_validation_flags);
-               BT_PUT(event_context_type);
-               BT_PUT(event_payload_type);
-               BT_PUT(event_class);
-
-               if (ret) {
-                       goto end;
-               }
-
-               if ((ec_validation_outputs[i].valid_flags &
-                               ec_validation_flags) != ec_validation_flags) {
-                       /* Invalid event class */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       stream_id = bt_ctf_stream_class_get_id(stream_class);
-       if (stream_id < 0) {
-               stream_id = trace->next_stream_id++;
-
-               /* Try to assign a new stream id */
-               for (i = 0; i < trace->stream_classes->len; i++) {
-                       if (stream_id == bt_ctf_stream_class_get_id(
-                               trace->stream_classes->pdata[i])) {
-                               /* Duplicate stream id found */
-                               ret = -1;
-                               goto end;
-                       }
-               }
-
-               if (bt_ctf_stream_class_set_id_no_check(stream_class,
-                       stream_id)) {
-                       /* TODO Should retry with a different stream id */
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       bt_object_set_parent(stream_class, trace);
-       g_ptr_array_add(trace->stream_classes, stream_class);
-
-       /*
-        * At this point we know that the function will be successful.
-        * Therefore we can replace the trace and stream class field
-        * types with what's in their validation output structure and
-        * mark them as valid. We can also replace the field types of
-        * all the event classes of the stream class and mark them as
-        * valid.
-        */
-       bt_ctf_validation_replace_types(trace, stream_class, NULL,
-               &trace_sc_validation_output, trace_sc_validation_flags);
-       trace->valid = 1;
-       stream_class->valid = 1;
-
-       /*
-        * Put what was not moved in bt_ctf_validation_replace_types().
-        */
-       bt_ctf_validation_output_put_types(&trace_sc_validation_output);
-
-       for (i = 0; i < event_class_count; i++) {
-               struct bt_ctf_event_class *event_class =
-                       bt_ctf_stream_class_get_event_class(stream_class, i);
-
-               bt_ctf_validation_replace_types(NULL, NULL, event_class,
-                       &ec_validation_outputs[i], ec_validation_flags);
-               event_class->valid = 1;
-               BT_PUT(event_class);
-
-               /*
-                * Put what was not moved in
-                * bt_ctf_validation_replace_types().
-                */
-               bt_ctf_validation_output_put_types(&ec_validation_outputs[i]);
-       }
-
-       /*
-        * All field type byte orders set as "native" byte ordering can now be
-        * safely set to trace's own endianness, including the stream class'.
-        */
-       bt_ctf_field_type_set_native_byte_order(trace->packet_header_type,
-               trace->byte_order);
-       bt_ctf_stream_class_set_byte_order(stream_class, trace->byte_order);
-
-       /*
-        * Freeze the trace and the stream class.
-        */
-       bt_ctf_stream_class_freeze(stream_class);
-       bt_ctf_trace_freeze(trace);
-
-       /* Notifiy listeners of the trace's schema modification. */
-       bt_ctf_stream_class_visit(stream_class,
-                       bt_ctf_trace_object_modification, trace);
-end:
-       if (ret) {
-               bt_object_set_parent(stream_class, NULL);
-
-               if (ec_validation_outputs) {
-                       for (i = 0; i < event_class_count; i++) {
-                               bt_ctf_validation_output_put_types(
-                                       &ec_validation_outputs[i]);
-                       }
-               }
-       }
-
-       g_free(ec_validation_outputs);
-       bt_ctf_validation_output_put_types(&trace_sc_validation_output);
-       bt_put(current_parent_trace);
-       assert(!packet_header_type);
-       assert(!packet_context_type);
-       assert(!event_header_type);
-       assert(!stream_event_ctx_type);
-
-       return ret;
-}
-
-int bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace)
-{
-       int ret;
-
-       if (!trace) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = trace->stream_classes->len;
-end:
-       return ret;
-}
-
-struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class(
-               struct bt_ctf_trace *trace, int index)
-{
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (!trace || index < 0 || index >= trace->stream_classes->len) {
-               goto end;
-       }
-
-       stream_class = g_ptr_array_index(trace->stream_classes, index);
-       bt_get(stream_class);
-end:
-       return stream_class;
-}
-
-struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
-               struct bt_ctf_trace *trace, uint32_t id)
-{
-       int i;
-       struct bt_ctf_stream_class *stream_class = NULL;
-
-       if (!trace) {
-               goto end;
-       }
-
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               struct bt_ctf_stream_class *stream_class_candidate;
-
-               stream_class_candidate =
-                       g_ptr_array_index(trace->stream_classes, i);
-
-               if (bt_ctf_stream_class_get_id(stream_class_candidate) ==
-                               (int64_t) id) {
-                       stream_class = stream_class_candidate;
-                       bt_get(stream_class);
-                       goto end;
-               }
-       }
-
-end:
-       return stream_class;
-}
-
-struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
-               struct bt_ctf_trace *trace, const char *name)
-{
-       size_t i;
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!trace || !name) {
-               goto end;
-       }
-
-       for (i = 0; i < trace->clocks->len; i++) {
-               struct bt_ctf_clock_class *cur_clk =
-                       g_ptr_array_index(trace->clocks, i);
-               const char *cur_clk_name = bt_ctf_clock_class_get_name(cur_clk);
-
-               if (!cur_clk_name) {
-                       goto end;
-               }
-
-               if (!strcmp(cur_clk_name, name)) {
-                       clock_class = cur_clk;
-                       bt_get(clock_class);
-                       goto end;
-               }
-       }
-
-end:
-       return clock_class;
-}
-
-BT_HIDDEN
-const char *get_byte_order_string(int byte_order)
-{
-       const char *string;
-
-       switch (byte_order) {
-       case LITTLE_ENDIAN:
-               string = "le";
-               break;
-       case BIG_ENDIAN:
-               string = "be";
-               break;
-       default:
-               string = "unknown";
-               break;
-       }
-
-       return string;
-}
-
-static
-int append_trace_metadata(struct bt_ctf_trace *trace,
-               struct metadata_context *context)
-{
-       unsigned char *uuid = trace->uuid;
-       int ret;
-
-       g_string_append(context->string, "trace {\n");
-
-       g_string_append(context->string, "\tmajor = 1;\n");
-       g_string_append(context->string, "\tminor = 8;\n");
-
-       g_string_append_printf(context->string,
-               "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
-               uuid[0], uuid[1], uuid[2], uuid[3],
-               uuid[4], uuid[5], uuid[6], uuid[7],
-               uuid[8], uuid[9], uuid[10], uuid[11],
-               uuid[12], uuid[13], uuid[14], uuid[15]);
-       g_string_append_printf(context->string, "\tbyte_order = %s;\n",
-               get_byte_order_string(trace->byte_order));
-
-       g_string_append(context->string, "\tpacket.header := ");
-       context->current_indentation_level++;
-       g_string_assign(context->field_name, "");
-       ret = bt_ctf_field_type_serialize(trace->packet_header_type,
-               context);
-       if (ret) {
-               goto end;
-       }
-       context->current_indentation_level--;
-
-       g_string_append(context->string, ";\n};\n\n");
-end:
-       return ret;
-}
-
-static
-void append_env_metadata(struct bt_ctf_trace *trace,
-               struct metadata_context *context)
-{
-       int i;
-       int env_size;
-
-       env_size = bt_ctf_attributes_get_count(trace->environment);
-
-       if (env_size <= 0) {
-               return;
-       }
-
-       g_string_append(context->string, "env {\n");
-
-       for (i = 0; i < env_size; i++) {
-               struct bt_value *env_field_value_obj = NULL;
-               const char *entry_name;
-
-               entry_name = bt_ctf_attributes_get_field_name(
-                       trace->environment, i);
-               env_field_value_obj = bt_ctf_attributes_get_field_value(
-                       trace->environment, i);
-
-               if (!entry_name || !env_field_value_obj) {
-                       goto loop_next;
-               }
-
-               switch (bt_value_get_type(env_field_value_obj)) {
-               case BT_VALUE_TYPE_INTEGER:
-               {
-                       int ret;
-                       int64_t int_value;
-
-                       ret = bt_value_integer_get(env_field_value_obj,
-                               &int_value);
-
-                       if (ret) {
-                               goto loop_next;
-                       }
-
-                       g_string_append_printf(context->string,
-                               "\t%s = %" PRId64 ";\n", entry_name,
-                               int_value);
-                       break;
-               }
-               case BT_VALUE_TYPE_STRING:
-               {
-                       int ret;
-                       const char *str_value;
-                       char *escaped_str = NULL;
-
-                       ret = bt_value_string_get(env_field_value_obj,
-                               &str_value);
-
-                       if (ret) {
-                               goto loop_next;
-                       }
-
-                       escaped_str = g_strescape(str_value, NULL);
-
-                       if (!escaped_str) {
-                               goto loop_next;
-                       }
-
-                       g_string_append_printf(context->string,
-                               "\t%s = \"%s\";\n", entry_name, escaped_str);
-                       free(escaped_str);
-                       break;
-               }
-
-               default:
-                       goto loop_next;
-               }
-
-loop_next:
-               BT_PUT(env_field_value_obj);
-       }
-
-       g_string_append(context->string, "};\n\n");
-}
-
-char *bt_ctf_trace_get_metadata_string(struct bt_ctf_trace *trace)
-{
-       char *metadata = NULL;
-       struct metadata_context *context = NULL;
-       int err = 0;
-       size_t i;
-
-       if (!trace) {
-               goto end;
-       }
-
-       context = g_new0(struct metadata_context, 1);
-       if (!context) {
-               goto end;
-       }
-
-       context->field_name = g_string_sized_new(DEFAULT_IDENTIFIER_SIZE);
-       context->string = g_string_sized_new(DEFAULT_METADATA_STRING_SIZE);
-       g_string_append(context->string, "/* CTF 1.8 */\n\n");
-       if (append_trace_metadata(trace, context)) {
-               goto error;
-       }
-       append_env_metadata(trace, context);
-       g_ptr_array_foreach(trace->clocks,
-               (GFunc)bt_ctf_clock_class_serialize, context);
-
-       for (i = 0; i < trace->stream_classes->len; i++) {
-               err = bt_ctf_stream_class_serialize(
-                       trace->stream_classes->pdata[i], context);
-               if (err) {
-                       goto error;
-               }
-       }
-
-       metadata = context->string->str;
-error:
-       g_string_free(context->string, err ? TRUE : FALSE);
-       g_string_free(context->field_name, TRUE);
-       g_free(context);
-end:
-       return metadata;
-}
-
-enum bt_ctf_byte_order bt_ctf_trace_get_byte_order(struct bt_ctf_trace *trace)
-{
-       enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
-
-       if (!trace) {
-               goto end;
-       }
-
-       switch (trace->byte_order) {
-       case BIG_ENDIAN:
-               ret = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
-               break;
-       case LITTLE_ENDIAN:
-               ret = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
-               break;
-       default:
-               break;
-       }
-end:
-       return ret;
-}
-
-int bt_ctf_trace_set_byte_order(struct bt_ctf_trace *trace,
-               enum bt_ctf_byte_order byte_order)
-{
-       int ret = 0;
-       int internal_byte_order;
-
-       if (!trace || trace->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       switch (byte_order) {
-       case BT_CTF_BYTE_ORDER_NATIVE:
-               /*
-                * This doesn't make sense since the CTF specification defines
-                * the "native" byte order as "the byte order described in the
-                * trace description". However, this behavior had been
-                * implemented as part of v1.2 and is kept to maintain
-                * compatibility.
-                *
-                * This may be changed on a major version bump only.
-                */
-               internal_byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ?
-                       LITTLE_ENDIAN : BIG_ENDIAN;
-               break;
-       case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
-               internal_byte_order = LITTLE_ENDIAN;
-               break;
-       case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
-       case BT_CTF_BYTE_ORDER_NETWORK:
-               internal_byte_order = BIG_ENDIAN;
-               break;
-       default:
-               ret = -1;
-               goto end;
-       }
-
-       trace->byte_order = internal_byte_order;
-end:
-       return ret;
-}
-
-struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
-               struct bt_ctf_trace *trace)
-{
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (!trace) {
-               goto end;
-       }
-
-       bt_get(trace->packet_header_type);
-       field_type = trace->packet_header_type;
-end:
-       return field_type;
-}
-
-int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace,
-               struct bt_ctf_field_type *packet_header_type)
-{
-       int ret = 0;
-
-       if (!trace || trace->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       /* packet_header_type must be a structure. */
-       if (packet_header_type &&
-                       bt_ctf_field_type_get_type_id(packet_header_type) !=
-                               BT_CTF_TYPE_ID_STRUCT) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_put(trace->packet_header_type);
-       trace->packet_header_type = bt_get(packet_header_type);
-end:
-       return ret;
-}
-
-static
-int get_stream_class_count(void *element)
-{
-       return bt_ctf_trace_get_stream_class_count(
-                       (struct bt_ctf_trace *) element);
-}
-
-static
-void *get_stream_class(void *element, int i)
-{
-       return bt_ctf_trace_get_stream_class(
-                       (struct bt_ctf_trace *) element, i);
-}
-
-static
-int visit_stream_class(void *object, bt_ctf_visitor visitor,void *data)
-{
-       return bt_ctf_stream_class_visit(object, visitor, data);
-}
-
-int bt_ctf_trace_visit(struct bt_ctf_trace *trace,
-               bt_ctf_visitor visitor, void *data)
-{
-       int ret;
-       struct bt_ctf_object obj =
-                       { .object = trace, .type = BT_CTF_OBJECT_TYPE_TRACE };
-
-       if (!trace || !visitor) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = visitor_helper(&obj, get_stream_class_count,
-                       get_stream_class, visit_stream_class, visitor, data);
-end:
-       return ret;
-}
-
-static
-int invoke_listener(struct bt_ctf_object *object, void *data)
-{
-       struct listener_wrapper *listener_wrapper = data;
-
-       listener_wrapper->listener(object, listener_wrapper->data);
-       return 0;
-}
-
-int bt_ctf_trace_add_listener(struct bt_ctf_trace *trace,
-               bt_ctf_listener_cb listener, void *listener_data)
-{
-       int ret = 0;
-       struct listener_wrapper *listener_wrapper =
-                       g_new0(struct listener_wrapper, 1);
-
-       if (!trace || !listener || !listener_wrapper) {
-               ret = -1;
-               goto error;
-       }
-
-       listener_wrapper->listener = listener;
-       listener_wrapper->data = listener_data;
-
-       /* Visit the current schema. */
-       ret = bt_ctf_trace_visit(trace, invoke_listener, listener_wrapper);
-       if (ret) {
-               goto error;
-       }
-
-       /*
-        * Add listener to the array of callbacks which will be invoked on
-        * schema changes.
-        */
-       g_ptr_array_add(trace->listeners, listener_wrapper);
-       return ret;
-error:
-       g_free(listener_wrapper);
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_trace_object_modification(struct bt_ctf_object *object,
-               void *trace_ptr)
-{
-       size_t i;
-       struct bt_ctf_trace *trace = trace_ptr;
-
-       assert(trace);
-       assert(object);
-
-       if (trace->listeners->len == 0) {
-               goto end;
-       }
-
-       for (i = 0; i < trace->listeners->len; i++) {
-               struct listener_wrapper *listener =
-                               g_ptr_array_index(trace->listeners, i);
-
-               listener->listener(object, listener->data);
-       }
-end:
-       return 0;
-}
-
-BT_HIDDEN
-struct bt_ctf_field_type *get_field_type(enum field_type_alias alias)
-{
-       int ret;
-       unsigned int alignment, size;
-       struct bt_ctf_field_type *field_type = NULL;
-
-       if (alias >= NR_FIELD_TYPE_ALIAS) {
-               goto end;
-       }
-
-       alignment = field_type_aliases_alignments[alias];
-       size = field_type_aliases_sizes[alias];
-       field_type = bt_ctf_field_type_integer_create(size);
-       ret = bt_ctf_field_type_set_alignment(field_type, alignment);
-       if (ret) {
-               BT_PUT(field_type);
-       }
-end:
-       return field_type;
-}
-
-static
-void bt_ctf_trace_freeze(struct bt_ctf_trace *trace)
-{
-       int i;
-
-       bt_ctf_field_type_freeze(trace->packet_header_type);
-       bt_ctf_attributes_freeze(trace->environment);
-
-       for (i = 0; i < trace->clocks->len; i++) {
-               struct bt_ctf_clock_class *clock_class =
-                       g_ptr_array_index(trace->clocks, i);
-
-               bt_ctf_clock_class_freeze(clock_class);
-       }
-
-       trace->frozen = 1;
-}
-
-static
-int init_trace_packet_header(struct bt_ctf_trace *trace)
-{
-       int ret = 0;
-       struct bt_ctf_field *magic = NULL, *uuid_array = NULL;
-       struct bt_ctf_field_type *_uint32_t =
-               get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
-       struct bt_ctf_field_type *_uint8_t =
-               get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
-       struct bt_ctf_field_type *trace_packet_header_type =
-               bt_ctf_field_type_structure_create();
-       struct bt_ctf_field_type *uuid_array_type =
-               bt_ctf_field_type_array_create(_uint8_t, 16);
-
-       if (!trace_packet_header_type || !uuid_array_type) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
-               _uint32_t, "magic");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
-               uuid_array_type, "uuid");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
-               _uint32_t, "stream_id");
-       if (ret) {
-               goto end;
-       }
-
-       ret = bt_ctf_trace_set_packet_header_type(trace,
-               trace_packet_header_type);
-       if (ret) {
-               goto end;
-       }
-end:
-       bt_put(uuid_array_type);
-       bt_put(_uint32_t);
-       bt_put(_uint8_t);
-       bt_put(magic);
-       bt_put(uuid_array);
-       bt_put(trace_packet_header_type);
-       return ret;
-}
diff --git a/formats/ctf/ir/utils.c b/formats/ctf/ir/utils.c
deleted file mode 100644 (file)
index 318b12d..0000000
+++ /dev/null
@@ -1,106 +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.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-
-static
-const char * const reserved_keywords_str[] = {"align", "callsite",
-       "const", "char", "clock", "double", "enum", "env", "event",
-       "floating_point", "float", "integer", "int", "long", "short", "signed",
-       "stream", "string", "struct", "trace", "typealias", "typedef",
-       "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"};
-
-static GHashTable *reserved_keywords_set;
-static int init_done;
-static int global_data_refcount;
-
-static __attribute__((constructor))
-void trace_init(void)
-{
-       size_t i;
-       const size_t reserved_keywords_count =
-               sizeof(reserved_keywords_str) / sizeof(char *);
-
-       global_data_refcount++;
-       if (init_done) {
-               return;
-       }
-
-       reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal);
-       for (i = 0; i < reserved_keywords_count; i++) {
-               gpointer quark = GINT_TO_POINTER(g_quark_from_string(
-                       reserved_keywords_str[i]));
-
-               g_hash_table_insert(reserved_keywords_set, quark, quark);
-       }
-
-       init_done = 1;
-}
-
-static __attribute__((destructor))
-void trace_finalize(void)
-{
-       if (--global_data_refcount == 0) {
-               g_hash_table_destroy(reserved_keywords_set);
-       }
-}
-
-int bt_ctf_validate_identifier(const char *input_string)
-{
-       int ret = 0;
-       char *string = NULL;
-       char *save_ptr, *token;
-
-       if (!input_string || input_string[0] == '\0') {
-               ret = -1;
-               goto end;
-       }
-
-       string = strdup(input_string);
-       if (!string) {
-               ret = -1;
-               goto end;
-       }
-
-       token = strtok_r(string, " ", &save_ptr);
-       while (token) {
-               if (g_hash_table_lookup_extended(reserved_keywords_set,
-                       GINT_TO_POINTER(g_quark_from_string(token)),
-                       NULL, NULL)) {
-                       ret = -1;
-                       goto end;
-               }
-
-               token = strtok_r(NULL, " ", &save_ptr);
-       }
-end:
-       free(string);
-       return ret;
-}
diff --git a/formats/ctf/ir/validation.c b/formats/ctf/ir/validation.c
deleted file mode 100644 (file)
index dc2a3a9..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * validation.c
- *
- * Babeltrace - CTF IR: Validation of trace, stream class, and event class
- *
- * 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 <babeltrace/ctf-ir/validation-internal.h>
-#include <babeltrace/ctf-ir/resolve-internal.h>
-#include <babeltrace/ctf-ir/trace-internal.h>
-#include <babeltrace/ctf-ir/stream-class-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/event-class-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ref.h>
-
-#define _printf_error(fmt, args...) \
-       printf_verbose("[validation] " fmt, ## args)
-
-/*
- * This function resolves and validates the field types of an event
- * class. Only `event_context_type` and `event_payload_type` are
- * resolved and validated; the other field types are used as eventual
- * resolving targets.
- *
- * All parameters are owned by the caller.
- */
-static
-int validate_event_class_types(struct bt_value *environment,
-               struct bt_ctf_field_type *packet_header_type,
-               struct bt_ctf_field_type *packet_context_type,
-               struct bt_ctf_field_type *event_header_type,
-               struct bt_ctf_field_type *stream_event_ctx_type,
-               struct bt_ctf_field_type *event_context_type,
-               struct bt_ctf_field_type *event_payload_type)
-{
-       int ret = 0;
-
-       /* Resolve sequence type lengths and variant type tags first */
-       ret = bt_ctf_resolve_types(environment, packet_header_type,
-               packet_context_type, event_header_type, stream_event_ctx_type,
-               event_context_type, event_payload_type,
-               BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT |
-               BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD);
-       if (ret) {
-               _printf_error("Cannot resolve event class types\n");
-               goto end;
-       }
-
-       /* Validate field types individually */
-       if (event_context_type) {
-               ret = bt_ctf_field_type_validate(event_context_type);
-               if (ret) {
-                       _printf_error("Invalid event context type\n");
-                       goto end;
-               }
-       }
-
-       if (event_payload_type) {
-               ret = bt_ctf_field_type_validate(event_payload_type);
-               if (ret) {
-                       _printf_error("Invalid event payload type\n");
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-/*
- * This function resolves and validates the field types of a stream
- * class. Only `packet_context_type`, `event_header_type`, and
- * `stream_event_ctx_type` are resolved and validated; the other field
- * type is used as an eventual resolving target.
- *
- * All parameters are owned by the caller.
- */
-static
-int validate_stream_class_types(struct bt_value *environment,
-               struct bt_ctf_field_type *packet_header_type,
-               struct bt_ctf_field_type *packet_context_type,
-               struct bt_ctf_field_type *event_header_type,
-               struct bt_ctf_field_type *stream_event_ctx_type)
-{
-       int ret = 0;
-
-       /* Resolve sequence type lengths and variant type tags first */
-       ret = bt_ctf_resolve_types(environment, packet_header_type,
-               packet_context_type, event_header_type, stream_event_ctx_type,
-               NULL, NULL,
-               BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT |
-               BT_CTF_RESOLVE_FLAG_EVENT_HEADER |
-               BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX);
-       if (ret) {
-               _printf_error("Cannot resolve stream class types\n");
-               goto end;
-       }
-
-       /* Validate field types individually */
-       if (packet_context_type) {
-               ret = bt_ctf_field_type_validate(packet_context_type);
-               if (ret) {
-                       _printf_error("Invalid stream packet context type\n");
-                       goto end;
-               }
-       }
-
-       if (event_header_type) {
-               ret = bt_ctf_field_type_validate(event_header_type);
-               if (ret) {
-                       _printf_error("Invalid stream event header type\n");
-                       goto end;
-               }
-       }
-
-       if (stream_event_ctx_type) {
-               ret = bt_ctf_field_type_validate(
-                       stream_event_ctx_type);
-               if (ret) {
-                       _printf_error("Invalid stream event context type\n");
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-/*
- * This function resolves and validates the field types of a trace.
- *
- * All parameters are owned by the caller.
- */
-static
-int validate_trace_types(struct bt_value *environment,
-               struct bt_ctf_field_type *packet_header_type)
-{
-       int ret = 0;
-
-       /* Resolve sequence type lengths and variant type tags first */
-       ret = bt_ctf_resolve_types(environment, packet_header_type,
-               NULL, NULL, NULL, NULL, NULL,
-               BT_CTF_RESOLVE_FLAG_PACKET_HEADER);
-       if (ret) {
-               _printf_error("Cannot resolve trace types\n");
-               goto end;
-       }
-
-       /* Validate field types individually */
-       if (packet_header_type) {
-               ret = bt_ctf_field_type_validate(packet_header_type);
-               if (ret) {
-                       _printf_error("Invalid trace packet header type\n");
-                       goto end;
-               }
-       }
-
-end:
-       return ret;
-}
-
-/*
- * Checks whether or not `field_type` contains a variant or a sequence
- * field type, recursively. Returns 1 if it's the case.
- *
- * `field_type` is owned by the caller.
- */
-static
-int field_type_contains_sequence_or_variant_ft(struct bt_ctf_field_type *type)
-{
-       int ret = 0;
-       enum bt_ctf_type_id type_id = bt_ctf_field_type_get_type_id(type);
-
-       switch (type_id) {
-       case BT_CTF_TYPE_ID_SEQUENCE:
-       case BT_CTF_TYPE_ID_VARIANT:
-               ret = 1;
-               goto end;
-       case BT_CTF_TYPE_ID_ARRAY:
-       case BT_CTF_TYPE_ID_STRUCT:
-       {
-               int i;
-               int field_count = bt_ctf_field_type_get_field_count(type);
-
-               if (field_count < 0) {
-                       ret = -1;
-                       goto end;
-               }
-
-               for (i = 0; i < field_count; ++i) {
-                       struct bt_ctf_field_type *child_type =
-                               bt_ctf_field_type_get_field_at_index(type, i);
-
-                       ret = field_type_contains_sequence_or_variant_ft(
-                               child_type);
-                       BT_PUT(child_type);
-                       if (ret != 0) {
-                               goto end;
-                       }
-               }
-               break;
-       }
-       default:
-               break;
-       }
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-int bt_ctf_validate_class_types(struct bt_value *environment,
-               struct bt_ctf_field_type *packet_header_type,
-               struct bt_ctf_field_type *packet_context_type,
-               struct bt_ctf_field_type *event_header_type,
-               struct bt_ctf_field_type *stream_event_ctx_type,
-               struct bt_ctf_field_type *event_context_type,
-               struct bt_ctf_field_type *event_payload_type,
-               int trace_valid, int stream_class_valid, int event_class_valid,
-               struct bt_ctf_validation_output *output,
-               enum bt_ctf_validation_flag validate_flags)
-{
-       int ret = 0;
-       int contains_seq_var;
-       int valid_ret;
-
-       /* Clean output values */
-       memset(output, 0, sizeof(*output));
-
-       /* Set initial valid flags according to valid parameters */
-       if (trace_valid) {
-               output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
-       }
-
-       if (stream_class_valid) {
-               output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
-       }
-
-       if (event_class_valid) {
-               output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
-       }
-
-       /* Own the type parameters */
-       bt_get(packet_header_type);
-       bt_get(packet_context_type);
-       bt_get(event_header_type);
-       bt_get(stream_event_ctx_type);
-       bt_get(event_context_type);
-       bt_get(event_payload_type);
-
-       /* Validate trace */
-       if ((validate_flags & BT_CTF_VALIDATION_FLAG_TRACE) && !trace_valid) {
-               struct bt_ctf_field_type *packet_header_type_copy = NULL;
-
-               /* Create field type copies */
-               if (packet_header_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       packet_header_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               packet_header_type_copy = packet_header_type;
-                               bt_get(packet_header_type_copy);
-                               goto skip_packet_header_type_copy;
-                       }
-
-                       packet_header_type_copy =
-                               bt_ctf_field_type_copy(packet_header_type);
-                       if (!packet_header_type_copy) {
-                               ret = -1;
-                               _printf_error("Cannot copy packet header type\n");
-                               goto error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(packet_header_type_copy);
-               }
-
-skip_packet_header_type_copy:
-               /* Put original reference and move copy */
-               BT_MOVE(packet_header_type, packet_header_type_copy);
-
-               /* Validate trace field types */
-               valid_ret = validate_trace_types(environment,
-                       packet_header_type);
-               if (!valid_ret) {
-                       /* Trace is valid */
-                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
-               }
-       }
-
-       /* Validate stream class */
-       if ((validate_flags & BT_CTF_VALIDATION_FLAG_STREAM) &&
-                       !stream_class_valid) {
-               struct bt_ctf_field_type *packet_context_type_copy = NULL;
-               struct bt_ctf_field_type *event_header_type_copy = NULL;
-               struct bt_ctf_field_type *stream_event_ctx_type_copy = NULL;
-
-               if (packet_context_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       packet_context_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               packet_context_type_copy = packet_context_type;
-                               bt_get(packet_context_type_copy);
-                               goto skip_packet_context_type_copy;
-                       }
-
-                       packet_context_type_copy =
-                               bt_ctf_field_type_copy(packet_context_type);
-                       if (!packet_context_type_copy) {
-                               _printf_error("Cannot copy packet context type\n");
-                               goto sc_validation_error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(packet_context_type_copy);
-               }
-
-skip_packet_context_type_copy:
-               if (event_header_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       event_header_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               event_header_type_copy = event_header_type;
-                               bt_get(event_header_type_copy);
-                               goto skip_event_header_type_copy;
-                       }
-
-                       event_header_type_copy =
-                               bt_ctf_field_type_copy(event_header_type);
-                       if (!event_header_type_copy) {
-                               _printf_error("Cannot copy event header type\n");
-                               goto sc_validation_error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(event_header_type_copy);
-               }
-
-skip_event_header_type_copy:
-               if (stream_event_ctx_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       stream_event_ctx_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               stream_event_ctx_type_copy =
-                                       stream_event_ctx_type;
-                               bt_get(stream_event_ctx_type_copy);
-                               goto skip_stream_event_ctx_type_copy;
-                       }
-
-                       stream_event_ctx_type_copy =
-                               bt_ctf_field_type_copy(stream_event_ctx_type);
-                       if (!stream_event_ctx_type_copy) {
-                               _printf_error("Cannot copy stream event context type\n");
-                               goto sc_validation_error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(stream_event_ctx_type_copy);
-               }
-
-skip_stream_event_ctx_type_copy:
-               /* Put original references and move copies */
-               BT_MOVE(packet_context_type, packet_context_type_copy);
-               BT_MOVE(event_header_type, event_header_type_copy);
-               BT_MOVE(stream_event_ctx_type, stream_event_ctx_type_copy);
-
-               /* Validate stream class field types */
-               valid_ret = validate_stream_class_types(environment,
-                       packet_header_type, packet_context_type,
-                       event_header_type, stream_event_ctx_type);
-               if (!valid_ret) {
-                       /* Stream class is valid */
-                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
-               }
-
-               goto sc_validation_done;
-
-sc_validation_error:
-               BT_PUT(packet_context_type_copy);
-               BT_PUT(event_header_type_copy);
-               BT_PUT(stream_event_ctx_type_copy);
-               ret = -1;
-               goto error;
-       }
-
-sc_validation_done:
-       /* Validate event class */
-       if ((validate_flags & BT_CTF_VALIDATION_FLAG_EVENT) &&
-                       !event_class_valid) {
-               struct bt_ctf_field_type *event_context_type_copy = NULL;
-               struct bt_ctf_field_type *event_payload_type_copy = NULL;
-
-               if (event_context_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       event_context_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               event_context_type_copy = event_context_type;
-                               bt_get(event_context_type_copy);
-                               goto skip_event_context_type_copy;
-                       }
-
-                       event_context_type_copy =
-                               bt_ctf_field_type_copy(event_context_type);
-                       if (!event_context_type_copy) {
-                               _printf_error("Cannot copy event context type\n");
-                               goto ec_validation_error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(event_context_type_copy);
-               }
-
-skip_event_context_type_copy:
-               if (event_payload_type) {
-                       contains_seq_var =
-                               field_type_contains_sequence_or_variant_ft(
-                                       event_payload_type);
-                       if (contains_seq_var < 0) {
-                               ret = contains_seq_var;
-                               goto error;
-                       } else if (!contains_seq_var) {
-                               /* No copy is needed */
-                               event_payload_type_copy = event_payload_type;
-                               bt_get(event_payload_type_copy);
-                               goto skip_event_payload_type_copy;
-                       }
-
-                       event_payload_type_copy =
-                               bt_ctf_field_type_copy(event_payload_type);
-                       if (!event_payload_type_copy) {
-                               _printf_error("Cannot copy event payload type\n");
-                               goto ec_validation_error;
-                       }
-
-                       /*
-                        * Freeze this copy: if it's returned to the
-                        * caller, it cannot be modified any way since
-                        * it will be resolved.
-                        */
-                       bt_ctf_field_type_freeze(event_payload_type_copy);
-               }
-
-skip_event_payload_type_copy:
-               /* Put original references and move copies */
-               BT_MOVE(event_context_type, event_context_type_copy);
-               BT_MOVE(event_payload_type, event_payload_type_copy);
-
-               /* Validate event class field types */
-               valid_ret = validate_event_class_types(environment,
-                       packet_header_type, packet_context_type,
-                       event_header_type, stream_event_ctx_type,
-                       event_context_type, event_payload_type);
-               if (!valid_ret) {
-                       /* Event class is valid */
-                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
-               }
-
-               goto ec_validation_done;
-
-ec_validation_error:
-               BT_PUT(event_context_type_copy);
-               BT_PUT(event_payload_type_copy);
-               ret = -1;
-               goto error;
-       }
-
-ec_validation_done:
-       /*
-        * Validation is complete. Move the field types that were used
-        * to validate (and that were possibly altered by the validation
-        * process) to the output values.
-        */
-       BT_MOVE(output->packet_header_type, packet_header_type);
-       BT_MOVE(output->packet_context_type, packet_context_type);
-       BT_MOVE(output->event_header_type, event_header_type);
-       BT_MOVE(output->stream_event_ctx_type, stream_event_ctx_type);
-       BT_MOVE(output->event_context_type, event_context_type);
-       BT_MOVE(output->event_payload_type, event_payload_type);
-
-       return ret;
-
-error:
-       BT_PUT(packet_header_type);
-       BT_PUT(packet_context_type);
-       BT_PUT(event_header_type);
-       BT_PUT(stream_event_ctx_type);
-       BT_PUT(event_context_type);
-       BT_PUT(event_payload_type);
-
-       return ret;
-}
-
-BT_HIDDEN
-void bt_ctf_validation_replace_types(struct bt_ctf_trace *trace,
-               struct bt_ctf_stream_class *stream_class,
-               struct bt_ctf_event_class *event_class,
-               struct bt_ctf_validation_output *output,
-               enum bt_ctf_validation_flag replace_flags)
-{
-       if ((replace_flags & BT_CTF_VALIDATION_FLAG_TRACE) && trace) {
-               bt_ctf_field_type_freeze(trace->packet_header_type);
-               BT_MOVE(trace->packet_header_type, output->packet_header_type);
-       }
-
-       if ((replace_flags & BT_CTF_VALIDATION_FLAG_STREAM) && stream_class) {
-               bt_ctf_field_type_freeze(stream_class->packet_context_type);
-               bt_ctf_field_type_freeze(stream_class->event_header_type);
-               bt_ctf_field_type_freeze(stream_class->event_context_type);
-               BT_MOVE(stream_class->packet_context_type,
-                       output->packet_context_type);
-               BT_MOVE(stream_class->event_header_type,
-                       output->event_header_type);
-               BT_MOVE(stream_class->event_context_type,
-                       output->stream_event_ctx_type);
-       }
-
-       if ((replace_flags & BT_CTF_VALIDATION_FLAG_EVENT) && event_class) {
-               bt_ctf_field_type_freeze(event_class->context);
-               bt_ctf_field_type_freeze(event_class->fields);
-               BT_MOVE(event_class->context, output->event_context_type);
-               BT_MOVE(event_class->fields, output->event_payload_type);
-       }
-}
-
-BT_HIDDEN
-void bt_ctf_validation_output_put_types(
-               struct bt_ctf_validation_output *output)
-{
-       BT_PUT(output->packet_header_type);
-       BT_PUT(output->packet_context_type);
-       BT_PUT(output->event_header_type);
-       BT_PUT(output->stream_event_ctx_type);
-       BT_PUT(output->event_context_type);
-       BT_PUT(output->event_payload_type);
-}
diff --git a/formats/ctf/ir/visitor.c b/formats/ctf/ir/visitor.c
deleted file mode 100644 (file)
index 115b54a..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * visitor.c
- *
- * Babeltrace CTF IR - Visitor
- *
- * Copyright 2016 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/visitor-internal.h>
-#include <babeltrace/ref.h>
-
-BT_HIDDEN
-int visitor_helper(struct bt_ctf_object *root,
-               bt_child_count_accessor child_counter,
-               bt_child_accessor child_accessor,
-               bt_child_visitor child_visitor,
-               bt_ctf_visitor visitor,
-               void *data)
-{
-       int ret, child_count, i;
-
-       ret = visitor(root, data);
-       if (ret) {
-               goto end;
-       }
-
-       child_count = child_counter(root->object);
-       if (child_count < 0) {
-               ret = child_count;
-               goto end;
-       }
-
-       for (i = 0; i < child_count; i++) {
-               void *child;
-
-               child = child_accessor(root->object, i);
-               if (!child) {
-                       ret = -1;
-                       goto end;
-               }
-               ret = child_visitor(child, visitor, data);
-               BT_PUT(child);
-               if (ret) {
-                       goto end;
-               }
-       }
-end:
-       return ret;
-}
-
-enum bt_ctf_object_type bt_ctf_object_get_type(struct bt_ctf_object *object)
-{
-       enum bt_ctf_object_type ret = BT_CTF_OBJECT_TYPE_UNKNOWN;
-
-       if (!object) {
-               goto end;
-       }
-
-       ret = object->type;
-end:
-       return ret;
-}
-
-void *bt_ctf_object_get_object(struct bt_ctf_object *object)
-{
-       void *ret = NULL;
-
-       if (!object) {
-               goto end;
-       }
-
-       ret = object->object;
-end:
-       return ret;
-}
diff --git a/formats/ctf/iterator.c b/formats/ctf/iterator.c
deleted file mode 100644 (file)
index 31bb30c..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * ctf/iterator.c
- *
- * Babeltrace Library
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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.h>
-#include <babeltrace/format.h>
-#include <babeltrace/ctf/events.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/prio_heap.h>
-#include <babeltrace/iterator-internal.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/ctf/metadata.h>
-#include <glib.h>
-
-#include "events-private.h"
-
-struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos)
-{
-       struct bt_ctf_iter *iter;
-       int ret;
-
-       if (!ctx)
-               return NULL;
-
-       iter = g_new0(struct bt_ctf_iter, 1);
-       ret = bt_iter_init(&iter->parent, ctx, begin_pos, end_pos);
-       if (ret) {
-               g_free(iter);
-               return NULL;
-       }
-       iter->callbacks = g_array_new(FALSE, TRUE,
-                       sizeof(struct bt_stream_callbacks));
-       iter->recalculate_dep_graph = 0;
-       iter->main_callbacks.callback = NULL;
-       iter->dep_gc = g_ptr_array_new();
-       return iter;
-}
-
-struct bt_ctf_iter *bt_ctf_iter_create_intersect(struct bt_context *ctx,
-               struct bt_iter_pos **inter_begin_pos,
-               struct bt_iter_pos **inter_end_pos)
-{
-       int ret;
-       int64_t begin, end;
-
-       /*
-        * The iterator's range is the union of each trace's intersection of
-        * streams. This means that we determine the "active" region of each
-        * trace (that is the region where all of its streams are active), and
-        * use the TraceCollection to merge all of these active regions.
-        *
-        * This results in a union of the traces' active regions.
-        */
-       ret = ctf_find_tc_stream_packet_intersection_union(ctx, &begin, &end);
-       if (ret == 1) {
-               fprintf(stderr, "[error] No intersection found between trace files.\n");
-               goto error;
-       } else if (ret != 0) {
-               goto error;
-       }
-       *inter_begin_pos = bt_iter_create_time_pos(NULL, begin);
-       if (!(*inter_begin_pos)) {
-               goto error;
-       }
-       *inter_end_pos = bt_iter_create_time_pos(NULL, end);
-       if (!(*inter_end_pos)) {
-               goto error;
-       }
-
-       ret = ctf_tc_set_stream_intersection_mode(ctx);
-       if (ret) {
-               goto error;
-       }
-
-       /*
-        * bt_ctf_iter does not take ownership of begin and end positions,
-        * so we return them to the caller who must still assume their ownership
-        * until the iterator is destroyed.
-        */
-       return bt_ctf_iter_create(ctx, *inter_begin_pos,
-                       *inter_end_pos);
-error:
-       return NULL;
-}
-
-void bt_ctf_iter_destroy(struct bt_ctf_iter *iter)
-{
-       struct bt_stream_callbacks *bt_stream_cb;
-       struct bt_callback_chain *bt_chain;
-       int i, j;
-
-       assert(iter);
-
-       /* free all events callbacks */
-       if (iter->main_callbacks.callback)
-               g_array_free(iter->main_callbacks.callback, TRUE);
-
-       /* free per-event callbacks */
-       for (i = 0; i < iter->callbacks->len; i++) {
-               bt_stream_cb = &g_array_index(iter->callbacks,
-                               struct bt_stream_callbacks, i);
-               if (!bt_stream_cb || !bt_stream_cb->per_id_callbacks)
-                       continue;
-               for (j = 0; j < bt_stream_cb->per_id_callbacks->len; j++) {
-                       bt_chain = &g_array_index(bt_stream_cb->per_id_callbacks,
-                                       struct bt_callback_chain, j);
-                       if (bt_chain->callback) {
-                               g_array_free(bt_chain->callback, TRUE);
-                       }
-               }
-               g_array_free(bt_stream_cb->per_id_callbacks, TRUE);
-       }
-       g_array_free(iter->callbacks, TRUE);
-       g_ptr_array_free(iter->dep_gc, TRUE);
-
-       bt_iter_fini(&iter->parent);
-       g_free(iter);
-}
-
-struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter)
-{
-       if (!iter)
-               return NULL;
-
-       return &iter->parent;
-}
-
-struct bt_ctf_event *bt_ctf_iter_read_event_flags(struct bt_ctf_iter *iter,
-               int *flags)
-{
-       struct ctf_file_stream *file_stream;
-       struct bt_ctf_event *ret;
-       struct ctf_stream_definition *stream;
-       struct packet_index *packet_index;
-
-       /*
-        * We do not want to fail for any other reason than end of
-        * trace, hence the assert.
-        */
-       assert(iter);
-
-       if (flags)
-               *flags = 0;
-
-       ret = &iter->current_ctf_event;
-       file_stream = bt_heap_maximum(iter->parent.stream_heap);
-       if (!file_stream) {
-               /* end of file for all streams */
-               goto stop;
-       }
-
-       /*
-        * If the packet is empty (contains only headers or is of size 0), the
-        * caller has to know that we can't read the current event and we need
-        * to do a bt_iter_next.
-        */
-       if (file_stream->pos.data_offset == file_stream->pos.content_size
-                       || file_stream->pos.content_size == 0) {
-               /* More events may come. */
-               ret = NULL;
-               if (flags)
-                       *flags |= BT_ITER_FLAG_RETRY;
-               goto end;
-       }
-
-       stream = &file_stream->parent;
-       if (iter->parent.end_pos &&
-               iter->parent.end_pos->type == BT_SEEK_TIME &&
-               stream->real_timestamp > iter->parent.end_pos->u.seek_time) {
-               goto stop;
-       }
-       ret->parent = g_ptr_array_index(stream->events_by_id,
-                       stream->event_id);
-
-       if (!file_stream->pos.packet_index)
-               packet_index = NULL;
-       else
-               packet_index = &g_array_index(file_stream->pos.packet_index,
-                               struct packet_index, file_stream->pos.cur_index);
-       iter->events_lost = 0;
-       if (packet_index && packet_index->events_discarded >
-                       file_stream->pos.last_events_discarded) {
-               if (flags)
-                       *flags |= BT_ITER_FLAG_LOST_EVENTS;
-               iter->events_lost += packet_index->events_discarded -
-                       file_stream->pos.last_events_discarded;
-               file_stream->pos.last_events_discarded =
-                       packet_index->events_discarded;
-       }
-
-       if (ret->parent->stream->stream_id > iter->callbacks->len)
-               goto end;
-
-       process_callbacks(iter, ret->parent->stream);
-
-end:
-       return ret;
-stop:
-       return NULL;
-}
-
-struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
-{
-       return bt_ctf_iter_read_event_flags(iter, NULL);
-}
-
-uint64_t bt_ctf_get_lost_events_count(struct bt_ctf_iter *iter)
-{
-       if (!iter)
-               return -1ULL;
-
-       return iter->events_lost;
-}
diff --git a/formats/ctf/metadata/Makefile.am b/formats/ctf/metadata/Makefile.am
deleted file mode 100644 (file)
index cc67e9e..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include \
-               -I$(srcdir)
-BUILT_SOURCES = ctf-parser.h
-AM_YFLAGS = -t -d -v
-
-noinst_LTLIBRARIES = libctf-parser.la libctf-ast.la
-
-noinst_HEADERS = \
-       ctf-scanner.h \
-       ctf-ast.h \
-       ctf-scanner-symbols.h \
-       objstack.h
-
-libctf_parser_la_SOURCES = ctf-lexer.l ctf-parser.y objstack.c
-# ctf-scanner-symbols.h is included to prefix generated yy_* symbols
-# with bt_.
-libctf_parser_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir) \
-               -include $(srcdir)/ctf-scanner-symbols.h
-
-libctf_ast_la_CFLAGS = $(AM_CFLAGS) -I$(builddir)
-libctf_ast_la_SOURCES = ctf-visitor-xml.c \
-               ctf-visitor-parent-links.c \
-               ctf-visitor-semantic-validator.c \
-               ctf-visitor-generate-io-struct.c
-libctf_ast_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
-
-if BABELTRACE_BUILD_WITH_LIBUUID
-libctf_ast_la_LIBADD += -luuid
-endif
-if BABELTRACE_BUILD_WITH_LIBC_UUID
-libctf_ast_la_LIBADD += -lc
-endif
-if BABELTRACE_BUILD_WITH_MINGW
-libctf_ast_la_LIBADD += -lrpcrt4 -lintl -liconv -lole32 -lpopt
-endif
-
-noinst_PROGRAMS = ctf-parser-test
-ctf_parser_test_SOURCES = ctf-parser-test.c
-ctf_parser_test_CFLAGS = $(AM_CFLAGS) -I$(builddir)
-ctf_parser_test_LDADD = \
-               libctf-parser.la \
-               libctf-ast.la
-
-CLEANFILES = ctf-lexer.c ctf-parser.c ctf-parser.h ctf-parser.output
diff --git a/formats/ctf/metadata/ctf-ast.h b/formats/ctf/metadata/ctf-ast.h
deleted file mode 100644 (file)
index 2ba6e86..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-#ifndef _CTF_AST_H
-#define _CTF_AST_H
-
-/*
- * ctf-ast.h
- *
- * Copyright 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@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.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <glib.h>
-#include <babeltrace/list.h>
-
-// the parameter name (of the reentrant 'yyparse' function)
-// data is a pointer to a 'SParserParam' structure
-//#define YYPARSE_PARAM        scanner
-
-struct ctf_node;
-struct ctf_parser;
-
-#define FOREACH_CTF_NODES(F) \
-       F(NODE_UNKNOWN) \
-       F(NODE_ROOT) \
-       F(NODE_ERROR) \
-       F(NODE_EVENT) \
-       F(NODE_STREAM) \
-       F(NODE_ENV) \
-       F(NODE_TRACE) \
-       F(NODE_CLOCK) \
-       F(NODE_CALLSITE) \
-       F(NODE_CTF_EXPRESSION) \
-       F(NODE_UNARY_EXPRESSION) \
-       F(NODE_TYPEDEF) \
-       F(NODE_TYPEALIAS_TARGET) \
-       F(NODE_TYPEALIAS_ALIAS) \
-       F(NODE_TYPEALIAS) \
-       F(NODE_TYPE_SPECIFIER) \
-       F(NODE_TYPE_SPECIFIER_LIST) \
-       F(NODE_POINTER) \
-       F(NODE_TYPE_DECLARATOR) \
-       F(NODE_FLOATING_POINT) \
-       F(NODE_INTEGER) \
-       F(NODE_STRING) \
-       F(NODE_ENUMERATOR) \
-       F(NODE_ENUM) \
-       F(NODE_STRUCT_OR_VARIANT_DECLARATION) \
-       F(NODE_VARIANT) \
-       F(NODE_STRUCT)
-
-enum node_type {
-#define ENTRY(S)       S,
-       FOREACH_CTF_NODES(ENTRY)
-#undef ENTRY
-       NR_NODE_TYPES,
-};
-
-struct ctf_node {
-       /*
-        * Parent node is only set on demand by specific visitor.
-        */
-       struct ctf_node *parent;
-       struct bt_list_head siblings;
-       struct bt_list_head tmp_head;
-       unsigned int lineno;
-       /*
-        * We mark nodes visited in the generate-io-struct phase (last
-        * phase). We only mark the 1-depth level nodes as visited
-        * (never the root node, and not their sub-nodes). This allows
-        * skipping already visited nodes when doing incremental
-        * metadata append.
-        */
-       int visited;
-
-       enum node_type type;
-       union {
-               struct {
-               } unknown;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-                       struct bt_list_head trace;
-                       struct bt_list_head env;
-                       struct bt_list_head stream;
-                       struct bt_list_head event;
-                       struct bt_list_head clock;
-                       struct bt_list_head callsite;
-               } root;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } event;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } stream;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } env;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } trace;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } clock;
-               struct {
-                       /*
-                        * Children nodes are ctf_expression, typedef,
-                        * typealias and type_specifier_list.
-                        */
-                       struct bt_list_head declaration_list;
-               } callsite;
-               struct {
-                       struct bt_list_head left;       /* Should be string */
-                       struct bt_list_head right;      /* Unary exp. or type */
-               } ctf_expression;
-               struct {
-                       enum {
-                               UNARY_UNKNOWN = 0,
-                               UNARY_STRING,
-                               UNARY_SIGNED_CONSTANT,
-                               UNARY_UNSIGNED_CONSTANT,
-                               UNARY_SBRAC,
-                       } type;
-                       union {
-                               /*
-                                * string for identifier, id_type, keywords,
-                                * string literals and character constants.
-                                */
-                               char *string;
-                               int64_t signed_constant;
-                               uint64_t unsigned_constant;
-                               struct ctf_node *sbrac_exp;
-                       } u;
-                       enum {
-                               UNARY_LINK_UNKNOWN = 0,
-                               UNARY_DOTLINK,
-                               UNARY_ARROWLINK,
-                               UNARY_DOTDOTDOT,
-                       } link;
-               } unary_expression;
-               struct {
-                       struct ctf_node *type_specifier_list;
-                       struct bt_list_head type_declarators;
-               } _typedef;
-               /* new type is "alias", existing type "target" */
-               struct {
-                       struct ctf_node *type_specifier_list;
-                       struct bt_list_head type_declarators;
-               } typealias_target;
-               struct {
-                       struct ctf_node *type_specifier_list;
-                       struct bt_list_head type_declarators;
-               } typealias_alias;
-               struct {
-                       struct ctf_node *target;
-                       struct ctf_node *alias;
-               } typealias;
-               struct {
-                       enum {
-                               TYPESPEC_UNKNOWN = 0,
-                               TYPESPEC_VOID,
-                               TYPESPEC_CHAR,
-                               TYPESPEC_SHORT,
-                               TYPESPEC_INT,
-                               TYPESPEC_LONG,
-                               TYPESPEC_FLOAT,
-                               TYPESPEC_DOUBLE,
-                               TYPESPEC_SIGNED,
-                               TYPESPEC_UNSIGNED,
-                               TYPESPEC_BOOL,
-                               TYPESPEC_COMPLEX,
-                               TYPESPEC_IMAGINARY,
-                               TYPESPEC_CONST,
-                               TYPESPEC_ID_TYPE,
-                               TYPESPEC_FLOATING_POINT,
-                               TYPESPEC_INTEGER,
-                               TYPESPEC_STRING,
-                               TYPESPEC_STRUCT,
-                               TYPESPEC_VARIANT,
-                               TYPESPEC_ENUM,
-                       } type;
-                       /* For struct, variant and enum */
-                       struct ctf_node *node;
-                       const char *id_type;
-               } type_specifier;
-               struct {
-                       /* list of type_specifier */
-                       struct bt_list_head head;
-               } type_specifier_list;
-               struct {
-                       unsigned int const_qualifier;
-               } pointer;
-               struct {
-                       struct bt_list_head pointers;
-                       enum {
-                               TYPEDEC_UNKNOWN = 0,
-                               TYPEDEC_ID,     /* identifier */
-                               TYPEDEC_NESTED, /* (), array or sequence */
-                       } type;
-                       union {
-                               char *id;
-                               struct {
-                                       /* typedec has no pointer list */
-                                       struct ctf_node *type_declarator;
-                                       /*
-                                        * unary expression (value) or
-                                        * type_specifier_list.
-                                        */
-                                       struct bt_list_head length;
-                                       /* for abstract type declarator */
-                                       unsigned int abstract_array;
-                               } nested;
-                       } u;
-                       struct ctf_node *bitfield_len;
-               } type_declarator;
-               struct {
-                       /* Children nodes are ctf_expression. */
-                       struct bt_list_head expressions;
-               } floating_point;
-               struct {
-                       /* Children nodes are ctf_expression. */
-                       struct bt_list_head expressions;
-               } integer;
-               struct {
-                       /* Children nodes are ctf_expression. */
-                       struct bt_list_head expressions;
-               } string;
-               struct {
-                       char *id;
-                       /*
-                        * Range list or single value node. Contains unary
-                        * expressions.
-                        */
-                       struct bt_list_head values;
-               } enumerator;
-               struct {
-                       char *enum_id;
-                       /*
-                        * Either NULL, or points to unary expression or
-                        * type_specifier_list.
-                        */
-                       struct ctf_node *container_type;
-                       struct bt_list_head enumerator_list;
-                       int has_body;
-               } _enum;
-               struct {
-                       struct ctf_node *type_specifier_list;
-                       struct bt_list_head type_declarators;
-               } struct_or_variant_declaration;
-               struct {
-                       char *name;
-                       char *choice;
-                       /* list of typedef, typealias and declarations */
-                       struct bt_list_head declaration_list;
-                       int has_body;
-               } variant;
-               struct {
-                       char *name;
-                       /* list of typedef, typealias and declarations */
-                       struct bt_list_head declaration_list;
-                       int has_body;
-                       struct bt_list_head min_align;  /* align() attribute */
-               } _struct;
-       } u;
-};
-
-struct ctf_ast {
-       struct ctf_node root;
-};
-
-const char *node_type(struct ctf_node *node);
-
-struct ctf_trace;
-
-BT_HIDDEN
-int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node);
-BT_HIDDEN
-int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node);
-BT_HIDDEN
-int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node);
-BT_HIDDEN
-int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
-                       struct ctf_trace *trace, int byte_order);
-BT_HIDDEN
-int ctf_destroy_metadata(struct ctf_trace *trace);
-
-#endif /* _CTF_AST_H */
diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l
deleted file mode 100644 (file)
index 6b605a0..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-%{
-/*
- * ctf-lexer.l
- *
- * Common Trace Formal Lexer
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <ctype.h>
-#include <babeltrace/babeltrace-internal.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-#define PARSE_INTEGER_LITERAL(base)                                    \
-       do {                                                            \
-               errno = 0;                                              \
-               yylval->ull = strtoull(yytext, NULL, base);             \
-               if (errno) {                                            \
-                       printfl_perror(yylineno, "Integer literal");    \
-                       return ERROR;                                   \
-               }                                                       \
-       } while (0)
-
-BT_HIDDEN
-void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src);
-
-static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
-       __attribute__((unused));
-static int input (yyscan_t yyscanner) __attribute__((unused));
-
-BT_HIDDEN
-int import_string(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src, char delim);
-
-%}
-
-%x comment_ml comment_sl string_lit char_const
-%option reentrant yylineno noyywrap bison-bridge
-%option extra-type="struct ctf_scanner *"
-       /* bison-locations */
-INTEGER_SUFFIX                 (U|UL|ULL|LU|LLU|Ul|Ull|lU|llU|u|uL|uLL|Lu|LLu|ul|ull|lu|llu)
-DIGIT                          [0-9]
-NONDIGIT                       [a-zA-Z_]
-HEXDIGIT                       [0-9A-Fa-f]
-OCTALDIGIT                     [0-7]
-UCHARLOWERCASE                 \\u{HEXDIGIT}{4}
-UCHARUPPERCASE                 \\U{HEXDIGIT}{8}
-ID_NONDIGIT                    {NONDIGIT}|{UCHARLOWERCASE}|{UCHARUPPERCASE}
-IDENTIFIER                     {ID_NONDIGIT}({ID_NONDIGIT}|{DIGIT})*
-%%
-
-                               /*
-                                * Using start conditions to deal with comments
-                                * and strings.
-                                */ 
-
-"/*"                           BEGIN(comment_ml);
-<comment_ml>[^*\n]*            /* eat anything that's not a '*' */
-<comment_ml>"*"+[^*/\n]*       /* eat up '*'s not followed by '/'s */
-<comment_ml>\n
-<comment_ml>"*"+"/"            BEGIN(INITIAL);
-
-"//"[^\n]*\n                   /* skip comment */
-
-L?\"(\\.|[^\\"])*\"            { if (import_string(yyextra, yylval, yytext, '\"') < 0) return ERROR; else return STRING_LITERAL; }
-L?\'(\\.|[^\\'])*\'            { if (import_string(yyextra, yylval, yytext, '\'') < 0) return ERROR; else return CHARACTER_LITERAL; }
-
-"["                            return LSBRAC;
-"]"                            return RSBRAC;
-"("                            return LPAREN;
-")"                            return RPAREN;
-"{"                            return LBRAC;
-"}"                            return RBRAC;
-"->"                           return RARROW;
-"*"                            return STAR;
-"+"                            return PLUS;
-"-"                            return MINUS;
-"<"                            return LT;
-">"                            return GT;
-:=                             return TYPEASSIGN;
-:                              return COLON;
-;                              return SEMICOLON;
-"..."                          return DOTDOTDOT;
-"."                            return DOT;
-=                              return EQUAL;
-","                            return COMMA;
-align                          setstring(yyextra, yylval, yytext); return TOK_ALIGN;
-const                          setstring(yyextra, yylval, yytext); return CONST;
-char                           setstring(yyextra, yylval, yytext); return CHAR;
-clock                          setstring(yyextra, yylval, yytext); return CLOCK;
-double                         setstring(yyextra, yylval, yytext); return DOUBLE;
-enum                           setstring(yyextra, yylval, yytext); return ENUM;
-env                            setstring(yyextra, yylval, yytext); return ENV;
-event                          setstring(yyextra, yylval, yytext); return EVENT;
-floating_point                 setstring(yyextra, yylval, yytext); return FLOATING_POINT;
-float                          setstring(yyextra, yylval, yytext); return FLOAT;
-integer                                setstring(yyextra, yylval, yytext); return INTEGER;
-int                            setstring(yyextra, yylval, yytext); return INT;
-long                           setstring(yyextra, yylval, yytext); return LONG;
-short                          setstring(yyextra, yylval, yytext); return SHORT;
-signed                         setstring(yyextra, yylval, yytext); return SIGNED;
-stream                         setstring(yyextra, yylval, yytext); return STREAM;
-string                         setstring(yyextra, yylval, yytext); return STRING;
-struct                         setstring(yyextra, yylval, yytext); return STRUCT;
-trace                          setstring(yyextra, yylval, yytext); return TRACE;
-callsite                       setstring(yyextra, yylval, yytext); return CALLSITE;
-typealias                      setstring(yyextra, yylval, yytext); return TYPEALIAS;
-typedef                                setstring(yyextra, yylval, yytext); return TYPEDEF;
-unsigned                       setstring(yyextra, yylval, yytext); return UNSIGNED;
-variant                                setstring(yyextra, yylval, yytext); return VARIANT;
-void                           setstring(yyextra, yylval, yytext); return VOID;
-_Bool                          setstring(yyextra, yylval, yytext); return _BOOL;
-_Complex                       setstring(yyextra, yylval, yytext); return _COMPLEX;
-_Imaginary                     setstring(yyextra, yylval, yytext); return _IMAGINARY;
-[1-9]{DIGIT}*{INTEGER_SUFFIX}? PARSE_INTEGER_LITERAL(10); return INTEGER_LITERAL;
-0{OCTALDIGIT}*{INTEGER_SUFFIX}?        PARSE_INTEGER_LITERAL(8); return INTEGER_LITERAL;
-0[xX]{HEXDIGIT}+{INTEGER_SUFFIX}?      PARSE_INTEGER_LITERAL(16); return INTEGER_LITERAL;
-
-{IDENTIFIER}                   printf_debug("<IDENTIFIER %s>\n", yytext); setstring(yyextra, yylval, yytext); if (is_type(yyextra, yytext)) return ID_TYPE; else return IDENTIFIER;
-[ \t\r\n]                      ; /* ignore */
-.                              printfl_error(yylineno, "invalid character '0x%02X'", yytext[0]);  return ERROR;
-%%
diff --git a/formats/ctf/metadata/ctf-parser-test.c b/formats/ctf/metadata/ctf-parser-test.c
deleted file mode 100644 (file)
index fed85f1..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * ctf-parser-test.c
- *
- * Common Trace Format Parser Test
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdlib.h>
-#include <stdio.h>
-#include <glib.h>
-#include <errno.h>
-#include <babeltrace/endian.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/metadata.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-bool babeltrace_verbose, babeltrace_debug;
-
-int main(int argc, char **argv)
-{
-       struct ctf_scanner *scanner;
-       struct ctf_trace *trace;
-       int ret = 0;
-
-       babeltrace_debug = 1;
-       babeltrace_verbose = 1;
-       scanner = ctf_scanner_alloc();
-       if (!scanner) {
-               fprintf(stderr, "Error allocating scanner\n");
-               return -ENOMEM;
-       }
-       ret = ctf_scanner_append_ast(scanner, stdin);
-       if (ret) {
-               fprintf(stderr, "Error creating AST\n");
-               goto end;
-       }
-
-       ret = ctf_visitor_print_xml(stderr, 0, &scanner->ast->root);
-       if (ret) {
-               fprintf(stderr, "Error visiting AST for XML output\n");
-               goto end;
-       }
-
-       ret = ctf_visitor_semantic_check(stderr, 0, &scanner->ast->root);
-       if (ret) {
-               fprintf(stderr, "Error in CTF semantic validation %d\n", ret);
-               goto end;
-       }
-       trace = malloc(sizeof(*trace));
-       memset(trace, 0, sizeof(*trace));
-       ret = ctf_visitor_construct_metadata(stderr, 0, &scanner->ast->root,
-                       trace, BYTE_ORDER);
-       if (ret) {
-               fprintf(stderr, "Error in CTF metadata constructor %d\n", ret);
-               goto free_trace;
-       }
-free_trace:
-       free(trace);
-end:
-       ctf_scanner_free(scanner);
-       return ret;
-} 
diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y
deleted file mode 100644 (file)
index d0866ff..0000000
+++ /dev/null
@@ -1,2586 +0,0 @@
-%{
-/*
- * ctf-parser.y
- *
- * Common Trace Format Metadata Grammar.
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <glib.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <babeltrace/list.h>
-#include <babeltrace/babeltrace-internal.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-#include "objstack.h"
-
-BT_HIDDEN
-int yydebug;
-
-/* Join two lists, put "add" at the end of "head".  */
-static inline void
-_bt_list_splice_tail (struct bt_list_head *add, struct bt_list_head *head)
-{
-       /* Do nothing if the list which gets added is empty.  */
-       if (add != add->next) {
-               add->next->prev = head->prev;
-               add->prev->next = head;
-               head->prev->next = add->next;
-               head->prev = add->prev;
-       }
-}
-
-BT_HIDDEN
-int yyparse(struct ctf_scanner *scanner, yyscan_t yyscanner);
-BT_HIDDEN
-int yylex(union YYSTYPE *yyval, yyscan_t yyscanner);
-BT_HIDDEN
-int yylex_init_extra(struct ctf_scanner *scanner, yyscan_t * ptr_yy_globals);
-BT_HIDDEN
-int yylex_destroy(yyscan_t yyscanner);
-BT_HIDDEN
-void yyrestart(FILE * in_str, yyscan_t yyscanner);
-BT_HIDDEN
-int yyget_lineno(yyscan_t yyscanner);
-BT_HIDDEN
-char *yyget_text(yyscan_t yyscanner);
-
-static const char *node_type_to_str[] = {
-#define ENTRY(S)       [S] = #S,
-       FOREACH_CTF_NODES(ENTRY)
-#undef ENTRY
-};
-
-/*
- * Static node for out of memory errors. Only "type" is used. lineno is
- * always left at 0. The rest of the node content can be overwritten,
- * but is never used.
- */
-static struct ctf_node error_node = {
-       .type = NODE_ERROR,
-};
-
-BT_HIDDEN
-const char *node_type(struct ctf_node *node)
-{
-       if (node->type < NR_NODE_TYPES)
-               return node_type_to_str[node->type];
-       else
-               return NULL;
-}
-
-void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src)
-{
-       lvalp->s = objstack_alloc(scanner->objstack, strlen(src) + 1);
-       strcpy(lvalp->s, src);
-}
-
-static
-int str_check(size_t str_len, size_t offset, size_t len)
-{
-       /* check overflow */
-       if (offset + len < offset)
-               return -1;
-       if (offset + len > str_len)
-               return -1;
-       return 0;
-}
-
-static
-int bt_isodigit(int c)
-{
-       switch (c) {
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-               return 1;
-       default:
-               return 0;
-       }
-}
-
-static
-int parse_base_sequence(const char *src, size_t len, size_t pos,
-               char *buffer, size_t *buf_len, int base)
-{
-       const size_t max_char = 3;
-       int nr_char = 0;
-
-       while (!str_check(len, pos, 1) && nr_char < max_char) {
-               char c = src[pos++];
-
-               if (base == 8) {
-                       if (bt_isodigit(c))
-                               buffer[nr_char++] = c;
-                       else
-                               break;
-               } else if (base == 16) {
-                       if (isxdigit(c))
-                               buffer[nr_char++] = c;
-                       else
-                               break;
-
-               } else {
-                       /* Unsupported base */
-                       return -1;
-               }
-       }
-       assert(nr_char > 0);
-       buffer[nr_char] = '\0';
-       *buf_len = nr_char;
-       return 0;
-}
-
-static
-int import_basic_string(struct ctf_scanner *scanner, YYSTYPE *lvalp,
-               size_t len, const char *src, char delim)
-{
-       size_t pos = 0, dpos = 0;
-
-       if (str_check(len, pos, 1))
-               return -1;
-       if (src[pos++] != delim)
-               return -1;
-
-       while (src[pos] != delim) {
-               char c;
-
-               if (str_check(len, pos, 1))
-                       return -1;
-               c = src[pos++];
-               if (c == '\\') {
-                       if (str_check(len, pos, 1))
-                               return -1;
-                       c = src[pos++];
-
-                       switch (c) {
-                       case 'a':
-                               c = '\a';
-                               break;
-                       case 'b':
-                               c = '\b';
-                               break;
-                       case 'f':
-                               c = '\f';
-                               break;
-                       case 'n':
-                               c = '\n';
-                               break;
-                       case 'r':
-                               c = '\r';
-                               break;
-                       case 't':
-                               c = '\t';
-                               break;
-                       case 'v':
-                               c = '\v';
-                               break;
-                       case '\\':
-                               c = '\\';
-                               break;
-                       case '\'':
-                               c = '\'';
-                               break;
-                       case '\"':
-                               c = '\"';
-                               break;
-                       case '?':
-                               c = '?';
-                               break;
-                       case '0':
-                       case '1':
-                       case '2':
-                       case '3':
-                       case '4':
-                       case '5':
-                       case '6':
-                       case '7':
-                       {
-                               char oct_buffer[4];
-                               size_t oct_len;
-
-                               if (parse_base_sequence(src, len, pos - 1,
-                                               oct_buffer, &oct_len, 8))
-                                       return -1;
-                               c = strtoul(&oct_buffer[0], NULL, 8);
-                               pos += oct_len - 1;
-                               break;
-                       }
-                       case 'x':
-                       {
-                               char hex_buffer[4];
-                               size_t hex_len;
-
-                               if (parse_base_sequence(src, len, pos,
-                                               hex_buffer, &hex_len, 16))
-                                       return -1;
-                               c = strtoul(&hex_buffer[0], NULL, 16);
-                               pos += hex_len;
-                               break;
-                       }
-                       default:
-                               return -1;
-                       }
-               }
-               if (str_check(len, dpos, 1))
-                       return -1;
-               lvalp->s[dpos++] = c;
-       }
-
-       if (str_check(len, dpos, 1))
-               return -1;
-       lvalp->s[dpos++] = '\0';
-
-       if (str_check(len, pos, 1))
-               return -1;
-       if (src[pos++] != delim)
-               return -1;
-
-       if (str_check(len, pos, 1))
-               return -1;
-       if (src[pos] != '\0')
-               return -1;
-       return 0;
-}
-
-int import_string(struct ctf_scanner *scanner, YYSTYPE *lvalp,
-               const char *src, char delim)
-{
-       size_t len;
-
-       len = strlen(src) + 1;
-       lvalp->s = objstack_alloc(scanner->objstack, len);
-       if (src[0] == 'L') {
-               // TODO: import wide string
-               printfl_error(yyget_lineno(scanner),
-                       "Wide string not supported yet.");
-               return -1;
-       } else {
-               return import_basic_string(scanner, lvalp, len, src, delim);
-       }
-}
-
-static void init_scope(struct ctf_scanner_scope *scope,
-                      struct ctf_scanner_scope *parent)
-{
-       scope->parent = parent;
-       scope->types = g_hash_table_new_full(g_str_hash, g_str_equal,
-                                            NULL, NULL);
-}
-
-static void finalize_scope(struct ctf_scanner_scope *scope)
-{
-       g_hash_table_destroy(scope->types);
-}
-
-static void push_scope(struct ctf_scanner *scanner)
-{
-       struct ctf_scanner_scope *ns;
-
-       printf_debug("push scope\n");
-       ns = malloc(sizeof(struct ctf_scanner_scope));
-       init_scope(ns, scanner->cs);
-       scanner->cs = ns;
-}
-
-static void pop_scope(struct ctf_scanner *scanner)
-{
-       struct ctf_scanner_scope *os;
-
-       printf_debug("pop scope\n");
-       os = scanner->cs;
-       scanner->cs = os->parent;
-       finalize_scope(os);
-       free(os);
-}
-
-static int lookup_type(struct ctf_scanner_scope *s, const char *id)
-{
-       int ret;
-
-       ret = GPOINTER_TO_INT(g_hash_table_lookup(s->types, id));
-       printf_debug("lookup %p %s %d\n", s, id, ret);
-       return ret;
-}
-
-BT_HIDDEN
-int is_type(struct ctf_scanner *scanner, const char *id)
-{
-       struct ctf_scanner_scope *it;
-       int ret = 0;
-
-       for (it = scanner->cs; it != NULL; it = it->parent) {
-               if (lookup_type(it, id)) {
-                       ret = 1;
-                       break;
-               }
-       }
-       printf_debug("is type %s %d\n", id, ret);
-       return ret;
-}
-
-static void add_type(struct ctf_scanner *scanner, char *id)
-{
-       printf_debug("add type %s\n", id);
-       if (lookup_type(scanner->cs, id))
-               return;
-       g_hash_table_insert(scanner->cs->types, id, id);
-}
-
-static struct ctf_node *make_node(struct ctf_scanner *scanner,
-                                 enum node_type type)
-{
-       struct ctf_node *node;
-
-       node = objstack_alloc(scanner->objstack, sizeof(*node));
-       if (!node) {
-               printfl_fatal(yyget_lineno(scanner->scanner), "out of memory");
-               return &error_node;
-       }
-       node->type = type;
-       node->lineno = yyget_lineno(scanner->scanner);
-       BT_INIT_LIST_HEAD(&node->tmp_head);
-       bt_list_add(&node->siblings, &node->tmp_head);
-
-       switch (type) {
-       case NODE_ROOT:
-               node->type = NODE_ERROR;
-               printfn_fatal(node, "trying to create root node");
-               break;
-
-       case NODE_EVENT:
-               BT_INIT_LIST_HEAD(&node->u.event.declaration_list);
-               break;
-       case NODE_STREAM:
-               BT_INIT_LIST_HEAD(&node->u.stream.declaration_list);
-               break;
-       case NODE_ENV:
-               BT_INIT_LIST_HEAD(&node->u.env.declaration_list);
-               break;
-       case NODE_TRACE:
-               BT_INIT_LIST_HEAD(&node->u.trace.declaration_list);
-               break;
-       case NODE_CLOCK:
-               BT_INIT_LIST_HEAD(&node->u.clock.declaration_list);
-               break;
-       case NODE_CALLSITE:
-               BT_INIT_LIST_HEAD(&node->u.callsite.declaration_list);
-               break;
-
-       case NODE_CTF_EXPRESSION:
-               BT_INIT_LIST_HEAD(&node->u.ctf_expression.left);
-               BT_INIT_LIST_HEAD(&node->u.ctf_expression.right);
-               break;
-       case NODE_UNARY_EXPRESSION:
-               break;
-
-       case NODE_TYPEDEF:
-               BT_INIT_LIST_HEAD(&node->u._typedef.type_declarators);
-               break;
-       case NODE_TYPEALIAS_TARGET:
-               BT_INIT_LIST_HEAD(&node->u.typealias_target.type_declarators);
-               break;
-       case NODE_TYPEALIAS_ALIAS:
-               BT_INIT_LIST_HEAD(&node->u.typealias_alias.type_declarators);
-               break;
-       case NODE_TYPEALIAS:
-               break;
-
-       case NODE_TYPE_SPECIFIER:
-               break;
-       case NODE_TYPE_SPECIFIER_LIST:
-               BT_INIT_LIST_HEAD(&node->u.type_specifier_list.head);
-               break;
-       case NODE_POINTER:
-               break;
-       case NODE_TYPE_DECLARATOR:
-               BT_INIT_LIST_HEAD(&node->u.type_declarator.pointers);
-               break;
-
-       case NODE_FLOATING_POINT:
-               BT_INIT_LIST_HEAD(&node->u.floating_point.expressions);
-               break;
-       case NODE_INTEGER:
-               BT_INIT_LIST_HEAD(&node->u.integer.expressions);
-               break;
-       case NODE_STRING:
-               BT_INIT_LIST_HEAD(&node->u.string.expressions);
-               break;
-       case NODE_ENUMERATOR:
-               BT_INIT_LIST_HEAD(&node->u.enumerator.values);
-               break;
-       case NODE_ENUM:
-               BT_INIT_LIST_HEAD(&node->u._enum.enumerator_list);
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               BT_INIT_LIST_HEAD(&node->u.struct_or_variant_declaration.type_declarators);
-               break;
-       case NODE_VARIANT:
-               BT_INIT_LIST_HEAD(&node->u.variant.declaration_list);
-               break;
-       case NODE_STRUCT:
-               BT_INIT_LIST_HEAD(&node->u._struct.declaration_list);
-               BT_INIT_LIST_HEAD(&node->u._struct.min_align);
-               break;
-
-       case NODE_UNKNOWN:
-       default:
-               node->type = NODE_ERROR;
-               printfn_fatal(node, "unknown node type '%d'", (int) type);
-               break;
-       }
-
-       return node;
-}
-
-static int reparent_ctf_expression(struct ctf_node *node,
-                                  struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_EVENT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
-               break;
-       case NODE_STREAM:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
-               break;
-       case NODE_ENV:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.env.declaration_list);
-               break;
-       case NODE_TRACE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
-               break;
-       case NODE_CLOCK:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
-               break;
-       case NODE_CALLSITE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
-               break;
-       case NODE_FLOATING_POINT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.floating_point.expressions);
-               break;
-       case NODE_INTEGER:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.integer.expressions);
-               break;
-       case NODE_STRING:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.string.expressions);
-               break;
-
-       case NODE_ROOT:
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPE_SPECIFIER_LIST:
-       case NODE_POINTER:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_ENUMERATOR:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_ROOT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.root.declaration_list);
-               break;
-       case NODE_EVENT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
-               break;
-       case NODE_STREAM:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
-               break;
-       case NODE_ENV:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.env.declaration_list);
-               break;
-       case NODE_TRACE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
-               break;
-       case NODE_CLOCK:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
-               break;
-       case NODE_CALLSITE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
-               break;
-       case NODE_VARIANT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
-               break;
-       case NODE_STRUCT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
-               break;
-
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPE_SPECIFIER_LIST:
-       case NODE_POINTER:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_ENUMERATOR:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type %d", parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_ROOT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.root.declaration_list);
-               break;
-       case NODE_EVENT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.event.declaration_list);
-               break;
-       case NODE_STREAM:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.stream.declaration_list);
-               break;
-       case NODE_ENV:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.env.declaration_list);
-               break;
-       case NODE_TRACE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.trace.declaration_list);
-               break;
-       case NODE_CLOCK:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list);
-               break;
-       case NODE_CALLSITE:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list);
-               break;
-       case NODE_VARIANT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
-               break;
-       case NODE_STRUCT:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
-               break;
-
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPE_SPECIFIER_LIST:
-       case NODE_POINTER:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_ENUMERATOR:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int reparent_type_specifier(struct ctf_node *node,
-                                  struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_TYPE_SPECIFIER_LIST:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.type_specifier_list.head);
-               break;
-
-       case NODE_TYPE_SPECIFIER:
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_TYPEALIAS:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_CTF_EXPRESSION:
-       case NODE_POINTER:
-       case NODE_ENUMERATOR:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int reparent_type_specifier_list(struct ctf_node *node,
-                                       struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_ROOT:
-               bt_list_add_tail(&node->siblings, &parent->u.root.declaration_list);
-               break;
-       case NODE_EVENT:
-               bt_list_add_tail(&node->siblings, &parent->u.event.declaration_list);
-               break;
-       case NODE_STREAM:
-               bt_list_add_tail(&node->siblings, &parent->u.stream.declaration_list);
-               break;
-       case NODE_ENV:
-               bt_list_add_tail(&node->siblings, &parent->u.env.declaration_list);
-               break;
-       case NODE_TRACE:
-               bt_list_add_tail(&node->siblings, &parent->u.trace.declaration_list);
-               break;
-       case NODE_CLOCK:
-               bt_list_add_tail(&node->siblings, &parent->u.clock.declaration_list);
-               break;
-       case NODE_CALLSITE:
-               bt_list_add_tail(&node->siblings, &parent->u.callsite.declaration_list);
-               break;
-       case NODE_VARIANT:
-               bt_list_add_tail(&node->siblings, &parent->u.variant.declaration_list);
-               break;
-       case NODE_STRUCT:
-               bt_list_add_tail(&node->siblings, &parent->u._struct.declaration_list);
-               break;
-       case NODE_TYPEDEF:
-               parent->u._typedef.type_specifier_list = node;
-               break;
-       case NODE_TYPEALIAS_TARGET:
-               parent->u.typealias_target.type_specifier_list = node;
-               break;
-       case NODE_TYPEALIAS_ALIAS:
-               parent->u.typealias_alias.type_specifier_list = node;
-               break;
-       case NODE_ENUM:
-               parent->u._enum.container_type = node;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               parent->u.struct_or_variant_declaration.type_specifier_list = node;
-               break;
-       case NODE_TYPE_DECLARATOR:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPEALIAS:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_CTF_EXPRESSION:
-       case NODE_POINTER:
-       case NODE_ENUMERATOR:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int reparent_type_declarator(struct ctf_node *node,
-                                   struct ctf_node *parent)
-{
-       switch (parent->type) {
-       case NODE_TYPE_DECLARATOR:
-               parent->u.type_declarator.type = TYPEDEC_NESTED;
-               parent->u.type_declarator.u.nested.type_declarator = node;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.struct_or_variant_declaration.type_declarators);
-               break;
-       case NODE_TYPEDEF:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u._typedef.type_declarators);
-               break;
-       case NODE_TYPEALIAS_TARGET:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.typealias_target.type_declarators);
-               break;
-       case NODE_TYPEALIAS_ALIAS:
-               _bt_list_splice_tail(&node->tmp_head, &parent->u.typealias_alias.type_declarators);
-               break;
-
-       case NODE_ROOT:
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       case NODE_TYPEALIAS:
-       case NODE_ENUM:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPE_SPECIFIER_LIST:
-       case NODE_POINTER:
-       case NODE_ENUMERATOR:
-       case NODE_UNARY_EXPRESSION:
-               return -EPERM;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-/*
- * set_parent_node
- *
- * Link node to parent. Returns 0 on success, -EPERM if it is not permitted to
- * create the link declared by the input, -ENOENT if node or parent is NULL,
- * -EINVAL if there is an internal structure problem.
- */
-static int set_parent_node(struct ctf_node *node,
-                        struct ctf_node *parent)
-{
-       if (!node || !parent)
-               return -ENOENT;
-
-       /* Note: Linking to parent will be done only by an external visitor */
-
-       switch (node->type) {
-       case NODE_ROOT:
-               printfn_fatal(node, "trying to reparent root node");
-               return -EINVAL;
-
-       case NODE_EVENT:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.event);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_STREAM:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.stream);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_ENV:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.env);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_TRACE:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.trace);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_CLOCK:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.clock);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_CALLSITE:
-               if (parent->type == NODE_ROOT) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.root.callsite);
-               } else {
-                       return -EPERM;
-               }
-               break;
-
-       case NODE_CTF_EXPRESSION:
-               return reparent_ctf_expression(node, parent);
-       case NODE_UNARY_EXPRESSION:
-               if (parent->type == NODE_TYPE_DECLARATOR)
-                       parent->u.type_declarator.bitfield_len = node;
-               else
-                       return -EPERM;
-               break;
-
-       case NODE_TYPEDEF:
-               return reparent_typedef(node, parent);
-       case NODE_TYPEALIAS_TARGET:
-               if (parent->type == NODE_TYPEALIAS)
-                       parent->u.typealias.target = node;
-               else
-                       return -EINVAL;
-       case NODE_TYPEALIAS_ALIAS:
-               if (parent->type == NODE_TYPEALIAS)
-                       parent->u.typealias.alias = node;
-               else
-                       return -EINVAL;
-       case NODE_TYPEALIAS:
-               return reparent_typealias(node, parent);
-
-       case NODE_POINTER:
-               if (parent->type == NODE_TYPE_DECLARATOR) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.type_declarator.pointers);
-               } else
-                       return -EPERM;
-               break;
-       case NODE_TYPE_DECLARATOR:
-               return reparent_type_declarator(node, parent);
-
-       case NODE_TYPE_SPECIFIER_LIST:
-               return reparent_type_specifier_list(node, parent);
-
-       case NODE_TYPE_SPECIFIER:
-               return reparent_type_specifier(node, parent);
-
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_ENUM:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-               return -EINVAL; /* Dealt with internally within grammar */
-
-       case NODE_ENUMERATOR:
-               if (parent->type == NODE_ENUM) {
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u._enum.enumerator_list);
-               } else {
-                       return -EPERM;
-               }
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               switch (parent->type) {
-               case NODE_STRUCT:
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u._struct.declaration_list);
-                       break;
-               case NODE_VARIANT:
-                       _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               break;
-
-       case NODE_UNKNOWN:
-       default:
-               printfn_fatal(node, "unknown node type '%d'", (int) parent->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-BT_HIDDEN
-void yyerror(struct ctf_scanner *scanner, yyscan_t yyscanner, const char *str)
-{
-       printfl_error(yyget_lineno(scanner->scanner),
-               "token \"%s\": %s\n",
-               yyget_text(scanner->scanner), str);
-}
-BT_HIDDEN
-int yywrap(void)
-{
-       return 1;
-} 
-
-#define reparent_error(scanner, str)                           \
-do {                                                           \
-       yyerror(scanner, scanner->scanner, YY_("reparent_error: " str)); \
-       YYERROR;                                                \
-} while (0)
-
-static struct ctf_ast *ctf_ast_alloc(struct ctf_scanner *scanner)
-{
-       struct ctf_ast *ast;
-
-       ast = objstack_alloc(scanner->objstack, sizeof(*ast));
-       if (!ast)
-               return NULL;
-       ast->root.type = NODE_ROOT;
-       BT_INIT_LIST_HEAD(&ast->root.tmp_head);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.declaration_list);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.trace);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.env);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.stream);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.event);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.clock);
-       BT_INIT_LIST_HEAD(&ast->root.u.root.callsite);
-       return ast;
-}
-
-int ctf_scanner_append_ast(struct ctf_scanner *scanner, FILE *input)
-{
-       /* Start processing new stream */
-       yyrestart(input, scanner->scanner);
-       if (yydebug)
-               fprintf(stdout, "Scanner input is a%s.\n",
-                       isatty(fileno(input)) ? "n interactive tty" :
-                                               " noninteractive file");
-       return yyparse(scanner, scanner->scanner);
-}
-
-struct ctf_scanner *ctf_scanner_alloc(void)
-{
-       struct ctf_scanner *scanner;
-       int ret;
-
-       yydebug = babeltrace_debug;
-
-       scanner = malloc(sizeof(*scanner));
-       if (!scanner)
-               return NULL;
-       memset(scanner, 0, sizeof(*scanner));
-       ret = yylex_init_extra(scanner, &scanner->scanner);
-       if (ret) {
-               printf_fatal("yylex_init error");
-               goto cleanup_scanner;
-       }
-       scanner->objstack = objstack_create();
-       if (!scanner->objstack)
-               goto cleanup_lexer;
-       scanner->ast = ctf_ast_alloc(scanner);
-       if (!scanner->ast)
-               goto cleanup_objstack;
-       init_scope(&scanner->root_scope, NULL);
-       scanner->cs = &scanner->root_scope;
-
-       return scanner;
-
-cleanup_objstack:
-       objstack_destroy(scanner->objstack);
-cleanup_lexer:
-       ret = yylex_destroy(scanner->scanner);
-       if (!ret)
-               printf_fatal("yylex_destroy error");
-cleanup_scanner:
-       free(scanner);
-       return NULL;
-}
-
-void ctf_scanner_free(struct ctf_scanner *scanner)
-{
-       int ret;
-
-       if (!scanner)
-               return;
-       finalize_scope(&scanner->root_scope);
-       objstack_destroy(scanner->objstack);
-       ret = yylex_destroy(scanner->scanner);
-       if (ret)
-               printf_error("yylex_destroy error");
-       free(scanner);
-}
-
-%}
-
-%define api.pure
-       /* %locations */
-%error-verbose
-%parse-param {struct ctf_scanner *scanner}
-%parse-param {yyscan_t yyscanner}
-%lex-param {yyscan_t yyscanner}
-/*
- * Expect two shift-reduce conflicts. Caused by enum name-opt : type {}
- * vs struct { int :value; } (unnamed bit-field). The default is to
- * shift, so whenever we encounter an enumeration, we are doing the
- * proper thing (shift). It is illegal to declare an enumeration
- * "bit-field", so it is OK if this situation ends up in a parsing
- * error.
- */
-%expect 2
-%start file
-%token INTEGER_LITERAL STRING_LITERAL CHARACTER_LITERAL LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CALLSITE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY TOK_ALIGN
-%token <s> IDENTIFIER ID_TYPE
-%token ERROR
-%union
-{
-       long long ll;
-       unsigned long long ull;
-       char c;
-       char *s;
-       struct ctf_node *n;
-}
-
-%type <s> STRING_LITERAL CHARACTER_LITERAL
-
-%type <s> keywords
-
-%type <ull> INTEGER_LITERAL
-%type <n> postfix_expression unary_expression unary_expression_or_range
-
-%type <n> declaration
-%type <n> event_declaration
-%type <n> stream_declaration
-%type <n> env_declaration
-%type <n> trace_declaration
-%type <n> clock_declaration
-%type <n> callsite_declaration
-%type <n> integer_declaration_specifiers
-%type <n> declaration_specifiers
-%type <n> alias_declaration_specifiers
-
-%type <n> type_declarator_list
-%type <n> integer_type_specifier
-%type <n> type_specifier
-%type <n> struct_type_specifier
-%type <n> variant_type_specifier
-%type <n> enum_type_specifier
-%type <n> struct_or_variant_declaration_list
-%type <n> struct_or_variant_declaration
-%type <n> struct_or_variant_declarator_list
-%type <n> struct_or_variant_declarator
-%type <n> enumerator_list
-%type <n> enumerator
-%type <n> abstract_declarator_list
-%type <n> abstract_declarator
-%type <n> direct_abstract_declarator
-%type <n> alias_abstract_declarator_list
-%type <n> alias_abstract_declarator
-%type <n> direct_alias_abstract_declarator
-%type <n> declarator
-%type <n> direct_declarator
-%type <n> type_declarator
-%type <n> direct_type_declarator
-%type <n> pointer      
-%type <n> ctf_assignment_expression_list
-%type <n> ctf_assignment_expression
-
-%%
-
-file:
-               declaration
-               {
-                       if (set_parent_node($1, &ctf_scanner_get_ast(scanner)->root))
-                               reparent_error(scanner, "error reparenting to root");
-               }
-       |       file declaration
-               {
-                       if (set_parent_node($2, &ctf_scanner_get_ast(scanner)->root))
-                               reparent_error(scanner, "error reparenting to root");
-               }
-       ;
-
-keywords:
-               VOID
-               {       $$ = yylval.s;          }
-       |       CHAR
-               {       $$ = yylval.s;          }
-       |       SHORT
-               {       $$ = yylval.s;          }
-       |       INT
-               {       $$ = yylval.s;          }
-       |       LONG
-               {       $$ = yylval.s;          }
-       |       FLOAT
-               {       $$ = yylval.s;          }
-       |       DOUBLE
-               {       $$ = yylval.s;          }
-       |       SIGNED
-               {       $$ = yylval.s;          }
-       |       UNSIGNED
-               {       $$ = yylval.s;          }
-       |       _BOOL
-               {       $$ = yylval.s;          }
-       |       _COMPLEX
-               {       $$ = yylval.s;          }
-       |       _IMAGINARY
-               {       $$ = yylval.s;          }
-       |       FLOATING_POINT
-               {       $$ = yylval.s;          }
-       |       INTEGER
-               {       $$ = yylval.s;          }
-       |       STRING
-               {       $$ = yylval.s;          }
-       |       ENUM
-               {       $$ = yylval.s;          }
-       |       VARIANT
-               {       $$ = yylval.s;          }
-       |       STRUCT
-               {       $$ = yylval.s;          }
-       |       CONST
-               {       $$ = yylval.s;          }
-       |       TYPEDEF
-               {       $$ = yylval.s;          }
-       |       EVENT
-               {       $$ = yylval.s;          }
-       |       STREAM
-               {       $$ = yylval.s;          }
-       |       ENV
-               {       $$ = yylval.s;          }
-       |       TRACE
-               {       $$ = yylval.s;          }
-       |       CLOCK
-               {       $$ = yylval.s;          }
-       |       CALLSITE
-               {       $$ = yylval.s;          }
-       |       TOK_ALIGN
-               {       $$ = yylval.s;          }
-       ;
-
-
-/* 2: Phrase structure grammar */
-
-postfix_expression:
-               IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-               }
-       |       keywords
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-               }
-       |       INTEGER_LITERAL
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT;
-                       $$->u.unary_expression.u.unsigned_constant = $1;
-               }
-       |       STRING_LITERAL
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = $1;
-               }
-       |       CHARACTER_LITERAL
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = $1;
-               }
-       |       LPAREN unary_expression RPAREN
-               {
-                       $$ = $2;
-               }
-       |       postfix_expression LSBRAC unary_expression RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_SBRAC;
-                       $$->u.unary_expression.u.sbrac_exp = $3;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       |       postfix_expression DOT IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-                       $$->u.unary_expression.link = UNARY_DOTLINK;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       |       postfix_expression DOT ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-                       $$->u.unary_expression.link = UNARY_DOTLINK;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       |       postfix_expression DOT keywords
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-                       $$->u.unary_expression.link = UNARY_DOTLINK;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       |       postfix_expression RARROW IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-                       $$->u.unary_expression.link = UNARY_ARROWLINK;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       |       postfix_expression RARROW ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_UNARY_EXPRESSION);
-                       $$->u.unary_expression.type = UNARY_STRING;
-                       $$->u.unary_expression.u.string = yylval.s;
-                       $$->u.unary_expression.link = UNARY_ARROWLINK;
-                       bt_list_splice(&($1)->tmp_head, &($$)->tmp_head);
-                       bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-unary_expression:
-               postfix_expression
-               {       $$ = $1;                                }
-       |       PLUS postfix_expression
-               {
-                       $$ = $2;
-                       if ($$->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT
-                               && $$->u.unary_expression.type != UNARY_SIGNED_CONSTANT) {
-                               reparent_error(scanner, "expecting numeric constant");
-                       }
-               }
-       |       MINUS postfix_expression
-               {
-                       $$ = $2;
-                       if ($$->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT) {
-                               $$->u.unary_expression.type = UNARY_SIGNED_CONSTANT;
-                               $$->u.unary_expression.u.signed_constant =
-                                       -($$->u.unary_expression.u.unsigned_constant);
-                       } else if ($$->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT) {
-                               $$->u.unary_expression.u.signed_constant =
-                                       -($$->u.unary_expression.u.signed_constant);
-                       } else {
-                               reparent_error(scanner, "expecting numeric constant");
-                       }
-               }
-       ;
-
-unary_expression_or_range:
-               unary_expression DOTDOTDOT unary_expression
-               {
-                       $$ = $1;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->tmp_head);
-                       $3->u.unary_expression.link = UNARY_DOTDOTDOT;
-               }
-       |       unary_expression
-               {       $$ = $1;                }
-       ;
-
-/* 2.2: Declarations */
-
-declaration:
-               declaration_specifiers SEMICOLON
-               {       $$ = $1;        }
-       |       event_declaration
-               {       $$ = $1;        }
-       |       stream_declaration
-               {       $$ = $1;        }
-       |       env_declaration
-               {       $$ = $1;        }
-       |       trace_declaration
-               {       $$ = $1;        }
-       |       clock_declaration
-               {       $$ = $1;        }
-       |       callsite_declaration
-               {       $$ = $1;        }
-       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($4)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       declaration_specifiers TYPEDEF type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list TYPEASSIGN alias_declaration_specifiers alias_abstract_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.target->u.typealias_target.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.target->u.typealias_target.type_declarators);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.alias->u.typealias_alias.type_specifier_list = list;
-                       _bt_list_splice_tail(&($5)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
-       ;
-
-event_declaration:
-               event_declaration_begin event_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_EVENT);
-               }
-       |       event_declaration_begin ctf_assignment_expression_list event_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_EVENT);
-                       if (set_parent_node($2, $$))
-                               reparent_error(scanner, "event_declaration");
-               }
-       ;
-
-event_declaration_begin:
-               EVENT LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-event_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-
-stream_declaration:
-               stream_declaration_begin stream_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_STREAM);
-               }
-       |       stream_declaration_begin ctf_assignment_expression_list stream_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_STREAM);
-                       if (set_parent_node($2, $$))
-                               reparent_error(scanner, "stream_declaration");
-               }
-       ;
-
-stream_declaration_begin:
-               STREAM LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-stream_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-env_declaration:
-               env_declaration_begin env_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_ENV);
-               }
-       |       env_declaration_begin ctf_assignment_expression_list env_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_ENV);
-                       if (set_parent_node($2, $$))
-                               reparent_error(scanner, "env declaration");
-               }
-       ;
-
-env_declaration_begin:
-               ENV LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-env_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-trace_declaration:
-               trace_declaration_begin trace_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_TRACE);
-               }
-       |       trace_declaration_begin ctf_assignment_expression_list trace_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_TRACE);
-                       if (set_parent_node($2, $$))
-                               reparent_error(scanner, "trace_declaration");
-               }
-       ;
-
-trace_declaration_begin:
-               TRACE LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-trace_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-clock_declaration:
-               CLOCK clock_declaration_begin clock_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_CLOCK);
-               }
-       |       CLOCK clock_declaration_begin ctf_assignment_expression_list clock_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_CLOCK);
-                       if (set_parent_node($3, $$))
-                               reparent_error(scanner, "trace_declaration");
-               }
-       ;
-
-clock_declaration_begin:
-               LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-clock_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-callsite_declaration:
-               CALLSITE callsite_declaration_begin callsite_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_CALLSITE);
-               }
-       |       CALLSITE callsite_declaration_begin ctf_assignment_expression_list callsite_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_CALLSITE);
-                       if (set_parent_node($3, $$))
-                               reparent_error(scanner, "trace_declaration");
-               }
-       ;
-
-callsite_declaration_begin:
-               LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-callsite_declaration_end:
-               RBRAC SEMICOLON
-               {       pop_scope(scanner);     }
-       ;
-
-integer_declaration_specifiers:
-               CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       integer_type_specifier
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = $1;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       integer_declaration_specifiers CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = $1;
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       integer_declaration_specifiers integer_type_specifier
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($2)->siblings, &($$)->u.type_specifier_list.head);
-               }
-       ;
-
-declaration_specifiers:
-               CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       type_specifier
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = $1;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       declaration_specifiers CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = $1;
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       declaration_specifiers type_specifier
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($2)->siblings, &($$)->u.type_specifier_list.head);
-               }
-       ;
-
-type_declarator_list:
-               type_declarator
-               {       $$ = $1;        }
-       |       type_declarator_list COMMA type_declarator
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($3)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-integer_type_specifier:
-               CHAR
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_CHAR;
-               }
-       |       SHORT
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_SHORT;
-               }
-       |       INT
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INT;
-               }
-       |       LONG
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_LONG;
-               }
-       |       SIGNED
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_SIGNED;
-               }
-       |       UNSIGNED
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_UNSIGNED;
-               }
-       |       _BOOL
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_BOOL;
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_ID_TYPE;
-                       $$->u.type_specifier.id_type = yylval.s;
-               }
-       |       INTEGER LBRAC RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INTEGER;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_INTEGER);
-               }
-       |       INTEGER LBRAC ctf_assignment_expression_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INTEGER;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_INTEGER);
-                       if (set_parent_node($3, $$->u.type_specifier.node))
-                               reparent_error(scanner, "integer reparent error");
-               }
-       ;
-
-type_specifier:
-               VOID
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_VOID;
-               }
-       |       CHAR
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_CHAR;
-               }
-       |       SHORT
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_SHORT;
-               }
-       |       INT
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INT;
-               }
-       |       LONG
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_LONG;
-               }
-       |       FLOAT
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_FLOAT;
-               }
-       |       DOUBLE
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_DOUBLE;
-               }
-       |       SIGNED
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_SIGNED;
-               }
-       |       UNSIGNED
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_UNSIGNED;
-               }
-       |       _BOOL
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_BOOL;
-               }
-       |       _COMPLEX
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_COMPLEX;
-               }
-       |       _IMAGINARY
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_IMAGINARY;
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_ID_TYPE;
-                       $$->u.type_specifier.id_type = yylval.s;
-               }
-       |       FLOATING_POINT LBRAC RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_FLOATING_POINT;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_FLOATING_POINT);
-               }
-       |       FLOATING_POINT LBRAC ctf_assignment_expression_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_FLOATING_POINT;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_FLOATING_POINT);
-                       if (set_parent_node($3, $$->u.type_specifier.node))
-                               reparent_error(scanner, "floating point reparent error");
-               }
-       |       INTEGER LBRAC RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INTEGER;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_INTEGER);
-               }
-       |       INTEGER LBRAC ctf_assignment_expression_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_INTEGER;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_INTEGER);
-                       if (set_parent_node($3, $$->u.type_specifier.node))
-                               reparent_error(scanner, "integer reparent error");
-               }
-       |       STRING
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_STRING;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_STRING);
-               }
-       |       STRING LBRAC RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_STRING;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_STRING);
-               }
-       |       STRING LBRAC ctf_assignment_expression_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_STRING;
-                       $$->u.type_specifier.node = make_node(scanner, NODE_STRING);
-                       if (set_parent_node($3, $$->u.type_specifier.node))
-                               reparent_error(scanner, "string reparent error");
-               }
-       |       ENUM enum_type_specifier
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_ENUM;
-                       $$->u.type_specifier.node = $2;
-               }
-       |       VARIANT variant_type_specifier
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_VARIANT;
-                       $$->u.type_specifier.node = $2;
-               }
-       |       STRUCT struct_type_specifier
-               {
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       $$->u.type_specifier.type = TYPESPEC_STRUCT;
-                       $$->u.type_specifier.node = $2;
-               }
-       ;
-
-struct_type_specifier:
-               struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       if ($2 && set_parent_node($2, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       |       IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       $$->u._struct.name = $1;
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       |       ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       $$->u._struct.name = $1;
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       |       IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 0;
-                       $$->u._struct.name = $1;
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 0;
-                       $$->u._struct.name = $1;
-               }
-       |       struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       bt_list_add_tail(&($6)->siblings, &$$->u._struct.min_align);
-                       if ($2 && set_parent_node($2, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       |       IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       $$->u._struct.name = $1;
-                       bt_list_add_tail(&($7)->siblings, &$$->u._struct.min_align);
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       |       ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end TOK_ALIGN LPAREN unary_expression RPAREN
-               {
-                       $$ = make_node(scanner, NODE_STRUCT);
-                       $$->u._struct.has_body = 1;
-                       $$->u._struct.name = $1;
-                       bt_list_add_tail(&($7)->siblings, &$$->u._struct.min_align);
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "struct reparent error");
-               }
-       ;
-
-struct_declaration_begin:
-               LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-struct_declaration_end:
-               RBRAC
-               {       pop_scope(scanner);     }
-       ;
-
-variant_type_specifier:
-               variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       if ($2 && set_parent_node($2, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.choice = $2;
-                       if ($5 && set_parent_node($5, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.choice = $2;
-                       if ($5 && set_parent_node($5, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       IDENTIFIER variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       IDENTIFIER LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-                       if ($6 && set_parent_node($6, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       IDENTIFIER LT IDENTIFIER GT
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 0;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-               }
-       |       IDENTIFIER LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-                       if ($6 && set_parent_node($6, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       IDENTIFIER LT ID_TYPE GT
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 0;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-               }
-       |       ID_TYPE variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       if ($3 && set_parent_node($3, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       ID_TYPE LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-                       if ($6 && set_parent_node($6, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       ID_TYPE LT IDENTIFIER GT
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 0;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-               }
-       |       ID_TYPE LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 1;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-                       if ($6 && set_parent_node($6, $$))
-                               reparent_error(scanner, "variant reparent error");
-               }
-       |       ID_TYPE LT ID_TYPE GT
-               {
-                       $$ = make_node(scanner, NODE_VARIANT);
-                       $$->u.variant.has_body = 0;
-                       $$->u.variant.name = $1;
-                       $$->u.variant.choice = $3;
-               }
-       ;
-
-variant_declaration_begin:
-               LBRAC
-               {       push_scope(scanner);    }
-       ;
-
-variant_declaration_end:
-               RBRAC
-               {       pop_scope(scanner);     }
-       ;
-
-enum_type_specifier:
-               LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       _bt_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       COLON integer_declaration_specifiers LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       ($$)->u._enum.container_type = $2;
-                       _bt_list_splice_tail(&($4)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       IDENTIFIER LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       IDENTIFIER COLON integer_declaration_specifiers LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       ($$)->u._enum.container_type = $3;
-                       _bt_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       ID_TYPE LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       ID_TYPE COLON integer_declaration_specifiers LBRAC enumerator_list RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       ($$)->u._enum.container_type = $3;
-                       _bt_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       _bt_list_splice_tail(&($2)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       COLON integer_declaration_specifiers LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       ($$)->u._enum.container_type = $2;
-                       _bt_list_splice_tail(&($4)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       IDENTIFIER LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       IDENTIFIER COLON integer_declaration_specifiers LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       ($$)->u._enum.container_type = $3;
-                       _bt_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 0;
-                       $$->u._enum.enum_id = $1;
-               }
-       |       ID_TYPE LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       ID_TYPE COLON integer_declaration_specifiers LBRAC enumerator_list COMMA RBRAC
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 1;
-                       $$->u._enum.enum_id = $1;
-                       ($$)->u._enum.container_type = $3;
-                       _bt_list_splice_tail(&($5)->tmp_head, &($$)->u._enum.enumerator_list);
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_ENUM);
-                       $$->u._enum.has_body = 0;
-                       $$->u._enum.enum_id = $1;
-               }
-       ;
-
-struct_or_variant_declaration_list:
-               /* empty */
-               {       $$ = NULL;      }
-       |       struct_or_variant_declaration_list struct_or_variant_declaration
-               {
-                       if ($1) {
-                               $$ = $1;
-                               bt_list_add_tail(&($2)->siblings, &($$)->tmp_head);
-                       } else {
-                               $$ = $2;
-                               bt_list_add_tail(&($$)->siblings, &($$)->tmp_head);
-                       }
-               }
-       ;
-
-struct_or_variant_declaration:
-               declaration_specifiers struct_or_variant_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       $$ = make_node(scanner, NODE_STRUCT_OR_VARIANT_DECLARATION);
-                       ($$)->u.struct_or_variant_declaration.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->tmp_head, &($$)->u.struct_or_variant_declaration.type_declarators);
-               }
-       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($4)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       declaration_specifiers TYPEDEF type_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       ($$)->u.struct_or_variant_declaration.type_specifier_list = list;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list TYPEASSIGN alias_declaration_specifiers alias_abstract_declarator_list SEMICOLON
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.target->u.typealias_target.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.target->u.typealias_target.type_declarators);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.alias->u.typealias_alias.type_specifier_list = list;
-                       _bt_list_splice_tail(&($5)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
-       ;
-
-alias_declaration_specifiers:
-               CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       type_specifier
-               {
-                       struct ctf_node *node;
-
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = $1;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       IDENTIFIER
-               {
-                       struct ctf_node *node;
-
-                       add_type(scanner, $1);
-                       $$ = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_ID_TYPE;
-                       node->u.type_specifier.id_type = yylval.s;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       alias_declaration_specifiers CONST
-               {
-                       struct ctf_node *node;
-
-                       $$ = $1;
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_CONST;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       alias_declaration_specifiers type_specifier
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($2)->siblings, &($$)->u.type_specifier_list.head);
-               }
-       |       alias_declaration_specifiers IDENTIFIER
-               {
-                       struct ctf_node *node;
-
-                       add_type(scanner, $2);
-                       $$ = $1;
-                       node = make_node(scanner, NODE_TYPE_SPECIFIER);
-                       node->u.type_specifier.type = TYPESPEC_ID_TYPE;
-                       node->u.type_specifier.id_type = yylval.s;
-                       bt_list_add_tail(&node->siblings, &($$)->u.type_specifier_list.head);
-               }
-       ;
-
-struct_or_variant_declarator_list:
-               struct_or_variant_declarator
-               {       $$ = $1;        }
-       |       struct_or_variant_declarator_list COMMA struct_or_variant_declarator
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($3)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-struct_or_variant_declarator:
-               declarator
-               {       $$ = $1;        }
-       |       COLON unary_expression
-               {       $$ = $2;        }
-       |       declarator COLON unary_expression
-               {
-                       $$ = $1;
-                       if (set_parent_node($3, $1))
-                               reparent_error(scanner, "struct_or_variant_declarator");
-               }
-       ;
-
-enumerator_list:
-               enumerator
-               {       $$ = $1;        }
-       |       enumerator_list COMMA enumerator
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($3)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-enumerator:
-               IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-               }
-       |       ID_TYPE
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-               }
-       |       keywords
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-               }
-       |       STRING_LITERAL
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-               }
-       |       IDENTIFIER EQUAL unary_expression_or_range
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-                       bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values);
-               }
-       |       ID_TYPE EQUAL unary_expression_or_range
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-                       bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values);
-               }
-       |       keywords EQUAL unary_expression_or_range
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-                       bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values);
-               }
-       |       STRING_LITERAL EQUAL unary_expression_or_range
-               {
-                       $$ = make_node(scanner, NODE_ENUMERATOR);
-                       $$->u.enumerator.id = $1;
-                       bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values);
-               }
-       ;
-
-abstract_declarator_list:
-               abstract_declarator
-               {       $$ = $1;        }
-       |       abstract_declarator_list COMMA abstract_declarator
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($3)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-abstract_declarator:
-               direct_abstract_declarator
-               {       $$ = $1;        }
-       |       pointer direct_abstract_declarator
-               {
-                       $$ = $2;
-                       bt_list_splice(&($1)->tmp_head, &($$)->u.type_declarator.pointers);
-               }
-       ;
-
-direct_abstract_declarator:
-               /* empty */
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                        $$->u.type_declarator.type = TYPEDEC_ID;
-                       /* id is NULL */
-               }
-       |       IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_ID;
-                       $$->u.type_declarator.u.id = $1;
-               }
-       |       LPAREN abstract_declarator RPAREN
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $2;
-               }
-       |       direct_abstract_declarator LSBRAC unary_expression RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       BT_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
-               }
-       |       direct_abstract_declarator LSBRAC RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       $$->u.type_declarator.u.nested.abstract_array = 1;
-               }
-       ;
-
-alias_abstract_declarator_list:
-               alias_abstract_declarator
-               {       $$ = $1;        }
-       |       alias_abstract_declarator_list COMMA alias_abstract_declarator
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($3)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-alias_abstract_declarator:
-               direct_alias_abstract_declarator
-               {       $$ = $1;        }
-       |       pointer direct_alias_abstract_declarator
-               {
-                       $$ = $2;
-                       bt_list_splice(&($1)->tmp_head, &($$)->u.type_declarator.pointers);
-               }
-       ;
-
-direct_alias_abstract_declarator:
-               /* empty */
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                        $$->u.type_declarator.type = TYPEDEC_ID;
-                       /* id is NULL */
-               }
-       |       LPAREN alias_abstract_declarator RPAREN
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $2;
-               }
-       |       direct_alias_abstract_declarator LSBRAC unary_expression RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       BT_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
-               }
-       |       direct_alias_abstract_declarator LSBRAC RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       $$->u.type_declarator.u.nested.abstract_array = 1;
-               }
-       ;
-
-declarator:
-               direct_declarator
-               {       $$ = $1;        }
-       |       pointer direct_declarator
-               {
-                       $$ = $2;
-                       bt_list_splice(&($1)->tmp_head, &($$)->u.type_declarator.pointers);
-               }
-       ;
-
-direct_declarator:
-               IDENTIFIER
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_ID;
-                       $$->u.type_declarator.u.id = $1;
-               }
-       |       LPAREN declarator RPAREN
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $2;
-               }
-       |       direct_declarator LSBRAC unary_expression RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       BT_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
-               }
-       ;
-
-type_declarator:
-               direct_type_declarator
-               {       $$ = $1;        }
-       |       pointer direct_type_declarator
-               {
-                       $$ = $2;
-                       bt_list_splice(&($1)->tmp_head, &($$)->u.type_declarator.pointers);
-               }
-       ;
-
-direct_type_declarator:
-               IDENTIFIER
-               {
-                       add_type(scanner, $1);
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_ID;
-                       $$->u.type_declarator.u.id = $1;
-               }
-       |       LPAREN type_declarator RPAREN
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $2;
-               }
-       |       direct_type_declarator LSBRAC unary_expression RSBRAC
-               {
-                       $$ = make_node(scanner, NODE_TYPE_DECLARATOR);
-                       $$->u.type_declarator.type = TYPEDEC_NESTED;
-                       $$->u.type_declarator.u.nested.type_declarator = $1;
-                       BT_INIT_LIST_HEAD(&($$)->u.type_declarator.u.nested.length);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.type_declarator.u.nested.length);
-               }
-       ;
-
-pointer:       
-               STAR
-               {
-                       $$ = make_node(scanner, NODE_POINTER);
-               }
-       |       STAR pointer
-               {
-                       $$ = make_node(scanner, NODE_POINTER);
-                       bt_list_splice(&($2)->tmp_head, &($$)->tmp_head);
-               }
-       |       STAR type_qualifier_list pointer
-               {
-                       $$ = make_node(scanner, NODE_POINTER);
-                       $$->u.pointer.const_qualifier = 1;
-                       bt_list_splice(&($3)->tmp_head, &($$)->tmp_head);
-               }
-       ;
-
-type_qualifier_list:
-               /* pointer assumes only const type qualifier */
-               CONST
-       |       type_qualifier_list CONST
-       ;
-
-/* 2.3: CTF-specific declarations */
-
-ctf_assignment_expression_list:
-               ctf_assignment_expression SEMICOLON
-               {       $$ = $1;        }
-       |       ctf_assignment_expression_list ctf_assignment_expression SEMICOLON
-               {
-                       $$ = $1;
-                       bt_list_add_tail(&($2)->siblings, &($$)->tmp_head);
-               }
-       ;
-
-ctf_assignment_expression:
-               unary_expression EQUAL unary_expression
-               {
-                       /*
-                        * Because we have left and right, cannot use
-                        * set_parent_node.
-                        */
-                       $$ = make_node(scanner, NODE_CTF_EXPRESSION);
-                       _bt_list_splice_tail(&($1)->tmp_head, &($$)->u.ctf_expression.left);
-                       if ($1->u.unary_expression.type != UNARY_STRING)
-                               reparent_error(scanner, "ctf_assignment_expression left expects string");
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.ctf_expression.right);
-               }
-       |       unary_expression TYPEASSIGN declaration_specifiers      /* Only allow struct */
-               {
-                       /*
-                        * Because we have left and right, cannot use
-                        * set_parent_node.
-                        */
-                       $$ = make_node(scanner, NODE_CTF_EXPRESSION);
-                       _bt_list_splice_tail(&($1)->tmp_head, &($$)->u.ctf_expression.left);
-                       if ($1->u.unary_expression.type != UNARY_STRING)
-                               reparent_error(scanner, "ctf_assignment_expression left expects string");
-                       bt_list_add_tail(&($3)->siblings, &($$)->u.ctf_expression.right);
-               }
-       |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list
-               {
-                       struct ctf_node *list;
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       ($$)->u.struct_or_variant_declaration.type_specifier_list = list;
-                       _bt_list_splice_tail(&($4)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEDEF declaration_specifiers type_declarator_list
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u._typedef.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       declaration_specifiers TYPEDEF type_declarator_list
-               {
-                       struct ctf_node *list;
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       _bt_list_splice_tail(&($1)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       $$ = make_node(scanner, NODE_TYPEDEF);
-                       ($$)->u.struct_or_variant_declaration.type_specifier_list = list;
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u._typedef.type_declarators);
-               }
-       |       TYPEALIAS declaration_specifiers abstract_declarator_list TYPEASSIGN alias_declaration_specifiers alias_abstract_declarator_list
-               {
-                       struct ctf_node *list;
-
-                       $$ = make_node(scanner, NODE_TYPEALIAS);
-                       $$->u.typealias.target = make_node(scanner, NODE_TYPEALIAS_TARGET);
-                       $$->u.typealias.alias = make_node(scanner, NODE_TYPEALIAS_ALIAS);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.target->u.typealias_target.type_specifier_list = list;
-                       _bt_list_splice_tail(&($2)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($3)->tmp_head, &($$)->u.typealias.target->u.typealias_target.type_declarators);
-
-                       list = make_node(scanner, NODE_TYPE_SPECIFIER_LIST);
-                       $$->u.typealias.alias->u.typealias_alias.type_specifier_list = list;
-                       _bt_list_splice_tail(&($5)->u.type_specifier_list.head, &list->u.type_specifier_list.head);
-                       _bt_list_splice_tail(&($6)->tmp_head, &($$)->u.typealias.alias->u.typealias_alias.type_declarators);
-               }
-       ;
diff --git a/formats/ctf/metadata/ctf-scanner-symbols.h b/formats/ctf/metadata/ctf-scanner-symbols.h
deleted file mode 100644 (file)
index 9b9e363..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _CTF_SCANNER_SYMBOLS
-#define _CTF_SCANNER_SYMBOLS
-
-/*
- * ctf-scanner-symbols.h
- *
- * Copyright 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@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.
- */
-
-#define yy_create_buffer bt_yy_create_buffer
-#define yy_delete_buffer bt_yy_delete_buffer
-#define yy_flush_buffer bt_yy_flush_buffer
-#define yy_scan_buffer bt_yy_scan_buffer
-#define yy_scan_bytes bt_yy_scan_bytes
-#define yy_scan_string bt_yy_scan_string
-#define yy_switch_to_buffer bt_yy_switch_to_buffer
-#define yyalloc bt_yyalloc
-#define yyfree bt_yyfree
-#define yyget_column bt_yyget_column
-#define yyget_debug bt_yyget_debug
-#define yyget_extra bt_yyget_extra
-#define yyget_in bt_yyget_in
-#define yyget_leng bt_yyget_leng
-#define yyget_lineno bt_yyget_lineno
-#define yyget_lval bt_yyget_lval
-#define yyget_out bt_yyget_out
-#define yyget_text bt_yyget_text
-#define yylex_init bt_yylex_init
-#define yypop_buffer_state bt_yypop_buffer_state
-#define yypush_buffer_state bt_yypush_buffer_state
-#define yyrealloc bt_yyrealloc
-#define yyset_column bt_yyset_column
-#define yyset_debug bt_yyset_debug
-#define yyset_extra bt_yyset_extra
-#define yyset_in bt_yyset_in
-#define yyset_lineno bt_yyset_lineno
-#define yyset_lval bt_yyset_lval
-#define yyset_out bt_yyset_out
-
-#endif /* _CTF_SCANNER_SYMBOLS */
diff --git a/formats/ctf/metadata/ctf-scanner.h b/formats/ctf/metadata/ctf-scanner.h
deleted file mode 100644 (file)
index 51484a1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _CTF_SCANNER_H
-#define _CTF_SCANNER_H
-
-/*
- * ctf-scanner.h
- *
- * Copyright 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@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.
- */
-
-#include <stdio.h>
-#include "ctf-ast.h"
-
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-struct ctf_scanner_scope;
-struct ctf_scanner_scope {
-       struct ctf_scanner_scope *parent;
-       GHashTable *types;
-};
-
-struct ctf_scanner {
-       yyscan_t scanner;
-       struct ctf_ast *ast;
-       struct ctf_scanner_scope root_scope;
-       struct ctf_scanner_scope *cs;
-       struct objstack *objstack;
-};
-
-struct ctf_scanner *ctf_scanner_alloc(void);
-void ctf_scanner_free(struct ctf_scanner *scanner);
-int ctf_scanner_append_ast(struct ctf_scanner *scanner, FILE *input);
-
-static inline
-struct ctf_ast *ctf_scanner_get_ast(struct ctf_scanner *scanner)
-{
-       return scanner->ast;
-}
-
-BT_HIDDEN
-int is_type(struct ctf_scanner *scanner, const char *id);
-
-#endif /* _CTF_SCANNER_H */
diff --git a/formats/ctf/metadata/ctf-test/development/ctf-embedded-1.txt b/formats/ctf/metadata/ctf-test/development/ctf-embedded-1.txt
deleted file mode 100644 (file)
index e814835..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* CTF 1.8 */
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "f816d884-6cea-11e0-ac7a-8f5f4e9f7724";
-       byte_order = be;        /* Assuming big endian streams */
-};
-
-/* Architecture with 32-bit pointers, 32-bit integers, 32-bit longs */
-
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-typealias integer { size = 32; align = 32; signed = false; } := void *;
-
-stream {
-       event.header := struct {
-               uint32_t id;
-               uint64_t timestamp;
-       };
-       event.context := struct {       /*
-               uint32_t thread_id;      * This context belongs to all
-               void *func_called;       * events in this stream.
-               void *called_from;       */
-               uint32_t event_count;   /* for debug */
-       };                      
-};
-
-/*
- * All events have empty context/fields, because their field layout is
- * replicated for all events of the stream (in this particular trace
- * layout). See ctf-embedded-2.txt for a more compact layout.
- */
-
-event { name = invalid; id = 0; };
-event { name = func_enter; id = 1; };
-event { name = func_exit; id = 2; };
-
-event {
-       name = timer_tick;      /* or sync_point... */
-       id = 3;
-       fields := {
-               uint64_t monotonic_value;
-               uint64_t tsc_value;
-               uint32_t seqnum;
-       };
-};
-
-event {
-       name = freq_change;
-       id = 4;
-       fields := {
-               uint64_t new_freq;
-       };
-}
-
-clock {
-       name = monotonic;
-       uuid = ;
-};
-
-clock {
-       name = seqnum;
-       uuid = ;
-};
-
-clock {
-       name = tsc;
-       sync_points = {
-               map {
-                       parent.clock = monotonic;
-                       parent.value = event.timer_tick.monotonic_value;
-                       value = event.timer_tick.tsc_value;
-               };
-               map {
-                       parent.clock = seqnum;
-                       parent.value = event.timer_tick.seqnum;
-                       value = event.timer_tick.tsc_value;
-               };
-       };
-
-       freq = {
-               update = event.freq_change.new_freq;
-       };
-       uuid = ;
-};
diff --git a/formats/ctf/metadata/ctf-test/fail/array-negative-len.txt b/formats/ctf/metadata/ctf-test/fail/array-negative-len.txt
deleted file mode 100644 (file)
index 3431b4c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* CTF 1.8 */
-
-typealias integer { size = 32; align = 32; signed = false; } := uint;
-typedef uint myarray[-10];
diff --git a/formats/ctf/metadata/ctf-test/fail/array-unexisting-elem-type.txt b/formats/ctf/metadata/ctf-test/fail/array-unexisting-elem-type.txt
deleted file mode 100644 (file)
index 5310438..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-typedef nonexist myarray[10];
diff --git a/formats/ctf/metadata/ctf-test/fail/enum-with-non-numeric-range.txt b/formats/ctf/metadata/ctf-test/fail/enum-with-non-numeric-range.txt
deleted file mode 100644 (file)
index 1e1d908..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-enum test {X = array[2].N ... 1, };
diff --git a/formats/ctf/metadata/ctf-test/fail/event-with-non-text-left.txt b/formats/ctf/metadata/ctf-test/fail/event-with-non-text-left.txt
deleted file mode 100644 (file)
index e30b003..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-event { 42 = test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-elem-type.txt b/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-elem-type.txt
deleted file mode 100644 (file)
index 78651f2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = false; } := uint;
-typedef nonexist testseq[uint];
diff --git a/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type-signedness.txt b/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type-signedness.txt
deleted file mode 100644 (file)
index ec96296..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = false; } := uint;
-typealias integer { size = 32; align = 32; signed = true; } := int;
-typedef uint testseq[int];
diff --git a/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type.txt b/formats/ctf/metadata/ctf-test/fail/sequence-incorrect-len-type.txt
deleted file mode 100644 (file)
index 67de76a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* CTF 1.8 */
-struct name {};
-typealias integer { size = 32; align = 32; signed = false; } := uint;
-typedef uint testseq[struct name];
diff --git a/formats/ctf/metadata/ctf-test/fail/stream-with-non-text-left.txt b/formats/ctf/metadata/ctf-test/fail/stream-with-non-text-left.txt
deleted file mode 100644 (file)
index 8d090b9..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-stream { 42 = test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-unexisting-field-type.txt b/formats/ctf/metadata/ctf-test/fail/struct-unexisting-field-type.txt
deleted file mode 100644 (file)
index da9df8a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/* CTF 1.8 */
-struct test {
-       int a;
-       int b;
-};
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-duplicate-field-name.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-duplicate-field-name.txt
deleted file mode 100644 (file)
index c079821..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = true; } := int;
-
-struct {
-       int a;
-       int a;
-};
-
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-2.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-2.txt
deleted file mode 100644 (file)
index f14a94a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { int a.array[3].N; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-3.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-3.txt
deleted file mode 100644 (file)
index 15fafbc..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { a->array[3].N test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-4.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-4.txt
deleted file mode 100644 (file)
index c78232f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { array[1] blah; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-5.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left-5.txt
deleted file mode 100644 (file)
index 5ce45c2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { 42 = test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-non-text-left.txt
deleted file mode 100644 (file)
index eb1d8a4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { array[3].N = test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/struct-with-right-range.txt b/formats/ctf/metadata/ctf-test/fail/struct-with-right-range.txt
deleted file mode 100644 (file)
index aa412ac..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-struct test { test = 444 ... 555; };
diff --git a/formats/ctf/metadata/ctf-test/fail/trace-with-non-text-left.txt b/formats/ctf/metadata/ctf-test/fail/trace-with-non-text-left.txt
deleted file mode 100644 (file)
index 93cabfa..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-trace { 42 = test; };
diff --git a/formats/ctf/metadata/ctf-test/fail/typealias-left-abstract-array.txt b/formats/ctf/metadata/ctf-test/fail/typealias-left-abstract-array.txt
deleted file mode 100644 (file)
index 3f5efcb..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias uint8_t [] := puint8_t;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = le;
-       packet.header := struct {
-            uint8_t  field;
-       };
-};
-
-event {
-       name = string;
-       fields := struct { string str; };
-};
diff --git a/formats/ctf/metadata/ctf-test/fail/typealias-no-array-alias.txt b/formats/ctf/metadata/ctf-test/fail/typealias-no-array-alias.txt
deleted file mode 100644 (file)
index 0a08728..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = false; } : unsigned const long [];
diff --git a/formats/ctf/metadata/ctf-test/fail/typedef-untagged-variant.txt b/formats/ctf/metadata/ctf-test/fail/typedef-untagged-variant.txt
deleted file mode 100644 (file)
index 289be14..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = true; } := int;
-
-typedef variant {
-       int a;
-       int b;
-} name;
diff --git a/formats/ctf/metadata/ctf-test/fail/variant-unexisting-field-type.txt b/formats/ctf/metadata/ctf-test/fail/variant-unexisting-field-type.txt
deleted file mode 100644 (file)
index 59f5170..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/* CTF 1.8 */
-variant test {
-       int a;
-       int b;
-};
diff --git a/formats/ctf/metadata/ctf-test/fail/variant-with-duplicate-field-name.txt b/formats/ctf/metadata/ctf-test/fail/variant-with-duplicate-field-name.txt
deleted file mode 100644 (file)
index e684dda..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 32; align = 32; signed = true; } := int;
-
-variant {
-       int a;
-       int a;
-};
-
diff --git a/formats/ctf/metadata/ctf-test/fail/variant-with-non-text-left.txt b/formats/ctf/metadata/ctf-test/fail/variant-with-non-text-left.txt
deleted file mode 100644 (file)
index cf467db..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/* CTF 1.8 */
-variant test { 555 = test };
diff --git a/formats/ctf/metadata/ctf-test/readme.txt b/formats/ctf/metadata/ctf-test/readme.txt
deleted file mode 100644 (file)
index 5bcb830..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-These are the CTF metadata parser test. Those under succeed/ should successfully
-parse. Those under fail/ should provide an appropriate failure message.
-
-The tests under tofix/ do not follow the CTF specifications due to
-ambiguity in the LALR parser implementation. These are rarely used.
-
-Mathieu Desnoyers
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-embedded-1.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-embedded-1.txt
deleted file mode 100644 (file)
index cb17344..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* CTF 1.8 */
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "f816d884-6cea-11e0-ac7a-8f5f4e9f7724";
-       byte_order = be;        /* Assuming big endian streams */
-};
-
-/* Architecture with 32-bit pointers, 32-bit integers, 32-bit longs */
-
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-typealias integer { size = 32; align = 32; signed = false; } := void *;
-
-stream {
-       event.header := struct {
-               uint32_t id;
-               uint64_t timestamp;
-       };
-       event.context := struct {       /*
-               uint32_t thread_id;      * This context belongs to all
-               void *func_called;       * events in this stream.
-               void *called_from;       */
-               uint32_t event_count;   /* for debug */
-       };
-};
-
-/*
- * All events have empty context/fields, because their field layout is
- * replicated for all events of the stream (in this particular trace
- * layout). See ctf-embedded-2.txt for a more compact layout.
- */
-
-event { name = invalid; id = 0; };
-event { name = func_enter; id = 1; };
-event { name = func_exit; id = 2; };
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-embedded-2.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-embedded-2.txt
deleted file mode 100644 (file)
index 7be3ef4..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* CTF 1.8 */
-
-/* Architecture with 32-bit pointers, 32-bit integers, 32-bit longs */
-
-typealias integer { size = 1; align = 1; signed = false; } := uint1_t;
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 63; align = 1; signed = false; } := timestamp_t;
-
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-typealias integer { size = 32; align = 32; signed = false; } := void *;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = be;
-       packet.header := struct {
-               uint32_t magic;
-               uint8_t  uuid[16];
-               uint32_t stream_id;
-       };
-};
-
-stream {
-       id = 0;
-       event.header := struct {
-               uint1_t id;
-               timestamp_t timestamp;
-       };
-       event.context := struct {
-               uint32_t thread_id;
-               uint32_t event_count;
-       };                      
-};
-
-event {
-       name = func_enter;
-       id = 0;
-       stream_id = 0;
-       fields := struct {
-               void *func_called;
-               void *called_from;
-       };
-};
-
-event {
-       name = func_exit;
-       id = 1;
-       stream_id = 0;
-};
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-single-stream-with-packet-context.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-single-stream-with-packet-context.txt
deleted file mode 100644 (file)
index d18b4cc..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* CTF 1.8 */
-
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = le;
-       packet.header := struct {
-               uint32_t magic;
-               uint8_t  uuid[16];
-       };
-};
-
-stream {
-       packet.context := struct {
-               uint32_t content_size;
-               uint32_t packet_size;
-       };
-};
-
-event {
-       name = string;
-       fields := struct { string str; };
-};
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-single-stream.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-single-stream.txt
deleted file mode 100644 (file)
index f1ebfc8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* CTF 1.8 */
-
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = le;
-       packet.header := struct {
-               uint32_t magic;
-               uint8_t  uuid[16];
-       };
-};
-
-event {
-       name = string;
-       fields := struct { string str; };
-};
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-test-align-attribute.txt
deleted file mode 100644 (file)
index 3f236ca..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* CTF 1.8
- *
- * Architecture with 32-bit pointers, 32-bit integers, 32-bit longs.
- */
-
-typealias integer { size = 1; align = 1; signed = false; } := uint1_t;
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 63; align = 1; signed = false; } := timestamp_t;
-
-typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-typealias integer { size = 32; align = 32; signed = false; } := void *;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = be;
-       packet.header := struct {
-               uint32_t magic;
-               uint8_t  uuid[16];
-               uint32_t stream_id;
-       };
-};
-
-stream {
-       id = 0;
-       event.header := struct {
-               uint1_t id;
-               timestamp_t timestamp;
-       } align(8);
-       event.context := struct {
-               uint32_t thread_id;
-               uint32_t event_count;
-       };                      
-};
-
-event {
-       name = func_enter;
-       id = 0;
-       stream_id = 0;
-       fields := struct {
-               void *func_called;
-               void *called_from;
-       };
-};
-
-event {
-       name = func_exit;
-       id = 1;
-       stream_id = 0;
-};
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-test-seq.txt
deleted file mode 100644 (file)
index 82a30ca..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* CTF 1.8
- *
- * Architecture with 32-bit pointers, 32-bit integers, 32-bit longs.
- */
-
-typealias integer { size = 1; align = 1; signed = false; } := uint1_t;
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 63; align = 1; signed = false; } := timestamp_t;
-
-typealias integer { size = 32; align = 32; signed = false; base = dec; } := uint32_t;
-typealias integer { size = 32; align = 32; signed = false; base = hex;} := void *;
-
-trace {
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = be;
-       packet.header := struct {
-               uint32_t magic;
-               uint8_t  uuid[16];
-               uint32_t stream_id;
-       };
-};
-
-stream {
-       id = 0;
-       event.header := struct {
-               uint1_t id;
-               timestamp_t timestamp;
-       } align(8);
-       event.context := struct {
-               uint32_t thread_id;
-               uint32_t event_count;
-       };                      
-};
-
-event {
-       name = func_enter;
-       id = 0;
-       stream_id = 0;
-       fields := struct {
-               uint8_t len;
-               uint32_t myseq[len];
-       };
-};
diff --git a/formats/ctf/metadata/ctf-test/succeed/ctf-test.txt b/formats/ctf/metadata/ctf-test/succeed/ctf-test.txt
deleted file mode 100644 (file)
index b6b1ab9..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* CTF 1.8 */
-
-typealias integer { size = 32; align = 32; signed = true; } := int;
-typealias integer { size = 32; align = 32; signed = false; } := uint;
-typealias integer { size = 64; align = 64; signed = true; } := long;
-typealias integer { size = 64; align = 64; } := unsigned long;
-
-enum name1 : int {
-  ZERO,
-  ONE,
-  TWO,
-  TEN = 10,
-  ELEVEN,
-};
-
-enum name2 : long { ONE, TWO };
-
-enum name3 : unsigned long { ONE, TWO };
-
-enum name4 : unsigned long {
-  string          = 1 ... 2,
-  "other string"      = 3...4,
-  yet_another_string,   /* will be assigned to end_value2 + 1 */
-  "some other string" = 10,
-};
-
-enum name5 : long { "int" = 1, };
-
-enum name6 { "int" = 1, };
-
-typealias floating_point {
-  exp_dig = 8;         /* sizeof(float) * CHAR_BIT - FLT_MANT_DIG */
-  mant_dig = 24;       /* FLT_MANT_DIG */
-  byte_order = native;
-} := float;
-
-typealias integer {
-  size = 32;
-  align = 32;
-  signed = false;
-} := struct page *;
-
-struct event_packet_header {
-  typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-  typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-
-  uint32_t magic;
-  uint8_t  uuid[16];
-  uint32_t stream_id;
-};
-
-trace {
-       major = 66;
-       minor = 2;
-       byte_order = le;
-       uuid = "1123fcea-706e-11e0-a38b-f3c28a683a3d";
-       packet.header := struct event_packet_header;
-};
-
-stream {
-  typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-  typealias integer { size = 16; align = 16; signed = false; } := uint16_t;
-  typealias integer { size = 32; align = 32; signed = true; } := int;
-  typedef int pid_t;
-
-  id = 5;
-  /* Type 1 - Few event IDs; Type 2 - Many event IDs. See section 6.2. */
-  event.header := struct { uint64_t timestamp; uint16_t id; };
-  event.context := struct { pid_t pid; };
-};
-
-struct example {
-  /* TODO gcc bitfields not supported yet. */
-  /* short a:12;
-  short b:5; */
-};
-
-struct name {
-  typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-  typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-  typealias integer { size = 32; align = 32; signed = true; } := int32_t;
-  typealias integer { size = 2; align = 8; signed = false; } := uint2_t;
-  typealias integer { size = 16; align = 16; signed = true; } := short;
-  typealias uint32_t := unsigned int;
-
-  enum : uint2_t { a, b, c, d } choice;
-  /* Unrelated fields can be added between the variant and its tag */
-  int32_t somevalue;
-  variant <choice> {
-    uint32_t a;
-    uint64_t b;
-    short c;
-    struct {
-      unsigned int field1;
-      uint64_t field2;
-    } d;
-  } s;
-};
-
-typealias integer {
-  size = 32;
-  signed = false;
-  align = 32;
-} := uint32_t;
-
-typealias string { encoding = UTF8; } := test;
-
-struct event_packet_context {
-  typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-  typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-  typealias integer { size = 16; align = 16; signed = false; } := uint16_t;
-  typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-
-  uint64_t timestamp_begin;
-  uint64_t timestamp_end;
-  uint32_t checksum;
-  uint32_t stream_packet_count;
-  uint32_t events_discarded;
-  uint32_t cpu_id;
-  uint16_t content_size;
-  uint16_t packet_size;
-  uint8_t  stream_packet_count_bits;    /* Significant counter bits */
-  uint8_t  compression_scheme;
-  uint8_t  encryption_scheme;
-  uint8_t  checksum_scheme;
-};
-
-struct event_header_1 {
-  typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-  typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-  typealias integer { size = 5; align = 1; signed = false; } := uint5_t;
-  typealias integer { size = 27; align = 1; signed = false; } := uint27_t;
-
-  /*
-   * id: range: 0 - 30.
-   * id 31 is reserved to indicate an extended header.
-   */
-  enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
-  variant <id> {
-    struct {
-      uint27_t timestamp;
-    } compact;
-    struct {
-      uint32_t id;                       /* 32-bit event IDs */
-      uint64_t timestamp;                /* 64-bit timestamps */
-    } extended;
-  } v;
-};
-
-struct event_header_2 {
-  typealias integer { size = 64; align = 64; signed = false; } := uint64_t;
-  typealias integer { size = 32; align = 32; signed = false; } := uint32_t;
-  typealias integer { size = 16; align = 16; signed = false; } := uint16_t;
-
-  /*
-   * id: range: 0 - 65534.
-   * id 65535 is reserved to indicate an extended header.
-   */
-  enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;
-  variant <id> {
-    struct {
-      uint32_t timestamp;
-    } compact;
-    struct {
-      uint32_t id;                       /* 32-bit event IDs */
-      uint64_t timestamp;                /* 64-bit timestamps */
-    } extended;
-  } v;
-};
-
-typedef int rootscopetest;
-
-/* parser level only: event { a.b.c.d.e = f.g.h->i->j; }; */
-
-event {
-       name = test_event;
-       id = 0;
-       stream_id = 5;
-       context := struct {};
-       fields := struct {};
-};
-
-typealias integer { size = 32; align = 32; signed = false; } := unsigned long long *;
-
-variant vardecl {
-       int a;
-       int b;
-};
-
-event {
-       typealias integer { size = 8; align = 8; signed = true; } := char;
-       typealias integer { size = 32; align = 32; signed = false; } := unsigned int;
-
-       name = test_event2;
-       id = 1;
-       stream_id = 5;
-       fields := struct {
-               enum : char { a = 0, b = 1, } tag;
-               variant vardecl <tag> myvariant;
-               unsigned int seqlen;
-               int myseq[seqlen];
-       };
-};
-
-typedef int myarray[10];
diff --git a/formats/ctf/metadata/ctf-test/tofix/ctf-path.txt b/formats/ctf/metadata/ctf-test/tofix/ctf-path.txt
deleted file mode 100644 (file)
index 3d8a2c7..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 8; align = 8; signed = false; base = hex; } := uint8_t;
-typealias integer { size = 32; align = 8; signed = false; base = hex;  } := uint32_t;
-
-trace {
-    major = 1;
-    minor = 2;
-    byte_order = le;
-    uuid = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa";
-    packet.header := struct  {
-        uint32_t magic;                        
-    };
-};
-
-variant var {
-    uint8_t small;
-    uint32_t big;
-};
-
-enum select : uint8_t { small = 0, big = 1 };
-
-stream {
-    event.header := struct {
-        enum select a;
-    };
-};
-
-event {
-    name = event1;
-    fields := struct {
-       /*
-        * TODO: Only an identifier is expected in the variant/sequence
-        * tag. It should be a dotted expression (a path).
-        *
-        */
-        variant var <stream.event.header.a> b;
-
-       /*
-        * TODO
-        * The path lookup only allows lookup for a full path starting
-        * from the root or for a field within the current scope. The
-        * CTF spec allows defining a relative sub-scope for a preceding
-        * field.
-        */
-       struct {
-               enum select sel2;
-       } str2;
-        variant var2 <str2.sel2> b;
-
-       /*
-        * TODO: Deal with path name lookup conflict, e.g. if a field is
-        * named "stream", it conflicts with the stream dynamic scope.
-        * Local fields hide dynamic scopes.
-        */
-       struct {
-               enum select sel3
-       } stream;
-        variant var3 <stream.sel3> c;
-       /* But now the following lookup should fail: */
-       /* variant var4 <stream.event.header.a> d; */
-
-       /*
-        * TODO: support conflict-free local-scoped tags, starting with
-        * ".".
-        */
-       variant var5 <.stream.sel3> e;
-    };
-};
diff --git a/formats/ctf/metadata/ctf-test/tofix/ctf-redefine-type.txt b/formats/ctf/metadata/ctf-test/tofix/ctf-redefine-type.txt
deleted file mode 100644 (file)
index eca6723..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* CTF 1.8 */
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 32; align = 8; signed = false; } := uint32_t;
-
-// Define newtype
-typealias uint32_t := newtype;
-
-trace {
-       // Hide newtype
-       typedef uint8_t newtype;
-    
-       major = 0;
-       minor = 1;
-       uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564";
-       byte_order = le;
-       packet.header := struct {
-            uint8_t  field;
-       };
-};
-
-event {
-       name = string;
-       fields := struct { string str; };
-};
diff --git a/formats/ctf/metadata/ctf-test/tofix/ctf-typedef-ambiguity.txt b/formats/ctf/metadata/ctf-test/tofix/ctf-typedef-ambiguity.txt
deleted file mode 100644 (file)
index 94bc39e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/* CTF 1.8 */
-// Define unsigned long
-typealias integer { ... } := unsigned long;
-
-// Define unsigned long int
-typealias integer { ... } := unsigned long int;
-
-// Define int
-typedef unsigned long int;
diff --git a/formats/ctf/metadata/ctf-visitor-generate-io-struct.c b/formats/ctf/metadata/ctf-visitor-generate-io-struct.c
deleted file mode 100644 (file)
index 13b79f0..0000000
+++ /dev/null
@@ -1,3192 +0,0 @@
-/*
- * ctf-visitor-generate-io-struct.c
- *
- * Common Trace Format Metadata Visitor (generate I/O structures).
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <glib.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/list.h>
-#include <babeltrace/types.h>
-#include <babeltrace/ctf/metadata.h>
-#include <babeltrace/compat/uuid.h>
-#include <babeltrace/endian.h>
-#include <babeltrace/ctf/events-internal.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-#define fprintf_dbg(fd, fmt, args...)  fprintf(fd, "%s: " fmt, __func__, ## args)
-
-#define _bt_list_first_entry(ptr, type, member)        \
-       bt_list_entry((ptr)->next, type, member)
-
-struct last_enum_value {
-       union {
-               int64_t s;
-               uint64_t u;
-       } u;
-};
-
-int opt_clock_force_correlate;
-
-static
-struct bt_declaration *ctf_type_specifier_list_visit(FILE *fd,
-               int depth, struct ctf_node *type_specifier_list,
-               struct declaration_scope *declaration_scope,
-               struct ctf_trace *trace);
-
-static
-int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
-                    struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace);
-
-static
-int is_unary_string(struct bt_list_head *head)
-{
-       struct ctf_node *node;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               if (node->type != NODE_UNARY_EXPRESSION)
-                       return 0;
-               if (node->u.unary_expression.type != UNARY_STRING)
-                       return 0;
-       }
-       return 1;
-}
-
-/*
- * String returned must be freed by the caller using g_free.
- */
-static
-char *concatenate_unary_strings(struct bt_list_head *head)
-{
-       struct ctf_node *node;
-       GString *str;
-       int i = 0;
-
-       str = g_string_new("");
-       bt_list_for_each_entry(node, head, siblings) {
-               char *src_string;
-
-               if (node->type != NODE_UNARY_EXPRESSION
-                               || node->u.unary_expression.type != UNARY_STRING
-                               || !((node->u.unary_expression.link != UNARY_LINK_UNKNOWN)
-                                       ^ (i == 0)))
-                       return NULL;
-               switch (node->u.unary_expression.link) {
-               case UNARY_DOTLINK:
-                       g_string_append(str, ".");
-                       break;
-               case UNARY_ARROWLINK:
-                       g_string_append(str, "->");
-                       break;
-               case UNARY_DOTDOTDOT:
-                       g_string_append(str, "...");
-                       break;
-               default:
-                       break;
-               }
-               src_string = node->u.unary_expression.u.string;
-               g_string_append(str, src_string);
-               i++;
-       }
-       return g_string_free(str, FALSE);
-}
-
-static
-GQuark get_map_clock_name_value(struct bt_list_head *head)
-{
-       struct ctf_node *node;
-       const char *name = NULL;
-       int i = 0;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               char *src_string;
-
-               if (node->type != NODE_UNARY_EXPRESSION
-                       || node->u.unary_expression.type != UNARY_STRING
-                       || !((node->u.unary_expression.link != UNARY_LINK_UNKNOWN)
-                               ^ (i == 0)))
-                       return 0;
-               /* needs to be chained with . */
-               switch (node->u.unary_expression.link) {
-               case UNARY_DOTLINK:
-                       break;
-               case UNARY_ARROWLINK:
-               case UNARY_DOTDOTDOT:
-                       return 0;
-               default:
-                       break;
-               }
-               src_string = node->u.unary_expression.u.string;
-               switch (i) {
-               case 0: if (strcmp("clock", src_string) != 0) {
-                               return 0;
-                       }
-                       break;
-               case 1: name = src_string;
-                       break;
-               case 2: if (strcmp("value", src_string) != 0) {
-                               return 0;
-                       }
-                       break;
-               default:
-                       return 0;       /* extra identifier, unknown */
-               }
-               i++;
-       }
-       return g_quark_from_string(name);
-}
-
-static
-int is_unary_unsigned(struct bt_list_head *head)
-{
-       struct ctf_node *node;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               if (node->type != NODE_UNARY_EXPRESSION)
-                       return 0;
-               if (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
-                       return 0;
-       }
-       return 1;
-}
-
-static
-int get_unary_unsigned(struct bt_list_head *head, uint64_t *value)
-{
-       struct ctf_node *node;
-       int i = 0;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               if (node->type != NODE_UNARY_EXPRESSION
-                               || node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT
-                               || node->u.unary_expression.link != UNARY_LINK_UNKNOWN
-                               || i != 0)
-                       return -EINVAL;
-               *value = node->u.unary_expression.u.unsigned_constant;
-               i++;
-       }
-       return 0;
-}
-
-static
-int is_unary_signed(struct bt_list_head *head)
-{
-       struct ctf_node *node;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               if (node->type != NODE_UNARY_EXPRESSION)
-                       return 0;
-               if (node->u.unary_expression.type != UNARY_SIGNED_CONSTANT)
-                       return 0;
-       }
-       return 1;
-}
-
-static
-int get_unary_signed(struct bt_list_head *head, int64_t *value)
-{
-       struct ctf_node *node;
-       int i = 0;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               if (node->type != NODE_UNARY_EXPRESSION
-                               || (node->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT && node->u.unary_expression.type != UNARY_SIGNED_CONSTANT)
-                               || node->u.unary_expression.link != UNARY_LINK_UNKNOWN
-                               || i != 0)
-                       return -EINVAL;
-               switch (node->u.unary_expression.type) {
-               case UNARY_UNSIGNED_CONSTANT:
-                       *value = (int64_t) node->u.unary_expression.u.unsigned_constant;
-                       break;
-               case UNARY_SIGNED_CONSTANT:
-                       *value = node->u.unary_expression.u.signed_constant;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               i++;
-       }
-       return 0;
-}
-
-static
-int get_unary_uuid(struct bt_list_head *head, unsigned char *uuid)
-{
-       struct ctf_node *node;
-       int i = 0;
-       int ret = -1;
-
-       bt_list_for_each_entry(node, head, siblings) {
-               const char *src_string;
-
-               if (node->type != NODE_UNARY_EXPRESSION
-                               || node->u.unary_expression.type != UNARY_STRING
-                               || node->u.unary_expression.link != UNARY_LINK_UNKNOWN
-                               || i != 0)
-                       return -EINVAL;
-               src_string = node->u.unary_expression.u.string;
-               ret = bt_uuid_parse(src_string, uuid);
-       }
-       return ret;
-}
-
-static
-struct ctf_stream_declaration *trace_stream_lookup(struct ctf_trace *trace, uint64_t stream_id)
-{
-       if (trace->streams->len <= stream_id)
-               return NULL;
-       return g_ptr_array_index(trace->streams, stream_id);
-}
-
-static
-struct ctf_event_declaration *stream_event_lookup(struct ctf_stream_declaration *stream, uint64_t event_id)
-{
-       if (stream->events_by_id->len <= event_id)
-               return NULL;
-       return g_ptr_array_index(stream->events_by_id, event_id);
-}
-
-static
-struct ctf_clock *trace_clock_lookup(struct ctf_trace *trace, GQuark clock_name)
-{
-       return g_hash_table_lookup(trace->parent.clocks, GUINT_TO_POINTER(clock_name));
-}
-
-static
-int visit_type_specifier(FILE *fd, struct ctf_node *type_specifier, GString *str)
-{
-       if (type_specifier->type != NODE_TYPE_SPECIFIER)
-               return -EINVAL;
-
-       switch (type_specifier->u.type_specifier.type) {
-       case TYPESPEC_VOID:
-               g_string_append(str, "void");
-               break;
-       case TYPESPEC_CHAR:
-               g_string_append(str, "char");
-               break;
-       case TYPESPEC_SHORT:
-               g_string_append(str, "short");
-               break;
-       case TYPESPEC_INT:
-               g_string_append(str, "int");
-               break;
-       case TYPESPEC_LONG:
-               g_string_append(str, "long");
-               break;
-       case TYPESPEC_FLOAT:
-               g_string_append(str, "float");
-               break;
-       case TYPESPEC_DOUBLE:
-               g_string_append(str, "double");
-               break;
-       case TYPESPEC_SIGNED:
-               g_string_append(str, "signed");
-               break;
-       case TYPESPEC_UNSIGNED:
-               g_string_append(str, "unsigned");
-               break;
-       case TYPESPEC_BOOL:
-               g_string_append(str, "bool");
-               break;
-       case TYPESPEC_COMPLEX:
-               g_string_append(str, "_Complex");
-               break;
-       case TYPESPEC_IMAGINARY:
-               g_string_append(str, "_Imaginary");
-               break;
-       case TYPESPEC_CONST:
-               g_string_append(str, "const");
-               break;
-       case TYPESPEC_ID_TYPE:
-               if (type_specifier->u.type_specifier.id_type)
-                       g_string_append(str, type_specifier->u.type_specifier.id_type);
-               break;
-       case TYPESPEC_STRUCT:
-       {
-               struct ctf_node *node = type_specifier->u.type_specifier.node;
-
-               if (!node->u._struct.name) {
-                       fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
-                       return -EINVAL;
-               }
-               g_string_append(str, "struct ");
-               g_string_append(str, node->u._struct.name);
-               break;
-       }
-       case TYPESPEC_VARIANT:
-       {
-               struct ctf_node *node = type_specifier->u.type_specifier.node;
-
-               if (!node->u.variant.name) {
-                       fprintf(fd, "[error] %s: unexpected empty variant name\n", __func__);
-                       return -EINVAL;
-               }
-               g_string_append(str, "variant ");
-               g_string_append(str, node->u.variant.name);
-               break;
-       }
-       case TYPESPEC_ENUM:
-       {
-               struct ctf_node *node = type_specifier->u.type_specifier.node;
-
-               if (!node->u._enum.enum_id) {
-                       fprintf(fd, "[error] %s: unexpected empty enum ID\n", __func__);
-                       return -EINVAL;
-               }
-               g_string_append(str, "enum ");
-               g_string_append(str, node->u._enum.enum_id);
-               break;
-       }
-       case TYPESPEC_FLOATING_POINT:
-       case TYPESPEC_INTEGER:
-       case TYPESPEC_STRING:
-       default:
-               fprintf(fd, "[error] %s: unknown specifier\n", __func__);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-int visit_type_specifier_list(FILE *fd, struct ctf_node *type_specifier_list, GString *str)
-{
-       struct ctf_node *iter;
-       int alias_item_nr = 0;
-       int ret;
-
-       bt_list_for_each_entry(iter, &type_specifier_list->u.type_specifier_list.head, siblings) {
-               if (alias_item_nr != 0)
-                       g_string_append(str, " ");
-               alias_item_nr++;
-               ret = visit_type_specifier(fd, iter, str);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static
-GQuark create_typealias_identifier(FILE *fd, int depth,
-       struct ctf_node *type_specifier_list,
-       struct ctf_node *node_type_declarator)
-{
-       struct ctf_node *iter;
-       GString *str;
-       char *str_c;
-       GQuark alias_q;
-       int ret;
-
-       str = g_string_new("");
-       ret = visit_type_specifier_list(fd, type_specifier_list, str);
-       if (ret) {
-               g_string_free(str, TRUE);
-               return 0;
-       }
-       bt_list_for_each_entry(iter, &node_type_declarator->u.type_declarator.pointers, siblings) {
-               g_string_append(str, " *");
-               if (iter->u.pointer.const_qualifier)
-                       g_string_append(str, " const");
-       }
-       str_c = g_string_free(str, FALSE);
-       alias_q = g_quark_from_string(str_c);
-       g_free(str_c);
-       return alias_q;
-}
-
-static
-struct bt_declaration *ctf_type_declarator_visit(FILE *fd, int depth,
-       struct ctf_node *type_specifier_list,
-       GQuark *field_name,
-       struct ctf_node *node_type_declarator,
-       struct declaration_scope *declaration_scope,
-       struct bt_declaration *nested_declaration,
-       struct ctf_trace *trace)
-{
-       /*
-        * Visit type declarator by first taking care of sequence/array
-        * (recursively). Then, when we get to the identifier, take care
-        * of pointers.
-        */
-
-       if (node_type_declarator) {
-               if (node_type_declarator->u.type_declarator.type == TYPEDEC_UNKNOWN) {
-                       return NULL;
-               }
-
-               /* TODO: gcc bitfields not supported yet. */
-               if (node_type_declarator->u.type_declarator.bitfield_len != NULL) {
-                       fprintf(fd, "[error] %s: gcc bitfields are not supported yet.\n", __func__);
-                       return NULL;
-               }
-       }
-
-       if (!nested_declaration) {
-               if (node_type_declarator && !bt_list_empty(&node_type_declarator->u.type_declarator.pointers)) {
-                       GQuark alias_q;
-
-                       /*
-                        * If we have a pointer declarator, it _has_ to be present in
-                        * the typealiases (else fail).
-                        */
-                       alias_q = create_typealias_identifier(fd, depth,
-                               type_specifier_list, node_type_declarator);
-                       nested_declaration = bt_lookup_declaration(alias_q, declaration_scope);
-                       if (!nested_declaration) {
-                               fprintf(fd, "[error] %s: cannot find typealias \"%s\".\n", __func__, g_quark_to_string(alias_q));
-                               return NULL;
-                       }
-                       if (nested_declaration->id == BT_CTF_TYPE_ID_INTEGER) {
-                               struct declaration_integer *integer_declaration =
-                                       container_of(nested_declaration, struct declaration_integer, p);
-                               /* For base to 16 for pointers (expected pretty-print) */
-                               if (!integer_declaration->base) {
-                                       /*
-                                        * We need to do a copy of the
-                                        * integer declaration to modify it. There could be other references to
-                                        * it.
-                                        */
-                                       integer_declaration = bt_integer_declaration_new(integer_declaration->len,
-                                               integer_declaration->byte_order, integer_declaration->signedness,
-                                               integer_declaration->p.alignment, 16, integer_declaration->encoding,
-                                               integer_declaration->clock);
-                                       nested_declaration = &integer_declaration->p;
-                               }
-                       }
-               } else {
-                       nested_declaration = ctf_type_specifier_list_visit(fd, depth,
-                               type_specifier_list, declaration_scope, trace);
-               }
-       }
-
-       if (!node_type_declarator)
-               return nested_declaration;
-
-       if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
-               if (node_type_declarator->u.type_declarator.u.id)
-                       *field_name = g_quark_from_string(node_type_declarator->u.type_declarator.u.id);
-               else
-                       *field_name = 0;
-               return nested_declaration;
-       } else {
-               struct bt_declaration *declaration;
-               struct ctf_node *first;
-
-               /* TYPEDEC_NESTED */
-
-               if (!nested_declaration) {
-                       fprintf(fd, "[error] %s: nested type is unknown.\n", __func__);
-                       return NULL;
-               }
-
-               /* create array/sequence, pass nested_declaration as child. */
-               if (bt_list_empty(&node_type_declarator->u.type_declarator.u.nested.length)) {
-                       fprintf(fd, "[error] %s: expecting length field reference or value.\n", __func__);
-                       return NULL;
-               }
-               first = _bt_list_first_entry(&node_type_declarator->u.type_declarator.u.nested.length,
-                               struct ctf_node, siblings);
-               if (first->type != NODE_UNARY_EXPRESSION) {
-                       return NULL;
-               }
-
-               switch (first->u.unary_expression.type) {
-               case UNARY_UNSIGNED_CONSTANT:
-               {
-                       struct declaration_array *array_declaration;
-                       size_t len;
-
-                       len = first->u.unary_expression.u.unsigned_constant;
-                       array_declaration = bt_array_declaration_new(len, nested_declaration,
-                                               declaration_scope);
-
-                       if (!array_declaration) {
-                               fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
-                               return NULL;
-                       }
-                       bt_declaration_unref(nested_declaration);
-                       declaration = &array_declaration->p;
-                       break;
-               }
-               case UNARY_STRING:
-               {
-                       /* Lookup unsigned integer definition, create sequence */
-                       char *length_name = concatenate_unary_strings(&node_type_declarator->u.type_declarator.u.nested.length);
-                       struct declaration_sequence *sequence_declaration;
-
-                       if (!length_name)
-                               return NULL;
-                       sequence_declaration = bt_sequence_declaration_new(length_name, nested_declaration, declaration_scope);
-                       if (!sequence_declaration) {
-                               fprintf(fd, "[error] %s: cannot create sequence declaration.\n", __func__);
-                               g_free(length_name);
-                               return NULL;
-                       }
-                       bt_declaration_unref(nested_declaration);
-                       declaration = &sequence_declaration->p;
-                       g_free(length_name);
-                       break;
-               }
-               default:
-                       return NULL;
-               }
-
-               /* Pass it as content of outer container */
-               declaration = ctf_type_declarator_visit(fd, depth,
-                               type_specifier_list, field_name,
-                               node_type_declarator->u.type_declarator.u.nested.type_declarator,
-                               declaration_scope, declaration, trace);
-               return declaration;
-       }
-}
-
-static
-int ctf_struct_type_declarators_visit(FILE *fd, int depth,
-       struct declaration_struct *struct_declaration,
-       struct ctf_node *type_specifier_list,
-       struct bt_list_head *type_declarators,
-       struct declaration_scope *declaration_scope,
-       struct ctf_trace *trace)
-{
-       struct ctf_node *iter;
-       GQuark field_name;
-
-       bt_list_for_each_entry(iter, type_declarators, siblings) {
-               struct bt_declaration *field_declaration;
-
-               field_declaration = ctf_type_declarator_visit(fd, depth,
-                                               type_specifier_list,
-                                               &field_name, iter,
-                                               struct_declaration->scope,
-                                               NULL, trace);
-               if (!field_declaration) {
-                       fprintf(fd, "[error] %s: unable to find struct field declaration type\n", __func__);
-                       return -EINVAL;
-               }
-
-               /* Check if field with same name already exists */
-               if (bt_struct_declaration_lookup_field_index(struct_declaration, field_name) >= 0) {
-                       fprintf(fd, "[error] %s: duplicate field %s in struct\n", __func__, g_quark_to_string(field_name));
-                       return -EINVAL;
-               }
-
-               bt_struct_declaration_add_field(struct_declaration,
-                                            g_quark_to_string(field_name),
-                                            field_declaration);
-               bt_declaration_unref(field_declaration);
-       }
-       return 0;
-}
-
-static
-int ctf_variant_type_declarators_visit(FILE *fd, int depth,
-       struct declaration_untagged_variant *untagged_variant_declaration,
-       struct ctf_node *type_specifier_list,
-       struct bt_list_head *type_declarators,
-       struct declaration_scope *declaration_scope,
-       struct ctf_trace *trace)
-{
-       struct ctf_node *iter;
-       GQuark field_name;
-
-       bt_list_for_each_entry(iter, type_declarators, siblings) {
-               struct bt_declaration *field_declaration;
-
-               field_declaration = ctf_type_declarator_visit(fd, depth,
-                                               type_specifier_list,
-                                               &field_name, iter,
-                                               untagged_variant_declaration->scope,
-                                               NULL, trace);
-               if (!field_declaration) {
-                       fprintf(fd, "[error] %s: unable to find variant field declaration type\n", __func__);
-                       return -EINVAL;
-               }
-
-               if (bt_untagged_variant_declaration_get_field_from_tag(untagged_variant_declaration, field_name) != NULL) {
-                       fprintf(fd, "[error] %s: duplicate field %s in variant\n", __func__, g_quark_to_string(field_name));
-                       return -EINVAL;
-               }
-
-               bt_untagged_variant_declaration_add_field(untagged_variant_declaration,
-                                             g_quark_to_string(field_name),
-                                             field_declaration);
-               bt_declaration_unref(field_declaration);
-       }
-       return 0;
-}
-
-static
-int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
-               struct ctf_node *type_specifier_list,
-               struct bt_list_head *type_declarators,
-               struct ctf_trace *trace)
-{
-       struct ctf_node *iter;
-       GQuark identifier;
-
-       bt_list_for_each_entry(iter, type_declarators, siblings) {
-               struct bt_declaration *type_declaration;
-               int ret;
-
-               type_declaration = ctf_type_declarator_visit(fd, depth,
-                                       type_specifier_list,
-                                       &identifier, iter,
-                                       scope, NULL, trace);
-               if (!type_declaration) {
-                       fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
-                       return -EINVAL;
-               }
-               /*
-                * Don't allow typedef and typealias of untagged
-                * variants.
-                */
-               if (type_declaration->id == BT_CTF_TYPE_ID_UNTAGGED_VARIANT) {
-                       fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
-                       bt_declaration_unref(type_declaration);
-                       return -EPERM;
-               }
-               ret = bt_register_declaration(identifier, type_declaration, scope);
-               if (ret) {
-                       type_declaration->declaration_free(type_declaration);
-                       return ret;
-               }
-               bt_declaration_unref(type_declaration);
-       }
-       return 0;
-}
-
-static
-int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
-               struct ctf_node *target, struct ctf_node *alias,
-               struct ctf_trace *trace)
-{
-       struct bt_declaration *type_declaration;
-       struct ctf_node *node;
-       GQuark dummy_id;
-       GQuark alias_q;
-       int err;
-
-       /* See ctf_visitor_type_declarator() in the semantic validator. */
-
-       /*
-        * Create target type declaration.
-        */
-
-       if (bt_list_empty(&target->u.typealias_target.type_declarators))
-               node = NULL;
-       else
-               node = _bt_list_first_entry(&target->u.typealias_target.type_declarators,
-                               struct ctf_node, siblings);
-       type_declaration = ctf_type_declarator_visit(fd, depth,
-               target->u.typealias_target.type_specifier_list,
-               &dummy_id, node,
-               scope, NULL, trace);
-       if (!type_declaration) {
-               fprintf(fd, "[error] %s: problem creating type declaration\n", __func__);
-               err = -EINVAL;
-               goto error;
-       }
-       /*
-        * Don't allow typedef and typealias of untagged
-        * variants.
-        */
-       if (type_declaration->id == BT_CTF_TYPE_ID_UNTAGGED_VARIANT) {
-               fprintf(fd, "[error] %s: typedef of untagged variant is not permitted.\n", __func__);
-               bt_declaration_unref(type_declaration);
-               return -EPERM;
-       }
-       /*
-        * The semantic validator does not check whether the target is
-        * abstract or not (if it has an identifier). Check it here.
-        */
-       if (dummy_id != 0) {
-               fprintf(fd, "[error] %s: expecting empty identifier\n", __func__);
-               err = -EINVAL;
-               goto error;
-       }
-       /*
-        * Create alias identifier.
-        */
-
-       node = _bt_list_first_entry(&alias->u.typealias_alias.type_declarators,
-                               struct ctf_node, siblings);
-       alias_q = create_typealias_identifier(fd, depth,
-                       alias->u.typealias_alias.type_specifier_list, node);
-       err = bt_register_declaration(alias_q, type_declaration, scope);
-       if (err)
-               goto error;
-       bt_declaration_unref(type_declaration);
-       return 0;
-
-error:
-       if (type_declaration) {
-               type_declaration->declaration_free(type_declaration);
-       }
-       return err;
-}
-
-static
-int ctf_struct_declaration_list_visit(FILE *fd, int depth,
-       struct ctf_node *iter, struct declaration_struct *struct_declaration,
-       struct ctf_trace *trace)
-{
-       int ret;
-
-       switch (iter->type) {
-       case NODE_TYPEDEF:
-               /* For each declarator, declare type and add type to struct bt_declaration scope */
-               ret = ctf_typedef_visit(fd, depth,
-                       struct_declaration->scope,
-                       iter->u._typedef.type_specifier_list,
-                       &iter->u._typedef.type_declarators, trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               /* Declare type with declarator and add type to struct bt_declaration scope */
-               ret = ctf_typealias_visit(fd, depth,
-                       struct_declaration->scope,
-                       iter->u.typealias.target,
-                       iter->u.typealias.alias, trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               /* Add field to structure declaration */
-               ret = ctf_struct_type_declarators_visit(fd, depth,
-                               struct_declaration,
-                               iter->u.struct_or_variant_declaration.type_specifier_list,
-                               &iter->u.struct_or_variant_declaration.type_declarators,
-                               struct_declaration->scope, trace);
-               if (ret)
-                       return ret;
-               break;
-       default:
-               fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-int ctf_variant_declaration_list_visit(FILE *fd, int depth,
-       struct ctf_node *iter,
-       struct declaration_untagged_variant *untagged_variant_declaration,
-       struct ctf_trace *trace)
-{
-       int ret;
-
-       switch (iter->type) {
-       case NODE_TYPEDEF:
-               /* For each declarator, declare type and add type to variant declaration scope */
-               ret = ctf_typedef_visit(fd, depth,
-                       untagged_variant_declaration->scope,
-                       iter->u._typedef.type_specifier_list,
-                       &iter->u._typedef.type_declarators, trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               /* Declare type with declarator and add type to variant declaration scope */
-               ret = ctf_typealias_visit(fd, depth,
-                       untagged_variant_declaration->scope,
-                       iter->u.typealias.target,
-                       iter->u.typealias.alias, trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               /* Add field to structure declaration */
-               ret = ctf_variant_type_declarators_visit(fd, depth,
-                               untagged_variant_declaration,
-                               iter->u.struct_or_variant_declaration.type_specifier_list,
-                               &iter->u.struct_or_variant_declaration.type_declarators,
-                               untagged_variant_declaration->scope, trace);
-               if (ret)
-                       return ret;
-               break;
-       default:
-               fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) iter->type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-struct bt_declaration *ctf_declaration_struct_visit(FILE *fd,
-       int depth, const char *name, struct bt_list_head *declaration_list,
-       int has_body, struct bt_list_head *min_align,
-       struct declaration_scope *declaration_scope,
-       struct ctf_trace *trace)
-{
-       struct declaration_struct *struct_declaration;
-       struct ctf_node *iter;
-
-       /*
-        * For named struct (without body), lookup in
-        * declaration scope. Don't take reference on struct
-        * declaration: ref is only taken upon definition.
-        */
-       if (!has_body) {
-               if (!name)
-                       return NULL;
-               struct_declaration =
-                       bt_lookup_struct_declaration(g_quark_from_string(name),
-                                                 declaration_scope);
-               bt_declaration_ref(&struct_declaration->p);
-               return &struct_declaration->p;
-       } else {
-               uint64_t min_align_value = 0;
-
-               /* For unnamed struct, create type */
-               /* For named struct (with body), create type and add to declaration scope */
-               if (name) {
-                       if (bt_lookup_struct_declaration(g_quark_from_string(name),
-                                                     declaration_scope)) {
-                               fprintf(fd, "[error] %s: struct %s already declared in scope\n", __func__, name);
-                               return NULL;
-                       }
-               }
-               if (!bt_list_empty(min_align)) {
-                       int ret;
-
-                       ret = get_unary_unsigned(min_align, &min_align_value);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for structure \"align\" attribute\n", __func__);
-                               goto error;
-                       }
-               }
-               struct_declaration = bt_struct_declaration_new(declaration_scope,
-                                                           min_align_value);
-               bt_list_for_each_entry(iter, declaration_list, siblings) {
-                       int ret;
-
-                       ret = ctf_struct_declaration_list_visit(fd, depth + 1, iter,
-                               struct_declaration, trace);
-                       if (ret)
-                               goto error_free_declaration;
-               }
-               if (name) {
-                       int ret;
-
-                       ret = bt_register_struct_declaration(g_quark_from_string(name),
-                                       struct_declaration,
-                                       declaration_scope);
-                       if (ret)
-                               return NULL;
-               }
-               return &struct_declaration->p;
-       }
-error_free_declaration:
-       struct_declaration->p.declaration_free(&struct_declaration->p);
-error:
-       return NULL;
-}
-
-static
-struct bt_declaration *ctf_declaration_variant_visit(FILE *fd,
-       int depth, const char *name, const char *choice,
-       struct bt_list_head *declaration_list,
-       int has_body, struct declaration_scope *declaration_scope,
-       struct ctf_trace *trace)
-{
-       struct declaration_untagged_variant *untagged_variant_declaration;
-       struct declaration_variant *variant_declaration;
-       struct ctf_node *iter;
-
-       /*
-        * For named variant (without body), lookup in
-        * declaration scope. Don't take reference on variant
-        * declaration: ref is only taken upon definition.
-        */
-       if (!has_body) {
-               if (!name)
-                       return NULL;
-               untagged_variant_declaration =
-                       bt_lookup_variant_declaration(g_quark_from_string(name),
-                                                  declaration_scope);
-               bt_declaration_ref(&untagged_variant_declaration->p);
-       } else {
-               /* For unnamed variant, create type */
-               /* For named variant (with body), create type and add to declaration scope */
-               if (name) {
-                       if (bt_lookup_variant_declaration(g_quark_from_string(name),
-                                                      declaration_scope)) {
-                               fprintf(fd, "[error] %s: variant %s already declared in scope\n", __func__, name);
-                               return NULL;
-                       }
-               }
-               untagged_variant_declaration = bt_untagged_bt_variant_declaration_new(declaration_scope);
-               bt_list_for_each_entry(iter, declaration_list, siblings) {
-                       int ret;
-
-                       ret = ctf_variant_declaration_list_visit(fd, depth + 1, iter,
-                               untagged_variant_declaration, trace);
-                       if (ret)
-                               goto error;
-               }
-               if (name) {
-                       int ret;
-
-                       ret = bt_register_variant_declaration(g_quark_from_string(name),
-                                       untagged_variant_declaration,
-                                       declaration_scope);
-                       if (ret)
-                               return NULL;
-               }
-       }
-       /*
-        * if tagged, create tagged variant and return. else return
-        * untagged variant.
-        */
-       if (!choice) {
-               return &untagged_variant_declaration->p;
-       } else {
-               variant_declaration = bt_variant_declaration_new(untagged_variant_declaration, choice);
-               if (!variant_declaration)
-                       goto error;
-               bt_declaration_unref(&untagged_variant_declaration->p);
-               return &variant_declaration->p;
-       }
-error:
-       untagged_variant_declaration->p.declaration_free(&untagged_variant_declaration->p);
-       return NULL;
-}
-
-static
-int ctf_enumerator_list_visit(FILE *fd, int depth,
-               struct ctf_node *enumerator,
-               struct declaration_enum *enum_declaration,
-               struct last_enum_value *last)
-{
-       GQuark q;
-       struct ctf_node *iter;
-
-       q = g_quark_from_string(enumerator->u.enumerator.id);
-       if (enum_declaration->integer_declaration->signedness) {
-               int64_t start = 0, end = 0;
-               int nr_vals = 0;
-
-               bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
-                       int64_t *target;
-
-                       if (iter->type != NODE_UNARY_EXPRESSION)
-                               return -EINVAL;
-                       if (nr_vals == 0)
-                               target = &start;
-                       else
-                               target = &end;
-
-                       switch (iter->u.unary_expression.type) {
-                       case UNARY_SIGNED_CONSTANT:
-                               *target = iter->u.unary_expression.u.signed_constant;
-                               break;
-                       case UNARY_UNSIGNED_CONSTANT:
-                               *target = iter->u.unary_expression.u.unsigned_constant;
-                               break;
-                       default:
-                               fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
-                               return -EINVAL;
-                       }
-                       if (nr_vals > 1) {
-                               fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
-                               return -EINVAL;
-                       }
-                       nr_vals++;
-               }
-               if (nr_vals == 0)
-                       start = last->u.s;
-               if (nr_vals <= 1)
-                       end = start;
-               last->u.s = end + 1;
-               bt_enum_signed_insert(enum_declaration, start, end, q);
-       } else {
-               uint64_t start = 0, end = 0;
-               int nr_vals = 0;
-
-               bt_list_for_each_entry(iter, &enumerator->u.enumerator.values, siblings) {
-                       uint64_t *target;
-
-                       if (iter->type != NODE_UNARY_EXPRESSION)
-                               return -EINVAL;
-                       if (nr_vals == 0)
-                               target = &start;
-                       else
-                               target = &end;
-
-                       switch (iter->u.unary_expression.type) {
-                       case UNARY_UNSIGNED_CONSTANT:
-                               *target = iter->u.unary_expression.u.unsigned_constant;
-                               break;
-                       case UNARY_SIGNED_CONSTANT:
-                               /*
-                                * We don't accept signed constants for enums with unsigned
-                                * container type.
-                                */
-                               fprintf(fd, "[error] %s: invalid enumerator (signed constant encountered, but enum container type is unsigned)\n", __func__);
-                               return -EINVAL;
-                       default:
-                               fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
-                               return -EINVAL;
-                       }
-                       if (nr_vals > 1) {
-                               fprintf(fd, "[error] %s: invalid enumerator\n", __func__);
-                               return -EINVAL;
-                       }
-                       nr_vals++;
-               }
-               if (nr_vals == 0)
-                       start = last->u.u;
-               if (nr_vals <= 1)
-                       end = start;
-               last->u.u = end + 1;
-               bt_enum_unsigned_insert(enum_declaration, start, end, q);
-       }
-       return 0;
-}
-
-static
-struct bt_declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
-                       const char *name,
-                       struct ctf_node *container_type,
-                       struct bt_list_head *enumerator_list,
-                       int has_body,
-                       struct declaration_scope *declaration_scope,
-                       struct ctf_trace *trace)
-{
-       struct bt_declaration *declaration;
-       struct declaration_enum *enum_declaration;
-       struct declaration_integer *integer_declaration;
-       struct last_enum_value last_value;
-       struct ctf_node *iter;
-       GQuark dummy_id;
-
-       /*
-        * For named enum (without body), lookup in
-        * declaration scope. Don't take reference on enum
-        * declaration: ref is only taken upon definition.
-        */
-       if (!has_body) {
-               if (!name)
-                       return NULL;
-               enum_declaration =
-                       bt_lookup_enum_declaration(g_quark_from_string(name),
-                                               declaration_scope);
-               bt_declaration_ref(&enum_declaration->p);
-               return &enum_declaration->p;
-       } else {
-               /* For unnamed enum, create type */
-               /* For named enum (with body), create type and add to declaration scope */
-               if (name) {
-                       if (bt_lookup_enum_declaration(g_quark_from_string(name),
-                                                   declaration_scope)) {
-                               fprintf(fd, "[error] %s: enum %s already declared in scope\n", __func__, name);
-                               return NULL;
-                       }
-               }
-               if (!container_type) {
-                       declaration = bt_lookup_declaration(g_quark_from_string("int"),
-                                                        declaration_scope);
-                       if (!declaration) {
-                               fprintf(fd, "[error] %s: \"int\" type declaration missing for enumeration\n", __func__);
-                               return NULL;
-                       }
-               } else {
-                       declaration = ctf_type_declarator_visit(fd, depth,
-                                               container_type,
-                                               &dummy_id, NULL,
-                                               declaration_scope,
-                                               NULL, trace);
-               }
-               if (!declaration) {
-                       fprintf(fd, "[error] %s: unable to create container type for enumeration\n", __func__);
-                       return NULL;
-               }
-               if (declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-                       fprintf(fd, "[error] %s: container type for enumeration is not integer\n", __func__);
-                       return NULL;
-               }
-               integer_declaration = container_of(declaration, struct declaration_integer, p);
-               enum_declaration = bt_enum_declaration_new(integer_declaration);
-               bt_declaration_unref(&integer_declaration->p);  /* leave ref to enum */
-               if (enum_declaration->integer_declaration->signedness) {
-                       last_value.u.s = 0;
-               } else {
-                       last_value.u.u = 0;
-               }
-               bt_list_for_each_entry(iter, enumerator_list, siblings) {
-                       int ret;
-
-                       ret = ctf_enumerator_list_visit(fd, depth + 1, iter, enum_declaration,
-                                       &last_value);
-                       if (ret)
-                               goto error;
-               }
-               if (name) {
-                       int ret;
-
-                       ret = bt_register_enum_declaration(g_quark_from_string(name),
-                                       enum_declaration,
-                                       declaration_scope);
-                       if (ret)
-                               return NULL;
-                       bt_declaration_unref(&enum_declaration->p);
-               }
-               return &enum_declaration->p;
-       }
-error:
-       enum_declaration->p.declaration_free(&enum_declaration->p);
-       return NULL;
-}
-
-static
-struct bt_declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
-               struct ctf_node *type_specifier_list,
-               struct declaration_scope *declaration_scope)
-{
-       GString *str;
-       struct bt_declaration *declaration;
-       char *str_c;
-       int ret;
-       GQuark id_q;
-
-       str = g_string_new("");
-       ret = visit_type_specifier_list(fd, type_specifier_list, str);
-       if (ret) {
-               (void) g_string_free(str, TRUE);
-               return NULL;
-       }
-       str_c = g_string_free(str, FALSE);
-       id_q = g_quark_from_string(str_c);
-       g_free(str_c);
-       declaration = bt_lookup_declaration(id_q, declaration_scope);
-       if (!declaration)
-               return NULL;
-       bt_declaration_ref(declaration);
-       return declaration;
-}
-
-/*
- * Returns 0/1 boolean, or < 0 on error.
- */
-static
-int get_boolean(FILE *fd, int depth, struct ctf_node *unary_expression)
-{
-       if (unary_expression->type != NODE_UNARY_EXPRESSION) {
-               fprintf(fd, "[error] %s: expecting unary expression\n",
-                       __func__);
-               return -EINVAL;
-       }
-       switch (unary_expression->u.unary_expression.type) {
-       case UNARY_UNSIGNED_CONSTANT:
-               if (unary_expression->u.unary_expression.u.unsigned_constant == 0)
-                       return 0;
-               else
-                       return 1;
-       case UNARY_SIGNED_CONSTANT:
-               if (unary_expression->u.unary_expression.u.signed_constant == 0)
-                       return 0;
-               else
-                       return 1;
-       case UNARY_STRING:
-               if (!strcmp(unary_expression->u.unary_expression.u.string, "true"))
-                       return 1;
-               else if (!strcmp(unary_expression->u.unary_expression.u.string, "TRUE"))
-                       return 1;
-               else if (!strcmp(unary_expression->u.unary_expression.u.string, "false"))
-                       return 0;
-               else if (!strcmp(unary_expression->u.unary_expression.u.string, "FALSE"))
-                       return 0;
-               else {
-                       fprintf(fd, "[error] %s: unexpected string \"%s\"\n",
-                               __func__, unary_expression->u.unary_expression.u.string);
-                       return -EINVAL;
-               }
-               break;
-       default:
-               fprintf(fd, "[error] %s: unexpected unary expression type\n",
-                       __func__);
-               return -EINVAL;
-       }
-
-}
-
-static
-int get_trace_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression)
-{
-       int byte_order;
-
-       if (unary_expression->u.unary_expression.type != UNARY_STRING) {
-               fprintf(fd, "[error] %s: byte_order: expecting string\n",
-                       __func__);
-               return -EINVAL;
-       }
-       if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
-               byte_order = BIG_ENDIAN;
-       else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
-               byte_order = LITTLE_ENDIAN;
-       else {
-               fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"be\" or \"le\".\n",
-                       __func__, unary_expression->u.unary_expression.u.string);
-               return -EINVAL;
-       }
-       return byte_order;
-}
-
-static
-int get_byte_order(FILE *fd, int depth, struct ctf_node *unary_expression,
-               struct ctf_trace *trace)
-{
-       int byte_order;
-
-       if (unary_expression->u.unary_expression.type != UNARY_STRING) {
-               fprintf(fd, "[error] %s: byte_order: expecting string\n",
-                       __func__);
-               return -EINVAL;
-       }
-       if (!strcmp(unary_expression->u.unary_expression.u.string, "native"))
-               byte_order = trace->byte_order;
-       else if (!strcmp(unary_expression->u.unary_expression.u.string, "network"))
-               byte_order = BIG_ENDIAN;
-       else if (!strcmp(unary_expression->u.unary_expression.u.string, "be"))
-               byte_order = BIG_ENDIAN;
-       else if (!strcmp(unary_expression->u.unary_expression.u.string, "le"))
-               byte_order = LITTLE_ENDIAN;
-       else {
-               fprintf(fd, "[error] %s: unexpected string \"%s\". Should be \"native\", \"network\", \"be\" or \"le\".\n",
-                       __func__, unary_expression->u.unary_expression.u.string);
-               return -EINVAL;
-       }
-       return byte_order;
-}
-
-static
-struct bt_declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
-               struct bt_list_head *expressions,
-               struct ctf_trace *trace)
-{
-       struct ctf_node *expression;
-       uint64_t alignment = 1, size = 0;
-       int byte_order = trace->byte_order;
-       int signedness = 0;
-       int has_alignment = 0, has_size = 0;
-       int base = 0;
-       enum ctf_string_encoding encoding = CTF_STRING_NONE;
-       struct ctf_clock *clock = NULL;
-       struct declaration_integer *integer_declaration;
-
-       bt_list_for_each_entry(expression, expressions, siblings) {
-               struct ctf_node *left, *right;
-
-               left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
-               right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
-               if (left->u.unary_expression.type != UNARY_STRING)
-                       return NULL;
-               if (!strcmp(left->u.unary_expression.u.string, "signed")) {
-                       signedness = get_boolean(fd, depth, right);
-                       if (signedness < 0)
-                               return NULL;
-               } else if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
-                       byte_order = get_byte_order(fd, depth, right, trace);
-                       if (byte_order < 0)
-                               return NULL;
-               } else if (!strcmp(left->u.unary_expression.u.string, "size")) {
-                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
-                               fprintf(fd, "[error] %s: size: expecting unsigned constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       size = right->u.unary_expression.u.unsigned_constant;
-                       if (!size) {
-                               fprintf(fd, "[error] %s: integer size: expecting non-zero constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       has_size = 1;
-               } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
-                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
-                               fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       alignment = right->u.unary_expression.u.unsigned_constant;
-                       /* Make sure alignment is a power of two */
-                       if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
-                               fprintf(fd, "[error] %s: align: expecting power of two\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       has_alignment = 1;
-               } else if (!strcmp(left->u.unary_expression.u.string, "base")) {
-                       switch (right->u.unary_expression.type) {
-                       case UNARY_UNSIGNED_CONSTANT:
-                               switch (right->u.unary_expression.u.unsigned_constant) {
-                               case 2:
-                               case 8:
-                               case 10:
-                               case 16:
-                                       base = right->u.unary_expression.u.unsigned_constant;
-                                       break;
-                               default:
-                                       fprintf(fd, "[error] %s: base not supported (%" PRIu64 ")\n",
-                                               __func__, right->u.unary_expression.u.unsigned_constant);
-                               return NULL;
-                               }
-                               break;
-                       case UNARY_STRING:
-                       {
-                               char *s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
-                               if (!s_right) {
-                                       fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
-                                       g_free(s_right);
-                                       return NULL;
-                               }
-                               if (!strcmp(s_right, "decimal") || !strcmp(s_right, "dec") || !strcmp(s_right, "d")
-                                   || !strcmp(s_right, "i") || !strcmp(s_right, "u")) {
-                                       base = 10;
-                               } else if (!strcmp(s_right, "hexadecimal") || !strcmp(s_right, "hex")
-                                   || !strcmp(s_right, "x") || !strcmp(s_right, "X")
-                                   || !strcmp(s_right, "p")) {
-                                       base = 16;
-                               } else if (!strcmp(s_right, "octal") || !strcmp(s_right, "oct")
-                                   || !strcmp(s_right, "o")) {
-                                       base = 8;
-                               } else if (!strcmp(s_right, "binary") || !strcmp(s_right, "b")) {
-                                       base = 2;
-                               } else {
-                                       fprintf(fd, "[error] %s: unexpected expression for integer base (%s)\n", __func__, s_right);
-                                       g_free(s_right);
-                                       return NULL;
-                               }
-
-                               g_free(s_right);
-                               break;
-                       }
-                       default:
-                               fprintf(fd, "[error] %s: base: expecting unsigned constant or unary string\n",
-                                       __func__);
-                               return NULL;
-                       }
-               } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
-                       char *s_right;
-
-                       if (right->u.unary_expression.type != UNARY_STRING) {
-                               fprintf(fd, "[error] %s: encoding: expecting unary string\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
-                       if (!s_right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
-                               g_free(s_right);
-                               return NULL;
-                       }
-                       if (!strcmp(s_right, "UTF8")
-                           || !strcmp(s_right, "utf8")
-                           || !strcmp(s_right, "utf-8")
-                           || !strcmp(s_right, "UTF-8"))
-                               encoding = CTF_STRING_UTF8;
-                       else if (!strcmp(s_right, "ASCII")
-                           || !strcmp(s_right, "ascii"))
-                               encoding = CTF_STRING_ASCII;
-                       else if (!strcmp(s_right, "none"))
-                               encoding = CTF_STRING_NONE;
-                       else {
-                               fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
-                               g_free(s_right);
-                               return NULL;
-                       }
-                       g_free(s_right);
-               } else if (!strcmp(left->u.unary_expression.u.string, "map")) {
-                       GQuark clock_name;
-
-                       if (right->u.unary_expression.type != UNARY_STRING) {
-                               fprintf(fd, "[error] %s: map: expecting identifier\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       /* currently only support clock.name.value */
-                       clock_name = get_map_clock_name_value(&expression->u.ctf_expression.right);
-                       if (!clock_name) {
-                               char *s_right;
-
-                               s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
-                               if (!s_right) {
-                                       fprintf(fd, "[error] %s: unexpected unary expression for integer map\n", __func__);
-                                       g_free(s_right);
-                                       return NULL;
-                               }
-                               fprintf(fd, "[warning] %s: unknown map %s in integer declaration\n", __func__,
-                                       s_right);
-                               g_free(s_right);
-                               continue;
-                       }
-                       clock = trace_clock_lookup(trace, clock_name);
-                       if (!clock) {
-                               fprintf(fd, "[error] %s: map: unable to find clock %s declaration\n",
-                                       __func__, g_quark_to_string(clock_name));
-                               return NULL;
-                       }
-               } else {
-                       fprintf(fd, "[warning] %s: unknown attribute name %s\n",
-                               __func__, left->u.unary_expression.u.string);
-                       /* Fall-through after warning */
-               }
-       }
-       if (!has_size) {
-               fprintf(fd, "[error] %s: missing size attribute\n", __func__);
-               return NULL;
-       }
-       if (!has_alignment) {
-               if (size % CHAR_BIT) {
-                       /* bit-packed alignment */
-                       alignment = 1;
-               } else {
-                       /* byte-packed alignment */
-                       alignment = CHAR_BIT;
-               }
-       }
-       integer_declaration = bt_integer_declaration_new(size,
-                               byte_order, signedness, alignment,
-                               base, encoding, clock);
-       return &integer_declaration->p;
-}
-
-static
-struct bt_declaration *ctf_declaration_floating_point_visit(FILE *fd, int depth,
-               struct bt_list_head *expressions,
-               struct ctf_trace *trace)
-{
-       struct ctf_node *expression;
-       uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
-       int byte_order = trace->byte_order, has_alignment = 0,
-               has_exp_dig = 0, has_mant_dig = 0;
-       struct declaration_float *float_declaration;
-
-       bt_list_for_each_entry(expression, expressions, siblings) {
-               struct ctf_node *left, *right;
-
-               left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
-               right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
-               if (left->u.unary_expression.type != UNARY_STRING)
-                       return NULL;
-               if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
-                       byte_order = get_byte_order(fd, depth, right, trace);
-                       if (byte_order < 0)
-                               return NULL;
-               } else if (!strcmp(left->u.unary_expression.u.string, "exp_dig")) {
-                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
-                               fprintf(fd, "[error] %s: exp_dig: expecting unsigned constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       exp_dig = right->u.unary_expression.u.unsigned_constant;
-                       has_exp_dig = 1;
-               } else if (!strcmp(left->u.unary_expression.u.string, "mant_dig")) {
-                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
-                               fprintf(fd, "[error] %s: mant_dig: expecting unsigned constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       mant_dig = right->u.unary_expression.u.unsigned_constant;
-                       has_mant_dig = 1;
-               } else if (!strcmp(left->u.unary_expression.u.string, "align")) {
-                       if (right->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) {
-                               fprintf(fd, "[error] %s: align: expecting unsigned constant\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       alignment = right->u.unary_expression.u.unsigned_constant;
-                       /* Make sure alignment is a power of two */
-                       if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
-                               fprintf(fd, "[error] %s: align: expecting power of two\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       has_alignment = 1;
-               } else {
-                       fprintf(fd, "[warning] %s: unknown attribute name %s\n",
-                               __func__, left->u.unary_expression.u.string);
-                       /* Fall-through after warning */
-               }
-       }
-       if (!has_mant_dig) {
-               fprintf(fd, "[error] %s: missing mant_dig attribute\n", __func__);
-               return NULL;
-       }
-       if (!has_exp_dig) {
-               fprintf(fd, "[error] %s: missing exp_dig attribute\n", __func__);
-               return NULL;
-       }
-       if (!has_alignment) {
-               if ((mant_dig + exp_dig) % CHAR_BIT) {
-                       /* bit-packed alignment */
-                       alignment = 1;
-               } else {
-                       /* byte-packed alignment */
-                       alignment = CHAR_BIT;
-               }
-       }
-       float_declaration = bt_float_declaration_new(mant_dig, exp_dig,
-                               byte_order, alignment);
-       return &float_declaration->p;
-}
-
-static
-struct bt_declaration *ctf_declaration_string_visit(FILE *fd, int depth,
-               struct bt_list_head *expressions,
-               struct ctf_trace *trace)
-{
-       struct ctf_node *expression;
-       const char *encoding_c = NULL;
-       enum ctf_string_encoding encoding = CTF_STRING_UTF8;
-       struct declaration_string *string_declaration;
-
-       bt_list_for_each_entry(expression, expressions, siblings) {
-               struct ctf_node *left, *right;
-
-               left = _bt_list_first_entry(&expression->u.ctf_expression.left, struct ctf_node, siblings);
-               right = _bt_list_first_entry(&expression->u.ctf_expression.right, struct ctf_node, siblings);
-               if (left->u.unary_expression.type != UNARY_STRING)
-                       return NULL;
-               if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
-                       if (right->u.unary_expression.type != UNARY_STRING) {
-                               fprintf(fd, "[error] %s: encoding: expecting string\n",
-                                       __func__);
-                               return NULL;
-                       }
-                       encoding_c = right->u.unary_expression.u.string;
-               } else {
-                       fprintf(fd, "[warning] %s: unknown attribute name %s\n",
-                               __func__, left->u.unary_expression.u.string);
-                       /* Fall-through after warning */
-               }
-       }
-       if (encoding_c && !strcmp(encoding_c, "ASCII"))
-               encoding = CTF_STRING_ASCII;
-       string_declaration = bt_string_declaration_new(encoding);
-       return &string_declaration->p;
-}
-
-
-static
-struct bt_declaration *ctf_type_specifier_list_visit(FILE *fd,
-               int depth, struct ctf_node *type_specifier_list,
-               struct declaration_scope *declaration_scope,
-               struct ctf_trace *trace)
-{
-       struct ctf_node *first;
-       struct ctf_node *node;
-
-       if (type_specifier_list->type != NODE_TYPE_SPECIFIER_LIST)
-               return NULL;
-
-       first = _bt_list_first_entry(&type_specifier_list->u.type_specifier_list.head, struct ctf_node, siblings);
-
-       if (first->type != NODE_TYPE_SPECIFIER)
-               return NULL;
-
-       node = first->u.type_specifier.node;
-
-       switch (first->u.type_specifier.type) {
-       case TYPESPEC_FLOATING_POINT:
-               return ctf_declaration_floating_point_visit(fd, depth,
-                       &node->u.floating_point.expressions, trace);
-       case TYPESPEC_INTEGER:
-               return ctf_declaration_integer_visit(fd, depth,
-                       &node->u.integer.expressions, trace);
-       case TYPESPEC_STRING:
-               return ctf_declaration_string_visit(fd, depth,
-                       &node->u.string.expressions, trace);
-       case TYPESPEC_STRUCT:
-               return ctf_declaration_struct_visit(fd, depth,
-                       node->u._struct.name,
-                       &node->u._struct.declaration_list,
-                       node->u._struct.has_body,
-                       &node->u._struct.min_align,
-                       declaration_scope,
-                       trace);
-       case TYPESPEC_VARIANT:
-               return ctf_declaration_variant_visit(fd, depth,
-                       node->u.variant.name,
-                       node->u.variant.choice,
-                       &node->u.variant.declaration_list,
-                       node->u.variant.has_body,
-                       declaration_scope,
-                       trace);
-       case TYPESPEC_ENUM:
-               return ctf_declaration_enum_visit(fd, depth,
-                       node->u._enum.enum_id,
-                       node->u._enum.container_type,
-                       &node->u._enum.enumerator_list,
-                       node->u._enum.has_body,
-                       declaration_scope,
-                       trace);
-
-       case TYPESPEC_VOID:
-       case TYPESPEC_CHAR:
-       case TYPESPEC_SHORT:
-       case TYPESPEC_INT:
-       case TYPESPEC_LONG:
-       case TYPESPEC_FLOAT:
-       case TYPESPEC_DOUBLE:
-       case TYPESPEC_SIGNED:
-       case TYPESPEC_UNSIGNED:
-       case TYPESPEC_BOOL:
-       case TYPESPEC_COMPLEX:
-       case TYPESPEC_IMAGINARY:
-       case TYPESPEC_CONST:
-       case TYPESPEC_ID_TYPE:
-               return ctf_declaration_type_specifier_visit(fd, depth,
-                       type_specifier_list, declaration_scope);
-       default:
-               fprintf(fd, "[error] %s: unexpected node type %d\n", __func__, (int) first->u.type_specifier.type);
-               return NULL;
-       }
-}
-
-static
-int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_event_declaration *event, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       switch (node->type) {
-       case NODE_TYPEDEF:
-               ret = ctf_typedef_visit(fd, depth + 1,
-                                       event->declaration_scope,
-                                       node->u._typedef.type_specifier_list,
-                                       &node->u._typedef.type_declarators,
-                                       trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               ret = ctf_typealias_visit(fd, depth + 1,
-                               event->declaration_scope,
-                               node->u.typealias.target, node->u.typealias.alias,
-                               trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "name")) {
-                       char *right;
-
-                       if (CTF_EVENT_FIELD_IS_SET(event, name)) {
-                               fprintf(fd, "[error] %s: name already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event name\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       event->name = g_quark_from_string(right);
-                       g_free(right);
-                       CTF_EVENT_SET_FIELD(event, name);
-               } else if (!strcmp(left, "id")) {
-                       if (CTF_EVENT_FIELD_IS_SET(event, id)) {
-                               fprintf(fd, "[error] %s: id already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->id);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event id\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_EVENT_SET_FIELD(event, id);
-               } else if (!strcmp(left, "stream_id")) {
-                       if (CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
-                               fprintf(fd, "[error] %s: stream_id already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &event->stream_id);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event stream_id\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       event->stream = trace_stream_lookup(trace, event->stream_id);
-                       if (!event->stream) {
-                               fprintf(fd, "[error] %s: stream id %" PRIu64 " cannot be found\n", __func__, event->stream_id);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_EVENT_SET_FIELD(event, stream_id);
-               } else if (!strcmp(left, "context")) {
-                       struct bt_declaration *declaration;
-
-                       if (event->context_decl) {
-                               fprintf(fd, "[error] %s: context already declared in event declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       event->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       event->context_decl = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "fields")) {
-                       struct bt_declaration *declaration;
-
-                       if (event->fields_decl) {
-                               fprintf(fd, "[error] %s: fields already declared in event declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       event->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       event->fields_decl = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "loglevel")) {
-                       int64_t loglevel = -1;
-
-                       if (CTF_EVENT_FIELD_IS_SET(event, loglevel)) {
-                               fprintf(fd, "[error] %s: loglevel already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_signed(&node->u.ctf_expression.right, &loglevel);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event loglevel\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       event->loglevel = (int) loglevel;
-                       CTF_EVENT_SET_FIELD(event, loglevel);
-               } else if (!strcmp(left, "model.emf.uri")) {
-                       char *right;
-
-                       if (CTF_EVENT_FIELD_IS_SET(event, model_emf_uri)) {
-                               fprintf(fd, "[error] %s: model.emf.uri already declared in event declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for event model.emf.uri\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       event->model_emf_uri = g_quark_from_string(right);
-                       g_free(right);
-                       CTF_EVENT_SET_FIELD(event, model_emf_uri);
-               } else {
-                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in event declaration.\n", __func__, left);
-                       /* Fall-through after warning */
-               }
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       /* TODO: declaration specifier should be added. */
-       }
-
-       return ret;
-}
-
-static
-int ctf_event_visit(FILE *fd, int depth, struct ctf_node *node,
-                   struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-       struct ctf_event_declaration *event;
-       struct bt_ctf_event_decl *event_decl;
-
-       if (node->visited)
-               return 0;
-       node->visited = 1;
-
-       event_decl = g_new0(struct bt_ctf_event_decl, 1);
-       event = &event_decl->parent;
-       event->declaration_scope = bt_new_declaration_scope(parent_declaration_scope);
-       event->loglevel = -1;
-       bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
-               ret = ctf_event_declaration_visit(fd, depth + 1, iter, event, trace);
-               if (ret)
-                       goto error;
-       }
-       if (!CTF_EVENT_FIELD_IS_SET(event, name)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing name field in event declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_EVENT_FIELD_IS_SET(event, stream_id)) {
-               /* Allow missing stream_id if there is only a single stream */
-               switch (trace->streams->len) {
-               case 0: /* Create stream if there was none. */
-                       ret = ctf_stream_visit(fd, depth, NULL, trace->root_declaration_scope, trace);
-                       if (ret)
-                               goto error;
-                       /* Fall-through */
-               case 1:
-                       event->stream_id = 0;
-                       event->stream = trace_stream_lookup(trace, event->stream_id);
-                       break;
-               default:
-                       ret = -EPERM;
-                       fprintf(fd, "[error] %s: missing stream_id field in event declaration\n", __func__);
-                       goto error;
-               }
-       }
-       /* Allow only one event without id per stream */
-       if (!CTF_EVENT_FIELD_IS_SET(event, id)
-           && event->stream->events_by_id->len != 0) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing id field in event declaration\n", __func__);
-               goto error;
-       }
-       /* Disallow re-using the same event ID in the same stream */
-       if (stream_event_lookup(event->stream, event->id)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: event ID %" PRIu64 " used more than once in stream %" PRIu64 "\n",
-                       __func__, event->id, event->stream_id);
-               goto error;
-       }
-       if (event->stream->events_by_id->len <= event->id)
-               g_ptr_array_set_size(event->stream->events_by_id, event->id + 1);
-       g_ptr_array_index(event->stream->events_by_id, event->id) = event;
-       g_hash_table_insert(event->stream->event_quark_to_id,
-                           GUINT_TO_POINTER(event->name),
-                           &event->id);
-       g_ptr_array_add(trace->event_declarations, event_decl);
-       return 0;
-
-error:
-       if (event->fields_decl)
-               bt_declaration_unref(&event->fields_decl->p);
-       if (event->context_decl)
-               bt_declaration_unref(&event->context_decl->p);
-       bt_free_declaration_scope(event->declaration_scope);
-       g_free(event_decl);
-       return ret;
-}
-
-
-static
-int ctf_stream_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_stream_declaration *stream, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       switch (node->type) {
-       case NODE_TYPEDEF:
-               ret = ctf_typedef_visit(fd, depth + 1,
-                                       stream->declaration_scope,
-                                       node->u._typedef.type_specifier_list,
-                                       &node->u._typedef.type_declarators,
-                                       trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               ret = ctf_typealias_visit(fd, depth + 1,
-                               stream->declaration_scope,
-                               node->u.typealias.target, node->u.typealias.alias,
-                               trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "id")) {
-                       if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
-                               fprintf(fd, "[error] %s: id already declared in stream declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &stream->stream_id);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for stream id\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_STREAM_SET_FIELD(stream, stream_id);
-               } else if (!strcmp(left, "event.header")) {
-                       struct bt_declaration *declaration;
-
-                       if (stream->event_header_decl) {
-                               fprintf(fd, "[error] %s: event.header already declared in stream declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       stream->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       stream->event_header_decl = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "event.context")) {
-                       struct bt_declaration *declaration;
-
-                       if (stream->event_context_decl) {
-                               fprintf(fd, "[error] %s: event.context already declared in stream declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       stream->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       stream->event_context_decl = container_of(declaration, struct declaration_struct, p);
-               } else if (!strcmp(left, "packet.context")) {
-                       struct bt_declaration *declaration;
-
-                       if (stream->packet_context_decl) {
-                               fprintf(fd, "[error] %s: packet.context already declared in stream declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       stream->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       stream->packet_context_decl = container_of(declaration, struct declaration_struct, p);
-               } else {
-                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in stream declaration.\n", __func__, left);
-                       /* Fall-through after warning */
-               }
-
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       /* TODO: declaration specifier should be added. */
-       }
-
-       return ret;
-}
-
-static
-int ctf_stream_visit(FILE *fd, int depth, struct ctf_node *node,
-                    struct declaration_scope *parent_declaration_scope, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-       struct ctf_stream_declaration *stream;
-
-       if (node) {
-               if (node->visited)
-                       return 0;
-               node->visited = 1;
-       }
-
-       stream = g_new0(struct ctf_stream_declaration, 1);
-       stream->declaration_scope = bt_new_declaration_scope(parent_declaration_scope);
-       stream->events_by_id = g_ptr_array_new();
-       stream->event_quark_to_id = g_hash_table_new(g_direct_hash, g_direct_equal);
-       stream->streams = g_ptr_array_new();
-       if (node) {
-               bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
-                       ret = ctf_stream_declaration_visit(fd, depth + 1, iter, stream, trace);
-                       if (ret)
-                               goto error;
-               }
-       }
-       if (CTF_STREAM_FIELD_IS_SET(stream, stream_id)) {
-               /* check that packet header has stream_id field. */
-               if (!trace->packet_header_decl
-                   || bt_struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_string("stream_id")) < 0) {
-                       ret = -EPERM;
-                       fprintf(fd, "[error] %s: missing stream_id field in packet header declaration, but stream_id attribute is declared for stream.\n", __func__);
-                       goto error;
-               }
-       } else {
-               /* Allow only one id-less stream */
-               if (trace->streams->len != 0) {
-                       ret = -EPERM;
-                       fprintf(fd, "[error] %s: missing id field in stream declaration\n", __func__);
-                       goto error;
-               }
-               stream->stream_id = 0;
-       }
-       if (trace->streams->len <= stream->stream_id)
-               g_ptr_array_set_size(trace->streams, stream->stream_id + 1);
-       g_ptr_array_index(trace->streams, stream->stream_id) = stream;
-       stream->trace = trace;
-
-       return 0;
-
-error:
-       if (stream->event_header_decl)
-               bt_declaration_unref(&stream->event_header_decl->p);
-       if (stream->event_context_decl)
-               bt_declaration_unref(&stream->event_context_decl->p);
-       if (stream->packet_context_decl)
-               bt_declaration_unref(&stream->packet_context_decl->p);
-       g_ptr_array_free(stream->streams, TRUE);
-       g_ptr_array_free(stream->events_by_id, TRUE);
-       g_hash_table_destroy(stream->event_quark_to_id);
-       bt_free_declaration_scope(stream->declaration_scope);
-       g_free(stream);
-       return ret;
-}
-
-static
-int ctf_trace_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       switch (node->type) {
-       case NODE_TYPEDEF:
-               ret = ctf_typedef_visit(fd, depth + 1,
-                                       trace->declaration_scope,
-                                       node->u._typedef.type_specifier_list,
-                                       &node->u._typedef.type_declarators,
-                                       trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               ret = ctf_typealias_visit(fd, depth + 1,
-                               trace->declaration_scope,
-                               node->u.typealias.target, node->u.typealias.alias,
-                               trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "major")) {
-                       if (CTF_TRACE_FIELD_IS_SET(trace, major)) {
-                               fprintf(fd, "[error] %s: major already declared in trace declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->major);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for trace major number\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_TRACE_SET_FIELD(trace, major);
-               } else if (!strcmp(left, "minor")) {
-                       if (CTF_TRACE_FIELD_IS_SET(trace, minor)) {
-                               fprintf(fd, "[error] %s: minor already declared in trace declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &trace->minor);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for trace minor number\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_TRACE_SET_FIELD(trace, minor);
-               } else if (!strcmp(left, "uuid")) {
-                       unsigned char uuid[BABELTRACE_UUID_LEN];
-
-                       ret = get_unary_uuid(&node->u.ctf_expression.right, uuid);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for trace uuid\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       if (CTF_TRACE_FIELD_IS_SET(trace, uuid)
-                               && bt_uuid_compare(uuid, trace->uuid)) {
-                               fprintf(fd, "[error] %s: uuid mismatch\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       } else {
-                               memcpy(trace->uuid, uuid, sizeof(uuid));
-                       }
-                       CTF_TRACE_SET_FIELD(trace, uuid);
-               } else if (!strcmp(left, "byte_order")) {
-                       struct ctf_node *right;
-                       int byte_order;
-
-                       right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
-                       byte_order = get_trace_byte_order(fd, depth, right);
-                       if (byte_order < 0) {
-                               ret = -EINVAL;
-                               goto error;
-                       }
-
-                       if (CTF_TRACE_FIELD_IS_SET(trace, byte_order)
-                               && byte_order != trace->byte_order) {
-                               fprintf(fd, "[error] %s: endianness mismatch\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       } else {
-                               if (byte_order != trace->byte_order) {
-                                       trace->byte_order = byte_order;
-                                       /*
-                                        * We need to restart
-                                        * construction of the
-                                        * intermediate representation.
-                                        */
-                                       trace->field_mask = 0;
-                                       CTF_TRACE_SET_FIELD(trace, byte_order);
-                                       ret = -EINTR;
-                                       goto error;
-                               }
-                       }
-                       CTF_TRACE_SET_FIELD(trace, byte_order);
-               } else if (!strcmp(left, "packet.header")) {
-                       struct bt_declaration *declaration;
-
-                       if (trace->packet_header_decl) {
-                               fprintf(fd, "[error] %s: packet.header already declared in trace declaration\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       declaration = ctf_type_specifier_list_visit(fd, depth,
-                                       _bt_list_first_entry(&node->u.ctf_expression.right,
-                                               struct ctf_node, siblings),
-                                       trace->declaration_scope, trace);
-                       if (!declaration) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       if (declaration->id != BT_CTF_TYPE_ID_STRUCT) {
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       trace->packet_header_decl = container_of(declaration, struct declaration_struct, p);
-               } else {
-                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in trace declaration.\n", __func__, left);
-               }
-
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       /* TODO: declaration specifier should be added. */
-       }
-
-       return ret;
-}
-
-static
-int ctf_trace_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       if (!trace->restart_root_decl && node->visited)
-               return 0;
-       node->visited = 1;
-
-       if (trace->declaration_scope)
-               return -EEXIST;
-
-       trace->declaration_scope = bt_new_declaration_scope(trace->root_declaration_scope);
-       trace->streams = g_ptr_array_new();
-       trace->event_declarations = g_ptr_array_new();
-       bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
-               ret = ctf_trace_declaration_visit(fd, depth + 1, iter, trace);
-               if (ret)
-                       goto error;
-       }
-       if (!CTF_TRACE_FIELD_IS_SET(trace, major)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing major field in trace declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_TRACE_FIELD_IS_SET(trace, minor)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing minor field in trace declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing byte_order field in trace declaration\n", __func__);
-               goto error;
-       }
-
-       if (!CTF_TRACE_FIELD_IS_SET(trace, byte_order)) {
-               /* check that the packet header contains a "magic" field */
-               if (!trace->packet_header_decl
-                   || bt_struct_declaration_lookup_field_index(trace->packet_header_decl, g_quark_from_string("magic")) < 0) {
-                       ret = -EPERM;
-                       fprintf(fd, "[error] %s: missing both byte_order and packet header magic number in trace declaration\n", __func__);
-                       goto error;
-               }
-       }
-       return 0;
-
-error:
-       if (trace->packet_header_decl) {
-               bt_declaration_unref(&trace->packet_header_decl->p);
-               trace->packet_header_decl = NULL;
-       }
-       g_ptr_array_free(trace->streams, TRUE);
-       g_ptr_array_free(trace->event_declarations, TRUE);
-       bt_free_declaration_scope(trace->declaration_scope);
-       trace->declaration_scope = NULL;
-       return ret;
-}
-
-static
-int ctf_clock_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
-               struct ctf_clock *clock, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       switch (node->type) {
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "name")) {
-                       char *right;
-
-                       if (CTF_CLOCK_FIELD_IS_SET(clock, name)) {
-                               fprintf(fd, "[error] %s: name already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock name\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       clock->name = g_quark_from_string(right);
-                       g_free(right);
-                       CTF_CLOCK_SET_FIELD(clock, name);
-               } else if (!strcmp(left, "uuid")) {
-                       char *right;
-
-                       if (clock->uuid) {
-                               fprintf(fd, "[error] %s: uuid already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock uuid\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       clock->uuid = g_quark_from_string(right);
-                       g_free(right);
-               } else if (!strcmp(left, "description")) {
-                       char *right;
-
-                       if (clock->description) {
-                               fprintf(fd, "[warning] %s: duplicated clock description\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for clock description\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       clock->description = right;
-               } else if (!strcmp(left, "freq")) {
-                       if (CTF_CLOCK_FIELD_IS_SET(clock, freq)) {
-                               fprintf(fd, "[error] %s: freq already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->freq);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock freq\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_CLOCK_SET_FIELD(clock, freq);
-               } else if (!strcmp(left, "precision")) {
-                       if (clock->precision) {
-                               fprintf(fd, "[error] %s: precision already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &clock->precision);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock precision\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-               } else if (!strcmp(left, "offset_s")) {
-                       if (clock->offset_s) {
-                               fprintf(fd, "[error] %s: offset_s already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_signed(&node->u.ctf_expression.right, &clock->offset_s);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock offset_s\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-               } else if (!strcmp(left, "offset")) {
-                       if (clock->offset) {
-                               fprintf(fd, "[error] %s: offset already declared in clock declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_signed(&node->u.ctf_expression.right, &clock->offset);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for clock offset\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-               } else if (!strcmp(left, "absolute")) {
-                       struct ctf_node *right;
-
-                       right = _bt_list_first_entry(&node->u.ctf_expression.right, struct ctf_node, siblings);
-                       ret = get_boolean(fd, depth, right);
-                       if (ret < 0) {
-                               fprintf(fd, "[error] %s: unexpected \"absolute\" right member\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       clock->absolute = ret;
-                       ret = 0;
-               } else {
-                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in clock declaration.\n", __func__, left);
-               }
-
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       /* TODO: declaration specifier should be added. */
-       }
-
-       return ret;
-}
-
-static
-int ctf_clock_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-       struct ctf_clock *clock;
-
-       if (node->visited)
-               return 0;
-       node->visited = 1;
-
-       clock = g_new0(struct ctf_clock, 1);
-       /* Default clock frequency is set to 1000000000 */
-       clock->freq = 1000000000ULL;
-       bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
-               ret = ctf_clock_declaration_visit(fd, depth + 1, iter, clock, trace);
-               if (ret)
-                       goto error;
-       }
-       if (opt_clock_force_correlate) {
-               /*
-                * User requested to forcibly correlate the clock
-                * sources, even if we have no correlation
-                * information.
-                */
-               if (!clock->absolute) {
-                       fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
-               }
-               clock->absolute = 1;
-       }
-       if (!CTF_CLOCK_FIELD_IS_SET(clock, name)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing name field in clock declaration\n", __func__);
-               goto error;
-       }
-       if (g_hash_table_size(trace->parent.clocks) > 0) {
-               fprintf(fd, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
-               ret = -EINVAL;
-               goto error;
-       }
-       trace->parent.single_clock = clock;
-       g_hash_table_insert(trace->parent.clocks, GUINT_TO_POINTER(clock->name), clock);
-       return 0;
-
-error:
-       g_free(clock->description);
-       g_free(clock);
-       return ret;
-}
-
-static
-void ctf_clock_default(FILE *fd, int depth, struct ctf_trace *trace)
-{
-       struct ctf_clock *clock;
-
-       clock = g_new0(struct ctf_clock, 1);
-       clock->name = g_quark_from_string("monotonic");
-       clock->uuid = 0;
-       clock->description = g_strdup("Default clock");
-       /* Default clock frequency is set to 1000000000 */
-       clock->freq = 1000000000ULL;
-       if (opt_clock_force_correlate) {
-               /*
-                * User requested to forcibly correlate the clock
-                * sources, even if we have no correlatation
-                * information.
-                */
-               if (!clock->absolute) {
-                       fprintf(fd, "[warning] Forcibly correlating trace clock sources (--clock-force-correlate).\n");
-               }
-               clock->absolute = 1;
-       } else {
-               clock->absolute = 0;    /* Not an absolute reference across traces */
-       }
-
-       trace->parent.single_clock = clock;
-       g_hash_table_insert(trace->parent.clocks, GUINT_TO_POINTER(clock->name), clock);
-}
-
-static
-void clock_free(gpointer data)
-{
-       struct ctf_clock *clock = data;
-
-       g_free(clock->description);
-       g_free(clock);
-}
-
-static
-int ctf_callsite_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
-               struct ctf_callsite *callsite, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       switch (node->type) {
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "name")) {
-                       char *right;
-
-                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
-                               fprintf(fd, "[error] %s: name already declared in callsite declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for callsite name\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       callsite->name = g_quark_from_string(right);
-                       g_free(right);
-                       CTF_CALLSITE_SET_FIELD(callsite, name);
-               } else if (!strcmp(left, "func")) {
-                       char *right;
-
-                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
-                               fprintf(fd, "[error] %s: func already declared in callsite declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for callsite func\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       callsite->func = right;
-                       CTF_CALLSITE_SET_FIELD(callsite, func);
-               } else if (!strcmp(left, "file")) {
-                       char *right;
-
-                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
-                               fprintf(fd, "[error] %s: file already declared in callsite declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for callsite file\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       callsite->file = right;
-                       CTF_CALLSITE_SET_FIELD(callsite, file);
-               } else if (!strcmp(left, "line")) {
-                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
-                               fprintf(fd, "[error] %s: line already declared in callsite declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->line);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for callsite line\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_CALLSITE_SET_FIELD(callsite, line);
-               } else if (!strcmp(left, "ip")) {
-                       if (CTF_CALLSITE_FIELD_IS_SET(callsite, ip)) {
-                               fprintf(fd, "[error] %s: ip already declared in callsite declaration\n", __func__);
-                               ret = -EPERM;
-                               goto error;
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &callsite->ip);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for callsite ip\n", __func__);
-                               ret = -EINVAL;
-                               goto error;
-                       }
-                       CTF_CALLSITE_SET_FIELD(callsite, ip);
-               } else {
-                       fprintf(fd, "[warning] %s: attribute \"%s\" is unknown in callsite declaration.\n", __func__, left);
-               }
-
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       /* TODO: declaration specifier should be added. */
-       }
-
-       return ret;
-}
-
-static
-int ctf_callsite_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-       struct ctf_callsite *callsite;
-       struct ctf_callsite_dups *cs_dups;
-
-       if (node->visited)
-               return 0;
-       node->visited = 1;
-
-       callsite = g_new0(struct ctf_callsite, 1);
-       bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
-               ret = ctf_callsite_declaration_visit(fd, depth + 1, iter, callsite, trace);
-               if (ret)
-                       goto error;
-       }
-       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, name)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing name field in callsite declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, func)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing func field in callsite declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, file)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing file field in callsite declaration\n", __func__);
-               goto error;
-       }
-       if (!CTF_CALLSITE_FIELD_IS_SET(callsite, line)) {
-               ret = -EPERM;
-               fprintf(fd, "[error] %s: missing line field in callsite declaration\n", __func__);
-               goto error;
-       }
-
-       cs_dups = g_hash_table_lookup(trace->callsites,
-               GUINT_TO_POINTER(callsite->name));
-       if (!cs_dups) {
-               cs_dups = g_new0(struct ctf_callsite_dups, 1);
-               BT_INIT_LIST_HEAD(&cs_dups->head);
-               g_hash_table_insert(trace->callsites,
-                       GUINT_TO_POINTER(callsite->name), cs_dups);
-       }
-       bt_list_add_tail(&callsite->node, &cs_dups->head);
-       return 0;
-
-error:
-       g_free(callsite->func);
-       g_free(callsite->file);
-       g_free(callsite);
-       return ret;
-}
-
-static
-void callsite_free(gpointer data)
-{
-       struct ctf_callsite_dups *cs_dups = data;
-       struct ctf_callsite *callsite, *cs_n;
-
-       bt_list_for_each_entry_safe(callsite, cs_n, &cs_dups->head, node) {
-               g_free(callsite->func);
-               g_free(callsite->file);
-               g_free(callsite);
-       }
-       g_free(cs_dups);
-}
-
-static
-int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
-               struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_tracer_env *env = &trace->env;
-
-       switch (node->type) {
-       case NODE_CTF_EXPRESSION:
-       {
-               char *left;
-
-               left = concatenate_unary_strings(&node->u.ctf_expression.left);
-               if (!left)
-                       return -EINVAL;
-               if (!strcmp(left, "vpid")) {
-                       uint64_t v;
-
-                       if (env->vpid != -1) {
-                               fprintf(fd, "[error] %s: vpid already declared in env declaration\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: unexpected unary expression for env vpid\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       env->vpid = (int) v;
-                       printf_verbose("env.vpid = %d\n", env->vpid);
-               } else if (!strcmp(left, "procname")) {
-                       char *right;
-
-                       if (env->procname[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env procname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env procname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->procname, right, TRACER_ENV_LEN);
-                       env->procname[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.procname = \"%s\"\n", env->procname);
-                       g_free(right);
-               } else if (!strcmp(left, "hostname")) {
-                       char *right;
-
-                       if (env->hostname[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env hostname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env hostname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->hostname, right, TRACER_ENV_LEN);
-                       env->hostname[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.hostname = \"%s\"\n", env->hostname);
-                       g_free(right);
-               } else if (!strcmp(left, "domain")) {
-                       char *right;
-
-                       if (env->domain[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env domain\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env domain\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->domain, right, TRACER_ENV_LEN);
-                       env->domain[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.domain = \"%s\"\n", env->domain);
-                       g_free(right);
-               } else if (!strcmp(left, "tracer_name")) {
-                       char *right;
-
-                       if (env->tracer_name[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env tracer_name\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env tracer_name\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->tracer_name, right, TRACER_ENV_LEN);
-                       env->tracer_name[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.tracer_name = \"%s\"\n", env->tracer_name);
-                       g_free(right);
-               } else if (!strcmp(left, "sysname")) {
-                       char *right;
-
-                       if (env->sysname[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env sysname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env sysname\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->sysname, right, TRACER_ENV_LEN);
-                       env->sysname[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.sysname = \"%s\"\n", env->sysname);
-                       g_free(right);
-               } else if (!strcmp(left, "kernel_release")) {
-                       char *right;
-
-                       if (env->release[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env release\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env release\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->release, right, TRACER_ENV_LEN);
-                       env->release[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.release = \"%s\"\n", env->release);
-                       g_free(right);
-               } else if (!strcmp(left, "kernel_version")) {
-                       char *right;
-
-                       if (env->version[0]) {
-                               fprintf(fd, "[warning] %s: duplicated env version\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                       if (!right) {
-                               fprintf(fd, "[warning] %s: unexpected unary expression for env version\n", __func__);
-                               goto error;     /* ret is 0, so not an actual error, just warn. */
-                       }
-                       strncpy(env->version, right, TRACER_ENV_LEN);
-                       env->version[TRACER_ENV_LEN - 1] = '\0';
-                       printf_verbose("env.version = \"%s\"\n", env->version);
-                       g_free(right);
-               } else {
-                       if (is_unary_string(&node->u.ctf_expression.right)) {
-                               char *right;
-
-                               right = concatenate_unary_strings(&node->u.ctf_expression.right);
-                               if (!right) {
-                                       fprintf(fd, "[warning] %s: unexpected unary expression for env\n", __func__);
-                                       ret = -EINVAL;
-                                       goto error;
-                               }
-                               printf_verbose("env.%s = \"%s\"\n", left, right);
-                               g_free(right);
-                       } else if (is_unary_unsigned(&node->u.ctf_expression.right)) {
-                               uint64_t v;
-                               int ret;
-
-                               ret = get_unary_unsigned(&node->u.ctf_expression.right, &v);
-                               if (ret)
-                                       goto error;
-                               printf_verbose("env.%s = %" PRIu64 "\n", left, v);
-                       } else if (is_unary_signed(&node->u.ctf_expression.right)) {
-                               int64_t v;
-                               int ret;
-
-                               ret = get_unary_signed(&node->u.ctf_expression.right, &v);
-                               if (ret)
-                                       goto error;
-                               printf_verbose("env.%s = %" PRId64 "\n", left, v);
-                       } else {
-                               printf_verbose("%s: attribute \"%s\" has unknown type.\n", __func__, left);
-                       }
-               }
-
-error:
-               g_free(left);
-               break;
-       }
-       default:
-               return -EPERM;
-       }
-
-       return ret;
-}
-
-static
-int ctf_env_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       if (node->visited)
-               return 0;
-       node->visited = 1;
-
-       trace->env.vpid = -1;
-       trace->env.procname[0] = '\0';
-       trace->env.hostname[0] = '\0';
-       trace->env.domain[0] = '\0';
-       trace->env.sysname[0] = '\0';
-       trace->env.release[0] = '\0';
-       trace->env.version[0] = '\0';
-       bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
-               ret = ctf_env_declaration_visit(fd, depth + 1, iter, trace);
-               if (ret)
-                       goto error;
-       }
-error:
-       return 0;
-}
-
-static
-int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       if (!trace->restart_root_decl && node->visited)
-               return 0;
-       node->visited = 1;
-
-       switch (node->type) {
-       case NODE_TYPEDEF:
-               ret = ctf_typedef_visit(fd, depth + 1,
-                                       trace->root_declaration_scope,
-                                       node->u._typedef.type_specifier_list,
-                                       &node->u._typedef.type_declarators,
-                                       trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPEALIAS:
-               ret = ctf_typealias_visit(fd, depth + 1,
-                               trace->root_declaration_scope,
-                               node->u.typealias.target, node->u.typealias.alias,
-                               trace);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPE_SPECIFIER_LIST:
-       {
-               struct bt_declaration *declaration;
-
-               /*
-                * Just add the type specifier to the root scope
-                * declaration scope. Release local reference.
-                */
-               declaration = ctf_type_specifier_list_visit(fd, depth + 1,
-                       node, trace->root_declaration_scope, trace);
-               if (!declaration)
-                       return -ENOMEM;
-               bt_declaration_unref(declaration);
-               break;
-       }
-       default:
-               return -EPERM;
-       }
-
-       return 0;
-}
-
-int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
-               struct ctf_trace *trace, int byte_order)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       printf_verbose("CTF visitor: metadata construction...\n");
-       trace->byte_order = byte_order;
-       trace->parent.clocks = g_hash_table_new_full(g_direct_hash,
-                               g_direct_equal, NULL, clock_free);
-       trace->callsites = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-                               NULL, callsite_free);
-
-retry:
-       trace->root_declaration_scope = bt_new_declaration_scope(NULL);
-
-       switch (node->type) {
-       case NODE_ROOT:
-               /*
-                * declarations need to query clock hash table,
-                * so clock need to be treated first.
-                */
-               if (bt_list_empty(&node->u.root.clock)) {
-                       ctf_clock_default(fd, depth + 1, trace);
-               } else {
-                       bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
-                               ret = ctf_clock_visit(fd, depth + 1, iter,
-                                                     trace);
-                               if (ret) {
-                                       fprintf(fd, "[error] %s: clock declaration error\n", __func__);
-                                       goto error;
-                               }
-                       }
-               }
-               bt_list_for_each_entry(iter, &node->u.root.declaration_list,
-                                       siblings) {
-                       ret = ctf_root_declaration_visit(fd, depth + 1, iter, trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: root declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
-                       ret = ctf_trace_visit(fd, depth + 1, iter, trace);
-                       if (ret == -EINTR) {
-                               trace->restart_root_decl = 1;
-                               bt_free_declaration_scope(trace->root_declaration_scope);
-                               /*
-                                * Need to restart creation of type
-                                * definitions, aliases and
-                                * trace header declarations.
-                                */
-                               goto retry;
-                       }
-                       if (ret) {
-                               fprintf(fd, "[error] %s: trace declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               trace->restart_root_decl = 0;
-               bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
-                       ret = ctf_callsite_visit(fd, depth + 1, iter,
-                                             trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: callsite declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               if (!trace->streams) {
-                       fprintf(fd, "[error] %s: missing trace declaration\n", __func__);
-                       ret = -EINVAL;
-                       goto error;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
-                       ret = ctf_env_visit(fd, depth + 1, iter, trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: env declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
-                       ret = ctf_stream_visit(fd, depth + 1, iter,
-                                              trace->root_declaration_scope, trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: stream declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
-                       ret = ctf_event_visit(fd, depth + 1, iter,
-                                             trace->root_declaration_scope, trace);
-                       if (ret) {
-                               fprintf(fd, "[error] %s: event declaration error\n", __func__);
-                               goto error;
-                       }
-               }
-               break;
-       case NODE_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
-                       (int) node->type);
-               ret = -EINVAL;
-               goto error;
-       }
-       printf_verbose("done.\n");
-       return ret;
-
-error:
-       bt_free_declaration_scope(trace->root_declaration_scope);
-       g_hash_table_destroy(trace->callsites);
-       g_hash_table_destroy(trace->parent.clocks);
-       return ret;
-}
-
-int ctf_destroy_metadata(struct ctf_trace *trace)
-{
-       int i;
-       struct ctf_file_stream *metadata_stream;
-
-       if (trace->streams) {
-               for (i = 0; i < trace->streams->len; i++) {
-                       struct ctf_stream_declaration *stream;
-                       int j;
-
-                       stream = g_ptr_array_index(trace->streams, i);
-                       if (!stream)
-                               continue;
-                       for (j = 0; j < stream->streams->len; j++) {
-                               struct ctf_stream_definition *stream_def;
-                               int k;
-
-                               stream_def = g_ptr_array_index(stream->streams, j);
-                               if (!stream_def)
-                                       continue;
-                               for (k = 0; k < stream_def->events_by_id->len; k++) {
-                                       struct ctf_event_definition *event;
-
-                                       event = g_ptr_array_index(stream_def->events_by_id, k);
-                                       if (!event)
-                                               continue;
-                                       if (&event->event_fields->p)
-                                               bt_definition_unref(&event->event_fields->p);
-                                       if (&event->event_context->p)
-                                               bt_definition_unref(&event->event_context->p);
-                                       g_free(event);
-                               }
-                               if (&stream_def->trace_packet_header->p)
-                                       bt_definition_unref(&stream_def->trace_packet_header->p);
-                               if (&stream_def->stream_event_header->p)
-                                       bt_definition_unref(&stream_def->stream_event_header->p);
-                               if (&stream_def->stream_packet_context->p)
-                                       bt_definition_unref(&stream_def->stream_packet_context->p);
-                               if (&stream_def->stream_event_context->p)
-                                       bt_definition_unref(&stream_def->stream_event_context->p);
-                               g_ptr_array_free(stream_def->events_by_id, TRUE);
-                               g_free(stream_def);
-                       }
-                       if (stream->event_header_decl)
-                               bt_declaration_unref(&stream->event_header_decl->p);
-                       if (stream->event_context_decl)
-                               bt_declaration_unref(&stream->event_context_decl->p);
-                       if (stream->packet_context_decl)
-                               bt_declaration_unref(&stream->packet_context_decl->p);
-                       g_ptr_array_free(stream->streams, TRUE);
-                       g_ptr_array_free(stream->events_by_id, TRUE);
-                       g_hash_table_destroy(stream->event_quark_to_id);
-                       bt_free_declaration_scope(stream->declaration_scope);
-                       g_free(stream);
-               }
-               g_ptr_array_free(trace->streams, TRUE);
-       }
-
-       if (trace->event_declarations) {
-               for (i = 0; i < trace->event_declarations->len; i++) {
-                       struct bt_ctf_event_decl *event_decl;
-                       struct ctf_event_declaration *event;
-
-                       event_decl = g_ptr_array_index(trace->event_declarations, i);
-                       if (event_decl->context_decl)
-                               g_ptr_array_free(event_decl->context_decl, TRUE);
-                       if (event_decl->fields_decl)
-                               g_ptr_array_free(event_decl->fields_decl, TRUE);
-                       if (event_decl->packet_header_decl)
-                               g_ptr_array_free(event_decl->packet_header_decl, TRUE);
-                       if (event_decl->event_context_decl)
-                               g_ptr_array_free(event_decl->event_context_decl, TRUE);
-                       if (event_decl->event_header_decl)
-                               g_ptr_array_free(event_decl->event_header_decl, TRUE);
-                       if (event_decl->packet_context_decl)
-                               g_ptr_array_free(event_decl->packet_context_decl, TRUE);
-
-                       event = &event_decl->parent;
-                       if (event->fields_decl)
-                               bt_declaration_unref(&event->fields_decl->p);
-                       if (event->context_decl)
-                               bt_declaration_unref(&event->context_decl->p);
-                       bt_free_declaration_scope(event->declaration_scope);
-
-                       g_free(event);
-               }
-               g_ptr_array_free(trace->event_declarations, TRUE);
-       }
-       if (trace->packet_header_decl)
-               bt_declaration_unref(&trace->packet_header_decl->p);
-
-       bt_free_declaration_scope(trace->root_declaration_scope);
-       bt_free_declaration_scope(trace->declaration_scope);
-
-       g_hash_table_destroy(trace->callsites);
-       g_hash_table_destroy(trace->parent.clocks);
-
-       metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent);
-       g_free(metadata_stream);
-
-       return 0;
-}
diff --git a/formats/ctf/metadata/ctf-visitor-parent-links.c b/formats/ctf/metadata/ctf-visitor-parent-links.c
deleted file mode 100644 (file)
index 037496a..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * ctf-visitor-parent-links.c
- *
- * Common Trace Format Metadata Parent Link Creator.
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <glib.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/list.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-#define fprintf_dbg(fd, fmt, args...)  fprintf(fd, "%s: " fmt, __func__, ## args)
-
-static
-int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-
-       switch (node->u.unary_expression.link) {
-       case UNARY_LINK_UNKNOWN:
-       case UNARY_DOTLINK:
-       case UNARY_ARROWLINK:
-       case UNARY_DOTDOTDOT:
-               break;
-       default:
-               fprintf(fd, "[error] %s: unknown expression link type %d\n", __func__,
-                       (int) node->u.unary_expression.link);
-               return -EINVAL;
-       }
-
-       switch (node->u.unary_expression.type) {
-       case UNARY_STRING:
-       case UNARY_SIGNED_CONSTANT:
-       case UNARY_UNSIGNED_CONSTANT:
-               break;
-       case UNARY_SBRAC:
-               node->u.unary_expression.u.sbrac_exp->parent = node;
-               ret = ctf_visitor_unary_expression(fd, depth + 1,
-                       node->u.unary_expression.u.sbrac_exp);
-               if (ret)
-                       return ret;
-               break;
-
-       case UNARY_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown expression type %d\n", __func__,
-                       (int) node->u.unary_expression.type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret;
-
-       switch (node->u.type_specifier.type) {
-       case TYPESPEC_VOID:
-       case TYPESPEC_CHAR:
-       case TYPESPEC_SHORT:
-       case TYPESPEC_INT:
-       case TYPESPEC_LONG:
-       case TYPESPEC_FLOAT:
-       case TYPESPEC_DOUBLE:
-       case TYPESPEC_SIGNED:
-       case TYPESPEC_UNSIGNED:
-       case TYPESPEC_BOOL:
-       case TYPESPEC_COMPLEX:
-       case TYPESPEC_IMAGINARY:
-       case TYPESPEC_CONST:
-       case TYPESPEC_ID_TYPE:
-               break;
-       case TYPESPEC_FLOATING_POINT:
-       case TYPESPEC_INTEGER:
-       case TYPESPEC_STRING:
-       case TYPESPEC_STRUCT:
-       case TYPESPEC_VARIANT:
-       case TYPESPEC_ENUM:
-               node->u.type_specifier.node->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u.type_specifier.node);
-               if (ret)
-                       return ret;
-               break;
-
-       case TYPESPEC_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown type specifier %d\n", __func__,
-                       (int) node->u.type_specifier.type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       depth++;
-
-       bt_list_for_each_entry(iter, &node->u.type_declarator.pointers,
-                               siblings) {
-               iter->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-               if (ret)
-                       return ret;
-       }
-
-       switch (node->u.type_declarator.type) {
-       case TYPEDEC_ID:
-               break;
-       case TYPEDEC_NESTED:
-               if (node->u.type_declarator.u.nested.type_declarator) {
-                       node->u.type_declarator.u.nested.type_declarator->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1,
-                               node->u.type_declarator.u.nested.type_declarator);
-                       if (ret)
-                               return ret;
-               }
-               if (!node->u.type_declarator.u.nested.abstract_array) {
-                       bt_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
-                                               siblings) {
-                               iter->parent = node;
-                               ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                               if (ret)
-                                       return ret;
-                       }
-               }
-               if (node->u.type_declarator.bitfield_len) {
-                       node->u.type_declarator.bitfield_len = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1,
-                               node->u.type_declarator.bitfield_len);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case TYPEDEC_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
-                       (int) node->u.type_declarator.type);
-               return -EINVAL;
-       }
-       depth--;
-       return 0;
-}
-
-int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       if (node->visited)
-               return 0;
-
-       switch (node->type) {
-       case NODE_ROOT:
-               bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.clock, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.callsite, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_EVENT:
-               bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_STREAM:
-               bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENV:
-               bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_TRACE:
-               bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_CLOCK:
-               bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_CALLSITE:
-               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_CTF_EXPRESSION:
-               depth++;
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_UNARY_EXPRESSION:
-               return ctf_visitor_unary_expression(fd, depth, node);
-
-       case NODE_TYPEDEF:
-               depth++;
-               node->u._typedef.type_specifier_list->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u._typedef.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_TYPEALIAS_TARGET:
-               depth++;
-               node->u.typealias_target.type_specifier_list->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u.typealias_target.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_TYPEALIAS_ALIAS:
-               depth++;
-               node->u.typealias_alias.type_specifier_list->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u.typealias_alias.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_TYPEALIAS:
-               node->u.typealias.target->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u.typealias.target);
-               if (ret)
-                       return ret;
-               node->u.typealias.alias->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1, node->u.typealias.alias);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_TYPE_SPECIFIER_LIST:
-               bt_list_for_each_entry(iter, &node->u.type_specifier_list.head, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_TYPE_SPECIFIER:
-               ret = ctf_visitor_type_specifier(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_POINTER:
-               break;
-       case NODE_TYPE_DECLARATOR:
-               ret = ctf_visitor_type_declarator(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_FLOATING_POINT:
-               bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_INTEGER:
-               bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_STRING:
-               bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENUMERATOR:
-               bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENUM:
-               depth++;
-               if (node->u._enum.container_type) {
-                       ret = ctf_visitor_parent_links(fd, depth + 1, node->u._enum.container_type);
-                       if (ret)
-                               return ret;
-               }
-
-               bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               node->u.struct_or_variant_declaration.type_specifier_list->parent = node;
-               ret = ctf_visitor_parent_links(fd, depth + 1,
-                       node->u.struct_or_variant_declaration.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_VARIANT:
-               bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_STRUCT:
-               bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u._struct.min_align,
-                                       siblings) {
-                       iter->parent = node;
-                       ret = ctf_visitor_parent_links(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
-                       (int) node->type);
-               return -EINVAL;
-       }
-       return ret;
-}
diff --git a/formats/ctf/metadata/ctf-visitor-semantic-validator.c b/formats/ctf/metadata/ctf-visitor-semantic-validator.c
deleted file mode 100644 (file)
index 96776a9..0000000
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * ctf-visitor-semantic-validator.c
- *
- * Common Trace Format Metadata Semantic Validator.
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <glib.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/list.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-#define _bt_list_first_entry(ptr, type, member)        \
-       bt_list_entry((ptr)->next, type, member)
-
-#define fprintf_dbg(fd, fmt, args...)  fprintf(fd, "%s: " fmt, __func__, ## args)
-
-static
-int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node);
-
-static
-int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
-{
-       struct ctf_node *iter;
-       int is_ctf_exp = 0, is_ctf_exp_left = 0;
-
-       switch (node->parent->type) {
-       case NODE_CTF_EXPRESSION:
-               is_ctf_exp = 1;
-               bt_list_for_each_entry(iter, &node->parent->u.ctf_expression.left,
-                                       siblings) {
-                       if (iter == node) {
-                               is_ctf_exp_left = 1;
-                               /*
-                                * We are a left child of a ctf expression.
-                                * We are only allowed to be a string.
-                                */
-                               if (node->u.unary_expression.type != UNARY_STRING) {
-                                       fprintf(fd, "[error]: semantic error (left child of a ctf expression is only allowed to be a string)\n");
-
-                                       goto errperm;
-                               }
-                               break;
-                       }
-               }
-               /* Right child of a ctf expression can be any type of unary exp. */
-               break;                  /* OK */
-       case NODE_TYPE_DECLARATOR:
-               /*
-                * We are the length of a type declarator.
-                */
-               switch (node->u.unary_expression.type) {
-               case UNARY_UNSIGNED_CONSTANT:
-               case UNARY_STRING:
-                       break;
-               default:
-                       fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants or references to fields (a.b.c))\n");
-                       goto errperm;
-               }
-               break;                  /* OK */
-
-       case NODE_STRUCT:
-               /*
-                * We are the size of a struct align attribute.
-                */
-               switch (node->u.unary_expression.type) {
-               case UNARY_UNSIGNED_CONSTANT:
-                       break;
-               default:
-                       fprintf(fd, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
-                       goto errperm;
-               }
-               break;
-
-       case NODE_ENUMERATOR:
-               /* The enumerator's parent has validated its validity already. */
-               break;                  /* OK */
-
-       case NODE_UNARY_EXPRESSION:
-               /*
-                * We disallow nested unary expressions and "sbrac" unary
-                * expressions.
-                */
-               fprintf(fd, "[error]: semantic error (nested unary expressions not allowed ( () and [] ))\n");
-               goto errperm;
-
-       case NODE_ROOT:
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_POINTER:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_VARIANT:
-       default:
-               goto errinval;
-       }
-
-       switch (node->u.unary_expression.link) {
-       case UNARY_LINK_UNKNOWN:
-               /* We don't allow empty link except on the first node of the list */
-               if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ?
-                                         &node->parent->u.ctf_expression.left :
-                                         &node->parent->u.ctf_expression.right,
-                                         struct ctf_node,
-                                         siblings) != node) {
-                       fprintf(fd, "[error]: semantic error (empty link not allowed except on first node of unary expression (need to separate nodes with \".\" or \"->\")\n");
-                       goto errperm;
-               }
-               break;                  /* OK */
-       case UNARY_DOTLINK:
-       case UNARY_ARROWLINK:
-               /* We only allow -> and . links between children of ctf_expression. */
-               if (node->parent->type != NODE_CTF_EXPRESSION) {
-                       fprintf(fd, "[error]: semantic error (links \".\" and \"->\" are only allowed as children of ctf expression)\n");
-                       goto errperm;
-               }
-               /*
-                * Only strings can be separated linked by . or ->.
-                * This includes "", '' and non-quoted identifiers.
-                */
-               if (node->u.unary_expression.type != UNARY_STRING) {
-                       fprintf(fd, "[error]: semantic error (links \".\" and \"->\" are only allowed to separate strings and identifiers)\n");
-                       goto errperm;
-               }
-               /* We don't allow link on the first node of the list */
-               if (is_ctf_exp && _bt_list_first_entry(is_ctf_exp_left ?
-                                         &node->parent->u.ctf_expression.left :
-                                         &node->parent->u.ctf_expression.right,
-                                         struct ctf_node,
-                                         siblings) == node) {
-                       fprintf(fd, "[error]: semantic error (links \".\" and \"->\" are not allowed before first node of the unary expression list)\n");
-                       goto errperm;
-               }
-               break;
-       case UNARY_DOTDOTDOT:
-               /* We only allow ... link between children of enumerator. */
-               if (node->parent->type != NODE_ENUMERATOR) {
-                       fprintf(fd, "[error]: semantic error (link \"...\" is only allowed within enumerator)\n");
-                       goto errperm;
-               }
-               /* We don't allow link on the first node of the list */
-               if (_bt_list_first_entry(&node->parent->u.enumerator.values,
-                                         struct ctf_node,
-                                         siblings) == node) {
-                       fprintf(fd, "[error]: semantic error (link \"...\" is not allowed on the first node of the unary expression list)\n");
-                       goto errperm;
-               }
-               break;
-       default:
-               fprintf(fd, "[error] %s: unknown expression link type %d\n", __func__,
-                       (int) node->u.unary_expression.link);
-               return -EINVAL;
-       }
-       return 0;
-
-errinval:
-       fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EINVAL;         /* Incoherent structure */
-
-errperm:
-       fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EPERM;          /* Structure not allowed */
-}
-
-static
-int ctf_visitor_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
-{
-       switch (node->parent->type) {
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_ROOT:
-               break;                  /* OK */
-
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_UNARY_EXPRESSION:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_TYPE_SPECIFIER_LIST:
-       case NODE_POINTER:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_ENUMERATOR:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       default:
-               goto errinval;
-       }
-       return 0;
-errinval:
-       fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EINVAL;         /* Incoherent structure */
-}
-
-static
-int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node)
-{
-       switch (node->parent->type) {
-       case NODE_TYPE_SPECIFIER_LIST:
-               break;                  /* OK */
-
-       case NODE_CTF_EXPRESSION:
-       case NODE_TYPE_DECLARATOR:
-       case NODE_TYPEDEF:
-       case NODE_TYPEALIAS_TARGET:
-       case NODE_TYPEALIAS_ALIAS:
-       case NODE_ENUM:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-       case NODE_ROOT:
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_UNARY_EXPRESSION:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_POINTER:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_ENUMERATOR:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       default:
-               goto errinval;
-       }
-       return 0;
-errinval:
-       fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EINVAL;         /* Incoherent structure */
-}
-
-static
-int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       depth++;
-
-       switch (node->parent->type) {
-       case NODE_TYPE_DECLARATOR:
-               /*
-                * A nested type declarator is not allowed to contain pointers.
-                */
-               if (!bt_list_empty(&node->u.type_declarator.pointers))
-                       goto errperm;
-               break;                  /* OK */
-       case NODE_TYPEALIAS_TARGET:
-               break;                  /* OK */
-       case NODE_TYPEALIAS_ALIAS:
-               /*
-                * Only accept alias name containing:
-                * - identifier
-                * - identifier *   (any number of pointers)
-                * NOT accepting alias names containing [] (would otherwise
-                * cause semantic clash for later declarations of
-                * arrays/sequences of elements, where elements could be
-                * arrays/sequences themselves (if allowed in typealias).
-                * NOT accepting alias with identifier. The declarator should
-                * be either empty or contain pointer(s).
-                */
-               if (node->u.type_declarator.type == TYPEDEC_NESTED)
-                       goto errperm;
-               bt_list_for_each_entry(iter, &node->parent->u.typealias_alias.type_specifier_list->u.type_specifier_list.head,
-                                       siblings) {
-                       switch (iter->u.type_specifier.type) {
-                       case TYPESPEC_FLOATING_POINT:
-                       case TYPESPEC_INTEGER:
-                       case TYPESPEC_STRING:
-                       case TYPESPEC_STRUCT:
-                       case TYPESPEC_VARIANT:
-                       case TYPESPEC_ENUM:
-                               if (bt_list_empty(&node->u.type_declarator.pointers))
-                                       goto errperm;
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               if (node->u.type_declarator.type == TYPEDEC_ID &&
-                   node->u.type_declarator.u.id != NULL)
-                       goto errperm;
-               break;                  /* OK */
-       case NODE_TYPEDEF:
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               break;                  /* OK */
-
-       case NODE_ROOT:
-       case NODE_EVENT:
-       case NODE_STREAM:
-       case NODE_ENV:
-       case NODE_TRACE:
-       case NODE_CLOCK:
-       case NODE_CALLSITE:
-       case NODE_CTF_EXPRESSION:
-       case NODE_UNARY_EXPRESSION:
-       case NODE_TYPEALIAS:
-       case NODE_TYPE_SPECIFIER:
-       case NODE_POINTER:
-       case NODE_FLOATING_POINT:
-       case NODE_INTEGER:
-       case NODE_STRING:
-       case NODE_ENUMERATOR:
-       case NODE_ENUM:
-       case NODE_VARIANT:
-       case NODE_STRUCT:
-       default:
-               goto errinval;
-       }
-
-       bt_list_for_each_entry(iter, &node->u.type_declarator.pointers,
-                               siblings) {
-               ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-               if (ret)
-                       return ret;
-       }
-
-       switch (node->u.type_declarator.type) {
-       case TYPEDEC_ID:
-               break;
-       case TYPEDEC_NESTED:
-       {
-               if (node->u.type_declarator.u.nested.type_declarator) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                               node->u.type_declarator.u.nested.type_declarator);
-                       if (ret)
-                               return ret;
-               }
-               if (!node->u.type_declarator.u.nested.abstract_array) {
-                       bt_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
-                                               siblings) {
-                               if (iter->type != NODE_UNARY_EXPRESSION) {
-                                       fprintf(fd, "[error] %s: expecting unary expression as length\n", __func__);
-                                       return -EINVAL;
-                               }
-                               ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                               if (ret)
-                                       return ret;
-                       }
-               } else {
-                       if (node->parent->type == NODE_TYPEALIAS_TARGET) {
-                               fprintf(fd, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__);
-                               return -EINVAL;
-                       }
-               }
-               if (node->u.type_declarator.bitfield_len) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                               node->u.type_declarator.bitfield_len);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       }
-       case TYPEDEC_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown type declarator %d\n", __func__,
-                       (int) node->u.type_declarator.type);
-               return -EINVAL;
-       }
-       depth--;
-       return 0;
-
-errinval:
-       fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EINVAL;         /* Incoherent structure */
-
-errperm:
-       fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EPERM;          /* Structure not allowed */
-}
-
-static
-int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       if (node->visited)
-               return 0;
-
-       switch (node->type) {
-       case NODE_ROOT:
-               bt_list_for_each_entry(iter, &node->u.root.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_EVENT:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_STREAM:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENV:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_TRACE:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_CLOCK:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_CALLSITE:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_CTF_EXPRESSION:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-               case NODE_EVENT:
-               case NODE_STREAM:
-               case NODE_ENV:
-               case NODE_TRACE:
-               case NODE_CLOCK:
-               case NODE_CALLSITE:
-               case NODE_FLOATING_POINT:
-               case NODE_INTEGER:
-               case NODE_STRING:
-                       break;                  /* OK */
-
-               case NODE_CTF_EXPRESSION:
-               case NODE_UNARY_EXPRESSION:
-               case NODE_TYPEDEF:
-               case NODE_TYPEALIAS_TARGET:
-               case NODE_TYPEALIAS_ALIAS:
-               case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               case NODE_TYPEALIAS:
-               case NODE_TYPE_SPECIFIER:
-               case NODE_TYPE_SPECIFIER_LIST:
-               case NODE_POINTER:
-               case NODE_TYPE_DECLARATOR:
-               case NODE_ENUMERATOR:
-               case NODE_ENUM:
-               case NODE_VARIANT:
-               case NODE_STRUCT:
-               default:
-                       goto errinval;
-               }
-
-               depth++;
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_UNARY_EXPRESSION:
-               return ctf_visitor_unary_expression(fd, depth, node);
-
-       case NODE_TYPEDEF:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-               case NODE_EVENT:
-               case NODE_STREAM:
-               case NODE_TRACE:
-               case NODE_VARIANT:
-               case NODE_STRUCT:
-                       break;                  /* OK */
-
-               case NODE_CTF_EXPRESSION:
-               case NODE_UNARY_EXPRESSION:
-               case NODE_TYPEDEF:
-               case NODE_TYPEALIAS_TARGET:
-               case NODE_TYPEALIAS_ALIAS:
-               case NODE_TYPEALIAS:
-               case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               case NODE_TYPE_SPECIFIER:
-               case NODE_TYPE_SPECIFIER_LIST:
-               case NODE_POINTER:
-               case NODE_TYPE_DECLARATOR:
-               case NODE_FLOATING_POINT:
-               case NODE_INTEGER:
-               case NODE_STRING:
-               case NODE_ENUMERATOR:
-               case NODE_ENUM:
-               case NODE_CLOCK:
-               case NODE_CALLSITE:
-               case NODE_ENV:
-               default:
-                       goto errinval;
-               }
-
-               depth++;
-               ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                       node->u._typedef.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_TYPEALIAS_TARGET:
-       {
-               int nr_declarators;
-
-               switch (node->parent->type) {
-               case NODE_TYPEALIAS:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               depth++;
-               ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                       node->u.typealias_target.type_specifier_list);
-               if (ret)
-                       return ret;
-               nr_declarators = 0;
-               bt_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-                       nr_declarators++;
-               }
-               if (nr_declarators > 1) {
-                       fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
-               
-                       return -EINVAL;
-               }
-               depth--;
-               break;
-       }
-       case NODE_TYPEALIAS_ALIAS:
-       {
-               int nr_declarators;
-
-               switch (node->parent->type) {
-               case NODE_TYPEALIAS:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-
-               depth++;
-               ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                       node->u.typealias_alias.type_specifier_list);
-               if (ret)
-                       return ret;
-               nr_declarators = 0;
-               bt_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-                       nr_declarators++;
-               }
-               if (nr_declarators > 1) {
-                       fprintf(fd, "[error] %s: Too many declarators in typealias alias (%d, max is 1)\n", __func__, nr_declarators);
-               
-                       return -EINVAL;
-               }
-               depth--;
-               break;
-       }
-       case NODE_TYPEALIAS:
-               switch (node->parent->type) {
-               case NODE_ROOT:
-               case NODE_EVENT:
-               case NODE_STREAM:
-               case NODE_TRACE:
-               case NODE_VARIANT:
-               case NODE_STRUCT:
-                       break;                  /* OK */
-
-               case NODE_CTF_EXPRESSION:
-               case NODE_UNARY_EXPRESSION:
-               case NODE_TYPEDEF:
-               case NODE_TYPEALIAS_TARGET:
-               case NODE_TYPEALIAS_ALIAS:
-               case NODE_TYPEALIAS:
-               case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               case NODE_TYPE_SPECIFIER:
-               case NODE_TYPE_SPECIFIER_LIST:
-               case NODE_POINTER:
-               case NODE_TYPE_DECLARATOR:
-               case NODE_FLOATING_POINT:
-               case NODE_INTEGER:
-               case NODE_STRING:
-               case NODE_ENUMERATOR:
-               case NODE_ENUM:
-               case NODE_CLOCK:
-               case NODE_CALLSITE:
-               case NODE_ENV:
-               default:
-                       goto errinval;
-               }
-
-               ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.target);
-               if (ret)
-                       return ret;
-               ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u.typealias.alias);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_TYPE_SPECIFIER_LIST:
-               ret = ctf_visitor_type_specifier_list(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_TYPE_SPECIFIER:
-               ret = ctf_visitor_type_specifier(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_POINTER:
-               switch (node->parent->type) {
-               case NODE_TYPE_DECLARATOR:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-               }
-               break;
-       case NODE_TYPE_DECLARATOR:
-               ret = ctf_visitor_type_declarator(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_FLOATING_POINT:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               case NODE_UNARY_EXPRESSION:
-                       goto errperm;
-               }
-               bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_INTEGER:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               }
-
-               bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_STRING:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               case NODE_UNARY_EXPRESSION:
-                       goto errperm;
-               }
-
-               bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENUMERATOR:
-               switch (node->parent->type) {
-               case NODE_ENUM:
-                       break;
-               default:
-                       goto errinval;
-               }
-               /*
-                * Enumerators are only allows to contain:
-                *    numeric unary expression
-                * or num. unary exp. ... num. unary exp
-                */
-               {
-                       int count = 0;
-
-                       bt_list_for_each_entry(iter, &node->u.enumerator.values,
-                                               siblings) {
-                               switch (count++) {
-                               case 0: if (iter->type != NODE_UNARY_EXPRESSION
-                                           || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
-                                               && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
-                                           || iter->u.unary_expression.link != UNARY_LINK_UNKNOWN) {
-                                               fprintf(fd, "[error]: semantic error (first unary expression of enumerator is unexpected)\n");
-                                               goto errperm;
-                                       }
-                                       break;
-                               case 1: if (iter->type != NODE_UNARY_EXPRESSION
-                                           || (iter->u.unary_expression.type != UNARY_SIGNED_CONSTANT
-                                               && iter->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT)
-                                           || iter->u.unary_expression.link != UNARY_DOTDOTDOT) {
-                                               fprintf(fd, "[error]: semantic error (second unary expression of enumerator is unexpected)\n");
-                                               goto errperm;
-                                       }
-                                       break;
-                               default:
-                                       goto errperm;
-                               }
-                       }
-               }
-
-               bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_ENUM:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               case NODE_UNARY_EXPRESSION:
-                       goto errperm;
-               }
-
-               depth++;
-               ret = _ctf_visitor_semantic_check(fd, depth + 1, node->u._enum.container_type);
-               if (ret)
-                       return ret;
-
-               bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               depth--;
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               switch (node->parent->type) {
-               case NODE_STRUCT:
-               case NODE_VARIANT:
-                       break;
-               default:
-                       goto errinval;
-               }
-               ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                       node->u.struct_or_variant_declaration.type_specifier_list);
-               if (ret)
-                       return ret;
-               bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-       case NODE_VARIANT:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               case NODE_UNARY_EXPRESSION:
-                       goto errperm;
-               }
-               bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_STRUCT:
-               switch (node->parent->type) {
-               case NODE_TYPE_SPECIFIER:
-                       break;                  /* OK */
-               default:
-                       goto errinval;
-
-               case NODE_UNARY_EXPRESSION:
-                       goto errperm;
-               }
-               bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               break;
-
-       case NODE_UNKNOWN:
-       default:
-               fprintf(fd, "[error] %s: unknown node type %d\n", __func__,
-                       (int) node->type);
-               return -EINVAL;
-       }
-       return ret;
-
-errinval:
-       fprintf(fd, "[error] %s: incoherent parent type %s for node type %s\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EINVAL;         /* Incoherent structure */
-
-errperm:
-       fprintf(fd, "[error] %s: semantic error (parent type %s for node type %s)\n", __func__,
-               node_type(node->parent), node_type(node));
-       return -EPERM;          /* Structure not allowed */
-}
-
-int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-
-       /*
-        * First make sure we create the parent links for all children. Let's
-        * take the safe route and recreate them at each validation, just in
-        * case the structure has changed.
-        */
-       printf_verbose("CTF visitor: parent links creation... ");
-       ret = ctf_visitor_parent_links(fd, depth, node);
-       if (ret)
-               return ret;
-       printf_verbose("done.\n");
-       printf_verbose("CTF visitor: semantic check... ");
-       ret = _ctf_visitor_semantic_check(fd, depth, node);
-       if (ret)
-               return ret;
-       printf_verbose("done.\n");
-       return ret;
-}
diff --git a/formats/ctf/metadata/ctf-visitor-xml.c b/formats/ctf/metadata/ctf-visitor-xml.c
deleted file mode 100644 (file)
index fca7704..0000000
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * ctf-visitor-xml.c
- *
- * Common Trace Format Metadata Visitor (XML dump).
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <glib.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/list.h>
-#include "ctf-scanner.h"
-#include "ctf-parser.h"
-#include "ctf-ast.h"
-
-#define fprintf_dbg(fd, fmt, args...)  fprintf(fd, "%s: " fmt, __func__, ## args)
-
-static
-void print_tabs(FILE *fd, int depth)
-{
-       int i;
-
-       for (i = 0; i < depth; i++)
-               fprintf(fd, "\t");
-}
-
-static
-int ctf_visitor_print_unary_expression(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-
-       switch (node->u.unary_expression.link) {
-       case UNARY_LINK_UNKNOWN:
-               break;
-       case UNARY_DOTLINK:
-               print_tabs(fd, depth);
-               fprintf(fd, "<dotlink/>\n");
-               break;
-       case UNARY_ARROWLINK:
-               print_tabs(fd, depth);
-               fprintf(fd, "<arrowlink/>\n");
-               break;
-       case UNARY_DOTDOTDOT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<dotdotdot/>\n");
-               break;
-       default:
-               fprintf(stderr, "[error] %s: unknown expression link type %d\n", __func__,
-                       (int) node->u.unary_expression.link);
-               return -EINVAL;
-       }
-
-       switch (node->u.unary_expression.type) {
-       case UNARY_STRING:
-               print_tabs(fd, depth);
-               fprintf(fd, "<unary_expression value=");
-               fprintf(fd, "\"%s\"", node->u.unary_expression.u.string);
-               fprintf(fd, " />\n");
-               break;
-       case UNARY_SIGNED_CONSTANT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<unary_expression value=\"");
-               fprintf(fd, "%" PRId64, node->u.unary_expression.u.signed_constant);
-               fprintf(fd, "\" />\n");
-               break;
-       case UNARY_UNSIGNED_CONSTANT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<unary_expression value=\"");
-               fprintf(fd, "%" PRIu64, node->u.unary_expression.u.signed_constant);
-               fprintf(fd, "\" />\n");
-               break;
-       case UNARY_SBRAC:
-               print_tabs(fd, depth);
-               fprintf(fd, "<unary_expression_sbrac>\n");
-               ret = ctf_visitor_print_unary_expression(fd, depth + 1,
-                       node->u.unary_expression.u.sbrac_exp);
-               if (ret)
-                       return ret;
-               print_tabs(fd, depth);
-               fprintf(fd, "</unary_expression_sbrac>\n");
-               break;
-
-       case UNARY_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown expression type %d\n", __func__,
-                       (int) node->u.unary_expression.type);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static
-int ctf_visitor_print_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
-{
-       struct ctf_node *iter;
-       int ret;
-
-       print_tabs(fd, depth);
-       fprintf(fd, "<type_specifier_list>\n");
-       bt_list_for_each_entry(iter, &node->u.type_specifier_list.head, siblings) {
-               ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-               if (ret)
-                       return ret;
-       }
-       print_tabs(fd, depth);
-       fprintf(fd, "</type_specifier_list>\n");
-       return 0;
-}
-
-static
-int ctf_visitor_print_type_specifier(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret;
-       print_tabs(fd, depth);
-
-       switch (node->u.type_specifier.type) {
-       case TYPESPEC_VOID:
-       case TYPESPEC_CHAR:
-       case TYPESPEC_SHORT:
-       case TYPESPEC_INT:
-       case TYPESPEC_LONG:
-       case TYPESPEC_FLOAT:
-       case TYPESPEC_DOUBLE:
-       case TYPESPEC_SIGNED:
-       case TYPESPEC_UNSIGNED:
-       case TYPESPEC_BOOL:
-       case TYPESPEC_COMPLEX:
-       case TYPESPEC_IMAGINARY:
-       case TYPESPEC_CONST:
-       case TYPESPEC_ID_TYPE:
-               fprintf(fd, "<type_specifier type=\"");
-               break;
-       case TYPESPEC_FLOATING_POINT:
-       case TYPESPEC_INTEGER:
-       case TYPESPEC_STRING:
-       case TYPESPEC_STRUCT:
-       case TYPESPEC_VARIANT:
-       case TYPESPEC_ENUM:
-               fprintf(fd, "<type_specifier>\n");
-               depth++;
-               break;
-       case TYPESPEC_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
-                       (int) node->u.type_specifier.type);
-               return -EINVAL;
-       }
-
-       switch (node->u.type_specifier.type) {
-       case TYPESPEC_VOID:
-               fprintf(fd, "void");
-               break;
-       case TYPESPEC_CHAR:
-               fprintf(fd, "char");
-               break;
-       case TYPESPEC_SHORT:
-               fprintf(fd, "short");
-               break;
-       case TYPESPEC_INT:
-               fprintf(fd, "int");
-               break;
-       case TYPESPEC_LONG:
-               fprintf(fd, "long");
-               break;
-       case TYPESPEC_FLOAT:
-               fprintf(fd, "float");
-               break;
-       case TYPESPEC_DOUBLE:
-               fprintf(fd, "double");
-               break;
-       case TYPESPEC_SIGNED:
-               fprintf(fd, "signed");
-               break;
-       case TYPESPEC_UNSIGNED:
-               fprintf(fd, "unsigned");
-               break;
-       case TYPESPEC_BOOL:
-               fprintf(fd, "bool");
-               break;
-       case TYPESPEC_COMPLEX:
-               fprintf(fd, "_Complex");
-               break;
-       case TYPESPEC_IMAGINARY:
-               fprintf(fd, "_Imaginary");
-               break;
-       case TYPESPEC_CONST:
-               fprintf(fd, "const");
-               break;
-       case TYPESPEC_ID_TYPE:
-               fprintf(fd, "%s", node->u.type_specifier.id_type);
-               break;
-       case TYPESPEC_FLOATING_POINT:
-       case TYPESPEC_INTEGER:
-       case TYPESPEC_STRING:
-       case TYPESPEC_STRUCT:
-       case TYPESPEC_VARIANT:
-       case TYPESPEC_ENUM:
-               ret = ctf_visitor_print_xml(fd, depth, node->u.type_specifier.node);
-               if (ret)
-                       return ret;
-               break;
-       case TYPESPEC_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
-                       (int) node->u.type_specifier.type);
-               return -EINVAL;
-       }
-
-       switch (node->u.type_specifier.type) {
-       case TYPESPEC_VOID:
-       case TYPESPEC_CHAR:
-       case TYPESPEC_SHORT:
-       case TYPESPEC_INT:
-       case TYPESPEC_LONG:
-       case TYPESPEC_FLOAT:
-       case TYPESPEC_DOUBLE:
-       case TYPESPEC_SIGNED:
-       case TYPESPEC_UNSIGNED:
-       case TYPESPEC_BOOL:
-       case TYPESPEC_COMPLEX:
-       case TYPESPEC_IMAGINARY:
-       case TYPESPEC_CONST:
-       case TYPESPEC_ID_TYPE:
-               fprintf(fd, "\"/>\n");
-               break;
-       case TYPESPEC_FLOATING_POINT:
-       case TYPESPEC_INTEGER:
-       case TYPESPEC_STRING:
-       case TYPESPEC_STRUCT:
-       case TYPESPEC_VARIANT:
-       case TYPESPEC_ENUM:
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</type_specifier>\n");
-               break;
-       case TYPESPEC_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown type specifier %d\n", __func__,
-                       (int) node->u.type_specifier.type);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static
-int ctf_visitor_print_type_declarator(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       print_tabs(fd, depth);
-       fprintf(fd, "<type_declarator>\n");
-       depth++;
-
-       if (!bt_list_empty(&node->u.type_declarator.pointers)) {
-               print_tabs(fd, depth);
-               fprintf(fd, "<pointers>\n");
-               bt_list_for_each_entry(iter, &node->u.type_declarator.pointers,
-                                       siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</pointers>\n");
-       }
-
-       switch (node->u.type_declarator.type) {
-       case TYPEDEC_ID:
-               if (node->u.type_declarator.u.id) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<id name=\"");
-                       fprintf(fd, "%s", node->u.type_declarator.u.id);
-                       fprintf(fd, "\" />\n");
-               }
-               break;
-       case TYPEDEC_NESTED:
-               if (node->u.type_declarator.u.nested.type_declarator) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<type_declarator>\n");
-                       ret = ctf_visitor_print_xml(fd, depth + 1,
-                               node->u.type_declarator.u.nested.type_declarator);
-                       if (ret)
-                               return ret;
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</type_declarator>\n");
-               }
-               if (node->u.type_declarator.u.nested.abstract_array) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<length>\n");
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</length>\n");
-               } else if (!bt_list_empty(&node->u.type_declarator.u.nested.length)) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<length>\n");
-                       bt_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
-                                               siblings) {
-                               ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                               if (ret)
-                                       return ret;
-                       }
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</length>\n");
-               }
-               if (node->u.type_declarator.bitfield_len) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<bitfield_len>\n");
-                       ret = ctf_visitor_print_xml(fd, depth + 1,
-                               node->u.type_declarator.bitfield_len);
-                       if (ret)
-                               return ret;
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</bitfield_len>\n");
-               }
-               break;
-       case TYPEDEC_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown type declarator %d\n", __func__,
-                       (int) node->u.type_declarator.type);
-               return -EINVAL;
-       }
-
-       depth--;
-       print_tabs(fd, depth);
-       fprintf(fd, "</type_declarator>\n");
-       return 0;
-}
-
-int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
-{
-       int ret = 0;
-       struct ctf_node *iter;
-
-       if (node->visited)
-               return 0;
-
-       switch (node->type) {
-       case NODE_ROOT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<root>\n");
-               bt_list_for_each_entry(iter, &node->u.root.declaration_list,
-                                       siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.stream, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               bt_list_for_each_entry(iter, &node->u.root.event, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</root>\n");
-               break;
-
-       case NODE_EVENT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<event>\n");
-               bt_list_for_each_entry(iter, &node->u.event.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</event>\n");
-               break;
-       case NODE_STREAM:
-               print_tabs(fd, depth);
-               fprintf(fd, "<stream>\n");
-               bt_list_for_each_entry(iter, &node->u.stream.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</stream>\n");
-               break;
-       case NODE_ENV:
-               print_tabs(fd, depth);
-               fprintf(fd, "<env>\n");
-               bt_list_for_each_entry(iter, &node->u.env.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</env>\n");
-               break;
-       case NODE_TRACE:
-               print_tabs(fd, depth);
-               fprintf(fd, "<trace>\n");
-               bt_list_for_each_entry(iter, &node->u.trace.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</trace>\n");
-               break;
-       case NODE_CLOCK:
-               print_tabs(fd, depth);
-               fprintf(fd, "<clock>\n");
-               bt_list_for_each_entry(iter, &node->u.clock.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</clock>\n");
-               break;
-       case NODE_CALLSITE:
-               print_tabs(fd, depth);
-               fprintf(fd, "<callsite>\n");
-               bt_list_for_each_entry(iter, &node->u.callsite.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</callsite>\n");
-               break;
-
-
-       case NODE_CTF_EXPRESSION:
-               print_tabs(fd, depth);
-               fprintf(fd, "<ctf_expression>\n");
-               depth++;
-               print_tabs(fd, depth);
-               fprintf(fd, "<left>\n");
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.left, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-
-               print_tabs(fd, depth);
-               fprintf(fd, "</left>\n");
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<right>\n");
-               bt_list_for_each_entry(iter, &node->u.ctf_expression.right, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</right>\n");
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</ctf_expression>\n");
-               break;
-       case NODE_UNARY_EXPRESSION:
-               return ctf_visitor_print_unary_expression(fd, depth, node);
-
-       case NODE_TYPEDEF:
-               print_tabs(fd, depth);
-               fprintf(fd, "<typedef>\n");
-               depth++;
-               ret = ctf_visitor_print_xml(fd, depth + 1, node->u._typedef.type_specifier_list);
-               if (ret)
-                       return ret;
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<type_declarator_list>\n");
-               bt_list_for_each_entry(iter, &node->u._typedef.type_declarators, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</type_declarator_list>\n");
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</typedef>\n");
-               break;
-       case NODE_TYPEALIAS_TARGET:
-               print_tabs(fd, depth);
-               fprintf(fd, "<target>\n");
-               depth++;
-
-               ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_target.type_specifier_list);
-               if (ret)
-                       return ret;
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<type_declarator_list>\n");
-               bt_list_for_each_entry(iter, &node->u.typealias_target.type_declarators, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</type_declarator_list>\n");
-
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</target>\n");
-               break;
-       case NODE_TYPEALIAS_ALIAS:
-               print_tabs(fd, depth);
-               fprintf(fd, "<alias>\n");
-               depth++;
-
-               ret = ctf_visitor_print_xml(fd, depth, node->u.typealias_alias.type_specifier_list);
-               if (ret)
-                       return ret;
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<type_declarator_list>\n");
-               bt_list_for_each_entry(iter, &node->u.typealias_alias.type_declarators, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</type_declarator_list>\n");
-
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</alias>\n");
-               break;
-       case NODE_TYPEALIAS:
-               print_tabs(fd, depth);
-               fprintf(fd, "<typealias>\n");
-               ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.target);
-               if (ret)
-                       return ret;
-               ret = ctf_visitor_print_xml(fd, depth + 1, node->u.typealias.alias);
-               if (ret)
-                       return ret;
-               print_tabs(fd, depth);
-               fprintf(fd, "</typealias>\n");
-               break;
-
-       case NODE_TYPE_SPECIFIER_LIST:
-               ret = ctf_visitor_print_type_specifier_list(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_TYPE_SPECIFIER:
-               ret = ctf_visitor_print_type_specifier(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-       case NODE_POINTER:
-               print_tabs(fd, depth);
-               if (node->u.pointer.const_qualifier)
-                       fprintf(fd, "<const_pointer />\n");
-               else
-                       fprintf(fd, "<pointer />\n");
-               break;
-       case NODE_TYPE_DECLARATOR:
-               ret = ctf_visitor_print_type_declarator(fd, depth, node);
-               if (ret)
-                       return ret;
-               break;
-
-       case NODE_FLOATING_POINT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<floating_point>\n");
-               bt_list_for_each_entry(iter, &node->u.floating_point.expressions, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</floating_point>\n");
-               break;
-       case NODE_INTEGER:
-               print_tabs(fd, depth);
-               fprintf(fd, "<integer>\n");
-               bt_list_for_each_entry(iter, &node->u.integer.expressions, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</integer>\n");
-               break;
-       case NODE_STRING:
-               print_tabs(fd, depth);
-               fprintf(fd, "<string>\n");
-               bt_list_for_each_entry(iter, &node->u.string.expressions, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</string>\n");
-               break;
-       case NODE_ENUMERATOR:
-               print_tabs(fd, depth);
-               fprintf(fd, "<enumerator");
-               if (node->u.enumerator.id)
-                       fprintf(fd, " id=\"%s\"", node->u.enumerator.id);
-               fprintf(fd, ">\n");
-               bt_list_for_each_entry(iter, &node->u.enumerator.values, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</enumerator>\n");
-               break;
-       case NODE_ENUM:
-               print_tabs(fd, depth);
-               if (node->u._struct.name)
-                       fprintf(fd, "<enum name=\"%s\">\n",
-                               node->u._enum.enum_id);
-               else
-                       fprintf(fd, "<enum >\n");
-               depth++;
-
-               if (node->u._enum.container_type) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<container_type>\n");
-                       ret = ctf_visitor_print_xml(fd, depth + 1, node->u._enum.container_type);
-                       if (ret)
-                               return ret;
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</container_type>\n");
-               }
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<enumerator_list>\n");
-               bt_list_for_each_entry(iter, &node->u._enum.enumerator_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</enumerator_list>\n");
-
-               depth--;
-               print_tabs(fd, depth);
-               fprintf(fd, "</enum>\n");
-               break;
-       case NODE_STRUCT_OR_VARIANT_DECLARATION:
-               ret = ctf_visitor_print_xml(fd, depth,
-                       node->u.struct_or_variant_declaration.type_specifier_list);
-               if (ret)
-                       return ret;
-
-               print_tabs(fd, depth);
-               fprintf(fd, "<type_declarator_list>\n");
-               bt_list_for_each_entry(iter, &node->u.struct_or_variant_declaration.type_declarators, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</type_declarator_list>\n");
-               break;
-       case NODE_VARIANT:
-               print_tabs(fd, depth);
-               fprintf(fd, "<variant");
-               if (node->u.variant.name)
-                       fprintf(fd, " name=\"%s\"", node->u.variant.name);
-               if (node->u.variant.choice)
-                       fprintf(fd, " choice=\"%s\"", node->u.variant.choice);
-               fprintf(fd, ">\n");
-               bt_list_for_each_entry(iter, &node->u.variant.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</variant>\n");
-               break;
-       case NODE_STRUCT:
-               print_tabs(fd, depth);
-               if (node->u._struct.name)
-                       fprintf(fd, "<struct name=\"%s\">\n",
-                               node->u._struct.name);
-               else
-                       fprintf(fd, "<struct>\n");
-               bt_list_for_each_entry(iter, &node->u._struct.declaration_list, siblings) {
-                       ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
-               print_tabs(fd, depth);
-               fprintf(fd, "</struct>\n");
-               if (!bt_list_empty(&node->u._struct.min_align)) {
-                       print_tabs(fd, depth);
-                       fprintf(fd, "<align>\n");
-                       bt_list_for_each_entry(iter, &node->u._struct.min_align, siblings) {
-                               ret = ctf_visitor_print_xml(fd, depth + 1, iter);
-                               if (ret)
-                                       return ret;
-                       }
-                       print_tabs(fd, depth);
-                       fprintf(fd, "</align>\n");
-               }
-               break;
-
-       case NODE_UNKNOWN:
-       default:
-               fprintf(stderr, "[error] %s: unknown node type %d\n", __func__,
-                       (int) node->type);
-               return -EINVAL;
-       }
-       return ret;
-}
diff --git a/formats/ctf/metadata/objstack.c b/formats/ctf/metadata/objstack.c
deleted file mode 100644 (file)
index 8087722..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * objstack.c
- *
- * Common Trace Format Object Stack.
- *
- * Copyright 2013 - Mathieu Desnoyers <mathieu.desnoyers@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 <stdlib.h>
-#include <babeltrace/list.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/align.h>
-
-#define OBJSTACK_ALIGN                 8       /* Object stack alignment */
-#define OBJSTACK_INIT_LEN              128
-#define OBJSTACK_POISON                        0xcc
-
-struct objstack {
-       struct bt_list_head head;       /* list of struct objstack_node */
-};
-
-struct objstack_node {
-       struct bt_list_head node;
-       size_t len;
-       size_t used_len;
-       char __attribute__ ((aligned (OBJSTACK_ALIGN))) data[];
-};
-
-BT_HIDDEN
-struct objstack *objstack_create(void)
-{
-       struct objstack *objstack;
-       struct objstack_node *node;
-
-       objstack = calloc(1, sizeof(*objstack));
-       if (!objstack)
-               return NULL;
-       node = calloc(sizeof(struct objstack_node) + OBJSTACK_INIT_LEN,
-                       sizeof(char));
-       if (!node) {
-               free(objstack);
-               return NULL;
-       }
-       BT_INIT_LIST_HEAD(&objstack->head);
-       bt_list_add_tail(&node->node, &objstack->head);
-       node->len = OBJSTACK_INIT_LEN;
-       return objstack;
-}
-
-static
-void objstack_node_free(struct objstack_node *node)
-{
-       size_t offset, len;
-       char *p;
-
-       if (!node)
-               return;
-       p = (char *) node;
-       len = sizeof(*node) + node->len;
-       for (offset = 0; offset < len; offset++)
-               p[offset] = OBJSTACK_POISON;
-       free(node);
-}
-
-BT_HIDDEN
-void objstack_destroy(struct objstack *objstack)
-{
-       struct objstack_node *node, *p;
-
-       if (!objstack)
-               return;
-       bt_list_for_each_entry_safe(node, p, &objstack->head, node) {
-               bt_list_del(&node->node);
-               objstack_node_free(node);
-       }
-       free(objstack);
-}
-
-static
-struct objstack_node *objstack_append_node(struct objstack *objstack)
-{
-       struct objstack_node *last_node, *new_node;
-
-       /* Get last node */
-       last_node = bt_list_entry(objstack->head.prev,
-                       struct objstack_node, node);
-
-       /* Allocate new node with double of size of last node */
-       new_node = calloc(sizeof(struct objstack_node) + (last_node->len << 1),
-                       sizeof(char));
-       if (!new_node) {
-               return NULL;
-       }
-       bt_list_add_tail(&new_node->node, &objstack->head);
-       new_node->len = last_node->len << 1;
-       return new_node;
-}
-
-BT_HIDDEN
-void *objstack_alloc(struct objstack *objstack, size_t len)
-{
-       struct objstack_node *last_node;
-       void *p;
-
-       len = ALIGN(len, OBJSTACK_ALIGN);
-
-       /* Get last node */
-       last_node = bt_list_entry(objstack->head.prev,
-                       struct objstack_node, node);
-       while (last_node->len - last_node->used_len < len) {
-               last_node = objstack_append_node(objstack);
-               if (!last_node) {
-                       return NULL;
-               }
-       }
-       p = &last_node->data[last_node->used_len];
-       last_node->used_len += len;
-       return p;
-}
diff --git a/formats/ctf/metadata/objstack.h b/formats/ctf/metadata/objstack.h
deleted file mode 100644 (file)
index c026eb5..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _OBJSTACK_H
-#define _OBJSTACK_H
-
-/*
- * objstack.h
- *
- * Common Trace Format Object Stack.
- *
- * Copyright 2013 - Mathieu Desnoyers <mathieu.desnoyers@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.
- */
-
-struct objstack;
-
-BT_HIDDEN
-struct objstack *objstack_create(void);
-BT_HIDDEN
-void objstack_destroy(struct objstack *objstack);
-
-/*
- * Allocate len bytes of zeroed memory.
- * Return NULL on error.
- */
-BT_HIDDEN
-void *objstack_alloc(struct objstack *objstack, size_t len);
-
-#endif /* _OBJSTACK_H */
diff --git a/formats/ctf/types/Makefile.am b/formats/ctf/types/Makefile.am
deleted file mode 100644 (file)
index 20c1fdd..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libctf-types.la
-
-libctf_types_la_SOURCES = \
-       array.c \
-       enum.c \
-       float.c \
-       integer.c \
-       sequence.c \
-       string.c \
-       struct.c \
-       variant.c
-
-libctf_types_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
diff --git a/formats/ctf/types/array.c b/formats/ctf/types/array.c
deleted file mode 100644 (file)
index 016d527..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Common Trace Format
- *
- * Array format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-
-int ctf_array_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_array *array_definition =
-               container_of(definition, struct definition_array, p);
-       struct declaration_array *array_declaration =
-               array_definition->declaration;
-       struct bt_declaration *elem = array_declaration->elem;
-       struct ctf_stream_pos *pos =
-               container_of(ppos, struct ctf_stream_pos, parent);
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT) {
-
-                               if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-                                       return -EFAULT;
-                               if (!ctf_pos_access_ok(pos, array_declaration->len * CHAR_BIT))
-                                       return -EFAULT;
-
-                               g_string_assign(array_definition->string, "");
-                               g_string_insert_len(array_definition->string,
-                                       0, (char *) ctf_get_pos_addr(pos),
-                                       array_declaration->len);
-                               /*
-                                * We want to populate both the string
-                                * and the underlying values, so carry
-                                * on calling bt_array_rw().
-                                */
-                       }
-               }
-       }
-       return bt_array_rw(ppos, definition);
-}
-
-int ctf_array_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_array *array_definition =
-               container_of(definition, struct definition_array, p);
-       struct declaration_array *array_declaration =
-               array_definition->declaration;
-       struct bt_declaration *elem = array_declaration->elem;
-       struct ctf_stream_pos *pos =
-               container_of(ppos, struct ctf_stream_pos, parent);
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT) {
-
-                               if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-                                       return -EFAULT;
-                               if (!ctf_pos_access_ok(pos, array_declaration->len * CHAR_BIT))
-                                       return -EFAULT;
-
-                               memcpy((char *) ctf_get_pos_addr(pos),
-                                       array_definition->string->str,
-                                       array_declaration->len);
-                               if (!ctf_move_pos(pos, array_declaration->len * CHAR_BIT))
-                                       return -EFAULT;
-                               return 0;
-                       }
-               }
-       }
-       return bt_array_rw(ppos, definition);
-}
diff --git a/formats/ctf/types/enum.c b/formats/ctf/types/enum.c
deleted file mode 100644 (file)
index 9461af6..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Common Trace Format
- *
- * Enumeration mapping strings (quarks) from/to integers.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <glib.h>
-
-int ctf_enum_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_enum *enum_definition =
-               container_of(definition, struct definition_enum, p);
-       const struct declaration_enum *enum_declaration =
-               enum_definition->declaration;
-       struct definition_integer *integer_definition =
-               enum_definition->integer;
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       GArray *qs;
-       int ret;
-
-       ret = ctf_integer_read(ppos, &integer_definition->p);
-       if (ret)
-               return ret;
-       if (!integer_declaration->signedness) {
-               qs = bt_enum_uint_to_quark_set(enum_declaration,
-                       integer_definition->value._unsigned);
-               if (!qs) {
-                       fprintf(stderr, "[warning] Unknown value %" PRIu64 " in enum.\n",
-                               integer_definition->value._unsigned);
-               }
-       } else {
-               qs = bt_enum_int_to_quark_set(enum_declaration,
-                       integer_definition->value._signed);
-               if (!qs) {
-                       fprintf(stderr, "[warning] Unknown value %" PRId64 " in enum.\n",
-                               integer_definition->value._signed);
-               }
-       }
-       /* unref previous quark set */
-       if (enum_definition->value)
-               g_array_unref(enum_definition->value);
-       enum_definition->value = qs;
-       return 0;
-}
-
-int ctf_enum_write(struct bt_stream_pos *pos, struct bt_definition *definition)
-{
-       struct definition_enum *enum_definition =
-               container_of(definition, struct definition_enum, p);
-       struct definition_integer *integer_definition =
-               enum_definition->integer;
-
-       return ctf_integer_write(pos, &integer_definition->p);
-}
diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c
deleted file mode 100644 (file)
index 2586952..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Common Trace Format
- *
- * Floating point read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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.
- *
- * Reference: ISO C99 standard 5.2.4
- */
-
-#include <babeltrace/ctf/types.h>
-#include <glib.h>
-#include <float.h>     /* C99 floating point definitions */
-#include <babeltrace/compat/limits.h>  /* C99 limits */
-#include <babeltrace/endian.h>
-#include <pthread.h>
-
-/*
- * This library is limited to binary representation of floating point values.
- * We use hardware support for conversion between 32 and 64-bit floating
- * point values.
- */
-
-/*
- * Aliasing float/double and unsigned long is not strictly permitted by strict
- * aliasing, but in practice declaration prunning is well supported, and this permits
- * us to use per-word read/writes rather than per-byte.
- */
-
-#if defined(__GNUC__) || defined(__MINGW32__) || defined(_MSC_VER)
-#define HAS_TYPE_PRUNING
-#endif
-
-#if (FLT_RADIX != 2)
-
-#error "Unsupported floating point radix"
-
-#endif
-
-union doubleIEEE754 {
-       double vd;
-       float vf;
-#ifdef HAS_TYPE_PRUNING
-       unsigned long bits[(sizeof(double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
-#else
-       unsigned char bits[sizeof(double)];
-#endif
-};
-
-/*
- * This mutex protects the static temporary float and double
- * declarations (static_float_declaration and static_double_declaration).
- */
-static pthread_mutex_t float_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static struct declaration_float *static_float_declaration,
-               *static_double_declaration;
-
-struct pos_len {
-       size_t len;
-};
-
-static void float_lock(void)
-{
-       int ret;
-
-       ret = pthread_mutex_lock(&float_mutex);
-       assert(!ret);
-}
-
-static void float_unlock(void)
-{
-       int ret;
-
-       ret = pthread_mutex_unlock(&float_mutex);
-       assert(!ret);
-}
-
-static int _ctf_float_copy(struct bt_stream_pos *destp,
-                   struct definition_float *dest_definition,
-                   struct bt_stream_pos *srcp,
-                   const struct definition_float *src_definition)
-{
-       int ret;
-
-       /* We only support copy of same-size floats for now */
-       assert(src_definition->declaration->sign->len ==
-               dest_definition->declaration->sign->len);
-       assert(src_definition->declaration->exp->len ==
-               dest_definition->declaration->exp->len);
-       assert(src_definition->declaration->mantissa->len ==
-               dest_definition->declaration->mantissa->len);
-       /* Read */
-       if (src_definition->declaration->byte_order == LITTLE_ENDIAN) {
-               ret = ctf_integer_read(srcp, &src_definition->mantissa->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_read(srcp, &src_definition->exp->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_read(srcp, &src_definition->sign->p);
-               if (ret)
-                       return ret;
-       } else {
-               ret = ctf_integer_read(srcp, &src_definition->sign->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_read(srcp, &src_definition->exp->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_read(srcp, &src_definition->mantissa->p);
-               if (ret)
-                       return ret;
-       }
-
-       dest_definition->mantissa->value._unsigned =
-               src_definition->mantissa->value._unsigned;
-       dest_definition->exp->value._signed =
-               src_definition->exp->value._signed;
-       dest_definition->sign->value._unsigned =
-               src_definition->sign->value._unsigned;
-
-       /* Write */
-       if (dest_definition->declaration->byte_order == LITTLE_ENDIAN) {
-               ret = ctf_integer_write(destp, &dest_definition->mantissa->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_write(destp, &dest_definition->exp->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_write(destp, &dest_definition->sign->p);
-               if (ret)
-                       return ret;
-       } else {
-               ret = ctf_integer_write(destp, &dest_definition->sign->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_write(destp, &dest_definition->exp->p);
-               if (ret)
-                       return ret;
-               ret = ctf_integer_write(destp, &dest_definition->mantissa->p);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-int ctf_float_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_float *float_definition =
-               container_of(definition, struct definition_float, p);
-       const struct declaration_float *float_declaration =
-               float_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       union doubleIEEE754 u;
-       struct bt_definition *tmpdef;
-       struct definition_float *tmpfloat;
-       struct ctf_stream_pos destp;
-       struct mmap_align mma;
-       int ret;
-
-       float_lock();
-       switch (float_declaration->mantissa->len + 1) {
-       case FLT_MANT_DIG:
-               tmpdef = static_float_declaration->p.definition_new(
-                               &static_float_declaration->p,
-                               NULL, 0, 0, "__tmpfloat");
-               break;
-       case DBL_MANT_DIG:
-               tmpdef = static_double_declaration->p.definition_new(
-                               &static_double_declaration->p,
-                               NULL, 0, 0, "__tmpfloat");
-               break;
-       default:
-               ret = -EINVAL;
-               goto end;
-       }
-       tmpfloat = container_of(tmpdef, struct definition_float, p);
-       memset(&destp, 0, sizeof(destp));
-       ctf_init_pos(&destp, NULL, -1, O_RDWR);
-       mmap_align_set_addr(&mma, (char *) u.bits);
-       destp.base_mma = &mma;
-       destp.content_size = destp.packet_size = sizeof(u) * CHAR_BIT;
-       if (!ctf_align_pos(pos, float_declaration->p.alignment)) {
-               ret = -EFAULT;
-               goto end_unref;
-       }
-       ret = _ctf_float_copy(&destp.parent, tmpfloat, ppos, float_definition);
-       switch (float_declaration->mantissa->len + 1) {
-       case FLT_MANT_DIG:
-               float_definition->value = u.vf;
-               break;
-       case DBL_MANT_DIG:
-               float_definition->value = u.vd;
-               break;
-       default:
-               ret = -EINVAL;
-               goto end_unref;
-       }
-
-end_unref:
-       bt_definition_unref(tmpdef);
-end:
-       float_unlock();
-       return ret;
-}
-
-int ctf_float_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_float *float_definition =
-               container_of(definition, struct definition_float, p);
-       const struct declaration_float *float_declaration =
-               float_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       union doubleIEEE754 u;
-       struct bt_definition *tmpdef;
-       struct definition_float *tmpfloat;
-       struct ctf_stream_pos srcp = { { 0 } };
-       struct mmap_align mma;
-       int ret;
-
-       float_lock();
-       switch (float_declaration->mantissa->len + 1) {
-       case FLT_MANT_DIG:
-               tmpdef = static_float_declaration->p.definition_new(
-                               &static_float_declaration->p,
-                               NULL, 0, 0, "__tmpfloat");
-               break;
-       case DBL_MANT_DIG:
-               tmpdef = static_double_declaration->p.definition_new(
-                               &static_double_declaration->p,
-                               NULL, 0, 0, "__tmpfloat");
-               break;
-       default:
-               ret = -EINVAL;
-               goto end;
-       }
-       tmpfloat = container_of(tmpdef, struct definition_float, p);
-       ctf_init_pos(&srcp, NULL, -1, O_RDONLY);
-       mmap_align_set_addr(&mma, (char *) u.bits);
-       srcp.base_mma = &mma;
-       srcp.content_size = srcp.packet_size = sizeof(u) * CHAR_BIT;
-       switch (float_declaration->mantissa->len + 1) {
-       case FLT_MANT_DIG:
-               u.vf = float_definition->value;
-               break;
-       case DBL_MANT_DIG:
-               u.vd = float_definition->value;
-               break;
-       default:
-               ret = -EINVAL;
-               goto end_unref;
-       }
-       if (!ctf_align_pos(pos, float_declaration->p.alignment)) {
-               ret = -EFAULT;
-               goto end_unref;
-       }
-       ret = _ctf_float_copy(ppos, float_definition, &srcp.parent, tmpfloat);
-
-end_unref:
-       bt_definition_unref(tmpdef);
-end:
-       float_unlock();
-       return ret;
-}
-
-double bt_get_float(const struct bt_definition *field)
-{
-       struct definition_float *definition =
-               container_of(field, struct definition_float, p);
-
-       return definition->value;
-}
-
-static
-void __attribute__((constructor)) ctf_float_init(void)
-{
-       static_float_declaration =
-               bt_float_declaration_new(FLT_MANT_DIG,
-                               sizeof(float) * CHAR_BIT - FLT_MANT_DIG,
-                               BYTE_ORDER,
-                               __alignof__(float));
-       static_double_declaration =
-               bt_float_declaration_new(DBL_MANT_DIG,
-                               sizeof(double) * CHAR_BIT - DBL_MANT_DIG,
-                               BYTE_ORDER,
-                               __alignof__(double));
-}
-
-static
-void __attribute__((destructor)) ctf_float_fini(void)
-{
-       bt_declaration_unref(&static_float_declaration->p);
-       bt_declaration_unref(&static_double_declaration->p);
-}
diff --git a/formats/ctf/types/integer.c b/formats/ctf/types/integer.c
deleted file mode 100644 (file)
index 85931be..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Common Trace Format
- *
- * Integers read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-#include <babeltrace/bitfield.h>
-#include <stdint.h>
-#include <glib.h>
-#include <babeltrace/endian.h>
-
-/*
- * The aligned read/write functions are expected to be faster than the
- * bitfield variants. They will be enabled eventually as an
- * optimisation.
- */
-
-static
-int _aligned_integer_read(struct bt_stream_pos *ppos,
-                         struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-               container_of(definition, struct definition_integer, p);
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       int rbo = (integer_declaration->byte_order != BYTE_ORDER);      /* reverse byte order */
-
-       if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-               return -EFAULT;
-
-       if (!ctf_pos_access_ok(pos, integer_declaration->len))
-               return -EFAULT;
-
-       assert(!(pos->offset % CHAR_BIT));
-       if (!integer_declaration->signedness) {
-               switch (integer_declaration->len) {
-               case 8:
-               {
-                       uint8_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._unsigned = v;
-                       break;
-               }
-               case 16:
-               {
-                       uint16_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._unsigned =
-                               rbo ? GUINT16_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               case 32:
-               {
-                       uint32_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._unsigned =
-                               rbo ? GUINT32_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               case 64:
-               {
-                       uint64_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._unsigned =
-                               rbo ? GUINT64_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               default:
-                       assert(0);
-               }
-       } else {
-               switch (integer_declaration->len) {
-               case 8:
-               {
-                       int8_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._signed = v;
-                       break;
-               }
-               case 16:
-               {
-                       int16_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._signed =
-                               rbo ? (int16_t) GUINT16_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               case 32:
-               {
-                       int32_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._signed =
-                               rbo ? (int32_t) GUINT32_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               case 64:
-               {
-                       int64_t v;
-
-                       memcpy(&v, ctf_get_pos_addr(pos), sizeof(v));
-                       integer_definition->value._signed =
-                               rbo ? (int64_t) GUINT64_SWAP_LE_BE(v) : v;
-                       break;
-               }
-               default:
-                       assert(0);
-               }
-       }
-       if (!ctf_move_pos(pos, integer_declaration->len))
-               return -EFAULT;
-       return 0;
-}
-
-static
-int _aligned_integer_write(struct bt_stream_pos *ppos,
-                           struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-               container_of(definition, struct definition_integer, p);
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       int rbo = (integer_declaration->byte_order != BYTE_ORDER);      /* reverse byte order */
-
-       if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-               return -EFAULT;
-
-       if (!ctf_pos_access_ok(pos, integer_declaration->len))
-               return -EFAULT;
-
-       assert(!(pos->offset % CHAR_BIT));
-       if (pos->dummy)
-               goto end;
-       if (!integer_declaration->signedness) {
-               switch (integer_declaration->len) {
-               case 8:
-               {
-                       uint8_t v = integer_definition->value._unsigned;
-
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 16:
-               {
-                       uint16_t v = integer_definition->value._unsigned;
-
-                       if (rbo)
-                               v = GUINT16_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 32:
-               {
-                       uint32_t v = integer_definition->value._unsigned;
-
-                       if (rbo)
-                               v = GUINT32_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 64:
-               {
-                       uint64_t v = integer_definition->value._unsigned;
-
-                       if (rbo)
-                               v = GUINT64_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               default:
-                       assert(0);
-               }
-       } else {
-               switch (integer_declaration->len) {
-               case 8:
-               {
-                       uint8_t v = integer_definition->value._signed;
-
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 16:
-               {
-                       int16_t v = integer_definition->value._signed;
-
-                       if (rbo)
-                               v = GUINT16_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 32:
-               {
-                       int32_t v = integer_definition->value._signed;
-
-                       if (rbo)
-                               v = GUINT32_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               case 64:
-               {
-                       int64_t v = integer_definition->value._signed;
-
-                       if (rbo)
-                               v = GUINT64_SWAP_LE_BE(v);
-                       memcpy(ctf_get_pos_addr(pos), &v, sizeof(v));
-                       break;
-               }
-               default:
-                       assert(0);
-               }
-       }
-end:
-       if (!ctf_move_pos(pos, integer_declaration->len))
-               return -EFAULT;
-       return 0;
-}
-
-int ctf_integer_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-               container_of(definition, struct definition_integer, p);
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (!(integer_declaration->p.alignment % CHAR_BIT)
-           && !(integer_declaration->len % CHAR_BIT)) {
-               return _aligned_integer_read(ppos, definition);
-       }
-
-       if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-               return -EFAULT;
-
-       if (!ctf_pos_access_ok(pos, integer_declaration->len))
-               return -EFAULT;
-
-       if (!integer_declaration->signedness) {
-               if (integer_declaration->byte_order == LITTLE_ENDIAN)
-                       bt_bitfield_read_le(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               &integer_definition->value._unsigned);
-               else
-                       bt_bitfield_read_be(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               &integer_definition->value._unsigned);
-       } else {
-               if (integer_declaration->byte_order == LITTLE_ENDIAN)
-                       bt_bitfield_read_le(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               &integer_definition->value._signed);
-               else
-                       bt_bitfield_read_be(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               &integer_definition->value._signed);
-       }
-       if (!ctf_move_pos(pos, integer_declaration->len))
-               return -EFAULT;
-       return 0;
-}
-
-int ctf_integer_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-               container_of(definition, struct definition_integer, p);
-       const struct declaration_integer *integer_declaration =
-               integer_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (!(integer_declaration->p.alignment % CHAR_BIT)
-           && !(integer_declaration->len % CHAR_BIT)) {
-               return _aligned_integer_write(ppos, definition);
-       }
-
-       if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-               return -EFAULT;
-
-       if (!ctf_pos_access_ok(pos, integer_declaration->len))
-               return -EFAULT;
-
-       if (pos->dummy)
-               goto end;
-       if (!integer_declaration->signedness) {
-               if (integer_declaration->byte_order == LITTLE_ENDIAN)
-                       bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               integer_definition->value._unsigned);
-               else
-                       bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               integer_definition->value._unsigned);
-       } else {
-               if (integer_declaration->byte_order == LITTLE_ENDIAN)
-                       bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               integer_definition->value._signed);
-               else
-                       bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
-                                       pos->mmap_base_offset, unsigned char,
-                               pos->offset, integer_declaration->len,
-                               integer_definition->value._signed);
-       }
-end:
-       if (!ctf_move_pos(pos, integer_declaration->len))
-               return -EFAULT;
-       return 0;
-}
diff --git a/formats/ctf/types/sequence.c b/formats/ctf/types/sequence.c
deleted file mode 100644 (file)
index 518b13d..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Common Trace Format
- *
- * Sequence format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-
-int ctf_sequence_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_sequence *sequence_definition =
-               container_of(definition, struct definition_sequence, p);
-       struct declaration_sequence *sequence_declaration =
-               sequence_definition->declaration;
-       struct bt_declaration *elem = sequence_declaration->elem;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT) {
-                               uint64_t len = bt_sequence_len(sequence_definition);
-
-                               if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-                                       return -EFAULT;
-                               if (!ctf_pos_access_ok(pos, len * CHAR_BIT))
-                                       return -EFAULT;
-
-                               g_string_assign(sequence_definition->string, "");
-                               g_string_insert_len(sequence_definition->string,
-                                       0, (char *) ctf_get_pos_addr(pos), len);
-                               if (!ctf_move_pos(pos, len * CHAR_BIT))
-                                       return -EFAULT;
-                               return 0;
-                       }
-               }
-       }
-       return bt_sequence_rw(ppos, definition);
-}
-
-int ctf_sequence_write(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_sequence *sequence_definition =
-               container_of(definition, struct definition_sequence, p);
-       struct declaration_sequence *sequence_declaration =
-               sequence_definition->declaration;
-       struct bt_declaration *elem = sequence_declaration->elem;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT) {
-                               uint64_t len = bt_sequence_len(sequence_definition);
-
-                               if (!ctf_align_pos(pos, integer_declaration->p.alignment))
-                                       return -EFAULT;
-                               if (!ctf_pos_access_ok(pos, len * CHAR_BIT))
-                                       return -EFAULT;
-
-                               memcpy((char *) ctf_get_pos_addr(pos),
-                                       sequence_definition->string->str, len);
-                               if (!ctf_move_pos(pos, len * CHAR_BIT))
-                                       return -EFAULT;
-                               return 0;
-                       }
-               }
-       }
-       return bt_sequence_rw(ppos, definition);
-}
diff --git a/formats/ctf/types/string.c b/formats/ctf/types/string.c
deleted file mode 100644 (file)
index a9cff6d..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Common Trace Format
- *
- * Strings read/write functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/ctf/types.h>
-#include <babeltrace/compat/limits.h>  /* C99 limits */
-#include <babeltrace/compat/string.h>
-
-int ctf_string_read(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_string *string_definition =
-               container_of(definition, struct definition_string, p);
-       const struct declaration_string *string_declaration =
-               string_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       size_t len;
-       ssize_t max_len_bits;
-       char *srcaddr;
-
-       if (!ctf_align_pos(pos, string_declaration->p.alignment))
-               return -EFAULT;
-
-       srcaddr = ctf_get_pos_addr(pos);
-       if (pos->offset == EOF)
-               return -EFAULT;
-       /* Not counting \0. Counting in bits. */
-       max_len_bits = pos->packet_size - pos->offset - CHAR_BIT;
-       if (max_len_bits < 0)
-               return -EFAULT;
-       /* Add \0, counting in bytes. */
-       len = bt_strnlen(srcaddr, (size_t) max_len_bits / CHAR_BIT) + 1;
-       /* Truncated string, unexpected. Trace probably corrupted. */
-       if (srcaddr[len - 1] != '\0')
-               return -EFAULT;
-
-       if (string_definition->alloc_len < len) {
-               string_definition->value =
-                       g_realloc(string_definition->value, len);
-               string_definition->alloc_len = len;
-       }
-       printf_debug("CTF string read %s\n", srcaddr);
-       memcpy(string_definition->value, srcaddr, len);
-       string_definition->len = len;
-       if (!ctf_move_pos(pos, len * CHAR_BIT))
-               return -EFAULT;
-       return 0;
-}
-
-int ctf_string_write(struct bt_stream_pos *ppos,
-                     struct bt_definition *definition)
-{
-       struct definition_string *string_definition =
-               container_of(definition, struct definition_string, p);
-       const struct declaration_string *string_declaration =
-               string_definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-       size_t len;
-       char *destaddr;
-
-       if (!ctf_align_pos(pos, string_declaration->p.alignment))
-               return -EFAULT;
-       assert(string_definition->value != NULL);
-       len = string_definition->len;
-
-       if (!ctf_pos_access_ok(pos, len))
-               return -EFAULT;
-
-       if (pos->dummy)
-               goto end;
-       destaddr = ctf_get_pos_addr(pos);
-       memcpy(destaddr, string_definition->value, len);
-end:
-       if (!ctf_move_pos(pos, len * CHAR_BIT))
-               return -EFAULT;
-       return 0;
-}
diff --git a/formats/ctf/types/struct.c b/formats/ctf/types/struct.c
deleted file mode 100644 (file)
index cbf53c1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Common Trace Format
- *
- * Structure format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-
-int ctf_struct_rw(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct bt_declaration *declaration = definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (!ctf_align_pos(pos, declaration->alignment))
-               return -EFAULT;
-       return bt_struct_rw(ppos, definition);
-}
diff --git a/formats/ctf/types/variant.c b/formats/ctf/types/variant.c
deleted file mode 100644 (file)
index fc7b7ad..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Common Trace Format
- *
- * Variant format access functions.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-
-int ctf_variant_rw(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct bt_declaration *declaration = definition->declaration;
-       struct ctf_stream_pos *pos = ctf_pos(ppos);
-
-       if (!ctf_align_pos(pos, declaration->alignment))
-               return -EFAULT;
-       return bt_variant_rw(ppos, definition);
-}
diff --git a/formats/ctf/writer/Makefile.am b/formats/ctf/writer/Makefile.am
deleted file mode 100644 (file)
index 1fa1fbc..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libctf-writer.la
-
-libctf_writer_la_SOURCES = \
-       clock.c \
-       writer.c \
-       functor.c
-
-libctf_writer_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
-
-if BABELTRACE_BUILD_WITH_LIBUUID
-libctf_writer_la_LIBADD += -luuid
-endif
-if BABELTRACE_BUILD_WITH_LIBC_UUID
-libctf_writer_la_LIBADD += -lc
-endif
diff --git a/formats/ctf/writer/clock.c b/formats/ctf/writer/clock.c
deleted file mode 100644 (file)
index 84125f2..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * clock.c
- *
- * Babeltrace CTF IR - Clock
- *
- * 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.
- */
-
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler.h>
-#include <inttypes.h>
-
-static
-void bt_ctf_clock_destroy(struct bt_object *obj);
-
-struct bt_ctf_clock *bt_ctf_clock_create(const char *name)
-{
-       struct bt_ctf_clock *clock = NULL;
-
-       if (!name) {
-               goto error;
-       }
-
-       clock = g_new0(struct bt_ctf_clock, 1);
-
-       if (!clock) {
-               goto error;
-       }
-
-       bt_object_init(clock, bt_ctf_clock_destroy);
-       clock->value = 0;
-       clock->clock_class = bt_ctf_clock_class_create(name);
-       if (!clock->clock_class) {
-               goto error;
-       }
-       return clock;
-
-error:
-       BT_PUT(clock);
-       return clock;
-}
-
-const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock)
-{
-       const char *name = NULL;
-
-       if (clock) {
-               name = bt_ctf_clock_class_get_name(clock->clock_class);
-       }
-
-       return name;
-}
-
-const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock)
-{
-       const char *description = NULL;
-
-       if (clock) {
-               description = bt_ctf_clock_class_get_description(
-                       clock->clock_class);
-       }
-
-       return description;
-}
-
-int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_description(clock->clock_class,
-                       desc);
-       }
-
-       return ret;
-}
-
-uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock)
-{
-       uint64_t freq = -1ULL;
-
-       if (clock) {
-               freq = bt_ctf_clock_class_get_frequency(clock->clock_class);
-       }
-
-       return freq;
-}
-
-int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_frequency(clock->clock_class,
-                       freq);
-       }
-
-       return ret;
-}
-
-uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock)
-{
-       uint64_t precision = -1ULL;
-
-       if (clock) {
-               precision = bt_ctf_clock_class_get_precision(
-                       clock->clock_class);
-       }
-
-       return precision;
-}
-
-int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_precision(clock->clock_class,
-                       precision);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_get_offset_s(clock->clock_class,
-                       offset_s);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_offset_s(clock->clock_class,
-                       offset_s);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_get_offset_cycles(clock->clock_class,
-                       offset);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_offset_cycles(clock->clock_class,
-                       offset);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock)
-{
-       int is_absolute = -1;
-
-       if (clock) {
-               is_absolute = bt_ctf_clock_class_get_is_absolute(
-                       clock->clock_class);
-       }
-
-       return is_absolute;
-}
-
-int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_is_absolute(clock->clock_class,
-                       is_absolute);
-       }
-
-       return ret;
-}
-
-const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock)
-{
-       const unsigned char *uuid = NULL;
-
-       if (clock) {
-               uuid = bt_ctf_clock_class_get_uuid(clock->clock_class);
-       }
-
-       return uuid;
-}
-
-int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid)
-{
-       int ret = -1;
-
-       if (clock) {
-               ret = bt_ctf_clock_class_set_uuid(clock->clock_class, uuid);
-       }
-
-       return ret;
-}
-
-int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
-{
-       int ret = 0;
-       int64_t value;
-
-       if (!clock) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Common case where cycles are actually nanoseconds */
-       if (clock->clock_class->frequency == 1000000000) {
-               value = time;
-       } else {
-               value = (uint64_t) (((double) time *
-                       (double) clock->clock_class->frequency) / 1e9);
-       }
-
-       if (clock->value > value) {
-               /* Timestamps must be strictly monotonic. */
-               ret = -1;
-               goto end;
-       }
-
-       clock->value = value;
-end:
-       return ret;
-}
-
-void bt_ctf_clock_get(struct bt_ctf_clock *clock)
-{
-       bt_get(clock);
-}
-
-void bt_ctf_clock_put(struct bt_ctf_clock *clock)
-{
-       bt_put(clock);
-}
-
-BT_HIDDEN
-int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value)
-{
-       int ret = 0;
-
-       if (!clock || !value) {
-               ret = -1;
-               goto end;
-       }
-
-       *value = clock->value;
-end:
-       return ret;
-}
-
-static
-void bt_ctf_clock_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_clock *clock;
-
-       clock = container_of(obj, struct bt_ctf_clock, base);
-       bt_put(clock->clock_class);
-       g_free(clock);
-}
diff --git a/formats/ctf/writer/functor.c b/formats/ctf/writer/functor.c
deleted file mode 100644 (file)
index 3d99b63..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * functor.c
- *
- * Babeltrace CTF Writer
- *
- * 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 <glib.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-
-BT_HIDDEN
-void value_exists(gpointer element, gpointer search_query)
-{
-       if (element == ((struct search_query *)search_query)->value) {
-               ((struct search_query *)search_query)->found = 1;
-       }
-}
diff --git a/formats/ctf/writer/writer.c b/formats/ctf/writer/writer.c
deleted file mode 100644 (file)
index 854de43..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * writer.c
- *
- * Babeltrace CTF Writer
- *
- * 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-writer/clock-internal.h>
-#include <babeltrace/ctf-writer/writer-internal.h>
-#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/fields-internal.h>
-#include <babeltrace/ctf-writer/functor-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/ref.h>
-#include <babeltrace/compiler.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
-
-static
-void bt_ctf_writer_destroy(struct bt_object *obj);
-
-struct bt_ctf_writer *bt_ctf_writer_create(const char *path)
-{
-       struct bt_ctf_writer *writer = NULL;
-
-       if (!path) {
-               goto error;
-       }
-
-       writer = g_new0(struct bt_ctf_writer, 1);
-       if (!writer) {
-               goto error;
-       }
-
-       bt_object_init(writer, bt_ctf_writer_destroy);
-       writer->path = g_string_new(path);
-       if (!writer->path) {
-               goto error_destroy;
-       }
-
-       writer->trace = bt_ctf_trace_create();
-       if (!writer->trace) {
-               goto error_destroy;
-       }
-
-       writer->trace->is_created_by_writer = 1;
-       bt_object_set_parent(writer->trace, writer);
-       bt_put(writer->trace);
-       /* Create trace directory if necessary and open a metadata file */
-       if (g_mkdir_with_parents(path, S_IRWXU | S_IRWXG)) {
-               perror("g_mkdir_with_parents");
-               goto error_destroy;
-       }
-
-       writer->trace_dir_fd = open(path, O_RDONLY, S_IRWXU | S_IRWXG);
-       if (writer->trace_dir_fd < 0) {
-               perror("open");
-               goto error_destroy;
-       }
-
-       writer->metadata_fd = openat(writer->trace_dir_fd, "metadata",
-               O_WRONLY | O_CREAT | O_TRUNC,
-               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-
-       return writer;
-
-error_destroy:
-       unlinkat(writer->trace_dir_fd, "metadata", 0);
-       BT_PUT(writer);
-error:
-       return writer;
-}
-
-void bt_ctf_writer_destroy(struct bt_object *obj)
-{
-       struct bt_ctf_writer *writer;
-
-       writer = container_of(obj, struct bt_ctf_writer, base);
-       bt_ctf_writer_flush_metadata(writer);
-       if (writer->path) {
-               g_string_free(writer->path, TRUE);
-       }
-
-       if (writer->trace_dir_fd > 0) {
-               if (close(writer->trace_dir_fd)) {
-                       perror("close");
-               }
-       }
-
-       if (writer->metadata_fd > 0) {
-               if (close(writer->metadata_fd)) {
-                       perror("close");
-               }
-       }
-
-       bt_object_release(writer->trace);
-       g_free(writer);
-}
-
-struct bt_ctf_trace *bt_ctf_writer_get_trace(struct bt_ctf_writer *writer)
-{
-       struct bt_ctf_trace *trace = NULL;
-
-       if (!writer) {
-               goto end;
-       }
-
-       trace = writer->trace;
-       bt_get(trace);
-end:
-       return trace;
-}
-
-struct bt_ctf_stream *bt_ctf_writer_create_stream(struct bt_ctf_writer *writer,
-               struct bt_ctf_stream_class *stream_class)
-{
-       struct bt_ctf_stream *stream = NULL;
-       int stream_class_count;
-       bool stream_class_found = false;
-       int i;
-
-       if (!writer || !stream_class) {
-               goto error;
-       }
-
-       /* Make sure the stream class is part of the writer's trace */
-       stream_class_count = bt_ctf_trace_get_stream_class_count(writer->trace);
-       if (stream_class_count < 0) {
-               goto error;
-       }
-
-       for (i = 0; i < stream_class_count; i++) {
-               struct bt_ctf_stream_class *existing_stream_class =
-                       bt_ctf_trace_get_stream_class(writer->trace, i);
-
-               if (existing_stream_class == stream_class) {
-                       stream_class_found = true;
-               }
-
-               BT_PUT(existing_stream_class);
-
-               if (stream_class_found) {
-                       break;
-               }
-       }
-
-       if (!stream_class_found) {
-               int ret = bt_ctf_trace_add_stream_class(writer->trace,
-                       stream_class);
-
-               if (ret) {
-                       goto error;
-               }
-       }
-
-       stream = bt_ctf_stream_create(stream_class, NULL);
-       if (!stream) {
-               goto error;
-       }
-
-       return stream;
-
-error:
-        BT_PUT(stream);
-       return stream;
-}
-
-int bt_ctf_writer_add_environment_field(struct bt_ctf_writer *writer,
-               const char *name,
-               const char *value)
-{
-       int ret = -1;
-
-       if (!writer || !name || !value) {
-               goto end;
-       }
-
-       ret = bt_ctf_trace_set_environment_field_string(writer->trace,
-               name, value);
-end:
-       return ret;
-}
-
-int bt_ctf_writer_add_environment_field_int64(struct bt_ctf_writer *writer,
-               const char *name,
-               int64_t value)
-{
-       int ret = -1;
-
-       if (!writer || !name) {
-               goto end;
-       }
-
-       ret = bt_ctf_trace_set_environment_field_integer(writer->trace, name,
-               value);
-end:
-       return ret;
-}
-
-int bt_ctf_writer_add_clock(struct bt_ctf_writer *writer,
-               struct bt_ctf_clock *clock)
-{
-       int ret = -1;
-
-       if (!writer || !clock) {
-               goto end;
-       }
-
-       ret = bt_ctf_trace_add_clock_class(writer->trace, clock->clock_class);
-end:
-       return ret;
-}
-
-char *bt_ctf_writer_get_metadata_string(struct bt_ctf_writer *writer)
-{
-       char *metadata_string = NULL;
-
-       if (!writer) {
-               goto end;
-       }
-
-       metadata_string = bt_ctf_trace_get_metadata_string(
-               writer->trace);
-end:
-       return metadata_string;
-}
-
-void bt_ctf_writer_flush_metadata(struct bt_ctf_writer *writer)
-{
-       int ret;
-       char *metadata_string = NULL;
-
-       if (!writer) {
-               goto end;
-       }
-
-       metadata_string = bt_ctf_trace_get_metadata_string(
-               writer->trace);
-       if (!metadata_string) {
-               goto end;
-       }
-
-       if (lseek(writer->metadata_fd, 0, SEEK_SET) == (off_t)-1) {
-               perror("lseek");
-               goto end;
-       }
-
-       if (ftruncate(writer->metadata_fd, 0)) {
-               perror("ftruncate");
-               goto end;
-       }
-
-       ret = write(writer->metadata_fd, metadata_string,
-               strlen(metadata_string));
-       if (ret < 0) {
-               perror("write");
-               goto end;
-       }
-end:
-       g_free(metadata_string);
-}
-
-int bt_ctf_writer_set_byte_order(struct bt_ctf_writer *writer,
-               enum bt_ctf_byte_order byte_order)
-{
-       int ret = 0;
-
-       if (!writer || writer->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = bt_ctf_trace_set_byte_order(writer->trace,
-               byte_order);
-end:
-       return ret;
-}
-
-void bt_ctf_writer_get(struct bt_ctf_writer *writer)
-{
-       bt_get(writer);
-}
-
-void bt_ctf_writer_put(struct bt_ctf_writer *writer)
-{
-       bt_put(writer);
-}
-
-BT_HIDDEN
-void bt_ctf_writer_freeze(struct bt_ctf_writer *writer)
-{
-       writer->frozen = 1;
-}
diff --git a/formats/lttng-live/Makefile.am b/formats/lttng-live/Makefile.am
deleted file mode 100644 (file)
index d976979..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)
-
-lib_LTLIBRARIES = libbabeltrace-lttng-live.la
-
-noinst_HEADERS = \
-                lttng-viewer-abi.h \
-                lttng-live.h
-
-libbabeltrace_lttng_live_la_SOURCES = \
-       lttng-live-plugin.c lttng-live-comm.c
-
-# Request that the linker keeps all static libraries objects.
-libbabeltrace_lttng_live_la_LDFLAGS = \
-       $(LD_NO_AS_NEEDED) -version-info $(BABELTRACE_LIBRARY_VERSION)
-
-libbabeltrace_lttng_live_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la
diff --git a/formats/lttng-live/lttng-live-comm.c b/formats/lttng-live/lttng-live-comm.c
deleted file mode 100644 (file)
index 6c5d4fd..0000000
+++ /dev/null
@@ -1,1754 +0,0 @@
-/*
- * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
- *                      Mathieu Desnoyers <mathieu.desnoyers@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 <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <fcntl.h>
-#include <poll.h>
-
-#include <babeltrace/ctf/ctf-index.h>
-
-#include <babeltrace/babeltrace.h>
-#include <babeltrace/ctf/events.h>
-#include <babeltrace/ctf/callbacks.h>
-#include <babeltrace/ctf/iterator.h>
-
-/* for packet_index */
-#include <babeltrace/ctf/types.h>
-
-#include <babeltrace/ctf/metadata.h>
-#include <babeltrace/ctf-text/types.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <formats/ctf/events-private.h>
-
-#include <babeltrace/endian.h>
-#include <babeltrace/compat/memstream.h>
-#include <babeltrace/compat/send.h>
-#include <babeltrace/compat/string.h>
-#include <babeltrace/compat/mman.h>
-#include <babeltrace/babeltrace-internal.h>
-
-#include "lttng-live.h"
-#include "lttng-viewer-abi.h"
-
-#define ACTIVE_POLL_DELAY      100     /* ms */
-
-static void ctf_live_packet_seek(struct bt_stream_pos *stream_pos,
-               size_t index, int whence);
-static int add_traces(struct lttng_live_ctx *ctx);
-static int del_traces(gpointer key, gpointer value, gpointer user_data);
-static int get_new_metadata(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *viewer_stream,
-               char **metadata_buf);
-
-static
-ssize_t lttng_live_recv(int fd, void *buf, size_t len)
-{
-       ssize_t ret;
-       size_t copied = 0, to_copy = len;
-
-       do {
-               ret = recv(fd, buf + copied, to_copy, 0);
-               if (ret > 0) {
-                       assert(ret <= to_copy);
-                       copied += ret;
-                       to_copy -= ret;
-               }
-       } while ((ret > 0 && to_copy > 0)
-               || (ret < 0 && errno == EINTR));
-       if (ret > 0)
-               ret = copied;
-       /* ret = 0 means orderly shutdown, ret < 0 is error. */
-       return ret;
-}
-
-static
-ssize_t lttng_live_send(int fd, const void *buf, size_t len)
-{
-       ssize_t ret;
-
-       do {
-               ret = bt_send_nosigpipe(fd, buf, len);
-       } while (ret < 0 && errno == EINTR);
-       return ret;
-}
-
-int lttng_live_connect_viewer(struct lttng_live_ctx *ctx)
-{
-       struct hostent *host;
-       struct sockaddr_in server_addr;
-       int ret;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       host = gethostbyname(ctx->relay_hostname);
-       if (!host) {
-               fprintf(stderr, "[error] Cannot lookup hostname %s\n",
-                       ctx->relay_hostname);
-               goto error;
-       }
-
-       if ((ctx->control_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-               perror("Socket");
-               goto error;
-       }
-
-       server_addr.sin_family = AF_INET;
-       server_addr.sin_port = htons(ctx->port);
-       server_addr.sin_addr = *((struct in_addr *) host->h_addr);
-       memset(&(server_addr.sin_zero), 0, 8);
-
-       if (connect(ctx->control_sock, (struct sockaddr *) &server_addr,
-                               sizeof(struct sockaddr)) == -1) {
-               perror("Connect");
-               goto error;
-       }
-
-       ret = 0;
-
-end:
-       return ret;
-
-error:
-       fprintf(stderr, "[error] Connection failed\n");
-       return -1;
-}
-
-int lttng_live_establish_connection(struct lttng_live_ctx *ctx)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_connect connect;
-       int ret;
-       ssize_t ret_len;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT);
-       cmd.data_size = htobe64((uint64_t) sizeof(connect));
-       cmd.cmd_version = htobe32(0);
-
-       connect.viewer_session_id = -1ULL;      /* will be set on recv */
-       connect.major = htobe32(LTTNG_LIVE_MAJOR);
-       connect.minor = htobe32(LTTNG_LIVE_MINOR);
-       connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &connect, sizeof(connect));
-       if (ret_len < 0) {
-               perror("[error] Error sending version");
-               goto error;
-       }
-       assert(ret_len == sizeof(connect));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &connect, sizeof(connect));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving version");
-               goto error;
-       }
-       assert(ret_len == sizeof(connect));
-
-       printf_verbose("Received viewer session ID : %" PRIu64 "\n",
-                       be64toh(connect.viewer_session_id));
-       printf_verbose("Relayd version : %u.%u\n", be32toh(connect.major),
-                       be32toh(connect.minor));
-
-       if (LTTNG_LIVE_MAJOR != be32toh(connect.major)) {
-               fprintf(stderr, "[error] Incompatible lttng-relayd protocol\n");
-               goto error;
-       }
-       /* Use the smallest protocol version implemented. */
-       if (LTTNG_LIVE_MINOR > be32toh(connect.minor)) {
-               ctx->minor =  be32toh(connect.minor);
-       } else {
-               ctx->minor =  LTTNG_LIVE_MINOR;
-       }
-       ctx->major = LTTNG_LIVE_MAJOR;
-       ret = 0;
-end:
-       return ret;
-
-error:
-       fprintf(stderr, "[error] Unable to establish connection\n");
-       return -1;
-}
-
-static
-void free_session_list(GPtrArray *session_list)
-{
-       int i;
-       struct lttng_live_relay_session *relay_session;
-
-       for (i = 0; i < session_list->len; i++) {
-               relay_session = g_ptr_array_index(session_list, i);
-               free(relay_session->name);
-               free(relay_session->hostname);
-       }
-       g_ptr_array_free(session_list, TRUE);
-}
-
-static
-void print_session_list(GPtrArray *session_list, const char *path)
-{
-       int i;
-       struct lttng_live_relay_session *relay_session;
-
-       for (i = 0; i < session_list->len; i++) {
-               relay_session = g_ptr_array_index(session_list, i);
-               fprintf(LTTNG_LIVE_OUTPUT_FP, "%s/host/%s/%s (timer = %u, "
-                               "%u stream(s), %u client(s) connected)\n",
-                               path, relay_session->hostname,
-                               relay_session->name, relay_session->timer,
-                               relay_session->streams, relay_session->clients);
-       }
-}
-
-static
-void update_session_list(GPtrArray *session_list, char *hostname,
-               char *session_name, uint32_t streams, uint32_t clients,
-               uint32_t timer)
-{
-       int i, found = 0;
-       struct lttng_live_relay_session *relay_session;
-
-       for (i = 0; i < session_list->len; i++) {
-               relay_session = g_ptr_array_index(session_list, i);
-               if ((strncmp(relay_session->hostname, hostname, MAXNAMLEN) == 0) &&
-                               strncmp(relay_session->name,
-                                       session_name, MAXNAMLEN) == 0) {
-                       relay_session->streams += streams;
-                       if (relay_session->clients < clients)
-                               relay_session->clients = clients;
-                       found = 1;
-                       break;
-               }
-       }
-       if (found)
-               return;
-
-       relay_session = g_new0(struct lttng_live_relay_session, 1);
-       relay_session->hostname = bt_strndup(hostname, MAXNAMLEN);
-       relay_session->name = bt_strndup(session_name, MAXNAMLEN);
-       relay_session->clients = clients;
-       relay_session->streams = streams;
-       relay_session->timer = timer;
-       g_ptr_array_add(session_list, relay_session);
-}
-
-int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_list_sessions list;
-       struct lttng_viewer_session lsession;
-       int i, ret, sessions_count, print_list = 0;
-       ssize_t ret_len;
-       uint64_t session_id;
-       GPtrArray *session_list = NULL;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       if (strlen(ctx->session_name) == 0) {
-               print_list = 1;
-               session_list = g_ptr_array_new();
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS);
-       cmd.data_size = htobe64((uint64_t) 0);
-       cmd.cmd_version = htobe32(0);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &list, sizeof(list));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving session list");
-               goto error;
-       }
-       assert(ret_len == sizeof(list));
-
-       sessions_count = be32toh(list.sessions_count);
-       for (i = 0; i < sessions_count; i++) {
-               ret_len = lttng_live_recv(ctx->control_sock, &lsession, sizeof(lsession));
-               if (ret_len == 0) {
-                       fprintf(stderr, "[error] Remote side has closed connection\n");
-                       goto error;
-               }
-               if (ret_len < 0) {
-                       perror("[error] Error receiving session");
-                       goto error;
-               }
-               assert(ret_len == sizeof(lsession));
-               lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0';
-               lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0';
-               session_id = be64toh(lsession.id);
-
-               if (print_list) {
-                       update_session_list(session_list,
-                                       lsession.hostname,
-                                       lsession.session_name,
-                                       be32toh(lsession.streams),
-                                       be32toh(lsession.clients),
-                                       be32toh(lsession.live_timer));
-               } else {
-                       if ((strncmp(lsession.session_name, ctx->session_name,
-                               MAXNAMLEN) == 0) && (strncmp(lsession.hostname,
-                                       ctx->traced_hostname, MAXNAMLEN) == 0)) {
-                               printf_verbose("Reading from session %" PRIu64 "\n",
-                                               session_id);
-                               g_array_append_val(ctx->session_ids,
-                                               session_id);
-                       }
-               }
-       }
-
-       if (print_list) {
-               print_session_list(session_list, path);
-               free_session_list(session_list);
-       }
-       ret = 0;
-end:
-       return ret;
-
-error:
-       fprintf(stderr, "[error] Unable to list sessions\n");
-       return -1;
-}
-
-int lttng_live_ctf_trace_assign(struct lttng_live_viewer_stream *stream,
-               uint64_t ctf_trace_id)
-{
-       struct lttng_live_ctf_trace *trace;
-       int ret = 0;
-
-       trace = g_hash_table_lookup(stream->session->ctf_traces,
-                       &ctf_trace_id);
-       if (!trace) {
-               trace = g_new0(struct lttng_live_ctf_trace, 1);
-               trace->ctf_trace_id = ctf_trace_id;
-               trace->streams = g_ptr_array_new();
-               g_hash_table_insert(stream->session->ctf_traces,
-                               &trace->ctf_trace_id,
-                               trace);
-       }
-       if (stream->metadata_flag)
-               trace->metadata_stream = stream;
-
-       stream->ctf_trace = trace;
-       g_ptr_array_add(trace->streams, stream);
-
-       return ret;
-}
-
-static
-int open_metadata_fp_write(struct lttng_live_viewer_stream *stream,
-               char **metadata_buf, size_t *size)
-{
-       int ret = 0;
-
-       stream->metadata_fp_write =
-               bt_open_memstream(metadata_buf, size);
-       if (!stream->metadata_fp_write) {
-               perror("Metadata open_memstream");
-               ret = -1;
-       }
-
-       return ret;
-}
-
-int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_attach_session_request rq;
-       struct lttng_viewer_attach_session_response rp;
-       struct lttng_viewer_stream stream;
-       int ret, i;
-       ssize_t ret_len;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_ATTACH_SESSION);
-       cmd.data_size = htobe64((uint64_t) sizeof(rq));
-       cmd.cmd_version = htobe32(0);
-
-       memset(&rq, 0, sizeof(rq));
-       rq.session_id = htobe64(id);
-       // TODO: add cmd line parameter to select seek beginning
-       // rq.seek = htobe32(LTTNG_VIEWER_SEEK_BEGINNING);
-       rq.seek = htobe32(LTTNG_VIEWER_SEEK_LAST);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &rq, sizeof(rq));
-       if (ret_len < 0) {
-               perror("[error] Error sending attach request");
-               goto error;
-       }
-       assert(ret_len == sizeof(rq));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &rp, sizeof(rp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving attach response");
-               goto error;
-       }
-       assert(ret_len == sizeof(rp));
-
-       switch(be32toh(rp.status)) {
-       case LTTNG_VIEWER_ATTACH_OK:
-               break;
-       case LTTNG_VIEWER_ATTACH_UNK:
-               ret = -LTTNG_VIEWER_ATTACH_UNK;
-               goto end;
-       case LTTNG_VIEWER_ATTACH_ALREADY:
-               fprintf(stderr, "[error] There is already a viewer attached to this session\n");
-               goto error;
-       case LTTNG_VIEWER_ATTACH_NOT_LIVE:
-               fprintf(stderr, "[error] Not a live session\n");
-               goto error;
-       case LTTNG_VIEWER_ATTACH_SEEK_ERR:
-               fprintf(stderr, "[error] Wrong seek parameter\n");
-               goto error;
-       default:
-               fprintf(stderr, "[error] Unknown attach return code %u\n",
-                               be32toh(rp.status));
-               goto error;
-       }
-       if (be32toh(rp.status) != LTTNG_VIEWER_ATTACH_OK) {
-               goto error;
-       }
-
-       ctx->session->stream_count += be32toh(rp.streams_count);
-       /*
-        * When the session is created but not started, we do an active wait
-        * until it starts. It allows the viewer to start processing the trace
-        * as soon as the session starts.
-        */
-       if (ctx->session->stream_count == 0) {
-               ret = 0;
-               goto end;
-       }
-       printf_verbose("Waiting for %" PRIu64 " streams:\n",
-               ctx->session->stream_count);
-       ctx->session->streams = g_new0(struct lttng_live_viewer_stream,
-                       ctx->session->stream_count);
-       for (i = 0; i < be32toh(rp.streams_count); i++) {
-               ret_len = lttng_live_recv(ctx->control_sock, &stream, sizeof(stream));
-               if (ret_len == 0) {
-                       fprintf(stderr, "[error] Remote side has closed connection\n");
-                       goto error;
-               }
-               if (ret_len < 0) {
-                       perror("[error] Error receiving stream");
-                       goto error;
-               }
-               assert(ret_len == sizeof(stream));
-               stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0';
-               stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0';
-
-               printf_verbose("    stream %" PRIu64 " : %s/%s\n",
-                               be64toh(stream.id), stream.path_name,
-                               stream.channel_name);
-               ctx->session->streams[i].id = be64toh(stream.id);
-               ctx->session->streams[i].session = ctx->session;
-
-               ctx->session->streams[i].mmap_size = 0;
-               ctx->session->streams[i].ctf_stream_id = -1ULL;
-
-               if (be32toh(stream.metadata_flag)) {
-                       ctx->session->streams[i].metadata_flag = 1;
-               }
-               ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i],
-                               be64toh(stream.ctf_trace_id));
-               if (ret < 0) {
-                       goto error;
-               }
-
-       }
-       ret = 0;
-end:
-       return ret;
-
-error:
-       return -1;
-}
-
-/*
- * Ask the relay for new streams.
- *
- * Returns the number of new streams received or a negative value on error.
- */
-static
-int ask_new_streams(struct lttng_live_ctx *ctx)
-{
-       int i, ret = 0, nb_streams = 0;
-       uint64_t id;
-
-restart:
-       for (i = 0; i < ctx->session_ids->len; i++) {
-               id = g_array_index(ctx->session_ids, uint64_t, i);
-               ret = lttng_live_get_new_streams(ctx, id);
-               printf_verbose("Asking for new streams returns %d\n", ret);
-               if (ret < 0) {
-                       if (lttng_live_should_quit()) {
-                               goto end;
-                       }
-                       if (ret == -LTTNG_VIEWER_NEW_STREAMS_HUP) {
-                               printf_verbose("Session %" PRIu64 " closed\n",
-                                               id);
-                               /*
-                                * The streams have already been closed during
-                                * the reading, so we only need to get rid of
-                                * the trace in our internal table of sessions.
-                                */
-                               g_array_remove_index(ctx->session_ids, i);
-                               /*
-                                * We can't continue iterating on the g_array
-                                * after a remove, we have to start again.
-                                */
-                               goto restart;
-                       } else {
-                               ret = -1;
-                               goto end;
-                       }
-               } else {
-                       nb_streams += ret;
-               }
-       }
-       ret = nb_streams;
-
-end:
-       return ret;
-}
-
-static
-int append_metadata(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *viewer_stream)
-{
-       int ret;
-       struct lttng_live_viewer_stream *metadata;
-       char *metadata_buf = NULL;
-
-       printf_verbose("get_next_index: new metadata needed\n");
-       ret = get_new_metadata(ctx, viewer_stream, &metadata_buf);
-       if (ret < 0) {
-               free(metadata_buf);
-               goto error;
-       }
-
-       metadata = viewer_stream->ctf_trace->metadata_stream;
-       metadata->ctf_trace->metadata_fp =
-               bt_fmemopen(metadata_buf,
-                               metadata->metadata_len, "rb");
-       if (!metadata->ctf_trace->metadata_fp) {
-               perror("Metadata fmemopen");
-               free(metadata_buf);
-               ret = -1;
-               goto error;
-       }
-       ret = ctf_append_trace_metadata(
-                       viewer_stream->ctf_trace->handle->td,
-                       metadata->ctf_trace->metadata_fp);
-       /* We accept empty metadata packets */
-       if (ret != 0 && ret != -ENOENT) {
-               fprintf(stderr, "[error] Appending metadata\n");
-               goto error;
-       }
-       ret = 0;
-
-error:
-       return ret;
-}
-
-static
-int get_data_packet(struct lttng_live_ctx *ctx,
-               struct ctf_stream_pos *pos,
-               struct lttng_live_viewer_stream *stream, uint64_t offset,
-               uint64_t len)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_get_packet rq;
-       struct lttng_viewer_trace_packet rp;
-       ssize_t ret_len;
-       int ret;
-
-retry:
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET);
-       cmd.data_size = htobe64((uint64_t) sizeof(rq));
-       cmd.cmd_version = htobe32(0);
-
-       memset(&rq, 0, sizeof(rq));
-       rq.stream_id = htobe64(stream->id);
-       rq.offset = htobe64(offset);
-       rq.len = htobe32(len);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &rq, sizeof(rq));
-       if (ret_len < 0) {
-               perror("[error] Error sending get_data_packet request");
-               goto error;
-       }
-       assert(ret_len == sizeof(rq));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &rp, sizeof(rp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving data response");
-               goto error;
-       }
-       if (ret_len != sizeof(rp)) {
-               fprintf(stderr, "[error] get_data_packet: expected %zu"
-                               ", received %zd\n", sizeof(rp),
-                               ret_len);
-               goto error;
-       }
-
-       rp.flags = be32toh(rp.flags);
-
-       switch (be32toh(rp.status)) {
-       case LTTNG_VIEWER_GET_PACKET_OK:
-               len = be32toh(rp.len);
-               printf_verbose("get_data_packet: Ok, packet size : %" PRIu64
-                               "\n", len);
-               break;
-       case LTTNG_VIEWER_GET_PACKET_RETRY:
-               /* Unimplemented by relay daemon */
-               printf_verbose("get_data_packet: retry\n");
-               goto error;
-       case LTTNG_VIEWER_GET_PACKET_ERR:
-               if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) {
-                       printf_verbose("get_data_packet: new metadata needed\n");
-                       ret = append_metadata(ctx, stream);
-                       if (ret)
-                               goto error;
-               }
-               if (rp.flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
-                       printf_verbose("get_data_packet: new streams needed\n");
-                       ret = ask_new_streams(ctx);
-                       if (ret < 0) {
-                               goto error;
-                       } else if (ret > 0) {
-                               ret = add_traces(ctx);
-                               if (ret < 0) {
-                                       goto error;
-                               }
-                       }
-               }
-               if (rp.flags & (LTTNG_VIEWER_FLAG_NEW_METADATA
-                               | LTTNG_VIEWER_FLAG_NEW_STREAM)) {
-                       goto retry;
-               }
-               fprintf(stderr, "[error] get_data_packet: error\n");
-               goto error;
-       case LTTNG_VIEWER_GET_PACKET_EOF:
-               ret = -2;
-               goto end;
-       default:
-               printf_verbose("get_data_packet: unknown\n");
-               goto error;
-       }
-
-       if (len == 0) {
-               goto error;
-       }
-
-       if (len > stream->mmap_size) {
-               uint64_t new_size;
-
-               new_size = max_t(uint64_t, len, stream->mmap_size << 1);
-               if (pos->base_mma) {
-                       /* unmap old base */
-                       ret = munmap_align(pos->base_mma);
-                       if (ret) {
-                               perror("[error] Unable to unmap old base");
-                               goto error;
-                       }
-                       pos->base_mma = NULL;
-               }
-               pos->base_mma = mmap_align(new_size,
-                               PROT_READ | PROT_WRITE,
-                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-               if (pos->base_mma == MAP_FAILED) {
-                       perror("[error] mmap error");
-                       pos->base_mma = NULL;
-                       goto error;
-               }
-
-               stream->mmap_size = new_size;
-               printf_verbose("Expanding stream mmap size to %" PRIu64 " bytes\n",
-                               stream->mmap_size);
-       }
-
-       ret_len = lttng_live_recv(ctx->control_sock,
-                       mmap_align_addr(pos->base_mma), len);
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving trace packet");
-               goto error;
-       }
-       assert(ret_len == len);
-       ret = 0;
-end:
-       return ret;
-
-error:
-       return -1;
-}
-
-static
-int get_one_metadata_packet(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *metadata_stream)
-{
-       uint64_t len = 0;
-       int ret;
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_get_metadata rq;
-       struct lttng_viewer_metadata_packet rp;
-       char *data = NULL;
-       ssize_t ret_len;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       rq.stream_id = htobe64(metadata_stream->id);
-       cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA);
-       cmd.data_size = htobe64((uint64_t) sizeof(rq));
-       cmd.cmd_version = htobe32(0);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &rq, sizeof(rq));
-       if (ret_len < 0) {
-               perror("[error] Error sending get_metadata request");
-               goto error;
-       }
-       assert(ret_len == sizeof(rq));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &rp, sizeof(rp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving metadata response");
-               goto error;
-       }
-       assert(ret_len == sizeof(rp));
-
-       switch (be32toh(rp.status)) {
-               case LTTNG_VIEWER_METADATA_OK:
-                       printf_verbose("get_metadata : OK\n");
-                       break;
-               case LTTNG_VIEWER_NO_NEW_METADATA:
-                       printf_verbose("get_metadata : NO NEW\n");
-                       ret = 0;
-                       goto end;
-               case LTTNG_VIEWER_METADATA_ERR:
-                       printf_verbose("get_metadata : ERR\n");
-                       goto error;
-               default:
-                       printf_verbose("get_metadata : UNKNOWN\n");
-                       goto error;
-       }
-
-       len = be64toh(rp.len);
-       printf_verbose("Writing %" PRIu64" bytes to metadata\n", len);
-       if (len <= 0) {
-               goto error;
-       }
-
-       data = zmalloc(len);
-       if (!data) {
-               perror("relay data zmalloc");
-               goto error;
-       }
-       ret_len = lttng_live_recv(ctx->control_sock, data, len);
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error_free_data;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving trace packet");
-               goto error_free_data;
-       }
-       assert(ret_len == len);
-
-       do {
-               ret_len = fwrite(data, 1, len,
-                               metadata_stream->metadata_fp_write);
-       } while (ret_len < 0 && errno == EINTR);
-       if (ret_len < 0) {
-               fprintf(stderr, "[error] Writing in the metadata fp\n");
-               goto error_free_data;
-       }
-       assert(ret_len == len);
-       metadata_stream->metadata_len += len;
-       free(data);
-       ret = len;
-end:
-       return ret;
-
-error_free_data:
-       free(data);
-error:
-       return -1;
-}
-
-/*
- * Return 0 on success, a negative value on error.
- */
-static
-int get_new_metadata(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *viewer_stream,
-               char **metadata_buf)
-{
-       int ret = 0;
-       struct lttng_live_viewer_stream *metadata_stream;
-       size_t size, len_read = 0;
-
-       metadata_stream = viewer_stream->ctf_trace->metadata_stream;
-       if (!metadata_stream) {
-               fprintf(stderr, "[error] No metadata stream\n");
-               ret = -1;
-               goto error;
-       }
-       metadata_stream->metadata_len = 0;
-       ret = open_metadata_fp_write(metadata_stream, metadata_buf, &size);
-       if (ret < 0) {
-               goto error;
-       }
-
-       do {
-               if (lttng_live_should_quit()) {
-                       ret = -1;
-                       goto error;
-               }
-               /*
-                * get_one_metadata_packet returns the number of bytes
-                * received, 0 when we have received everything, a
-                * negative value on error.
-                */
-               ret = get_one_metadata_packet(ctx, metadata_stream);
-               if (ret > 0) {
-                       len_read += ret;
-               }
-               if (!len_read) {
-                       (void) poll(NULL, 0, ACTIVE_POLL_DELAY);
-               }
-       } while (ret > 0 || !len_read);
-
-       if (bt_close_memstream(metadata_buf, &size,
-                       metadata_stream->metadata_fp_write)) {
-               perror("bt_close_memstream");
-       }
-       metadata_stream->metadata_fp_write = NULL;
-
-error:
-       return ret;
-}
-
-/*
- * Assign the fields from a lttng_viewer_index to a packet_index.
- */
-static
-void lttng_index_to_packet_index(struct lttng_viewer_index *lindex,
-               struct packet_index *pindex)
-{
-       assert(lindex);
-       assert(pindex);
-
-       pindex->offset = be64toh(lindex->offset);
-       pindex->packet_size = be64toh(lindex->packet_size);
-       pindex->content_size = be64toh(lindex->content_size);
-       pindex->ts_cycles.timestamp_begin = be64toh(lindex->timestamp_begin);
-       pindex->ts_cycles.timestamp_end = be64toh(lindex->timestamp_end);
-       pindex->events_discarded = be64toh(lindex->events_discarded);
-}
-
-/*
- * Get one index for a stream.
- *
- * Returns 0 on success or a negative value on error.
- */
-static
-int get_next_index(struct lttng_live_ctx *ctx,
-               struct lttng_live_viewer_stream *viewer_stream,
-               struct packet_index *index, uint64_t *stream_id)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_get_next_index rq;
-       int ret;
-       ssize_t ret_len;
-       struct lttng_viewer_index *rp = &viewer_stream->current_index;
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX);
-       cmd.data_size = htobe64((uint64_t) sizeof(rq));
-       cmd.cmd_version = htobe32(0);
-
-       memset(&rq, 0, sizeof(rq));
-       rq.stream_id = htobe64(viewer_stream->id);
-
-retry:
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &rq, sizeof(rq));
-       if (ret_len < 0) {
-               perror("[error] Error sending get_next_index request");
-               goto error;
-       }
-       assert(ret_len == sizeof(rq));
-
-       ret_len = lttng_live_recv(ctx->control_sock, rp, sizeof(*rp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving index response");
-               goto error;
-       }
-       assert(ret_len == sizeof(*rp));
-
-       rp->flags = be32toh(rp->flags);
-
-       switch (be32toh(rp->status)) {
-       case LTTNG_VIEWER_INDEX_INACTIVE:
-               printf_verbose("get_next_index: inactive\n");
-               memset(index, 0, sizeof(struct packet_index));
-               index->ts_cycles.timestamp_end = be64toh(rp->timestamp_end);
-               *stream_id = be64toh(rp->stream_id);
-               break;
-       case LTTNG_VIEWER_INDEX_OK:
-               printf_verbose("get_next_index: Ok, need metadata update : %u\n",
-                               rp->flags & LTTNG_VIEWER_FLAG_NEW_METADATA);
-               lttng_index_to_packet_index(rp, index);
-               *stream_id = be64toh(rp->stream_id);
-               viewer_stream->data_pending = 1;
-
-               if (rp->flags & LTTNG_VIEWER_FLAG_NEW_METADATA) {
-                       ret = append_metadata(ctx, viewer_stream);
-                       if (ret)
-                               goto error;
-               }
-               if (rp->flags & LTTNG_VIEWER_FLAG_NEW_STREAM) {
-                       printf_verbose("get_next_index: need new streams\n");
-                       ret = ask_new_streams(ctx);
-                       if (ret < 0) {
-                               goto error;
-                       } else if (ret > 0) {
-                               ret = add_traces(ctx);
-                               if (ret < 0) {
-                                       goto error;
-                               }
-                       }
-               }
-               break;
-       case LTTNG_VIEWER_INDEX_RETRY:
-               printf_verbose("get_next_index: retry\n");
-               (void) poll(NULL, 0, ACTIVE_POLL_DELAY);
-               goto retry;
-       case LTTNG_VIEWER_INDEX_HUP:
-               printf_verbose("get_next_index: stream hung up\n");
-               viewer_stream->id = -1ULL;
-               index->offset = EOF;
-               ctx->session->stream_count--;
-               break;
-       case LTTNG_VIEWER_INDEX_ERR:
-               fprintf(stderr, "[error] get_next_index: error\n");
-               goto error;
-       default:
-               fprintf(stderr, "[error] get_next_index: unkwown value\n");
-               goto error;
-       }
-       ret = 0;
-end:
-       return ret;
-
-error:
-       return -1;
-}
-
-static
-void read_packet_header(struct ctf_stream_pos *pos,
-               struct ctf_file_stream *file_stream)
-{
-       int ret;
-
-       /* update trace_packet_header and stream_packet_context */
-       if (!(pos->prot & PROT_WRITE) &&
-               file_stream->parent.trace_packet_header) {
-               /* Read packet header */
-               ret = generic_rw(&pos->parent,
-                               &file_stream->parent.trace_packet_header->p);
-               if (ret) {
-                       pos->offset = EOF;
-                       fprintf(stderr, "[error] trace packet "
-                                       "header read failed\n");
-                       goto end;
-               }
-       }
-       if (!(pos->prot & PROT_WRITE) &&
-               file_stream->parent.stream_packet_context) {
-               /* Read packet context */
-               ret = generic_rw(&pos->parent,
-                               &file_stream->parent.stream_packet_context->p);
-               if (ret) {
-                       pos->offset = EOF;
-                       fprintf(stderr, "[error] stream packet "
-                                       "context read failed\n");
-                       goto end;
-               }
-       }
-       pos->data_offset = pos->offset;
-
-end:
-       return;
-}
-
-/*
- * Handle the seek parameters.
- * Returns 0 if the packet_seek can continue, a positive value to
- * cleanly exit the packet_seek, a negative value on error.
- */
-static
-int handle_seek_position(size_t index, int whence,
-               struct lttng_live_viewer_stream *viewer_stream,
-               struct ctf_stream_pos *pos,
-               struct ctf_file_stream *file_stream)
-{
-       int ret = 0;
-
-       switch (whence) {
-       case SEEK_CUR:
-               ret = 0;
-               goto end;
-       case SEEK_SET:
-               /*
-                * We only allow to seek to 0.
-                */
-               if (index != 0) {
-                       fprintf(stderr, "[error] Arbitrary seek in lttng-live "
-                                       "trace not supported\n");
-                       pos->offset = EOF;
-                       ret = -1;
-                       goto end;
-               }
-
-               ret = 0;
-               goto end;
-
-       default:
-               fprintf(stderr, "[error] Invalid seek parameter\n");
-               assert(0);
-       }
-
-end:
-       return ret;
-}
-
-static
-void ctf_live_packet_seek(struct bt_stream_pos *stream_pos, size_t index,
-               int whence)
-{
-       struct ctf_stream_pos *pos;
-       struct ctf_file_stream *file_stream;
-       struct packet_index *prev_index = NULL, *cur_index;
-       struct lttng_live_viewer_stream *viewer_stream;
-       struct lttng_live_session *session;
-       uint64_t stream_id = -1ULL;
-       int ret;
-
-       pos = ctf_pos(stream_pos);
-       file_stream = container_of(pos, struct ctf_file_stream, pos);
-       viewer_stream = (struct lttng_live_viewer_stream *) pos->priv;
-       session = viewer_stream->session;
-
-       ret = handle_seek_position(index, whence, viewer_stream, pos,
-                       file_stream);
-       if (ret != 0) {
-               return;
-       }
-
-retry:
-       switch (pos->packet_index->len) {
-       case 0:
-               g_array_set_size(pos->packet_index, 1);
-               cur_index = &g_array_index(pos->packet_index,
-                               struct packet_index, 0);
-               break;
-       case 1:
-               g_array_set_size(pos->packet_index, 2);
-               prev_index = &g_array_index(pos->packet_index,
-                               struct packet_index, 0);
-               cur_index = &g_array_index(pos->packet_index,
-                               struct packet_index, 1);
-               break;
-       case 2:
-               g_array_index(pos->packet_index,
-                       struct packet_index, 0) =
-                               g_array_index(pos->packet_index,
-                                       struct packet_index, 1);
-               prev_index = &g_array_index(pos->packet_index,
-                               struct packet_index, 0);
-               cur_index = &g_array_index(pos->packet_index,
-                               struct packet_index, 1);
-               break;
-       default:
-               abort();
-               break;
-       }
-
-       if (viewer_stream->data_pending) {
-               lttng_index_to_packet_index(&viewer_stream->current_index, cur_index);
-       } else {
-               printf_verbose("get_next_index for stream %" PRIu64 "\n", viewer_stream->id);
-               ret = get_next_index(session->ctx, viewer_stream, cur_index, &stream_id);
-               if (ret < 0) {
-                       pos->offset = EOF;
-                       if (!lttng_live_should_quit()) {
-                               fprintf(stderr, "[error] get_next_index failed\n");
-                       }
-                       return;
-               }
-               printf_verbose("Index received : packet_size : %" PRIu64
-                               ", offset %" PRIu64 ", content_size %" PRIu64
-                               ", timestamp_end : %" PRIu64 "\n",
-                               cur_index->packet_size, cur_index->offset,
-                               cur_index->content_size,
-                               cur_index->ts_cycles.timestamp_end);
-
-       }
-
-       /*
-        * On the first time we receive an index, the stream_id needs to
-        * be set for the stream in order to use it, we don't want any
-        * data at this stage.
-        */
-       if (file_stream->parent.stream_id == -1ULL) {
-               /*
-                * Warning: with lttng-tools < 2.4.2, the beacon does not
-                * contain the real stream ID, it is memset to 0, so this
-                * might create a problem when a session has multiple
-                * channels. We can't detect it at this stage, lttng-tools
-                * has to be upgraded to fix this problem.
-                */
-               printf_verbose("Assigning stream_id %" PRIu64 "\n",
-                               stream_id);
-               file_stream->parent.stream_id = stream_id;
-               viewer_stream->ctf_stream_id = stream_id;
-
-               return;
-       }
-
-       pos->packet_size = cur_index->packet_size;
-       pos->content_size = cur_index->content_size;
-       pos->mmap_base_offset = 0;
-       if (cur_index->offset == EOF) {
-               pos->offset = EOF;
-       } else {
-               pos->offset = 0;
-       }
-
-       if (cur_index->content_size == 0) {
-               if (file_stream->parent.stream_class) {
-                       file_stream->parent.cycles_timestamp =
-                               cur_index->ts_cycles.timestamp_end;
-                       file_stream->parent.real_timestamp = ctf_get_real_timestamp(
-                                       &file_stream->parent,
-                                       cur_index->ts_cycles.timestamp_end);
-               }
-       } else {
-               if (file_stream->parent.stream_class) {
-                       /* Convert the timestamps and append to the real_index. */
-                       cur_index->ts_real.timestamp_begin = ctf_get_real_timestamp(
-                                       &file_stream->parent,
-                                       cur_index->ts_cycles.timestamp_begin);
-                       cur_index->ts_real.timestamp_end = ctf_get_real_timestamp(
-                                       &file_stream->parent,
-                                       cur_index->ts_cycles.timestamp_end);
-               }
-
-               ctf_update_current_packet_index(&file_stream->parent,
-                               prev_index, cur_index);
-
-               file_stream->parent.cycles_timestamp =
-                               cur_index->ts_cycles.timestamp_begin;
-               file_stream->parent.real_timestamp =
-                               cur_index->ts_real.timestamp_begin;
-       }
-
-       /*
-        * Flush the output between attempts to grab a packet, thus
-        * ensuring we flush at least at the periodical timer period.
-        * This ensures the output remains reactive for interactive users and
-        * that the output is flushed when redirected to a file by the shell.
-        */
-       if (fflush(LTTNG_LIVE_OUTPUT_FP) < 0) {
-               perror("fflush");
-               goto end;
-       }
-
-       if (pos->packet_size == 0 || pos->offset == EOF) {
-               goto end;
-       }
-
-       printf_verbose("get_data_packet for stream %" PRIu64 "\n",
-                       viewer_stream->id);
-       ret = get_data_packet(session->ctx, pos, viewer_stream,
-                       cur_index->offset,
-                       cur_index->packet_size / CHAR_BIT);
-       if (ret == -2) {
-               goto retry;
-       } else if (ret < 0) {
-               pos->offset = EOF;
-               if (!lttng_live_should_quit()) {
-                       fprintf(stderr, "[error] get_data_packet failed\n");
-               }
-               return;
-       }
-       viewer_stream->data_pending = 0;
-
-       read_packet_header(pos, file_stream);
-
-end:
-       return;
-}
-
-int lttng_live_create_viewer_session(struct lttng_live_ctx *ctx)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_create_session_response resp;
-       int ret;
-       ssize_t ret_len;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_CREATE_SESSION);
-       cmd.data_size = htobe64((uint64_t) 0);
-       cmd.cmd_version = htobe32(0);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &resp, sizeof(resp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving create session reply");
-               goto error;
-       }
-       assert(ret_len == sizeof(resp));
-
-       if (be32toh(resp.status) != LTTNG_VIEWER_CREATE_SESSION_OK) {
-               fprintf(stderr, "[error] Error creating viewer session\n");
-               goto error;
-       }
-       ret = 0;
-end:
-       return ret;
-
-error:
-       return -1;
-}
-
-static
-int del_traces(gpointer key, gpointer value, gpointer user_data)
-{
-       struct bt_context *bt_ctx = user_data;
-       struct lttng_live_ctf_trace *trace = value;
-       int ret;
-
-       ret = bt_context_remove_trace(bt_ctx, trace->trace_id);
-       if (ret < 0)
-               fprintf(stderr, "[error] removing trace from context\n");
-
-       /* remove the key/value pair from the HT. */
-       return 1;
-}
-
-static
-int add_one_trace(struct lttng_live_ctx *ctx,
-               struct lttng_live_ctf_trace *trace)
-{
-       int i, ret;
-       struct bt_context *bt_ctx = ctx->bt_ctx;
-       struct lttng_live_viewer_stream *stream;
-       struct bt_mmap_stream *new_mmap_stream;
-       struct bt_mmap_stream_list mmap_list;
-       struct bt_trace_descriptor *td;
-       struct bt_trace_handle *handle;
-
-       /*
-        * We don't know how many streams we will receive for a trace, so
-        * once we are done receiving the traces, we add all the traces
-        * received to the bt_context.
-        * We can receive streams during the attach command or the
-        * get_new_streams, so we have to make sure not to add multiple
-        * times the same traces.
-        * If a trace is already in the context, we just skip this function.
-        */
-       if (trace->in_use) {
-               ret = 0;
-               goto end;
-       }
-
-       BT_INIT_LIST_HEAD(&mmap_list.head);
-
-       for (i = 0; i < trace->streams->len; i++) {
-               stream = g_ptr_array_index(trace->streams, i);
-
-               if (!stream->metadata_flag) {
-                       new_mmap_stream = zmalloc(sizeof(struct bt_mmap_stream));
-                       new_mmap_stream->priv = (void *) stream;
-                       new_mmap_stream->fd = -1;
-                       bt_list_add(&new_mmap_stream->list, &mmap_list.head);
-               } else {
-                       char *metadata_buf = NULL;
-
-                       /* Get all possible metadata before starting */
-                       ret = get_new_metadata(ctx, stream, &metadata_buf);
-                       if (ret) {
-                               free(metadata_buf);
-                               goto end_free;
-                       }
-                       if (!stream->metadata_len) {
-                               fprintf(stderr, "[error] empty metadata\n");
-                               ret = -1;
-                               free(metadata_buf);
-                               goto end_free;
-                       }
-
-                       trace->metadata_fp = bt_fmemopen(metadata_buf,
-                                       stream->metadata_len, "rb");
-                       if (!trace->metadata_fp) {
-                               perror("Metadata fmemopen");
-                               ret = -1;
-                               free(metadata_buf);
-                               goto end_free;
-                       }
-               }
-       }
-
-       if (!trace->metadata_fp) {
-               fprintf(stderr, "[error] No metadata stream opened\n");
-               ret = -1;
-               goto end_free;
-       }
-
-       ret = bt_context_add_trace(bt_ctx, NULL, "ctf",
-                       ctf_live_packet_seek, &mmap_list, trace->metadata_fp);
-       if (ret < 0) {
-               fprintf(stderr, "[error] Error adding trace\n");
-               ret = -1;
-               goto end_free;
-       }
-       trace->metadata_stream->metadata_len = 0;
-
-       handle = (struct bt_trace_handle *) g_hash_table_lookup(
-                       bt_ctx->trace_handles,
-                       (gpointer) (unsigned long) ret);
-       td = handle->td;
-       trace->handle = handle;
-       if (bt_ctx->current_iterator) {
-               bt_iter_add_trace(bt_ctx->current_iterator, td);
-       }
-
-       trace->trace_id = ret;
-       trace->in_use = 1;
-
-       goto end;
-
-end_free:
-       bt_context_put(bt_ctx);
-end:
-       return ret;
-}
-
-static
-int add_traces(struct lttng_live_ctx *ctx)
-{
-       int ret;
-       struct lttng_live_ctf_trace *trace;
-       GHashTableIter it;
-       gpointer key;
-       gpointer value;
-
-       g_hash_table_iter_init(&it, ctx->session->ctf_traces);
-       while (g_hash_table_iter_next(&it, &key, &value)) {
-               trace = (struct lttng_live_ctf_trace *) value;
-               ret = add_one_trace(ctx, trace);
-               if (ret < 0) {
-                       goto end;
-               }
-       }
-
-       ret = 0;
-
-end:
-       return ret;
-}
-
-/*
- * Request new streams for a session.
- * Returns the number of streams received or a negative value on error.
- */
-int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id)
-{
-       struct lttng_viewer_cmd cmd;
-       struct lttng_viewer_new_streams_request rq;
-       struct lttng_viewer_new_streams_response rp;
-       struct lttng_viewer_stream stream;
-       int ret, i, nb_streams = 0;
-       ssize_t ret_len;
-       uint32_t stream_count;
-
-       if (lttng_live_should_quit()) {
-               ret = -1;
-               goto end;
-       }
-
-       cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEW_STREAMS);
-       cmd.data_size = htobe64((uint64_t) sizeof(rq));
-       cmd.cmd_version = htobe32(0);
-
-       memset(&rq, 0, sizeof(rq));
-       rq.session_id = htobe64(id);
-
-       ret_len = lttng_live_send(ctx->control_sock, &cmd, sizeof(cmd));
-       if (ret_len < 0) {
-               perror("[error] Error sending cmd");
-               goto error;
-       }
-       assert(ret_len == sizeof(cmd));
-
-       ret_len = lttng_live_send(ctx->control_sock, &rq, sizeof(rq));
-       if (ret_len < 0) {
-               perror("[error] Error sending get_new_streams request");
-               goto error;
-       }
-       assert(ret_len == sizeof(rq));
-
-       ret_len = lttng_live_recv(ctx->control_sock, &rp, sizeof(rp));
-       if (ret_len == 0) {
-               fprintf(stderr, "[error] Remote side has closed connection\n");
-               goto error;
-       }
-       if (ret_len < 0) {
-               perror("[error] Error receiving get_new_streams response");
-               goto error;
-       }
-       assert(ret_len == sizeof(rp));
-
-       switch(be32toh(rp.status)) {
-       case LTTNG_VIEWER_NEW_STREAMS_OK:
-               break;
-       case LTTNG_VIEWER_NEW_STREAMS_NO_NEW:
-               ret = 0;
-               goto end;
-       case LTTNG_VIEWER_NEW_STREAMS_HUP:
-               ret = -LTTNG_VIEWER_NEW_STREAMS_HUP;
-               goto end;
-       case LTTNG_VIEWER_NEW_STREAMS_ERR:
-               fprintf(stderr, "[error] get_new_streams error\n");
-               goto error;
-       default:
-               fprintf(stderr, "[error] Unknown return code %u\n",
-                               be32toh(rp.status));
-               goto error;
-       }
-
-       stream_count = be32toh(rp.streams_count);
-       ctx->session->stream_count += stream_count;
-       /*
-        * When the session is created but not started, we do an active wait
-        * until it starts. It allows the viewer to start processing the trace
-        * as soon as the session starts.
-        */
-       if (ctx->session->stream_count == 0) {
-               ret = 0;
-               goto end;
-       }
-       printf_verbose("Waiting for %" PRIu64 " streams:\n",
-               ctx->session->stream_count);
-       ctx->session->streams = g_new0(struct lttng_live_viewer_stream,
-                       ctx->session->stream_count);
-       for (i = 0; i < stream_count; i++) {
-               ret_len = lttng_live_recv(ctx->control_sock, &stream, sizeof(stream));
-               if (ret_len == 0) {
-                       fprintf(stderr, "[error] Remote side has closed connection\n");
-                       goto error;
-               }
-               if (ret_len < 0) {
-                       perror("[error] Error receiving stream");
-                       goto error;
-               }
-               assert(ret_len == sizeof(stream));
-               stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0';
-               stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0';
-
-               printf_verbose("    stream %" PRIu64 " : %s/%s\n",
-                               be64toh(stream.id), stream.path_name,
-                               stream.channel_name);
-               ctx->session->streams[i].id = be64toh(stream.id);
-               ctx->session->streams[i].session = ctx->session;
-
-               ctx->session->streams[i].mmap_size = 0;
-               ctx->session->streams[i].ctf_stream_id = -1ULL;
-
-               if (be32toh(stream.metadata_flag)) {
-                       ctx->session->streams[i].metadata_flag = 1;
-               }
-               ret = lttng_live_ctf_trace_assign(&ctx->session->streams[i],
-                               be64toh(stream.ctf_trace_id));
-               if (ret < 0) {
-                       goto error;
-               }
-               nb_streams++;
-
-       }
-       ret = nb_streams;
-end:
-       return ret;
-
-error:
-       return -1;
-}
-
-int lttng_live_read(struct lttng_live_ctx *ctx)
-{
-       int ret = -1;
-       int i;
-       struct bt_ctf_iter *iter;
-       const struct bt_ctf_event *event;
-       struct bt_iter_pos begin_pos;
-       struct bt_trace_descriptor *td_write;
-       struct bt_format *fmt_write;
-       struct ctf_text_stream_pos *sout;
-       uint64_t id;
-
-       ctx->bt_ctx = bt_context_create();
-       if (!ctx->bt_ctx) {
-               fprintf(stderr, "[error] bt_context_create allocation\n");
-               goto end;
-       }
-
-       fmt_write = bt_lookup_format(g_quark_from_string("text"));
-       if (!fmt_write) {
-               fprintf(stderr, "[error] ctf-text error\n");
-               goto end;
-       }
-
-       td_write = fmt_write->open_trace(NULL, O_RDWR, NULL, NULL);
-       if (!td_write) {
-               fprintf(stderr, "[error] Error opening output trace\n");
-               goto end_free;
-       }
-
-       sout = container_of(td_write, struct ctf_text_stream_pos,
-                       trace_descriptor);
-       if (!sout->parent.event_cb) {
-               goto end_free;
-       }
-
-       ret = lttng_live_create_viewer_session(ctx);
-       if (ret < 0) {
-               goto end_free;
-       }
-
-       for (i = 0; i < ctx->session_ids->len; i++) {
-               id = g_array_index(ctx->session_ids, uint64_t, i);
-               printf_verbose("Attaching to session %" PRIu64 "\n", id);
-               ret = lttng_live_attach_session(ctx, id);
-               printf_verbose("Attaching session returns %d\n", ret);
-               if (ret < 0) {
-                       if (ret == -LTTNG_VIEWER_ATTACH_UNK) {
-                               fprintf(stderr, "[error] Unknown session ID\n");
-                       }
-                       goto end_free;
-               }
-       }
-
-       /*
-        * As long as the session is active, we try to get new streams.
-        */
-       for (;;) {
-               int flags;
-
-               if (lttng_live_should_quit()) {
-                       ret = 0;
-                       goto end_free;
-               }
-
-               while (!ctx->session->stream_count) {
-                       if (lttng_live_should_quit()
-                                       || ctx->session_ids->len == 0) {
-                               ret = 0;
-                               goto end_free;
-                       }
-                       ret = ask_new_streams(ctx);
-                       if (ret < 0) {
-                               goto end_free;
-                       }
-                       if (!ctx->session->stream_count) {
-                               (void) poll(NULL, 0, ACTIVE_POLL_DELAY);
-                       }
-               }
-
-               ret = add_traces(ctx);
-               if (ret < 0) {
-                       goto end_free;
-               }
-
-               begin_pos.type = BT_SEEK_BEGIN;
-               iter = bt_ctf_iter_create(ctx->bt_ctx, &begin_pos, NULL);
-               if (!iter) {
-                       if (lttng_live_should_quit()) {
-                               ret = 0;
-                               goto end;
-                       }
-                       fprintf(stderr, "[error] Iterator creation error\n");
-                       goto end;
-               }
-               for (;;) {
-                       if (lttng_live_should_quit()) {
-                               ret = 0;
-                               goto end_free;
-                       }
-                       event = bt_ctf_iter_read_event_flags(iter, &flags);
-                       if (!(flags & BT_ITER_FLAG_RETRY)) {
-                               if (!event) {
-                                       /* End of trace */
-                                       break;
-                               }
-                               ret = sout->parent.event_cb(&sout->parent,
-                                               event->parent->stream);
-                               if (ret) {
-                                       fprintf(stderr, "[error] Writing "
-                                                       "event failed.\n");
-                                       goto end_free;
-                               }
-                       }
-                       ret = bt_iter_next(bt_ctf_get_iter(iter));
-                       if (ret < 0) {
-                               goto end_free;
-                       }
-               }
-               bt_ctf_iter_destroy(iter);
-               g_hash_table_foreach_remove(ctx->session->ctf_traces,
-                               del_traces, ctx->bt_ctx);
-               ctx->session->stream_count = 0;
-       }
-
-end_free:
-       bt_context_put(ctx->bt_ctx);
-end:
-       if (lttng_live_should_quit()) {
-               ret = 0;
-       }
-       return ret;
-}
diff --git a/formats/lttng-live/lttng-live-plugin.c b/formats/lttng-live/lttng-live-plugin.c
deleted file mode 100644 (file)
index f2c7536..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * BabelTrace - LTTng live Output
- *
- * Copyright 2013 Julien Desfossez <jdesfossez@efficios.com>
- *                Mathieu Desnoyers <mathieu.desnoyers@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-text/types.h>
-#include <babeltrace/format.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include "lttng-live.h"
-
-static volatile int should_quit;
-
-void bt_lttng_live_hook(void)
-{
-       /*
-        * Dummy function to prevent the linker from discarding this format as
-        * "unused" in static builds.
-        */
-}
-
-int lttng_live_should_quit(void)
-{
-       return should_quit;
-}
-
-static
-void sighandler(int sig)
-{
-       switch (sig) {
-       case SIGTERM:
-       case SIGINT:
-               should_quit = 1;
-               break;
-       default:
-               break;
-       }
-}
-
-/*
- * TODO: Eventually, this signal handler setup should be done at the
- * plugin manager level, rather than within this plugin. Beware, we are
- * not cleaning up the signal handler after plugin execution.
- */
-static
-int setup_sighandler(void)
-{
-       struct sigaction sa;
-       sigset_t sigset;
-       int ret;
-
-       if ((ret = sigemptyset(&sigset)) < 0) {
-               perror("sigemptyset");
-               return ret;
-       }
-       sa.sa_handler = sighandler;
-       sa.sa_mask = sigset;
-       sa.sa_flags = 0;
-       if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
-               perror("sigaction");
-               return ret;
-       }
-       if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
-               perror("sigaction");
-               return ret;
-       }
-       return 0;
-}
-
-/*
- * hostname parameter needs to hold MAXNAMLEN chars.
- */
-static
-int parse_url(const char *path, struct lttng_live_ctx *ctx)
-{
-       char remain[3][MAXNAMLEN];
-       int ret = -1, proto, proto_offset = 0;
-       size_t path_len = strlen(path); /* not accounting \0 */
-
-       /*
-        * Since sscanf API does not allow easily checking string length
-        * against a size defined by a macro. Test it beforehand on the
-        * input. We know the output is always <= than the input length.
-        */
-       if (path_len >= MAXNAMLEN) {
-               goto end;
-       }
-       ret = sscanf(path, "net%d://", &proto);
-       if (ret < 1) {
-               proto = 4;
-               /* net:// */
-               proto_offset = strlen("net://");
-       } else {
-               /* net4:// or net6:// */
-               proto_offset = strlen("netX://");
-       }
-       if (proto_offset > path_len) {
-               goto end;
-       }
-       if (proto == 6) {
-               fprintf(stderr, "[error] IPv6 is currently unsupported by lttng-live\n");
-               goto end;
-       }
-       /* TODO : parse for IPv6 as well */
-       /* Parse the hostname or IP */
-       ret = sscanf(&path[proto_offset], "%[a-zA-Z.0-9%-]%s",
-               ctx->relay_hostname, remain[0]);
-       if (ret == 2) {
-               /* Optional port number */
-               switch (remain[0][0]) {
-               case ':':
-                       ret = sscanf(remain[0], ":%d%s", &ctx->port, remain[1]);
-                       /* Optional session ID with port number */
-                       if (ret == 2) {
-                               ret = sscanf(remain[1], "/%s", remain[2]);
-                               /* Accept 0 or 1 (optional) */
-                               if (ret < 0) {
-                                       goto end;
-                               }
-                       } else if (ret == 0) {
-                               fprintf(stderr, "[error] Missing port number after delimitor ':'\n");
-                               ret = -1;
-                               goto end;
-                       }
-                       break;
-               case '/':
-                       /* Optional session ID */
-                       ret = sscanf(remain[0], "/%s", remain[2]);
-                       /* Accept 0 or 1 (optional) */
-                       if (ret < 0) {
-                               goto end;
-                       }
-                       break;
-               default:
-                       fprintf(stderr, "[error] wrong delimitor : %c\n",
-                               remain[0][0]);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       if (ctx->port < 0) {
-               ctx->port = LTTNG_DEFAULT_NETWORK_VIEWER_PORT;
-       }
-
-       if (strlen(remain[2]) == 0) {
-               printf_verbose("Connecting to hostname : %s, port : %d, "
-                               "proto : IPv%d\n",
-                               ctx->relay_hostname, ctx->port, proto);
-               ret = 0;
-               goto end;
-       }
-       ret = sscanf(remain[2], "host/%[a-zA-Z.0-9%-]/%s",
-                       ctx->traced_hostname, ctx->session_name);
-       if (ret != 2) {
-               fprintf(stderr, "[error] Format : "
-                       "net://<hostname>/host/<traced_hostname>/<session_name>\n");
-               goto end;
-       }
-
-       printf_verbose("Connecting to hostname : %s, port : %d, "
-                       "traced hostname : %s, session name : %s, "
-                       "proto : IPv%d\n",
-                       ctx->relay_hostname, ctx->port, ctx->traced_hostname,
-                       ctx->session_name, proto);
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static
-guint g_uint64p_hash(gconstpointer key)
-{
-       uint64_t v = *(uint64_t *) key;
-
-       if (sizeof(gconstpointer) == sizeof(uint64_t)) {
-               return g_direct_hash((gconstpointer) (unsigned long) v);
-       } else {
-               return g_direct_hash((gconstpointer) (unsigned long) (v >> 32))
-                       ^ g_direct_hash((gconstpointer) (unsigned long) v);
-       }
-}
-
-static
-gboolean g_uint64p_equal(gconstpointer a, gconstpointer b)
-{
-       uint64_t va = *(uint64_t *) a;
-       uint64_t vb = *(uint64_t *) b;
-
-       if (va != vb)
-               return FALSE;
-       return TRUE;
-}
-
-static int lttng_live_open_trace_read(const char *path)
-{
-       int ret = 0;
-       struct lttng_live_ctx *ctx;
-
-       ctx = g_new0(struct lttng_live_ctx, 1);
-       ctx->session = g_new0(struct lttng_live_session, 1);
-
-       /* We need a pointer to the context from the packet_seek function. */
-       ctx->session->ctx = ctx;
-
-       /* HT to store the CTF traces. */
-       ctx->session->ctf_traces = g_hash_table_new(g_uint64p_hash,
-                       g_uint64p_equal);
-       ctx->port = -1;
-       ctx->session_ids = g_array_new(FALSE, TRUE, sizeof(uint64_t));
-
-       ret = parse_url(path, ctx);
-       if (ret < 0) {
-               goto end_free;
-       }
-       ret = setup_sighandler();
-       if (ret < 0) {
-               goto end_free;
-       }
-       ret = lttng_live_connect_viewer(ctx);
-       if (ret < 0) {
-               goto end_free;
-       }
-       printf_verbose("LTTng-live connected to relayd\n");
-
-       ret = lttng_live_establish_connection(ctx);
-       if (ret < 0) {
-               goto end_free;
-       }
-
-       printf_verbose("Listing sessions\n");
-       ret = lttng_live_list_sessions(ctx, path);
-       if (ret < 0) {
-               goto end_free;
-       }
-
-       if (ctx->session_ids->len > 0) {
-               ret = lttng_live_read(ctx);
-       }
-
-end_free:
-       g_hash_table_destroy(ctx->session->ctf_traces);
-       g_free(ctx->session);
-       g_free(ctx->session->streams);
-       g_free(ctx);
-
-       if (lttng_live_should_quit()) {
-               ret = 0;
-       }
-       return ret;
-}
-
-static
-struct bt_trace_descriptor *lttng_live_open_trace(const char *path, int flags,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence), FILE *metadata_fp)
-{
-       struct ctf_text_stream_pos *pos;
-
-       switch (flags & O_ACCMODE) {
-       case O_RDONLY:
-               /* OK */
-               break;
-       case O_RDWR:
-               fprintf(stderr, "[error] lttng live plugin cannot be used as output plugin.\n");
-               goto error;
-       default:
-               fprintf(stderr, "[error] Incorrect open flags.\n");
-               goto error;
-       }
-
-       pos = g_new0(struct ctf_text_stream_pos, 1);
-       pos->parent.rw_table = NULL;
-       pos->parent.event_cb = NULL;
-       pos->parent.trace = &pos->trace_descriptor;
-       /*
-        * Since we do *everything* in this function, we are skipping
-        * the output plugin handling that is part of Babeltrace 1.x.
-        * Therefore, don't expect the --output cmd line option to work.
-        * This limits the output of lttng-live to stderr and stdout.
-        */
-       if (lttng_live_open_trace_read(path) < 0) {
-               goto error;
-       }
-       return &pos->trace_descriptor;
-
-error:
-       return NULL;
-}
-
-static
-int lttng_live_close_trace(struct bt_trace_descriptor *td)
-{
-       struct ctf_text_stream_pos *pos =
-               container_of(td, struct ctf_text_stream_pos,
-                       trace_descriptor);
-       g_free(pos);
-       return 0;
-}
-
-static
-struct bt_format lttng_live_format = {
-       .open_trace = lttng_live_open_trace,
-       .close_trace = lttng_live_close_trace,
-};
-
-static
-void __attribute__((constructor)) lttng_live_init(void)
-{
-       int ret;
-
-       lttng_live_format.name = g_quark_from_string("lttng-live");
-       ret = bt_register_format(&lttng_live_format);
-       assert(!ret);
-}
-
-static
-void __attribute__((destructor)) lttng_live_exit(void)
-{
-       bt_unregister_format(&lttng_live_format);
-}
diff --git a/formats/lttng-live/lttng-live.h b/formats/lttng-live/lttng-live.h
deleted file mode 100644 (file)
index b315458..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef _LTTNG_LIVE_H
-#define _LTTNG_LIVE_H
-
-/*
- * Copyright 2013 Julien Desfossez <julien.desfossez@efficios.com>
- *                Mathieu Desnoyers <mathieu.desnoyers@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 <sys/param.h>
-#include "lttng-viewer-abi.h"
-
-#define LTTNG_DEFAULT_NETWORK_VIEWER_PORT      5344
-
-#define LTTNG_LIVE_MAJOR                       2
-#define LTTNG_LIVE_MINOR                       4
-
-/*
- * The lttng-live output file pointer is currently hardcoded to stdout,
- * and is expected to be hardcoded to this by fflush() performed between
- * each packet.
- */
-#define LTTNG_LIVE_OUTPUT_FP                   stdout
-
-struct lttng_live_ctx {
-       char traced_hostname[MAXNAMLEN];
-       char session_name[MAXNAMLEN];
-       char relay_hostname[MAXNAMLEN];
-       int control_sock;
-       int port;
-       /* Protocol version to use for this connection. */
-       uint32_t major;
-       uint32_t minor;
-       struct lttng_live_session *session;
-       struct bt_context *bt_ctx;
-       GArray *session_ids;
-};
-
-struct lttng_live_viewer_stream {
-       uint64_t id;
-       uint64_t mmap_size;
-       uint64_t ctf_stream_id;
-       FILE *metadata_fp_write;
-       ssize_t metadata_len;
-       int metadata_flag;
-       int data_pending;
-       struct lttng_live_session *session;
-       struct lttng_live_ctf_trace *ctf_trace;
-       struct lttng_viewer_index current_index;
-       char path[PATH_MAX];
-};
-
-struct lttng_live_session {
-       uint64_t live_timer_interval;
-       uint64_t stream_count;
-       struct lttng_live_ctx *ctx;
-       struct lttng_live_viewer_stream *streams;
-       /* HashTable mapping trace_ids to ptrs to struct lttng_live_ctf_trace */
-       GHashTable *ctf_traces;
-};
-
-struct lttng_live_ctf_trace {
-       uint64_t ctf_trace_id;
-       struct lttng_live_viewer_stream *metadata_stream;
-       GPtrArray *streams;
-       FILE *metadata_fp;
-       struct bt_trace_handle *handle;
-       int trace_id;
-       int in_use;
-};
-
-/* Just used in listing. */
-struct lttng_live_relay_session {
-       uint32_t streams;
-       uint32_t clients;
-       uint32_t timer;
-       char *name;
-       char *hostname;
-};
-
-int lttng_live_connect_viewer(struct lttng_live_ctx *ctx);
-int lttng_live_establish_connection(struct lttng_live_ctx *ctx);
-int lttng_live_list_sessions(struct lttng_live_ctx *ctx, const char *path);
-int lttng_live_attach_session(struct lttng_live_ctx *ctx, uint64_t id);
-int lttng_live_read(struct lttng_live_ctx *ctx);
-int lttng_live_get_new_streams(struct lttng_live_ctx *ctx, uint64_t id);
-int lttng_live_should_quit(void);
-
-#endif /* _LTTNG_LIVE_H */
diff --git a/formats/lttng-live/lttng-viewer-abi.h b/formats/lttng-live/lttng-viewer-abi.h
deleted file mode 100644 (file)
index d254bf9..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-#ifndef LTTNG_VIEWER_ABI_H
-#define LTTNG_VIEWER_ABI_H
-
-/*
- * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
- *                      Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *                      David Goulet <dgoulet@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/compat/limits.h>
-
-#define LTTNG_VIEWER_PATH_MAX          4096
-#define LTTNG_VIEWER_NAME_MAX          255
-#define LTTNG_VIEWER_HOST_NAME_MAX     64
-
-/* Flags in reply to get_next_index and get_packet. */
-enum {
-       /* New metadata is required to read this packet. */
-       LTTNG_VIEWER_FLAG_NEW_METADATA  = (1 << 0),
-       /* New stream got added to the trace. */
-       LTTNG_VIEWER_FLAG_NEW_STREAM    = (1 << 1),
-};
-
-enum lttng_viewer_command {
-       LTTNG_VIEWER_CONNECT            = 1,
-       LTTNG_VIEWER_LIST_SESSIONS      = 2,
-       LTTNG_VIEWER_ATTACH_SESSION     = 3,
-       LTTNG_VIEWER_GET_NEXT_INDEX     = 4,
-       LTTNG_VIEWER_GET_PACKET         = 5,
-       LTTNG_VIEWER_GET_METADATA       = 6,
-       LTTNG_VIEWER_GET_NEW_STREAMS    = 7,
-       LTTNG_VIEWER_CREATE_SESSION     = 8,
-};
-
-enum lttng_viewer_attach_return_code {
-       LTTNG_VIEWER_ATTACH_OK          = 1, /* The attach command succeeded. */
-       LTTNG_VIEWER_ATTACH_ALREADY     = 2, /* A viewer is already attached. */
-       LTTNG_VIEWER_ATTACH_UNK         = 3, /* The session ID is unknown. */
-       LTTNG_VIEWER_ATTACH_NOT_LIVE    = 4, /* The session is not live. */
-       LTTNG_VIEWER_ATTACH_SEEK_ERR    = 5, /* Seek error. */
-       LTTNG_VIEWER_ATTACH_NO_SESSION  = 6, /* No viewer session created. */
-};
-
-enum lttng_viewer_next_index_return_code {
-       LTTNG_VIEWER_INDEX_OK           = 1, /* Index is available. */
-       LTTNG_VIEWER_INDEX_RETRY        = 2, /* Index not yet available. */
-       LTTNG_VIEWER_INDEX_HUP          = 3, /* Index closed (trace destroyed). */
-       LTTNG_VIEWER_INDEX_ERR          = 4, /* Unknow error. */
-       LTTNG_VIEWER_INDEX_INACTIVE     = 5, /* Inactive stream beacon. */
-       LTTNG_VIEWER_INDEX_EOF          = 6, /* End of index file. */
-};
-
-enum lttng_viewer_get_packet_return_code {
-       LTTNG_VIEWER_GET_PACKET_OK      = 1,
-       LTTNG_VIEWER_GET_PACKET_RETRY   = 2,
-       LTTNG_VIEWER_GET_PACKET_ERR     = 3,
-       LTTNG_VIEWER_GET_PACKET_EOF     = 4,
-};
-
-enum lttng_viewer_get_metadata_return_code {
-       LTTNG_VIEWER_METADATA_OK        = 1,
-       LTTNG_VIEWER_NO_NEW_METADATA    = 2,
-       LTTNG_VIEWER_METADATA_ERR       = 3,
-};
-
-enum lttng_viewer_connection_type {
-       LTTNG_VIEWER_CLIENT_COMMAND             = 1,
-       LTTNG_VIEWER_CLIENT_NOTIFICATION        = 2,
-};
-
-enum lttng_viewer_seek {
-       /* Receive the trace packets from the beginning. */
-       LTTNG_VIEWER_SEEK_BEGINNING     = 1,
-       /* Receive the trace packets from now. */
-       LTTNG_VIEWER_SEEK_LAST          = 2,
-};
-
-enum lttng_viewer_new_streams_return_code {
-       LTTNG_VIEWER_NEW_STREAMS_OK           = 1, /* If new streams are being sent. */
-       LTTNG_VIEWER_NEW_STREAMS_NO_NEW       = 2, /* If no new streams are available. */
-       LTTNG_VIEWER_NEW_STREAMS_ERR          = 3, /* Error. */
-       LTTNG_VIEWER_NEW_STREAMS_HUP          = 4, /* Session closed. */
-};
-
-enum lttng_viewer_create_session_return_code {
-       LTTNG_VIEWER_CREATE_SESSION_OK          = 1,
-       LTTNG_VIEWER_CREATE_SESSION_ERR         = 2,
-};
-
-struct lttng_viewer_session {
-       uint64_t id;
-       uint32_t live_timer;
-       uint32_t clients;
-       uint32_t streams;
-       char hostname[LTTNG_VIEWER_HOST_NAME_MAX];
-       char session_name[LTTNG_VIEWER_NAME_MAX];
-} __attribute__((__packed__));
-
-struct lttng_viewer_stream {
-       uint64_t id;
-       uint64_t ctf_trace_id;
-       uint32_t metadata_flag;
-       char path_name[LTTNG_VIEWER_PATH_MAX];
-       char channel_name[LTTNG_VIEWER_NAME_MAX];
-} __attribute__((__packed__));
-
-struct lttng_viewer_cmd {
-       uint64_t data_size;     /* data size following this header */
-       uint32_t cmd;           /* enum lttcomm_relayd_command */
-       uint32_t cmd_version;   /* command version */
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_CONNECT payload.
- */
-struct lttng_viewer_connect {
-       /* session ID assigned by the relay for command connections */
-       uint64_t viewer_session_id;
-       uint32_t major;
-       uint32_t minor;
-       uint32_t type;          /* enum lttng_viewer_connection_type */
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_LIST_SESSIONS payload.
- */
-struct lttng_viewer_list_sessions {
-       uint32_t sessions_count;
-       char session_list[];    /* struct lttng_viewer_session */
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_ATTACH_SESSION payload.
- */
-struct lttng_viewer_attach_session_request {
-       uint64_t session_id;
-       uint64_t offset;        /* unused for now */
-       uint32_t seek;          /* enum lttng_viewer_seek */
-} __attribute__((__packed__));
-
-struct lttng_viewer_attach_session_response {
-       /* enum lttng_viewer_attach_return_code */
-       uint32_t status;
-       uint32_t streams_count;
-       /* struct lttng_viewer_stream */
-       char stream_list[];
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_GET_NEXT_INDEX payload.
- */
-struct lttng_viewer_get_next_index {
-       uint64_t stream_id;
-} __attribute__ ((__packed__));
-
-struct lttng_viewer_index {
-       uint64_t offset;
-       uint64_t packet_size;
-       uint64_t content_size;
-       uint64_t timestamp_begin;
-       uint64_t timestamp_end;
-       uint64_t events_discarded;
-       uint64_t stream_id;
-       uint32_t status;        /* enum lttng_viewer_next_index_return_code */
-       uint32_t flags;         /* LTTNG_VIEWER_FLAG_* */
-} __attribute__ ((__packed__));
-
-/*
- * LTTNG_VIEWER_GET_PACKET payload.
- */
-struct lttng_viewer_get_packet {
-       uint64_t stream_id;
-       uint64_t offset;
-       uint32_t len;
-} __attribute__((__packed__));
-
-struct lttng_viewer_trace_packet {
-       uint32_t status;        /* enum lttng_viewer_get_packet_return_code */
-       uint32_t len;
-       uint32_t flags;         /* LTTNG_VIEWER_FLAG_* */
-       char data[];
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_GET_METADATA payload.
- */
-struct lttng_viewer_get_metadata {
-       uint64_t stream_id;
-} __attribute__((__packed__));
-
-struct lttng_viewer_metadata_packet {
-       uint64_t len;
-       uint32_t status;        /* enum lttng_viewer_get_metadata_return_code */
-       char data[];
-} __attribute__((__packed__));
-
-/*
- * LTTNG_VIEWER_GET_NEW_STREAMS payload.
- */
-struct lttng_viewer_new_streams_request {
-       uint64_t session_id;
-} __attribute__((__packed__));
-
-struct lttng_viewer_new_streams_response {
-       /* enum lttng_viewer_new_streams_return_code */
-       uint32_t status;
-       uint32_t streams_count;
-       /* struct lttng_viewer_stream */
-       char stream_list[];
-} __attribute__((__packed__));
-
-struct lttng_viewer_create_session_response {
-       /* enum lttng_viewer_create_session_return_code */
-       uint32_t status;
-} __attribute__((__packed__));
-
-#endif /* LTTNG_VIEWER_ABI_H */
index 5f01846bf597b7b122f4ea93dd3337e1c89fb050..003e7c32b36760779478503ebd0ce354067ce203 100644 (file)
@@ -1,18 +1,10 @@
 babeltraceinclude_HEADERS = \
        babeltrace/babeltrace.h \
-       babeltrace/format.h \
-       babeltrace/context.h \
-       babeltrace/iterator.h \
-       babeltrace/trace-handle.h \
-       babeltrace/list.h \
-       babeltrace/clock-types.h \
        babeltrace/values.h \
        babeltrace/ref.h
 
 babeltracectfinclude_HEADERS = \
-       babeltrace/ctf/events.h \
-       babeltrace/ctf/callbacks.h \
-       babeltrace/ctf/iterator.h
+       babeltrace/ctf/events.h
 
 babeltracectfwriterinclude_HEADERS = \
        babeltrace/ctf-writer/clock.h \
@@ -75,31 +67,18 @@ noinst_HEADERS = \
        babeltrace/align.h \
        babeltrace/babeltrace-internal.h \
        babeltrace/bitfield.h \
-       babeltrace/clock-internal.h \
        babeltrace/common-internal.h \
        babeltrace/compiler.h \
-       babeltrace/context-internal.h \
-       babeltrace/format-internal.h \
-       babeltrace/iterator-internal.h \
-       babeltrace/trace-collection.h \
        babeltrace/prio_heap.h \
        babeltrace/ref-internal.h \
-       babeltrace/types.h \
        babeltrace/object-internal.h \
        babeltrace/crc32.h \
-       babeltrace/debug-info.h \
-       babeltrace/trace-debug-info.h \
        babeltrace/dwarf.h \
        babeltrace/bin-info.h \
        babeltrace/utils.h \
-       babeltrace/ctf-ir/metadata.h \
-       babeltrace/ctf/events-internal.h \
-       babeltrace/ctf/metadata.h \
-       babeltrace/ctf-text/types.h \
-       babeltrace/ctf/types.h \
-       babeltrace/ctf/callbacks-internal.h \
-       babeltrace/ctf/ctf-index.h \
+       babeltrace/list.h \
        babeltrace/ctf-writer/writer-internal.h \
+       babeltrace/ctf-writer/serialize-internal.h \
        babeltrace/ctf-ir/attributes-internal.h \
        babeltrace/ctf-ir/field-types-internal.h \
        babeltrace/ctf-ir/fields-internal.h \
@@ -116,7 +95,6 @@ noinst_HEADERS = \
        babeltrace/ctf-ir/visitor-internal.h \
        babeltrace/ctf-writer/clock-internal.h \
        babeltrace/ctf-writer/functor-internal.h \
-       babeltrace/trace-handle-internal.h \
        babeltrace/compat/uuid.h \
        babeltrace/compat/memstream.h \
        babeltrace/compat/string.h \
diff --git a/include/babeltrace/clock-internal.h b/include/babeltrace/clock-internal.h
deleted file mode 100644 (file)
index 4bd4611..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _BABELTRACE_CLOCK_INTERNAL_H
-#define _BABELTRACE_CLOCK_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * clocks header (internal)
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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.
- */
-
-static inline
-uint64_t clock_cycles_to_ns(struct ctf_clock *clock, uint64_t cycles)
-{
-       if (clock->freq == 1000000000ULL) {
-               /* 1GHZ freq, no need to scale cycles value */
-               return cycles;
-       } else {
-               return (double) cycles * 1000000000.0
-                               / (double) clock->freq;
-       }
-}
-
-/*
- * Note: if using a frequency different from 1GHz for clock->offset, it
- * is recommended to express the seconds in offset_s, otherwise there
- * will be a loss of precision caused by the limited size of the double
- * mantissa.
- * This offset can be negative.
- */
-static inline
-int64_t clock_offset_ns(struct ctf_clock *clock)
-{
-       return clock->offset_s * 1000000000ULL
-                       + clock_cycles_to_ns(clock, clock->offset);
-}
-
-#endif /* _BABELTRACE_CLOCK_INTERNAL_H */
diff --git a/include/babeltrace/clock-types.h b/include/babeltrace/clock-types.h
deleted file mode 100644 (file)
index 8a3921a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _BABELTRACE_CLOCK_TYPES_H
-#define _BABELTRACE_CLOCK_TYPES_H
-
-/*
- * BabelTrace
- *
- * Clock types header
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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
-
-/*
- * The Babeltrace clock representations
- */
-enum bt_clock_type {
-       BT_CLOCK_CYCLES = 0,
-       BT_CLOCK_REAL,
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_CLOCK_TYPES_H */
diff --git a/include/babeltrace/context-internal.h b/include/babeltrace/context-internal.h
deleted file mode 100644 (file)
index 17d6202..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _BABELTRACE_CONTEXT_INTERNAL_H
-#define _BABELTRACE_CONTEXT_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * context header (internal)
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 <glib.h>
-
-struct trace_collection;
-struct GHashTable;
-
-/*
- * The context represents the object in which a trace_collection is
- * open. As long as this structure is allocated, the trace_collection is
- * open and the traces it contains can be read and seeked by the
- * iterators and callbacks.
- *
- * It has to be created with the bt_context_create() function and
- * destroyed by calling one more bt_context_put() than bt_context_get()
- */
-struct bt_context {
-       struct trace_collection *tc;
-       GHashTable *trace_handles;
-       int refcount;
-       int last_trace_handle_id;
-       struct bt_iter *current_iterator;
-};
-
-#endif /* _BABELTRACE_CONTEXT_INTERNAL_H */
diff --git a/include/babeltrace/context.h b/include/babeltrace/context.h
deleted file mode 100644 (file)
index b28df09..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef _BABELTRACE_CONTEXT_H
-#define _BABELTRACE_CONTEXT_H
-
-/*
- * BabelTrace
- *
- * context header
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 <unistd.h>
-#include <babeltrace/format.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* struct bt_context is opaque to the user */
-struct bt_context;
-struct bt_stream_pos;
-struct bt_ctf_event;
-
-/*
- * bt_context_create : create a Babeltrace context
- *
- * Allocate a new context. The creation of the context sets the refcount
- * to 1.
- *
- * Returns an allocated context on success and NULL on error
- */
-struct bt_context *bt_context_create(void);
-
-/*
- * bt_context_add_trace : Add a trace by path to the context
- *
- * Open a trace.
- *
- * path is the path to the trace, it is not recursive. If "path" is NULL,
- * stream_list is used instead as a list of mmap streams to open for the trace.
- *
- * format is a string containing the format name in which the trace was
- * produced.
- *
- * packet_seek can be NULL to use the default packet_seek handler provided by
- * the trace format. If non-NULL, it is used as an override of the handler for
- * seeks across packets. It takes as parameter a stream position, the packet
- * index it needs to seek to (for SEEK_SET), and a "whence" parameter (either
- * SEEK_CUR: seek to next packet, or SEEK_SET: seek to packet at packet index).
- *
- * stream_list is a linked list of streams, it is used to open a trace where
- * the trace data is located in memory mapped areas instead of trace files,
- * this argument should be non-NULL when path is NULL.
- *
- * The metadata parameter acts as a metadata override when not NULL, otherwise
- * the format handles the metadata opening.
- *
- * Return: the trace handle id (>= 0) on success, a negative
- * value on error.
- */
-int bt_context_add_trace(struct bt_context *ctx, const char *path,
-               const char *format,
-               void (*packet_seek)(struct bt_stream_pos *pos,
-                       size_t index, int whence),
-               struct bt_mmap_stream_list *stream_list,
-               FILE *metadata);
-
-/*
- * bt_context_remove_trace: Remove a trace from the context.
- *
- * Effectively closing the trace. Return negative error value if trace
- * is not in context.
- */
-int bt_context_remove_trace(struct bt_context *ctx, int trace_id);
-
-/*
- * bt_context_get and bt_context_put : increments and decrement the
- * refcount of the context
- *
- * These functions ensures that the context won't be destroyed when it
- * is in use. The same number of get and put (plus one extra put to
- * release the initial reference done at creation) has to be done to
- * destroy a context.
- *
- * When the context refcount is decremented to 0 by a bt_context_put,
- * the context is freed.
- */
-void bt_context_get(struct bt_context *ctx);
-void bt_context_put(struct bt_context *ctx);
-
-/*
- * bt_ctf_get_context : get the context associated with an event
- *
- * Returns NULL on error
- */
-struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *event);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_CONTEXT_H */
index 43b6ac41ce05420dcc27b80d1d74e8a01011859f..1546a78a4ebaab7851b44a31958942c448501c53 100644 (file)
@@ -31,7 +31,6 @@
 #include <babeltrace/ctf-ir/fields.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/values.h>
-#include <babeltrace/ctf/types.h>
 #include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf-ir/stream.h>
 #include <babeltrace/object-internal.h>
@@ -78,4 +77,12 @@ BT_HIDDEN
 int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
                uint32_t stream_id);
 
+static inline
+struct bt_ctf_stream_class *bt_ctf_event_class_borrow_stream_class(
+               struct bt_ctf_event_class *event_class)
+{
+       assert(event_class);
+       return (void *) bt_object_borrow_parent(event_class);
+}
+
 #endif /* BABELTRACE_CTF_IR_EVENT_CLASS_INTERNAL_H */
index 90be6e2451992054e69b614f3fb999138f4df6ad..85fea18cd4817c5ae70127e0fe8cf4ef2ae0b43d 100644 (file)
 #include <babeltrace/ctf-writer/event-fields.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/values.h>
-#include <babeltrace/ctf/types.h>
 #include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf-ir/stream.h>
 #include <babeltrace/ctf-ir/packet.h>
 #include <babeltrace/object-internal.h>
+#include <assert.h>
 #include <glib.h>
 
+struct bt_ctf_stream_pos;
+
 struct bt_ctf_event {
        struct bt_object base;
        struct bt_ctf_event_class *event_class;
@@ -56,9 +58,18 @@ int bt_ctf_event_validate(struct bt_ctf_event *event);
 
 BT_HIDDEN
 int bt_ctf_event_serialize(struct bt_ctf_event *event,
-               struct ctf_stream_pos *pos);
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order);
 
 BT_HIDDEN
 void bt_ctf_event_freeze(struct bt_ctf_event *event);
 
+static inline
+struct bt_ctf_event_class *bt_ctf_event_borrow_event_class(
+               struct bt_ctf_event *event)
+{
+       assert(event);
+       return event->event_class;
+}
+
 #endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
index 1b340b5b2ad9224935739f93e5a6b3c101b761c1..dcb5b12ab3211963460b2b38752e86c8aaa9f3c2 100644 (file)
@@ -34,8 +34,6 @@
 #include <babeltrace/ctf-ir/clock-class.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/object-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/ctf/events.h>
 #include <glib.h>
 
 typedef void (*type_freeze_func)(struct bt_ctf_field_type *);
@@ -44,7 +42,8 @@ typedef int (*type_serialize_func)(struct bt_ctf_field_type *,
 
 struct bt_ctf_field_type {
        struct bt_object base;
-       struct bt_declaration *declaration;
+       enum bt_ctf_type_id id;
+       unsigned int alignment;
        type_freeze_func freeze;
        type_serialize_func serialize;
        /*
@@ -63,16 +62,12 @@ struct bt_ctf_field_type {
 
 struct bt_ctf_field_type_integer {
        struct bt_ctf_field_type parent;
-       struct declaration_integer declaration;
        struct bt_ctf_clock_class *mapped_clock;
-
-       /*
-        * This is what the user sets and is never modified by internal
-        * code.
-        *
-        * This field must contain a `BT_CTF_BYTE_ORDER_*` value.
-        */
        enum bt_ctf_byte_order user_byte_order;
+       bool is_signed;
+       unsigned int size;
+       enum bt_ctf_integer_base base;
+       enum bt_ctf_string_encoding encoding;
 };
 
 struct enumeration_mapping {
@@ -92,7 +87,6 @@ struct bt_ctf_field_type_enumeration {
        struct bt_ctf_field_type parent;
        struct bt_ctf_field_type *container;
        GPtrArray *entries; /* Array of ptrs to struct enumeration_mapping */
-       struct declaration_enum declaration;
        /* Only set during validation. */
        bool has_overlapping_ranges;
 };
@@ -117,24 +111,9 @@ struct bt_ctf_field_type_enumeration_mapping_iterator {
 
 struct bt_ctf_field_type_floating_point {
        struct bt_ctf_field_type parent;
-       struct declaration_float declaration;
-
-       /*
-        * The `declaration` field above contains 3 pointers pointing
-        * to the fields below. This avoids unnecessary dynamic
-        * allocations.
-        */
-       struct declaration_integer sign;
-       struct declaration_integer mantissa;
-       struct declaration_integer exp;
-
-       /*
-        * This is what the user sets and is never modified by internal
-        * code.
-        *
-        * This field must contain a `BT_CTF_BYTE_ORDER_*` value.
-        */
        enum bt_ctf_byte_order user_byte_order;
+       unsigned int exp_dig;
+       unsigned int mant_dig;
 };
 
 struct structure_field {
@@ -146,7 +125,6 @@ struct bt_ctf_field_type_structure {
        struct bt_ctf_field_type parent;
        GHashTable *field_name_to_index;
        GPtrArray *fields; /* Array of pointers to struct structure_field */
-       struct declaration_struct declaration;
 };
 
 struct bt_ctf_field_type_variant {
@@ -156,14 +134,12 @@ struct bt_ctf_field_type_variant {
        struct bt_ctf_field_path *tag_field_path;
        GHashTable *field_name_to_index;
        GPtrArray *fields; /* Array of pointers to struct structure_field */
-       struct declaration_variant declaration;
 };
 
 struct bt_ctf_field_type_array {
        struct bt_ctf_field_type parent;
        struct bt_ctf_field_type *element_type;
        unsigned int length; /* Number of elements */
-       struct declaration_array declaration;
 };
 
 struct bt_ctf_field_type_sequence {
@@ -171,12 +147,11 @@ struct bt_ctf_field_type_sequence {
        struct bt_ctf_field_type *element_type;
        GString *length_field_name;
        struct bt_ctf_field_path *length_field_path;
-       struct declaration_sequence declaration;
 };
 
 struct bt_ctf_field_type_string {
        struct bt_ctf_field_type parent;
-       struct declaration_string declaration;
+       enum bt_ctf_string_encoding encoding;
 };
 
 BT_HIDDEN
@@ -197,11 +172,6 @@ int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
 BT_HIDDEN
 int bt_ctf_field_type_validate(struct bt_ctf_field_type *type);
 
-/* Override field type's byte order only if it is set to "native" */
-BT_HIDDEN
-void bt_ctf_field_type_set_native_byte_order(
-               struct bt_ctf_field_type *type, int byte_order);
-
 BT_HIDDEN
 int bt_ctf_field_type_structure_get_field_name_index(
                struct bt_ctf_field_type *structure, const char *name);
index 4794e72d9945f06d4cabc51ae293466a3e8483e9..720b88848b776f10d1de6d1563d542e488b28c73 100644 (file)
  * SOFTWARE.
  */
 
+#include <babeltrace/ctf-ir/field-types.h>
 #include <babeltrace/ctf-writer/event-fields.h>
 #include <babeltrace/object-internal.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/types.h>
+#include <stdint.h>
 #include <glib.h>
 
+struct bt_ctf_stream_pos;
+
 struct bt_ctf_field {
        struct bt_object base;
        struct bt_ctf_field_type *type;
@@ -42,7 +45,10 @@ struct bt_ctf_field {
 
 struct bt_ctf_field_integer {
        struct bt_ctf_field parent;
-       struct definition_integer definition;
+       union {
+               int64_t signd;
+               uint64_t unsignd;
+       } payload;
 };
 
 struct bt_ctf_field_enumeration {
@@ -52,8 +58,7 @@ struct bt_ctf_field_enumeration {
 
 struct bt_ctf_field_floating_point {
        struct bt_ctf_field parent;
-       struct definition_float definition;
-       struct definition_integer sign, mantissa, exp;
+       double payload;
 };
 
 struct bt_ctf_field_structure {
@@ -101,7 +106,8 @@ int bt_ctf_field_reset(struct bt_ctf_field *field);
 
 BT_HIDDEN
 int bt_ctf_field_serialize(struct bt_ctf_field *field,
-               struct ctf_stream_pos *pos);
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order);
 
 BT_HIDDEN
 void bt_ctf_field_freeze(struct bt_ctf_field *field);
diff --git a/include/babeltrace/ctf-ir/metadata.h b/include/babeltrace/ctf-ir/metadata.h
deleted file mode 100644 (file)
index 4d291c7..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-#ifndef _BABELTRACE_CTF_IR_METADATA_H
-#define _BABELTRACE_CTF_IR_METADATA_H
-
-/*
- * BabelTrace
- *
- * CTF Intermediate Representation Metadata Header
- *
- * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-#include <babeltrace/format.h>
-#include <babeltrace/format-internal.h>
-#include <babeltrace/ctf/types.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <babeltrace/compat/uuid.h>
-#include <assert.h>
-#include <glib.h>
-
-struct ctf_trace;
-struct ctf_stream_declaration;
-struct ctf_event_declaration;
-struct ctf_clock;
-struct ctf_callsite;
-struct ctf_scanner;
-
-struct ctf_stream_packet_limits {
-       uint64_t begin;
-       uint64_t end;
-};
-
-struct ctf_stream_packet_timestamp {
-       struct ctf_stream_packet_limits cycles;
-       struct ctf_stream_packet_limits real;
-};
-
-struct ctf_stream_definition {
-       struct ctf_stream_declaration *stream_class;
-       uint64_t real_timestamp;                /* Current timestamp, in ns */
-       uint64_t cycles_timestamp;              /* Current timestamp, in cycles */
-       uint64_t event_id;                      /* Current event ID */
-       int has_timestamp;
-       uint64_t stream_id;
-
-       struct definition_struct *trace_packet_header;
-       struct definition_struct *stream_packet_context;
-       struct definition_struct *stream_event_header;
-       struct definition_struct *stream_event_context;
-       GPtrArray *events_by_id;                /* Array of struct ctf_event_definition pointers indexed by id */
-       struct definition_scope *parent_def_scope;      /* for initialization */
-       int stream_definitions_created;
-
-       struct ctf_clock *current_clock;
-
-       /* Event discarded information */
-       uint64_t events_discarded;
-       /* Trace packets lost */
-       uint64_t packets_lost;
-       struct ctf_stream_packet_timestamp prev;
-       struct ctf_stream_packet_timestamp current;
-       char path[PATH_MAX];                    /* Path to stream. '\0' for mmap traces */
-};
-
-struct ctf_event_definition {
-       struct ctf_stream_definition *stream;
-       struct definition_struct *event_context;
-       struct definition_struct *event_fields;
-};
-
-#define CTF_CLOCK_SET_FIELD(ctf_clock, field)                          \
-       do {                                                            \
-               (ctf_clock)->field_mask |= CTF_CLOCK_ ## field;         \
-       } while (0)
-
-#define CTF_CLOCK_FIELD_IS_SET(ctf_clock, field)                       \
-               ((ctf_clock)->field_mask & CTF_CLOCK_ ## field)
-
-#define CTF_CLOCK_GET_FIELD(ctf_clock, field)                          \
-       ({                                                              \
-               assert(CTF_CLOCK_FIELD_IS_SET(ctf_clock, field));       \
-               (ctf_clock)->(field);                                   \
-       })
-
-struct ctf_clock {
-       GQuark name;
-       GQuark uuid;
-       char *description;
-       uint64_t freq;  /* frequency, in HZ */
-       /* precision in seconds is: precision * (1/freq) */
-       uint64_t precision;
-       /*
-        * The offset from Epoch is: offset_s + (offset * (1/freq))
-        * Coarse clock offset from Epoch (in seconds).
-        * It can be negative.
-        */
-       int64_t offset_s;
-       /*
-        * Fine clock offset from Epoch, in (1/freq) units.
-        * It can be negative.
-        */
-       int64_t offset;
-       int absolute;
-
-       enum {                                  /* Fields populated mask */
-               CTF_CLOCK_name          =       (1U << 0),
-               CTF_CLOCK_freq          =       (1U << 1),
-       } field_mask;
-};
-
-#define CTF_CALLSITE_SET_FIELD(ctf_callsite, field)                    \
-       do {                                                            \
-               (ctf_callsite)->field_mask |= CTF_CALLSITE_ ## field;   \
-       } while (0)
-
-#define CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field)                 \
-               ((ctf_callsite)->field_mask & CTF_CALLSITE_ ## field)
-
-#define CTF_CALLSITE_GET_FIELD(ctf_callsite, field)                    \
-       ({                                                              \
-               assert(CTF_CALLSITE_FIELD_IS_SET(ctf_callsite, field)); \
-               (ctf_callsite)->(field);                                \
-       })
-
-struct ctf_callsite {
-       GQuark name;            /* event name associated with callsite */
-       char *func;
-       char *file;
-       uint64_t line;
-       uint64_t ip;
-       struct bt_list_head node;
-       enum {                                  /* Fields populated mask */
-               CTF_CALLSITE_name       =       (1U << 0),
-               CTF_CALLSITE_func       =       (1U << 1),
-               CTF_CALLSITE_file       =       (1U << 2),
-               CTF_CALLSITE_line       =       (1U << 3),
-               CTF_CALLSITE_ip         =       (1U << 4),
-       } field_mask;
-};
-
-struct ctf_callsite_dups {
-       struct bt_list_head head;
-};
-
-#define CTF_TRACE_SET_FIELD(ctf_trace, field)                          \
-       do {                                                            \
-               (ctf_trace)->field_mask |= CTF_TRACE_ ## field;         \
-       } while (0)
-
-#define CTF_TRACE_FIELD_IS_SET(ctf_trace, field)                       \
-               ((ctf_trace)->field_mask & CTF_TRACE_ ## field)
-
-#define CTF_TRACE_GET_FIELD(ctf_trace, field)                          \
-       ({                                                              \
-               assert(CTF_TRACE_FIELD_IS_SET(ctf_trace, field));       \
-               (ctf_trace)->(field);                                   \
-       })
-
-#define TRACER_ENV_LEN 128
-
-/* tracer-specific environment */
-struct ctf_tracer_env {
-       int vpid;               /* negative if unset */
-
-       /* All strings below: "" if unset. */
-       char procname[TRACER_ENV_LEN];
-       char hostname[TRACER_ENV_LEN];
-       char domain[TRACER_ENV_LEN];
-       char sysname[TRACER_ENV_LEN];
-       char release[TRACER_ENV_LEN];
-       char version[TRACER_ENV_LEN];
-       char tracer_name[TRACER_ENV_LEN];
-};
-
-#ifdef ENABLE_DEBUG_INFO
-struct debug_info;
-#endif
-
-struct ctf_trace {
-       struct bt_trace_descriptor parent;
-
-       /* root scope */
-       struct declaration_scope *root_declaration_scope;
-
-       struct declaration_scope *declaration_scope;
-       /* innermost definition scope. to be used as parent of stream. */
-       struct definition_scope *definition_scope;
-       GPtrArray *streams;                     /* Array of struct ctf_stream_declaration pointers */
-       struct ctf_stream_definition *metadata;
-       char *metadata_string;
-       int metadata_packetized;
-       GHashTable *callsites;
-       GPtrArray *event_declarations;          /* Array of all the struct bt_ctf_event_decl */
-
-       struct declaration_struct *packet_header_decl;
-       struct ctf_scanner *scanner;
-       int restart_root_decl;
-
-       uint64_t major;
-       uint64_t minor;
-       unsigned char uuid[BABELTRACE_UUID_LEN];
-       int byte_order;         /* trace BYTE_ORDER. 0 if unset. */
-       struct ctf_tracer_env env;
-
-       enum {                                  /* Fields populated mask */
-               CTF_TRACE_major         =       (1U << 0),
-               CTF_TRACE_minor         =       (1U << 1),
-               CTF_TRACE_uuid          =       (1U << 2),
-               CTF_TRACE_byte_order    =       (1U << 3),
-               CTF_TRACE_packet_header =       (1U << 4),
-       } field_mask;
-
-       /* Information about trace backing directory and files */
-       DIR *dir;
-       int dirfd;
-       int flags;              /* open flags */
-
-#ifdef ENABLE_DEBUG_INFO
-       /* Debug information for this trace */
-       struct debug_info *debug_info;
-#endif
-};
-
-#define CTF_STREAM_SET_FIELD(ctf_stream, field)                                \
-       do {                                                            \
-               (ctf_stream)->field_mask |= CTF_STREAM_ ## field;       \
-       } while (0)
-
-#define CTF_STREAM_FIELD_IS_SET(ctf_stream, field)                     \
-               ((ctf_stream)->field_mask & CTF_STREAM_ ## field)
-
-#define CTF_STREAM_GET_FIELD(ctf_stream, field)                                \
-       ({                                                              \
-               assert(CTF_STREAM_FIELD_IS_SET(ctf_stream, field));     \
-               (ctf_stream)->(field);                                  \
-       })
-
-struct ctf_stream_declaration {
-       struct ctf_trace *trace;
-       /* parent is lexical scope containing the stream scope */
-       struct declaration_scope *declaration_scope;
-       /* innermost definition scope. to be used as parent of event. */
-       struct definition_scope *definition_scope;
-       GPtrArray *events_by_id;                /* Array of struct ctf_event_declaration pointers indexed by id */
-       GHashTable *event_quark_to_id;          /* GQuark to numeric id */
-
-       struct declaration_struct *packet_context_decl;
-       struct declaration_struct *event_header_decl;
-       struct declaration_struct *event_context_decl;
-
-       uint64_t stream_id;
-
-       enum {                                  /* Fields populated mask */
-               CTF_STREAM_stream_id =  (1 << 0),
-       } field_mask;
-
-       GPtrArray *streams;     /* Array of struct ctf_stream_definition pointers */
-};
-
-#define CTF_EVENT_SET_FIELD(ctf_event, field)                          \
-       do {                                                            \
-               (ctf_event)->field_mask |= CTF_EVENT_ ## field;         \
-       } while (0)
-
-#define CTF_EVENT_FIELD_IS_SET(ctf_event, field)                       \
-               ((ctf_event)->field_mask & CTF_EVENT_ ## field)
-
-#define CTF_EVENT_GET_FIELD(ctf_event, field)                          \
-       ({                                                              \
-               assert(CTF_EVENT_FIELD_IS_SET(ctf_event, field));       \
-               (ctf_event)->(field);                                   \
-       })
-
-struct ctf_event_declaration {
-       /* stream mapped by stream_id */
-       struct ctf_stream_declaration *stream;
-       /* parent is lexical scope containing the event scope */
-       struct declaration_scope *declaration_scope;
-
-       struct declaration_struct *context_decl;
-       struct declaration_struct *fields_decl;
-
-       GQuark name;
-       uint64_t id;            /* Numeric identifier within the stream */
-       uint64_t stream_id;
-       int loglevel;
-       GQuark model_emf_uri;
-
-       enum {                                  /* Fields populated mask */
-               CTF_EVENT_name  =               (1 << 0),
-               CTF_EVENT_id    =               (1 << 1),
-               CTF_EVENT_stream_id =           (1 << 2),
-               CTF_EVENT_loglevel =            (1 << 4),
-               CTF_EVENT_model_emf_uri =       (1 << 5),
-       } field_mask;
-};
-
-#endif /* _BABELTRACE_CTF_IR_METADATA_H */
index db5b7c79dccdd5e314a016cd0972355d52dc975a..b8366aaabd64a757d75384ccb533265b51a53996 100644 (file)
@@ -33,8 +33,8 @@
 #include <babeltrace/ctf-ir/trace.h>
 #include <babeltrace/object-internal.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/types.h>
 #include <babeltrace/ctf-ir/trace-internal.h>
+#include <assert.h>
 #include <glib.h>
 
 struct bt_ctf_stream_class {
@@ -81,4 +81,12 @@ BT_HIDDEN
 int bt_ctf_stream_class_set_id_no_check(
                struct bt_ctf_stream_class *stream_class, uint32_t id);
 
+static inline
+struct bt_ctf_trace *bt_ctf_stream_class_borrow_trace(
+               struct bt_ctf_stream_class *stream_class)
+{
+       assert(stream_class);
+       return (void *) bt_object_borrow_parent(stream_class);
+}
+
 #endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
index 0e0e2498b4d43bf40c0303074a16cb845885b060..c101236e275a96a4cbf9a268903b791b955e9136 100644 (file)
@@ -32,8 +32,8 @@
 #include <babeltrace/ctf-writer/clock.h>
 #include <babeltrace/ctf-writer/event-fields.h>
 #include <babeltrace/ctf-writer/event-types.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
 #include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/types.h>
 #include <glib.h>
 
 struct bt_ctf_stream {
@@ -47,7 +47,7 @@ struct bt_ctf_stream {
        /* Writer-specific members. */
        /* Array of pointers to bt_ctf_event for the current packet */
        GPtrArray *events;
-       struct ctf_stream_pos pos;
+       struct bt_ctf_stream_pos pos;
        unsigned int flushed_packet_count;
        uint64_t size;
 };
index 9c0ba851fb7c7fa14787afb0abd1756e5375b545..38c89e7b3c8d15756961c7a576fcef093354c587 100644 (file)
@@ -52,7 +52,7 @@ struct bt_ctf_trace {
        GString *name;
        int frozen;
        uuid_t uuid;
-       int byte_order; /* A value defined in Babeltrace's "endian.h" */
+       enum bt_ctf_byte_order native_byte_order;
        struct bt_value *environment;
        GPtrArray *clocks; /* Array of pointers to bt_ctf_clock_class */
        GPtrArray *stream_classes; /* Array of ptrs to bt_ctf_stream_class */
diff --git a/include/babeltrace/ctf-text/types.h b/include/babeltrace/ctf-text/types.h
deleted file mode 100644 (file)
index 7b4b717..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef _BABELTRACE_CTF_TEXT_TYPES_H
-#define _BABELTRACE_CTF_TEXT_TYPES_H
-
-/*
- * Common Trace Format (Text Output)
- *
- * Type header
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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 <sys/mman.h>
-#include <errno.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <glib.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/format.h>
-#include <babeltrace/format-internal.h>
-
-/*
- * Inherit from both struct bt_stream_pos and struct bt_trace_descriptor.
- */
-struct ctf_text_stream_pos {
-       struct bt_stream_pos parent;
-       struct bt_trace_descriptor trace_descriptor;
-       FILE *fp;               /* File pointer. NULL if unset. */
-       int depth;
-       int dummy;              /* disable output */
-       int print_names;        /* print field names */
-       int field_nr;
-       uint64_t last_real_timestamp;   /* to print delta */
-       uint64_t last_cycles_timestamp; /* to print delta */
-       GString *string;        /* Current string */
-};
-
-static inline
-struct ctf_text_stream_pos *ctf_text_pos(struct bt_stream_pos *pos)
-{
-       return container_of(pos, struct ctf_text_stream_pos, parent);
-}
-
-/*
- * Write only is supported for now.
- */
-BT_HIDDEN
-int ctf_text_integer_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_float_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_string_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_enum_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_struct_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_variant_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_array_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_text_sequence_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-
-static inline
-void print_pos_tabs(struct ctf_text_stream_pos *pos)
-{
-       int i;
-
-       for (i = 0; i < pos->depth; i++)
-               fprintf(pos->fp, "\t");
-}
-
-/*
- * Check if the field must be printed.
- */
-BT_HIDDEN
-int print_field(struct bt_definition *definition);
-
-#endif /* _BABELTRACE_CTF_TEXT_TYPES_H */
diff --git a/include/babeltrace/ctf-writer/serialize-internal.h b/include/babeltrace/ctf-writer/serialize-internal.h
new file mode 100644 (file)
index 0000000..b04ec36
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef BABELTRACE_CTF_WRITER_SERIALIZE_INTERNAL_H
+#define BABELTRACE_CTF_WRITER_SERIALIZE_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.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-ir/fields.h>
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/align.h>
+#include <babeltrace/mmap-align.h>
+
+struct bt_ctf_stream_pos {
+       int fd;
+       int prot;               /* mmap protection */
+       int flags;              /* mmap flags */
+
+       /* Current position */
+       off_t mmap_offset;      /* mmap offset in the file, in bytes */
+       off_t mmap_base_offset; /* offset of start of packet in mmap, in bytes */
+       uint64_t packet_size;   /* current packet size, in bits */
+       uint64_t content_size;  /* current content size, in bits */
+       int64_t offset;         /* offset from base, in bits. EOF for end of file. */
+       struct mmap_align *base_mma;/* mmap base address */
+};
+
+BT_HIDDEN
+int bt_ctf_field_integer_write(struct bt_ctf_field_integer *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order);
+
+BT_HIDDEN
+int bt_ctf_field_floating_point_write(struct bt_ctf_field_floating_point *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order);
+
+static inline
+int bt_ctf_stream_pos_access_ok(struct bt_ctf_stream_pos *pos, uint64_t bit_len)
+{
+       uint64_t max_len;
+
+       if (unlikely(pos->offset == EOF))
+               return 0;
+       if (pos->prot == PROT_READ) {
+               /*
+                * Reads may only reach up to the "content_size",
+                * regardless of the packet_size.
+                */
+               max_len = pos->content_size;
+       } else {
+               /* Writes may take place up to the end of the packet. */
+               max_len = pos->packet_size;
+       }
+       if (unlikely(pos->offset + bit_len > max_len))
+               return 0;
+       return 1;
+}
+
+static inline
+int bt_ctf_stream_pos_move(struct bt_ctf_stream_pos *pos, uint64_t bit_offset)
+{
+       int ret = 0;
+
+       ret = bt_ctf_stream_pos_access_ok(pos, bit_offset);
+       if (!ret) {
+               goto end;
+       }
+       pos->offset += bit_offset;
+end:
+       return ret;
+}
+
+static inline
+int bt_ctf_stream_pos_align(struct bt_ctf_stream_pos *pos, uint64_t bit_offset)
+{
+       return bt_ctf_stream_pos_move(pos,
+               offset_align(pos->offset, bit_offset));
+}
+
+static inline
+char *bt_ctf_stream_pos_get_addr(struct bt_ctf_stream_pos *pos)
+{
+       /* Only makes sense to get the address after aligning on CHAR_BIT */
+       assert(!(pos->offset % CHAR_BIT));
+       return mmap_align_addr(pos->base_mma) +
+               pos->mmap_base_offset + (pos->offset / CHAR_BIT);
+}
+
+static inline
+int bt_ctf_stream_pos_init(struct bt_ctf_stream_pos *pos,
+               int fd, int open_flags)
+{
+       pos->fd = fd;
+
+       switch (open_flags & O_ACCMODE) {
+       case O_RDONLY:
+               pos->prot = PROT_READ;
+               pos->flags = MAP_PRIVATE;
+               break;
+       case O_RDWR:
+               pos->prot = PROT_READ | PROT_WRITE;
+               pos->flags = MAP_SHARED;
+               break;
+       default:
+               assert(false);
+       }
+
+       return 0;
+}
+
+static inline
+int bt_ctf_stream_pos_fini(struct bt_ctf_stream_pos *pos)
+{
+       if (pos->base_mma) {
+               int ret;
+
+               /* unmap old base */
+               ret = munmap_align(pos->base_mma);
+               if (ret) {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+BT_HIDDEN
+void bt_ctf_stream_pos_packet_seek(struct bt_ctf_stream_pos *pos, size_t index,
+       int whence);
+
+#endif /* BABELTRACE_CTF_WRITER_SERIALIZE_INTERNAL_H */
diff --git a/include/babeltrace/ctf/callbacks-internal.h b/include/babeltrace/ctf/callbacks-internal.h
deleted file mode 100644 (file)
index 014f4b9..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef _BABELTRACE_CALLBACKS_INTERNAL_H
-#define _BABELTRACE_CALLBACKS_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * Internal callbacks header
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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 <glib.h>
-#include <babeltrace/babeltrace-internal.h>
-
-struct bt_ctf_iter;
-struct ctf_stream_definition;
-
-struct bt_callback {
-       int prio;               /* Callback order priority. Lower first. Dynamically assigned from dependency graph. */
-       void *private_data;
-       int flags;
-       struct bt_dependencies *depends;
-       struct bt_dependencies *weak_depends;
-       struct bt_dependencies *provides;
-       enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data,
-                                  void *private_data);
-};
-
-struct bt_callback_chain {
-       GArray *callback;       /* Array of struct bt_callback, ordered by priority */
-};
-
-/*
- * per id callbacks need to be per stream class because event ID vs
- * event name mapping can vary from stream to stream.
- */
-struct bt_stream_callbacks {
-       GArray *per_id_callbacks;       /* Array of struct bt_callback_chain */
-};
-
-struct bt_dependencies {
-       GArray *deps;                   /* Array of GQuarks */
-       int refcount;                   /* free when decremented to 0 */
-};
-
-BT_HIDDEN
-void process_callbacks(struct bt_ctf_iter *iter, struct ctf_stream_definition *stream);
-
-#endif /* _BABELTRACE_CALLBACKS_INTERNAL_H */
diff --git a/include/babeltrace/ctf/callbacks.h b/include/babeltrace/ctf/callbacks.h
deleted file mode 100644 (file)
index bc75769..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef _BABELTRACE_CTF_CALLBACKS_H
-#define _BABELTRACE_CTF_CALLBACKS_H
-
-/*
- * BabelTrace
- *
- * CTF events API
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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/format.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Forward declarations */
-struct bt_ctf_iter;
-struct bt_dependencies;
-
-enum bt_cb_ret {
-       BT_CB_OK                = 0,
-       BT_CB_OK_STOP           = 1,
-       BT_CB_ERROR_STOP        = 2,
-       BT_CB_ERROR_CONTINUE    = 3,
-};
-
-/*
- * Receives a variable number of strings as parameter, ended with NULL.
- */
-struct bt_dependencies *bt_dependencies_create(const char *first, ...);
-
-/*
- * struct bt_dependencies must be destroyed explicitly if not passed as
- * parameter to a bt_ctf_iter_add_callback().
- */
-void bt_dependencies_destroy(struct bt_dependencies *dep);
-
-/*
- * bt_ctf_iter_add_callback: Add a callback to iterator.
- *
- * @iter: trace collection iterator (input)
- * @event: event to target. 0 for all events.
- * @private_data: private data pointer to pass to the callback
- * @flags: specific flags controlling the behavior of this callback
- *         (or'd).
- *            
- * @callback: function pointer to call
- * @depends: struct bt_dependency detailing the required computation results.
- *           Ends with 0. NULL is accepted as empty dependency.
- * @weak_depends: struct bt_dependency detailing the optional computation
- *                results that can be optionally consumed by this
- *                callback. NULL is accepted as empty dependency.
- * @provides: struct bt_dependency detailing the computation results
- *            provided by this callback.
- *            Ends with 0. NULL is accepted as empty dependency.
- *
- * "depends", "weak_depends" and "provides" memory is handled by the
- * babeltrace library after this call succeeds or fails. These objects
- * can still be used by the caller until the babeltrace iterator is
- * destroyed, but they belong to the babeltrace library.
- *
- * (note to implementor: we need to keep a gptrarray of struct
- * bt_dependencies to "garbage collect" in struct bt_ctf_iter, and
- * dependencies need to have a refcount to handle the case where they
- * would be passed to more than one iterator. Upon iterator detroy, we
- * iterate on all the gc ptrarray and decrement the refcounts, freeing
- * if we reach 0.)
- * (note to implementor: we calculate the dependency graph when
- * bt_ctf_iter_read_event() is executed after a
- * bt_ctf_iter_add_callback(). Beware that it is valid to create/add
- * callbacks/read/add more callbacks/read some more.)
- */
-int bt_ctf_iter_add_callback(struct bt_ctf_iter *iter,
-               bt_intern_str event, void *private_data, int flags,
-               enum bt_cb_ret (*callback)(struct bt_ctf_event *ctf_data,
-                                          void *caller_data),
-               struct bt_dependencies *depends,
-               struct bt_dependencies *weak_depends,
-               struct bt_dependencies *provides);
-
-/*
- * For flags parameter above.
- */
-enum {
-       BT_FLAGS_FREE_PRIVATE_DATA      = (1 << 0),
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*_BABELTRACE_CTF_CALLBACKS_H */
diff --git a/include/babeltrace/ctf/ctf-index.h b/include/babeltrace/ctf/ctf-index.h
deleted file mode 100644 (file)
index 8880c2f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
- *                      Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *                      David Goulet <dgoulet@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.
- */
-
-#ifndef LTTNG_INDEX_H
-#define LTTNG_INDEX_H
-
-#include <babeltrace/compat/limits.h>
-
-#define CTF_INDEX_MAGIC 0xC1F1DCC1
-#define CTF_INDEX_MAJOR 1
-#define CTF_INDEX_MINOR 1
-
-/*
- * Header at the beginning of each index file.
- * All integer fields are stored in big endian.
- */
-struct ctf_packet_index_file_hdr {
-       uint32_t magic;
-       uint32_t index_major;
-       uint32_t index_minor;
-       /* struct packet_index_len, in bytes */
-       uint32_t packet_index_len;
-} __attribute__((__packed__));
-
-/*
- * Packet index generated for each trace packet store in a trace file.
- * All integer fields are stored in big endian.
- */
-struct ctf_packet_index {
-       uint64_t offset;                /* offset of the packet in the file, in bytes */
-       uint64_t packet_size;           /* packet size, in bits */
-       uint64_t content_size;          /* content size, in bits */
-       uint64_t timestamp_begin;
-       uint64_t timestamp_end;
-       uint64_t events_discarded;
-       uint64_t stream_id;
-       /* CTF_INDEX 1.0 limit */
-       uint64_t stream_instance_id;    /* ID of the channel instance */
-       uint64_t packet_seq_num;        /* packet sequence number */
-} __attribute__((__packed__));
-
-#endif /* LTTNG_INDEX_H */
diff --git a/include/babeltrace/ctf/events-internal.h b/include/babeltrace/ctf/events-internal.h
deleted file mode 100644 (file)
index 37a7bf6..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-#ifndef _BABELTRACE_CTF_EVENTS_INTERNAL_H
-#define _BABELTRACE_CTF_EVENTS_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * CTF events API (internal)
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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/iterator-internal.h>
-#include <babeltrace/ctf/callbacks.h>
-#include <babeltrace/ctf/callbacks-internal.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/ctf-ir/field-types.h>
-#include <glib.h>
-
-struct ctf_stream_definition;
-
-/*
- * These structures are public mappings to internal ctf_event structures.
- */
-struct bt_ctf_event {
-       struct ctf_event_definition *parent;
-};
-
-struct bt_ctf_event_decl {
-       struct ctf_event_declaration parent;
-       GPtrArray *context_decl;
-       GPtrArray *fields_decl;
-       GPtrArray *packet_header_decl;
-       GPtrArray *event_context_decl;
-       GPtrArray *event_header_decl;
-       GPtrArray *packet_context_decl;
-};
-
-struct bt_ctf_iter {
-       struct bt_iter parent;
-       struct bt_ctf_event current_ctf_event;  /* last read event */
-       GArray *callbacks;                              /* Array of struct bt_stream_callbacks */
-       struct bt_callback_chain main_callbacks;        /* For all events */
-       /*
-        * Flag indicating if dependency graph needs to be recalculated.
-        * Set by bt_iter_add_callback(), and checked (and
-        * cleared) by upon entry into bt_iter_read_event().
-        * bt_iter_read_event() is responsible for calling dep
-        * graph calculation if it sees this flag set.
-        */
-       int recalculate_dep_graph;
-       /*
-        * Array of pointers to struct bt_dependencies, for garbage
-        * collection. We're not using a linked list here because each
-        * struct bt_dependencies can belong to more than one
-        * bt_iter.
-        */
-       GPtrArray *dep_gc;
-       uint64_t events_lost;
-};
-
-struct bt_definition;
-struct bt_declaration;
-struct bt_ctf_event;
-struct bt_ctf_event_decl;
-struct bt_ctf_field_decl;
-
-/*
- * the top-level scopes in CTF
- */
-enum ctf_scope {
-       BT_TRACE_PACKET_HEADER          = 0,
-       BT_STREAM_PACKET_CONTEXT        = 1,
-       BT_STREAM_EVENT_HEADER          = 2,
-       BT_STREAM_EVENT_CONTEXT         = 3,
-       BT_EVENT_CONTEXT                = 4,
-       BT_EVENT_FIELDS                 = 5,
-};
-
-/*
- * bt_ctf_get_top_level_scope: return a definition of the top-level scope
- *
- * Top-level scopes are defined in the ctf_scope enum.
- * In order to get a field or a field list, the user needs to pass a
- * scope as argument, this scope can be a top-level scope or a scope
- * relative to an arbitrary field. This function provides the mapping
- * between the enum and the actual definition of top-level scopes.
- * On error return NULL.
- */
-const struct bt_definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *event,
-               enum ctf_scope scope);
-
-/*
- * bt_ctf_event_get_name: returns the name of the event or NULL on error
- */
-const char *bt_ctf_event_name(const struct bt_ctf_event *event);
-
-/*
- * bt_ctf_get_cycles: returns the timestamp of the event as written
- * in the packet (in cycles) or -1ULL on error.
- */
-uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *event);
-
-/*
- * bt_ctf_get_timestamp: get the timestamp of the event offsetted
- * with the system clock source (in ns) in *timestamp.
- *
- * Return 0 on success, or -1ULL on error.
- */
-int bt_ctf_get_timestamp(const struct bt_ctf_event *event, int64_t *timestamp);
-
-/*
- * bt_ctf_get_field_list: obtain the list of fields for compound type
- *
- * This function can be used to obtain the list of fields contained
- * within a top-level scope of an event or a compound type: array,
- * sequence, structure, or variant.
-
- * This function sets the "list" pointer to an array of definition
- * pointers and set count to the number of elements in the array.
- * Return 0 on success and a negative value on error.
- *
- * The content pointed to by "list" should *not* be freed. It stays
- * valid as long as the event is unchanged (as long as the iterator
- * from which the event is extracted is unchanged).
- */
-int bt_ctf_get_field_list(const struct bt_ctf_event *event,
-               const struct bt_definition *scope,
-               struct bt_definition const * const **list,
-               unsigned int *count);
-
-/*
- * bt_ctf_get_field: returns the definition of a specific field
- */
-const struct bt_definition *bt_ctf_get_field(const struct bt_ctf_event *event,
-               const struct bt_definition *scope,
-               const char *field);
-
-/*
- * bt_ctf_get_index: if the field is an array or a sequence, return the element
- * at position index, otherwise return NULL;
- */
-const struct bt_definition *bt_ctf_get_index(const struct bt_ctf_event *event,
-               const struct bt_definition *field,
-               unsigned int index);
-
-/*
- * bt_ctf_field_name: returns the name of a field or NULL on error
- */
-const char *bt_ctf_field_name(const struct bt_definition *def);
-
-/*
- * bt_ctf_get_decl_from_def: return the declaration of a field from
- * its definition or NULL on error
- */
-const struct bt_declaration *bt_ctf_get_decl_from_def(const struct bt_definition *def);
-
-/*
- * bt_ctf_get_decl_from_field_decl: return the declaration of a field from
- * a field_decl or NULL on error
- */
-const struct bt_declaration *bt_ctf_get_decl_from_field_decl(
-               const struct bt_ctf_field_decl *field);
-
-/*
- * bt_ctf_field_type: returns the type of a field or -1 if unknown
- */
-enum ctf_type_id bt_ctf_field_type(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_int_signedness: return the signedness of an integer
- *
- * return 0 if unsigned
- * return 1 if signed
- * return -1 on error
- */
-int bt_ctf_get_int_signedness(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_int_base: return the base of an int or a negative value on error
- */
-int bt_ctf_get_int_base(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_int_byte_order: return the byte order of an int or a negative
- * value on error
- */
-int bt_ctf_get_int_byte_order(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_int_len: return the size, in bits, of an int or a negative
- * value on error
- */
-ssize_t bt_ctf_get_int_len(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_encoding: return the encoding of an int, a string, or of
- * the integer contained in a char array or a sequence.
- * return a negative value on error
- */
-enum ctf_string_encoding bt_ctf_get_encoding(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_array_len: return the len of an array or a negative
- * value on error
- */
-int bt_ctf_get_array_len(const struct bt_declaration *decl);
-
-/*
- * bt_ctf_get_struct_field_count: return the number of fields in a structure.
- * Returns a negative value on error.
- */
-uint64_t bt_ctf_get_struct_field_count(const struct bt_definition *field);
-
-/*
- * Field access functions
- *
- * These functions return the value associated with the field passed in
- * parameter.
- *
- * If the field does not exist or is not of the type requested, the value
- * returned is undefined. To check if an error occured, use the
- * bt_ctf_field_get_error() function after accessing a field.
- *
- * bt_ctf_get_enum_int gets the integer field of an enumeration.
- * bt_ctf_get_enum_str gets the string matching the current enumeration
- * value, or NULL if the current value does not match any string.
- */
-uint64_t bt_ctf_get_uint64(const struct bt_definition *field);
-int64_t bt_ctf_get_int64(const struct bt_definition *field);
-const struct bt_definition *bt_ctf_get_enum_int(const struct bt_definition *field);
-const char *bt_ctf_get_enum_str(const struct bt_definition *field);
-char *bt_ctf_get_char_array(const struct bt_definition *field);
-char *bt_ctf_get_string(const struct bt_definition *field);
-double bt_ctf_get_float(const struct bt_definition *field);
-const struct bt_definition *bt_ctf_get_variant(const struct bt_definition *field);
-const struct bt_definition *bt_ctf_get_struct_field_index(
-               const struct bt_definition *field, uint64_t i);
-
-/*
- * bt_ctf_field_get_error: returns the last error code encountered while
- * accessing a field and reset the error flag.
- * Return 0 if no error, a negative value otherwise.
- */
-int bt_ctf_field_get_error(void);
-
-/*
- * bt_ctf_get_event_decl_list: get a list of all the event declarations in
- * a trace.
- *
- * The list array is pointed to the array of event declarations.
- * The number of events in the array is written in count.
- *
- * Return 0 on success and a negative value on error.
- *
- * The content pointed to by "list" should *not* be freed. It stays
- * valid as long as the trace is opened.
- */
-int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx,
-               struct bt_ctf_event_decl * const **list,
-               unsigned int *count);
-
-/*
- * bt_ctf_get_decl_event_name: return the name of the event or NULL on error
- */
-const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event);
-
-/*
- * bt_ctf_get_decl_event_id: return the event-ID of the event or -1ULL on error
- */
-uint64_t bt_ctf_get_decl_event_id(const struct bt_ctf_event_decl *event);
-
-/*
- * bt_ctf_get_decl_fields: get all field declarations in a scope of an event
- *
- * The list array is pointed to the array of field declaration.
- * The number of field declaration in the array is written in count.
- *
- * Returns 0 on success and a negative value on error
- *
- * The content pointed to by "list" should *not* be freed. It stays
- * valid as long as the trace is opened.
- */
-int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl,
-               enum ctf_scope scope,
-               struct bt_ctf_field_decl const * const **list,
-               unsigned int *count);
-
-/*
- * bt_ctf_get_decl_field_name: return the name of a field decl or NULL on error
- */
-const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field);
-int ctf_find_tc_stream_packet_intersection_union(struct bt_context *ctx,
-               int64_t *ts_begin, int64_t *ts_end);
-
-void ctf_update_current_packet_index(struct ctf_stream_definition *stream,
-               struct packet_index *prev_index,
-               struct packet_index *cur_index);
-
-int ctf_tc_set_stream_intersection_mode(struct bt_context *ctx);
-
-#endif /*_BABELTRACE_CTF_EVENTS_INTERNAL_H */
index 134db8c01f73e38cbaeae84edc3c16693ec97b73..cc448ba45b1019fb82ec3dc7b5302095df434385 100644 (file)
@@ -1,26 +1,18 @@
-#ifndef _BABELTRACE_CTF_EVENTS_H
-#define _BABELTRACE_CTF_EVENTS_H
+#ifndef BABELTRACE_CTF_EVENT_H
+#define BABELTRACE_CTF_EVENT_H
 
 /*
- * BabelTrace
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
  *
- * CTF events API
+ * 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:
  *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 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,
  * 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 <babeltrace/context.h>
-#include <babeltrace/clock-types.h>
-#include <babeltrace/ctf-ir/field-types.h>
-
 /*
- * This header must exist in Babeltrace 2 because it contained
- * enumerations that were used in CTF writer's API. Those enumerations
- * are now located in ctf-ir/field-types.h.
+ * This header still exists for backward compatibility reasons because
+ * CTF writer needed it to be included.
  */
 
-#endif /* _BABELTRACE_CTF_EVENTS_H */
+#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_EVENT_H */
diff --git a/include/babeltrace/ctf/iterator.h b/include/babeltrace/ctf/iterator.h
deleted file mode 100644 (file)
index 5b2a281..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef _BABELTRACE_CTF_ITERATOR_H
-#define _BABELTRACE_CTF_ITERATOR_H
-
-/*
- * BabelTrace
- *
- * CTF iterator API
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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/iterator.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct bt_ctf_iter;
-struct bt_ctf_event;
-
-/*
- * bt_ctf_iter_create - Allocate a CTF trace collection iterator.
- *
- * begin_pos and end_pos are optional parameters to specify the position
- * at which the trace collection should be seeked upon iterator
- * creation, and the position at which iteration will start returning
- * "EOF".
- *
- * By default, if begin_pos is NULL, a BT_SEEK_CUR is performed at
- * creation. By default, if end_pos is NULL, a BT_SEEK_END (end of
- * trace) is the EOF criterion.
- *
- * Return a pointer to the newly allocated iterator.
- *
- * Only one iterator can be created against a context. If more than one
- * iterator is being created for the same context, the second creation
- * will return NULL. The previous iterator must be destroyed before
- * creation of the new iterator for this function to succeed.
- */
-struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos);
-
- /*
- * bt_ctf_iter_create_intersect - Allocate a CTF trace collection
- * iterator corresponding to the timerange when all streams are active
- * simultaneously.
- *
- * On success, return a pointer to the newly allocated iterator. The
- * out parameters inter_begin_pos and inter_end_pos are also set to
- * correspond to the beginning and end of the intersection,
- * respectively.
- *
- * On failure, return NULL.
- */
-struct bt_ctf_iter *bt_ctf_iter_create_intersect(struct bt_context *ctx,
-               struct bt_iter_pos **inter_begin_pos,
-               struct bt_iter_pos **inter_end_pos);
-
-/*
- * bt_ctf_get_iter - get iterator from ctf iterator.
- */
-struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter);
-
-/*
- * bt_ctf_iter_destroy - Free a CTF trace collection iterator.
- */
-void bt_ctf_iter_destroy(struct bt_ctf_iter *iter);
-
-/*
- * bt_ctf_iter_read_event: Read the iterator's current event data.
- *
- * @iter: trace collection iterator (input). Should NOT be NULL.
- *
- * Return current event on success, NULL on end of trace.
- */
-struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter);
-
-/*
- * bt_ctf_iter_read_event_flags: Read the iterator's current event data.
- *
- * @iter: trace collection iterator (input). Should NOT be NULL.
- * @flags: pointer passed by the user, in which the trace reader populates
- * flags on special condition (BT_ITER_FLAG_*).
- *
- * Return current event on success, NULL on end of trace.
- */
-struct bt_ctf_event *bt_ctf_iter_read_event_flags(struct bt_ctf_iter *iter,
-               int *flags);
-
-/*
- * bt_ctf_get_lost_events_count: returns the number of events discarded
- * immediately prior to the last event read
- *
- * @iter: trace collection iterator (input). Should NOT be NULL.
- *
- * Return the number of lost events or -1ULL on error.
- */
-uint64_t bt_ctf_get_lost_events_count(struct bt_ctf_iter *iter);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_CTF_ITERATOR_H */
diff --git a/include/babeltrace/ctf/metadata.h b/include/babeltrace/ctf/metadata.h
deleted file mode 100644 (file)
index 1b78762..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _BABELTRACE_CTF_METADATA_H
-#define _BABELTRACE_CTF_METADATA_H
-
-/*
- * BabelTrace
- *
- * CTF Metadata Header
- *
- * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-#include <babeltrace/format.h>
-#include <babeltrace/ctf/types.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/trace-handle-internal.h>
-#include <babeltrace/context-internal.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <assert.h>
-#include <glib.h>
-
-#define CTF_MAGIC      0xC1FC1FC1
-#define TSDL_MAGIC     0x75D11D57
-
-struct ctf_file_stream {
-       struct ctf_stream_definition parent;
-       struct ctf_stream_pos pos;      /* current stream position */
-};
-
-#define HEADER_END             char end_field
-#define header_sizeof(type)    offsetof(typeof(type), end_field)
-
-struct metadata_packet_header {
-       uint32_t magic;                 /* 0x75D11D57 */
-       uint8_t  uuid[16];              /* Unique Universal Identifier */
-       uint32_t checksum;              /* 0 if unused */
-       uint32_t content_size;          /* in bits */
-       uint32_t packet_size;           /* in bits */
-       uint8_t  compression_scheme;    /* 0 if unused */
-       uint8_t  encryption_scheme;     /* 0 if unused */
-       uint8_t  checksum_scheme;       /* 0 if unused */
-       uint8_t  major;                 /* CTF spec major version number */
-       uint8_t  minor;                 /* CTF spec minor version number */
-       HEADER_END;
-};
-
-#endif /* _BABELTRACE_CTF_METADATA_H */
diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h
deleted file mode 100644 (file)
index 39591c6..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-#ifndef _BABELTRACE_CTF_TYPES_H
-#define _BABELTRACE_CTF_TYPES_H
-
-/*
- * Common Trace Format
- *
- * Type header
- *
- * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@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/types.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <glib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <babeltrace/mmap-align.h>
-
-#define LAST_OFFSET_POISON     ((int64_t) ~0ULL)
-
-struct bt_stream_callbacks;
-
-struct packet_index_time {
-       int64_t timestamp_begin;
-       int64_t timestamp_end;
-};
-
-struct packet_index {
-       off_t offset;           /* offset of the packet in the file, in bytes */
-       int64_t data_offset;    /* offset of data within the packet, in bits */
-       uint64_t packet_size;   /* packet size, in bits */
-       uint64_t content_size;  /* content size, in bits */
-       uint64_t events_discarded;
-       uint64_t events_discarded_len;  /* length of the field, in bits */
-       struct packet_index_time ts_cycles;     /* timestamp in cycles */
-       struct packet_index_time ts_real;       /* realtime timestamp */
-       /* CTF_INDEX 1.0 limit */
-       uint64_t stream_instance_id;    /* ID of the channel instance */
-       uint64_t packet_seq_num;        /* packet sequence number */
-};
-
-/*
- * Always update ctf_stream_pos with ctf_move_pos and ctf_init_pos.
- */
-struct ctf_stream_pos {
-       struct bt_stream_pos parent;
-       int fd;                 /* backing file fd. -1 if unset. */
-       FILE *index_fp;         /* backing index file fp. NULL if unset. */
-       GArray *packet_index;   /* contains struct packet_index */
-       int prot;               /* mmap protection */
-       int flags;              /* mmap flags */
-
-       /* Current position */
-       off_t mmap_offset;      /* mmap offset in the file, in bytes */
-       off_t mmap_base_offset; /* offset of start of packet in mmap, in bytes */
-       uint64_t packet_size;   /* current packet size, in bits */
-       uint64_t content_size;  /* current content size, in bits */
-       uint64_t *content_size_loc; /* pointer to current content size */
-       struct mmap_align *base_mma;/* mmap base address */
-       int64_t offset;         /* offset from base, in bits. EOF for end of file. */
-       int64_t last_offset;    /* offset before the last read_event */
-       int64_t data_offset;    /* offset of data in current packet */
-       uint64_t cur_index;     /* current index in packet index */
-       uint64_t last_events_discarded; /* last known amount of event discarded */
-       void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence); /* function called to switch packet */
-
-       int dummy;              /* dummy position, for length calculation */
-       struct bt_stream_callbacks *cb; /* Callbacks registered for iterator. */
-       void *priv;
-};
-
-static inline
-struct ctf_stream_pos *ctf_pos(struct bt_stream_pos *pos)
-{
-       return container_of(pos, struct ctf_stream_pos, parent);
-}
-
-BT_HIDDEN
-int ctf_integer_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_integer_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_float_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_float_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_string_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_string_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_enum_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_enum_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_struct_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_variant_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_array_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_array_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_sequence_read(struct bt_stream_pos *pos, struct bt_definition *definition);
-BT_HIDDEN
-int ctf_sequence_write(struct bt_stream_pos *pos, struct bt_definition *definition);
-
-void ctf_packet_seek(struct bt_stream_pos *pos, size_t index, int whence);
-
-int ctf_init_pos(struct ctf_stream_pos *pos, struct bt_trace_descriptor *trace,
-               int fd, int open_flags);
-int ctf_fini_pos(struct ctf_stream_pos *pos);
-
-static inline
-int ctf_pos_access_ok(struct ctf_stream_pos *pos, uint64_t bit_len)
-{
-       uint64_t max_len;
-
-       if (unlikely(pos->offset == EOF))
-               return 0;
-       if (pos->prot == PROT_READ) {
-               /*
-                * Reads may only reach up to the "content_size",
-                * regardless of the packet_size.
-                */
-               max_len = pos->content_size;
-       } else {
-               /* Writes may take place up to the end of the packet. */
-               max_len = pos->packet_size;
-       }
-       if (unlikely(pos->offset + bit_len > max_len))
-               return 0;
-       return 1;
-}
-
-/*
- * move_pos - move position of a relative bit offset
- *
- * Return 1 if OK, 0 if out-of-bound.
- *
- * TODO: allow larger files by updating base too.
- */
-static inline
-int ctf_move_pos(struct ctf_stream_pos *pos, uint64_t bit_offset)
-{
-       int ret = 0;
-
-       printf_debug("ctf_move_pos test EOF: %" PRId64 "\n", pos->offset);
-       ret = ctf_pos_access_ok(pos, bit_offset);
-       if (!ret) {
-               goto end;
-       }
-       pos->offset += bit_offset;
-       printf_debug("ctf_move_pos after increment: %" PRId64 "\n", pos->offset);
-end:
-       return ret;
-}
-
-/*
- * align_pos - align position on a bit offset (> 0)
- *
- * Return 1 if OK, 0 if out-of-bound.
- *
- * TODO: allow larger files by updating base too.
- */
-static inline
-int ctf_align_pos(struct ctf_stream_pos *pos, uint64_t bit_offset)
-{
-       return ctf_move_pos(pos, offset_align(pos->offset, bit_offset));
-}
-
-static inline
-char *ctf_get_pos_addr(struct ctf_stream_pos *pos)
-{
-       /* Only makes sense to get the address after aligning on CHAR_BIT */
-       assert(!(pos->offset % CHAR_BIT));
-       return mmap_align_addr(pos->base_mma) +
-               pos->mmap_base_offset + (pos->offset / CHAR_BIT);
-}
-
-static inline
-void ctf_dummy_pos(struct ctf_stream_pos *pos, struct ctf_stream_pos *dummy)
-{
-       memcpy(dummy, pos, sizeof(struct ctf_stream_pos));
-       dummy->dummy = 1;
-       dummy->fd = -1;
-}
-
-/*
- * Check if current packet can hold data.
- * Returns 0 for success, negative error otherwise.
- */
-static inline
-int ctf_pos_packet(struct ctf_stream_pos *dummy)
-{
-       if (unlikely(dummy->offset > dummy->packet_size))
-               return -ENOSPC;
-       return 0;
-}
-
-static inline
-void ctf_pos_pad_packet(struct ctf_stream_pos *pos)
-{
-       ctf_packet_seek(&pos->parent, 0, SEEK_CUR);
-}
-
-/*
- * Update the stream position to the current event. This moves to
- * the next packet if we are located at the end of the current packet.
- */
-static inline
-void ctf_pos_get_event(struct ctf_stream_pos *pos)
-{
-       assert(pos->offset <= pos->content_size);
-       if (pos->offset == pos->content_size) {
-               printf_debug("ctf_packet_seek (before call): %" PRId64 "\n",
-                            pos->offset);
-               pos->packet_seek(&pos->parent, 0, SEEK_CUR);
-               printf_debug("ctf_packet_seek (after call): %" PRId64 "\n",
-                            pos->offset);
-       }
-}
-
-void ctf_print_timestamp(FILE *fp, struct ctf_stream_definition *stream,
-                       int64_t timestamp);
-int ctf_append_trace_metadata(struct bt_trace_descriptor *tdp,
-                       FILE *metadata_fp);
-
-#endif /* _BABELTRACE_CTF_TYPES_H */
diff --git a/include/babeltrace/debug-info.h b/include/babeltrace/debug-info.h
deleted file mode 100644 (file)
index 029b44f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef _BABELTRACE_DEBUG_INFO_H
-#define _BABELTRACE_DEBUG_INFO_H
-
-/*
- * Babeltrace - Debug information state tracker
- *
- * Copyright (c) 2015 EfficiOS Inc.
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
- * Copyright (c) 2016 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.
- */
-
-struct debug_info;
-struct ctf_event_definition;
-
-#ifdef ENABLE_DEBUG_INFO
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <babeltrace/babeltrace-internal.h>
-
-struct debug_info_source {
-       /* Strings are owned by debug_info_source. */
-       char *func;
-       uint64_t line_no;
-       char *src_path;
-       /* short_src_path points inside src_path, no need to free. */
-       const char *short_src_path;
-       char *bin_path;
-       /* short_bin_path points inside bin_path, no need to free. */
-       const char *short_bin_path;
-       /*
-        * Location within the binary. Either absolute (@0x1234) or
-        * relative (+0x4321).
-        */
-       char *bin_loc;
-};
-
-BT_HIDDEN
-struct debug_info *debug_info_create(void);
-
-BT_HIDDEN
-void debug_info_destroy(struct debug_info *debug_info);
-
-BT_HIDDEN
-void debug_info_handle_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event);
-
-#else /* ifdef ENABLE_DEBUG_INFO */
-
-static inline
-struct debug_info *debug_info_create(void) { return malloc(1); }
-
-static inline
-void debug_info_destroy(struct debug_info *debug_info) { free(debug_info); }
-
-static inline
-void debug_info_handle_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event) { }
-
-#endif /* ENABLE_DEBUG_INFO */
-
-#endif /* _BABELTRACE_DEBUG_INFO_H */
diff --git a/include/babeltrace/format-internal.h b/include/babeltrace/format-internal.h
deleted file mode 100644 (file)
index 9d5ba33..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _BABELTRACE_FORMAT_INTERNAL_H
-#define _BABELTRACE_FORMAT_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * Trace Format Internal Header
- *
- * Copyright 2010-2013 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compat/limits.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/ctf/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Parent trace descriptor */
-struct bt_trace_descriptor {
-       char path[PATH_MAX];            /* trace path */
-       struct bt_context *ctx;
-       struct bt_trace_handle *handle;
-       struct trace_collection *collection;    /* Container of this trace */
-       GHashTable *clocks;
-       struct ctf_clock *single_clock;         /* currently supports only one clock */
-       bool interval_set;
-       struct packet_index_time interval_real; /* Interval of events to consider */
-};
-
-static inline void init_trace_descriptor(struct bt_trace_descriptor *td) {
-       if (!td) {
-               return;
-       }
-
-       td->interval_real.timestamp_begin = INT64_MIN;
-       td->interval_real.timestamp_end = INT64_MAX;
-       td->interval_set = false;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_FORMAT_INTERNAL_H */
diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h
deleted file mode 100644 (file)
index c9b84a6..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef _BABELTRACE_FORMAT_H
-#define _BABELTRACE_FORMAT_H
-
-/*
- * BabelTrace
- *
- * Trace Format Header
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/list.h>
-#include <babeltrace/clock-types.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int bt_intern_str;
-
-/* forward declaration */
-struct bt_stream_pos;
-struct bt_context;
-struct bt_trace_handle;
-struct bt_trace_descriptor;
-
-struct bt_mmap_stream {
-       int fd;
-       struct bt_list_head list;
-       void *priv;
-};
-
-struct bt_mmap_stream_list {
-       struct bt_list_head head;
-};
-
-struct bt_format {
-       bt_intern_str name;
-
-       struct bt_trace_descriptor *(*open_trace)(const char *path, int flags,
-                       void (*packet_seek)(struct bt_stream_pos *pos,
-                               size_t index, int whence),
-                       FILE *metadata_fp);
-       struct bt_trace_descriptor *(*open_mmap_trace)(
-                       struct bt_mmap_stream_list *mmap_list,
-                       void (*packet_seek)(struct bt_stream_pos *pos,
-                               size_t index, int whence),
-                       FILE *metadata_fp);
-       int (*close_trace)(struct bt_trace_descriptor *descriptor);
-       void (*set_context)(struct bt_trace_descriptor *descriptor,
-                       struct bt_context *ctx);
-       void (*set_handle)(struct bt_trace_descriptor *descriptor,
-                       struct bt_trace_handle *handle);
-       int (*timestamp_begin)(struct bt_trace_descriptor *descriptor,
-                       struct bt_trace_handle *handle, enum bt_clock_type type,
-                       int64_t *timestamp);
-       int (*timestamp_end)(struct bt_trace_descriptor *descriptor,
-                       struct bt_trace_handle *handle, enum bt_clock_type type,
-                       int64_t *timestamp);
-       int (*convert_index_timestamp)(struct bt_trace_descriptor *descriptor);
-};
-
-extern struct bt_format *bt_lookup_format(bt_intern_str qname);
-extern void bt_fprintf_format_list(FILE *fp);
-extern int bt_register_format(struct bt_format *format);
-extern void bt_unregister_format(struct bt_format *format);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_FORMAT_H */
diff --git a/include/babeltrace/iterator-internal.h b/include/babeltrace/iterator-internal.h
deleted file mode 100644 (file)
index d0cc287..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _BABELTRACE_ITERATOR_INTERNAL_H
-#define _BABELTRACE_ITERATOR_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * Internal iterator header
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/events.h>
-
-/*
- * struct bt_iter: data structure representing an iterator on a trace
- * collection.
- */
-struct bt_iter {
-       struct ptr_heap *stream_heap;
-       struct bt_context *ctx;
-       const struct bt_iter_pos *end_pos;
-};
-
-/*
- * bt_iter_create - Allocate a trace collection iterator.
- *
- * begin_pos and end_pos are optional parameters to specify the position
- * at which the trace collection should be seeked upon iterator
- * creation, and the position at which iteration will start returning
- * "EOF".
- *
- * By default, if begin_pos is NULL, a BT_SEEK_CUR is performed at
- * creation. By default, if end_pos is NULL, a BT_SEEK_END (end of
- * trace) is the EOF criterion.
- */
-struct bt_iter *bt_iter_create(struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos);
-
-/*
- * bt_iter_destroy - Free a trace collection iterator.
- */
-void bt_iter_destroy(struct bt_iter *iter);
-
-int bt_iter_init(struct bt_iter *iter,
-               struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos);
-void bt_iter_fini(struct bt_iter *iter);
-int bt_iter_add_trace(struct bt_iter *iter,
-               struct bt_trace_descriptor *td_read);
-
-#endif /* _BABELTRACE_ITERATOR_INTERNAL_H */
diff --git a/include/babeltrace/iterator.h b/include/babeltrace/iterator.h
deleted file mode 100644 (file)
index 5c3939c..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-#ifndef _BABELTRACE_ITERATOR_H
-#define _BABELTRACE_ITERATOR_H
-
-/*
- * BabelTrace API Iterators
- *
- * Copyright 2010-2011 - Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <babeltrace/context.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Flags for the iterator read_event */
-enum {
-       BT_ITER_FLAG_LOST_EVENTS        = (1 << 0),
-       BT_ITER_FLAG_RETRY              = (1 << 1),
-};
-
-/* Forward declarations */
-struct bt_iter;
-struct bt_saved_pos;
-
-/*
- * bt_iter is an abstract class, each format has to implement its own
- * iterator derived from this parent class.
- */
-
-/*
- * bt_iter_pos
- *
- * This structure represents the position where to set an iterator.
- *
- * type represents the type of seek to use.
- * u is the argument of the seek if necessary :
- * - seek_time is the real timestamp to seek to when using BT_SEEK_TIME, it
- *   is expressed in nanoseconds
- * - restore is a position saved with bt_iter_get_pos, it is used with
- *   BT_SEEK_RESTORE.
- *
- * Note about BT_SEEK_LAST: if many events happen to be at the last
- * timestamp, it is implementation-defined which event will be the last,
- * and the order of events with the same timestamp may not be the same
- * as normal iteration on the trace. Therefore, it is recommended to
- * only use BT_SEEK_LAST to get the timestamp of the last event(s) in
- * the trace.
- */
-enum bt_iter_pos_type {
-       BT_SEEK_TIME,           /* uses u.seek_time */
-       BT_SEEK_RESTORE,        /* uses u.restore */
-       BT_SEEK_CUR,
-       BT_SEEK_BEGIN,
-       BT_SEEK_LAST,
-};
-
-struct bt_iter_pos {
-       enum bt_iter_pos_type type;
-       union {
-               uint64_t seek_time;
-               struct bt_saved_pos *restore;
-       } u;
-};
-
-/*
- * bt_iter_next: Move trace collection position to the next event.
- *
- * Returns 0 on success, a negative value on error
- */
-int bt_iter_next(struct bt_iter *iter);
-
-/*
- * bt_iter_get_pos - Get the current iterator position.
- *
- * The position returned by this function needs to be freed by
- * bt_iter_free_pos after use.
- */
-struct bt_iter_pos *bt_iter_get_pos(struct bt_iter *iter);
-
-/*
- * bt_iter_free_pos - Free the position.
- */
-void bt_iter_free_pos(struct bt_iter_pos *pos);
-
-/*
- * bt_iter_set_pos: move the iterator to a given position.
- *
- * On error, the stream_heap is reinitialized and returned empty.
- *
- * Return 0 for success.
- *
- * Return EOF if the position requested is after the last event of the
- * trace collection.
- * Return -EINVAL when called with invalid parameter.
- * Return -ENOMEM if the stream_heap could not be properly initialized.
- */
-int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *pos);
-
-/*
- * bt_iter_create_time_pos: create a position based on time
- *
- * This function allocates and returns a new bt_iter_pos (which must be freed
- * with bt_iter_free_pos) to be able to restore an iterator position based on a
- * real timestamp.
- */
-struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *iter,
-               uint64_t timestamp);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_ITERATOR_H */
index 5c3ca6d992caa1a029d7cf274057c4a5fcb5e345..e130a81e883d620cba525cffc28a4ffba2f90fcd 100644 (file)
@@ -74,11 +74,17 @@ void generic_release(struct bt_object *obj)
 }
 
 static inline
-struct bt_object *bt_object_get_parent(void *ptr)
+struct bt_object *bt_object_borrow_parent(void *ptr)
 {
        struct bt_object *obj = ptr;
 
-       return ptr ? bt_get(obj->parent) : NULL;
+       return obj ? obj->parent : NULL;
+}
+
+static inline
+struct bt_object *bt_object_get_parent(void *ptr)
+{
+       return bt_get(bt_object_borrow_parent(ptr));
 }
 
 static inline
diff --git a/include/babeltrace/trace-collection.h b/include/babeltrace/trace-collection.h
deleted file mode 100644 (file)
index 904a7d8..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _BABELTRACE_TRACE_COLLECTION_H
-#define _BABELTRACE_TRACE_COLLECTION_H
-/*
- * BabelTrace lib
- *
- * trace collection header
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Author: Yannick Brosseau <yannick.brosseau@gmail.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
-
-struct trace_collection;
-
-void bt_init_trace_collection(struct trace_collection *tc);
-void bt_finalize_trace_collection(struct trace_collection *tc);
-int bt_trace_collection_add(struct trace_collection *tc,
-                        struct bt_trace_descriptor *td);
-int bt_trace_collection_remove(struct trace_collection *tc,
-                        struct bt_trace_descriptor *td);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_TRACE_COLLECTION_H */
diff --git a/include/babeltrace/trace-debug-info.h b/include/babeltrace/trace-debug-info.h
deleted file mode 100644 (file)
index 451d54f..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-#ifndef _BABELTRACE_TRACE_DEBUG_INFO_H
-#define _BABELTRACE_TRACE_DEBUG_INFO_H
-
-/*
- * Babeltrace - Debug information state tracker wrapper
- *
- * Copyright (c) 2015 EfficiOS Inc.
- * Copyright (c) 2015 Antoine Busque <abusque@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/metadata.h>
-
-#ifdef ENABLE_DEBUG_INFO
-
-#include <babeltrace/debug-info.h>
-#include <babeltrace/ctf-text/types.h>
-#include <stdbool.h>
-
-static inline
-void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos,
-               struct bt_definition *definition)
-{
-       struct definition_integer *integer_definition =
-                       container_of(definition, struct definition_integer, p);
-       struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
-       struct debug_info_source *debug_info_src =
-                       integer_definition->debug_info_src;
-
-       /* Print debug info if available */
-       if (debug_info_src) {
-               if (debug_info_src->func || debug_info_src->src_path ||
-                               debug_info_src->bin_path) {
-                       bool add_comma = false;
-
-                       fprintf(pos->fp, ", debug_info = { ");
-
-                       if (debug_info_src->bin_path) {
-                               fprintf(pos->fp, "bin = \"%s%s\"",
-                                               opt_debug_info_full_path ?
-                                               debug_info_src->bin_path :
-                                               debug_info_src->short_bin_path,
-                                               debug_info_src->bin_loc);
-                               add_comma = true;
-                       }
-
-                       if (debug_info_src->func) {
-                               if (add_comma) {
-                                       fprintf(pos->fp, ", ");
-                               }
-
-                               fprintf(pos->fp, "func = \"%s\"",
-                                               debug_info_src->func);
-                       }
-
-                       if (debug_info_src->src_path) {
-                               if (add_comma) {
-                                       fprintf(pos->fp, ", ");
-                               }
-
-                               fprintf(pos->fp, "src = \"%s:%" PRIu64
-                                               "\"",
-                                               opt_debug_info_full_path ?
-                                               debug_info_src->src_path :
-                                               debug_info_src->short_src_path,
-                                               debug_info_src->line_no);
-                       }
-
-                       fprintf(pos->fp, " }");
-               }
-       }
-}
-
-static inline
-int trace_debug_info_create(struct ctf_trace *trace)
-{
-       int ret = 0;
-
-       if (strcmp(trace->env.domain, "ust") != 0) {
-               goto end;
-       }
-
-       if (strcmp(trace->env.tracer_name, "lttng-ust") != 0) {
-               goto end;
-       }
-
-       trace->debug_info = debug_info_create();
-       if (!trace->debug_info) {
-               ret = -1;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-static inline
-void trace_debug_info_destroy(struct ctf_trace *trace)
-{
-       debug_info_destroy(trace->debug_info);
-}
-
-static inline
-void handle_debug_info_event(struct ctf_stream_declaration *stream_class,
-               struct ctf_event_definition *event)
-{
-       debug_info_handle_event(stream_class->trace->debug_info, event);
-}
-
-#else  /* #ifdef ENABLE_DEBUG_INFO */
-
-static inline
-void ctf_text_integer_write_debug_info(struct bt_stream_pos *ppos,
-               struct bt_definition *definition)
-{
-       /* Do nothing. */
-}
-
-static inline
-int trace_debug_info_create(struct ctf_trace *trace)
-{
-       return 0;
-}
-
-static inline
-void trace_debug_info_destroy(struct ctf_trace *trace)
-{
-       /* Do nothing. */
-}
-
-static inline
-void handle_debug_info_event(struct ctf_stream_declaration *stream_class,
-               struct ctf_event_definition *event)
-{
-       /* Do nothing. */
-}
-
-#endif /* #else #ifdef ENABLE_DEBUG_INFO */
-
-#endif /* _BABELTRACE_TRACE_DEBUG_INFO_H */
diff --git a/include/babeltrace/trace-handle-internal.h b/include/babeltrace/trace-handle-internal.h
deleted file mode 100644 (file)
index 924c730..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _BABELTRACE_TRACE_HANDLE_INTERNAL_H
-#define _BABELTRACE_TRACE_HANDLE_INTERNAL_H
-
-/*
- * BabelTrace
- *
- * Internal trace handle header
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 <stdlib.h>
-#include <babeltrace/context.h>
-#include <babeltrace/format.h>
-
-/*
- * trace_handle : unique identifier of a trace
- *
- * The trace_handle allows the user to manipulate a trace file directly.
- * It is a unique identifier representing a trace file.
- */
-struct bt_trace_handle {
-       int id;
-       struct bt_trace_descriptor *td;
-       struct bt_format *format;
-       char path[PATH_MAX];
-       int64_t real_timestamp_begin;
-       int64_t real_timestamp_end;
-       int64_t cycles_timestamp_begin;
-       int64_t cycles_timestamp_end;
-};
-
-/*
- * bt_trace_handle_create : allocates a trace_handle
- *
- * Returns a newly allocated trace_handle or NULL on error
- */
-struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx);
-
-/*
- * bt_trace_handle_destroy : free a trace_handle
- */
-void bt_trace_handle_destroy(struct bt_trace_handle *bt);
-
-#endif /* _BABELTRACE_TRACE_HANDLE_INTERNAL_H */
diff --git a/include/babeltrace/trace-handle.h b/include/babeltrace/trace-handle.h
deleted file mode 100644 (file)
index 55c850f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef _BABELTRACE_TRACE_HANDLE_H
-#define _BABELTRACE_TRACE_HANDLE_H
-
-/*
- * BabelTrace
- *
- * trace_handle header
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 <babeltrace/clock-types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * trace_handle : unique identifier of a trace
- *
- * The trace_handle allows the user to manipulate a trace file directly.
- * It is a unique identifier representing a trace file.
- */
-struct bt_trace_handle;
-struct bt_ctf_event;
-
-/*
- * bt_trace_handle_get_path : returns the path of a trace_handle or NULL
- * on error.
- */
-const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id);
-
-/*
- * bt_trace_handle_get_timestamp_begin : get the creation time (in
- * nanoseconds or cycles depending on type) of the buffers of a trace.
- *
- * Returns 0 on success, -1 on error.
- */
-int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
-               int handle_id, enum bt_clock_type type,
-               int64_t *timestamp);
-
-/*
- * bt_trace_handle_get_timestamp_end : get the destruction time
- * (in nanoseconds or cycles depending on type) of the buffers of a
- * trace.
- *
- * Returns 0 on success, -1 on error.
- */
-int bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
-               int handle_id, enum bt_clock_type type,
-               int64_t *timestamp);
-
-/*
- * bt_ctf_event_get_handle_id : get the handle id associated with an event
- *
- * Returns -1 on error
- */
-int bt_ctf_event_get_handle_id(const struct bt_ctf_event *event);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BABELTRACE_TRACE_HANDLE_H */
diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h
deleted file mode 100644 (file)
index b4198c8..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-#ifndef _BABELTRACE_TYPES_H
-#define _BABELTRACE_TYPES_H
-
-/*
- * BabelTrace
- *
- * Type Header
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/align.h>
-#include <babeltrace/list.h>
-#include <babeltrace/ctf/events.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <babeltrace/compat/limits.h>
-#include <string.h>
-#include <glib.h>
-#include <assert.h>
-
-/* Preallocate this many fields for structures */
-#define DEFAULT_NR_STRUCT_FIELDS 8
-
-struct ctf_stream_definition;
-struct bt_stream_pos;
-struct bt_format;
-struct bt_definition;
-struct ctf_clock;
-
-/* type scope */
-struct declaration_scope {
-       /* Hash table mapping type name GQuark to "struct declaration" */
-       /* Used for both typedef and typealias. */
-       GHashTable *typedef_declarations;
-       /* Hash table mapping struct name GQuark to "struct declaration_struct" */
-       GHashTable *struct_declarations;
-       /* Hash table mapping variant name GQuark to "struct declaration_variant" */
-       GHashTable *variant_declarations;
-       /* Hash table mapping enum name GQuark to "struct type_enum" */
-       GHashTable *enum_declarations;
-       struct declaration_scope *parent_scope;
-};
-
-/* definition scope */
-struct definition_scope {
-       /* Hash table mapping field name GQuark to "struct definition" */
-       GHashTable *definitions;
-       struct definition_scope *parent_scope;
-       /*
-        * Complete "path" leading to this definition scope.
-        * Includes dynamic scope name '.' field name '.' field name '.' ....
-        * Array of GQuark elements (which are each separated by dots).
-        * The dynamic scope name can contain dots, and is encoded into
-        * a single GQuark. Thus, scope_path[0] returns the GQuark
-        * identifying the dynamic scope.
-        */
-       GArray *scope_path;     /* array of GQuark */
-};
-
-struct bt_declaration {
-       enum bt_ctf_type_id id;
-       size_t alignment;       /* type alignment, in bits */
-       int ref;                /* number of references to the type */
-       /*
-        * declaration_free called with declaration ref is decremented to 0.
-        */
-       void (*declaration_free)(struct bt_declaration *declaration);
-       struct bt_definition *
-               (*definition_new)(struct bt_declaration *declaration,
-                                 struct definition_scope *parent_scope,
-                                 GQuark field_name, int index,
-                                 const char *root_name);
-       /*
-        * definition_free called with definition ref is decremented to 0.
-        */
-       void (*definition_free)(struct bt_definition *definition);
-};
-
-struct bt_definition {
-       struct bt_declaration *declaration;
-       int index;              /* Position of the definition in its container */
-       GQuark name;            /* Field name in its container (or 0 if unset) */
-       int ref;                /* number of references to the definition */
-       GQuark path;
-       struct definition_scope *scope;
-};
-
-typedef int (*rw_dispatch)(struct bt_stream_pos *pos,
-                          struct bt_definition *definition);
-
-/* Parent of per-plugin positions */
-struct bt_stream_pos {
-       /* read/write dispatch table. Specific to plugin used for stream. */
-       rw_dispatch *rw_table;  /* rw dispatch table */
-       int (*event_cb)(struct bt_stream_pos *pos,
-                       struct ctf_stream_definition *stream);
-       int (*pre_trace_cb)(struct bt_stream_pos *pos,
-                       struct bt_trace_descriptor *trace);
-       int (*post_trace_cb)(struct bt_stream_pos *pos,
-                       struct bt_trace_descriptor *trace);
-       struct bt_trace_descriptor *trace;
-};
-
-static inline
-int generic_rw(struct bt_stream_pos *pos, struct bt_definition *definition)
-{
-       enum bt_ctf_type_id dispatch_id = definition->declaration->id;
-       rw_dispatch call;
-
-       assert(pos->rw_table[dispatch_id] != NULL);
-       call = pos->rw_table[dispatch_id];
-       return call(pos, definition);
-}
-
-/*
- * Because we address in bits, bitfields end up being exactly the same as
- * integers, except that their read/write functions must be able to deal with
- * read/write non aligned on CHAR_BIT.
- */
-struct declaration_integer {
-       struct bt_declaration p;
-       size_t len;             /* length, in bits. */
-       int byte_order;         /* LITTLE_ENDIAN/BIG_ENDIAN, 0 == "Native" */
-       int signedness;
-       int base;               /* Base for pretty-printing: 2, 8, 10, 16 */
-       enum ctf_string_encoding encoding;
-       struct ctf_clock *clock;
-};
-
-#ifdef ENABLE_DEBUG_INFO
-struct debug_info_source;
-#endif
-
-struct definition_integer {
-       struct bt_definition p;
-       struct declaration_integer *declaration;
-       /* Last values read */
-       union {
-               uint64_t _unsigned;
-               int64_t _signed;
-       } value;
-
-#ifdef ENABLE_DEBUG_INFO
-       /*
-        * Debug infos (NULL if not set).
-        *
-        * This is extended debug informations set by the CTF input plugin
-        * itself when available. If it's set, then this integer definition
-        * is the "_ip" field of the stream event context.
-        */
-       struct debug_info_source *debug_info_src;
-#endif
-};
-
-struct declaration_float {
-       struct bt_declaration p;
-       struct declaration_integer *sign;
-       struct declaration_integer *mantissa;
-       struct declaration_integer *exp;
-       int byte_order;         /* LITTLE_ENDIAN/BIG_ENDIAN, 0 == "Native" */
-       /* TODO: we might want to express more info about NaN, +inf and -inf */
-};
-
-struct definition_float {
-       struct bt_definition p;
-       struct declaration_float *declaration;
-       struct definition_integer *sign;
-       struct definition_integer *mantissa;
-       struct definition_integer *exp;
-       /* Last values read */
-       double value;
-};
-
-/*
- * enum_val_equal assumes that signed and unsigned memory layout overlap.
- */
-struct enum_range {
-       union {
-               int64_t _signed;
-               uint64_t _unsigned;
-       } start;        /* lowest range value */
-       union {
-               int64_t _signed;
-               uint64_t _unsigned;
-       } end;          /* highest range value */
-};
-
-struct enum_range_to_quark {
-       struct bt_list_head node;
-       struct enum_range range;
-       GQuark quark;
-};
-
-/*
- * We optimize the common case (range of size 1: single value) by creating a
- * hash table mapping values to quark sets. We then lookup the ranges to
- * complete the quark set.
- *
- * TODO: The proper structure to hold the range to quark set mapping would be an
- * interval tree, with O(n) size, O(n*log(n)) build time and O(log(n)) query
- * time. Using a simple O(n) list search for now for implementation speed and
- * given that we can expect to have a _relatively_ small number of enumeration
- * ranges. This might become untrue if we are fed with symbol tables often
- * required to lookup function names from instruction pointer value.
- */
-struct enum_table {
-       GHashTable *value_to_quark_set;         /* (value, GQuark GArray) */
-       struct bt_list_head range_to_quark;     /* (range, GQuark) */
-       GHashTable *quark_to_range_set;         /* (GQuark, range GArray) */
-};
-
-struct declaration_enum {
-       struct bt_declaration p;
-       struct declaration_integer *integer_declaration;
-       struct enum_table table;
-};
-
-struct definition_enum {
-       struct bt_definition p;
-       struct definition_integer *integer;
-       struct declaration_enum *declaration;
-       /* Last GQuark values read. Keeping a reference on the GQuark array. */
-       GArray *value;
-};
-
-struct declaration_string {
-       struct bt_declaration p;
-       enum ctf_string_encoding encoding;
-};
-
-struct definition_string {
-       struct bt_definition p;
-       struct declaration_string *declaration;
-       char *value;    /* freed at definition_string teardown */
-       size_t len, alloc_len;
-};
-
-struct declaration_field {
-       GQuark name;
-       struct bt_declaration *declaration;
-};
-
-struct declaration_struct {
-       struct bt_declaration p;
-       GHashTable *fields_by_name;     /* Tuples (field name, field index) */
-       struct declaration_scope *scope;
-       GArray *fields;                 /* Array of declaration_field */
-};
-
-struct definition_struct {
-       struct bt_definition p;
-       struct declaration_struct *declaration;
-       GPtrArray *fields;              /* Array of pointers to struct bt_definition */
-};
-
-struct declaration_untagged_variant {
-       struct bt_declaration p;
-       GHashTable *fields_by_tag;      /* Tuples (field tag, field index) */
-       struct declaration_scope *scope;
-       GArray *fields;                 /* Array of declaration_field */
-};
-
-struct declaration_variant {
-       struct bt_declaration p;
-       struct declaration_untagged_variant *untagged_variant;
-       GArray *tag_name;               /* Array of GQuark */
-};
-
-/* A variant needs to be tagged to be defined. */
-struct definition_variant {
-       struct bt_definition p;
-       struct declaration_variant *declaration;
-       struct bt_definition *enum_tag;
-       GPtrArray *fields;              /* Array of pointers to struct bt_definition */
-       struct bt_definition *current_field;    /* Last field read */
-};
-
-struct declaration_array {
-       struct bt_declaration p;
-       size_t len;
-       struct bt_declaration *elem;
-       struct declaration_scope *scope;
-};
-
-struct definition_array {
-       struct bt_definition p;
-       struct declaration_array *declaration;
-       GPtrArray *elems;               /* Array of pointers to struct bt_definition */
-       GString *string;                /* String for encoded integer children */
-};
-
-struct declaration_sequence {
-       struct bt_declaration p;
-       GArray *length_name;            /* Array of GQuark */
-       struct bt_declaration *elem;
-       struct declaration_scope *scope;
-};
-
-struct definition_sequence {
-       struct bt_definition p;
-       struct declaration_sequence *declaration;
-       struct definition_integer *length;
-       GPtrArray *elems;               /* Array of pointers to struct bt_definition */
-       GString *string;                /* String for encoded integer children */
-};
-
-int bt_register_declaration(GQuark declaration_name,
-                        struct bt_declaration *declaration,
-                        struct declaration_scope *scope);
-struct bt_declaration *bt_lookup_declaration(GQuark declaration_name,
-                               struct declaration_scope *scope);
-
-/*
- * Type scopes also contain a separate registry for struct, variant and
- * enum types. Those register types rather than type definitions, so
- * that a named variant can be declared without specifying its target
- * "choice" tag field immediately.
- */
-int bt_register_struct_declaration(GQuark struct_name,
-                               struct declaration_struct *struct_declaration,
-                               struct declaration_scope *scope);
-struct declaration_struct *
-       bt_lookup_struct_declaration(GQuark struct_name,
-                                 struct declaration_scope *scope);
-int bt_register_variant_declaration(GQuark variant_name,
-                         struct declaration_untagged_variant *untagged_variant_declaration,
-                         struct declaration_scope *scope);
-struct declaration_untagged_variant *bt_lookup_variant_declaration(GQuark variant_name,
-                                        struct declaration_scope *scope);
-int bt_register_enum_declaration(GQuark enum_name,
-                             struct declaration_enum *enum_declaration,
-                             struct declaration_scope *scope);
-struct declaration_enum *
-       bt_lookup_enum_declaration(GQuark enum_name,
-                               struct declaration_scope *scope);
-
-struct declaration_scope *
-       bt_new_declaration_scope(struct declaration_scope *parent_scope);
-void bt_free_declaration_scope(struct declaration_scope *scope);
-
-/*
- * field_definition is for field definitions. They are registered into
- * definition scopes.
- */
-struct bt_definition *
-       bt_lookup_path_definition(GArray *cur_path,     /* array of GQuark */
-                              GArray *lookup_path,     /* array of GQuark */
-                              struct definition_scope *scope);
-int bt_register_field_definition(GQuark field_name,
-                             struct bt_definition *definition,
-                             struct definition_scope *scope);
-struct definition_scope *
-       bt_new_definition_scope(struct definition_scope *parent_scope,
-                            GQuark field_name, const char *root_name);
-void bt_free_definition_scope(struct definition_scope *scope);
-
-GQuark bt_new_definition_path(struct definition_scope *parent_scope,
-                          GQuark field_name, const char *root_name);
-
-static inline
-int compare_definition_path(struct bt_definition *definition, GQuark path)
-{
-       return definition->path == path;
-}
-
-void bt_declaration_ref(struct bt_declaration *declaration);
-void bt_declaration_unref(struct bt_declaration *declaration);
-
-void bt_definition_ref(struct bt_definition *definition);
-void bt_definition_unref(struct bt_definition *definition);
-
-struct declaration_integer *bt_integer_declaration_new(size_t len, int byte_order,
-                                 int signedness, size_t alignment,
-                                 int base, enum ctf_string_encoding encoding,
-                                 struct ctf_clock *clock);
-uint64_t bt_get_unsigned_int(const struct bt_definition *field);
-int64_t bt_get_signed_int(const struct bt_definition *field);
-int bt_get_int_signedness(const struct bt_definition *field);
-int bt_get_int_byte_order(const struct bt_definition *field);
-int bt_get_int_base(const struct bt_definition *field);
-size_t bt_get_int_len(const struct bt_definition *field);      /* in bits */
-enum ctf_string_encoding bt_get_int_encoding(const struct bt_definition *field);
-
-/*
- * mantissa_len is the length of the number of bytes represented by the mantissa
- * (e.g. result of DBL_MANT_DIG). It includes the leading 1.
- */
-struct declaration_float *bt_float_declaration_new(size_t mantissa_len,
-                                 size_t exp_len, int byte_order,
-                                 size_t alignment);
-
-/*
- * A GQuark can be translated to/from strings with g_quark_from_string() and
- * g_quark_to_string().
- */
-
-/*
- * Returns a GArray of GQuark or NULL.
- * Caller must release the GArray with g_array_unref().
- */
-GArray *bt_enum_uint_to_quark_set(const struct declaration_enum *enum_declaration,
-                              uint64_t v);
-
-/*
- * Returns a GArray of GQuark or NULL.
- * Caller must release the GArray with g_array_unref().
- */
-GArray *bt_enum_int_to_quark_set(const struct declaration_enum *enum_declaration,
-                             int64_t v);
-
-/*
- * Returns a GArray of struct enum_range or NULL.
- * Callers do _not_ own the returned GArray (and therefore _don't_ need to
- * release it).
- */
-GArray *bt_enum_quark_to_range_set(const struct declaration_enum *enum_declaration,
-                               GQuark q);
-void bt_enum_signed_insert(struct declaration_enum *enum_declaration,
-                        int64_t start, int64_t end, GQuark q);
-void bt_enum_unsigned_insert(struct declaration_enum *enum_declaration,
-                         uint64_t start, uint64_t end, GQuark q);
-size_t bt_enum_get_nr_enumerators(struct declaration_enum *enum_declaration);
-
-struct declaration_enum *
-       bt_enum_declaration_new(struct declaration_integer *integer_declaration);
-
-struct declaration_string *
-       bt_string_declaration_new(enum ctf_string_encoding encoding);
-char *bt_get_string(const struct bt_definition *field);
-enum ctf_string_encoding bt_get_string_encoding(const struct bt_definition *field);
-
-double bt_get_float(const struct bt_definition *field);
-
-const struct bt_definition *bt_get_variant_field(struct bt_definition *definition);
-
-struct declaration_struct *
-       bt_struct_declaration_new(struct declaration_scope *parent_scope,
-                              uint64_t min_align);
-void bt_struct_declaration_add_field(struct declaration_struct *struct_declaration,
-                                 const char *field_name,
-                                 struct bt_declaration *field_declaration);
-/*
- * Returns the index of a field within a structure.
- */
-int bt_struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration,
-                                                   GQuark field_name);
-/*
- * field returned only valid as long as the field structure is not appended to.
- */
-struct declaration_field *
-bt_struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration,
-                                       int index);
-struct bt_definition *
-bt_struct_definition_get_field_from_index(const struct definition_struct *struct_definition,
-                                      int index);
-int bt_struct_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-uint64_t bt_struct_declaration_len(const struct declaration_struct *struct_declaration);
-
-/*
- * The tag enumeration is validated to ensure that it contains only mappings
- * from numeric values to a single tag. Overlapping tag value ranges are
- * therefore forbidden.
- */
-struct declaration_untagged_variant *bt_untagged_bt_variant_declaration_new(
-               struct declaration_scope *parent_scope);
-struct declaration_variant *bt_variant_declaration_new(struct declaration_untagged_variant *untagged_variant,
-               const char *tag);
-
-void bt_untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration,
-               const char *field_name,
-               struct bt_declaration *field_declaration);
-struct declaration_field *
-       bt_untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration,
-               GQuark tag);
-/*
- * Returns 0 on success, -EPERM on error.
- */
-int variant_definition_set_tag(struct definition_variant *variant,
-                              struct bt_definition *enum_tag);
-/*
- * Returns the field selected by the current tag value.
- * field returned only valid as long as the variant structure is not appended
- * to.
- */
-struct bt_definition *bt_variant_get_current_field(struct definition_variant *variant);
-int bt_variant_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-
-/*
- * elem_declaration passed as parameter now belongs to the array. No
- * need to free it explicitly. "len" is the number of elements in the
- * array.
- */
-struct declaration_array *
-       bt_array_declaration_new(size_t len, struct bt_declaration *elem_declaration,
-               struct declaration_scope *parent_scope);
-uint64_t bt_array_len(struct definition_array *array);
-struct bt_definition *bt_array_index(struct definition_array *array, uint64_t i);
-int bt_array_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-GString *bt_get_char_array(const struct bt_definition *field);
-int bt_get_array_len(const struct bt_definition *field);
-
-/*
- * int_declaration and elem_declaration passed as parameter now belong
- * to the sequence. No need to free them explicitly.
- */
-struct declaration_sequence *
-       bt_sequence_declaration_new(const char *length_name,
-               struct bt_declaration *elem_declaration,
-               struct declaration_scope *parent_scope);
-uint64_t bt_sequence_len(struct definition_sequence *sequence);
-struct bt_definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i);
-int bt_sequence_rw(struct bt_stream_pos *pos, struct bt_definition *definition);
-
-/*
- * in: path (dot separated), out: q (GArray of GQuark)
- */
-void bt_append_scope_path(const char *path, GArray *q);
-
-/*
- * Lookup helpers.
- */
-struct bt_definition *bt_lookup_definition(const struct bt_definition *definition,
-                                    const char *field_name);
-struct bt_definition *bt_lookup_definition_by_quark(const struct bt_definition *definition,
-                                    GQuark quark);
-struct definition_integer *bt_lookup_integer(const struct bt_definition *definition,
-                                         const char *field_name,
-                                         int signedness);
-struct definition_enum *bt_lookup_enum(const struct bt_definition *definition,
-                                   const char *field_name,
-                                   int signedness);
-struct bt_definition *bt_lookup_variant(const struct bt_definition *definition,
-                                 const char *field_name);
-
-static inline
-const char *rem_(const char *str)
-{
-       if (str[0] == '_')
-               return &str[1];
-       else
-               return str;
-}
-
-#endif /* _BABELTRACE_TYPES_H */
index 0ba33f39f5621a6a8c9e444cdd602531aebecc63..26929ff32243d519824c08559559221c327f57f9 100644 (file)
@@ -1,25 +1,16 @@
-SUBDIRS = prio_heap plugin component .
+SUBDIRS = ctf-ir ctf-writer prio_heap plugin component .
 
 AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
 
 lib_LTLIBRARIES = libbabeltrace.la
 
-libbabeltrace_la_SOURCES = babeltrace.c \
-                          iterator.c \
-                          context.c \
-                          trace-handle.c \
-                          trace-collection.c \
-                          registry.c \
-                          values.c \
-                          ref.c
-
+libbabeltrace_la_SOURCES = babeltrace.c values.c ref.c
 libbabeltrace_la_LDFLAGS = -version-info $(BABELTRACE_LIBRARY_VERSION)
 
 if ENABLE_DEBUG_INFO
 noinst_LTLIBRARIES = libdebug-info.la
 
-libdebug_info_la_SOURCES = debug-info.c \
-                         bin-info.c \
+libdebug_info_la_SOURCES = bin-info.c \
                          dwarf.c \
                          crc32.c \
                          utils.c
@@ -29,11 +20,12 @@ endif
 
 libbabeltrace_la_LIBADD = \
        prio_heap/libprio_heap.la \
-       $(top_builddir)/types/libbabeltrace_types.la \
        $(top_builddir)/compat/libcompat.la \
        component/libcomponent.la \
        plugin/libplugin.la \
-       $(top_builddir)/common/libbabeltrace-common.la
+       $(top_builddir)/common/libbabeltrace-common.la \
+       ctf-ir/libctf-ir.la \
+       ctf-writer/libctf-writer.la
 
 if BUILT_IN_PYTHON_PLUGIN_SUPPORT
 libbabeltrace_la_LIBADD += $(top_builddir)/python-plugin-provider/libbabeltrace-python-plugin-provider.la
index b564e79d20151685bcf7d31a73839b08160f7b50..881e80d605cf9f80d77c242604ab4bd3be66c2d8 100644 (file)
@@ -27,9 +27,8 @@
  */
 
 #include <babeltrace/babeltrace.h>
-#include <babeltrace/context.h>
-#include <babeltrace/ctf-text/types.h>
 #include <stdlib.h>
+#include <stdbool.h>
 
 bool babeltrace_verbose, babeltrace_debug;
 
diff --git a/lib/context.c b/lib/context.c
deleted file mode 100644 (file)
index 56ac320..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * context.c
- *
- * Babeltrace Library
- *
- * Copyright 2011-2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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.h>
-#include <babeltrace/context.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/trace-handle.h>
-#include <babeltrace/trace-handle-internal.h>
-#include <babeltrace/trace-collection.h>
-#include <babeltrace/format.h>
-#include <babeltrace/format-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <fcntl.h> /* For O_RDONLY */
-
-#include <glib.h>
-
-static
-void remove_trace_handle(struct bt_trace_handle *handle);
-
-struct bt_context *bt_context_create(void)
-{
-       struct bt_context *ctx;
-
-       ctx = g_new0(struct bt_context, 1);
-       ctx->refcount = 1;
-       /* Negative handle id are errors. */
-       ctx->last_trace_handle_id = 0;
-
-       /* Instanciate the trace handle container */
-       ctx->trace_handles = g_hash_table_new_full(g_direct_hash,
-                               g_direct_equal, NULL,
-                               (GDestroyNotify) remove_trace_handle);
-
-       ctx->current_iterator = NULL;
-       ctx->tc = g_new0(struct trace_collection, 1);
-       bt_init_trace_collection(ctx->tc);
-
-       return ctx;
-}
-
-int bt_context_add_trace(struct bt_context *ctx, const char *path,
-               const char *format_name,
-               void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
-                       int whence),
-               struct bt_mmap_stream_list *stream_list,
-               FILE *metadata)
-{
-       struct bt_trace_descriptor *td;
-       struct bt_format *fmt;
-       struct bt_trace_handle *handle;
-       int ret, closeret;
-
-       if (!ctx || !format_name || (!path && !stream_list))
-               return -EINVAL;
-
-       fmt = bt_lookup_format(g_quark_from_string(format_name));
-       if (!fmt) {
-               fprintf(stderr, "[error] [Context] Format \"%s\" unknown.\n\n",
-                       format_name);
-               ret = -1;
-               goto end;
-       }
-       if (path) {
-               td = fmt->open_trace(path, O_RDONLY, packet_seek, NULL);
-               if (!td) {
-                       fprintf(stderr, "[warning] [Context] Cannot open_trace of format %s at path %s.\n",
-                                       format_name, path);
-                       ret = -1;
-                       goto end;
-               }
-       } else {
-               td = fmt->open_mmap_trace(stream_list, packet_seek, metadata);
-               if (!td) {
-                       fprintf(stderr, "[error] [Context] Cannot open_mmap_trace of format %s.\n\n",
-                                       format_name);
-                       ret = -1;
-                       goto end;
-               }
-       }
-
-       /* Create an handle for the trace */
-       handle = bt_trace_handle_create(ctx);
-       if (!handle) {
-               fprintf(stderr, "[error] [Context] Creating trace handle %s .\n\n",
-                               path);
-               ret = -1;
-               goto error_close;
-       }
-       handle->format = fmt;
-       handle->td = td;
-       if (path) {
-               strncpy(handle->path, path, PATH_MAX);
-               handle->path[PATH_MAX - 1] = '\0';
-       }
-
-       ret = bt_trace_collection_add(ctx->tc, td);
-       if (ret != 0)
-               goto error_destroy_handle;
-
-       if (fmt->set_handle)
-               fmt->set_handle(td, handle);
-       if (fmt->set_context)
-               fmt->set_context(td, ctx);
-
-       if (fmt->convert_index_timestamp) {
-               ret = fmt->convert_index_timestamp(td);
-               if (ret < 0)
-                       goto error_collection_del;
-       }
-
-       if (fmt->timestamp_begin) {
-               ret = fmt->timestamp_begin(td, handle, BT_CLOCK_REAL,
-                               &handle->real_timestamp_begin);
-               if (ret < 0 && ret != -ENOENT) {
-                       ret = -1;
-                       goto error_collection_del;
-               }
-       }
-       if (fmt->timestamp_end) {
-               ret = fmt->timestamp_end(td, handle, BT_CLOCK_REAL,
-                               &handle->real_timestamp_end);
-               if (ret < 0 && ret != -ENOENT) {
-                       ret = -1;
-                       goto error_collection_del;
-               }
-       }
-       if (fmt->timestamp_begin) {
-               ret = fmt->timestamp_begin(td, handle, BT_CLOCK_CYCLES,
-                               &handle->cycles_timestamp_begin);
-               if (ret < 0 && ret != -ENOENT) {
-                       ret = -1;
-                       goto error_collection_del;
-               }
-       }
-       if (fmt->timestamp_end) {
-               ret = fmt->timestamp_end(td, handle, BT_CLOCK_CYCLES,
-                               &handle->cycles_timestamp_end);
-               if (ret < 0 && ret != -ENOENT) {
-                       ret = -1;
-                       goto error_collection_del;
-               }
-       }
-
-       /* Add new handle to container */
-       g_hash_table_insert(ctx->trace_handles,
-               GUINT_TO_POINTER(handle->id),
-               handle);
-
-       return handle->id;
-
-error_collection_del:
-       /* Remove from containers */
-       bt_trace_collection_remove(handle->td->ctx->tc, handle->td);
-error_destroy_handle:
-       bt_trace_handle_destroy(handle);
-error_close:
-       closeret = fmt->close_trace(td);
-       if (closeret) {
-               fprintf(stderr, "Error in close_trace callback\n");
-       }
-end:
-       return ret;
-}
-
-int bt_context_remove_trace(struct bt_context *ctx, int handle_id)
-{
-       int ret = 0;
-
-       if (!ctx) {
-               ret = -EINVAL;
-               goto end;
-       }
-
-       /*
-        * Remove the handle. remove_trace_handle will be called
-        * automatically.
-        */
-       if (!g_hash_table_remove(ctx->trace_handles,
-               GUINT_TO_POINTER(handle_id))) {
-               ret = -ENOENT;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-static
-void bt_context_destroy(struct bt_context *ctx)
-{
-       assert(ctx);
-
-       /*
-        * Remove all traces. The g_hash_table_destroy will call
-        * remove_trace_handle on each element.
-        */
-       g_hash_table_destroy(ctx->trace_handles);
-
-       bt_finalize_trace_collection(ctx->tc);
-
-       /* ctx->tc should always be valid */
-       assert(ctx->tc != NULL);
-       g_free(ctx->tc);
-       g_free(ctx);
-}
-
-void bt_context_get(struct bt_context *ctx)
-{
-       assert(ctx);
-       ctx->refcount++;
-}
-
-void bt_context_put(struct bt_context *ctx)
-{
-       assert(ctx);
-       ctx->refcount--;
-       if (ctx->refcount == 0)
-               bt_context_destroy(ctx);
-}
-
-static
-void remove_trace_handle(struct bt_trace_handle *handle)
-{
-       int ret;
-
-       if (!handle->td->ctx)
-               return;
-       /* Remove from containers */
-       bt_trace_collection_remove(handle->td->ctx->tc, handle->td);
-       /* Close the trace */
-       ret = handle->format->close_trace(handle->td);
-       if (ret) {
-               fprintf(stderr, "Error in close_trace callback\n");
-       }
-
-       bt_trace_handle_destroy(handle);
-}
diff --git a/lib/ctf-ir/Makefile.am b/lib/ctf-ir/Makefile.am
new file mode 100644 (file)
index 0000000..af63ae9
--- /dev/null
@@ -0,0 +1,30 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include -I.
+
+noinst_LTLIBRARIES = libctf-ir.la
+
+libctf_ir_la_SOURCES = \
+       attributes.c \
+       clock-class.c \
+       event.c \
+       event-class.c \
+       fields.c \
+       field-types.c \
+       field-path.c \
+       packet.c \
+       stream.c \
+       stream-class.c \
+       trace.c \
+       utils.c \
+       resolve.c \
+       validation.c \
+       visitor.c
+
+libctf_ir_la_LIBADD =
+
+if BABELTRACE_BUILD_WITH_LIBUUID
+libctf_ir_la_LIBADD += -luuid
+endif
+
+if BABELTRACE_BUILD_WITH_LIBC_UUID
+libctf_ir_la_LIBADD += -lc
+endif
diff --git a/lib/ctf-ir/attributes.c b/lib/ctf-ir/attributes.c
new file mode 100644 (file)
index 0000000..c6e8a23
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+
+#define BT_CTF_ATTR_NAME_INDEX         0
+#define BT_CTF_ATTR_VALUE_INDEX                1
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_create(void)
+{
+       /*
+        * 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]
+        *     ]
+        */
+       return bt_value_array_create();
+}
+
+BT_HIDDEN
+void bt_ctf_attributes_destroy(struct bt_value *attr_obj)
+{
+       bt_put(attr_obj);
+}
+
+BT_HIDDEN
+int bt_ctf_attributes_get_count(struct bt_value *attr_obj)
+{
+       return bt_value_array_size(attr_obj);
+}
+
+BT_HIDDEN
+const char *bt_ctf_attributes_get_field_name(struct bt_value *attr_obj,
+               int 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 || index < 0) {
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_get(attr_obj, index);
+
+       if (!attr_field_obj) {
+               goto end;
+       }
+
+       attr_field_name_obj = bt_value_array_get(attr_field_obj,
+               BT_CTF_ATTR_NAME_INDEX);
+
+       if (!attr_field_name_obj) {
+               goto end;
+       }
+
+       rc = bt_value_string_get(attr_field_name_obj, &ret);
+
+       if (rc) {
+               ret = NULL;
+       }
+
+end:
+       BT_PUT(attr_field_name_obj);
+       BT_PUT(attr_field_obj);
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_get_field_value(struct bt_value *attr_obj,
+               int index)
+{
+       struct bt_value *value_obj = NULL;
+       struct bt_value *attr_field_obj = NULL;
+
+       if (!attr_obj || index < 0) {
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_get(attr_obj, index);
+
+       if (!attr_field_obj) {
+               goto end;
+       }
+
+       value_obj = bt_value_array_get(attr_field_obj,
+               BT_CTF_ATTR_VALUE_INDEX);
+
+end:
+       BT_PUT(attr_field_obj);
+       return value_obj;
+}
+
+static
+struct bt_value *bt_ctf_attributes_get_field_by_name(
+               struct bt_value *attr_obj, const char *name)
+{
+       int i;
+       int 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) {
+               goto error;
+       }
+
+       for (i = 0; i < attr_size; ++i) {
+               int ret;
+               const char *field_name;
+
+               value_obj = bt_value_array_get(attr_obj, i);
+
+               if (!value_obj) {
+                       goto error;
+               }
+
+               attr_field_name_obj = bt_value_array_get(value_obj, 0);
+
+               if (!attr_field_name_obj) {
+                       goto error;
+               }
+
+               ret = bt_value_string_get(attr_field_name_obj, &field_name);
+               if (ret) {
+                       goto error;
+               }
+
+               if (!strcmp(field_name, name)) {
+                       BT_PUT(attr_field_name_obj);
+                       break;
+               }
+
+               BT_PUT(attr_field_name_obj);
+               BT_PUT(value_obj);
+       }
+
+       return value_obj;
+
+error:
+       BT_PUT(attr_field_name_obj);
+       BT_PUT(value_obj);
+
+       return value_obj;
+}
+
+BT_HIDDEN
+int bt_ctf_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) {
+               ret = -1;
+               goto end;
+       }
+
+       attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
+
+       if (attr_field_obj) {
+               ret = bt_value_array_set(attr_field_obj,
+                       BT_CTF_ATTR_VALUE_INDEX, value_obj);
+               goto end;
+       }
+
+       attr_field_obj = bt_value_array_create();
+
+       if (!attr_field_obj) {
+               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) {
+               goto end;
+       }
+
+       ret = bt_value_array_append(attr_obj, attr_field_obj);
+
+end:
+       BT_PUT(attr_field_obj);
+
+       return ret;
+}
+
+BT_HIDDEN
+struct bt_value *bt_ctf_attributes_get_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) {
+               goto end;
+       }
+
+       attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
+
+       if (!attr_field_obj) {
+               goto end;
+       }
+
+       value_obj = bt_value_array_get(attr_field_obj,
+               BT_CTF_ATTR_VALUE_INDEX);
+
+end:
+       BT_PUT(attr_field_obj);
+
+       return value_obj;
+}
+
+BT_HIDDEN
+int bt_ctf_attributes_freeze(struct bt_value *attr_obj)
+{
+       int i;
+       int count;
+       int ret = 0;
+
+       if (!attr_obj) {
+               ret = -1;
+               goto end;
+       }
+
+       count = bt_value_array_size(attr_obj);
+
+       if (count < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * 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_ctf_attributes_get_field_value(attr_obj, i);
+
+               if (!obj) {
+                       ret = -1;
+                       goto end;
+               }
+
+               bt_value_freeze(obj);
+               BT_PUT(obj);
+       }
+
+end:
+       return ret;
+}
diff --git a/lib/ctf-ir/clock-class.c b/lib/ctf-ir/clock-class.c
new file mode 100644 (file)
index 0000000..66f7f44
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/clock-class-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_clock_class_destroy(struct bt_object *obj);
+
+BT_HIDDEN
+bool bt_ctf_clock_class_is_valid(struct bt_ctf_clock_class *clock_class)
+{
+       return clock_class && clock_class->name;
+}
+
+int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class,
+               const char *name)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_validate_identifier(name)) {
+               ret = -1;
+               goto end;
+       }
+
+       if (clock_class->name) {
+               g_string_assign(clock_class->name, name);
+       } else {
+               clock_class->name = g_string_new(name);
+               if (!clock_class->name) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name)
+{
+       int ret;
+       struct bt_ctf_clock_class *clock_class =
+               g_new0(struct bt_ctf_clock_class, 1);
+
+       if (!clock_class) {
+               goto error;
+       }
+
+       clock_class->precision = 1;
+       clock_class->frequency = 1000000000;
+       bt_object_init(clock_class, bt_ctf_clock_class_destroy);
+
+       if (name) {
+               ret = bt_ctf_clock_class_set_name(clock_class, name);
+               if (ret) {
+                       goto error;
+               }
+       }
+
+       ret = bt_uuid_generate(clock_class->uuid);
+       if (ret) {
+               goto error;
+       }
+
+       clock_class->uuid_set = 1;
+       return clock_class;
+error:
+       BT_PUT(clock_class);
+       return clock_class;
+}
+
+const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class)
+{
+       const char *ret = NULL;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       if (clock_class->name) {
+               ret = clock_class->name->str;
+       }
+
+end:
+       return ret;
+}
+
+const char *bt_ctf_clock_class_get_description(
+               struct bt_ctf_clock_class *clock_class)
+{
+       const char *ret = NULL;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       if (clock_class->description) {
+               ret = clock_class->description->str;
+       }
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_description(struct bt_ctf_clock_class *clock_class,
+               const char *desc)
+{
+       int ret = 0;
+
+       if (!clock_class || !desc || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->description = g_string_new(desc);
+       ret = clock_class->description ? 0 : -1;
+end:
+       return ret;
+}
+
+uint64_t bt_ctf_clock_class_get_frequency(
+               struct bt_ctf_clock_class *clock_class)
+{
+       uint64_t ret = -1ULL;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       ret = clock_class->frequency;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_frequency(struct bt_ctf_clock_class *clock_class,
+               uint64_t freq)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->frequency = freq;
+end:
+       return ret;
+}
+
+uint64_t bt_ctf_clock_class_get_precision(struct bt_ctf_clock_class *clock_class)
+{
+       uint64_t ret = -1ULL;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       ret = clock_class->precision;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_precision(struct bt_ctf_clock_class *clock_class,
+               uint64_t precision)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->precision = precision;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_get_offset_s(struct bt_ctf_clock_class *clock_class,
+               int64_t *offset_s)
+{
+       int ret = 0;
+
+       if (!clock_class || !offset_s) {
+               ret = -1;
+               goto end;
+       }
+
+       *offset_s = clock_class->offset_s;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_offset_s(struct bt_ctf_clock_class *clock_class,
+               int64_t offset_s)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->offset_s = offset_s;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_get_offset_cycles(struct bt_ctf_clock_class *clock_class,
+               int64_t *offset)
+{
+       int ret = 0;
+
+       if (!clock_class || !offset) {
+               ret = -1;
+               goto end;
+       }
+
+       *offset = clock_class->offset;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_offset_cycles(struct bt_ctf_clock_class *clock_class,
+               int64_t offset)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->offset = offset;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_get_is_absolute(struct bt_ctf_clock_class *clock_class)
+{
+       int ret = -1;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       ret = clock_class->absolute;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_is_absolute(struct bt_ctf_clock_class *clock_class,
+               int is_absolute)
+{
+       int ret = 0;
+
+       if (!clock_class || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       clock_class->absolute = !!is_absolute;
+end:
+       return ret;
+}
+
+const unsigned char *bt_ctf_clock_class_get_uuid(
+               struct bt_ctf_clock_class *clock_class)
+{
+       const unsigned char *ret;
+
+       if (!clock_class || !clock_class->uuid_set) {
+               ret = NULL;
+               goto end;
+       }
+
+       ret = clock_class->uuid;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_class_set_uuid(struct bt_ctf_clock_class *clock_class,
+               const unsigned char *uuid)
+{
+       int ret = 0;
+
+       if (!clock_class || !uuid || clock_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       memcpy(clock_class->uuid, uuid, sizeof(uuid_t));
+       clock_class->uuid_set = 1;
+end:
+       return ret;
+}
+
+static uint64_t ns_from_value(uint64_t frequency, uint64_t value)
+{
+       uint64_t ns;
+
+       if (frequency == 1000000000) {
+               ns = value;
+       } else {
+               ns = (uint64_t) ((1e9 * (double) value) / (double) frequency);
+       }
+
+       return ns;
+}
+
+BT_HIDDEN
+void bt_ctf_clock_class_freeze(struct bt_ctf_clock_class *clock_class)
+{
+       if (!clock_class) {
+               return;
+       }
+
+       clock_class->frozen = 1;
+}
+
+BT_HIDDEN
+void bt_ctf_clock_class_serialize(struct bt_ctf_clock_class *clock_class,
+               struct metadata_context *context)
+{
+       unsigned char *uuid;
+
+       if (!clock_class || !context) {
+               return;
+       }
+
+       uuid = clock_class->uuid;
+       g_string_append(context->string, "clock {\n");
+       g_string_append_printf(context->string, "\tname = %s;\n",
+               clock_class->name->str);
+       g_string_append_printf(context->string,
+               "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
+               uuid[0], uuid[1], uuid[2], uuid[3],
+               uuid[4], uuid[5], uuid[6], uuid[7],
+               uuid[8], uuid[9], uuid[10], uuid[11],
+               uuid[12], uuid[13], uuid[14], uuid[15]);
+       if (clock_class->description) {
+               g_string_append_printf(context->string, "\tdescription = \"%s\";\n",
+                       clock_class->description->str);
+       }
+
+       g_string_append_printf(context->string, "\tfreq = %" PRIu64 ";\n",
+               clock_class->frequency);
+       g_string_append_printf(context->string, "\tprecision = %" PRIu64 ";\n",
+               clock_class->precision);
+       g_string_append_printf(context->string, "\toffset_s = %" PRIu64 ";\n",
+               clock_class->offset_s);
+       g_string_append_printf(context->string, "\toffset = %" PRIu64 ";\n",
+               clock_class->offset);
+       g_string_append_printf(context->string, "\tabsolute = %s;\n",
+               clock_class->absolute ? "TRUE" : "FALSE");
+       g_string_append(context->string, "};\n\n");
+}
+
+static
+void bt_ctf_clock_class_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_clock_class *clock_class;
+
+       clock_class = container_of(obj, struct bt_ctf_clock_class, base);
+       if (clock_class->name) {
+               g_string_free(clock_class->name, TRUE);
+       }
+       if (clock_class->description) {
+               g_string_free(clock_class->description, TRUE);
+       }
+
+       g_free(clock_class);
+}
+
+static
+void bt_ctf_clock_value_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_clock_value *value;
+
+       if (!obj) {
+               return;
+       }
+
+       value = container_of(obj, struct bt_ctf_clock_value, base);
+       bt_put(value->clock_class);
+       g_free(value);
+}
+
+struct bt_ctf_clock_value *bt_ctf_clock_value_create(
+               struct bt_ctf_clock_class *clock_class, uint64_t value)
+{
+       struct bt_ctf_clock_value *ret = NULL;
+
+       if (!clock_class) {
+               goto end;
+       }
+
+       ret = g_new0(struct bt_ctf_clock_value, 1);
+       if (!ret) {
+               goto end;
+       }
+
+       bt_object_init(ret, bt_ctf_clock_value_destroy);
+       ret->clock_class = bt_get(clock_class);
+       ret->value = value;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_value_get_value(
+               struct bt_ctf_clock_value *clock_value, uint64_t *raw_value)
+{
+       int ret = 0;
+
+       if (!clock_value || !raw_value) {
+               ret = -1;
+               goto end;
+       }
+
+       *raw_value = clock_value->value;
+end:
+       return ret;
+}
+
+int bt_ctf_clock_value_get_value_ns_from_epoch(struct bt_ctf_clock_value *value,
+               int64_t *ret_value_ns)
+{
+       int ret = 0;
+       int64_t ns;
+
+       if (!value || !ret_value_ns) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Initialize nanosecond timestamp to clock's offset in seconds. */
+       ns = value->clock_class->offset_s * 1000000000;
+
+       /* Add offset in cycles, converted to nanoseconds. */
+       ns += ns_from_value(value->clock_class->frequency,
+                       value->clock_class->offset);
+
+       /* Add given value, converter to nanoseconds. */
+       ns += ns_from_value(value->clock_class->frequency, value->value);
+
+       *ret_value_ns = ns;
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *bt_ctf_clock_value_get_class(
+               struct bt_ctf_clock_value *clock_value)
+{
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!clock_value) {
+               goto end;
+       }
+
+       clock_class = bt_get(clock_value->clock_class);
+
+end:
+       return clock_class;
+}
diff --git a/lib/ctf-ir/event-class.c b/lib/ctf-ir/event-class.c
new file mode 100644 (file)
index 0000000..3644487
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/fields-internal.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/stream-class.h>
+#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/ctf-ir/trace-internal.h>
+#include <babeltrace/ctf-ir/validation-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/ctf-ir/attributes-internal.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/endian.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_event_class_destroy(struct bt_object *obj);
+
+struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name)
+{
+       int ret;
+       struct bt_value *obj = NULL;
+       struct bt_ctf_event_class *event_class = NULL;
+
+       if (bt_ctf_validate_identifier(name)) {
+               goto error;
+       }
+
+       event_class = g_new0(struct bt_ctf_event_class, 1);
+       if (!event_class) {
+               goto error;
+       }
+
+       event_class->id = -1;
+       bt_object_init(event_class, bt_ctf_event_class_destroy);
+       event_class->fields = bt_ctf_field_type_structure_create();
+       if (!event_class->fields) {
+               goto error;
+       }
+
+       event_class->attributes = bt_ctf_attributes_create();
+       if (!event_class->attributes) {
+               goto error;
+       }
+
+       obj = bt_value_integer_create_init(-1);
+       if (!obj) {
+               goto error;
+       }
+
+       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
+               "id", obj);
+       if (ret) {
+               goto error;
+       }
+
+       BT_PUT(obj);
+
+       obj = bt_value_string_create_init(name);
+       if (!obj) {
+               goto error;
+       }
+
+       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
+               "name", obj);
+       if (ret) {
+               goto error;
+       }
+
+       BT_PUT(obj);
+
+       return event_class;
+
+error:
+        BT_PUT(event_class);
+       BT_PUT(obj);
+       return event_class;
+}
+
+const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
+{
+       struct bt_value *obj = NULL;
+       const char *name = NULL;
+
+       if (!event_class) {
+               goto end;
+       }
+
+       if (event_class->name) {
+               name = event_class->name;
+               goto end;
+       }
+
+       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
+               BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
+       if (!obj) {
+               goto end;
+       }
+
+       if (bt_value_string_get(obj, &name)) {
+               name = NULL;
+       }
+
+end:
+       BT_PUT(obj);
+       return name;
+}
+
+int64_t bt_ctf_event_class_get_id(struct bt_ctf_event_class *event_class)
+{
+       struct bt_value *obj = NULL;
+       int64_t ret = 0;
+
+       if (!event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       if (event_class->id >= 0) {
+               ret = event_class->id;
+               goto end;
+       }
+
+       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
+               BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
+       if (!obj) {
+               goto end;
+       }
+
+       if (bt_value_integer_get(obj, &ret)) {
+               ret = -1;
+       }
+
+       if (ret < 0) {
+               /* means ID is not set */
+               ret = -1;
+               goto end;
+       }
+
+end:
+       BT_PUT(obj);
+       return ret;
+}
+
+int bt_ctf_event_class_set_id(struct bt_ctf_event_class *event_class,
+               uint32_t id)
+{
+       int ret = 0;
+       struct bt_value *obj = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+
+       if (!event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       stream_class = bt_ctf_event_class_get_stream_class(event_class);
+       if (stream_class) {
+               /*
+                * We don't allow changing the id if the event class has already
+                * been added to a stream class.
+                */
+               ret = -1;
+               goto end;
+       }
+
+       obj = bt_ctf_attributes_get_field_value(event_class->attributes,
+               BT_CTF_EVENT_CLASS_ATTR_ID_INDEX);
+       if (!obj) {
+               goto end;
+       }
+
+       if (bt_value_integer_set(obj, id)) {
+               ret = -1;
+               goto end;
+       }
+
+end:
+       BT_PUT(obj);
+       BT_PUT(stream_class);
+       return ret;
+}
+
+int bt_ctf_event_class_set_attribute(
+               struct bt_ctf_event_class *event_class, const char *name,
+               struct bt_value *value)
+{
+       int ret = 0;
+
+       if (!event_class || !name || !value || event_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!strcmp(name, "id") || !strcmp(name, "loglevel") ||
+                       !strcmp(name, "stream_id")) {
+               if (!bt_value_is_integer(value)) {
+                       ret = -1;
+                       goto end;
+               }
+       } else if (!strcmp(name, "name") || !strcmp(name, "model.emf.uri") ||
+                       !strcmp(name, "loglevel_string")) {
+               if (!bt_value_is_string(value)) {
+                       ret = -1;
+                       goto end;
+               }
+       } else {
+               /* unknown attribute */
+               ret = -1;
+               goto end;
+       }
+
+       /* "id" special case: >= 0 */
+       if (!strcmp(name, "id")) {
+               int64_t val;
+
+               ret = bt_value_integer_get(value, &val);
+
+               if (ret) {
+                       goto end;
+               }
+
+               if (val < 0) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
+                       name, value);
+
+end:
+       return ret;
+}
+
+int bt_ctf_event_class_get_attribute_count(
+               struct bt_ctf_event_class *event_class)
+{
+       int ret = 0;
+
+       if (!event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_count(event_class->attributes);
+
+end:
+       return ret;
+}
+
+const char *
+bt_ctf_event_class_get_attribute_name(
+               struct bt_ctf_event_class *event_class, int index)
+{
+       const char *ret;
+
+       if (!event_class) {
+               ret = NULL;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_name(event_class->attributes, index);
+
+end:
+       return ret;
+}
+
+struct bt_value *
+bt_ctf_event_class_get_attribute_value(struct bt_ctf_event_class *event_class,
+               int index)
+{
+       struct bt_value *ret;
+
+       if (!event_class) {
+               ret = NULL;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_value(event_class->attributes, index);
+
+end:
+       return ret;
+}
+
+struct bt_value *
+bt_ctf_event_class_get_attribute_value_by_name(
+               struct bt_ctf_event_class *event_class, const char *name)
+{
+       struct bt_value *ret;
+
+       if (!event_class || !name) {
+               ret = NULL;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_value_by_name(event_class->attributes,
+               name);
+
+end:
+       return ret;
+
+}
+
+struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
+               struct bt_ctf_event_class *event_class)
+{
+       return event_class ?
+               bt_get(bt_ctf_event_class_borrow_stream_class(event_class)) :
+               NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_event_class_get_payload_type(
+               struct bt_ctf_event_class *event_class)
+{
+       struct bt_ctf_field_type *payload = NULL;
+
+       if (!event_class) {
+               goto end;
+       }
+
+       bt_get(event_class->fields);
+       payload = event_class->fields;
+end:
+       return payload;
+}
+
+int bt_ctf_event_class_set_payload_type(struct bt_ctf_event_class *event_class,
+               struct bt_ctf_field_type *payload)
+{
+       int ret = 0;
+
+       if (!event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       if (payload && bt_ctf_field_type_get_type_id(payload) !=
+                       BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(event_class->fields);
+       event_class->fields = bt_get(payload);
+end:
+       return ret;
+}
+
+int bt_ctf_event_class_add_field(struct bt_ctf_event_class *event_class,
+               struct bt_ctf_field_type *type,
+               const char *name)
+{
+       int ret = 0;
+
+       if (!event_class || !type || bt_ctf_validate_identifier(name) ||
+               event_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
+               BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(event_class->fields,
+               type, name);
+end:
+       return ret;
+}
+
+int bt_ctf_event_class_get_field_count(
+               struct bt_ctf_event_class *event_class)
+{
+       int ret;
+
+       if (!event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
+               BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_get_field_count(event_class->fields);
+end:
+       return ret;
+}
+
+int bt_ctf_event_class_get_field(struct bt_ctf_event_class *event_class,
+               const char **field_name, struct bt_ctf_field_type **field_type,
+               int index)
+{
+       int ret;
+
+       if (!event_class || index < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
+               BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_get_field(event_class->fields,
+               field_name, field_type, index);
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_event_class_get_field_by_name(
+               struct bt_ctf_event_class *event_class, const char *name)
+{
+       GQuark name_quark;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!event_class || !name) {
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(event_class->fields) !=
+               BT_CTF_TYPE_ID_STRUCT) {
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(name);
+       if (!name_quark) {
+               goto end;
+       }
+
+       /*
+        * No need to increment field_type's reference count since getting it
+        * from the structure already does.
+        */
+       field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+               event_class->fields, name);
+end:
+       return field_type;
+}
+
+struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
+               struct bt_ctf_event_class *event_class)
+{
+       struct bt_ctf_field_type *context_type = NULL;
+
+       if (!event_class || !event_class->context) {
+               goto end;
+       }
+
+       bt_get(event_class->context);
+       context_type = event_class->context;
+end:
+       return context_type;
+}
+
+int bt_ctf_event_class_set_context_type(
+               struct bt_ctf_event_class *event_class,
+               struct bt_ctf_field_type *context)
+{
+       int ret = 0;
+
+       if (!event_class || event_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (context && bt_ctf_field_type_get_type_id(context) !=
+                       BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(event_class->context);
+       event_class->context = bt_get(context);
+end:
+       return ret;
+
+}
+
+void bt_ctf_event_class_get(struct bt_ctf_event_class *event_class)
+{
+       bt_get(event_class);
+}
+
+void bt_ctf_event_class_put(struct bt_ctf_event_class *event_class)
+{
+       bt_put(event_class);
+}
+
+BT_HIDDEN
+int bt_ctf_event_class_set_stream_id(struct bt_ctf_event_class *event_class,
+               uint32_t stream_id)
+{
+       int ret = 0;
+       struct bt_value *obj;
+
+       obj = bt_value_integer_create_init(stream_id);
+
+       if (!obj) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_set_field_value(event_class->attributes,
+               "stream_id", obj);
+
+       if (event_class->frozen) {
+               bt_ctf_attributes_freeze(event_class->attributes);
+       }
+
+end:
+       BT_PUT(obj);
+       return ret;
+}
+
+static
+void bt_ctf_event_class_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_event_class *event_class;
+
+       event_class = container_of(obj, struct bt_ctf_event_class, base);
+       bt_ctf_attributes_destroy(event_class->attributes);
+       bt_put(event_class->context);
+       bt_put(event_class->fields);
+       g_free(event_class);
+}
+
+BT_HIDDEN
+void bt_ctf_event_class_freeze(struct bt_ctf_event_class *event_class)
+{
+       assert(event_class);
+       event_class->frozen = 1;
+       event_class->name = bt_ctf_event_class_get_name(event_class);
+       event_class->id = bt_ctf_event_class_get_id(event_class);
+       bt_ctf_field_type_freeze(event_class->context);
+       bt_ctf_field_type_freeze(event_class->fields);
+       bt_ctf_attributes_freeze(event_class->attributes);
+}
+
+BT_HIDDEN
+int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
+               struct metadata_context *context)
+{
+       int i;
+       int count;
+       int ret = 0;
+       struct bt_value *attr_value = NULL;
+
+       assert(event_class);
+       assert(context);
+
+       context->current_indentation_level = 1;
+       g_string_assign(context->field_name, "");
+       g_string_append(context->string, "event {\n");
+       count = bt_ctf_event_class_get_attribute_count(event_class);
+
+       if (count < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       for (i = 0; i < count; ++i) {
+               const char *attr_name = NULL;
+
+               attr_name = bt_ctf_event_class_get_attribute_name(
+                       event_class, i);
+               attr_value = bt_ctf_event_class_get_attribute_value(
+                       event_class, i);
+
+               if (!attr_name || !attr_value) {
+                       ret = -1;
+                       goto end;
+               }
+
+               switch (bt_value_get_type(attr_value)) {
+               case BT_VALUE_TYPE_INTEGER:
+               {
+                       int64_t value;
+
+                       ret = bt_value_integer_get(attr_value, &value);
+
+                       if (ret) {
+                               goto end;
+                       }
+
+                       g_string_append_printf(context->string,
+                               "\t%s = %" PRId64 ";\n", attr_name, value);
+                       break;
+               }
+
+               case BT_VALUE_TYPE_STRING:
+               {
+                       const char *value;
+
+                       ret = bt_value_string_get(attr_value, &value);
+
+                       if (ret) {
+                               goto end;
+                       }
+
+                       g_string_append_printf(context->string,
+                               "\t%s = \"%s\";\n", attr_name, value);
+                       break;
+               }
+
+               default:
+                       /* should never happen */
+                       assert(false);
+                       break;
+               }
+
+               BT_PUT(attr_value);
+       }
+
+       if (event_class->context) {
+               g_string_append(context->string, "\tcontext := ");
+               ret = bt_ctf_field_type_serialize(event_class->context,
+                       context);
+               if (ret) {
+                       goto end;
+               }
+               g_string_append(context->string, ";\n");
+       }
+
+       if (event_class->fields) {
+               g_string_append(context->string, "\tfields := ");
+               ret = bt_ctf_field_type_serialize(event_class->fields, context);
+               if (ret) {
+                       goto end;
+               }
+               g_string_append(context->string, ";\n");
+       }
+
+       g_string_append(context->string, "};\n\n");
+end:
+       context->current_indentation_level = 0;
+       BT_PUT(attr_value);
+       return ret;
+}
diff --git a/lib/ctf-ir/event.c b/lib/ctf-ir/event.c
new file mode 100644 (file)
index 0000000..80044dd
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+ * 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.
+ */
+
+#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/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-internal.h>
+#include <babeltrace/ctf-ir/validation-internal.h>
+#include <babeltrace/ctf-ir/packet-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/ctf-ir/attributes-internal.h>
+#include <babeltrace/compiler.h>
+
+static
+void bt_ctf_event_destroy(struct bt_object *obj);
+
+struct bt_ctf_event *bt_ctf_event_create(struct bt_ctf_event_class *event_class)
+{
+       int ret;
+       enum bt_ctf_validation_flag validation_flags =
+               BT_CTF_VALIDATION_FLAG_STREAM |
+               BT_CTF_VALIDATION_FLAG_EVENT;
+       struct bt_ctf_event *event = NULL;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_field_type *packet_header_type = NULL;
+       struct bt_ctf_field_type *packet_context_type = NULL;
+       struct bt_ctf_field_type *event_header_type = NULL;
+       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
+       struct bt_ctf_field_type *event_context_type = NULL;
+       struct bt_ctf_field_type *event_payload_type = NULL;
+       struct bt_ctf_field *event_header = NULL;
+       struct bt_ctf_field *stream_event_context = NULL;
+       struct bt_ctf_field *event_context = NULL;
+       struct bt_ctf_field *event_payload = NULL;
+       struct bt_value *environment = NULL;
+       struct bt_ctf_validation_output validation_output = { 0 };
+       int trace_valid = 0;
+
+       if (!event_class) {
+               goto error;
+       }
+
+       stream_class = bt_ctf_event_class_get_stream_class(event_class);
+
+       /*
+        * We disallow the creation of an event if its event class has not been
+        * associated to a stream class.
+        */
+       if (!stream_class) {
+               goto error;
+       }
+
+       /* A stream class should always have an existing event header type */
+       assert(stream_class->event_header_type);
+
+       /* The event class was frozen when added to its stream class */
+       assert(event_class->frozen);
+
+       /* Validate the trace (if any), the stream class, and the event class */
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (trace) {
+               packet_header_type = bt_ctf_trace_get_packet_header_type(trace);
+               trace_valid = trace->valid;
+               assert(trace_valid);
+               environment = trace->environment;
+       }
+
+       packet_context_type = bt_ctf_stream_class_get_packet_context_type(
+               stream_class);
+       event_header_type = bt_ctf_stream_class_get_event_header_type(
+               stream_class);
+       stream_event_ctx_type = bt_ctf_stream_class_get_event_context_type(
+               stream_class);
+       event_context_type = bt_ctf_event_class_get_context_type(event_class);
+       event_payload_type = bt_ctf_event_class_get_payload_type(event_class);
+       ret = bt_ctf_validate_class_types(environment, packet_header_type,
+               packet_context_type, event_header_type, stream_event_ctx_type,
+               event_context_type, event_payload_type, trace_valid,
+               stream_class->valid, event_class->valid,
+               &validation_output, validation_flags);
+       BT_PUT(packet_header_type);
+       BT_PUT(packet_context_type);
+       BT_PUT(event_header_type);
+       BT_PUT(stream_event_ctx_type);
+       BT_PUT(event_context_type);
+       BT_PUT(event_payload_type);
+       if (ret) {
+               /*
+                * This means something went wrong during the validation
+                * process, not that the objects are invalid.
+                */
+               goto error;
+       }
+
+       if ((validation_output.valid_flags & validation_flags) !=
+                       validation_flags) {
+               /* Invalid trace/stream class/event class */
+               goto error;
+       }
+
+       /*
+        * At this point we know the trace (if associated to the stream
+        * class), the stream class, and the event class, with their
+        * current types, are valid. We may proceed with creating
+        * the event.
+        */
+       event = g_new0(struct bt_ctf_event, 1);
+       if (!event) {
+               goto error;
+       }
+
+       bt_object_init(event, bt_ctf_event_destroy);
+
+       /*
+        * event does not share a common ancestor with the event class; it has
+        * to guarantee its existence by holding a reference. This reference
+        * shall be released once the event is associated to a stream since,
+        * from that point, the event and its class will share the same
+        * lifetime.
+        */
+       event->event_class = bt_get(event_class);
+       event->clock_values = g_hash_table_new_full(g_direct_hash,
+                       g_direct_equal, bt_put, bt_put);
+       event_header =
+               bt_ctf_field_create(validation_output.event_header_type);
+       if (!event_header) {
+               goto error;
+       }
+
+       if (validation_output.stream_event_ctx_type) {
+               stream_event_context = bt_ctf_field_create(
+                       validation_output.stream_event_ctx_type);
+               if (!stream_event_context) {
+                       goto error;
+               }
+       }
+
+       if (validation_output.event_context_type) {
+               event_context = bt_ctf_field_create(
+                       validation_output.event_context_type);
+               if (!event_context) {
+                       goto error;
+               }
+       }
+
+       if (validation_output.event_payload_type) {
+               event_payload = bt_ctf_field_create(
+                       validation_output.event_payload_type);
+               if (!event_payload) {
+                       goto error;
+               }
+       }
+
+       /*
+        * At this point all the fields are created, potentially from
+        * validated copies of field types, so that the field types and
+        * fields can be replaced in the trace, stream class,
+        * event class, and created event.
+        */
+       bt_ctf_validation_replace_types(trace, stream_class,
+               event_class, &validation_output, validation_flags);
+       BT_MOVE(event->event_header, event_header);
+       BT_MOVE(event->stream_event_context, stream_event_context);
+       BT_MOVE(event->context_payload, event_context);
+       BT_MOVE(event->fields_payload, event_payload);
+
+       /*
+        * Put what was not moved in bt_ctf_validation_replace_types().
+        */
+       bt_ctf_validation_output_put_types(&validation_output);
+
+       /*
+        * Freeze the stream class since the event header must not be changed
+        * anymore.
+        */
+       bt_ctf_stream_class_freeze(stream_class);
+
+       /*
+        * Mark stream class, and event class as valid since
+        * they're all frozen now.
+        */
+       stream_class->valid = 1;
+       event_class->valid = 1;
+
+       /* Put stuff we borrowed from the event class */
+       BT_PUT(stream_class);
+       BT_PUT(trace);
+
+       return event;
+
+error:
+       bt_ctf_validation_output_put_types(&validation_output);
+       BT_PUT(event);
+       BT_PUT(stream_class);
+       BT_PUT(trace);
+       BT_PUT(event_header);
+       BT_PUT(stream_event_context);
+       BT_PUT(event_context);
+       BT_PUT(event_payload);
+       assert(!packet_header_type);
+       assert(!packet_context_type);
+       assert(!event_header_type);
+       assert(!stream_event_ctx_type);
+       assert(!event_context_type);
+       assert(!event_payload_type);
+
+       return event;
+}
+
+struct bt_ctf_event_class *bt_ctf_event_get_class(struct bt_ctf_event *event)
+{
+       struct bt_ctf_event_class *event_class = NULL;
+
+       if (!event) {
+               goto end;
+       }
+
+       event_class = event ? bt_get(bt_ctf_event_borrow_event_class(event)) :
+               NULL;
+end:
+       return event_class;
+}
+
+struct bt_ctf_stream *bt_ctf_event_get_stream(struct bt_ctf_event *event)
+{
+       struct bt_ctf_stream *stream = NULL;
+
+       if (!event) {
+               goto end;
+       }
+
+       /*
+        * If the event has a parent, then this is its (writer) stream.
+        * If the event has no parent, then if it has a packet, this
+        * is its (non-writer) stream.
+        */
+       if (event->base.parent) {
+               stream = (struct bt_ctf_stream *) bt_object_get_parent(event);
+       } else {
+               if (event->packet) {
+                       stream = bt_get(event->packet->stream);
+               }
+       }
+
+end:
+       return stream;
+}
+
+int bt_ctf_event_set_payload(struct bt_ctf_event *event,
+               const char *name,
+               struct bt_ctf_field *payload)
+{
+       int ret = 0;
+
+       if (!event || !payload || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (name) {
+               ret = bt_ctf_field_structure_set_field(event->fields_payload,
+                       name, payload);
+       } else {
+               struct bt_ctf_field_type *payload_type;
+
+               payload_type = bt_ctf_field_get_type(payload);
+
+               if (bt_ctf_field_type_compare(payload_type,
+                               event->event_class->fields) == 0) {
+                       bt_put(event->fields_payload);
+                       bt_get(payload);
+                       event->fields_payload = payload;
+               } else {
+                       ret = -1;
+               }
+
+               bt_put(payload_type);
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_payload_field(struct bt_ctf_event *event)
+{
+       struct bt_ctf_field *payload = NULL;
+
+       if (!event || !event->fields_payload) {
+               goto end;
+       }
+
+       payload = event->fields_payload;
+       bt_get(payload);
+end:
+       return payload;
+}
+
+int bt_ctf_event_set_payload_field(struct bt_ctf_event *event,
+               struct bt_ctf_field *payload)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *payload_type = NULL;
+
+       if (!event || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       payload_type = bt_ctf_field_get_type(payload);
+       if (!payload_type) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(payload_type) !=
+                       BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(event->fields_payload);
+       event->fields_payload = bt_get(payload);
+end:
+       bt_put(payload_type);
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_payload(struct bt_ctf_event *event,
+               const char *name)
+{
+       struct bt_ctf_field *field = NULL;
+
+       if (!event) {
+               goto end;
+       }
+
+       if (name) {
+               field = bt_ctf_field_structure_get_field(event->fields_payload,
+                       name);
+       } else {
+               field = event->fields_payload;
+               bt_get(field);
+       }
+end:
+       return field;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_payload_by_index(
+               struct bt_ctf_event *event, int index)
+{
+       struct bt_ctf_field *field = NULL;
+
+       if (!event || index < 0) {
+               goto end;
+       }
+
+       field = bt_ctf_field_structure_get_field_by_index(event->fields_payload,
+               index);
+end:
+       return field;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_header(
+               struct bt_ctf_event *event)
+{
+       struct bt_ctf_field *header = NULL;
+
+       if (!event || !event->event_header) {
+               goto end;
+       }
+
+       header = event->event_header;
+       bt_get(header);
+end:
+       return header;
+}
+
+int bt_ctf_event_set_header(struct bt_ctf_event *event,
+               struct bt_ctf_field *header)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (!event || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       stream_class = (struct bt_ctf_stream_class *) bt_object_get_parent(
+                       event->event_class);
+       /*
+        * Ensure the provided header's type matches the one registered to the
+        * stream class.
+        */
+       field_type = bt_ctf_field_get_type(header);
+       if (bt_ctf_field_type_compare(field_type,
+                       stream_class->event_header_type)) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(event->event_header);
+       event->event_header = bt_get(header);
+end:
+       bt_put(stream_class);
+       bt_put(field_type);
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_event_context(
+               struct bt_ctf_event *event)
+{
+       struct bt_ctf_field *context = NULL;
+
+       if (!event || !event->context_payload) {
+               goto end;
+       }
+
+       context = event->context_payload;
+       bt_get(context);
+end:
+       return context;
+}
+
+int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
+               struct bt_ctf_field *context)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!event || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       field_type = bt_ctf_field_get_type(context);
+       if (bt_ctf_field_type_compare(field_type,
+                       event->event_class->context)) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(event->context_payload);
+       event->context_payload = bt_get(context);
+end:
+       bt_put(field_type);
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_event_get_stream_event_context(
+               struct bt_ctf_event *event)
+{
+       struct bt_ctf_field *stream_event_context = NULL;
+
+       if (!event || !event->stream_event_context) {
+               goto end;
+       }
+
+       stream_event_context = event->stream_event_context;
+end:
+       return bt_get(stream_event_context);
+}
+
+int bt_ctf_event_set_stream_event_context(struct bt_ctf_event *event,
+               struct bt_ctf_field *stream_event_context)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (!event || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
+       /*
+        * We should not have been able to create the event without associating
+        * the event class to a stream class.
+        */
+       assert(stream_class);
+
+       field_type = bt_ctf_field_get_type(stream_event_context);
+       if (bt_ctf_field_type_compare(field_type,
+                       stream_class->event_context_type)) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_get(stream_event_context);
+       BT_MOVE(event->stream_event_context, stream_event_context);
+end:
+       BT_PUT(stream_class);
+       bt_put(field_type);
+       return ret;
+}
+
+void bt_ctf_event_get(struct bt_ctf_event *event)
+{
+       bt_get(event);
+}
+
+void bt_ctf_event_put(struct bt_ctf_event *event)
+{
+       bt_put(event);
+}
+
+void bt_ctf_event_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_event *event;
+
+       event = container_of(obj, struct bt_ctf_event, base);
+       if (!event->base.parent) {
+               /*
+                * Event was keeping a reference to its class since it shared no
+                * common ancestor with it to guarantee they would both have the
+                * same lifetime.
+                */
+               bt_put(event->event_class);
+       }
+       g_hash_table_destroy(event->clock_values);
+       bt_put(event->event_header);
+       bt_put(event->stream_event_context);
+       bt_put(event->context_payload);
+       bt_put(event->fields_payload);
+       bt_put(event->packet);
+       g_free(event);
+}
+
+struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
+               struct bt_ctf_event *event, struct bt_ctf_clock_class *clock_class)
+{
+       struct bt_ctf_clock_value *clock_value = NULL;
+
+       if (!event || !clock_class) {
+               goto end;
+       }
+
+       clock_value = g_hash_table_lookup(event->clock_values, clock_class);
+       if (!clock_value) {
+               goto end;
+       }
+
+       bt_get(clock_value);
+end:
+       return clock_value;
+}
+
+int bt_ctf_event_set_clock_value(struct bt_ctf_event *event,
+               struct bt_ctf_clock_value *value)
+{
+       int ret = 0;
+
+       if (!event || !value || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       g_hash_table_insert(event->clock_values,
+               bt_ctf_clock_value_get_class(value), bt_get(value));
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_event_validate(struct bt_ctf_event *event)
+{
+       /* Make sure each field's payload has been set */
+       int ret;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       assert(event);
+       ret = bt_ctf_field_validate(event->event_header);
+       if (ret) {
+               goto end;
+       }
+
+       stream_class = bt_ctf_event_class_get_stream_class(event->event_class);
+       /*
+        * We should not have been able to create the event without associating
+        * the event class to a stream class.
+        */
+       assert(stream_class);
+       if (stream_class->event_context_type) {
+               ret = bt_ctf_field_validate(event->stream_event_context);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       ret = bt_ctf_field_validate(event->fields_payload);
+       if (ret) {
+               goto end;
+       }
+
+       if (event->event_class->context) {
+               ret = bt_ctf_field_validate(event->context_payload);
+       }
+end:
+       bt_put(stream_class);
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_event_serialize(struct bt_ctf_event *event,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       int ret = 0;
+
+       assert(event);
+       assert(pos);
+
+       if (event->context_payload) {
+               ret = bt_ctf_field_serialize(event->context_payload, pos,
+                       native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       if (event->fields_payload) {
+               ret = bt_ctf_field_serialize(event->fields_payload, pos,
+                       native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_packet *bt_ctf_event_get_packet(struct bt_ctf_event *event)
+{
+       struct bt_ctf_packet *packet = NULL;
+
+       if (!event || !event->packet) {
+               goto end;
+       }
+
+       packet = bt_get(event->packet);
+end:
+       return packet;
+}
+
+int bt_ctf_event_set_packet(struct bt_ctf_event *event,
+               struct bt_ctf_packet *packet)
+{
+       struct bt_ctf_stream_class *event_stream_class = NULL;
+       struct bt_ctf_stream_class *packet_stream_class = NULL;
+       struct bt_ctf_stream *stream = NULL;
+       int ret = 0;
+
+       if (!event || !packet || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * Make sure the new packet was created by this event's
+        * stream, if it is set.
+        */
+       stream = bt_ctf_event_get_stream(event);
+       if (stream) {
+               if (packet->stream != stream) {
+                       ret = -1;
+                       goto end;
+               }
+       } else {
+               event_stream_class =
+                       bt_ctf_event_class_get_stream_class(event->event_class);
+               packet_stream_class =
+                       bt_ctf_stream_get_class(packet->stream);
+
+               assert(event_stream_class);
+               assert(packet_stream_class);
+
+               if (event_stream_class != packet_stream_class) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       bt_get(packet);
+       BT_MOVE(event->packet, packet);
+
+end:
+       BT_PUT(stream);
+       BT_PUT(event_stream_class);
+       BT_PUT(packet_stream_class);
+
+       return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_event_freeze(struct bt_ctf_event *event)
+{
+       assert(event);
+       bt_ctf_packet_freeze(event->packet);
+       bt_ctf_field_freeze(event->event_header);
+       bt_ctf_field_freeze(event->stream_event_context);
+       bt_ctf_field_freeze(event->context_payload);
+       bt_ctf_field_freeze(event->fields_payload);
+       event->frozen = 1;
+}
diff --git a/lib/ctf-ir/field-path.c b/lib/ctf-ir/field-path.c
new file mode 100644 (file)
index 0000000..6c0b248
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-ir/field-path-internal.h>
+#include <babeltrace/ctf-ir/field-path.h>
+#include <limits.h>
+#include <glib.h>
+
+static
+void field_path_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_field_path *field_path = (struct bt_ctf_field_path *) obj;
+
+       if (!field_path) {
+               return;
+       }
+
+       if (field_path->indexes) {
+               g_array_free(field_path->indexes, TRUE);
+       }
+       g_free(field_path);
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_create(void)
+{
+       struct bt_ctf_field_path *field_path = NULL;
+
+       field_path = g_new0(struct bt_ctf_field_path, 1);
+       if (!field_path) {
+               goto error;
+       }
+
+       bt_object_init(field_path, field_path_destroy);
+       field_path->root = BT_CTF_SCOPE_UNKNOWN;
+       field_path->indexes = g_array_new(TRUE, FALSE, sizeof(int));
+       if (!field_path->indexes) {
+               goto error;
+       }
+
+       return field_path;
+
+error:
+       BT_PUT(field_path);
+       return NULL;
+}
+
+BT_HIDDEN
+void bt_ctf_field_path_clear(struct bt_ctf_field_path *field_path)
+{
+       if (field_path->indexes->len > 0) {
+               g_array_remove_range(field_path->indexes, 0,
+                       field_path->indexes->len);
+       }
+}
+
+BT_HIDDEN
+struct bt_ctf_field_path *bt_ctf_field_path_copy(
+               struct bt_ctf_field_path *path)
+{
+       struct bt_ctf_field_path *new_path = bt_ctf_field_path_create();
+
+       if (!new_path) {
+               goto end;
+       }
+
+       new_path->root = path->root;
+       g_array_insert_vals(new_path->indexes, 0,
+               path->indexes->data, path->indexes->len);
+end:
+       return new_path;
+}
+
+enum bt_ctf_scope bt_ctf_field_path_get_root_scope(
+               const struct bt_ctf_field_path *field_path)
+{
+       enum bt_ctf_scope scope = BT_CTF_SCOPE_UNKNOWN;
+
+       if (!field_path) {
+               goto end;
+       }
+
+       scope = field_path->root;
+
+end:
+       return scope;
+}
+
+int bt_ctf_field_path_get_index_count(
+               const struct bt_ctf_field_path *field_path)
+{
+       int ret = -1;
+
+       if (!field_path) {
+               goto end;
+       }
+
+       ret = field_path->indexes->len;
+
+end:
+       return ret;
+}
+
+int bt_ctf_field_path_get_index(const struct bt_ctf_field_path *field_path,
+               int index)
+{
+       int ret = INT_MIN;
+
+       if (!field_path || index < 0) {
+               goto end;
+       }
+
+       if (index >= field_path->indexes->len) {
+               goto end;
+       }
+
+       ret = g_array_index(field_path->indexes, int, index);
+
+end:
+       return ret;
+}
diff --git a/lib/ctf-ir/field-types.c b/lib/ctf-ir/field-types.c
new file mode 100644 (file)
index 0000000..2845982
--- /dev/null
@@ -0,0 +1,4191 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/field-path-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/clock-class-internal.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/endian.h>
+#include <float.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+struct range_overlap_query {
+       union {
+               uint64_t _unsigned;
+               int64_t _signed;
+       } range_start;
+
+       union {
+               uint64_t _unsigned;
+               int64_t _signed;
+       } range_end;
+       int overlaps;
+       GQuark mapping_name;
+};
+
+static
+void bt_ctf_field_type_destroy(struct bt_object *);
+static
+void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *);
+
+static
+void (* const type_destroy_funcs[])(struct bt_ctf_field_type *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_destroy,
+       [BT_CTF_TYPE_ID_ENUM] =
+               bt_ctf_field_type_enumeration_destroy,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_type_floating_point_destroy,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_destroy,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_destroy,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_destroy,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_destroy,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_destroy,
+};
+
+static
+void generic_field_type_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *);
+static
+void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *);
+
+static
+type_freeze_func const type_freeze_funcs[] = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_freeze,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_freeze,
+       [BT_CTF_TYPE_ID_FLOAT] = generic_field_type_freeze,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_freeze,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_freeze,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_freeze,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_freeze,
+       [BT_CTF_TYPE_ID_STRING] = generic_field_type_freeze,
+};
+
+static
+int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_floating_point_serialize(
+               struct bt_ctf_field_type *, struct metadata_context *);
+static
+int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+static
+int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *,
+               struct metadata_context *);
+
+static
+type_serialize_func const type_serialize_funcs[] = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_serialize,
+       [BT_CTF_TYPE_ID_ENUM] =
+               bt_ctf_field_type_enumeration_serialize,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_type_floating_point_serialize,
+       [BT_CTF_TYPE_ID_STRUCT] =
+               bt_ctf_field_type_structure_serialize,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_serialize,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_serialize,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_serialize,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_serialize,
+};
+
+static
+void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_enumeration_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_floating_point_set_byte_order(
+               struct bt_ctf_field_type *, enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order byte_order);
+
+static
+void (* const set_byte_order_funcs[])(struct bt_ctf_field_type *,
+               enum bt_ctf_byte_order) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_set_byte_order,
+       [BT_CTF_TYPE_ID_ENUM] =
+               bt_ctf_field_type_enumeration_set_byte_order,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_type_floating_point_set_byte_order,
+       [BT_CTF_TYPE_ID_STRUCT] =
+               bt_ctf_field_type_structure_set_byte_order,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_set_byte_order,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_set_byte_order,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_set_byte_order,
+       [BT_CTF_TYPE_ID_STRING] = NULL,
+};
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
+               struct bt_ctf_field_type *);
+
+static
+struct bt_ctf_field_type *(* const type_copy_funcs[])(
+               struct bt_ctf_field_type *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_copy,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_copy,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_copy,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_copy,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_copy,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_copy,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_copy,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_copy,
+};
+
+static
+int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *);
+
+static
+int (* const type_compare_funcs[])(struct bt_ctf_field_type *,
+               struct bt_ctf_field_type *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_compare,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_compare,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_type_floating_point_compare,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_compare,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_compare,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_compare,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_compare,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_type_string_compare,
+};
+
+static
+int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *);
+static
+int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *);
+
+static
+int (* const type_validate_funcs[])(struct bt_ctf_field_type *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_type_integer_validate,
+       [BT_CTF_TYPE_ID_FLOAT] = NULL,
+       [BT_CTF_TYPE_ID_STRING] = NULL,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_type_enumeration_validate,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_type_structure_validate,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_type_variant_validate,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_type_array_validate,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_type_sequence_validate,
+};
+
+static
+void destroy_enumeration_mapping(struct enumeration_mapping *mapping)
+{
+       g_free(mapping);
+}
+
+static
+void destroy_structure_field(struct structure_field *field)
+{
+       bt_put(field->type);
+       g_free(field);
+}
+
+static
+void check_ranges_overlap(gpointer element, gpointer query)
+{
+       struct enumeration_mapping *mapping = element;
+       struct range_overlap_query *overlap_query = query;
+
+       if (mapping->range_start._signed <= overlap_query->range_end._signed
+               && overlap_query->range_start._signed <=
+               mapping->range_end._signed) {
+               overlap_query->overlaps = 1;
+               overlap_query->mapping_name = mapping->string;
+       }
+
+       overlap_query->overlaps |=
+               mapping->string == overlap_query->mapping_name;
+}
+
+static
+void check_ranges_overlap_unsigned(gpointer element, gpointer query)
+{
+       struct enumeration_mapping *mapping = element;
+       struct range_overlap_query *overlap_query = query;
+
+       if (mapping->range_start._unsigned <= overlap_query->range_end._unsigned
+               && overlap_query->range_start._unsigned <=
+               mapping->range_end._unsigned) {
+               overlap_query->overlaps = 1;
+               overlap_query->mapping_name = mapping->string;
+       }
+
+       overlap_query->overlaps |=
+               mapping->string == overlap_query->mapping_name;
+}
+
+static
+gint compare_enumeration_mappings_signed(struct enumeration_mapping **a,
+               struct enumeration_mapping **b)
+{
+       return ((*a)->range_start._signed < (*b)->range_start._signed) ? -1 : 1;
+}
+
+static
+gint compare_enumeration_mappings_unsigned(struct enumeration_mapping **a,
+               struct enumeration_mapping **b)
+{
+       return ((*a)->range_start._unsigned < (*b)->range_start._unsigned) ? -1 : 1;
+}
+
+static
+void bt_ctf_field_type_init(struct bt_ctf_field_type *type, bool init_bo)
+{
+       assert(type && (type->id > BT_CTF_TYPE_ID_UNKNOWN) &&
+               (type->id < BT_CTF_NR_TYPE_IDS));
+
+       bt_object_init(type, bt_ctf_field_type_destroy);
+       type->freeze = type_freeze_funcs[type->id];
+       type->serialize = type_serialize_funcs[type->id];
+
+       if (init_bo) {
+               int ret = bt_ctf_field_type_set_byte_order(type,
+                       BT_CTF_BYTE_ORDER_NATIVE);
+               assert(ret == 0);
+       }
+
+       type->alignment = 1;
+}
+
+static
+int add_structure_field(GPtrArray *fields,
+               GHashTable *field_name_to_index,
+               struct bt_ctf_field_type *field_type,
+               const char *field_name)
+{
+       int ret = 0;
+       GQuark name_quark = g_quark_from_string(field_name);
+       struct structure_field *field;
+
+       /* Make sure structure does not contain a field of the same name */
+       if (g_hash_table_lookup_extended(field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, NULL)) {
+               ret = -1;
+               goto end;
+       }
+
+       field = g_new0(struct structure_field, 1);
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_get(field_type);
+       field->name = name_quark;
+       field->type = field_type;
+       g_hash_table_insert(field_name_to_index,
+               GUINT_TO_POINTER(name_quark),
+               GUINT_TO_POINTER(fields->len));
+       g_ptr_array_add(fields, field);
+end:
+       return ret;
+}
+
+static
+void bt_ctf_field_type_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_field_type *type;
+       enum bt_ctf_type_id type_id;
+
+       type = container_of(obj, struct bt_ctf_field_type, base);
+       type_id = type->id;
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
+               type_id >= BT_CTF_NR_TYPE_IDS) {
+               return;
+       }
+
+       type_destroy_funcs[type_id](type);
+}
+
+static
+int bt_ctf_field_type_integer_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+
+       struct bt_ctf_field_type_integer *integer =
+               container_of(type, struct bt_ctf_field_type_integer,
+                       parent);
+
+       if (integer->mapped_clock && integer->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+static
+struct enumeration_mapping *get_enumeration_mapping(
+               struct bt_ctf_field_type *type, int index)
+{
+       struct enumeration_mapping *mapping = NULL;
+       struct bt_ctf_field_type_enumeration *enumeration;
+
+       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+               parent);
+       if (index >= enumeration->entries->len) {
+               goto end;
+       }
+
+       mapping = g_ptr_array_index(enumeration->entries, index);
+end:
+       return mapping;
+}
+
+/*
+ * Note: This algorithm is O(n^2) vs number of enumeration mappings.
+ * Only used when freezing an enumeration.
+ */
+static
+void set_enumeration_range_overlap(
+               struct bt_ctf_field_type *type)
+{
+       int i, j, len;
+       struct bt_ctf_field_type *container_type;
+       struct bt_ctf_field_type_enumeration *enumeration_type;
+       int is_signed;
+
+       enumeration_type = container_of(type,
+                       struct bt_ctf_field_type_enumeration, parent);
+
+       len = enumeration_type->entries->len;
+       container_type = enumeration_type->container;
+       is_signed = bt_ctf_field_type_integer_get_signed(container_type);
+
+       for (i = 0; i < len; i++) {
+               for (j = i + 1; j < len; j++) {
+                       struct enumeration_mapping *mapping[2];
+
+                       mapping[0] = get_enumeration_mapping(type, i);
+                       mapping[1] = get_enumeration_mapping(type, j);
+                       if (is_signed) {
+                               if (mapping[0]->range_start._signed
+                                                       <= mapping[1]->range_end._signed
+                                               && mapping[0]->range_end._signed
+                                                       >= mapping[1]->range_start._signed) {
+                                       enumeration_type->has_overlapping_ranges = true;
+                                       return;
+                               }
+                       } else {
+                               if (mapping[0]->range_start._unsigned
+                                                       <= mapping[1]->range_end._unsigned
+                                               && mapping[0]->range_end._unsigned
+                                                       >= mapping[1]->range_start._unsigned) {
+                                       enumeration_type->has_overlapping_ranges = true;
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+
+static
+int bt_ctf_field_type_enumeration_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+
+       struct bt_ctf_field_type_enumeration *enumeration =
+               container_of(type, struct bt_ctf_field_type_enumeration,
+                       parent);
+       struct bt_ctf_field_type *container_type =
+               bt_ctf_field_type_enumeration_get_container_type(type);
+
+       if (!container_type) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_validate(container_type);
+       if (ret) {
+               goto end;
+       }
+
+       /* Ensure enum has entries */
+       ret = enumeration->entries->len ? 0 : -1;
+
+end:
+       BT_PUT(container_type);
+       return ret;
+}
+
+static
+int bt_ctf_field_type_sequence_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *element_type = NULL;
+       struct bt_ctf_field_type_sequence *sequence =
+               container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+
+       /* Length field name should be set at this point */
+       if (sequence->length_field_name->len == 0) {
+               ret = -1;
+               goto end;
+       }
+
+       element_type = bt_ctf_field_type_sequence_get_element_type(type);
+       if (!element_type) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_validate(element_type);
+
+end:
+       BT_PUT(element_type);
+
+       return ret;
+}
+
+static
+int bt_ctf_field_type_array_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *element_type = NULL;
+
+       element_type = bt_ctf_field_type_array_get_element_type(type);
+       if (!element_type) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_validate(element_type);
+
+end:
+       BT_PUT(element_type);
+
+       return ret;
+}
+
+static
+int bt_ctf_field_type_structure_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *child_type = NULL;
+       int field_count = bt_ctf_field_type_structure_get_field_count(type);
+       int i;
+
+       if (field_count < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       for (i = 0; i < field_count; ++i) {
+               ret = bt_ctf_field_type_structure_get_field(type,
+                       NULL, &child_type, i);
+               if (ret) {
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_validate(child_type);
+               if (ret) {
+                       goto end;
+               }
+
+               BT_PUT(child_type);
+       }
+
+end:
+       BT_PUT(child_type);
+
+       return ret;
+}
+
+static
+bool bt_ctf_field_type_enumeration_has_overlapping_ranges(
+               struct bt_ctf_field_type_enumeration *enumeration_type)
+{
+       if (!enumeration_type->parent.frozen) {
+               set_enumeration_range_overlap(&enumeration_type->parent);
+       }
+       return enumeration_type->has_overlapping_ranges;
+}
+
+static
+int bt_ctf_field_type_enumeration_get_mapping_name(
+               struct bt_ctf_field_type *enum_field_type,
+               int index,
+               const char **mapping_name)
+{
+       int ret = 0;
+       struct enumeration_mapping *mapping;
+
+       if (!enum_field_type || index < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       mapping = get_enumeration_mapping(enum_field_type, index);
+       if (!mapping) {
+               ret = -1;
+               goto end;
+       }
+
+       if (mapping_name) {
+               *mapping_name = g_quark_to_string(mapping->string);
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_variant_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       int field_count;
+       struct bt_ctf_field_type *child_type = NULL;
+       struct bt_ctf_field_type_variant *variant =
+               container_of(type, struct bt_ctf_field_type_variant,
+                       parent);
+       int i;
+       int tag_mappings_count;
+
+       if (variant->tag_name->len == 0 || !variant->tag) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_enumeration_has_overlapping_ranges(
+                       variant->tag)) {
+               ret = -1;
+               goto end;
+       }
+
+       tag_mappings_count =
+               bt_ctf_field_type_enumeration_get_mapping_count(
+                       (struct bt_ctf_field_type *) variant->tag);
+
+       if (tag_mappings_count != variant->fields->len) {
+               ret = -1;
+               goto end;
+       }
+
+       for (i = 0; i < tag_mappings_count; ++i) {
+               const char *label;
+               struct bt_ctf_field_type *ft;
+
+               ret = bt_ctf_field_type_enumeration_get_mapping_name(
+                       (struct bt_ctf_field_type *) variant->tag,
+                       i, &label);
+               if (ret) {
+                       goto end;
+               }
+               if (!label) {
+                       ret = -1;
+                       goto end;
+               }
+
+               ft = bt_ctf_field_type_variant_get_field_type_by_name(
+                       type, label);
+               if (!ft) {
+                       ret = -1;
+                       goto end;
+               }
+
+               BT_PUT(ft);
+       }
+
+       field_count = bt_ctf_field_type_variant_get_field_count(type);
+       if (field_count < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       for (i = 0; i < field_count; ++i) {
+               ret = bt_ctf_field_type_variant_get_field(type,
+                       NULL, &child_type, i);
+               if (ret) {
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_validate(child_type);
+               if (ret) {
+                       goto end;
+               }
+
+               BT_PUT(child_type);
+       }
+
+end:
+       BT_PUT(child_type);
+
+       return ret;
+}
+
+/*
+ * This function validates a given field type without considering
+ * where this field type is located. It only validates the properties
+ * of the given field type and the properties of its children if
+ * applicable.
+ */
+BT_HIDDEN
+int bt_ctf_field_type_validate(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       enum bt_ctf_type_id id = bt_ctf_field_type_get_type_id(type);
+
+       if (!type) {
+               ret = -1;
+               goto end;
+       }
+
+       if (type->valid) {
+               /* Already marked as valid */
+               goto end;
+       }
+
+       if (type_validate_funcs[id]) {
+               ret = type_validate_funcs[id](type);
+       }
+
+       if (!ret && type->frozen) {
+               /* Field type is valid */
+               type->valid = 1;
+       }
+
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_integer_create(unsigned int size)
+{
+       struct bt_ctf_field_type_integer *integer =
+               g_new0(struct bt_ctf_field_type_integer, 1);
+
+       if (!integer || size == 0 || size > 64) {
+               return NULL;
+       }
+
+       integer->parent.id = BT_CTF_TYPE_ID_INTEGER;
+       integer->size = size;
+       integer->base = BT_CTF_INTEGER_BASE_DECIMAL;
+       integer->encoding = BT_CTF_STRING_ENCODING_NONE;
+       bt_ctf_field_type_init(&integer->parent, TRUE);
+       return &integer->parent;
+}
+
+int bt_ctf_field_type_integer_get_size(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->id != BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       ret = (int) integer->size;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_integer_get_signed(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->id != BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       ret = integer->is_signed;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_integer_set_signed(struct bt_ctf_field_type *type,
+               int is_signed)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->frozen ||
+               type->id != BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       integer->is_signed = !!is_signed;
+end:
+       return ret;
+}
+
+enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
+               struct bt_ctf_field_type *type)
+{
+       enum bt_ctf_integer_base ret = BT_CTF_INTEGER_BASE_UNKNOWN;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->id != BT_CTF_TYPE_ID_INTEGER) {
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       ret = integer->base;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_integer_set_base(struct bt_ctf_field_type *type,
+               enum bt_ctf_integer_base base)
+{
+       int ret = 0;
+
+       if (!type || type->frozen ||
+               type->id != BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       switch (base) {
+       case BT_CTF_INTEGER_BASE_BINARY:
+       case BT_CTF_INTEGER_BASE_OCTAL:
+       case BT_CTF_INTEGER_BASE_DECIMAL:
+       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+       {
+               struct bt_ctf_field_type_integer *integer = container_of(type,
+                       struct bt_ctf_field_type_integer, parent);
+               integer->base = base;
+               break;
+       }
+       default:
+               ret = -1;
+       }
+end:
+       return ret;
+}
+
+enum bt_ctf_string_encoding bt_ctf_field_type_integer_get_encoding(
+               struct bt_ctf_field_type *type)
+{
+       enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->id != BT_CTF_TYPE_ID_INTEGER) {
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       ret = integer->encoding;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_integer_set_encoding(struct bt_ctf_field_type *type,
+               enum bt_ctf_string_encoding encoding)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_integer *integer;
+
+       if (!type || type->frozen ||
+               (type->id != BT_CTF_TYPE_ID_INTEGER) ||
+               (encoding < BT_CTF_STRING_ENCODING_NONE) ||
+               (encoding >= BT_CTF_STRING_ENCODING_UNKNOWN)) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       integer->encoding = encoding;
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *bt_ctf_field_type_integer_get_mapped_clock_class(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_integer *integer;
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!type) {
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       clock_class = integer->mapped_clock;
+       bt_get(clock_class);
+end:
+       return clock_class;
+}
+
+int bt_ctf_field_type_integer_set_mapped_clock_class(
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_clock_class *clock_class)
+{
+       struct bt_ctf_field_type_integer *integer;
+       int ret = 0;
+
+       if (!type || type->frozen || !bt_ctf_clock_class_is_valid(clock_class)) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       bt_put(integer->mapped_clock);
+       integer->mapped_clock = bt_get(clock_class);
+end:
+       return ret;
+}
+
+static
+void bt_ctf_field_type_enum_iter_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter =
+               container_of(obj,
+                       struct bt_ctf_field_type_enumeration_mapping_iterator,
+                       base);
+
+       bt_put(&iter->enumeration_type->parent);
+       g_free(iter);
+}
+
+static
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_type(
+               struct bt_ctf_field_type *type,
+               enum bt_ctf_field_type_enumeration_mapping_iterator_type iterator_type)
+{
+       struct bt_ctf_field_type_enumeration *enumeration_type;
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ENUM)) {
+               goto end;
+       }
+
+       enumeration_type = container_of(type,
+               struct bt_ctf_field_type_enumeration, parent);
+       iter = g_new0(struct bt_ctf_field_type_enumeration_mapping_iterator, 1);
+       if (!iter) {
+               goto end;
+       }
+
+       bt_object_init(&iter->base, bt_ctf_field_type_enum_iter_destroy);
+       bt_get(type);
+       iter->enumeration_type = enumeration_type;
+       iter->index = -1;
+       iter->type = iterator_type;
+end:
+       return iter;
+}
+
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_name(
+               struct bt_ctf_field_type *type, const char *name)
+{
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+       iter = bt_ctf_field_type_enumeration_find_mappings_type(
+                       type, ITERATOR_BY_NAME);
+       if (!iter) {
+               goto error;
+       }
+
+       iter->u.name_quark = g_quark_try_string(name);
+       if (!iter->u.name_quark) {
+               goto error;
+       }
+
+       /* Advance iterator to first entry, or leave index at -1. */
+       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
+               /* No entry found. */
+               goto error;
+       }
+
+       return iter;
+error:
+       bt_put(iter);
+       return NULL;
+}
+
+int bt_ctf_field_type_enumeration_mapping_iterator_next(
+               struct bt_ctf_field_type_enumeration_mapping_iterator *iter)
+{
+       struct bt_ctf_field_type_enumeration *enumeration;
+       struct bt_ctf_field_type *type;
+       int i, ret = 0, len;
+
+       enumeration = iter->enumeration_type;
+       type = &enumeration->parent;
+       len = enumeration->entries->len;
+       for (i = iter->index + 1; i < len; i++) {
+               struct enumeration_mapping *mapping =
+                       get_enumeration_mapping(type, i);
+
+               switch (iter->type) {
+               case ITERATOR_BY_NAME:
+                       if (mapping->string == iter->u.name_quark) {
+                               iter->index = i;
+                               goto end;
+                       }
+                       break;
+               case ITERATOR_BY_SIGNED_VALUE:
+               {
+                       int64_t value = iter->u.signed_value;
+
+                       if (value >= mapping->range_start._signed &&
+                                       value <= mapping->range_end._signed) {
+                               iter->index = i;
+                               goto end;
+                       }
+                       break;
+               }
+               case ITERATOR_BY_UNSIGNED_VALUE:
+               {
+                       uint64_t value = iter->u.unsigned_value;
+
+                       if (value >= mapping->range_start._unsigned &&
+                                       value <= mapping->range_end._unsigned) {
+                               iter->index = i;
+                               goto end;
+                       }
+                       break;
+               }
+               default:
+                       abort();
+               }
+       }
+
+       ret = -1;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
+               struct bt_ctf_field_type *type, int64_t value)
+{
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+       iter = bt_ctf_field_type_enumeration_find_mappings_type(
+                       type, ITERATOR_BY_SIGNED_VALUE);
+       if (!iter) {
+               goto error;
+       }
+
+       if (bt_ctf_field_type_integer_get_signed(
+                       iter->enumeration_type->container) != 1) {
+               goto error;
+       }
+       iter->u.signed_value = value;
+
+       /* Advance iterator to first entry, or leave index at -1. */
+       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
+               /* No entry found. */
+               goto error;
+       }
+
+       return iter;
+error:
+       bt_put(iter);
+       return NULL;
+}
+
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
+               struct bt_ctf_field_type *type, uint64_t value)
+{
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter;
+
+       iter = bt_ctf_field_type_enumeration_find_mappings_type(
+                       type, ITERATOR_BY_UNSIGNED_VALUE);
+       if (!iter) {
+               goto error;
+       }
+
+       if (bt_ctf_field_type_integer_get_signed(
+                       iter->enumeration_type->container) != 0) {
+               goto error;
+       }
+       iter->u.unsigned_value = value;
+
+       /* Advance iterator to first entry, or leave index at -1. */
+       if (bt_ctf_field_type_enumeration_mapping_iterator_next(iter)) {
+               /* No entry found. */
+               goto error;
+       }
+
+       return iter;
+error:
+       bt_put(iter);
+       return NULL;
+}
+
+int bt_ctf_field_type_enumeration_mapping_iterator_get_signed(
+               struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+               const char **mapping_name, int64_t *range_begin,
+               int64_t *range_end)
+{
+       int ret = 0;
+
+       if (!iter) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_enumeration_get_mapping_signed(
+                       &iter->enumeration_type->parent, iter->index,
+                       mapping_name, range_begin, range_end);
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
+               struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
+               const char **mapping_name, uint64_t *range_begin,
+               uint64_t *range_end)
+{
+       int ret = 0;
+
+       if (!iter) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_enumeration_get_mapping_unsigned(
+                       &iter->enumeration_type->parent, iter->index,
+                       mapping_name, range_begin, range_end);
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_enumeration_get_mapping_signed(
+               struct bt_ctf_field_type *enum_field_type,
+               int index,
+               const char **mapping_name, int64_t *range_begin,
+               int64_t *range_end)
+{
+       int ret = 0;
+       struct enumeration_mapping *mapping;
+
+       if (!enum_field_type || index < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       mapping = get_enumeration_mapping(enum_field_type, index);
+       if (!mapping) {
+               ret = -1;
+               goto end;
+       }
+
+       if (mapping_name) {
+               *mapping_name = g_quark_to_string(mapping->string);
+       }
+
+       if (range_begin) {
+               *range_begin = mapping->range_start._signed;
+       }
+
+       if (range_end) {
+               *range_end = mapping->range_end._signed;
+       }
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_enumeration_get_mapping_unsigned(
+               struct bt_ctf_field_type *enum_field_type,
+               int index,
+               const char **mapping_name, uint64_t *range_begin,
+               uint64_t *range_end)
+{
+       int ret = 0;
+       struct enumeration_mapping *mapping;
+
+       if (!enum_field_type || index < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       mapping = get_enumeration_mapping(enum_field_type, index);
+       if (!mapping) {
+               ret = -1;
+               goto end;
+       }
+
+       if (mapping_name) {
+               *mapping_name = g_quark_to_string(mapping->string);
+       }
+
+       if (range_begin) {
+               *range_begin = mapping->range_start._unsigned;
+       }
+
+       if (range_end) {
+               *range_end = mapping->range_end._unsigned;
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_create(
+               struct bt_ctf_field_type *integer_container_type)
+{
+       struct bt_ctf_field_type_enumeration *enumeration = NULL;
+
+       if (!integer_container_type) {
+               goto error;
+       }
+
+       if (integer_container_type->id != BT_CTF_TYPE_ID_INTEGER) {
+               goto error;
+       }
+
+       enumeration = g_new0(struct bt_ctf_field_type_enumeration, 1);
+       if (!enumeration) {
+               goto error;
+       }
+
+       enumeration->parent.id = BT_CTF_TYPE_ID_ENUM;
+       bt_get(integer_container_type);
+       enumeration->container = integer_container_type;
+       enumeration->entries = g_ptr_array_new_with_free_func(
+               (GDestroyNotify)destroy_enumeration_mapping);
+       bt_ctf_field_type_init(&enumeration->parent, FALSE);
+       return &enumeration->parent;
+error:
+       g_free(enumeration);
+       return NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *container_type = NULL;
+       struct bt_ctf_field_type_enumeration *enumeration_type;
+
+       if (!type) {
+               goto end;
+       }
+
+       if (type->id != BT_CTF_TYPE_ID_ENUM) {
+               goto end;
+       }
+
+       enumeration_type = container_of(type,
+               struct bt_ctf_field_type_enumeration, parent);
+       container_type = enumeration_type->container;
+       bt_get(container_type);
+end:
+       return container_type;
+}
+
+int bt_ctf_field_type_enumeration_add_mapping(
+               struct bt_ctf_field_type *type, const char *string,
+               int64_t range_start, int64_t range_end)
+{
+       int ret = 0;
+       GQuark mapping_name;
+       struct enumeration_mapping *mapping;
+       struct bt_ctf_field_type_enumeration *enumeration;
+       char *escaped_string;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ENUM) ||
+               type->frozen ||
+               (range_end < range_start)) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!string || strlen(string) == 0) {
+               ret = -1;
+               goto end;
+       }
+
+       escaped_string = g_strescape(string, NULL);
+       if (!escaped_string) {
+               ret = -1;
+               goto end;
+       }
+
+       mapping = g_new(struct enumeration_mapping, 1);
+       if (!mapping) {
+               ret = -1;
+               goto error_free;
+       }
+       mapping_name = g_quark_from_string(escaped_string);
+       *mapping = (struct enumeration_mapping) {
+               .range_start._signed = range_start,
+               .range_end._signed = range_end,
+               .string =  mapping_name,
+       };
+       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+               parent);
+       g_ptr_array_add(enumeration->entries, mapping);
+       g_ptr_array_sort(enumeration->entries,
+               (GCompareFunc)compare_enumeration_mappings_signed);
+error_free:
+       free(escaped_string);
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_enumeration_add_mapping_unsigned(
+               struct bt_ctf_field_type *type, const char *string,
+               uint64_t range_start, uint64_t range_end)
+{
+       int ret = 0;
+       GQuark mapping_name;
+       struct enumeration_mapping *mapping;
+       struct bt_ctf_field_type_enumeration *enumeration;
+       char *escaped_string;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ENUM) ||
+               type->frozen ||
+               (range_end < range_start)) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!string || strlen(string) == 0) {
+               ret = -1;
+               goto end;
+       }
+
+       escaped_string = g_strescape(string, NULL);
+       if (!escaped_string) {
+               ret = -1;
+               goto end;
+       }
+
+       mapping = g_new(struct enumeration_mapping, 1);
+       if (!mapping) {
+               ret = -1;
+               goto error_free;
+       }
+       mapping_name = g_quark_from_string(escaped_string);
+       *mapping = (struct enumeration_mapping) {
+               .range_start._unsigned = range_start,
+               .range_end._unsigned = range_end,
+               .string = mapping_name,
+       };
+       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+               parent);
+       g_ptr_array_add(enumeration->entries, mapping);
+       g_ptr_array_sort(enumeration->entries,
+               (GCompareFunc)compare_enumeration_mappings_unsigned);
+error_free:
+       free(escaped_string);
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_enumeration_get_mapping_count(
+               struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_enumeration *enumeration;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ENUM)) {
+               ret = -1;
+               goto end;
+       }
+
+       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+               parent);
+       ret = (int) enumeration->entries->len;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_create(void)
+{
+       struct bt_ctf_field_type_floating_point *floating_point =
+               g_new0(struct bt_ctf_field_type_floating_point, 1);
+
+       if (!floating_point) {
+               goto end;
+       }
+
+       floating_point->parent.id = BT_CTF_TYPE_ID_FLOAT;
+       floating_point->exp_dig = sizeof(float) * CHAR_BIT - FLT_MANT_DIG;
+       floating_point->mant_dig = FLT_MANT_DIG;
+       bt_ctf_field_type_init(&floating_point->parent, TRUE);
+end:
+       return floating_point ? &floating_point->parent : NULL;
+}
+
+int bt_ctf_field_type_floating_point_get_exponent_digits(
+               struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_floating_point *floating_point;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_FLOAT)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point = container_of(type,
+               struct bt_ctf_field_type_floating_point, parent);
+       ret = (int) floating_point->exp_dig;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_floating_point_set_exponent_digits(
+               struct bt_ctf_field_type *type,
+               unsigned int exponent_digits)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_floating_point *floating_point;
+
+       if (!type || type->frozen ||
+               (type->id != BT_CTF_TYPE_ID_FLOAT)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point = container_of(type,
+               struct bt_ctf_field_type_floating_point, parent);
+       if ((exponent_digits != sizeof(float) * CHAR_BIT - FLT_MANT_DIG) &&
+               (exponent_digits != sizeof(double) * CHAR_BIT - DBL_MANT_DIG) &&
+               (exponent_digits !=
+                       sizeof(long double) * CHAR_BIT - LDBL_MANT_DIG)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point->exp_dig = exponent_digits;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_floating_point_get_mantissa_digits(
+               struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_floating_point *floating_point;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_FLOAT)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point = container_of(type,
+               struct bt_ctf_field_type_floating_point, parent);
+       ret = (int) floating_point->mant_dig;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_floating_point_set_mantissa_digits(
+               struct bt_ctf_field_type *type,
+               unsigned int mantissa_digits)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_floating_point *floating_point;
+
+       if (!type || type->frozen ||
+               (type->id != BT_CTF_TYPE_ID_FLOAT)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point = container_of(type,
+               struct bt_ctf_field_type_floating_point, parent);
+
+       if ((mantissa_digits != FLT_MANT_DIG) &&
+               (mantissa_digits != DBL_MANT_DIG) &&
+               (mantissa_digits != LDBL_MANT_DIG)) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point->mant_dig = mantissa_digits;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void)
+{
+       struct bt_ctf_field_type_structure *structure =
+               g_new0(struct bt_ctf_field_type_structure, 1);
+
+       if (!structure) {
+               goto error;
+       }
+
+       structure->parent.id = BT_CTF_TYPE_ID_STRUCT;
+       structure->fields = g_ptr_array_new_with_free_func(
+               (GDestroyNotify)destroy_structure_field);
+       structure->field_name_to_index = g_hash_table_new(NULL, NULL);
+       bt_ctf_field_type_init(&structure->parent, TRUE);
+       return &structure->parent;
+error:
+       return NULL;
+}
+
+int bt_ctf_field_type_structure_add_field(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *field_type,
+               const char *field_name)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_structure *structure;
+
+       /*
+        * TODO: check that `field_type` does not contain `type`,
+        *       recursively.
+        */
+       if (!type || !field_type || type->frozen ||
+               bt_ctf_validate_identifier(field_name) ||
+               (type->id != BT_CTF_TYPE_ID_STRUCT) ||
+               type == field_type) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(type,
+               struct bt_ctf_field_type_structure, parent);
+       if (add_structure_field(structure->fields,
+               structure->field_name_to_index, field_type, field_name)) {
+               ret = -1;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_structure_get_field_count(
+               struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_structure *structure;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_STRUCT)) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       ret = (int) structure->fields->len;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_structure_get_field(struct bt_ctf_field_type *type,
+               const char **field_name, struct bt_ctf_field_type **field_type,
+               int index)
+{
+       struct bt_ctf_field_type_structure *structure;
+       struct structure_field *field;
+       int ret = 0;
+
+       if (!type || index < 0 ||
+                       (type->id != BT_CTF_TYPE_ID_STRUCT)) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       if (index >= structure->fields->len) {
+               ret = -1;
+               goto end;
+       }
+
+       field = g_ptr_array_index(structure->fields, index);
+       if (field_type) {
+               *field_type = field->type;
+               bt_get(field->type);
+       }
+       if (field_name) {
+               *field_name = g_quark_to_string(field->name);
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
+               struct bt_ctf_field_type *type,
+               const char *name)
+{
+       size_t index;
+       GQuark name_quark;
+       struct structure_field *field;
+       struct bt_ctf_field_type_structure *structure;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!type || !name) {
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(name);
+       if (!name_quark) {
+               goto end;
+       }
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+               goto end;
+       }
+
+       field = structure->fields->pdata[index];
+       field_type = field->type;
+       bt_get(field_type);
+end:
+       return field_type;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_variant_create(
+       struct bt_ctf_field_type *enum_tag, const char *tag_name)
+{
+       struct bt_ctf_field_type_variant *variant = NULL;
+
+       if (tag_name && bt_ctf_validate_identifier(tag_name)) {
+               goto error;
+       }
+
+       variant = g_new0(struct bt_ctf_field_type_variant, 1);
+       if (!variant) {
+               goto error;
+       }
+
+       variant->parent.id = BT_CTF_TYPE_ID_VARIANT;
+       variant->tag_name = g_string_new(tag_name);
+       variant->field_name_to_index = g_hash_table_new(NULL, NULL);
+       variant->fields = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) destroy_structure_field);
+       if (enum_tag) {
+               bt_get(enum_tag);
+               variant->tag = container_of(enum_tag,
+                       struct bt_ctf_field_type_enumeration, parent);
+       }
+
+       bt_ctf_field_type_init(&variant->parent, TRUE);
+       /* A variant's alignment is undefined */
+       variant->parent.alignment = 0;
+       return &variant->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_variant *variant;
+       struct bt_ctf_field_type *tag_type = NULL;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_VARIANT)) {
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+       if (!variant->tag) {
+               goto end;
+       }
+
+       tag_type = &variant->tag->parent;
+       bt_get(tag_type);
+end:
+       return tag_type;
+}
+
+const char *bt_ctf_field_type_variant_get_tag_name(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_variant *variant;
+       const char *tag_name = NULL;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_VARIANT)) {
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+       if (variant->tag_name->len == 0) {
+               goto end;
+       }
+
+       tag_name = variant->tag_name->str;
+end:
+       return tag_name;
+}
+
+int bt_ctf_field_type_variant_set_tag_name(
+               struct bt_ctf_field_type *type, const char *name)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || type->frozen ||
+               (type->id != BT_CTF_TYPE_ID_VARIANT) ||
+               bt_ctf_validate_identifier(name)) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+       g_string_assign(variant->tag_name, name);
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_variant_add_field(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *field_type,
+               const char *field_name)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+       GQuark field_name_quark = g_quark_from_string(field_name);
+
+       /*
+        * TODO: check that `field_type` does not contain `type`,
+        *       recursively.
+        */
+       if (!type || !field_type || type->frozen ||
+               bt_ctf_validate_identifier(field_name) ||
+               (type->id != BT_CTF_TYPE_ID_VARIANT) ||
+               type == field_type) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+
+       /* The user has explicitly provided a tag; validate against it. */
+       if (variant->tag) {
+               int name_found = 0;
+
+               /* Make sure this name is present in the enum tag */
+               for (i = 0; i < variant->tag->entries->len; i++) {
+                       struct enumeration_mapping *mapping =
+                               g_ptr_array_index(variant->tag->entries, i);
+
+                       if (mapping->string == field_name_quark) {
+                               name_found = 1;
+                               break;
+                       }
+               }
+
+               if (!name_found) {
+                       /* Validation failed */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       if (add_structure_field(variant->fields, variant->field_name_to_index,
+               field_type, field_name)) {
+               ret = -1;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
+               struct bt_ctf_field_type *type,
+               const char *field_name)
+{
+       size_t index;
+       GQuark name_quark;
+       struct structure_field *field;
+       struct bt_ctf_field_type_variant *variant;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!type || !field_name) {
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(field_name);
+       if (!name_quark) {
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+               goto end;
+       }
+
+       field = g_ptr_array_index(variant->fields, index);
+       field_type = field->type;
+       bt_get(field_type);
+end:
+       return field_type;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_from_tag(
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_field *tag)
+{
+       int ret;
+       const char *enum_value;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+
+       if (!type || !tag || type->id != BT_CTF_TYPE_ID_VARIANT) {
+               goto end;
+       }
+
+       iter = bt_ctf_field_enumeration_get_mappings(tag);
+       if (!iter) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_enumeration_mapping_iterator_get_signed(iter,
+               &enum_value, NULL, NULL);
+       if (ret) {
+               goto end;
+       }
+
+       field_type = bt_ctf_field_type_variant_get_field_type_by_name(
+               type, enum_value);
+end:
+       bt_put(iter);
+       return field_type;
+}
+
+int bt_ctf_field_type_variant_get_field_count(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_VARIANT)) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       ret = (int) variant->fields->len;
+end:
+       return ret;
+
+}
+
+int bt_ctf_field_type_variant_get_field(struct bt_ctf_field_type *type,
+               const char **field_name, struct bt_ctf_field_type **field_type,
+               int index)
+{
+       struct bt_ctf_field_type_variant *variant;
+       struct structure_field *field;
+       int ret = 0;
+
+       if (!type || index < 0 ||
+                       (type->id != BT_CTF_TYPE_ID_VARIANT)) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (index >= variant->fields->len) {
+               ret = -1;
+               goto end;
+       }
+
+       field = g_ptr_array_index(variant->fields, index);
+       if (field_type) {
+               *field_type = field->type;
+               bt_get(field->type);
+       }
+       if (field_name) {
+               *field_name = g_quark_to_string(field->name);
+       }
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_array_create(
+               struct bt_ctf_field_type *element_type,
+               unsigned int length)
+{
+       struct bt_ctf_field_type_array *array = NULL;
+
+       if (!element_type || length == 0) {
+               goto error;
+       }
+
+       array = g_new0(struct bt_ctf_field_type_array, 1);
+       if (!array) {
+               goto error;
+       }
+
+       array->parent.id = BT_CTF_TYPE_ID_ARRAY;
+       bt_get(element_type);
+       array->element_type = element_type;
+       array->length = length;
+       bt_ctf_field_type_init(&array->parent, FALSE);
+       return &array->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_array_get_element_type(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *ret = NULL;
+       struct bt_ctf_field_type_array *array;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ARRAY)) {
+               goto end;
+       }
+
+       array = container_of(type, struct bt_ctf_field_type_array, parent);
+       ret = array->element_type;
+       bt_get(ret);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_array_set_element_type(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *element_type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_array *array;
+
+       if (!type || !element_type ||
+                       (type->id != BT_CTF_TYPE_ID_ARRAY)) {
+               ret = -1;
+               goto end;
+       }
+
+       array = container_of(type, struct bt_ctf_field_type_array, parent);
+
+       if (array->element_type) {
+               BT_PUT(array->element_type);
+       }
+
+       array->element_type = element_type;
+       bt_get(array->element_type);
+
+end:
+       return ret;
+}
+
+int64_t bt_ctf_field_type_array_get_length(struct bt_ctf_field_type *type)
+{
+       int64_t ret;
+       struct bt_ctf_field_type_array *array;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_ARRAY)) {
+               ret = -1;
+               goto end;
+       }
+
+       array = container_of(type, struct bt_ctf_field_type_array, parent);
+       ret = (int64_t) array->length;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
+               struct bt_ctf_field_type *element_type,
+               const char *length_field_name)
+{
+       struct bt_ctf_field_type_sequence *sequence = NULL;
+
+       if (!element_type || bt_ctf_validate_identifier(length_field_name)) {
+               goto error;
+       }
+
+       sequence = g_new0(struct bt_ctf_field_type_sequence, 1);
+       if (!sequence) {
+               goto error;
+       }
+
+       sequence->parent.id = BT_CTF_TYPE_ID_SEQUENCE;
+       bt_get(element_type);
+       sequence->element_type = element_type;
+       sequence->length_field_name = g_string_new(length_field_name);
+       bt_ctf_field_type_init(&sequence->parent, FALSE);
+       return &sequence->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *ret = NULL;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_SEQUENCE)) {
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+       ret = sequence->element_type;
+       bt_get(ret);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_sequence_set_element_type(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *element_type)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || !element_type ||
+                       (type->id != BT_CTF_TYPE_ID_SEQUENCE)) {
+               ret = -1;
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence, parent);
+
+       if (sequence->element_type) {
+               BT_PUT(sequence->element_type);
+       }
+
+       sequence->element_type = element_type;
+       bt_get(sequence->element_type);
+
+end:
+       return ret;
+}
+
+const char *bt_ctf_field_type_sequence_get_length_field_name(
+               struct bt_ctf_field_type *type)
+{
+       const char *ret = NULL;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_SEQUENCE)) {
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+       ret = sequence->length_field_name->str;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_string_create(void)
+{
+       struct bt_ctf_field_type_string *string =
+               g_new0(struct bt_ctf_field_type_string, 1);
+
+       if (!string) {
+               return NULL;
+       }
+
+       string->parent.id = BT_CTF_TYPE_ID_STRING;
+       bt_ctf_field_type_init(&string->parent, TRUE);
+       string->encoding = BT_CTF_STRING_ENCODING_UTF8;
+       string->parent.alignment = CHAR_BIT;
+       return &string->parent;
+}
+
+enum bt_ctf_string_encoding bt_ctf_field_type_string_get_encoding(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_string *string;
+       enum bt_ctf_string_encoding ret = BT_CTF_STRING_ENCODING_UNKNOWN;
+
+       if (!type || (type->id != BT_CTF_TYPE_ID_STRING)) {
+               goto end;
+       }
+
+       string = container_of(type, struct bt_ctf_field_type_string,
+               parent);
+       ret = string->encoding;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_string_set_encoding(struct bt_ctf_field_type *type,
+               enum bt_ctf_string_encoding encoding)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_string *string;
+
+       if (!type || type->id != BT_CTF_TYPE_ID_STRING ||
+               (encoding != BT_CTF_STRING_ENCODING_UTF8 &&
+               encoding != BT_CTF_STRING_ENCODING_ASCII)) {
+               ret = -1;
+               goto end;
+       }
+
+       string = container_of(type, struct bt_ctf_field_type_string, parent);
+       string->encoding = encoding;
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_get_alignment(struct bt_ctf_field_type *type)
+{
+       int ret;
+       enum bt_ctf_type_id type_id;
+
+       if (!type) {
+               ret = -1;
+               goto end;
+       }
+
+       if (type->frozen) {
+               ret = (int) type->alignment;
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(type);
+       switch (type_id) {
+       case BT_CTF_TYPE_ID_SEQUENCE:
+       {
+               struct bt_ctf_field_type *element =
+                       bt_ctf_field_type_sequence_get_element_type(type);
+
+               if (!element) {
+                       ret = -1;
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_get_alignment(element);
+               bt_put(element);
+               break;
+       }
+       case BT_CTF_TYPE_ID_ARRAY:
+       {
+               struct bt_ctf_field_type *element =
+                       bt_ctf_field_type_array_get_element_type(type);
+
+               if (!element) {
+                       ret = -1;
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_get_alignment(element);
+               bt_put(element);
+               break;
+       }
+       case BT_CTF_TYPE_ID_STRUCT:
+       {
+               int i, element_count;
+
+               element_count = bt_ctf_field_type_structure_get_field_count(
+                       type);
+               if (element_count < 0) {
+                       ret = element_count;
+                       goto end;
+               }
+
+               for (i = 0; i < element_count; i++) {
+                       struct bt_ctf_field_type *field;
+                       int field_alignment;
+
+                       ret = bt_ctf_field_type_structure_get_field(type, NULL,
+                               &field, i);
+                       if (ret) {
+                               goto end;
+                       }
+
+                       assert(field);
+                       field_alignment = bt_ctf_field_type_get_alignment(
+                               field);
+                       bt_put(field);
+                       if (field_alignment < 0) {
+                               ret = field_alignment;
+                               goto end;
+                       }
+
+                       type->alignment = MAX(field_alignment, type->alignment);
+               }
+               ret = (int) type->alignment;
+               break;
+       }
+       case BT_CTF_TYPE_ID_UNKNOWN:
+               ret = -1;
+               break;
+       default:
+               ret = (int) type->alignment;
+               break;
+       }
+end:
+       return ret;
+}
+
+static inline
+int is_power_of_two(unsigned int value)
+{
+       return ((value & (value - 1)) == 0) && value > 0;
+}
+
+int bt_ctf_field_type_set_alignment(struct bt_ctf_field_type *type,
+               unsigned int alignment)
+{
+       int ret = 0;
+       enum bt_ctf_type_id type_id;
+
+       /* Alignment must be a power of two */
+       if (!type || type->frozen || !is_power_of_two(alignment)) {
+               ret = -1;
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(type);
+       if (type_id == BT_CTF_TYPE_ID_UNKNOWN) {
+               ret = -1;
+               goto end;
+       }
+
+       if (type->id == BT_CTF_TYPE_ID_STRING &&
+               alignment != CHAR_BIT) {
+               ret = -1;
+               goto end;
+       }
+
+       if (type_id == BT_CTF_TYPE_ID_VARIANT ||
+               type_id == BT_CTF_TYPE_ID_SEQUENCE ||
+               type_id == BT_CTF_TYPE_ID_ARRAY) {
+               /* Setting an alignment on these types makes no sense */
+               ret = -1;
+               goto end;
+       }
+
+       type->alignment = alignment;
+       ret = 0;
+end:
+       return ret;
+}
+
+enum bt_ctf_byte_order bt_ctf_field_type_get_byte_order(
+               struct bt_ctf_field_type *type)
+{
+       enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
+
+       if (!type) {
+               goto end;
+       }
+
+       switch (type->id) {
+       case BT_CTF_TYPE_ID_INTEGER:
+       {
+               struct bt_ctf_field_type_integer *integer = container_of(
+                       type, struct bt_ctf_field_type_integer, parent);
+               ret = integer->user_byte_order;
+               break;
+       }
+       case BT_CTF_TYPE_ID_ENUM:
+       {
+               struct bt_ctf_field_type_enumeration *enum_ft = container_of(
+                       type, struct bt_ctf_field_type_enumeration, parent);
+               ret = bt_ctf_field_type_get_byte_order(enum_ft->container);
+               break;
+       }
+       case BT_CTF_TYPE_ID_FLOAT:
+       {
+               struct bt_ctf_field_type_floating_point *floating_point =
+                       container_of(type,
+                               struct bt_ctf_field_type_floating_point,
+                               parent);
+               ret = floating_point->user_byte_order;
+               break;
+       }
+       default:
+               goto end;
+       }
+
+       assert(ret == BT_CTF_BYTE_ORDER_NATIVE ||
+               ret == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
+               ret == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
+               ret == BT_CTF_BYTE_ORDER_NETWORK);
+
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       int ret = 0;
+
+       if (!type || type->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (byte_order != BT_CTF_BYTE_ORDER_NATIVE &&
+                       byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
+                       byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
+                       byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
+               ret = -1;
+               goto end;
+       }
+
+       if (set_byte_order_funcs[type->id]) {
+               set_byte_order_funcs[type->id](type, byte_order);
+       }
+end:
+       return ret;
+}
+
+enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
+               struct bt_ctf_field_type *type)
+{
+       if (!type) {
+               return BT_CTF_TYPE_ID_UNKNOWN;
+       }
+
+       return type->id;
+}
+
+int bt_ctf_field_type_is_integer(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_INTEGER;
+}
+
+int bt_ctf_field_type_is_floating_point(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_FLOAT;
+}
+
+int bt_ctf_field_type_is_enumeration(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ENUM;
+}
+
+int bt_ctf_field_type_is_string(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRING;
+}
+
+int bt_ctf_field_type_is_structure(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_STRUCT;
+}
+
+int bt_ctf_field_type_is_array(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_ARRAY;
+}
+
+int bt_ctf_field_type_is_sequence(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_SEQUENCE;
+}
+
+int bt_ctf_field_type_is_variant(struct bt_ctf_field_type *type)
+{
+       return bt_ctf_field_type_get_type_id(type) == BT_CTF_TYPE_ID_VARIANT;
+}
+
+void bt_ctf_field_type_get(struct bt_ctf_field_type *type)
+{
+       bt_get(type);
+}
+
+void bt_ctf_field_type_put(struct bt_ctf_field_type *type)
+{
+       bt_put(type);
+}
+
+BT_HIDDEN
+void bt_ctf_field_type_freeze(struct bt_ctf_field_type *type)
+{
+       if (!type) {
+               return;
+       }
+
+       type->freeze(type);
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_signed(
+               struct bt_ctf_field_type_variant *variant,
+               int64_t tag_value)
+{
+       struct bt_ctf_field_type *type = NULL;
+       GQuark field_name_quark;
+       gpointer index;
+       struct structure_field *field_entry;
+       struct range_overlap_query query = {
+               .range_start._signed = tag_value,
+               .range_end._signed = tag_value,
+               .mapping_name = 0,
+               .overlaps = 0,
+       };
+
+       g_ptr_array_foreach(variant->tag->entries, check_ranges_overlap,
+               &query);
+       if (!query.overlaps) {
+               goto end;
+       }
+
+       field_name_quark = query.mapping_name;
+       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+               GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
+               goto end;
+       }
+
+       field_entry = g_ptr_array_index(variant->fields, (size_t) index);
+       type = field_entry->type;
+end:
+       return type;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_unsigned(
+               struct bt_ctf_field_type_variant *variant,
+               uint64_t tag_value)
+{
+       struct bt_ctf_field_type *type = NULL;
+       GQuark field_name_quark;
+       gpointer index;
+       struct structure_field *field_entry;
+       struct range_overlap_query query = {
+               .range_start._unsigned = tag_value,
+               .range_end._unsigned = tag_value,
+               .mapping_name = 0,
+               .overlaps = 0,
+       };
+
+       g_ptr_array_foreach(variant->tag->entries,
+               check_ranges_overlap_unsigned,
+               &query);
+       if (!query.overlaps) {
+               goto end;
+       }
+
+       field_name_quark = query.mapping_name;
+       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+               GUINT_TO_POINTER(field_name_quark), NULL, &index)) {
+               goto end;
+       }
+
+       field_entry = g_ptr_array_index(variant->fields, (size_t)index);
+       type = field_entry->type;
+end:
+       return type;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       int ret;
+
+       if (!type || !context) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Make sure field type is valid before serializing it */
+       ret = bt_ctf_field_type_validate(type);
+
+       if (ret) {
+               goto end;
+       }
+
+       ret = type->serialize(type, context);
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_field_type_copy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy = NULL;
+
+       if (!type) {
+               goto end;
+       }
+
+       copy = type_copy_funcs[type->id](type);
+       copy->alignment = type->alignment;
+end:
+       return copy;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_structure_get_field_name_index(
+               struct bt_ctf_field_type *type, const char *name)
+{
+       int ret;
+       size_t index;
+       GQuark name_quark;
+       struct bt_ctf_field_type_structure *structure;
+
+       if (!type || !name ||
+               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(name);
+       if (!name_quark) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+               ret = -1;
+               goto end;
+       }
+       ret = (int) index;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_structure_set_field_index(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *field, int index)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_structure *structure;
+
+       if (!type || !field ||
+               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       if (index < 0 || index >= structure->fields->len) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_get(field);
+       bt_put(((struct structure_field *)
+               g_ptr_array_index(structure->fields, index))->type);
+       ((struct structure_field *) structure->fields->pdata[index])->type =
+               field;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_get_field_name_index(
+               struct bt_ctf_field_type *type, const char *name)
+{
+       int ret;
+       size_t index;
+       GQuark name_quark;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !name ||
+               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
+               ret = -1;
+               goto end;
+       }
+
+       name_quark = g_quark_try_string(name);
+       if (!name_quark) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (!g_hash_table_lookup_extended(variant->field_name_to_index,
+               GUINT_TO_POINTER(name_quark), NULL, (gpointer *)&index)) {
+               ret = -1;
+               goto end;
+       }
+       ret = (int) index;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_sequence_set_length_field_path(
+               struct bt_ctf_field_type *type,
+               struct bt_ctf_field_path *path)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || bt_ctf_field_type_get_type_id(type) !=
+                       BT_CTF_TYPE_ID_SEQUENCE) {
+               ret = -1;
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+       bt_get(path);
+       BT_MOVE(sequence->length_field_path, path);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag_field_path(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_path *path)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || bt_ctf_field_type_get_type_id(type) !=
+                       BT_CTF_TYPE_ID_VARIANT) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       bt_get(path);
+       BT_MOVE(variant->tag_field_path, path);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_tag_field_type(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *tag)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !tag ||
+                       bt_ctf_field_type_get_type_id(tag) !=
+                       BT_CTF_TYPE_ID_ENUM) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       bt_get(tag);
+       if (variant->tag) {
+               bt_put(&variant->tag->parent);
+       }
+       variant->tag = container_of(tag, struct bt_ctf_field_type_enumeration,
+               parent);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_variant_set_field_index(struct bt_ctf_field_type *type,
+               struct bt_ctf_field_type *field, int index)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !field ||
+               bt_ctf_field_type_get_type_id(type) != BT_CTF_TYPE_ID_VARIANT) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (index < 0 || index >= variant->fields->len) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_get(field);
+       bt_put(((struct structure_field *)
+               g_ptr_array_index(variant->fields, index))->type);
+       ((struct structure_field *) variant->fields->pdata[index])->type =
+               field;
+end:
+       return ret;
+}
+
+static
+void bt_ctf_field_type_integer_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_integer *integer =
+               (struct bt_ctf_field_type_integer *) type;
+
+       if (!type) {
+               return;
+       }
+
+       bt_put(integer->mapped_clock);
+       g_free(integer);
+}
+
+static
+void bt_ctf_field_type_enumeration_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_enumeration *enumeration =
+               (struct bt_ctf_field_type_enumeration *) type;
+
+       if (!type) {
+               return;
+       }
+
+       g_ptr_array_free(enumeration->entries, TRUE);
+       bt_put(enumeration->container);
+       g_free(enumeration);
+}
+
+static
+void bt_ctf_field_type_floating_point_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_floating_point *floating_point =
+               (struct bt_ctf_field_type_floating_point *) type;
+
+       if (!type) {
+               return;
+       }
+
+       g_free(floating_point);
+}
+
+static
+void bt_ctf_field_type_structure_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_structure *structure =
+               (struct bt_ctf_field_type_structure *) type;
+
+       if (!type) {
+               return;
+       }
+
+       g_ptr_array_free(structure->fields, TRUE);
+       g_hash_table_destroy(structure->field_name_to_index);
+       g_free(structure);
+}
+
+static
+void bt_ctf_field_type_variant_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_variant *variant =
+               (struct bt_ctf_field_type_variant *) type;
+
+       if (!type) {
+               return;
+       }
+
+       g_ptr_array_free(variant->fields, TRUE);
+       g_hash_table_destroy(variant->field_name_to_index);
+       g_string_free(variant->tag_name, TRUE);
+       bt_put(&variant->tag->parent);
+       BT_PUT(variant->tag_field_path);
+       g_free(variant);
+}
+
+static
+void bt_ctf_field_type_array_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_array *array =
+               (struct bt_ctf_field_type_array *) type;
+
+       if (!type) {
+               return;
+       }
+
+       bt_put(array->element_type);
+       g_free(array);
+}
+
+static
+void bt_ctf_field_type_sequence_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_sequence *sequence =
+               (struct bt_ctf_field_type_sequence *) type;
+
+       if (!type) {
+               return;
+       }
+
+       bt_put(sequence->element_type);
+       g_string_free(sequence->length_field_name, TRUE);
+       BT_PUT(sequence->length_field_path);
+       g_free(sequence);
+}
+
+static
+void bt_ctf_field_type_string_destroy(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_string *string =
+               (struct bt_ctf_field_type_string *) type;
+
+       if (!type) {
+               return;
+       }
+
+       g_free(string);
+}
+
+static
+void generic_field_type_freeze(struct bt_ctf_field_type *type)
+{
+       type->frozen = 1;
+}
+
+static
+void bt_ctf_field_type_integer_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_integer *integer_type = container_of(
+               type, struct bt_ctf_field_type_integer, parent);
+
+       if (integer_type->mapped_clock) {
+               bt_ctf_clock_class_freeze(integer_type->mapped_clock);
+       }
+
+       generic_field_type_freeze(type);
+}
+
+static
+void bt_ctf_field_type_enumeration_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_enumeration *enumeration_type = container_of(
+               type, struct bt_ctf_field_type_enumeration, parent);
+
+       set_enumeration_range_overlap(type);
+
+       generic_field_type_freeze(type);
+       bt_ctf_field_type_freeze(enumeration_type->container);
+}
+
+static
+void freeze_structure_field(struct structure_field *field)
+{
+       bt_ctf_field_type_freeze(field->type);
+}
+
+static
+void bt_ctf_field_type_structure_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_structure *structure_type = container_of(
+               type, struct bt_ctf_field_type_structure, parent);
+
+       /* Cache the alignment */
+       type->alignment = bt_ctf_field_type_get_alignment(type);
+       generic_field_type_freeze(type);
+       g_ptr_array_foreach(structure_type->fields,
+               (GFunc) freeze_structure_field, NULL);
+}
+
+static
+void bt_ctf_field_type_variant_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_variant *variant_type = container_of(
+               type, struct bt_ctf_field_type_variant, parent);
+
+       generic_field_type_freeze(type);
+       g_ptr_array_foreach(variant_type->fields,
+               (GFunc) freeze_structure_field, NULL);
+}
+
+static
+void bt_ctf_field_type_array_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_array *array_type = container_of(
+               type, struct bt_ctf_field_type_array, parent);
+
+       /* Cache the alignment */
+       type->alignment = bt_ctf_field_type_get_alignment(type);
+       generic_field_type_freeze(type);
+       bt_ctf_field_type_freeze(array_type->element_type);
+}
+
+static
+void bt_ctf_field_type_sequence_freeze(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_sequence *sequence_type = container_of(
+               type, struct bt_ctf_field_type_sequence, parent);
+
+       /* Cache the alignment */
+       type->alignment = bt_ctf_field_type_get_alignment(type);
+       generic_field_type_freeze(type);
+       bt_ctf_field_type_freeze(sequence_type->element_type);
+}
+
+static
+const char *get_encoding_string(enum bt_ctf_string_encoding encoding)
+{
+       const char *encoding_string;
+
+       switch (encoding) {
+       case BT_CTF_STRING_ENCODING_NONE:
+               encoding_string = "none";
+               break;
+       case BT_CTF_STRING_ENCODING_ASCII:
+               encoding_string = "ASCII";
+               break;
+       case BT_CTF_STRING_ENCODING_UTF8:
+               encoding_string = "UTF8";
+               break;
+       default:
+               encoding_string = "unknown";
+               break;
+       }
+
+       return encoding_string;
+}
+
+static
+const char *get_integer_base_string(enum bt_ctf_integer_base base)
+{
+       const char *base_string;
+
+       switch (base) {
+       case BT_CTF_INTEGER_BASE_DECIMAL:
+               base_string = "decimal";
+               break;
+       case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+               base_string = "hexadecimal";
+               break;
+       case BT_CTF_INTEGER_BASE_OCTAL:
+               base_string = "octal";
+               break;
+       case BT_CTF_INTEGER_BASE_BINARY:
+               base_string = "binary";
+               break;
+       default:
+               base_string = "unknown";
+               break;
+       }
+
+       return base_string;
+}
+
+static
+int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       struct bt_ctf_field_type_integer *integer = container_of(type,
+               struct bt_ctf_field_type_integer, parent);
+       int ret = 0;
+
+       g_string_append_printf(context->string,
+               "integer { size = %u; align = %u; signed = %s; encoding = %s; base = %s; byte_order = %s",
+               integer->size, type->alignment,
+               (integer->is_signed ? "true" : "false"),
+               get_encoding_string(integer->encoding),
+               get_integer_base_string(integer->base),
+               get_byte_order_string(integer->user_byte_order));
+       if (integer->mapped_clock) {
+               const char *clock_name = bt_ctf_clock_class_get_name(
+                       integer->mapped_clock);
+
+               if (!clock_name) {
+                       ret = -1;
+                       goto end;
+               }
+
+               g_string_append_printf(context->string,
+                       "; map = clock.%s.value", clock_name);
+       }
+
+       g_string_append(context->string, "; }");
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_enumeration_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       size_t entry;
+       int ret;
+       struct bt_ctf_field_type_enumeration *enumeration = container_of(type,
+               struct bt_ctf_field_type_enumeration, parent);
+       struct bt_ctf_field_type *container_type;
+       int container_signed;
+
+       container_type = bt_ctf_field_type_enumeration_get_container_type(type);
+       if (!container_type) {
+               ret = -1;
+               goto end;
+       }
+
+       container_signed = bt_ctf_field_type_integer_get_signed(container_type);
+       if (container_signed < 0) {
+               ret = container_signed;
+               goto error_put_container_type;
+       }
+
+       g_string_append(context->string, "enum : ");
+       ret = bt_ctf_field_type_serialize(enumeration->container, context);
+       if (ret) {
+               goto error_put_container_type;
+       }
+
+       g_string_append(context->string, " { ");
+       for (entry = 0; entry < enumeration->entries->len; entry++) {
+               struct enumeration_mapping *mapping =
+                       enumeration->entries->pdata[entry];
+
+               if (container_signed) {
+                       if (mapping->range_start._signed ==
+                               mapping->range_end._signed) {
+                               g_string_append_printf(context->string,
+                                       "\"%s\" = %" PRId64,
+                                       g_quark_to_string(mapping->string),
+                                       mapping->range_start._signed);
+                       } else {
+                               g_string_append_printf(context->string,
+                                       "\"%s\" = %" PRId64 " ... %" PRId64,
+                                       g_quark_to_string(mapping->string),
+                                       mapping->range_start._signed,
+                                       mapping->range_end._signed);
+                       }
+               } else {
+                       if (mapping->range_start._unsigned ==
+                               mapping->range_end._unsigned) {
+                               g_string_append_printf(context->string,
+                                       "\"%s\" = %" PRIu64,
+                                       g_quark_to_string(mapping->string),
+                                       mapping->range_start._unsigned);
+                       } else {
+                               g_string_append_printf(context->string,
+                                       "\"%s\" = %" PRIu64 " ... %" PRIu64,
+                                       g_quark_to_string(mapping->string),
+                                       mapping->range_start._unsigned,
+                                       mapping->range_end._unsigned);
+                       }
+               }
+
+               g_string_append(context->string,
+                       ((entry != (enumeration->entries->len - 1)) ?
+                       ", " : " }"));
+       }
+
+       if (context->field_name->len) {
+               g_string_append_printf(context->string, " %s",
+                       context->field_name->str);
+               g_string_assign(context->field_name, "");
+       }
+error_put_container_type:
+       bt_put(container_type);
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_floating_point_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       struct bt_ctf_field_type_floating_point *floating_point = container_of(
+               type, struct bt_ctf_field_type_floating_point, parent);
+
+       g_string_append_printf(context->string,
+               "floating_point { exp_dig = %u; mant_dig = %u; byte_order = %s; align = %u; }",
+               floating_point->exp_dig,
+               floating_point->mant_dig,
+               get_byte_order_string(floating_point->user_byte_order),
+               type->alignment);
+       return 0;
+}
+
+static
+int bt_ctf_field_type_structure_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       size_t i;
+       unsigned int indent;
+       int ret = 0;
+       struct bt_ctf_field_type_structure *structure = container_of(type,
+               struct bt_ctf_field_type_structure, parent);
+       GString *structure_field_name = context->field_name;
+
+       context->field_name = g_string_new("");
+
+       context->current_indentation_level++;
+       g_string_append(context->string, "struct {\n");
+
+       for (i = 0; i < structure->fields->len; i++) {
+               struct structure_field *field;
+
+               for (indent = 0; indent < context->current_indentation_level;
+                       indent++) {
+                       g_string_append_c(context->string, '\t');
+               }
+
+               field = structure->fields->pdata[i];
+               g_string_assign(context->field_name,
+                       g_quark_to_string(field->name));
+               ret = bt_ctf_field_type_serialize(field->type, context);
+               if (ret) {
+                       goto end;
+               }
+
+               if (context->field_name->len) {
+                       g_string_append_printf(context->string, " %s",
+                               context->field_name->str);
+               }
+               g_string_append(context->string, ";\n");
+       }
+
+       context->current_indentation_level--;
+       for (indent = 0; indent < context->current_indentation_level;
+               indent++) {
+               g_string_append_c(context->string, '\t');
+       }
+
+       g_string_append_printf(context->string, "} align(%u)",
+                type->alignment);
+end:
+       g_string_free(context->field_name, TRUE);
+       context->field_name = structure_field_name;
+       return ret;
+}
+
+static
+int bt_ctf_field_type_variant_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       size_t i;
+       unsigned int indent;
+       int ret = 0;
+       struct bt_ctf_field_type_variant *variant = container_of(
+               type, struct bt_ctf_field_type_variant, parent);
+       GString *variant_field_name = context->field_name;
+
+       context->field_name = g_string_new("");
+       if (variant->tag_name->len > 0) {
+               g_string_append_printf(context->string,
+                       "variant <%s> {\n", variant->tag_name->str);
+       } else {
+               g_string_append(context->string, "variant {\n");
+       }
+
+       context->current_indentation_level++;
+       for (i = 0; i < variant->fields->len; i++) {
+               struct structure_field *field = variant->fields->pdata[i];
+
+               g_string_assign(context->field_name,
+                       g_quark_to_string(field->name));
+               for (indent = 0; indent < context->current_indentation_level;
+                       indent++) {
+                       g_string_append_c(context->string, '\t');
+               }
+
+               g_string_assign(context->field_name,
+                       g_quark_to_string(field->name));
+               ret = bt_ctf_field_type_serialize(field->type, context);
+               if (ret) {
+                       goto end;
+               }
+
+               if (context->field_name->len) {
+                       g_string_append_printf(context->string, " %s;",
+                               context->field_name->str);
+               }
+
+               g_string_append_c(context->string, '\n');
+       }
+
+       context->current_indentation_level--;
+       for (indent = 0; indent < context->current_indentation_level;
+               indent++) {
+               g_string_append_c(context->string, '\t');
+       }
+
+       g_string_append(context->string, "}");
+end:
+       g_string_free(context->field_name, TRUE);
+       context->field_name = variant_field_name;
+       return ret;
+}
+
+static
+int bt_ctf_field_type_array_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_array *array = container_of(type,
+               struct bt_ctf_field_type_array, parent);
+
+       ret = bt_ctf_field_type_serialize(array->element_type, context);
+       if (ret) {
+               goto end;
+       }
+
+       if (context->field_name->len) {
+               g_string_append_printf(context->string, " %s[%u]",
+                       context->field_name->str, array->length);
+               g_string_assign(context->field_name, "");
+       } else {
+               g_string_append_printf(context->string, "[%u]", array->length);
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_sequence_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_sequence *sequence = container_of(
+               type, struct bt_ctf_field_type_sequence, parent);
+
+       ret = bt_ctf_field_type_serialize(sequence->element_type, context);
+       if (ret) {
+               goto end;
+       }
+
+       if (context->field_name->len) {
+               g_string_append_printf(context->string, " %s[%s]",
+                       context->field_name->str,
+                       sequence->length_field_name->str);
+               g_string_assign(context->field_name, "");
+       } else {
+               g_string_append_printf(context->string, "[%s]",
+                       sequence->length_field_name->str);
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_string_serialize(struct bt_ctf_field_type *type,
+               struct metadata_context *context)
+{
+       struct bt_ctf_field_type_string *string = container_of(
+               type, struct bt_ctf_field_type_string, parent);
+
+       g_string_append_printf(context->string,
+               "string { encoding = %s; }",
+               get_encoding_string(string->encoding));
+       return 0;
+}
+
+static
+void bt_ctf_field_type_integer_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       struct bt_ctf_field_type_integer *integer_type = container_of(type,
+               struct bt_ctf_field_type_integer, parent);
+
+       integer_type->user_byte_order = byte_order;
+}
+
+static
+void bt_ctf_field_type_enumeration_set_byte_order(
+               struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order)
+{
+       struct bt_ctf_field_type_enumeration *enum_type = container_of(type,
+               struct bt_ctf_field_type_enumeration, parent);
+
+       /* Safe to assume that container is an integer */
+       bt_ctf_field_type_integer_set_byte_order(enum_type->container,
+               byte_order);
+}
+
+static
+void bt_ctf_field_type_floating_point_set_byte_order(
+               struct bt_ctf_field_type *type, enum bt_ctf_byte_order byte_order)
+{
+       struct bt_ctf_field_type_floating_point *floating_point_type =
+               container_of(type, struct bt_ctf_field_type_floating_point,
+               parent);
+
+       floating_point_type->user_byte_order = byte_order;
+}
+
+static
+void bt_ctf_field_type_structure_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       int i;
+       struct bt_ctf_field_type_structure *structure_type =
+               container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+
+       for (i = 0; i < structure_type->fields->len; i++) {
+               struct structure_field *field = g_ptr_array_index(
+                       structure_type->fields, i);
+               struct bt_ctf_field_type *field_type = field->type;
+
+               if (set_byte_order_funcs[field_type->id]) {
+                       set_byte_order_funcs[field_type->id](
+                               field_type, byte_order);
+               }
+       }
+}
+
+static
+void bt_ctf_field_type_variant_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       int i;
+       struct bt_ctf_field_type_variant *variant_type =
+               container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+
+       for (i = 0; i < variant_type->fields->len; i++) {
+               struct structure_field *field = g_ptr_array_index(
+                       variant_type->fields, i);
+               struct bt_ctf_field_type *field_type = field->type;
+
+               if (set_byte_order_funcs[field_type->id]) {
+                       set_byte_order_funcs[field_type->id](
+                               field_type, byte_order);
+               }
+       }
+}
+
+static
+void bt_ctf_field_type_array_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       struct bt_ctf_field_type_array *array_type =
+               container_of(type, struct bt_ctf_field_type_array,
+               parent);
+
+       if (set_byte_order_funcs[array_type->element_type->id]) {
+               set_byte_order_funcs[array_type->element_type->id](
+                       array_type->element_type, byte_order);
+       }
+}
+
+static
+void bt_ctf_field_type_sequence_set_byte_order(struct bt_ctf_field_type *type,
+               enum bt_ctf_byte_order byte_order)
+{
+       struct bt_ctf_field_type_sequence *sequence_type =
+               container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+
+       if (set_byte_order_funcs[
+               sequence_type->element_type->id]) {
+               set_byte_order_funcs[
+                       sequence_type->element_type->id](
+                       sequence_type->element_type, byte_order);
+       }
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_integer_copy(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy;
+       struct bt_ctf_field_type_integer *integer, *copy_integer;
+
+       integer = container_of(type, struct bt_ctf_field_type_integer, parent);
+       copy = bt_ctf_field_type_integer_create(integer->size);
+       if (!copy) {
+               goto end;
+       }
+
+       copy_integer = container_of(copy, struct bt_ctf_field_type_integer,
+               parent);
+       copy_integer->mapped_clock = bt_get(integer->mapped_clock);
+       copy_integer->user_byte_order = integer->user_byte_order;
+       copy_integer->is_signed = integer->is_signed;
+       copy_integer->size = integer->size;
+       copy_integer->base = integer->base;
+       copy_integer->encoding = integer->encoding;
+
+end:
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_enumeration_copy(
+               struct bt_ctf_field_type *type)
+{
+       size_t i;
+       struct bt_ctf_field_type *copy = NULL, *copy_container;
+       struct bt_ctf_field_type_enumeration *enumeration, *copy_enumeration;
+
+       enumeration = container_of(type, struct bt_ctf_field_type_enumeration,
+               parent);
+
+       /* Copy the source enumeration's container */
+       copy_container = bt_ctf_field_type_copy(enumeration->container);
+       if (!copy_container) {
+               goto end;
+       }
+
+       copy = bt_ctf_field_type_enumeration_create(copy_container);
+       if (!copy) {
+               goto end;
+       }
+       copy_enumeration = container_of(copy,
+               struct bt_ctf_field_type_enumeration, parent);
+
+       /* Copy all enumaration entries */
+       for (i = 0; i < enumeration->entries->len; i++) {
+               struct enumeration_mapping *mapping = g_ptr_array_index(
+                       enumeration->entries, i);
+               struct enumeration_mapping *copy_mapping = g_new0(
+                       struct enumeration_mapping, 1);
+
+               if (!copy_mapping) {
+                       goto error;
+               }
+
+               *copy_mapping = *mapping;
+               g_ptr_array_add(copy_enumeration->entries, copy_mapping);
+       }
+
+end:
+       bt_put(copy_container);
+       return copy;
+error:
+       bt_put(copy_container);
+        BT_PUT(copy);
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_floating_point_copy(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy;
+       struct bt_ctf_field_type_floating_point *floating_point, *copy_float;
+
+       floating_point = container_of(type,
+               struct bt_ctf_field_type_floating_point, parent);
+       copy = bt_ctf_field_type_floating_point_create();
+       if (!copy) {
+               goto end;
+       }
+
+       copy_float = container_of(copy,
+               struct bt_ctf_field_type_floating_point, parent);
+       copy_float->user_byte_order = floating_point->user_byte_order;
+       copy_float->exp_dig = floating_point->exp_dig;
+       copy_float->mant_dig = floating_point->mant_dig;
+end:
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_structure_copy(
+               struct bt_ctf_field_type *type)
+{
+       int i;
+       GHashTableIter iter;
+       gpointer key, value;
+       struct bt_ctf_field_type *copy;
+       struct bt_ctf_field_type_structure *structure, *copy_structure;
+
+       structure = container_of(type, struct bt_ctf_field_type_structure,
+               parent);
+       copy = bt_ctf_field_type_structure_create();
+       if (!copy) {
+               goto end;
+       }
+
+       copy_structure = container_of(copy,
+               struct bt_ctf_field_type_structure, parent);
+
+       /* Copy field_name_to_index */
+       g_hash_table_iter_init(&iter, structure->field_name_to_index);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               g_hash_table_insert(copy_structure->field_name_to_index,
+                       key, value);
+       }
+
+       for (i = 0; i < structure->fields->len; i++) {
+               struct structure_field *entry, *copy_entry;
+               struct bt_ctf_field_type *copy_field;
+
+               copy_entry = g_new0(struct structure_field, 1);
+               if (!copy_entry) {
+                       goto error;
+               }
+
+               entry = g_ptr_array_index(structure->fields, i);
+               copy_field = bt_ctf_field_type_copy(entry->type);
+               if (!copy_field) {
+                       g_free(copy_entry);
+                       goto error;
+               }
+
+               copy_entry->name = entry->name;
+               copy_entry->type = copy_field;
+               g_ptr_array_add(copy_structure->fields, copy_entry);
+       }
+
+end:
+       return copy;
+error:
+        BT_PUT(copy);
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_variant_copy(
+               struct bt_ctf_field_type *type)
+{
+       int i;
+       GHashTableIter iter;
+       gpointer key, value;
+       struct bt_ctf_field_type *copy = NULL, *copy_tag = NULL;
+       struct bt_ctf_field_type_variant *variant, *copy_variant;
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+               parent);
+       if (variant->tag) {
+               copy_tag = bt_ctf_field_type_copy(&variant->tag->parent);
+               if (!copy_tag) {
+                       goto end;
+               }
+       }
+
+       copy = bt_ctf_field_type_variant_create(copy_tag,
+               variant->tag_name->len ? variant->tag_name->str : NULL);
+       if (!copy) {
+               goto end;
+       }
+
+       copy_variant = container_of(copy, struct bt_ctf_field_type_variant,
+               parent);
+
+       /* Copy field_name_to_index */
+       g_hash_table_iter_init(&iter, variant->field_name_to_index);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               g_hash_table_insert(copy_variant->field_name_to_index,
+                       key, value);
+       }
+
+       for (i = 0; i < variant->fields->len; i++) {
+               struct structure_field *entry, *copy_entry;
+               struct bt_ctf_field_type *copy_field;
+
+               copy_entry = g_new0(struct structure_field, 1);
+               if (!copy_entry) {
+                       goto error;
+               }
+
+               entry = g_ptr_array_index(variant->fields, i);
+               copy_field = bt_ctf_field_type_copy(entry->type);
+               if (!copy_field) {
+                       g_free(copy_entry);
+                       goto error;
+               }
+
+               copy_entry->name = entry->name;
+               copy_entry->type = copy_field;
+               g_ptr_array_add(copy_variant->fields, copy_entry);
+       }
+
+       if (variant->tag_field_path) {
+               copy_variant->tag_field_path = bt_ctf_field_path_copy(
+                       variant->tag_field_path);
+               if (!copy_variant->tag_field_path) {
+                       goto error;
+               }
+       }
+end:
+       bt_put(copy_tag);
+       return copy;
+error:
+       bt_put(copy_tag);
+        BT_PUT(copy);
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_array_copy(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy = NULL, *copy_element;
+       struct bt_ctf_field_type_array *array;
+
+       array = container_of(type, struct bt_ctf_field_type_array,
+               parent);
+       copy_element = bt_ctf_field_type_copy(array->element_type);
+       if (!copy_element) {
+               goto end;
+       }
+
+       copy = bt_ctf_field_type_array_create(copy_element, array->length);
+       if (!copy) {
+               goto end;
+       }
+end:
+       bt_put(copy_element);
+       return copy;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_copy(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy = NULL, *copy_element;
+       struct bt_ctf_field_type_sequence *sequence, *copy_sequence;
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+               parent);
+       copy_element = bt_ctf_field_type_copy(sequence->element_type);
+       if (!copy_element) {
+               goto end;
+       }
+
+       copy = bt_ctf_field_type_sequence_create(copy_element,
+               sequence->length_field_name->len ?
+                       sequence->length_field_name->str : NULL);
+       if (!copy) {
+               goto end;
+       }
+
+       copy_sequence = container_of(copy, struct bt_ctf_field_type_sequence,
+               parent);
+       if (sequence->length_field_path) {
+               copy_sequence->length_field_path = bt_ctf_field_path_copy(
+                       sequence->length_field_path);
+               if (!copy_sequence->length_field_path) {
+                       goto error;
+               }
+       }
+end:
+       bt_put(copy_element);
+       return copy;
+error:
+       BT_PUT(copy);
+       goto end;
+}
+
+static
+struct bt_ctf_field_type *bt_ctf_field_type_string_copy(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type *copy;
+       struct bt_ctf_field_type_string *string;
+
+       copy = bt_ctf_field_type_string_create();
+       if (!copy) {
+               goto end;
+       }
+
+       string = container_of(type, struct bt_ctf_field_type_string,
+               parent);
+end:
+       return copy;
+}
+
+static
+int bt_ctf_field_type_integer_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       struct bt_ctf_field_type_integer *int_type_a;
+       struct bt_ctf_field_type_integer *int_type_b;
+
+       int_type_a = container_of(type_a, struct bt_ctf_field_type_integer,
+               parent);
+       int_type_b = container_of(type_b, struct bt_ctf_field_type_integer,
+               parent);
+
+       /* Length */
+       if (int_type_a->size != int_type_b->size) {
+               goto end;
+       }
+
+       /* Byte order */
+       if (int_type_a->user_byte_order != int_type_b->user_byte_order) {
+               goto end;
+       }
+
+       /* Signedness */
+       if (int_type_a->is_signed != int_type_b->is_signed) {
+               goto end;
+       }
+
+       /* Base */
+       if (int_type_a->base != int_type_b->base) {
+               goto end;
+       }
+
+       /* Encoding */
+       if (int_type_a->encoding != int_type_b->encoding) {
+               goto end;
+       }
+
+       /* Mapped clock */
+       if (int_type_a->mapped_clock != int_type_b->mapped_clock) {
+               goto end;
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_floating_point_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       struct bt_ctf_field_type_floating_point *float_a;
+       struct bt_ctf_field_type_floating_point *float_b;
+
+       float_a = container_of(type_a,
+               struct bt_ctf_field_type_floating_point, parent);
+       float_b = container_of(type_b,
+               struct bt_ctf_field_type_floating_point, parent);
+
+       /* Byte order */
+       if (float_a->user_byte_order != float_b->user_byte_order) {
+               goto end;
+       }
+
+       /* Exponent length */
+       if (float_a->exp_dig != float_b->exp_dig) {
+               goto end;
+       }
+
+       /* Mantissa length */
+       if (float_a->mant_dig != float_b->mant_dig) {
+               goto end;
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int compare_enumeration_mappings(struct enumeration_mapping *mapping_a,
+               struct enumeration_mapping *mapping_b)
+{
+       int ret = 1;
+
+       /* Label */
+       if (mapping_a->string != mapping_b->string) {
+               goto end;
+       }
+
+       /* Range start */
+       if (mapping_a->range_start._unsigned !=
+                       mapping_b->range_start._unsigned) {
+               goto end;
+       }
+
+       /* Range end */
+       if (mapping_a->range_end._unsigned !=
+                       mapping_b->range_end._unsigned) {
+               goto end;
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_enumeration_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       int i;
+       struct bt_ctf_field_type_enumeration *enum_a;
+       struct bt_ctf_field_type_enumeration *enum_b;
+
+       enum_a = container_of(type_a,
+               struct bt_ctf_field_type_enumeration, parent);
+       enum_b = container_of(type_b,
+               struct bt_ctf_field_type_enumeration, parent);
+
+       /* Container field type */
+       ret = bt_ctf_field_type_compare(enum_a->container, enum_b->container);
+       if (ret) {
+               goto end;
+       }
+
+       ret = 1;
+
+       /* Entries */
+       if (enum_a->entries->len != enum_b->entries->len) {
+               goto end;
+       }
+
+       for (i = 0; i < enum_a->entries->len; ++i) {
+               struct enumeration_mapping *mapping_a =
+                       g_ptr_array_index(enum_a->entries, i);
+               struct enumeration_mapping *mapping_b =
+                       g_ptr_array_index(enum_b->entries, i);
+
+               if (compare_enumeration_mappings(mapping_a, mapping_b)) {
+                       goto end;
+               }
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_string_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       struct bt_ctf_field_type_string *string_a;
+       struct bt_ctf_field_type_string *string_b;
+
+       string_a = container_of(type_a,
+               struct bt_ctf_field_type_string, parent);
+       string_b = container_of(type_b,
+               struct bt_ctf_field_type_string, parent);
+
+       /* Encoding */
+       if (string_a->encoding != string_b->encoding) {
+               goto end;
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int compare_structure_fields(struct structure_field *field_a,
+               struct structure_field *field_b)
+{
+       int ret = 1;
+
+       /* Label */
+       if (field_a->name != field_b->name) {
+               goto end;
+       }
+
+       /* Type */
+       ret = bt_ctf_field_type_compare(field_a->type, field_b->type);
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_structure_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       int i;
+       struct bt_ctf_field_type_structure *struct_a;
+       struct bt_ctf_field_type_structure *struct_b;
+
+       struct_a = container_of(type_a,
+               struct bt_ctf_field_type_structure, parent);
+       struct_b = container_of(type_b,
+               struct bt_ctf_field_type_structure, parent);
+
+       /* Alignment */
+       if (bt_ctf_field_type_get_alignment(type_a) !=
+                       bt_ctf_field_type_get_alignment(type_b)) {
+               goto end;
+       }
+
+       /* Fields */
+       if (struct_a->fields->len != struct_b->fields->len) {
+               goto end;
+       }
+
+       for (i = 0; i < struct_a->fields->len; ++i) {
+               struct structure_field *field_a =
+                       g_ptr_array_index(struct_a->fields, i);
+               struct structure_field *field_b =
+                       g_ptr_array_index(struct_b->fields, i);
+
+               ret = compare_structure_fields(field_a, field_b);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_variant_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       int i;
+       struct bt_ctf_field_type_variant *variant_a;
+       struct bt_ctf_field_type_variant *variant_b;
+
+       variant_a = container_of(type_a,
+               struct bt_ctf_field_type_variant, parent);
+       variant_b = container_of(type_b,
+               struct bt_ctf_field_type_variant, parent);
+
+       /* Tag name */
+       if (strcmp(variant_a->tag_name->str, variant_b->tag_name->str)) {
+               goto end;
+       }
+
+       /* Tag type */
+       ret = bt_ctf_field_type_compare(
+               (struct bt_ctf_field_type *) variant_a->tag,
+               (struct bt_ctf_field_type *) variant_b->tag);
+       if (ret) {
+               goto end;
+       }
+
+       ret = 1;
+
+       /* Fields */
+       if (variant_a->fields->len != variant_b->fields->len) {
+               goto end;
+       }
+
+       for (i = 0; i < variant_a->fields->len; ++i) {
+               struct structure_field *field_a =
+                       g_ptr_array_index(variant_a->fields, i);
+               struct structure_field *field_b =
+                       g_ptr_array_index(variant_b->fields, i);
+
+               ret = compare_structure_fields(field_a, field_b);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       /* Equal */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_array_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+       struct bt_ctf_field_type_array *array_a;
+       struct bt_ctf_field_type_array *array_b;
+
+       array_a = container_of(type_a,
+               struct bt_ctf_field_type_array, parent);
+       array_b = container_of(type_b,
+               struct bt_ctf_field_type_array, parent);
+
+       /* Length */
+       if (array_a->length != array_b->length) {
+               goto end;
+       }
+
+       /* Element type */
+       ret = bt_ctf_field_type_compare(array_a->element_type,
+               array_b->element_type);
+
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_type_sequence_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = -1;
+       struct bt_ctf_field_type_sequence *sequence_a;
+       struct bt_ctf_field_type_sequence *sequence_b;
+
+       sequence_a = container_of(type_a,
+               struct bt_ctf_field_type_sequence, parent);
+       sequence_b = container_of(type_b,
+               struct bt_ctf_field_type_sequence, parent);
+
+       /* Length name */
+       if (strcmp(sequence_a->length_field_name->str,
+                       sequence_b->length_field_name->str)) {
+               goto end;
+       }
+
+       /* Element type */
+       ret = bt_ctf_field_type_compare(sequence_a->element_type,
+                       sequence_b->element_type);
+
+end:
+       return ret;
+}
+
+int bt_ctf_field_type_compare(struct bt_ctf_field_type *type_a,
+               struct bt_ctf_field_type *type_b)
+{
+       int ret = 1;
+
+       if (type_a == type_b) {
+               /* Same reference: equal (even if both are NULL) */
+               ret = 0;
+               goto end;
+       }
+
+       if (!type_a || !type_b) {
+               ret = -1;
+               goto end;
+       }
+
+       if (type_a->id != type_b->id) {
+               /* Different type IDs */
+               goto end;
+       }
+
+       if (type_a->id == BT_CTF_TYPE_ID_UNKNOWN) {
+               /* Both have unknown type IDs */
+               goto end;
+       }
+
+       ret = type_compare_funcs[type_a->id](type_a, type_b);
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_get_field_count(struct bt_ctf_field_type *field_type)
+{
+       int field_count = -1;
+       enum bt_ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
+
+       switch (type_id) {
+       case CTF_TYPE_STRUCT:
+               field_count =
+                       bt_ctf_field_type_structure_get_field_count(field_type);
+               break;
+       case CTF_TYPE_VARIANT:
+               field_count =
+                       bt_ctf_field_type_variant_get_field_count(field_type);
+               break;
+       case CTF_TYPE_ARRAY:
+       case CTF_TYPE_SEQUENCE:
+               /*
+                * Array and sequence types always contain a single member
+                * (the element type).
+                */
+               field_count = 1;
+               break;
+       default:
+               break;
+       }
+
+       return field_count;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type *bt_ctf_field_type_get_field_at_index(
+               struct bt_ctf_field_type *field_type, int index)
+{
+       struct bt_ctf_field_type *field = NULL;
+       enum bt_ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
+
+       switch (type_id) {
+       case CTF_TYPE_STRUCT:
+               bt_ctf_field_type_structure_get_field(field_type, NULL, &field,
+                       index);
+               break;
+       case CTF_TYPE_VARIANT:
+       {
+               int ret = bt_ctf_field_type_variant_get_field(field_type, NULL,
+                       &field, index);
+               if (ret) {
+                       field = NULL;
+                       goto end;
+               }
+               break;
+       }
+       case CTF_TYPE_ARRAY:
+               field = bt_ctf_field_type_array_get_element_type(field_type);
+               break;
+       case CTF_TYPE_SEQUENCE:
+               field = bt_ctf_field_type_sequence_get_element_type(field_type);
+               break;
+       default:
+               break;
+       }
+end:
+       return field;
+}
+
+BT_HIDDEN
+int bt_ctf_field_type_get_field_index(struct bt_ctf_field_type *field_type,
+               const char *name)
+{
+       int field_index = -1;
+       enum bt_ctf_type_id type_id = bt_ctf_field_type_get_type_id(field_type);
+
+       switch (type_id) {
+       case CTF_TYPE_STRUCT:
+               field_index = bt_ctf_field_type_structure_get_field_name_index(
+                       field_type, name);
+               break;
+       case CTF_TYPE_VARIANT:
+               field_index = bt_ctf_field_type_variant_get_field_name_index(
+                       field_type, name);
+               break;
+       default:
+               break;
+       }
+
+       return field_index;
+}
+
+struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_path *field_path = NULL;
+       struct bt_ctf_field_type_variant *variant;
+
+       if (!type || !bt_ctf_field_type_is_variant(type)) {
+               goto end;
+       }
+
+       variant = container_of(type, struct bt_ctf_field_type_variant,
+                       parent);
+       field_path = bt_get(variant->tag_field_path);
+end:
+       return field_path;
+}
+
+struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
+               struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_path *field_path = NULL;
+       struct bt_ctf_field_type_sequence *sequence;
+
+       if (!type || !bt_ctf_field_type_is_sequence(type)) {
+               goto end;
+       }
+
+       sequence = container_of(type, struct bt_ctf_field_type_sequence,
+                       parent);
+       field_path = bt_get(sequence->length_field_path);
+end:
+       return field_path;
+}
diff --git a/lib/ctf-ir/fields.c b/lib/ctf-ir/fields.c
new file mode 100644 (file)
index 0000000..eb98259
--- /dev/null
@@ -0,0 +1,2533 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/compat/fcntl.h>
+#include <babeltrace/align.h>
+
+#define PACKET_LEN_INCREMENT   (getpagesize() * 8 * CHAR_BIT)
+
+static
+struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_enumeration_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_floating_point_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_structure_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_variant_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_array_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_sequence_create(
+               struct bt_ctf_field_type *);
+static
+struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *);
+
+static
+void bt_ctf_field_destroy(struct bt_object *);
+static
+void bt_ctf_field_integer_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_structure_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_variant_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_array_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_sequence_destroy(struct bt_ctf_field *);
+static
+void bt_ctf_field_string_destroy(struct bt_ctf_field *);
+
+static
+int bt_ctf_field_generic_validate(struct bt_ctf_field *);
+static
+int bt_ctf_field_structure_validate(struct bt_ctf_field *);
+static
+int bt_ctf_field_variant_validate(struct bt_ctf_field *);
+static
+int bt_ctf_field_enumeration_validate(struct bt_ctf_field *);
+static
+int bt_ctf_field_array_validate(struct bt_ctf_field *);
+static
+int bt_ctf_field_sequence_validate(struct bt_ctf_field *);
+
+static
+int bt_ctf_field_generic_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_structure_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_variant_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_enumeration_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_array_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_sequence_reset(struct bt_ctf_field *);
+static
+int bt_ctf_field_string_reset(struct bt_ctf_field *);
+
+static
+int bt_ctf_field_integer_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_structure_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_variant_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_array_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_sequence_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+static
+int bt_ctf_field_string_serialize(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order);
+
+static
+int bt_ctf_field_integer_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_enumeration_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_floating_point_copy(struct bt_ctf_field *,
+               struct bt_ctf_field *);
+static
+int bt_ctf_field_structure_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_variant_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_array_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_sequence_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+static
+int bt_ctf_field_string_copy(struct bt_ctf_field *, struct bt_ctf_field *);
+
+static
+void generic_field_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_structure_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_variant_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_array_freeze(struct bt_ctf_field *);
+static
+void bt_ctf_field_sequence_freeze(struct bt_ctf_field *);
+
+static
+bool bt_ctf_field_generic_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_structure_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_variant_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_array_is_set(struct bt_ctf_field *);
+static
+bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *);
+
+static
+int increase_packet_size(struct bt_ctf_stream_pos *pos);
+
+static
+struct bt_ctf_field *(* const field_create_funcs[])(
+               struct bt_ctf_field_type *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_create,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_create,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_floating_point_create,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_create,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_create,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_create,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_create,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_create,
+};
+
+static
+void (* const field_destroy_funcs[])(struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_destroy,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_destroy,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_floating_point_destroy,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_destroy,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_destroy,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_destroy,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_destroy,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_destroy,
+};
+
+static
+int (* const field_validate_funcs[])(struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_validate,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_validate,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_validate,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_validate,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_validate,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_validate,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_validate,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_validate,
+};
+
+static
+int (* const field_reset_funcs[])(struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_reset,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_reset,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_reset,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_reset,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_reset,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_reset,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_reset,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_reset,
+};
+
+static
+int (* const field_serialize_funcs[])(struct bt_ctf_field *,
+               struct bt_ctf_stream_pos *, enum bt_ctf_byte_order) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_serialize,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_serialize,
+       [BT_CTF_TYPE_ID_FLOAT] =
+               bt_ctf_field_floating_point_serialize,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_serialize,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_serialize,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_serialize,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_serialize,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_serialize,
+};
+
+static
+int (* const field_copy_funcs[])(struct bt_ctf_field *,
+               struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_integer_copy,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_copy,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_floating_point_copy,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_copy,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_copy,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_copy,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_copy,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_string_copy,
+};
+
+static
+void (* const field_freeze_funcs[])(struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = generic_field_freeze,
+       [BT_CTF_TYPE_ID_FLOAT] = generic_field_freeze,
+       [BT_CTF_TYPE_ID_STRING] = generic_field_freeze,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_freeze,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_freeze,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_freeze,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_freeze,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_freeze,
+};
+
+static
+bool (* const field_is_set_funcs[])(struct bt_ctf_field *) = {
+       [BT_CTF_TYPE_ID_INTEGER] = bt_ctf_field_generic_is_set,
+       [BT_CTF_TYPE_ID_ENUM] = bt_ctf_field_enumeration_is_set,
+       [BT_CTF_TYPE_ID_FLOAT] = bt_ctf_field_generic_is_set,
+       [BT_CTF_TYPE_ID_STRUCT] = bt_ctf_field_structure_is_set,
+       [BT_CTF_TYPE_ID_VARIANT] = bt_ctf_field_variant_is_set,
+       [BT_CTF_TYPE_ID_ARRAY] = bt_ctf_field_array_is_set,
+       [BT_CTF_TYPE_ID_SEQUENCE] = bt_ctf_field_sequence_is_set,
+       [BT_CTF_TYPE_ID_STRING] = bt_ctf_field_generic_is_set,
+};
+
+struct bt_ctf_field *bt_ctf_field_create(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field *field = NULL;
+       enum bt_ctf_type_id type_id;
+       int ret;
+
+       if (!type) {
+               goto error;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
+                       type_id >= BT_CTF_NR_TYPE_IDS) {
+               goto error;
+       }
+
+       /* Field class MUST be valid */
+       ret = bt_ctf_field_type_validate(type);
+
+       if (ret) {
+               /* Invalid */
+               goto error;
+       }
+
+       field = field_create_funcs[type_id](type);
+       if (!field) {
+               goto error;
+       }
+
+       /* The type's declaration can't change after this point */
+       bt_ctf_field_type_freeze(type);
+       bt_get(type);
+       bt_object_init(field, bt_ctf_field_destroy);
+       field->type = type;
+error:
+       return field;
+}
+
+void bt_ctf_field_get(struct bt_ctf_field *field)
+{
+       bt_get(field);
+}
+
+void bt_ctf_field_put(struct bt_ctf_field *field)
+{
+       bt_put(field);
+}
+
+struct bt_ctf_field_type *bt_ctf_field_get_type(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_type *ret = NULL;
+
+       if (!field) {
+               goto end;
+       }
+
+       ret = field->type;
+       bt_get(ret);
+end:
+       return ret;
+}
+
+enum bt_ctf_type_id bt_ctf_field_get_type_id(struct bt_ctf_field *field)
+{
+       enum bt_ctf_type_id ret = BT_CTF_TYPE_ID_UNKNOWN;
+
+       if (!field) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_get_type_id(field->type);
+end:
+       return ret;
+}
+
+int bt_ctf_field_is_integer(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_INTEGER;
+}
+
+int bt_ctf_field_is_floating_point(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_FLOAT;
+}
+
+int bt_ctf_field_is_enumeration(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ENUM;
+}
+
+int bt_ctf_field_is_string(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRING;
+}
+
+int bt_ctf_field_is_structure(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_STRUCT;
+}
+
+int bt_ctf_field_is_array(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_ARRAY;
+}
+
+int bt_ctf_field_is_sequence(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_SEQUENCE;
+}
+
+int bt_ctf_field_is_variant(struct bt_ctf_field *field)
+{
+       return bt_ctf_field_get_type_id(field) == BT_CTF_TYPE_ID_VARIANT;
+}
+
+struct bt_ctf_field *bt_ctf_field_sequence_get_length(
+               struct bt_ctf_field *field)
+{
+       struct bt_ctf_field *ret = NULL;
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field) {
+               goto end;
+       }
+
+       if (bt_ctf_field_type_get_type_id(field->type) !=
+               BT_CTF_TYPE_ID_SEQUENCE) {
+               goto end;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       ret = sequence->length;
+       bt_get(ret);
+end:
+       return ret;
+}
+
+int bt_ctf_field_sequence_set_length(struct bt_ctf_field *field,
+               struct bt_ctf_field *length_field)
+{
+       int ret = 0;
+       struct bt_ctf_field_type_integer *length_type;
+       struct bt_ctf_field_integer *length;
+       struct bt_ctf_field_sequence *sequence;
+       uint64_t sequence_length;
+
+       if (!field || !length_field || field->frozen) {
+               ret = -1;
+               goto end;
+       }
+       if (bt_ctf_field_type_get_type_id(length_field->type) !=
+               BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       length_type = container_of(length_field->type,
+               struct bt_ctf_field_type_integer, parent);
+       /* The length field must be unsigned */
+       if (length_type->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+       length = container_of(length_field, struct bt_ctf_field_integer,
+               parent);
+       sequence_length = length->payload.unsignd;
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       if (sequence->elements) {
+               g_ptr_array_free(sequence->elements, TRUE);
+               bt_put(sequence->length);
+       }
+
+       sequence->elements = g_ptr_array_sized_new((size_t)sequence_length);
+       if (!sequence->elements) {
+               ret = -1;
+               goto end;
+       }
+
+       g_ptr_array_set_free_func(sequence->elements,
+               (GDestroyNotify) bt_put);
+       g_ptr_array_set_size(sequence->elements, (size_t) sequence_length);
+       bt_get(length_field);
+       sequence->length = length_field;
+end:
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_field_structure_get_field(
+               struct bt_ctf_field *field, const char *name)
+{
+       struct bt_ctf_field *new_field = NULL;
+       GQuark field_quark;
+       struct bt_ctf_field_structure *structure;
+       struct bt_ctf_field_type *field_type = NULL;
+       size_t index;
+
+       if (!field || !name ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRUCT) {
+               goto error;
+       }
+
+       field_quark = g_quark_from_string(name);
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       field_type =
+               bt_ctf_field_type_structure_get_field_type_by_name(field->type,
+               name);
+       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
+               GUINT_TO_POINTER(field_quark), NULL, (gpointer *)&index)) {
+               goto error;
+       }
+
+       if (structure->fields->pdata[index]) {
+               new_field = structure->fields->pdata[index];
+               goto end;
+       }
+
+       /* We don't want to modify this field if it's frozen */
+       if (field->frozen) {
+               goto end;
+       }
+
+       new_field = bt_ctf_field_create(field_type);
+       if (!new_field) {
+               goto error;
+       }
+
+       structure->fields->pdata[index] = new_field;
+end:
+       bt_get(new_field);
+error:
+       if (field_type) {
+               bt_put(field_type);
+       }
+       return new_field;
+}
+
+struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
+               struct bt_ctf_field *field, int index)
+{
+       int ret;
+       const char *field_name;
+       struct bt_ctf_field_structure *structure;
+       struct bt_ctf_field_type *structure_type;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_field *ret_field = NULL;
+
+       if (!field ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+               BT_CTF_TYPE_ID_STRUCT) {
+               goto end;
+       }
+
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       if (index >= structure->fields->len) {
+               goto error;
+       }
+
+       ret_field = structure->fields->pdata[index];
+       if (ret_field) {
+               goto end;
+       }
+
+       /* We don't want to modify this field if it's frozen */
+       if (field->frozen) {
+               goto end;
+       }
+
+       /* Field has not been instanciated yet, create it */
+       structure_type = bt_ctf_field_get_type(field);
+       if (!structure_type) {
+               goto error;
+       }
+
+       ret = bt_ctf_field_type_structure_get_field(structure_type,
+               &field_name, &field_type, index);
+       bt_put(structure_type);
+       if (ret) {
+               goto error;
+       }
+
+       ret_field = bt_ctf_field_create(field_type);
+       if (!ret_field) {
+               goto error;
+       }
+
+       structure->fields->pdata[index] = ret_field;
+end:
+       bt_get(ret_field);
+error:
+       bt_put(field_type);
+       return ret_field;
+}
+
+BT_HIDDEN
+int bt_ctf_field_structure_set_field(struct bt_ctf_field *field,
+               const char *name, struct bt_ctf_field *value)
+{
+       int ret = 0;
+       GQuark field_quark;
+       struct bt_ctf_field_structure *structure;
+       struct bt_ctf_field_type *expected_field_type = NULL;
+       size_t index;
+
+       if (!field || !name || !value || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       field_quark = g_quark_from_string(name);
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       expected_field_type =
+               bt_ctf_field_type_structure_get_field_type_by_name(field->type,
+               name);
+
+       if (bt_ctf_field_type_compare(expected_field_type, value->type)) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!g_hash_table_lookup_extended(structure->field_name_to_index,
+               GUINT_TO_POINTER(field_quark), NULL, (gpointer *) &index)) {
+               goto end;
+       }
+
+       if (structure->fields->pdata[index]) {
+               bt_put(structure->fields->pdata[index]);
+       }
+
+       structure->fields->pdata[index] = value;
+       bt_get(value);
+end:
+       if (expected_field_type) {
+               bt_put(expected_field_type);
+       }
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_field_array_get_field(struct bt_ctf_field *field,
+               uint64_t index)
+{
+       struct bt_ctf_field *new_field = NULL;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_field_array *array;
+
+       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
+               BT_CTF_TYPE_ID_ARRAY) {
+               goto end;
+       }
+
+       array = container_of(field, struct bt_ctf_field_array, parent);
+       if (index >= array->elements->len) {
+               goto end;
+       }
+
+       field_type = bt_ctf_field_type_array_get_element_type(field->type);
+       if (array->elements->pdata[(size_t)index]) {
+               new_field = array->elements->pdata[(size_t)index];
+               goto end;
+       }
+
+       /* We don't want to modify this field if it's frozen */
+       if (field->frozen) {
+               goto end;
+       }
+
+       new_field = bt_ctf_field_create(field_type);
+       array->elements->pdata[(size_t)index] = new_field;
+end:
+       if (field_type) {
+               bt_put(field_type);
+       }
+       if (new_field) {
+               bt_get(new_field);
+       }
+       return new_field;
+}
+
+struct bt_ctf_field *bt_ctf_field_sequence_get_field(struct bt_ctf_field *field,
+               uint64_t index)
+{
+       struct bt_ctf_field *new_field = NULL;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
+               BT_CTF_TYPE_ID_SEQUENCE) {
+               goto end;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       if (!sequence->elements || sequence->elements->len <= index) {
+               goto end;
+       }
+
+       field_type = bt_ctf_field_type_sequence_get_element_type(field->type);
+       if (sequence->elements->pdata[(size_t) index]) {
+               new_field = sequence->elements->pdata[(size_t) index];
+               goto end;
+       }
+
+       /* We don't want to modify this field if it's frozen */
+       if (field->frozen) {
+               goto end;
+       }
+
+       new_field = bt_ctf_field_create(field_type);
+       sequence->elements->pdata[(size_t) index] = new_field;
+end:
+       if (field_type) {
+               bt_put(field_type);
+       }
+       if (new_field) {
+               bt_get(new_field);
+       }
+       return new_field;
+}
+
+struct bt_ctf_field *bt_ctf_field_variant_get_field(struct bt_ctf_field *field,
+               struct bt_ctf_field *tag_field)
+{
+       struct bt_ctf_field *new_field = NULL;
+       struct bt_ctf_field_variant *variant;
+       struct bt_ctf_field_type_variant *variant_type;
+       struct bt_ctf_field_type *field_type;
+       struct bt_ctf_field *tag_enum = NULL;
+       struct bt_ctf_field_integer *tag_enum_integer;
+       int64_t tag_enum_value;
+
+       if (!field || !tag_field ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_VARIANT ||
+               bt_ctf_field_type_get_type_id(tag_field->type) !=
+                       BT_CTF_TYPE_ID_ENUM) {
+               goto end;
+       }
+
+       variant = container_of(field, struct bt_ctf_field_variant, parent);
+       variant_type = container_of(field->type,
+               struct bt_ctf_field_type_variant, parent);
+       tag_enum = bt_ctf_field_enumeration_get_container(tag_field);
+       if (!tag_enum) {
+               goto end;
+       }
+
+       tag_enum_integer = container_of(tag_enum, struct bt_ctf_field_integer,
+               parent);
+
+       if (bt_ctf_field_validate(tag_field) < 0) {
+               goto end;
+       }
+
+       tag_enum_value = tag_enum_integer->payload.signd;
+
+       /*
+        * If the variant currently has a tag and a payload, and if the
+        * requested tag value is the same as the current one, return
+        * the current payload instead of creating a fresh one.
+        */
+       if (variant->tag && variant->payload) {
+               struct bt_ctf_field *cur_tag_container = NULL;
+               struct bt_ctf_field_integer *cur_tag_enum_integer;
+               int64_t cur_tag_value;
+
+               cur_tag_container =
+                       bt_ctf_field_enumeration_get_container(variant->tag);
+               assert(cur_tag_container);
+               cur_tag_enum_integer = container_of(cur_tag_container,
+                       struct bt_ctf_field_integer, parent);
+               bt_put(cur_tag_container);
+               cur_tag_value = cur_tag_enum_integer->payload.signd;
+
+               if (cur_tag_value == tag_enum_value) {
+                       new_field = variant->payload;
+                       bt_get(new_field);
+                       goto end;
+               }
+       }
+
+       /* We don't want to modify this field if it's frozen */
+       if (field->frozen) {
+               goto end;
+       }
+
+       field_type = bt_ctf_field_type_variant_get_field_type_signed(
+               variant_type, tag_enum_value);
+       if (!field_type) {
+               goto end;
+       }
+
+       new_field = bt_ctf_field_create(field_type);
+       if (!new_field) {
+               goto end;
+       }
+
+       bt_put(variant->tag);
+       bt_put(variant->payload);
+       bt_get(new_field);
+       bt_get(tag_field);
+       variant->tag = tag_field;
+       variant->payload = new_field;
+end:
+       bt_put(tag_enum);
+       return new_field;
+}
+
+struct bt_ctf_field *bt_ctf_field_variant_get_current_field(
+               struct bt_ctf_field *variant_field)
+{
+       struct bt_ctf_field *current_field = NULL;
+       struct bt_ctf_field_variant *variant;
+
+       if (!variant_field ||
+               bt_ctf_field_type_get_type_id(variant_field->type) !=
+                       BT_CTF_TYPE_ID_VARIANT) {
+               goto end;
+       }
+
+       variant = container_of(variant_field, struct bt_ctf_field_variant,
+               parent);
+
+       if (variant->payload) {
+               current_field = variant->payload;
+               bt_get(current_field);
+               goto end;
+       }
+
+end:
+       return current_field;
+}
+
+struct bt_ctf_field *bt_ctf_field_variant_get_tag(
+               struct bt_ctf_field *variant_field)
+{
+       struct bt_ctf_field *tag = NULL;
+       struct bt_ctf_field_variant *variant;
+
+       if (!variant_field ||
+                       bt_ctf_field_type_get_type_id(variant_field->type) !=
+                       BT_CTF_TYPE_ID_VARIANT) {
+               goto end;
+       }
+
+       variant = container_of(variant_field, struct bt_ctf_field_variant,
+                       parent);
+       if (variant->tag) {
+               tag = bt_get(variant->tag);
+       }
+end:
+       return tag;
+}
+
+struct bt_ctf_field *bt_ctf_field_enumeration_get_container(
+       struct bt_ctf_field *field)
+{
+       struct bt_ctf_field *container = NULL;
+       struct bt_ctf_field_enumeration *enumeration;
+
+       if (!field || bt_ctf_field_type_get_type_id(field->type) !=
+               BT_CTF_TYPE_ID_ENUM) {
+               goto end;
+       }
+
+       enumeration = container_of(field, struct bt_ctf_field_enumeration,
+               parent);
+       if (!enumeration->payload) {
+               /* We don't want to modify this field if it's frozen */
+               if (field->frozen) {
+                       goto end;
+               }
+
+               struct bt_ctf_field_type_enumeration *enumeration_type =
+                       container_of(field->type,
+                       struct bt_ctf_field_type_enumeration, parent);
+               enumeration->payload =
+                       bt_ctf_field_create(enumeration_type->container);
+       }
+
+       container = enumeration->payload;
+       bt_get(container);
+end:
+       return container;
+}
+
+struct bt_ctf_field_type_enumeration_mapping_iterator *
+bt_ctf_field_enumeration_get_mappings(struct bt_ctf_field *field)
+{
+       int ret;
+       struct bt_ctf_field *container = NULL;
+       struct bt_ctf_field_type *container_type = NULL;
+       struct bt_ctf_field_type_integer *integer_type = NULL;
+       struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+
+       container = bt_ctf_field_enumeration_get_container(field);
+       if (!container) {
+               goto end;
+       }
+
+       container_type = bt_ctf_field_get_type(container);
+       if (!container_type) {
+               goto error_put_container;
+       }
+
+       integer_type = container_of(container_type,
+               struct bt_ctf_field_type_integer, parent);
+
+       if (!integer_type->is_signed) {
+               uint64_t value;
+
+               ret = bt_ctf_field_unsigned_integer_get_value(container,
+                     &value);
+               if (ret) {
+                       goto error_put_container_type;
+               }
+               iter = bt_ctf_field_type_enumeration_find_mappings_by_unsigned_value(
+                               field->type, value);
+       } else {
+               int64_t value;
+
+               ret = bt_ctf_field_signed_integer_get_value(container,
+                     &value);
+               if (ret) {
+                       goto error_put_container_type;
+               }
+               iter = bt_ctf_field_type_enumeration_find_mappings_by_signed_value(
+                               field->type, value);
+       }
+
+error_put_container_type:
+       bt_put(container_type);
+error_put_container:
+       bt_put(container);
+end:
+       return iter;
+}
+
+int bt_ctf_field_signed_integer_get_value(struct bt_ctf_field *field,
+               int64_t *value)
+{
+       int ret = 0;
+       struct bt_ctf_field_integer *integer;
+       struct bt_ctf_field_type_integer *integer_type;
+
+       if (!field || !value || !field->payload_set ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer_type = container_of(field->type,
+               struct bt_ctf_field_type_integer, parent);
+       if (!integer_type->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(field,
+               struct bt_ctf_field_integer, parent);
+       *value = integer->payload.signd;
+end:
+       return ret;
+}
+
+int bt_ctf_field_signed_integer_set_value(struct bt_ctf_field *field,
+               int64_t value)
+{
+       int ret = 0;
+       struct bt_ctf_field_integer *integer;
+       struct bt_ctf_field_type_integer *integer_type;
+       unsigned int size;
+       int64_t min_value, max_value;
+
+       if (!field || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(field, struct bt_ctf_field_integer, parent);
+       integer_type = container_of(field->type,
+               struct bt_ctf_field_type_integer, parent);
+       if (!integer_type->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+       size = integer_type->size;
+       min_value = -(1ULL << (size - 1));
+       max_value = (1ULL << (size - 1)) - 1;
+       if (value < min_value || value > max_value) {
+               ret = -1;
+               goto end;
+       }
+
+       integer->payload.signd = value;
+       integer->parent.payload_set = 1;
+end:
+       return ret;
+}
+
+int bt_ctf_field_unsigned_integer_get_value(struct bt_ctf_field *field,
+               uint64_t *value)
+{
+       int ret = 0;
+       struct bt_ctf_field_integer *integer;
+       struct bt_ctf_field_type_integer *integer_type;
+
+       if (!field || !value || !field->payload_set ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer_type = container_of(field->type,
+               struct bt_ctf_field_type_integer, parent);
+       if (integer_type->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(field,
+               struct bt_ctf_field_integer, parent);
+       *value = integer->payload.unsignd;
+end:
+       return ret;
+}
+
+int bt_ctf_field_unsigned_integer_set_value(struct bt_ctf_field *field,
+               uint64_t value)
+{
+       int ret = 0;
+       struct bt_ctf_field_integer *integer;
+       struct bt_ctf_field_type_integer *integer_type;
+       unsigned int size;
+       uint64_t max_value;
+
+       if (!field || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       integer = container_of(field, struct bt_ctf_field_integer, parent);
+       integer_type = container_of(field->type,
+               struct bt_ctf_field_type_integer, parent);
+       if (integer_type->is_signed) {
+               ret = -1;
+               goto end;
+       }
+
+       size = integer_type->size;
+       max_value = (size == 64) ? UINT64_MAX : ((uint64_t) 1 << size) - 1;
+       if (value > max_value) {
+               ret = -1;
+               goto end;
+       }
+
+       integer->payload.unsignd = value;
+       integer->parent.payload_set = 1;
+end:
+       return ret;
+}
+
+int bt_ctf_field_floating_point_get_value(struct bt_ctf_field *field,
+               double *value)
+{
+       int ret = 0;
+       struct bt_ctf_field_floating_point *floating_point;
+
+       if (!field || !value || !field->payload_set ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_FLOAT) {
+               ret = -1;
+               goto end;
+       }
+
+       floating_point = container_of(field,
+               struct bt_ctf_field_floating_point, parent);
+       *value = floating_point->payload;
+end:
+       return ret;
+}
+
+int bt_ctf_field_floating_point_set_value(struct bt_ctf_field *field,
+               double value)
+{
+       int ret = 0;
+       struct bt_ctf_field_floating_point *floating_point;
+
+       if (!field || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_FLOAT) {
+               ret = -1;
+               goto end;
+       }
+       floating_point = container_of(field, struct bt_ctf_field_floating_point,
+               parent);
+       floating_point->payload = value;
+       floating_point->parent.payload_set = 1;
+end:
+       return ret;
+}
+
+const char *bt_ctf_field_string_get_value(struct bt_ctf_field *field)
+{
+       const char *ret = NULL;
+       struct bt_ctf_field_string *string;
+
+       if (!field || !field->payload_set ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRING) {
+               goto end;
+       }
+
+       string = container_of(field,
+               struct bt_ctf_field_string, parent);
+       ret = string->payload->str;
+end:
+       return ret;
+}
+
+int bt_ctf_field_string_set_value(struct bt_ctf_field *field,
+               const char *value)
+{
+       int ret = 0;
+       struct bt_ctf_field_string *string;
+
+       if (!field || !value || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRING) {
+               ret = -1;
+               goto end;
+       }
+
+       string = container_of(field, struct bt_ctf_field_string, parent);
+       if (string->payload) {
+               g_string_assign(string->payload, value);
+       } else {
+               string->payload = g_string_new(value);
+       }
+
+       string->parent.payload_set = 1;
+end:
+       return ret;
+}
+
+int bt_ctf_field_string_append(struct bt_ctf_field *field,
+               const char *value)
+{
+       int ret = 0;
+       struct bt_ctf_field_string *string_field;
+
+       if (!field || !value || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRING) {
+               ret = -1;
+               goto end;
+       }
+
+       string_field = container_of(field, struct bt_ctf_field_string, parent);
+
+       if (string_field->payload) {
+               g_string_append(string_field->payload, value);
+       } else {
+               string_field->payload = g_string_new(value);
+       }
+
+       string_field->parent.payload_set = 1;
+
+end:
+       return ret;
+}
+
+int bt_ctf_field_string_append_len(struct bt_ctf_field *field,
+               const char *value, unsigned int length)
+{
+       int i;
+       int ret = 0;
+       unsigned int effective_length = length;
+       struct bt_ctf_field_string *string_field;
+
+       if (!field || !value || field->frozen ||
+               bt_ctf_field_type_get_type_id(field->type) !=
+                       BT_CTF_TYPE_ID_STRING) {
+               ret = -1;
+               goto end;
+       }
+
+       string_field = container_of(field, struct bt_ctf_field_string, parent);
+
+       /* make sure no null bytes are appended */
+       for (i = 0; i < length; ++i) {
+               if (value[i] == '\0') {
+                       effective_length = i;
+                       break;
+               }
+       }
+
+       if (string_field->payload) {
+               g_string_append_len(string_field->payload, value,
+                       effective_length);
+       } else {
+               string_field->payload = g_string_new_len(value,
+                       effective_length);
+       }
+
+       string_field->parent.payload_set = 1;
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_validate(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       enum bt_ctf_type_id type_id;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(field->type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = field_validate_funcs[type_id](field);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_reset(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       enum bt_ctf_type_id type_id;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(field->type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = field_reset_funcs[type_id](field);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_field_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       int ret = 0;
+       enum bt_ctf_type_id type_id;
+
+       if (!field || !pos) {
+               ret = -1;
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(field->type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = field_serialize_funcs[type_id](field, pos, native_byte_order);
+end:
+       return ret;
+}
+
+
+BT_HIDDEN
+bool bt_ctf_field_is_set(struct bt_ctf_field *field)
+{
+       bool is_set = false;
+       enum bt_ctf_type_id type_id;
+
+       if (!field) {
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(field->type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+               goto end;
+       }
+
+       is_set = field_is_set_funcs[type_id](field);
+end:
+       return is_set;
+}
+
+struct bt_ctf_field *bt_ctf_field_copy(struct bt_ctf_field *field)
+{
+       int ret;
+       struct bt_ctf_field *copy = NULL;
+       enum bt_ctf_type_id type_id;
+
+       if (!field) {
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(field->type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN || type_id >= BT_CTF_NR_TYPE_IDS) {
+               goto end;
+       }
+
+       copy = bt_ctf_field_create(field->type);
+       if (!copy) {
+               goto end;
+       }
+
+       copy->payload_set = field->payload_set;
+       ret = field_copy_funcs[type_id](field, copy);
+       if (ret) {
+               bt_put(copy);
+               copy = NULL;
+       }
+end:
+       return copy;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_integer_create(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_integer *integer = g_new0(
+               struct bt_ctf_field_integer, 1);
+
+       return integer ? &integer->parent : NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_enumeration_create(
+       struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_enumeration *enumeration = g_new0(
+               struct bt_ctf_field_enumeration, 1);
+
+       return enumeration ? &enumeration->parent : NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_floating_point_create(
+       struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_floating_point *floating_point;
+
+       floating_point = g_new0(struct bt_ctf_field_floating_point, 1);
+       return floating_point ? &floating_point->parent : NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_structure_create(
+       struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_type_structure *structure_type = container_of(type,
+               struct bt_ctf_field_type_structure, parent);
+       struct bt_ctf_field_structure *structure = g_new0(
+               struct bt_ctf_field_structure, 1);
+       struct bt_ctf_field *field = NULL;
+
+       if (!structure) {
+               goto end;
+       }
+
+       structure->field_name_to_index = structure_type->field_name_to_index;
+       structure->fields = g_ptr_array_new_with_free_func(
+               (GDestroyNotify)bt_ctf_field_put);
+       g_ptr_array_set_size(structure->fields,
+               g_hash_table_size(structure->field_name_to_index));
+       field = &structure->parent;
+end:
+       return field;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_variant_create(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_variant *variant = g_new0(
+               struct bt_ctf_field_variant, 1);
+       return variant ? &variant->parent : NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_array_create(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_array *array = g_new0(struct bt_ctf_field_array, 1);
+       struct bt_ctf_field_type_array *array_type;
+       unsigned int array_length;
+
+       if (!array || !type) {
+               goto error;
+       }
+
+       array_type = container_of(type, struct bt_ctf_field_type_array, parent);
+       array_length = array_type->length;
+       array->elements = g_ptr_array_sized_new(array_length);
+       if (!array->elements) {
+               goto error;
+       }
+
+       g_ptr_array_set_free_func(array->elements,
+               (GDestroyNotify)bt_ctf_field_put);
+       g_ptr_array_set_size(array->elements, array_length);
+       return &array->parent;
+error:
+       g_free(array);
+       return NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_sequence_create(
+       struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_sequence *sequence = g_new0(
+               struct bt_ctf_field_sequence, 1);
+       return sequence ? &sequence->parent : NULL;
+}
+
+static
+struct bt_ctf_field *bt_ctf_field_string_create(struct bt_ctf_field_type *type)
+{
+       struct bt_ctf_field_string *string = g_new0(
+               struct bt_ctf_field_string, 1);
+       return string ? &string->parent : NULL;
+}
+
+static
+void bt_ctf_field_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_field *field;
+       struct bt_ctf_field_type *type;
+       enum bt_ctf_type_id type_id;
+
+       field = container_of(obj, struct bt_ctf_field, base);
+       type = field->type;
+       type_id = bt_ctf_field_type_get_type_id(type);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
+               type_id >= BT_CTF_NR_TYPE_IDS) {
+               return;
+       }
+
+       field_destroy_funcs[type_id](field);
+       bt_put(type);
+}
+
+static
+void bt_ctf_field_integer_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_integer *integer;
+
+       if (!field) {
+               return;
+       }
+
+       integer = container_of(field, struct bt_ctf_field_integer, parent);
+       g_free(integer);
+}
+
+static
+void bt_ctf_field_enumeration_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_enumeration *enumeration;
+
+       if (!field) {
+               return;
+       }
+
+       enumeration = container_of(field, struct bt_ctf_field_enumeration,
+               parent);
+       bt_put(enumeration->payload);
+       g_free(enumeration);
+}
+
+static
+void bt_ctf_field_floating_point_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_floating_point *floating_point;
+
+       if (!field) {
+               return;
+       }
+
+       floating_point = container_of(field, struct bt_ctf_field_floating_point,
+               parent);
+       g_free(floating_point);
+}
+
+static
+void bt_ctf_field_structure_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_structure *structure;
+
+       if (!field) {
+               return;
+       }
+
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       g_ptr_array_free(structure->fields, TRUE);
+       g_free(structure);
+}
+
+static
+void bt_ctf_field_variant_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_variant *variant;
+
+       if (!field) {
+               return;
+       }
+
+       variant = container_of(field, struct bt_ctf_field_variant, parent);
+       bt_put(variant->tag);
+       bt_put(variant->payload);
+       g_free(variant);
+}
+
+static
+void bt_ctf_field_array_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_array *array;
+
+       if (!field) {
+               return;
+       }
+
+       array = container_of(field, struct bt_ctf_field_array, parent);
+       g_ptr_array_free(array->elements, TRUE);
+       g_free(array);
+}
+
+static
+void bt_ctf_field_sequence_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field) {
+               return;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       if (sequence->elements) {
+               g_ptr_array_free(sequence->elements, TRUE);
+       }
+       bt_put(sequence->length);
+       g_free(sequence);
+}
+
+static
+void bt_ctf_field_string_destroy(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_string *string;
+       if (!field) {
+               return;
+       }
+
+       string = container_of(field, struct bt_ctf_field_string, parent);
+       if (string->payload) {
+               g_string_free(string->payload, TRUE);
+       }
+       g_free(string);
+}
+
+static
+int bt_ctf_field_generic_validate(struct bt_ctf_field *field)
+{
+       return (field && field->payload_set) ? 0 : -1;
+}
+
+static
+int bt_ctf_field_enumeration_validate(struct bt_ctf_field *field)
+{
+       int ret;
+       struct bt_ctf_field_enumeration *enumeration;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       enumeration = container_of(field, struct bt_ctf_field_enumeration,
+               parent);
+       if (!enumeration->payload) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_validate(enumeration->payload);
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_structure_validate(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_structure *structure;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       for (i = 0; i < structure->fields->len; i++) {
+               ret = bt_ctf_field_validate(structure->fields->pdata[i]);
+               if (ret) {
+                       const char *name;
+                       struct bt_ctf_field_type *field_type =
+                                       bt_ctf_field_get_type(field);
+
+                       (void) bt_ctf_field_type_structure_get_field(field_type,
+                                       &name, NULL, i);
+                       fprintf(stderr, "Field %s failed validation\n",
+                                       name ? name : "NULL");
+                       bt_put(field_type);
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_variant_validate(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_variant *variant;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(field, struct bt_ctf_field_variant, parent);
+       ret = bt_ctf_field_validate(variant->payload);
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_array_validate(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_array *array;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       array = container_of(field, struct bt_ctf_field_array, parent);
+       for (i = 0; i < array->elements->len; i++) {
+               ret = bt_ctf_field_validate(array->elements->pdata[i]);
+               if (ret) {
+                       fprintf(stderr, "Failed to validate array field #%zu\n", i);
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_sequence_validate(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       for (i = 0; i < sequence->elements->len; i++) {
+               ret = bt_ctf_field_validate(sequence->elements->pdata[i]);
+               if (ret) {
+                       fprintf(stderr, "Failed to validate sequence field #%zu\n", i);
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_generic_reset(struct bt_ctf_field *field)
+{
+       int ret = 0;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       field->payload_set = 0;
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_enumeration_reset(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_enumeration *enumeration;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       enumeration = container_of(field, struct bt_ctf_field_enumeration,
+               parent);
+       if (!enumeration->payload) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_reset(enumeration->payload);
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_structure_reset(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_structure *structure;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       for (i = 0; i < structure->fields->len; i++) {
+               struct bt_ctf_field *member = structure->fields->pdata[i];
+
+               if (!member) {
+                       /*
+                        * Structure members are lazily initialized; skip if
+                        * this member has not been allocated yet.
+                        */
+                       continue;
+               }
+
+               ret = bt_ctf_field_reset(member);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_variant_reset(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_variant *variant;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       variant = container_of(field, struct bt_ctf_field_variant, parent);
+       if (variant->payload) {
+               ret = bt_ctf_field_reset(variant->payload);
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_array_reset(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_array *array;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       array = container_of(field, struct bt_ctf_field_array, parent);
+       for (i = 0; i < array->elements->len; i++) {
+               struct bt_ctf_field *member = array->elements->pdata[i];
+
+               if (!member) {
+                       /*
+                        * Array elements are lazily initialized; skip if
+                        * this member has not been allocated yet.
+                        */
+                       continue;
+               }
+
+               ret = bt_ctf_field_reset(member);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_sequence_reset(struct bt_ctf_field *field)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       for (i = 0; i < sequence->elements->len; i++) {
+               struct bt_ctf_field *member = sequence->elements->pdata[i];
+
+               if (!member) {
+                       /*
+                        * Sequence elements are lazily initialized; skip if
+                        * this member has not been allocated yet.
+                        */
+                       continue;
+               }
+
+               ret = bt_ctf_field_reset(member);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_string_reset(struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_string *string;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_generic_reset(field);
+       if (ret) {
+               goto end;
+       }
+
+       string = container_of(field, struct bt_ctf_field_string, parent);
+       if (string->payload) {
+               g_string_truncate(string->payload, 0);
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_integer_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       int ret = 0;
+       struct bt_ctf_field_integer *integer = container_of(field,
+               struct bt_ctf_field_integer, parent);
+
+       if (!bt_ctf_field_generic_is_set(field)) {
+               ret = -1;
+               goto end;
+       }
+retry:
+       ret = bt_ctf_field_integer_write(integer, pos, native_byte_order);
+       if (ret == -EFAULT) {
+               /*
+                * The field is too large to fit in the current packet's
+                * remaining space. Bump the packet size and retry.
+                */
+               ret = increase_packet_size(pos);
+               if (ret) {
+                       goto end;
+               }
+               goto retry;
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_enumeration_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       struct bt_ctf_field_enumeration *enumeration = container_of(
+               field, struct bt_ctf_field_enumeration, parent);
+
+       return bt_ctf_field_serialize(enumeration->payload, pos,
+               native_byte_order);
+}
+
+static
+int bt_ctf_field_floating_point_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       int ret = 0;
+       struct bt_ctf_field_floating_point *floating_point = container_of(field,
+               struct bt_ctf_field_floating_point, parent);
+
+       if (!bt_ctf_field_generic_is_set(field)) {
+               ret = -1;
+               goto end;
+       }
+retry:
+       ret = bt_ctf_field_floating_point_write(floating_point, pos,
+               native_byte_order);
+       if (ret == -EFAULT) {
+               /*
+                * The field is too large to fit in the current packet's
+                * remaining space. Bump the packet size and retry.
+                */
+               ret = increase_packet_size(pos);
+               if (ret) {
+                       goto end;
+               }
+               goto retry;
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_structure_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_structure *structure = container_of(
+               field, struct bt_ctf_field_structure, parent);
+
+       while (!bt_ctf_stream_pos_access_ok(pos,
+               offset_align(pos->offset, field->type->alignment))) {
+               ret = increase_packet_size(pos);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       if (!bt_ctf_stream_pos_align(pos, field->type->alignment)) {
+               ret = -1;
+               goto end;
+       }
+
+       for (i = 0; i < structure->fields->len; i++) {
+               struct bt_ctf_field *member = g_ptr_array_index(
+                       structure->fields, i);
+
+               ret = bt_ctf_field_serialize(member, pos, native_byte_order);
+               if (ret) {
+                       const char *name;
+                       struct bt_ctf_field_type *structure_type =
+                                       bt_ctf_field_get_type(field);
+
+                       (void) bt_ctf_field_type_structure_get_field(
+                                       structure_type, &name, NULL, i);
+                       fprintf(stderr, "Field %s failed to serialize\n",
+                                       name ? name : "NULL");
+                       bt_put(structure_type);
+                       break;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_variant_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       struct bt_ctf_field_variant *variant = container_of(
+               field, struct bt_ctf_field_variant, parent);
+
+       return bt_ctf_field_serialize(variant->payload, pos,
+               native_byte_order);
+}
+
+static
+int bt_ctf_field_array_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_array *array = container_of(
+               field, struct bt_ctf_field_array, parent);
+
+       for (i = 0; i < array->elements->len; i++) {
+               ret = bt_ctf_field_serialize(
+                       g_ptr_array_index(array->elements, i), pos,
+                       native_byte_order);
+               if (ret) {
+                       fprintf(stderr, "Failed to serialize array element #%zu\n", i);
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_sequence_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_sequence *sequence = container_of(
+               field, struct bt_ctf_field_sequence, parent);
+
+       for (i = 0; i < sequence->elements->len; i++) {
+               ret = bt_ctf_field_serialize(
+                       g_ptr_array_index(sequence->elements, i), pos,
+                       native_byte_order);
+               if (ret) {
+                       fprintf(stderr, "Failed to serialize sequence element #%zu\n", i);
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_string_serialize(struct bt_ctf_field *field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       size_t i;
+       int ret = 0;
+       struct bt_ctf_field_string *string = container_of(field,
+               struct bt_ctf_field_string, parent);
+       struct bt_ctf_field_type *character_type =
+               get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
+       struct bt_ctf_field *character = bt_ctf_field_create(character_type);
+
+       for (i = 0; i < string->payload->len + 1; i++) {
+               ret = bt_ctf_field_unsigned_integer_set_value(character,
+                       (uint64_t) string->payload->str[i]);
+               if (ret) {
+                       goto end;
+               }
+
+               ret = bt_ctf_field_integer_serialize(character, pos,
+                       native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       bt_put(character);
+       bt_put(character_type);
+       return ret;
+}
+
+static
+int bt_ctf_field_integer_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       struct bt_ctf_field_integer *integer_src, *integer_dst;
+
+       integer_src = container_of(src, struct bt_ctf_field_integer, parent);
+       integer_dst = container_of(dst, struct bt_ctf_field_integer, parent);
+       integer_dst->payload = integer_src->payload;
+       return 0;
+}
+
+static
+int bt_ctf_field_enumeration_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0;
+       struct bt_ctf_field_enumeration *enum_src, *enum_dst;
+
+       enum_src = container_of(src, struct bt_ctf_field_enumeration, parent);
+       enum_dst = container_of(dst, struct bt_ctf_field_enumeration, parent);
+
+       if (enum_src->payload) {
+               enum_dst->payload = bt_ctf_field_copy(enum_src->payload);
+               if (!enum_dst->payload) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_floating_point_copy(
+               struct bt_ctf_field *src, struct bt_ctf_field *dst)
+{
+       struct bt_ctf_field_floating_point *float_src, *float_dst;
+
+       float_src = container_of(src, struct bt_ctf_field_floating_point,
+               parent);
+       float_dst = container_of(dst, struct bt_ctf_field_floating_point,
+               parent);
+       float_dst->payload = float_src->payload;
+       return 0;
+}
+
+static
+int bt_ctf_field_structure_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0, i;
+       struct bt_ctf_field_structure *struct_src, *struct_dst;
+
+       struct_src = container_of(src, struct bt_ctf_field_structure, parent);
+       struct_dst = container_of(dst, struct bt_ctf_field_structure, parent);
+
+       /* This field_name_to_index HT is owned by the structure field type */
+       struct_dst->field_name_to_index = struct_src->field_name_to_index;
+       g_ptr_array_set_size(struct_dst->fields, struct_src->fields->len);
+
+       for (i = 0; i < struct_src->fields->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(struct_src->fields, i);
+               struct bt_ctf_field *field_copy = NULL;
+
+               if (field) {
+                       field_copy = bt_ctf_field_copy(field);
+
+                       if (!field_copy) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               g_ptr_array_index(struct_dst->fields, i) = field_copy;
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_variant_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0;
+       struct bt_ctf_field_variant *variant_src, *variant_dst;
+
+       variant_src = container_of(src, struct bt_ctf_field_variant, parent);
+       variant_dst = container_of(dst, struct bt_ctf_field_variant, parent);
+
+       if (variant_src->tag) {
+               variant_dst->tag = bt_ctf_field_copy(variant_src->tag);
+               if (!variant_dst->tag) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+       if (variant_src->payload) {
+               variant_dst->payload = bt_ctf_field_copy(variant_src->payload);
+               if (!variant_dst->payload) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_array_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0, i;
+       struct bt_ctf_field_array *array_src, *array_dst;
+
+       array_src = container_of(src, struct bt_ctf_field_array, parent);
+       array_dst = container_of(dst, struct bt_ctf_field_array, parent);
+
+       g_ptr_array_set_size(array_dst->elements, array_src->elements->len);
+       for (i = 0; i < array_src->elements->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(array_src->elements, i);
+               struct bt_ctf_field *field_copy = NULL;
+
+               if (field) {
+                       field_copy = bt_ctf_field_copy(field);
+
+                       if (!field_copy) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               g_ptr_array_index(array_dst->elements, i) = field_copy;
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_sequence_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0, i;
+       struct bt_ctf_field_sequence *sequence_src, *sequence_dst;
+       struct bt_ctf_field *src_length;
+       struct bt_ctf_field *dst_length;
+
+       sequence_src = container_of(src, struct bt_ctf_field_sequence, parent);
+       sequence_dst = container_of(dst, struct bt_ctf_field_sequence, parent);
+
+       src_length = bt_ctf_field_sequence_get_length(src);
+
+       if (!src_length) {
+               /* no length set yet: keep destination sequence empty */
+               goto end;
+       }
+
+       /* copy source length */
+       dst_length = bt_ctf_field_copy(src_length);
+       bt_put(src_length);
+
+       if (!dst_length) {
+               ret = -1;
+               goto end;
+       }
+
+       /* this will initialize the destination sequence's internal array */
+       ret = bt_ctf_field_sequence_set_length(dst, dst_length);
+       bt_put(dst_length);
+
+       if (ret) {
+               goto end;
+       }
+
+       assert(sequence_dst->elements->len == sequence_src->elements->len);
+
+       for (i = 0; i < sequence_src->elements->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(sequence_src->elements, i);
+               struct bt_ctf_field *field_copy = NULL;
+
+               if (field) {
+                       field_copy = bt_ctf_field_copy(field);
+
+                       if (!field_copy) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               g_ptr_array_index(sequence_dst->elements, i) = field_copy;
+       }
+end:
+       return ret;
+}
+
+static
+int bt_ctf_field_string_copy(struct bt_ctf_field *src,
+               struct bt_ctf_field *dst)
+{
+       int ret = 0;
+       struct bt_ctf_field_string *string_src, *string_dst;
+
+       string_src = container_of(src, struct bt_ctf_field_string, parent);
+       string_dst = container_of(dst, struct bt_ctf_field_string, parent);
+
+       if (string_src->payload) {
+               string_dst->payload = g_string_new(string_src->payload->str);
+               if (!string_dst->payload) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+static
+int increase_packet_size(struct bt_ctf_stream_pos *pos)
+{
+       int ret;
+
+       assert(pos);
+       ret = munmap_align(pos->base_mma);
+       if (ret) {
+               goto end;
+       }
+
+       pos->packet_size += PACKET_LEN_INCREMENT;
+       do {
+               ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
+                       pos->packet_size / CHAR_BIT);
+       } while (ret == EINTR);
+       if (ret) {
+               errno = EINTR;
+               ret = -1;
+               goto end;
+       }
+
+       pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
+               pos->flags, pos->fd, pos->mmap_offset);
+       if (pos->base_mma == MAP_FAILED) {
+               ret = -1;
+       }
+end:
+       return ret;
+}
+
+static
+void generic_field_freeze(struct bt_ctf_field *field)
+{
+       field->frozen = 1;
+}
+
+static
+void bt_ctf_field_enumeration_freeze(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_enumeration *enum_field =
+               container_of(field, struct bt_ctf_field_enumeration, parent);
+
+       bt_ctf_field_freeze(enum_field->payload);
+       generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_structure_freeze(struct bt_ctf_field *field)
+{
+       int i;
+       struct bt_ctf_field_structure *structure_field =
+               container_of(field, struct bt_ctf_field_structure, parent);
+
+       for (i = 0; i < structure_field->fields->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(structure_field->fields, i);
+
+               bt_ctf_field_freeze(field);
+       }
+
+       generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_variant_freeze(struct bt_ctf_field *field)
+{
+       struct bt_ctf_field_variant *variant_field =
+               container_of(field, struct bt_ctf_field_variant, parent);
+
+       bt_ctf_field_freeze(variant_field->tag);
+       bt_ctf_field_freeze(variant_field->payload);
+       generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_array_freeze(struct bt_ctf_field *field)
+{
+       int i;
+       struct bt_ctf_field_array *array_field =
+               container_of(field, struct bt_ctf_field_array, parent);
+
+       for (i = 0; i < array_field->elements->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(array_field->elements, i);
+
+               bt_ctf_field_freeze(field);
+       }
+
+       generic_field_freeze(field);
+}
+
+static
+void bt_ctf_field_sequence_freeze(struct bt_ctf_field *field)
+{
+       int i;
+       struct bt_ctf_field_sequence *sequence_field =
+               container_of(field, struct bt_ctf_field_sequence, parent);
+
+       bt_ctf_field_freeze(sequence_field->length);
+
+       for (i = 0; i < sequence_field->elements->len; i++) {
+               struct bt_ctf_field *field =
+                       g_ptr_array_index(sequence_field->elements, i);
+
+               bt_ctf_field_freeze(field);
+       }
+
+       generic_field_freeze(field);
+}
+
+BT_HIDDEN
+void bt_ctf_field_freeze(struct bt_ctf_field *field)
+{
+       enum bt_ctf_type_id type_id;
+
+       if (!field) {
+               goto end;
+       }
+
+       type_id = bt_ctf_field_get_type_id(field);
+       if (type_id <= BT_CTF_TYPE_ID_UNKNOWN ||
+                       type_id >= BT_CTF_NR_TYPE_IDS) {
+               goto end;
+       }
+
+       field_freeze_funcs[type_id](field);
+end:
+       return;
+}
+
+static
+bool bt_ctf_field_generic_is_set(struct bt_ctf_field *field)
+{
+       return field && field->payload_set;
+}
+
+static
+bool bt_ctf_field_enumeration_is_set(struct bt_ctf_field *field)
+{
+       bool is_set = false;
+       struct bt_ctf_field_enumeration *enumeration;
+
+       if (!field) {
+               goto end;
+       }
+
+       enumeration = container_of(field, struct bt_ctf_field_enumeration,
+                       parent);
+       if (!enumeration->payload) {
+               goto end;
+       }
+
+       is_set = bt_ctf_field_is_set(enumeration->payload);
+end:
+       return is_set;
+}
+
+static
+bool bt_ctf_field_structure_is_set(struct bt_ctf_field *field)
+{
+       bool is_set = false;
+       size_t i;
+       struct bt_ctf_field_structure *structure;
+
+       if (!field) {
+               goto end;
+       }
+
+       structure = container_of(field, struct bt_ctf_field_structure, parent);
+       for (i = 0; i < structure->fields->len; i++) {
+               is_set = bt_ctf_field_is_set(structure->fields->pdata[i]);
+               if (!is_set) {
+                       goto end;
+               }
+       }
+end:
+       return is_set;
+}
+
+static
+bool bt_ctf_field_variant_is_set(struct bt_ctf_field *field)
+{
+       bool is_set = false;
+       struct bt_ctf_field_variant *variant;
+
+       if (!field) {
+               goto end;
+       }
+
+       variant = container_of(field, struct bt_ctf_field_variant, parent);
+       is_set = bt_ctf_field_is_set(variant->payload);
+end:
+       return is_set;
+}
+
+static
+bool bt_ctf_field_array_is_set(struct bt_ctf_field *field)
+{
+       size_t i;
+       bool is_set = false;
+       struct bt_ctf_field_array *array;
+
+       if (!field) {
+               goto end;
+       }
+
+       array = container_of(field, struct bt_ctf_field_array, parent);
+       for (i = 0; i < array->elements->len; i++) {
+               is_set = bt_ctf_field_is_set(array->elements->pdata[i]);
+               if (!is_set) {
+                       goto end;
+               }
+       }
+end:
+       return is_set;
+}
+
+static
+bool bt_ctf_field_sequence_is_set(struct bt_ctf_field *field)
+{
+       size_t i;
+       bool is_set = false;
+       struct bt_ctf_field_sequence *sequence;
+
+       if (!field) {
+               goto end;
+       }
+
+       sequence = container_of(field, struct bt_ctf_field_sequence, parent);
+       for (i = 0; i < sequence->elements->len; i++) {
+               is_set = bt_ctf_field_validate(sequence->elements->pdata[i]);
+               if (!is_set) {
+                       goto end;
+               }
+       }
+end:
+       return is_set;
+}
diff --git a/lib/ctf-ir/packet.c b/lib/ctf-ir/packet.c
new file mode 100644 (file)
index 0000000..6236e00
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/fields-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/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/trace-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/ref.h>
+
+struct bt_ctf_stream *bt_ctf_packet_get_stream(struct bt_ctf_packet *packet)
+{
+       return packet ? bt_get(packet->stream) : NULL;
+}
+
+struct bt_ctf_field *bt_ctf_packet_get_header(
+               struct bt_ctf_packet *packet)
+{
+       return packet ? bt_get(packet->header) : NULL;
+}
+
+int bt_ctf_packet_set_header(struct bt_ctf_packet *packet,
+               struct bt_ctf_field *header)
+{
+       int ret = 0;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_field_type *header_field_type = NULL;
+       struct bt_ctf_field_type *expected_header_field_type = NULL;
+
+       if (!packet || packet->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!header) {
+               goto skip_validation;
+       }
+
+       stream_class = bt_ctf_stream_get_class(packet->stream);
+       assert(stream_class);
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       assert(trace);
+       header_field_type = bt_ctf_field_get_type(header);
+       assert(header_field_type);
+       expected_header_field_type = bt_ctf_trace_get_packet_header_type(trace);
+
+       if (bt_ctf_field_type_compare(header_field_type,
+                       expected_header_field_type)) {
+               ret = -1;
+               goto end;
+       }
+
+skip_validation:
+       bt_put(packet->header);
+       packet->header = bt_get(header);
+
+end:
+       BT_PUT(trace);
+       BT_PUT(stream_class);
+       BT_PUT(header_field_type);
+       BT_PUT(expected_header_field_type);
+
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_packet_get_context(
+               struct bt_ctf_packet *packet)
+{
+       return packet ? bt_get(packet->context) : NULL;
+}
+
+int bt_ctf_packet_set_context(struct bt_ctf_packet *packet,
+               struct bt_ctf_field *context)
+{
+       int ret = 0;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_field_type *context_field_type = NULL;
+       struct bt_ctf_field_type *expected_context_field_type = NULL;
+
+       if (!packet || packet->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!context) {
+               goto skip_validation;
+       }
+
+       stream_class = bt_ctf_stream_get_class(packet->stream);
+       assert(stream_class);
+       context_field_type = bt_ctf_field_get_type(context);
+       assert(context_field_type);
+       expected_context_field_type =
+               bt_ctf_stream_class_get_packet_context_type(stream_class);
+
+       if (bt_ctf_field_type_compare(context_field_type,
+                       expected_context_field_type)) {
+               ret = -1;
+               goto end;
+       }
+
+skip_validation:
+       bt_put(packet->context);
+       packet->context = bt_get(context);
+
+end:
+       BT_PUT(stream_class);
+       BT_PUT(context_field_type);
+       BT_PUT(expected_context_field_type);
+
+       return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_packet_freeze(struct bt_ctf_packet *packet)
+{
+       if (!packet) {
+               return;
+       }
+
+       bt_ctf_field_freeze(packet->header);
+       bt_ctf_field_freeze(packet->context);
+       packet->frozen = 1;
+}
+
+static
+void bt_ctf_packet_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_packet *packet;
+
+       packet = container_of(obj, struct bt_ctf_packet, base);
+       bt_put(packet->header);
+       bt_put(packet->context);
+       bt_put(packet->stream);
+       g_free(packet);
+}
+
+struct bt_ctf_packet *bt_ctf_packet_create(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_ctf_packet *packet = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_trace *trace = NULL;
+
+       if (!stream || stream->pos.fd >= 0) {
+               goto end;
+       }
+
+       stream_class = bt_ctf_stream_get_class(stream);
+       assert(stream_class);
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       assert(trace);
+       packet = g_new0(struct bt_ctf_packet, 1);
+       if (!packet) {
+               goto end;
+       }
+
+       bt_object_init(packet, bt_ctf_packet_destroy);
+       packet->stream = bt_get(stream);
+       packet->header = bt_ctf_field_create(trace->packet_header_type);
+       if (!packet->header && trace->packet_header_type) {
+               BT_PUT(packet);
+               goto end;
+       }
+
+       packet->context = bt_ctf_field_create(
+               stream->stream_class->packet_context_type);
+       if (!packet->context && stream->stream_class->packet_context_type) {
+               BT_PUT(packet);
+               goto end;
+       }
+
+end:
+       BT_PUT(trace);
+       BT_PUT(stream_class);
+
+       return packet;
+}
diff --git a/lib/ctf-ir/resolve.c b/lib/ctf-ir/resolve.c
new file mode 100644 (file)
index 0000000..41dd6c5
--- /dev/null
@@ -0,0 +1,1194 @@
+/*
+ * resolve.c
+ *
+ * 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/event.h>
+#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace/ctf-ir/resolve-internal.h>
+#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-ir/field-path.h>
+#include <babeltrace/ctf-ir/field-path-internal.h>
+#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/values.h>
+#include <limits.h>
+#include <glib.h>
+
+#define _printf_error(fmt, args...) \
+       printf_verbose("[resolving] " fmt, ## args)
+
+typedef GPtrArray type_stack;
+
+/*
+ * A stack frame.
+ *
+ * `type` contains a compound field type (structure, variant, array,
+ * or sequence) and `index` indicates the index of the field type in
+ * the upper frame (-1 for array and sequence field types).
+ *
+ * `type` is owned by the stack frame.
+ */
+struct type_stack_frame {
+       struct bt_ctf_field_type *type;
+       int index;
+};
+
+/*
+ * The current context of the resolving engine.
+ *
+ * `scopes` contain the 6 CTF scope field types (see CTF, sect. 7.3.2)
+ * in the following order:
+ *
+ *   * Packet header
+ *   * Packet context
+ *   * Event header
+ *   * Stream event context
+ *   * Event context
+ *   * Event payload
+ */
+struct resolve_context {
+       struct bt_value *environment;
+       struct bt_ctf_field_type *scopes[6];
+
+       /* Root scope being visited */
+       enum bt_ctf_scope root_scope;
+       type_stack *type_stack;
+       struct bt_ctf_field_type *cur_field_type;
+};
+
+/* TSDL dynamic scope prefixes as defined in CTF Section 7.3.2 */
+static const char * const absolute_path_prefixes[] = {
+       [BT_CTF_SCOPE_ENV]                      = "env.",
+       [BT_CTF_SCOPE_TRACE_PACKET_HEADER]      = "trace.packet.header.",
+       [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT]    = "stream.packet.context.",
+       [BT_CTF_SCOPE_STREAM_EVENT_HEADER]      = "stream.event.header.",
+       [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT]     = "stream.event.context.",
+       [BT_CTF_SCOPE_EVENT_CONTEXT]            = "event.context.",
+       [BT_CTF_SCOPE_EVENT_FIELDS]             = "event.fields.",
+};
+
+/* Number of path tokens used for the absolute prefixes */
+static const int absolute_path_prefix_ptoken_counts[] = {
+       [BT_CTF_SCOPE_ENV]                      = 1,
+       [BT_CTF_SCOPE_TRACE_PACKET_HEADER]      = 3,
+       [BT_CTF_SCOPE_STREAM_PACKET_CONTEXT]    = 3,
+       [BT_CTF_SCOPE_STREAM_EVENT_HEADER]      = 3,
+       [BT_CTF_SCOPE_STREAM_EVENT_CONTEXT]     = 3,
+       [BT_CTF_SCOPE_EVENT_CONTEXT]            = 2,
+       [BT_CTF_SCOPE_EVENT_FIELDS]             = 2,
+};
+
+/*
+ * Destroys a type stack frame.
+ */
+static
+void type_stack_destroy_notify(gpointer data)
+{
+       struct type_stack_frame *frame = data;
+
+       BT_PUT(frame->type);
+       g_free(frame);
+}
+
+/*
+ * Creates a type stack.
+ *
+ * Return value is owned by the caller.
+ */
+static
+type_stack *type_stack_create(void)
+{
+       return g_ptr_array_new_with_free_func(type_stack_destroy_notify);
+}
+
+/*
+ * Destroys a type stack.
+ */
+static
+void type_stack_destroy(type_stack *stack)
+{
+       g_ptr_array_free(stack, TRUE);
+}
+
+/*
+ * Pushes a field type onto a type stack.
+ *
+ * `type` is owned by the caller (stack frame gets a new reference).
+ */
+static
+int type_stack_push(type_stack *stack, struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       struct type_stack_frame *frame = NULL;
+
+       if (!stack || !type) {
+               ret = -1;
+               goto end;
+       }
+
+       frame = g_new0(struct type_stack_frame, 1);
+       if (!frame) {
+               ret = -1;
+               goto end;
+       }
+
+       frame->type = bt_get(type);
+       g_ptr_array_add(stack, frame);
+
+end:
+       return ret;
+}
+
+/*
+ * Checks whether or not `stack` is empty.
+ */
+static
+bool type_stack_empty(type_stack *stack)
+{
+       return stack->len == 0;
+}
+
+/*
+ * Returns the number of frames in `stack`.
+ */
+static
+size_t type_stack_size(type_stack *stack)
+{
+       return stack->len;
+}
+
+/*
+ * Returns the top frame of `stack`.
+ *
+ * Return value is owned by `stack`.
+ */
+static
+struct type_stack_frame *type_stack_peek(type_stack *stack)
+{
+       struct type_stack_frame *entry = NULL;
+
+       if (!stack || type_stack_empty(stack)) {
+               goto end;
+       }
+
+       entry = g_ptr_array_index(stack, stack->len - 1);
+end:
+       return entry;
+}
+
+/*
+ * Returns the frame at index `index` in `stack`.
+ *
+ * Return value is owned by `stack`.
+ */
+static
+struct type_stack_frame *type_stack_at(type_stack *stack,
+               size_t index)
+{
+       struct type_stack_frame *entry = NULL;
+
+       if (!stack || index >= stack->len) {
+               goto end;
+       }
+
+       entry = g_ptr_array_index(stack, index);
+
+end:
+       return entry;
+}
+
+/*
+ * Removes the top frame of `stack`.
+ */
+static
+void type_stack_pop(type_stack *stack)
+{
+       if (!type_stack_empty(stack)) {
+               /*
+                * This will call the frame's destructor and free it, as
+                * well as put its contained field type.
+                */
+               g_ptr_array_set_size(stack, stack->len - 1);
+       }
+}
+
+/*
+ * Returns the scope field type of `scope` in the context `ctx`.
+ *
+ * Return value is owned by `ctx` on success.
+ */
+static
+struct bt_ctf_field_type *get_type_from_ctx(struct resolve_context *ctx,
+               enum bt_ctf_scope scope)
+{
+       assert(scope >= BT_CTF_SCOPE_TRACE_PACKET_HEADER &&
+               scope <= BT_CTF_SCOPE_EVENT_FIELDS);
+
+       return ctx->scopes[scope - BT_CTF_SCOPE_TRACE_PACKET_HEADER];
+}
+
+/*
+ * Returns the CTF scope from a path string. May return
+ * CTF_NODE_UNKNOWN if the path is found to be relative.
+ */
+static
+enum bt_ctf_scope get_root_scope_from_absolute_pathstr(const char *pathstr)
+{
+       enum bt_ctf_scope scope;
+       enum bt_ctf_scope ret = BT_CTF_SCOPE_UNKNOWN;
+       const size_t prefixes_count = sizeof(absolute_path_prefixes) /
+               sizeof(*absolute_path_prefixes);
+
+       for (scope = BT_CTF_SCOPE_ENV; scope < BT_CTF_SCOPE_ENV +
+                       prefixes_count; scope++) {
+               /*
+                * Chech if path string starts with a known absolute
+                * path prefix.
+                *
+                * Refer to CTF 7.3.2 STATIC AND DYNAMIC SCOPES.
+                */
+               if (strncmp(pathstr, absolute_path_prefixes[scope],
+                               strlen(absolute_path_prefixes[scope]))) {
+                       /* Prefix does not match: try the next one */
+                       continue;
+               }
+
+               /* Found it! */
+               ret = scope;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * Destroys a path token.
+ */
+static
+void ptokens_destroy_func(gpointer ptoken, gpointer data)
+{
+       g_string_free(ptoken, TRUE);
+}
+
+/*
+ * Destroys a path token list.
+ */
+static
+void ptokens_destroy(GList *ptokens)
+{
+       if (!ptokens) {
+               return;
+       }
+
+       g_list_foreach(ptokens, ptokens_destroy_func, NULL);
+       g_list_free(ptokens);
+}
+
+/*
+ * Returns the string contained in a path token.
+ */
+static
+const char *ptoken_get_string(GList *ptoken)
+{
+       GString *tokenstr = (GString *) ptoken->data;
+
+       return tokenstr->str;
+}
+
+/*
+ * Converts a path string to a path token list, that is, splits the
+ * individual words of a path string into a list of individual
+ * strings.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+GList *pathstr_to_ptokens(const char *pathstr)
+{
+       const char *at = pathstr;
+       const char *last = at;
+       GList *ptokens = NULL;
+
+       for (;;) {
+               if (*at == '.' || *at == '\0') {
+                       GString *tokenstr;
+
+                       if (at == last) {
+                               /* Error: empty token */
+                               _printf_error("Empty token in path string at position %d\n",
+                                       (int) (at - pathstr));
+                               goto error;
+                       }
+
+                       tokenstr = g_string_new(NULL);
+                       g_string_append_len(tokenstr, last, at - last);
+                       ptokens = g_list_append(ptokens, tokenstr);
+                       last = at + 1;
+               }
+
+               if (*at == '\0') {
+                       break;
+               }
+
+               at++;
+       }
+
+       return ptokens;
+
+error:
+       ptokens_destroy(ptokens);
+       return NULL;
+}
+
+/*
+ * Converts a path token list to a field path object. The path token
+ * list is relative from `type`. The index of the source looking for
+ * its target within `type` is indicated by `src_index`. This can be
+ * `INT_MAX` if the source is contained in `type`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here. `type` is owned by the
+ * caller.
+ */
+static
+int ptokens_to_field_path(GList *ptokens, struct bt_ctf_field_path *field_path,
+               struct bt_ctf_field_type *type, int src_index)
+{
+       int ret = 0;
+       GList *cur_ptoken = ptokens;
+       bool first_level_done = false;
+
+       /* Get our own reference */
+       bt_get(type);
+
+       /* Locate target */
+       while (cur_ptoken) {
+               int child_index;
+               struct bt_ctf_field_type *child_type;
+               const char *field_name = ptoken_get_string(cur_ptoken);
+               enum bt_ctf_type_id type_id =
+                       bt_ctf_field_type_get_type_id(type);
+
+               /* Find to which index corresponds the current path token */
+               if (type_id == CTF_TYPE_ARRAY || type_id == CTF_TYPE_SEQUENCE) {
+                       child_index = -1;
+               } else {
+                       child_index = bt_ctf_field_type_get_field_index(type,
+                               field_name);
+                       if (child_index < 0) {
+                               /*
+                                * Error: field name does not exist or
+                                * wrong current type.
+                                */
+                               _printf_error("Cannot get index of field type named \"%s\"\n",
+                                       field_name);
+                               ret = -1;
+                               goto end;
+                       } else if (child_index > src_index &&
+                                       !first_level_done) {
+                               _printf_error("Child type is located after source index (%d)\n",
+                                       src_index);
+                               ret = -1;
+                               goto end;
+                       }
+
+                       /* Next path token */
+                       cur_ptoken = g_list_next(cur_ptoken);
+                       first_level_done = true;
+               }
+
+               /* Create new field path entry */
+               g_array_append_val(field_path->indexes, child_index);
+
+               /* Get child field type */
+               child_type = bt_ctf_field_type_get_field_at_index(type,
+                       child_index);
+               if (!child_type) {
+                       _printf_error("Cannot get child type at index %d (field \"%s\")\n",
+                               child_index, field_name);
+                       ret = -1;
+                       goto end;
+               }
+
+               /* Move child type to current type */
+               BT_MOVE(type, child_type);
+       }
+
+end:
+       bt_put(type);
+       return ret;
+}
+
+/*
+ * Converts a known absolute path token list to a field path object
+ * within the resolving context `ctx`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here.
+ */
+static
+int absolute_ptokens_to_field_path(GList *ptokens,
+               struct bt_ctf_field_path *field_path,
+               struct resolve_context *ctx)
+{
+       int ret = 0;
+       GList *cur_ptoken;
+       struct bt_ctf_field_type *type;
+
+       /* Skip absolute path tokens */
+       cur_ptoken = g_list_nth(ptokens,
+               absolute_path_prefix_ptoken_counts[field_path->root]);
+
+       /* Start with root type */
+       type = get_type_from_ctx(ctx, field_path->root);
+       if (!type) {
+               /* Error: root type is not available */
+               _printf_error("Root type with scope type %d is not available\n",
+                       field_path->root);
+               ret = -1;
+               goto end;
+       }
+
+       /* Locate target */
+       ret = ptokens_to_field_path(cur_ptoken, field_path, type, INT_MAX);
+
+end:
+       return ret;
+}
+
+/*
+ * Converts a known relative path token list to a field path object
+ * within the resolving context `ctx`.
+ *
+ * `ptokens` is owned by the caller. `field_path` is an output parameter
+ * owned by the caller that must be filled here.
+ */
+static
+int relative_ptokens_to_field_path(GList *ptokens,
+               struct bt_ctf_field_path *field_path,
+               struct resolve_context *ctx)
+{
+       int ret = 0;
+       int parent_pos_in_stack;
+       struct bt_ctf_field_path *tail_field_path = bt_ctf_field_path_create();
+
+       if (!tail_field_path) {
+               _printf_error("Cannot create field path\n");
+               ret = -1;
+               goto end;
+       }
+
+       parent_pos_in_stack = type_stack_size(ctx->type_stack) - 1;
+
+       while (parent_pos_in_stack >= 0) {
+               struct bt_ctf_field_type *parent_type =
+                       type_stack_at(ctx->type_stack,
+                               parent_pos_in_stack)->type;
+               int cur_index = type_stack_at(ctx->type_stack,
+                       parent_pos_in_stack)->index;
+
+               /* Locate target from current parent type */
+               ret = ptokens_to_field_path(ptokens, tail_field_path,
+                       parent_type, cur_index);
+               if (ret) {
+                       /* Not found... yet */
+                       bt_ctf_field_path_clear(tail_field_path);
+               } else {
+                       /* Found: stitch tail field path to head field path */
+                       int i = 0;
+                       int tail_field_path_len =
+                               tail_field_path->indexes->len;
+
+                       while (true) {
+                               struct bt_ctf_field_type *cur_type =
+                                       type_stack_at(ctx->type_stack, i)->type;
+                               int index = type_stack_at(
+                                       ctx->type_stack, i)->index;
+
+                               if (cur_type == parent_type) {
+                                       break;
+                               }
+
+                               g_array_append_val(field_path->indexes,
+                                       index);
+                               i++;
+                       }
+
+                       for (i = 0; i < tail_field_path_len; i++) {
+                               int index = g_array_index(
+                                       tail_field_path->indexes,
+                                       int, i);
+
+                               g_array_append_val(field_path->indexes,
+                                       index);
+                       }
+                       break;
+               }
+
+               parent_pos_in_stack--;
+       }
+
+       if (parent_pos_in_stack < 0) {
+               /* Not found: look in previous scopes */
+               field_path->root--;
+
+               while (field_path->root >= BT_CTF_SCOPE_TRACE_PACKET_HEADER) {
+                       struct bt_ctf_field_type *root_type;
+                       bt_ctf_field_path_clear(field_path);
+
+                       root_type = get_type_from_ctx(ctx, field_path->root);
+                       if (!root_type) {
+                               field_path->root--;
+                               continue;
+                       }
+
+                       /* Locate target in previous scope */
+                       ret = ptokens_to_field_path(ptokens, field_path,
+                               root_type, INT_MAX);
+                       if (ret) {
+                               /* Not found yet */
+                               field_path->root--;
+                               continue;
+                       }
+
+                       /* Found */
+                       break;
+               }
+       }
+
+end:
+       BT_PUT(tail_field_path);
+       return ret;
+}
+
+/*
+ * Converts a path string to a field path object within the resolving
+ * context `ctx`.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_path *pathstr_to_field_path(const char *pathstr,
+               struct resolve_context *ctx)
+{
+       int ret;
+       enum bt_ctf_scope root_scope;
+       GList *ptokens = NULL;
+       struct bt_ctf_field_path *field_path = NULL;
+
+       /* Create field path */
+       field_path = bt_ctf_field_path_create();
+       if (!field_path) {
+               _printf_error("Cannot create field path\n");
+               ret = -1;
+               goto end;
+       }
+
+       /* Convert path string to path tokens */
+       ptokens = pathstr_to_ptokens(pathstr);
+       if (!ptokens) {
+               _printf_error("Cannot convert path string \"%s\" to path tokens\n",
+                       pathstr);
+               ret = -1;
+               goto end;
+       }
+
+       /* Absolute or relative path? */
+       root_scope = get_root_scope_from_absolute_pathstr(pathstr);
+
+       if (root_scope == BT_CTF_SCOPE_UNKNOWN) {
+               /* Relative path: start with current root scope */
+               field_path->root = ctx->root_scope;
+               ret = relative_ptokens_to_field_path(ptokens, field_path, ctx);
+               if (ret) {
+                       _printf_error("Cannot get relative field path of path string \"%s\"\n",
+                               pathstr);
+                       _printf_error("  Starting at root scope %d, finished at root scope %d\n",
+                               ctx->root_scope, field_path->root);
+                       goto end;
+               }
+       } else if (root_scope == BT_CTF_SCOPE_ENV) {
+               _printf_error("Sequence field types referring the trace environment are not supported as of this version\n");
+               ret = -1;
+               goto end;
+       } else {
+               /* Absolute path: use found root scope */
+               field_path->root = root_scope;
+               ret = absolute_ptokens_to_field_path(ptokens, field_path, ctx);
+               if (ret) {
+                       _printf_error("Cannot get absolute field path of path string \"%s\"\n",
+                               pathstr);
+                       _printf_error("  Looking in root scope %d\n", root_scope);
+                       goto end;
+               }
+       }
+
+end:
+       if (ret) {
+               BT_PUT(field_path);
+       }
+
+       ptokens_destroy(ptokens);
+
+       return field_path;
+}
+
+/*
+ * Retrieves a field type by following the field path `field_path` in
+ * the resolving context `ctx`.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_type *field_path_to_field_type(
+               struct bt_ctf_field_path *field_path,
+               struct resolve_context *ctx)
+{
+       int i;
+       struct bt_ctf_field_type *type;
+
+       /* Start with root type */
+       type = get_type_from_ctx(ctx, field_path->root);
+       bt_get(type);
+       if (!type) {
+               /* Error: root type is not available */
+               _printf_error("Root type with scope type %d is not available\n",
+                       field_path->root);
+               goto error;
+       }
+
+       /* Locate target */
+       for (i = 0; i < field_path->indexes->len; i++) {
+               struct bt_ctf_field_type *child_type;
+               int child_index =
+                       g_array_index(field_path->indexes, int, i);
+
+               /* Get child field type */
+               child_type = bt_ctf_field_type_get_field_at_index(type,
+                       child_index);
+               if (!child_type) {
+                       _printf_error("Cannot get field type field at index %d\n",
+                               child_index);
+                       goto error;
+               }
+
+               /* Move child type to current type */
+               BT_MOVE(type, child_type);
+       }
+
+       return type;
+
+error:
+       BT_PUT(type);
+       return type;
+}
+
+/*
+ * Returns the equivalent field path object of the context type stack.
+ *
+ * Return value is owned by the caller on success.
+ */
+static
+struct bt_ctf_field_path *get_ctx_stack_field_path(struct resolve_context *ctx)
+{
+       int i;
+       struct bt_ctf_field_path *field_path;
+
+       /* Create field path */
+       field_path = bt_ctf_field_path_create();
+       if (!field_path) {
+               _printf_error("Cannot create field path\n");
+               goto error;
+       }
+
+       field_path->root = ctx->root_scope;
+
+       for (i = 0; i < type_stack_size(ctx->type_stack); i++) {
+               struct type_stack_frame *frame;
+
+               frame = type_stack_at(ctx->type_stack, i);
+               g_array_append_val(field_path->indexes, frame->index);
+       }
+
+       return field_path;
+
+error:
+       BT_PUT(field_path);
+       return field_path;
+}
+
+/*
+ * Returns the lowest common ancestor of two field path objects
+ * having the same root scope.
+ *
+ * `field_path1` and `field_path2` are owned by the caller.
+ */
+int get_field_paths_lca_index(struct bt_ctf_field_path *field_path1,
+               struct bt_ctf_field_path *field_path2)
+{
+       int lca_index = 0;
+       int field_path1_len, field_path2_len;
+
+       /*
+        * Start from both roots and find the first mismatch.
+        */
+       assert(field_path1->root == field_path2->root);
+       field_path1_len = field_path1->indexes->len;
+       field_path2_len = field_path2->indexes->len;
+
+       while (true) {
+               int target_index, ctx_index;
+
+               if (lca_index == field_path2_len ||
+                               lca_index == field_path1_len) {
+                       /*
+                        * This means that both field paths never split.
+                        * This is invalid because the target cannot be
+                        * an ancestor of the source.
+                        */
+                       _printf_error("In source and target: one is an ancestor of the other\n");
+                       lca_index = -1;
+                       break;
+               }
+
+               target_index = g_array_index(field_path1->indexes, int,
+                       lca_index);
+               ctx_index = g_array_index(field_path2->indexes, int,
+                       lca_index);
+
+               if (target_index != ctx_index) {
+                       /* LCA index is the previous */
+                       break;
+               }
+
+               lca_index++;
+       }
+
+       return lca_index;
+}
+
+/*
+ * Validates a target field path.
+ *
+ * `target_field_path` and `target_type` are owned by the caller.
+ */
+static
+int validate_target_field_path(struct bt_ctf_field_path *target_field_path,
+               struct bt_ctf_field_type *target_type,
+               struct resolve_context *ctx)
+{
+       int ret = 0;
+       struct bt_ctf_field_path *ctx_field_path;
+       int target_field_path_len = target_field_path->indexes->len;
+       int lca_index;
+       int ctx_cur_field_type_id;
+       int target_type_id;
+
+       /* Get context field path */
+       ctx_field_path = get_ctx_stack_field_path(ctx);
+       if (!ctx_field_path) {
+               _printf_error("Cannot get source field path\n");
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * Make sure the target is not a root.
+        */
+       if (target_field_path_len == 0) {
+               _printf_error("Target field path's length is 0 (targeting the root)\n");
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * Make sure the root of the target field path is not located
+        * after the context field path's root.
+        */
+       if (target_field_path->root > ctx_field_path->root) {
+               _printf_error("Target is located after source\n");
+               ret = -1;
+               goto end;
+       }
+
+       if (target_field_path->root == ctx_field_path->root) {
+               int target_index, ctx_index;
+
+               /*
+                * Find the index of the lowest common ancestor of both field
+                * paths.
+                */
+               lca_index = get_field_paths_lca_index(target_field_path,
+                       ctx_field_path);
+               if (lca_index < 0) {
+                       _printf_error("Cannot get least common ancestor\n");
+                       ret = -1;
+                       goto end;
+               }
+
+               /*
+                * Make sure the target field path is located before the
+                * context field path.
+                */
+               target_index = g_array_index(target_field_path->indexes,
+                       int, lca_index);
+               ctx_index = g_array_index(ctx_field_path->indexes,
+                       int, lca_index);
+
+               if (target_index >= ctx_index) {
+                       _printf_error("Target index (%d) is greater or equal to source index (%d) in LCA\n",
+                               target_index, ctx_index);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       /*
+        * Make sure the target type has the right type and properties.
+        */
+       ctx_cur_field_type_id = bt_ctf_field_type_get_type_id(
+               ctx->cur_field_type);
+       target_type_id = bt_ctf_field_type_get_type_id(target_type);
+
+       if (ctx_cur_field_type_id == CTF_TYPE_VARIANT) {
+               if (target_type_id != CTF_TYPE_ENUM) {
+                       _printf_error("Variant type's tag field type is not an enumeration\n");
+                       ret = -1;
+                       goto end;
+               }
+       } else if (ctx_cur_field_type_id == CTF_TYPE_SEQUENCE) {
+               if (target_type_id != CTF_TYPE_INTEGER ||
+                               bt_ctf_field_type_integer_get_signed(
+                                       target_type)) {
+                       _printf_error("Sequence type's length field type is not an unsigned integer\n");
+                       ret = -1;
+                       goto end;
+               }
+       } else {
+               assert(false);
+       }
+
+end:
+       BT_PUT(ctx_field_path);
+       return ret;
+}
+
+/*
+ * Resolves a variant or sequence field type `type`.
+ *
+ * `type` is owned by the caller.
+ */
+static
+int resolve_sequence_or_variant_type(struct bt_ctf_field_type *type,
+               struct resolve_context *ctx)
+{
+       int ret = 0;
+       const char *pathstr;
+       int type_id = bt_ctf_field_type_get_type_id(type);
+       struct bt_ctf_field_path *target_field_path = NULL;
+       struct bt_ctf_field_type *target_type = NULL;
+
+       /* Get path string */
+       switch (type_id) {
+       case CTF_TYPE_SEQUENCE:
+               pathstr =
+                       bt_ctf_field_type_sequence_get_length_field_name(type);
+               break;
+       case CTF_TYPE_VARIANT:
+               pathstr =
+                       bt_ctf_field_type_variant_get_tag_name(type);
+               break;
+       default:
+               assert(false);
+               ret = -1;
+               goto end;
+       }
+
+       /* Get target field path out of path string */
+       target_field_path = pathstr_to_field_path(pathstr, ctx);
+       if (!target_field_path) {
+               _printf_error("Cannot get target field path for path string \"%s\"\n",
+                       pathstr);
+               ret = -1;
+               goto end;
+       }
+
+       /* Get target field type */
+       target_type = field_path_to_field_type(target_field_path, ctx);
+       if (!target_type) {
+               _printf_error("Cannot get target field type for path string \"%s\"\n",
+                       pathstr);
+               ret = -1;
+               goto end;
+       }
+
+       ret = validate_target_field_path(target_field_path, target_type, ctx);
+       if (ret) {
+               _printf_error("Invalid target field path for path string \"%s\"\n",
+                       pathstr);
+               goto end;
+       }
+
+       /* Set target field path and target field type */
+       if (type_id == CTF_TYPE_SEQUENCE) {
+               ret = bt_ctf_field_type_sequence_set_length_field_path(
+                       type, target_field_path);
+               if (ret) {
+                       _printf_error("Cannot set sequence field type's length field path\n");
+                       goto end;
+               }
+       } else if (type_id == CTF_TYPE_VARIANT) {
+               ret = bt_ctf_field_type_variant_set_tag_field_path(
+                       type, target_field_path);
+               if (ret) {
+                       _printf_error("Cannot set variant field type's tag field path\n");
+                       goto end;
+               }
+
+               ret = bt_ctf_field_type_variant_set_tag_field_type(
+                       type, target_type);
+               if (ret) {
+                       _printf_error("Cannot set variant field type's tag field type\n");
+                       goto end;
+               }
+       } else {
+               assert(false);
+       }
+
+end:
+       BT_PUT(target_field_path);
+       BT_PUT(target_type);
+       return ret;
+}
+
+/*
+ * Resolves a field type `type`.
+ *
+ * `type` is owned by the caller.
+ */
+static
+int resolve_type(struct bt_ctf_field_type *type, struct resolve_context *ctx)
+{
+       int ret = 0;
+       int type_id;
+
+       if (!type) {
+               /* Type is not available; still valid */
+               goto end;
+       }
+
+       type_id = bt_ctf_field_type_get_type_id(type);
+       ctx->cur_field_type = type;
+
+       /* Resolve sequence/variant field type */
+       switch (type_id) {
+       case CTF_TYPE_SEQUENCE:
+       case CTF_TYPE_VARIANT:
+               ret = resolve_sequence_or_variant_type(type, ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve sequence or variant field type's length/tag\n");
+                       goto end;
+               }
+               break;
+       default:
+               break;
+       }
+
+       /* Recurse into compound types */
+       switch (type_id) {
+       case CTF_TYPE_STRUCT:
+       case CTF_TYPE_VARIANT:
+       case CTF_TYPE_SEQUENCE:
+       case CTF_TYPE_ARRAY:
+       {
+               int field_count, f_index;
+
+               ret = type_stack_push(ctx->type_stack, type);
+               if (ret) {
+                       _printf_error("Cannot push field type on type stack\n");
+                       _printf_error("  Stack size: %zu\n",
+                               type_stack_size(ctx->type_stack));
+                       goto end;
+               }
+
+               field_count = bt_ctf_field_type_get_field_count(type);
+               if (field_count < 0) {
+                       _printf_error("Cannot get field type field count\n");
+                       ret = field_count;
+                       goto end;
+               }
+
+               for (f_index = 0; f_index < field_count; f_index++) {
+                       struct bt_ctf_field_type *child_type =
+                               bt_ctf_field_type_get_field_at_index(type,
+                                       f_index);
+
+                       if (!child_type) {
+                               _printf_error("Cannot get field type field at index %d/%d\n",
+                                       f_index, field_count);
+                               ret = -1;
+                               goto end;
+                       }
+
+                       if (type_id == CTF_TYPE_ARRAY ||
+                                       type_id == CTF_TYPE_SEQUENCE) {
+                               type_stack_peek(ctx->type_stack)->index = -1;
+                       } else {
+                               type_stack_peek(ctx->type_stack)->index =
+                                       f_index;
+                       }
+
+                       ret = resolve_type(child_type, ctx);
+                       BT_PUT(child_type);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+
+               type_stack_pop(ctx->type_stack);
+               break;
+       }
+       default:
+               break;
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * Resolves the root field type corresponding to the scope `root_scope`.
+ */
+static
+int resolve_root_type(enum bt_ctf_scope root_scope, struct resolve_context *ctx)
+{
+       int ret;
+
+       assert(type_stack_size(ctx->type_stack) == 0);
+       ctx->root_scope = root_scope;
+       ret = resolve_type(get_type_from_ctx(ctx, root_scope), ctx);
+       ctx->root_scope = BT_CTF_SCOPE_UNKNOWN;
+
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_resolve_types(
+               struct bt_value *environment,
+               struct bt_ctf_field_type *packet_header_type,
+               struct bt_ctf_field_type *packet_context_type,
+               struct bt_ctf_field_type *event_header_type,
+               struct bt_ctf_field_type *stream_event_ctx_type,
+               struct bt_ctf_field_type *event_context_type,
+               struct bt_ctf_field_type *event_payload_type,
+               enum bt_ctf_resolve_flag flags)
+{
+       int ret = 0;
+       struct resolve_context ctx = {
+               .environment = environment,
+               .scopes = {
+                       packet_header_type,
+                       packet_context_type,
+                       event_header_type,
+                       stream_event_ctx_type,
+                       event_context_type,
+                       event_payload_type,
+               },
+               .root_scope = BT_CTF_SCOPE_UNKNOWN,
+       };
+
+       /* Initialize type stack */
+       ctx.type_stack = type_stack_create();
+       if (!ctx.type_stack) {
+               printf_error("Cannot create type stack\n");
+               ret = -1;
+               goto end;
+       }
+
+       /* Resolve packet header type */
+       if (flags & BT_CTF_RESOLVE_FLAG_PACKET_HEADER) {
+               ret = resolve_root_type(BT_CTF_SCOPE_TRACE_PACKET_HEADER, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve trace packet header type\n");
+                       goto end;
+               }
+       }
+
+       /* Resolve packet context type */
+       if (flags & BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT) {
+               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_PACKET_CONTEXT, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve stream packet context type\n");
+                       goto end;
+               }
+       }
+
+       /* Resolve event header type */
+       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_HEADER) {
+               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_HEADER, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve stream event header type\n");
+                       goto end;
+               }
+       }
+
+       /* Resolve stream event context type */
+       if (flags & BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX) {
+               ret = resolve_root_type(BT_CTF_SCOPE_STREAM_EVENT_CONTEXT, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve stream event context type\n");
+                       goto end;
+               }
+       }
+
+       /* Resolve event context type */
+       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT) {
+               ret = resolve_root_type(BT_CTF_SCOPE_EVENT_CONTEXT, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve event context type\n");
+                       goto end;
+               }
+       }
+
+       /* Resolve event payload type */
+       if (flags & BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD) {
+               ret = resolve_root_type(BT_CTF_SCOPE_EVENT_FIELDS, &ctx);
+               if (ret) {
+                       _printf_error("Cannot resolve event payload type\n");
+                       goto end;
+               }
+       }
+
+end:
+       type_stack_destroy(ctx.type_stack);
+
+       return ret;
+}
diff --git a/lib/ctf-ir/stream-class.c b/lib/ctf-ir/stream-class.c
new file mode 100644 (file)
index 0000000..fbf8194
--- /dev/null
@@ -0,0 +1,933 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/clock.h>
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-ir/clock-class-internal.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-ir/event-class-internal.h>
+#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-writer/stream.h>
+#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/ctf-ir/validation-internal.h>
+#include <babeltrace/ctf-ir/visitor-internal.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/align.h>
+#include <babeltrace/endian.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_stream_class_destroy(struct bt_object *obj);
+static
+int init_event_header(struct bt_ctf_stream_class *stream_class);
+static
+int init_packet_context(struct bt_ctf_stream_class *stream_class);
+
+struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name)
+{
+       int ret;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (name && bt_ctf_validate_identifier(name)) {
+               goto error;
+       }
+
+       stream_class = g_new0(struct bt_ctf_stream_class, 1);
+       if (!stream_class) {
+               goto error;
+       }
+
+       stream_class->name = g_string_new(name);
+       stream_class->event_classes = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_release);
+       if (!stream_class->event_classes) {
+               goto error;
+       }
+
+       stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
+                       g_int64_equal, g_free, NULL);
+
+       ret = init_event_header(stream_class);
+       if (ret) {
+               goto error;
+       }
+
+       ret = init_packet_context(stream_class);
+       if (ret) {
+               goto error;
+       }
+
+       bt_object_init(stream_class, bt_ctf_stream_class_destroy);
+       return stream_class;
+
+error:
+        BT_PUT(stream_class);
+       return stream_class;
+}
+
+struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
+               struct bt_ctf_stream_class *stream_class)
+{
+       return stream_class ?
+               bt_get(bt_ctf_stream_class_borrow_trace(stream_class)) :
+               NULL;
+}
+
+const char *bt_ctf_stream_class_get_name(
+               struct bt_ctf_stream_class *stream_class)
+{
+       const char *name = NULL;
+
+       if (!stream_class) {
+               goto end;
+       }
+
+       name = stream_class->name->str;
+end:
+       return name;
+}
+
+int bt_ctf_stream_class_set_name(struct bt_ctf_stream_class *stream_class,
+               const char *name)
+{
+       int ret = 0;
+
+       if (!stream_class || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       g_string_assign(stream_class->name, name);
+end:
+       return ret;
+}
+
+struct bt_ctf_clock *bt_ctf_stream_class_get_clock(
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_clock *clock = NULL;
+
+       if (!stream_class || !stream_class->clock) {
+               goto end;
+       }
+
+       clock = bt_get(stream_class->clock);
+end:
+       return clock;
+}
+
+int bt_ctf_stream_class_set_clock(struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_clock *clock)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *timestamp_field = NULL;
+
+       if (!stream_class || !clock || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * Look for a "timestamp" integer field type in the stream
+        * class's event header field type and map the stream class's
+        * clock's class to that field type if there's no current
+        * mapping.
+        */
+       timestamp_field = bt_ctf_field_type_structure_get_field_type_by_name(
+               stream_class->event_header_type, "timestamp");
+       if (timestamp_field) {
+               struct bt_ctf_clock_class *mapped_clock_class =
+                       bt_ctf_field_type_integer_get_mapped_clock_class(
+                               timestamp_field);
+
+               if (!mapped_clock_class) {
+                       ret = bt_ctf_field_type_integer_set_mapped_clock_class(
+                               timestamp_field, clock->clock_class);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+
+               BT_PUT(mapped_clock_class);
+       }
+
+       /* Replace the current clock of this stream class. */
+       bt_put(stream_class->clock);
+       stream_class->clock = bt_get(clock);
+
+end:
+       bt_put(timestamp_field);
+       return ret;
+}
+
+int64_t bt_ctf_stream_class_get_id(struct bt_ctf_stream_class *stream_class)
+{
+       int64_t ret;
+
+       if (!stream_class || !stream_class->id_set) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = (int64_t) stream_class->id;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int _bt_ctf_stream_class_set_id(
+               struct bt_ctf_stream_class *stream_class, uint32_t id)
+{
+       stream_class->id = id;
+       stream_class->id_set = 1;
+       return 0;
+}
+
+struct event_class_set_stream_id_data {
+       uint32_t stream_id;
+       int ret;
+};
+
+static
+void event_class_set_stream_id(gpointer event_class, gpointer data)
+{
+       struct event_class_set_stream_id_data *typed_data = data;
+
+       typed_data->ret |= bt_ctf_event_class_set_stream_id(event_class,
+               typed_data->stream_id);
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_set_id_no_check(
+               struct bt_ctf_stream_class *stream_class, uint32_t id)
+{
+       int ret = 0;
+       struct event_class_set_stream_id_data data =
+               { .stream_id = id, .ret = 0 };
+
+       /*
+        * Make sure all event classes have their "stream_id" attribute
+        * set to this value.
+        */
+       g_ptr_array_foreach(stream_class->event_classes,
+               event_class_set_stream_id, &data);
+       ret = data.ret;
+       if (ret) {
+               goto end;
+       }
+
+       ret = _bt_ctf_stream_class_set_id(stream_class, id);
+       if (ret) {
+               goto end;
+       }
+end:
+       return ret;
+}
+
+int bt_ctf_stream_class_set_id(struct bt_ctf_stream_class *stream_class,
+               uint32_t id)
+{
+       int ret = 0;
+
+       if (!stream_class || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_stream_class_set_id_no_check(stream_class, id);
+end:
+       return ret;
+}
+
+static
+void event_class_exists(gpointer element, gpointer query)
+{
+       struct bt_ctf_event_class *event_class_a = element;
+       struct search_query *search_query = query;
+       struct bt_ctf_event_class *event_class_b = search_query->value;
+       int64_t id_a, id_b;
+
+       if (search_query->value == element) {
+               search_query->found = 1;
+               goto end;
+       }
+
+       /*
+        * Two event classes cannot share the same name in a given
+        * stream class.
+        */
+       if (!strcmp(bt_ctf_event_class_get_name(event_class_a),
+                       bt_ctf_event_class_get_name(event_class_b))) {
+               search_query->found = 1;
+               goto end;
+       }
+
+       /*
+        * Two event classes cannot share the same ID in a given
+        * stream class.
+        */
+       id_a = bt_ctf_event_class_get_id(event_class_a);
+       id_b = bt_ctf_event_class_get_id(event_class_b);
+
+       if (id_a < 0 || id_b < 0) {
+               /* at least one ID is not set: will be automatically set later */
+               goto end;
+       }
+
+       if (id_a == id_b) {
+               search_query->found = 1;
+               goto end;
+       }
+
+end:
+       return;
+}
+
+int bt_ctf_stream_class_add_event_class(
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_event_class *event_class)
+{
+       int ret = 0;
+       int64_t *event_id = NULL;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_stream_class *old_stream_class = NULL;
+       struct bt_ctf_validation_output validation_output = { 0 };
+       struct bt_ctf_field_type *packet_header_type = NULL;
+       struct bt_ctf_field_type *packet_context_type = NULL;
+       struct bt_ctf_field_type *event_header_type = NULL;
+       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
+       struct bt_ctf_field_type *event_context_type = NULL;
+       struct bt_ctf_field_type *event_payload_type = NULL;
+       const enum bt_ctf_validation_flag validation_flags =
+               BT_CTF_VALIDATION_FLAG_EVENT;
+
+       if (!stream_class || !event_class) {
+               ret = -1;
+               goto end;
+       }
+
+       event_id = g_new(int64_t, 1);
+       if (!event_id) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Check for duplicate event classes */
+       struct search_query query = { .value = event_class, .found = 0 };
+       g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
+               &query);
+       if (query.found) {
+               ret = -1;
+               goto end;
+       }
+
+       old_stream_class = bt_ctf_event_class_get_stream_class(event_class);
+       if (old_stream_class) {
+               /* Event class is already associated to a stream class. */
+               ret = -1;
+               goto end;
+       }
+
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (trace) {
+               /*
+                * If the stream class is associated with a trace, then
+                * both those objects are frozen. Also, this event class
+                * is about to be frozen.
+                *
+                * Therefore the event class must be validated here.
+                * The trace and stream class should be valid at this
+                * point.
+                */
+               assert(trace->valid);
+               assert(stream_class->valid);
+               packet_header_type =
+                       bt_ctf_trace_get_packet_header_type(trace);
+               packet_context_type =
+                       bt_ctf_stream_class_get_packet_context_type(
+                               stream_class);
+               event_header_type =
+                       bt_ctf_stream_class_get_event_header_type(stream_class);
+               stream_event_ctx_type =
+                       bt_ctf_stream_class_get_event_context_type(
+                               stream_class);
+               event_context_type =
+                       bt_ctf_event_class_get_context_type(event_class);
+               event_payload_type =
+                       bt_ctf_event_class_get_payload_type(event_class);
+               ret = bt_ctf_validate_class_types(
+                       trace->environment, packet_header_type,
+                       packet_context_type, event_header_type,
+                       stream_event_ctx_type, event_context_type,
+                       event_payload_type, trace->valid,
+                       stream_class->valid, event_class->valid,
+                       &validation_output, validation_flags);
+               BT_PUT(packet_header_type);
+               BT_PUT(packet_context_type);
+               BT_PUT(event_header_type);
+               BT_PUT(stream_event_ctx_type);
+               BT_PUT(event_context_type);
+               BT_PUT(event_payload_type);
+
+               if (ret) {
+                       /*
+                        * This means something went wrong during the
+                        * validation process, not that the objects are
+                        * invalid.
+                        */
+                       goto end;
+               }
+
+               if ((validation_output.valid_flags & validation_flags) !=
+                               validation_flags) {
+                       /* Invalid event class */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       /* Only set an event ID if none was explicitly set before */
+       *event_id = bt_ctf_event_class_get_id(event_class);
+       if (*event_id < 0) {
+               if (bt_ctf_event_class_set_id(event_class,
+                       stream_class->next_event_id++)) {
+                       ret = -1;
+                       goto end;
+               }
+               *event_id = stream_class->next_event_id;
+       }
+
+       ret = bt_ctf_event_class_set_stream_id(event_class, stream_class->id);
+       if (ret) {
+               goto end;
+       }
+
+       bt_object_set_parent(event_class, stream_class);
+
+       if (trace) {
+               /*
+                * At this point we know that the function will be
+                * successful. Therefore we can replace the event
+                * class's field types with what's in the validation
+                * output structure and mark this event class as valid.
+                */
+               bt_ctf_validation_replace_types(NULL, NULL, event_class,
+                       &validation_output, validation_flags);
+               event_class->valid = 1;
+
+               /*
+                * Put what was not moved in
+                * bt_ctf_validation_replace_types().
+                */
+               bt_ctf_validation_output_put_types(&validation_output);
+       }
+
+       /* Add to the event classes of the stream class */
+       g_ptr_array_add(stream_class->event_classes, event_class);
+       g_hash_table_insert(stream_class->event_classes_ht, event_id,
+                       event_class);
+       event_id = NULL;
+
+       /* Freeze the event class */
+       bt_ctf_event_class_freeze(event_class);
+
+       /* Notifiy listeners of the trace's schema modification. */
+       if (trace) {
+               struct bt_ctf_object obj = { .object = event_class,
+                               .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
+
+               (void) bt_ctf_trace_object_modification(&obj, trace);
+       }
+end:
+       BT_PUT(trace);
+       BT_PUT(old_stream_class);
+       bt_ctf_validation_output_put_types(&validation_output);
+       assert(!packet_header_type);
+       assert(!packet_context_type);
+       assert(!event_header_type);
+       assert(!stream_event_ctx_type);
+       assert(!event_context_type);
+       assert(!event_payload_type);
+       g_free(event_id);
+
+       return ret;
+}
+
+int bt_ctf_stream_class_get_event_class_count(
+               struct bt_ctf_stream_class *stream_class)
+{
+       int ret;
+
+       if (!stream_class) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = (int) stream_class->event_classes->len;
+end:
+       return ret;
+}
+
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
+               struct bt_ctf_stream_class *stream_class, int index)
+{
+       struct bt_ctf_event_class *event_class = NULL;
+
+       if (!stream_class || index < 0 ||
+               index >= stream_class->event_classes->len) {
+               goto end;
+       }
+
+       event_class = g_ptr_array_index(stream_class->event_classes, index);
+       bt_get(event_class);
+end:
+       return event_class;
+}
+
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
+               struct bt_ctf_stream_class *stream_class, const char *name)
+{
+       size_t i;
+       struct bt_ctf_event_class *event_class = NULL;
+
+       if (!stream_class || !name) {
+               goto end;
+       }
+
+       for (i = 0; i < stream_class->event_classes->len; i++) {
+               struct bt_ctf_event_class *cur_event_class =
+                       g_ptr_array_index(stream_class->event_classes, i);
+               const char *cur_event_class_name =
+                       bt_ctf_event_class_get_name(cur_event_class);
+
+               if (!strcmp(name, cur_event_class_name)) {
+                       event_class = cur_event_class;
+                       bt_get(event_class);
+                       goto end;
+               }
+       }
+end:
+       return event_class;
+}
+
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
+               struct bt_ctf_stream_class *stream_class, uint32_t id)
+{
+       int64_t id_key = id;
+       struct bt_ctf_event_class *event_class = NULL;
+
+       if (!stream_class) {
+               goto end;
+       }
+
+       event_class = g_hash_table_lookup(stream_class->event_classes_ht,
+                       &id_key);
+       bt_get(event_class);
+end:
+       return event_class;
+}
+
+struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_field_type *ret = NULL;
+
+       if (!stream_class) {
+               goto end;
+       }
+
+       bt_get(stream_class->packet_context_type);
+       ret = stream_class->packet_context_type;
+end:
+       return ret;
+}
+
+int bt_ctf_stream_class_set_packet_context_type(
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_field_type *packet_context_type)
+{
+       int ret = 0;
+
+       if (!stream_class || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (packet_context_type &&
+                       bt_ctf_field_type_get_type_id(packet_context_type) !=
+                               BT_CTF_TYPE_ID_STRUCT) {
+               /* A packet context must be a structure. */
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(stream_class->packet_context_type);
+       bt_get(packet_context_type);
+       stream_class->packet_context_type = packet_context_type;
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_stream_class_get_event_header_type(
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_field_type *ret = NULL;
+
+       if (!stream_class || !stream_class->event_header_type) {
+               goto end;
+       }
+
+       bt_get(stream_class->event_header_type);
+       ret = stream_class->event_header_type;
+end:
+       return ret;
+}
+
+int bt_ctf_stream_class_set_event_header_type(
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_field_type *event_header_type)
+{
+       int ret = 0;
+
+       if (!stream_class || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (event_header_type &&
+                       bt_ctf_field_type_get_type_id(event_header_type) !=
+                               BT_CTF_TYPE_ID_STRUCT) {
+               /* An event header must be a structure. */
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(stream_class->event_header_type);
+       stream_class->event_header_type = bt_get(event_header_type);
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_stream_class_get_event_context_type(
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_field_type *ret = NULL;
+
+       if (!stream_class || !stream_class->event_context_type) {
+               goto end;
+       }
+
+       bt_get(stream_class->event_context_type);
+       ret = stream_class->event_context_type;
+end:
+       return ret;
+}
+
+int bt_ctf_stream_class_set_event_context_type(
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_field_type *event_context_type)
+{
+       int ret = 0;
+
+       if (!stream_class || stream_class->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (event_context_type &&
+                       bt_ctf_field_type_get_type_id(event_context_type) !=
+                               BT_CTF_TYPE_ID_STRUCT) {
+               /* A packet context must be a structure. */
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(stream_class->event_context_type);
+       stream_class->event_context_type = bt_get(event_context_type);
+end:
+       return ret;
+}
+
+void bt_ctf_stream_class_get(struct bt_ctf_stream_class *stream_class)
+{
+       bt_get(stream_class);
+}
+
+void bt_ctf_stream_class_put(struct bt_ctf_stream_class *stream_class)
+{
+       bt_put(stream_class);
+}
+
+static
+int get_event_class_count(void *element)
+{
+       return bt_ctf_stream_class_get_event_class_count(
+                       (struct bt_ctf_stream_class *) element);
+}
+
+static
+void *get_event_class(void *element, int i)
+{
+       return bt_ctf_stream_class_get_event_class(
+                       (struct bt_ctf_stream_class *) element, i);
+}
+
+static
+int visit_event_class(void *object, bt_ctf_visitor visitor,void *data)
+{
+       struct bt_ctf_object obj =
+                       { .object = object,
+                       .type = BT_CTF_OBJECT_TYPE_EVENT_CLASS };
+
+       return visitor(&obj, data);
+}
+
+int bt_ctf_stream_class_visit(struct bt_ctf_stream_class *stream_class,
+               bt_ctf_visitor visitor, void *data)
+{
+       int ret;
+       struct bt_ctf_object obj =
+                       { .object = stream_class,
+                       .type = BT_CTF_OBJECT_TYPE_STREAM_CLASS };
+
+       if (!stream_class || !visitor) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = visitor_helper(&obj, get_event_class_count,
+                       get_event_class,
+                       visit_event_class, visitor, data);
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_stream_class_freeze(struct bt_ctf_stream_class *stream_class)
+{
+       if (!stream_class) {
+               return;
+       }
+
+       stream_class->frozen = 1;
+       bt_ctf_field_type_freeze(stream_class->event_header_type);
+       bt_ctf_field_type_freeze(stream_class->packet_context_type);
+       bt_ctf_field_type_freeze(stream_class->event_context_type);
+
+       if (stream_class->clock) {
+               bt_ctf_clock_class_freeze(stream_class->clock->clock_class);
+       }
+}
+
+BT_HIDDEN
+int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class *stream_class,
+               struct metadata_context *context)
+{
+       int64_t ret = 0;
+       size_t i;
+
+       g_string_assign(context->field_name, "");
+       context->current_indentation_level = 1;
+       if (!stream_class->id_set) {
+               ret = -1;
+               goto end;
+       }
+
+       g_string_append_printf(context->string,
+               "stream {\n\tid = %" PRIu32 ";\n\tevent.header := ",
+               stream_class->id);
+       ret = bt_ctf_field_type_serialize(stream_class->event_header_type,
+               context);
+       if (ret) {
+               goto end;
+       }
+
+       if (stream_class->packet_context_type) {
+               g_string_append(context->string, ";\n\n\tpacket.context := ");
+               ret = bt_ctf_field_type_serialize(stream_class->packet_context_type,
+                       context);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       if (stream_class->event_context_type) {
+               g_string_append(context->string, ";\n\n\tevent.context := ");
+               ret = bt_ctf_field_type_serialize(
+                       stream_class->event_context_type, context);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       g_string_append(context->string, ";\n};\n\n");
+       for (i = 0; i < stream_class->event_classes->len; i++) {
+               struct bt_ctf_event_class *event_class =
+                       stream_class->event_classes->pdata[i];
+
+               ret = bt_ctf_event_class_serialize(event_class, context);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       context->current_indentation_level = 0;
+       return ret;
+}
+
+static
+void bt_ctf_stream_class_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_stream_class *stream_class;
+
+       stream_class = container_of(obj, struct bt_ctf_stream_class, base);
+       bt_put(stream_class->clock);
+
+       if (stream_class->event_classes_ht) {
+               g_hash_table_destroy(stream_class->event_classes_ht);
+       }
+       if (stream_class->event_classes) {
+               g_ptr_array_free(stream_class->event_classes, TRUE);
+       }
+
+       if (stream_class->name) {
+               g_string_free(stream_class->name, TRUE);
+       }
+
+       bt_put(stream_class->event_header_type);
+       bt_put(stream_class->packet_context_type);
+       bt_put(stream_class->event_context_type);
+       g_free(stream_class);
+}
+
+static
+int init_event_header(struct bt_ctf_stream_class *stream_class)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *event_header_type =
+               bt_ctf_field_type_structure_create();
+       struct bt_ctf_field_type *_uint32_t =
+               get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
+       struct bt_ctf_field_type *_uint64_t =
+               get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
+
+       if (!event_header_type) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(event_header_type,
+               _uint32_t, "id");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(event_header_type,
+               _uint64_t, "timestamp");
+       if (ret) {
+               goto end;
+       }
+
+       if (stream_class->event_header_type) {
+               bt_put(stream_class->event_header_type);
+       }
+       stream_class->event_header_type = event_header_type;
+end:
+       if (ret) {
+               bt_put(event_header_type);
+       }
+
+       bt_put(_uint32_t);
+       bt_put(_uint64_t);
+       return ret;
+}
+
+static
+int init_packet_context(struct bt_ctf_stream_class *stream_class)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *packet_context_type =
+               bt_ctf_field_type_structure_create();
+       struct bt_ctf_field_type *_uint64_t =
+               get_field_type(FIELD_TYPE_ALIAS_UINT64_T);
+
+       if (!packet_context_type) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * We create a stream packet context as proposed in the CTF
+        * specification.
+        */
+       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+               _uint64_t, "timestamp_begin");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+               _uint64_t, "timestamp_end");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+               _uint64_t, "content_size");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+               _uint64_t, "packet_size");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+               _uint64_t, "events_discarded");
+       if (ret) {
+               goto end;
+       }
+
+       bt_put(stream_class->packet_context_type);
+       stream_class->packet_context_type = packet_context_type;
+end:
+       if (ret) {
+               bt_put(packet_context_type);
+               goto end;
+       }
+
+       bt_put(_uint64_t);
+       return ret;
+}
diff --git a/lib/ctf-ir/stream.c b/lib/ctf-ir/stream.c
new file mode 100644 (file)
index 0000000..39d490c
--- /dev/null
@@ -0,0 +1,1230 @@
+/*
+ * 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.
+ */
+
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-writer/clock.h>
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/event.h>
+#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/ctf-ir/stream-internal.h>
+#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/ctf-ir/trace-internal.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/align.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_stream_destroy(struct bt_object *obj);
+static
+int try_set_structure_field_integer(struct bt_ctf_field *, char *, uint64_t);
+static
+int set_structure_field_integer(struct bt_ctf_field *, char *, uint64_t);
+
+static
+int set_integer_field_value(struct bt_ctf_field* field, uint64_t value)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!field) {
+               ret = -1;
+               goto end;
+       }
+
+       field_type = bt_ctf_field_get_type(field);
+       assert(field_type);
+
+       if (bt_ctf_field_type_get_type_id(field_type) !=
+                       BT_CTF_TYPE_ID_INTEGER) {
+               /* Not an integer and the value is unset, error. */
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_integer_get_signed(field_type)) {
+               ret = bt_ctf_field_signed_integer_set_value(field, (int64_t) value);
+               if (ret) {
+                       /* Value is out of range, error. */
+                       goto end;
+               }
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(field, value);
+               if (ret) {
+                       /* Value is out of range, error. */
+                       goto end;
+               }
+       }
+end:
+       bt_put(field_type);
+       return ret;
+}
+
+static
+int set_packet_header_magic(struct bt_ctf_stream *stream)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *magic_field_type = NULL;
+       struct bt_ctf_field *magic_field = bt_ctf_field_structure_get_field(
+               stream->packet_header, "magic");
+
+       if (!magic_field) {
+               /* No magic field found. Not an error, skip. */
+               goto end;
+       }
+
+       if (bt_ctf_field_is_set(magic_field)) {
+               /* Value already set. Not an error, skip. */
+               goto end;
+       }
+
+       magic_field_type = bt_ctf_field_get_type(magic_field);
+       assert(magic_field_type);
+
+       if (bt_ctf_field_type_get_type_id(magic_field_type) !=
+               BT_CTF_TYPE_ID_INTEGER) {
+               /* Magic field is not an integer. Not an error, skip. */
+               goto end;
+       }
+
+       if (bt_ctf_field_type_integer_get_size(magic_field_type) != 32) {
+               /*
+                * Magic field is not of the expected size.
+                * Not an error, skip.
+                */
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_integer_get_signed(magic_field_type);
+       assert(ret >= 0);
+       if (ret) {
+               ret = bt_ctf_field_signed_integer_set_value(magic_field,
+                       (int64_t) 0xC1FC1FC1);
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(magic_field,
+                       (uint64_t) 0xC1FC1FC1);
+       }
+end:
+       bt_put(magic_field);
+       bt_put(magic_field_type);
+       return ret;
+}
+
+static
+int set_packet_header_uuid(struct bt_ctf_stream *stream)
+{
+       int i, ret = 0;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_field_type *uuid_field_type = NULL;
+       struct bt_ctf_field_type *element_field_type = NULL;
+       struct bt_ctf_field *uuid_field = bt_ctf_field_structure_get_field(
+               stream->packet_header, "uuid");
+
+       if (!uuid_field) {
+               /* No uuid field found. Not an error, skip. */
+               goto end;
+       }
+
+       if (bt_ctf_field_is_set(uuid_field)) {
+               /* Value already set. Not an error, skip. */
+               goto end;
+       }
+
+       uuid_field_type = bt_ctf_field_get_type(uuid_field);
+       assert(uuid_field_type);
+       if (bt_ctf_field_type_get_type_id(uuid_field_type) !=
+               BT_CTF_TYPE_ID_ARRAY) {
+               /* UUID field is not an array. Not an error, skip. */
+               goto end;
+       }
+
+       if (bt_ctf_field_type_array_get_length(uuid_field_type) != 16) {
+               /*
+                * UUID field is not of the expected size.
+                * Not an error, skip.
+                */
+               goto end;
+       }
+
+       element_field_type = bt_ctf_field_type_array_get_element_type(
+               uuid_field_type);
+       assert(element_field_type);
+       if (bt_ctf_field_type_get_type_id(element_field_type) !=
+               BT_CTF_TYPE_ID_INTEGER) {
+               /* UUID array elements are not integers. Not an error, skip */
+               goto end;
+       }
+
+       trace = (struct bt_ctf_trace *) bt_object_get_parent(stream);
+       for (i = 0; i < 16; i++) {
+               struct bt_ctf_field *uuid_element =
+                       bt_ctf_field_array_get_field(uuid_field, i);
+
+               ret = bt_ctf_field_type_integer_get_signed(element_field_type);
+               assert(ret >= 0);
+
+               if (ret) {
+                       ret = bt_ctf_field_signed_integer_set_value(
+                               uuid_element, (int64_t) trace->uuid[i]);
+               } else {
+                       ret = bt_ctf_field_unsigned_integer_set_value(
+                               uuid_element,
+                               (uint64_t) trace->uuid[i]);
+               }
+               bt_put(uuid_element);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       bt_put(uuid_field);
+       bt_put(uuid_field_type);
+       bt_put(element_field_type);
+       BT_PUT(trace);
+       return ret;
+}
+static
+int set_packet_header_stream_id(struct bt_ctf_stream *stream)
+{
+       int ret = 0;
+       uint32_t stream_id;
+       struct bt_ctf_field_type *stream_id_field_type = NULL;
+       struct bt_ctf_field *stream_id_field = bt_ctf_field_structure_get_field(
+               stream->packet_header, "stream_id");
+
+       if (!stream_id_field) {
+               /* No stream_id field found. Not an error, skip. */
+               goto end;
+       }
+
+       if (bt_ctf_field_is_set(stream_id_field)) {
+               /* Value already set. Not an error, skip. */
+               goto end;
+       }
+
+       stream_id_field_type = bt_ctf_field_get_type(stream_id_field);
+       assert(stream_id_field_type);
+       if (bt_ctf_field_type_get_type_id(stream_id_field_type) !=
+               BT_CTF_TYPE_ID_INTEGER) {
+               /* stream_id field is not an integer. Not an error, skip. */
+               goto end;
+       }
+
+       stream_id = stream->stream_class->id;
+       ret = bt_ctf_field_type_integer_get_signed(stream_id_field_type);
+       assert(ret >= 0);
+       if (ret) {
+               ret = bt_ctf_field_signed_integer_set_value(stream_id_field,
+                       (int64_t) stream_id);
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(stream_id_field,
+                       (uint64_t) stream_id);
+       }
+end:
+       bt_put(stream_id_field);
+       bt_put(stream_id_field_type);
+       return ret;
+}
+
+static
+int set_packet_header(struct bt_ctf_stream *stream)
+{
+       int ret;
+
+       ret = set_packet_header_magic(stream);
+       if (ret) {
+               goto end;
+       }
+
+       ret = set_packet_header_uuid(stream);
+       if (ret) {
+               goto end;
+       }
+
+       ret = set_packet_header_stream_id(stream);
+       if (ret) {
+               goto end;
+       }
+end:
+       return ret;
+}
+
+static
+void release_event(struct bt_ctf_event *event)
+{
+       if (bt_object_get_ref_count(event)) {
+               /*
+                * The event is being orphaned, but it must guarantee the
+                * existence of its event class for the duration of its
+                * lifetime.
+                */
+               bt_get(event->event_class);
+               BT_PUT(event->base.parent);
+       } else {
+               bt_object_release(event);
+       }
+}
+
+static
+int create_stream_file(struct bt_ctf_writer *writer,
+               struct bt_ctf_stream *stream)
+{
+       int fd;
+       GString *filename = g_string_new(stream->stream_class->name->str);
+
+       if (stream->stream_class->name->len == 0) {
+               int64_t ret;
+
+               ret = bt_ctf_stream_class_get_id(stream->stream_class);
+               if (ret < 0) {
+                       fd = -1;
+                       goto error;
+               }
+
+               g_string_printf(filename, "stream_%" PRId64, ret);
+       }
+
+       g_string_append_printf(filename, "_%" PRIu32, stream->id);
+       fd = openat(writer->trace_dir_fd, filename->str,
+               O_RDWR | O_CREAT | O_TRUNC,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+error:
+       g_string_free(filename, TRUE);
+       return fd;
+}
+
+static
+int set_stream_fd(struct bt_ctf_stream *stream, int fd)
+{
+       int ret = 0;
+
+       if (stream->pos.fd != -1) {
+               ret = -1;
+               goto end;
+       }
+
+       (void) bt_ctf_stream_pos_init(&stream->pos, fd, O_RDWR);
+       stream->pos.fd = fd;
+end:
+       return ret;
+}
+
+struct bt_ctf_stream *bt_ctf_stream_create(
+               struct bt_ctf_stream_class *stream_class,
+               const char *name)
+{
+       int ret;
+       struct bt_ctf_stream *stream = NULL;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_writer *writer = NULL;
+
+       if (!stream_class) {
+               goto error;
+       }
+
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (!trace) {
+               goto error;
+       }
+
+       stream = g_new0(struct bt_ctf_stream, 1);
+       if (!stream) {
+               goto error;
+       }
+
+       bt_object_init(stream, bt_ctf_stream_destroy);
+       /*
+        * Acquire reference to parent since stream will become publicly
+        * reachable; it needs its parent to remain valid.
+        */
+       bt_object_set_parent(stream, trace);
+       stream->id = stream_class->next_stream_id++;
+       stream->stream_class = stream_class;
+       stream->pos.fd = -1;
+
+       if (name) {
+               stream->name = g_string_new(name);
+               if (!stream->name) {
+                       goto error;
+               }
+       }
+
+       if (trace->is_created_by_writer) {
+               int fd;
+               writer = (struct bt_ctf_writer *)
+                       bt_object_get_parent(trace);
+
+               assert(writer);
+               if (stream_class->packet_context_type) {
+                       stream->packet_context = bt_ctf_field_create(
+                               stream_class->packet_context_type);
+                       if (!stream->packet_context) {
+                               goto error;
+                       }
+
+                       /* Initialize events_discarded */
+                       ret = try_set_structure_field_integer(
+                               stream->packet_context,
+                               "events_discarded", 0);
+                       if (ret != 1) {
+                               goto error;
+                       }
+               }
+
+               stream->events = g_ptr_array_new_with_free_func(
+                       (GDestroyNotify) release_event);
+               if (!stream->events) {
+                       goto error;
+               }
+
+               /* A trace is not allowed to have a NULL packet header */
+               assert(trace->packet_header_type);
+               stream->packet_header =
+                       bt_ctf_field_create(trace->packet_header_type);
+               if (!stream->packet_header) {
+                       goto error;
+               }
+
+               /*
+                * Attempt to populate the default trace packet header fields
+                * (magic, uuid and stream_id). This will _not_ fail shall the
+                * fields not be found or be of an incompatible type; they will
+                * simply not be populated automatically. The user will have to
+                * make sure to set the trace packet header fields himself
+                * before flushing.
+                */
+               ret = set_packet_header(stream);
+               if (ret) {
+                       goto error;
+               }
+
+               /* Create file associated with this stream */
+               fd = create_stream_file(writer, stream);
+               if (fd < 0) {
+                       goto error;
+               }
+
+               ret = set_stream_fd(stream, fd);
+               if (ret) {
+                       goto error;
+               }
+
+               /* Freeze the writer */
+               bt_ctf_writer_freeze(writer);
+       } else {
+               /* Non-writer stream indicated by a negative FD */
+               ret = set_stream_fd(stream, -1);
+               if (ret) {
+                       goto error;
+               }
+       }
+
+       /* Add this stream to the trace's streams */
+       g_ptr_array_add(trace->streams, stream);
+
+       BT_PUT(trace);
+       BT_PUT(writer);
+       return stream;
+error:
+       BT_PUT(stream);
+       BT_PUT(trace);
+       BT_PUT(writer);
+       return stream;
+}
+
+struct bt_ctf_stream_class *bt_ctf_stream_get_class(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (!stream) {
+               goto end;
+       }
+
+       stream_class = stream->stream_class;
+       bt_get(stream_class);
+end:
+       return stream_class;
+}
+
+int bt_ctf_stream_get_discarded_events_count(
+               struct bt_ctf_stream *stream, uint64_t *count)
+{
+       int64_t ret = 0;
+       int field_signed;
+       struct bt_ctf_field *events_discarded_field = NULL;
+       struct bt_ctf_field_type *events_discarded_field_type = NULL;
+
+       if (!stream || !count || !stream->packet_context ||
+                       stream->pos.fd < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       events_discarded_field = bt_ctf_field_structure_get_field(
+               stream->packet_context, "events_discarded");
+       if (!events_discarded_field) {
+               ret = -1;
+               goto end;
+       }
+
+       events_discarded_field_type = bt_ctf_field_get_type(
+               events_discarded_field);
+       if (!events_discarded_field_type) {
+               ret = -1;
+               goto end;
+       }
+
+       field_signed = bt_ctf_field_type_integer_get_signed(
+               events_discarded_field_type);
+       if (field_signed < 0) {
+               ret = field_signed;
+               goto end;
+       }
+
+       if (field_signed) {
+               int64_t signed_count;
+
+               ret = bt_ctf_field_signed_integer_get_value(
+                       events_discarded_field, &signed_count);
+               if (ret) {
+                       goto end;
+               }
+               if (signed_count < 0) {
+                       /* Invalid value */
+                       ret = -1;
+                       goto end;
+               }
+               *count = (uint64_t) signed_count;
+       } else {
+               ret = bt_ctf_field_unsigned_integer_get_value(
+                       events_discarded_field, count);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       bt_put(events_discarded_field);
+       bt_put(events_discarded_field_type);
+       return ret;
+}
+
+void bt_ctf_stream_append_discarded_events(struct bt_ctf_stream *stream,
+               uint64_t event_count)
+{
+       int ret;
+       int field_signed;
+       uint64_t previous_count;
+       uint64_t new_count;
+       struct bt_ctf_field *events_discarded_field = NULL;
+       struct bt_ctf_field_type *events_discarded_field_type = NULL;
+
+       if (!stream || !stream->packet_context || stream->pos.fd < 0) {
+               goto end;
+       }
+
+       ret = bt_ctf_stream_get_discarded_events_count(stream,
+               &previous_count);
+       if (ret) {
+               goto end;
+       }
+
+       events_discarded_field = bt_ctf_field_structure_get_field(
+               stream->packet_context, "events_discarded");
+       if (!events_discarded_field) {
+               goto end;
+       }
+
+       events_discarded_field_type = bt_ctf_field_get_type(
+               events_discarded_field);
+       if (!events_discarded_field_type) {
+               goto end;
+       }
+
+       field_signed = bt_ctf_field_type_integer_get_signed(
+               events_discarded_field_type);
+       if (field_signed < 0) {
+               goto end;
+       }
+
+       new_count = previous_count + event_count;
+       if (field_signed) {
+               ret = bt_ctf_field_signed_integer_set_value(
+                       events_discarded_field, (int64_t) new_count);
+               if (ret) {
+                       goto end;
+               }
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(
+                       events_discarded_field, new_count);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+end:
+       bt_put(events_discarded_field);
+       bt_put(events_discarded_field_type);
+}
+
+static int auto_populate_event_header(struct bt_ctf_stream *stream,
+               struct bt_ctf_event *event)
+{
+       int ret = 0;
+       struct bt_ctf_field *id_field = NULL, *timestamp_field = NULL;
+       struct bt_ctf_clock_class *mapped_clock_class = NULL;
+
+       if (!event || event->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * The condition to automatically set the ID are:
+        *
+        * 1. The event header field "id" exists and is an integer
+        *    field.
+        * 2. The event header field "id" is NOT set.
+        */
+       id_field = bt_ctf_field_structure_get_field(event->event_header, "id");
+       if (id_field && !bt_ctf_field_is_set(id_field)) {
+               ret = set_integer_field_value(id_field,
+                       (uint64_t) bt_ctf_event_class_get_id(
+                                       event->event_class));
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       /*
+        * The conditions to automatically set the timestamp are:
+        *
+        * 1. The event header field "timestamp" exists and is an
+        *    integer field.
+        * 2. This stream's class has a registered clock (set with
+        *    bt_ctf_stream_class_set_clock()).
+        * 3. The event header field "timestamp" has its type mapped to
+        *    a clock class which is also the clock class of this
+        *    stream's class's registered clock.
+        * 4. The event header field "timestamp" is NOT set.
+        */
+       timestamp_field = bt_ctf_field_structure_get_field(event->event_header,
+                       "timestamp");
+       if (timestamp_field && !bt_ctf_field_is_set(timestamp_field) &&
+                       stream->stream_class->clock) {
+               struct bt_ctf_clock_class *stream_class_clock_class =
+                       stream->stream_class->clock->clock_class;
+               struct bt_ctf_field_type *timestamp_field_type =
+                       bt_ctf_field_get_type(timestamp_field);
+
+               assert(timestamp_field_type);
+               mapped_clock_class =
+                       bt_ctf_field_type_integer_get_mapped_clock_class(
+                               timestamp_field_type);
+               BT_PUT(timestamp_field_type);
+               if (mapped_clock_class == stream_class_clock_class) {
+                       uint64_t timestamp;
+
+                       ret = bt_ctf_clock_get_value(
+                               stream->stream_class->clock,
+                               &timestamp);
+                       if (ret) {
+                               goto end;
+                       }
+
+                       ret = set_integer_field_value(timestamp_field,
+                                       timestamp);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+       }
+
+end:
+       bt_put(id_field);
+       bt_put(timestamp_field);
+       bt_put(mapped_clock_class);
+       return ret;
+}
+
+int bt_ctf_stream_append_event(struct bt_ctf_stream *stream,
+               struct bt_ctf_event *event)
+{
+       int ret = 0;
+
+       if (!stream || !event || stream->pos.fd < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       /*
+        * The event is not supposed to have a parent stream at this
+        * point. The only other way an event can have a parent stream
+        * is if it was assigned when setting a packet to the event,
+        * in which case the packet's stream is not a writer stream,
+        * and thus the user is trying to append an event which belongs
+        * to another stream.
+        */
+       if (event->base.parent) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_object_set_parent(event, stream);
+       ret = auto_populate_event_header(stream, event);
+       if (ret) {
+               goto error;
+       }
+
+       /* Make sure the various scopes of the event are set */
+       ret = bt_ctf_event_validate(event);
+       if (ret) {
+               goto error;
+       }
+
+       /* Save the new event and freeze it */
+       bt_ctf_event_freeze(event);
+       g_ptr_array_add(stream->events, event);
+
+       /*
+        * Event had to hold a reference to its event class as long as it wasn't
+        * part of the same trace hierarchy. From now on, the event and its
+        * class share the same lifetime guarantees and the reference is no
+        * longer needed.
+        */
+       bt_put(event->event_class);
+
+end:
+       return ret;
+
+error:
+       /*
+        * Orphan the event; we were not successful in associating it to
+        * a stream.
+        */
+       bt_object_set_parent(event, NULL);
+
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_stream_get_packet_context(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_ctf_field *packet_context = NULL;
+
+       if (!stream || stream->pos.fd < 0) {
+               goto end;
+       }
+
+       packet_context = stream->packet_context;
+       if (packet_context) {
+               bt_get(packet_context);
+       }
+end:
+       return packet_context;
+}
+
+int bt_ctf_stream_set_packet_context(struct bt_ctf_stream *stream,
+               struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type;
+
+       if (!stream || stream->pos.fd < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       field_type = bt_ctf_field_get_type(field);
+       if (bt_ctf_field_type_compare(field_type,
+                       stream->stream_class->packet_context_type)) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(field_type);
+       bt_put(stream->packet_context);
+       stream->packet_context = bt_get(field);
+end:
+       return ret;
+}
+
+struct bt_ctf_field *bt_ctf_stream_get_packet_header(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_ctf_field *packet_header = NULL;
+
+       if (!stream || stream->pos.fd < 0) {
+               goto end;
+       }
+
+       packet_header = stream->packet_header;
+       if (packet_header) {
+               bt_get(packet_header);
+       }
+end:
+       return packet_header;
+}
+
+int bt_ctf_stream_set_packet_header(struct bt_ctf_stream *stream,
+               struct bt_ctf_field *field)
+{
+       int ret = 0;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!stream || stream->pos.fd < 0) {
+               ret = -1;
+               goto end;
+       }
+
+       trace = (struct bt_ctf_trace *) bt_object_get_parent(stream);
+       field_type = bt_ctf_field_get_type(field);
+       if (bt_ctf_field_type_compare(field_type, trace->packet_header_type)) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(stream->packet_header);
+       stream->packet_header = bt_get(field);
+end:
+       BT_PUT(trace);
+       bt_put(field_type);
+       return ret;
+}
+
+static
+int get_event_header_timestamp(struct bt_ctf_field *event_header, uint64_t *timestamp)
+{
+       int ret = 0;
+       struct bt_ctf_field *timestamp_field = NULL;
+       struct bt_ctf_field_type *timestamp_field_type = NULL;
+
+       timestamp_field = bt_ctf_field_structure_get_field(event_header,
+               "timestamp");
+       if (!timestamp_field) {
+               ret = -1;
+               goto end;
+       }
+
+       timestamp_field_type = bt_ctf_field_get_type(timestamp_field);
+       assert(timestamp_field_type);
+       if (bt_ctf_field_type_get_type_id(timestamp_field_type) !=
+               BT_CTF_TYPE_ID_INTEGER) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_integer_get_signed(timestamp_field_type)) {
+               int64_t val;
+
+               ret = bt_ctf_field_signed_integer_get_value(timestamp_field,
+                       &val);
+               if (ret) {
+                       goto end;
+               }
+               *timestamp = (uint64_t) val;
+       } else {
+               ret = bt_ctf_field_unsigned_integer_get_value(timestamp_field,
+                       timestamp);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       bt_put(timestamp_field);
+       bt_put(timestamp_field_type);
+       return ret;
+}
+
+static
+void reset_structure_field(struct bt_ctf_field *structure, const char *name)
+{
+       struct bt_ctf_field *member;
+
+       member = bt_ctf_field_structure_get_field(structure, name);
+       assert(member);
+       (void) bt_ctf_field_reset(member);
+       bt_put(member);
+}
+
+int bt_ctf_stream_flush(struct bt_ctf_stream *stream)
+{
+       int ret = 0;
+       size_t i;
+       uint64_t timestamp_begin, timestamp_end;
+       struct bt_ctf_field *integer = NULL;
+       struct bt_ctf_stream_pos packet_context_pos;
+       struct bt_ctf_trace *trace;
+       enum bt_ctf_byte_order native_byte_order;
+       bool empty_packet;
+       uint64_t packet_size_bits;
+       struct {
+               bool timestamp_begin;
+               bool timestamp_end;
+               bool content_size;
+               bool packet_size;
+       } auto_set_fields = { 0 };
+
+       if (!stream || stream->pos.fd < 0) {
+               /*
+                * Stream does not have an associated fd. It is,
+                * therefore, not a stream being used to write events.
+                */
+               ret = -1;
+               goto end;
+       }
+
+       if (!stream->packet_context && stream->flushed_packet_count > 0) {
+               /*
+                * A stream without a packet context, and thus without
+                * content and packet size members, can't have more than
+                * one packet.
+                */
+               ret = -1;
+               goto end;
+       }
+
+       trace = bt_ctf_stream_class_borrow_trace(stream->stream_class);
+       assert(trace);
+       native_byte_order = bt_ctf_trace_get_byte_order(trace);
+       empty_packet = (stream->events->len == 0);
+
+       /* mmap the next packet */
+       bt_ctf_stream_pos_packet_seek(&stream->pos, 0, SEEK_CUR);
+       ret = bt_ctf_field_serialize(stream->packet_header, &stream->pos,
+               native_byte_order);
+       if (ret) {
+               goto end;
+       }
+
+       if (stream->packet_context) {
+               /* Set the default context attributes if present and unset. */
+               if (!empty_packet && !get_event_header_timestamp(
+                       ((struct bt_ctf_event *) g_ptr_array_index(
+                               stream->events, 0))->event_header, &timestamp_begin)) {
+                       ret = try_set_structure_field_integer(
+                               stream->packet_context,
+                               "timestamp_begin", timestamp_begin);
+                       if (ret < 0) {
+                               goto end;
+                       }
+                       auto_set_fields.timestamp_begin = ret == 1;
+               }
+
+               if (!empty_packet && !get_event_header_timestamp(
+                       ((struct bt_ctf_event *) g_ptr_array_index(
+                               stream->events, stream->events->len - 1))->event_header,
+                               &timestamp_end)) {
+
+                       ret = try_set_structure_field_integer(
+                               stream->packet_context,
+                               "timestamp_end", timestamp_end);
+                       if (ret < 0) {
+                               goto end;
+                       }
+                       auto_set_fields.timestamp_end = ret == 1;
+               }
+               ret = try_set_structure_field_integer(stream->packet_context,
+                       "content_size", UINT64_MAX);
+               if (ret < 0) {
+                       goto end;
+               }
+               auto_set_fields.content_size = ret == 1;
+
+               ret = try_set_structure_field_integer(stream->packet_context,
+                       "packet_size", UINT64_MAX);
+               if (ret < 0) {
+                       goto end;
+               }
+               auto_set_fields.packet_size = ret == 1;
+
+               /* Write packet context */
+               memcpy(&packet_context_pos, &stream->pos,
+                       sizeof(packet_context_pos));
+               ret = bt_ctf_field_serialize(stream->packet_context,
+                       &stream->pos, native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       for (i = 0; i < stream->events->len; i++) {
+               struct bt_ctf_event *event = g_ptr_array_index(
+                       stream->events, i);
+
+               /* Write event header */
+               ret = bt_ctf_field_serialize(event->event_header,
+                       &stream->pos, native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+
+               /* Write stream event context */
+               if (event->stream_event_context) {
+                       ret = bt_ctf_field_serialize(
+                               event->stream_event_context, &stream->pos,
+                               native_byte_order);
+                       if (ret) {
+                               goto end;
+                       }
+               }
+
+               /* Write event content */
+               ret = bt_ctf_event_serialize(event, &stream->pos,
+                       native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       /* Rounded-up in case content_size is not byte-aligned. */
+       packet_size_bits = (stream->pos.offset + (CHAR_BIT - 1)) &
+               ~(CHAR_BIT - 1);
+       stream->pos.packet_size = packet_size_bits;
+
+       if (stream->packet_context) {
+               /*
+                * Update the packet total size and content size and overwrite
+                * the packet context.
+                * Copy base_mma as the packet may have been remapped (e.g. when
+                * a packet is resized).
+                */
+               packet_context_pos.base_mma = stream->pos.base_mma;
+               if (auto_set_fields.content_size) {
+                       ret = set_structure_field_integer(
+                                       stream->packet_context,
+                                       "content_size", stream->pos.offset);
+                       if (ret < 0) {
+                               goto end;
+                       }
+               }
+
+               if (auto_set_fields.packet_size) {
+                       ret = set_structure_field_integer(stream->packet_context,
+                                       "packet_size", packet_size_bits);
+                       if (ret < 0) {
+                               goto end;
+                       }
+               }
+
+               ret = bt_ctf_field_serialize(stream->packet_context,
+                       &packet_context_pos, native_byte_order);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       g_ptr_array_set_size(stream->events, 0);
+       stream->flushed_packet_count++;
+       stream->size += packet_size_bits / CHAR_BIT;
+end:
+       /* Reset automatically-set fields. */
+       if (auto_set_fields.timestamp_begin) {
+               reset_structure_field(stream->packet_context,
+                               "timestamp_begin");
+       }
+       if (auto_set_fields.timestamp_end) {
+               reset_structure_field(stream->packet_context,
+                               "timestamp_end");
+       }
+       if (auto_set_fields.packet_size) {
+               reset_structure_field(stream->packet_context,
+                               "packet_size");
+       }
+       if (auto_set_fields.content_size) {
+               reset_structure_field(stream->packet_context,
+                               "content_size");
+       }
+       bt_put(integer);
+
+       if (ret < 0) {
+               /*
+                * We failed to write the packet. Its size is therefore set to 0
+                * to ensure the next mapping is done in the same place rather
+                * than advancing by "stream->pos.packet_size", which would
+                * leave a corrupted packet in the trace.
+                */
+               stream->pos.packet_size = 0;
+       }
+       return ret;
+}
+
+void bt_ctf_stream_get(struct bt_ctf_stream *stream)
+{
+       bt_get(stream);
+}
+
+void bt_ctf_stream_put(struct bt_ctf_stream *stream)
+{
+       bt_put(stream);
+}
+
+static
+void bt_ctf_stream_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_stream *stream;
+
+       stream = container_of(obj, struct bt_ctf_stream, base);
+       (void) bt_ctf_stream_pos_fini(&stream->pos);
+       if (stream->pos.fd >= 0) {
+               int ret;
+
+               /*
+                * Truncate the file's size to the minimum required to fit the
+                * last packet as we might have grown it too much on the last
+                * mmap.
+                */
+               do {
+                       ret = ftruncate(stream->pos.fd, stream->size);
+               } while (ret == -1 && errno == EINTR);
+               if (ret) {
+                       perror("ftruncate");
+               }
+
+               if (close(stream->pos.fd)) {
+                       perror("close");
+               }
+       }
+
+       if (stream->events) {
+               g_ptr_array_free(stream->events, TRUE);
+       }
+
+       if (stream->name) {
+               g_string_free(stream->name, TRUE);
+       }
+
+       bt_put(stream->packet_header);
+       bt_put(stream->packet_context);
+       g_free(stream);
+}
+
+static
+int _set_structure_field_integer(struct bt_ctf_field *structure, char *name,
+               uint64_t value, bool force)
+{
+       int ret = 0;
+       struct bt_ctf_field_type *field_type = NULL;
+       struct bt_ctf_field *integer =
+               bt_ctf_field_structure_get_field(structure, name);
+
+       if (!structure || !name) {
+               ret = -1;
+               goto end;
+       }
+
+       if (!integer) {
+               /* Field not found, not an error. */
+               goto end;
+       }
+
+       /* Make sure the payload has not already been set. */
+       if (!force && bt_ctf_field_is_set(integer)) {
+               /* Payload already set, not an error */
+               goto end;
+       }
+
+       field_type = bt_ctf_field_get_type(integer);
+       assert(field_type);
+       if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_TYPE_ID_INTEGER) {
+               /*
+                * The user most likely meant for us to populate this field
+                * automatically. However, we can only do this if the field
+                * is an integer. Return an error.
+                */
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_ctf_field_type_integer_get_signed(field_type)) {
+               ret = bt_ctf_field_signed_integer_set_value(integer,
+                       (int64_t) value);
+       } else {
+               ret = bt_ctf_field_unsigned_integer_set_value(integer, value);
+       }
+       ret = !ret ? 1 : ret;
+end:
+       bt_put(integer);
+       bt_put(field_type);
+       return ret;
+}
+
+static
+int set_structure_field_integer(struct bt_ctf_field *structure, char *name,
+               uint64_t value)
+{
+       return _set_structure_field_integer(structure, name, value, true);
+}
+
+/*
+ * Returns the following codes:
+ * 1 if the field was found and set,
+ * 0 if nothing was done (field not found, or was already set),
+ * <0 if an error was encoutered
+ */
+static
+int try_set_structure_field_integer(struct bt_ctf_field *structure, char *name,
+               uint64_t value)
+{
+       return _set_structure_field_integer(structure, name, value, false);
+}
+
+const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream)
+{
+       const char *name = NULL;
+
+       if (!stream) {
+               goto end;
+       }
+
+       name = stream->name ? stream->name->str : NULL;
+
+end:
+       return name;
+}
+
+int bt_ctf_stream_is_writer(struct bt_ctf_stream *stream)
+{
+       int ret = -1;
+
+       if (!stream) {
+               goto end;
+       }
+
+       ret = (stream->pos.fd >= 0);
+
+end:
+       return ret;
+}
diff --git a/lib/ctf-ir/trace.c b/lib/ctf-ir/trace.c
new file mode 100644 (file)
index 0000000..c16686a
--- /dev/null
@@ -0,0 +1,1253 @@
+/*
+ * 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.
+ */
+
+#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-types-internal.h>
+#include <babeltrace/ctf-ir/attributes-internal.h>
+#include <babeltrace/ctf-ir/validation-internal.h>
+#include <babeltrace/ctf-ir/visitor-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/graph/notification-schema.h>
+#include <babeltrace/compiler.h>
+#include <babeltrace/values.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/endian.h>
+#include <inttypes.h>
+
+#define DEFAULT_IDENTIFIER_SIZE 128
+#define DEFAULT_METADATA_STRING_SIZE 4096
+
+struct listener_wrapper {
+       bt_ctf_listener_cb listener;
+       void *data;
+};
+
+static
+void bt_ctf_trace_destroy(struct bt_object *obj);
+static
+int init_trace_packet_header(struct bt_ctf_trace *trace);
+static
+void bt_ctf_trace_freeze(struct bt_ctf_trace *trace);
+
+static
+const unsigned int field_type_aliases_alignments[] = {
+       [FIELD_TYPE_ALIAS_UINT5_T] = 1,
+       [FIELD_TYPE_ALIAS_UINT8_T ... FIELD_TYPE_ALIAS_UINT16_T] = 8,
+       [FIELD_TYPE_ALIAS_UINT27_T] = 1,
+       [FIELD_TYPE_ALIAS_UINT32_T ... FIELD_TYPE_ALIAS_UINT64_T] = 8,
+};
+
+static
+const unsigned int field_type_aliases_sizes[] = {
+       [FIELD_TYPE_ALIAS_UINT5_T] = 5,
+       [FIELD_TYPE_ALIAS_UINT8_T] = 8,
+       [FIELD_TYPE_ALIAS_UINT16_T] = 16,
+       [FIELD_TYPE_ALIAS_UINT27_T] = 27,
+       [FIELD_TYPE_ALIAS_UINT32_T] = 32,
+       [FIELD_TYPE_ALIAS_UINT64_T] = 64,
+};
+
+struct bt_ctf_trace *bt_ctf_trace_create(void)
+{
+       struct bt_ctf_trace *trace = NULL;
+
+       trace = g_new0(struct bt_ctf_trace, 1);
+       if (!trace) {
+               goto error;
+       }
+
+       bt_ctf_trace_set_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE);
+       bt_object_init(trace, bt_ctf_trace_destroy);
+       trace->clocks = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_put);
+       trace->streams = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_release);
+       trace->stream_classes = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_object_release);
+       if (!trace->clocks || !trace->stream_classes || !trace->streams) {
+               goto error;
+       }
+
+       /* Generate a trace UUID */
+       uuid_generate(trace->uuid);
+       if (init_trace_packet_header(trace)) {
+               goto error;
+       }
+
+       /* Create the environment array object */
+       trace->environment = bt_ctf_attributes_create();
+       if (!trace->environment) {
+               goto error;
+       }
+
+       trace->listeners = g_ptr_array_new_with_free_func(
+                       (GDestroyNotify) g_free);
+       if (!trace->listeners) {
+               goto error;
+       }
+
+       return trace;
+
+error:
+       BT_PUT(trace);
+       return trace;
+}
+
+const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace)
+{
+       const char *name = NULL;
+
+       if (!trace || !trace->name) {
+               goto end;
+       }
+
+       name = trace->name->str;
+end:
+       return name;
+}
+
+int bt_ctf_trace_set_name(struct bt_ctf_trace *trace, const char *name)
+{
+       int ret = 0;
+
+       if (!trace || !name || trace->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       trace->name = trace->name ? g_string_assign(trace->name, name) :
+                       g_string_new(name);
+       if (!trace->name) {
+               ret = -1;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+void bt_ctf_trace_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_trace *trace;
+
+       trace = container_of(obj, struct bt_ctf_trace, base);
+       if (trace->environment) {
+               bt_ctf_attributes_destroy(trace->environment);
+       }
+
+       if (trace->name) {
+               g_string_free(trace->name, TRUE);
+       }
+
+       if (trace->clocks) {
+               g_ptr_array_free(trace->clocks, TRUE);
+       }
+
+       if (trace->streams) {
+               g_ptr_array_free(trace->streams, TRUE);
+       }
+
+       if (trace->stream_classes) {
+               g_ptr_array_free(trace->stream_classes, TRUE);
+       }
+
+       if (trace->listeners) {
+               g_ptr_array_free(trace->listeners, TRUE);
+       }
+
+       bt_put(trace->packet_header_type);
+       g_free(trace);
+}
+
+int bt_ctf_trace_set_environment_field(struct bt_ctf_trace *trace,
+               const char *name, struct bt_value *value)
+{
+       int ret = 0;
+
+       if (!trace || !name || !value ||
+               bt_ctf_validate_identifier(name) ||
+               !(bt_value_is_integer(value) || bt_value_is_string(value))) {
+               ret = -1;
+               goto end;
+       }
+
+       if (strchr(name, ' ')) {
+               ret = -1;
+               goto end;
+       }
+
+       if (trace->frozen) {
+               /*
+                * New environment fields may be added to a frozen trace,
+                * but existing fields may not be changed.
+                *
+                * The object passed is frozen like all other attributes.
+                */
+               struct bt_value *attribute =
+                       bt_ctf_attributes_get_field_value_by_name(
+                               trace->environment, name);
+
+               if (attribute) {
+                       BT_PUT(attribute);
+                       ret = -1;
+                       goto end;
+               }
+
+               bt_value_freeze(value);
+       }
+
+       ret = bt_ctf_attributes_set_field_value(trace->environment, name,
+               value);
+
+end:
+       return ret;
+}
+
+int bt_ctf_trace_set_environment_field_string(struct bt_ctf_trace *trace,
+               const char *name, const char *value)
+{
+       int ret = 0;
+       struct bt_value *env_value_string_obj = NULL;
+
+       if (!trace || !name || !value) {
+               ret = -1;
+               goto end;
+       }
+
+       if (trace->frozen) {
+               /*
+                * New environment fields may be added to a frozen trace,
+                * but existing fields may not be changed.
+                */
+               struct bt_value *attribute =
+                       bt_ctf_attributes_get_field_value_by_name(
+                               trace->environment, name);
+
+               if (attribute) {
+                       BT_PUT(attribute);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       env_value_string_obj = bt_value_string_create_init(value);
+
+       if (!env_value_string_obj) {
+               ret = -1;
+               goto end;
+       }
+
+       if (trace->frozen) {
+               bt_value_freeze(env_value_string_obj);
+       }
+       ret = bt_ctf_trace_set_environment_field(trace, name,
+               env_value_string_obj);
+
+end:
+       BT_PUT(env_value_string_obj);
+       return ret;
+}
+
+int bt_ctf_trace_set_environment_field_integer(struct bt_ctf_trace *trace,
+               const char *name, int64_t value)
+{
+       int ret = 0;
+       struct bt_value *env_value_integer_obj = NULL;
+
+       if (!trace || !name) {
+               ret = -1;
+               goto end;
+       }
+
+       if (trace->frozen) {
+               /*
+                * New environment fields may be added to a frozen trace,
+                * but existing fields may not be changed.
+                */
+               struct bt_value *attribute =
+                       bt_ctf_attributes_get_field_value_by_name(
+                               trace->environment, name);
+
+               if (attribute) {
+                       BT_PUT(attribute);
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       env_value_integer_obj = bt_value_integer_create_init(value);
+       if (!env_value_integer_obj) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_trace_set_environment_field(trace, name,
+               env_value_integer_obj);
+       if (trace->frozen) {
+               bt_value_freeze(env_value_integer_obj);
+       }
+end:
+       BT_PUT(env_value_integer_obj);
+       return ret;
+}
+
+int bt_ctf_trace_get_environment_field_count(struct bt_ctf_trace *trace)
+{
+       int ret = 0;
+
+       if (!trace) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_count(trace->environment);
+
+end:
+       return ret;
+}
+
+const char *
+bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace,
+               int index)
+{
+       const char *ret = NULL;
+
+       if (!trace) {
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_name(trace->environment, index);
+
+end:
+       return ret;
+}
+
+struct bt_value *bt_ctf_trace_get_environment_field_value(
+               struct bt_ctf_trace *trace, int index)
+{
+       struct bt_value *ret = NULL;
+
+       if (!trace) {
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_value(trace->environment, index);
+
+end:
+       return ret;
+}
+
+struct bt_value *bt_ctf_trace_get_environment_field_value_by_name(
+               struct bt_ctf_trace *trace, const char *name)
+{
+       struct bt_value *ret = NULL;
+
+       if (!trace || !name) {
+               goto end;
+       }
+
+       ret = bt_ctf_attributes_get_field_value_by_name(trace->environment,
+               name);
+
+end:
+       return ret;
+}
+
+int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
+               struct bt_ctf_clock_class *clock_class)
+{
+       int ret = 0;
+       struct search_query query = { .value = clock_class, .found = 0 };
+
+       if (!trace || !bt_ctf_clock_class_is_valid(clock_class)) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Check for duplicate clock classes */
+       g_ptr_array_foreach(trace->clocks, value_exists, &query);
+       if (query.found) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_get(clock_class);
+       g_ptr_array_add(trace->clocks, clock_class);
+
+       if (trace->frozen) {
+               bt_ctf_clock_class_freeze(clock_class);
+       }
+end:
+       return ret;
+}
+
+int bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace)
+{
+       int ret = -1;
+
+       if (!trace) {
+               goto end;
+       }
+
+       ret = trace->clocks->len;
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class(
+               struct bt_ctf_trace *trace, int index)
+{
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!trace || index < 0 || index >= trace->clocks->len) {
+               goto end;
+       }
+
+       clock_class = g_ptr_array_index(trace->clocks, index);
+       bt_get(clock_class);
+end:
+       return clock_class;
+}
+
+int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
+               struct bt_ctf_stream_class *stream_class)
+{
+       int ret, i;
+       int64_t stream_id;
+       struct bt_ctf_validation_output trace_sc_validation_output = { 0 };
+       struct bt_ctf_validation_output *ec_validation_outputs = NULL;
+       const enum bt_ctf_validation_flag trace_sc_validation_flags =
+               BT_CTF_VALIDATION_FLAG_TRACE |
+               BT_CTF_VALIDATION_FLAG_STREAM;
+       const enum bt_ctf_validation_flag ec_validation_flags =
+               BT_CTF_VALIDATION_FLAG_EVENT;
+       struct bt_ctf_field_type *packet_header_type = NULL;
+       struct bt_ctf_field_type *packet_context_type = NULL;
+       struct bt_ctf_field_type *event_header_type = NULL;
+       struct bt_ctf_field_type *stream_event_ctx_type = NULL;
+       int event_class_count;
+       struct bt_ctf_trace *current_parent_trace = NULL;
+
+       if (!trace || !stream_class) {
+               ret = -1;
+               goto end;
+       }
+
+       current_parent_trace = bt_ctf_stream_class_get_trace(stream_class);
+       if (current_parent_trace) {
+               /* Stream class is already associated to a trace, abort. */
+               ret = -1;
+               goto end;
+       }
+
+       event_class_count =
+               bt_ctf_stream_class_get_event_class_count(stream_class);
+       assert(event_class_count >= 0);
+
+       /* Check for duplicate stream classes */
+       for (i = 0; i < trace->stream_classes->len; i++) {
+               if (trace->stream_classes->pdata[i] == stream_class) {
+                       /* Stream class already registered to the trace */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       if (stream_class->clock) {
+               struct bt_ctf_clock_class *stream_clock_class =
+                       stream_class->clock->clock_class;
+
+               if (trace->is_created_by_writer) {
+                       /*
+                        * Make sure this clock was also added to the
+                        * trace (potentially through its CTF writer
+                        * owner).
+                        */
+                       size_t i;
+
+                       for (i = 0; i < trace->clocks->len; i++) {
+                               if (trace->clocks->pdata[i] ==
+                                               stream_clock_class) {
+                                       /* Found! */
+                                       break;
+                               }
+                       }
+
+                       if (i == trace->clocks->len) {
+                               /* Not found */
+                               ret = -1;
+                               goto end;
+                       }
+               } else {
+                       /*
+                        * This trace was NOT created by a CTF writer,
+                        * thus do not allow the stream class to add to
+                        * have a clock at all. Those are two
+                        * independent APIs (non-writer and writer
+                        * APIs), and isolating them simplifies things.
+                        */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       /*
+        * We're about to freeze both the trace and the stream class.
+        * Also, each event class contained in this stream class are
+        * already frozen.
+        *
+        * This trace, this stream class, and all its event classes
+        * should be valid at this point.
+        *
+        * Validate trace and stream class first, then each event
+        * class of this stream class can be validated individually.
+        */
+       packet_header_type =
+               bt_ctf_trace_get_packet_header_type(trace);
+       packet_context_type =
+               bt_ctf_stream_class_get_packet_context_type(stream_class);
+       event_header_type =
+               bt_ctf_stream_class_get_event_header_type(stream_class);
+       stream_event_ctx_type =
+               bt_ctf_stream_class_get_event_context_type(stream_class);
+       ret = bt_ctf_validate_class_types(trace->environment,
+               packet_header_type, packet_context_type, event_header_type,
+               stream_event_ctx_type, NULL, NULL, trace->valid,
+               stream_class->valid, 1, &trace_sc_validation_output,
+               trace_sc_validation_flags);
+       BT_PUT(packet_header_type);
+       BT_PUT(packet_context_type);
+       BT_PUT(event_header_type);
+       BT_PUT(stream_event_ctx_type);
+
+       if (ret) {
+               /*
+                * This means something went wrong during the validation
+                * process, not that the objects are invalid.
+                */
+               goto end;
+       }
+
+       if ((trace_sc_validation_output.valid_flags &
+                       trace_sc_validation_flags) !=
+                       trace_sc_validation_flags) {
+               /* Invalid trace/stream class */
+               ret = -1;
+               goto end;
+       }
+
+       if (event_class_count > 0) {
+               ec_validation_outputs = g_new0(struct bt_ctf_validation_output,
+                       event_class_count);
+               if (!ec_validation_outputs) {
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       /* Validate each event class individually */
+       for (i = 0; i < event_class_count; i++) {
+               struct bt_ctf_event_class *event_class =
+                       bt_ctf_stream_class_get_event_class(stream_class, i);
+               struct bt_ctf_field_type *event_context_type = NULL;
+               struct bt_ctf_field_type *event_payload_type = NULL;
+
+               event_context_type =
+                       bt_ctf_event_class_get_context_type(event_class);
+               event_payload_type =
+                       bt_ctf_event_class_get_payload_type(event_class);
+
+               /*
+                * It is important to use the field types returned by
+                * the previous trace and stream class validation here
+                * because copies could have been made.
+                */
+               ret = bt_ctf_validate_class_types(trace->environment,
+                       trace_sc_validation_output.packet_header_type,
+                       trace_sc_validation_output.packet_context_type,
+                       trace_sc_validation_output.event_header_type,
+                       trace_sc_validation_output.stream_event_ctx_type,
+                       event_context_type, event_payload_type,
+                       1, 1, event_class->valid, &ec_validation_outputs[i],
+                       ec_validation_flags);
+               BT_PUT(event_context_type);
+               BT_PUT(event_payload_type);
+               BT_PUT(event_class);
+
+               if (ret) {
+                       goto end;
+               }
+
+               if ((ec_validation_outputs[i].valid_flags &
+                               ec_validation_flags) != ec_validation_flags) {
+                       /* Invalid event class */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       stream_id = bt_ctf_stream_class_get_id(stream_class);
+       if (stream_id < 0) {
+               stream_id = trace->next_stream_id++;
+
+               /* Try to assign a new stream id */
+               for (i = 0; i < trace->stream_classes->len; i++) {
+                       if (stream_id == bt_ctf_stream_class_get_id(
+                               trace->stream_classes->pdata[i])) {
+                               /* Duplicate stream id found */
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               if (bt_ctf_stream_class_set_id_no_check(stream_class,
+                       stream_id)) {
+                       /* TODO Should retry with a different stream id */
+                       ret = -1;
+                       goto end;
+               }
+       }
+
+       bt_object_set_parent(stream_class, trace);
+       g_ptr_array_add(trace->stream_classes, stream_class);
+
+       /*
+        * At this point we know that the function will be successful.
+        * Therefore we can replace the trace and stream class field
+        * types with what's in their validation output structure and
+        * mark them as valid. We can also replace the field types of
+        * all the event classes of the stream class and mark them as
+        * valid.
+        */
+       bt_ctf_validation_replace_types(trace, stream_class, NULL,
+               &trace_sc_validation_output, trace_sc_validation_flags);
+       trace->valid = 1;
+       stream_class->valid = 1;
+
+       /*
+        * Put what was not moved in bt_ctf_validation_replace_types().
+        */
+       bt_ctf_validation_output_put_types(&trace_sc_validation_output);
+
+       for (i = 0; i < event_class_count; i++) {
+               struct bt_ctf_event_class *event_class =
+                       bt_ctf_stream_class_get_event_class(stream_class, i);
+
+               bt_ctf_validation_replace_types(NULL, NULL, event_class,
+                       &ec_validation_outputs[i], ec_validation_flags);
+               event_class->valid = 1;
+               BT_PUT(event_class);
+
+               /*
+                * Put what was not moved in
+                * bt_ctf_validation_replace_types().
+                */
+               bt_ctf_validation_output_put_types(&ec_validation_outputs[i]);
+       }
+
+       /*
+        * Freeze the trace and the stream class.
+        */
+       bt_ctf_stream_class_freeze(stream_class);
+       bt_ctf_trace_freeze(trace);
+
+       /* Notifiy listeners of the trace's schema modification. */
+       bt_ctf_stream_class_visit(stream_class,
+                       bt_ctf_trace_object_modification, trace);
+end:
+       if (ret) {
+               bt_object_set_parent(stream_class, NULL);
+
+               if (ec_validation_outputs) {
+                       for (i = 0; i < event_class_count; i++) {
+                               bt_ctf_validation_output_put_types(
+                                       &ec_validation_outputs[i]);
+                       }
+               }
+       }
+
+       g_free(ec_validation_outputs);
+       bt_ctf_validation_output_put_types(&trace_sc_validation_output);
+       bt_put(current_parent_trace);
+       assert(!packet_header_type);
+       assert(!packet_context_type);
+       assert(!event_header_type);
+       assert(!stream_event_ctx_type);
+
+       return ret;
+}
+
+int bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace)
+{
+       int ret;
+
+       if (!trace) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = trace->stream_classes->len;
+end:
+       return ret;
+}
+
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class(
+               struct bt_ctf_trace *trace, int index)
+{
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (!trace || index < 0 || index >= trace->stream_classes->len) {
+               goto end;
+       }
+
+       stream_class = g_ptr_array_index(trace->stream_classes, index);
+       bt_get(stream_class);
+end:
+       return stream_class;
+}
+
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
+               struct bt_ctf_trace *trace, uint32_t id)
+{
+       int i;
+       struct bt_ctf_stream_class *stream_class = NULL;
+
+       if (!trace) {
+               goto end;
+       }
+
+       for (i = 0; i < trace->stream_classes->len; i++) {
+               struct bt_ctf_stream_class *stream_class_candidate;
+
+               stream_class_candidate =
+                       g_ptr_array_index(trace->stream_classes, i);
+
+               if (bt_ctf_stream_class_get_id(stream_class_candidate) ==
+                               (int64_t) id) {
+                       stream_class = stream_class_candidate;
+                       bt_get(stream_class);
+                       goto end;
+               }
+       }
+
+end:
+       return stream_class;
+}
+
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
+               struct bt_ctf_trace *trace, const char *name)
+{
+       size_t i;
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!trace || !name) {
+               goto end;
+       }
+
+       for (i = 0; i < trace->clocks->len; i++) {
+               struct bt_ctf_clock_class *cur_clk =
+                       g_ptr_array_index(trace->clocks, i);
+               const char *cur_clk_name = bt_ctf_clock_class_get_name(cur_clk);
+
+               if (!cur_clk_name) {
+                       goto end;
+               }
+
+               if (!strcmp(cur_clk_name, name)) {
+                       clock_class = cur_clk;
+                       bt_get(clock_class);
+                       goto end;
+               }
+       }
+
+end:
+       return clock_class;
+}
+
+BT_HIDDEN
+const char *get_byte_order_string(enum bt_ctf_byte_order byte_order)
+{
+       const char *string;
+
+       switch (byte_order) {
+       case BT_CTF_BYTE_ORDER_LITTLE_ENDIAN:
+               string = "le";
+               break;
+       case BT_CTF_BYTE_ORDER_BIG_ENDIAN:
+               string = "be";
+               break;
+       case BT_CTF_BYTE_ORDER_NATIVE:
+               string = "native";
+               break;
+       default:
+               assert(false);
+       }
+
+       return string;
+}
+
+static
+int append_trace_metadata(struct bt_ctf_trace *trace,
+               struct metadata_context *context)
+{
+       unsigned char *uuid = trace->uuid;
+       int ret;
+
+       g_string_append(context->string, "trace {\n");
+
+       g_string_append(context->string, "\tmajor = 1;\n");
+       g_string_append(context->string, "\tminor = 8;\n");
+       assert(trace->native_byte_order == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
+               trace->native_byte_order == BT_CTF_BYTE_ORDER_BIG_ENDIAN ||
+               trace->native_byte_order == BT_CTF_BYTE_ORDER_NETWORK);
+       g_string_append_printf(context->string,
+               "\tuuid = \"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n",
+               uuid[0], uuid[1], uuid[2], uuid[3],
+               uuid[4], uuid[5], uuid[6], uuid[7],
+               uuid[8], uuid[9], uuid[10], uuid[11],
+               uuid[12], uuid[13], uuid[14], uuid[15]);
+       g_string_append_printf(context->string, "\tbyte_order = %s;\n",
+               get_byte_order_string(trace->native_byte_order));
+
+       g_string_append(context->string, "\tpacket.header := ");
+       context->current_indentation_level++;
+       g_string_assign(context->field_name, "");
+       ret = bt_ctf_field_type_serialize(trace->packet_header_type,
+               context);
+       if (ret) {
+               goto end;
+       }
+       context->current_indentation_level--;
+
+       g_string_append(context->string, ";\n};\n\n");
+end:
+       return ret;
+}
+
+static
+void append_env_metadata(struct bt_ctf_trace *trace,
+               struct metadata_context *context)
+{
+       int i;
+       int env_size;
+
+       env_size = bt_ctf_attributes_get_count(trace->environment);
+
+       if (env_size <= 0) {
+               return;
+       }
+
+       g_string_append(context->string, "env {\n");
+
+       for (i = 0; i < env_size; i++) {
+               struct bt_value *env_field_value_obj = NULL;
+               const char *entry_name;
+
+               entry_name = bt_ctf_attributes_get_field_name(
+                       trace->environment, i);
+               env_field_value_obj = bt_ctf_attributes_get_field_value(
+                       trace->environment, i);
+
+               if (!entry_name || !env_field_value_obj) {
+                       goto loop_next;
+               }
+
+               switch (bt_value_get_type(env_field_value_obj)) {
+               case BT_VALUE_TYPE_INTEGER:
+               {
+                       int ret;
+                       int64_t int_value;
+
+                       ret = bt_value_integer_get(env_field_value_obj,
+                               &int_value);
+
+                       if (ret) {
+                               goto loop_next;
+                       }
+
+                       g_string_append_printf(context->string,
+                               "\t%s = %" PRId64 ";\n", entry_name,
+                               int_value);
+                       break;
+               }
+               case BT_VALUE_TYPE_STRING:
+               {
+                       int ret;
+                       const char *str_value;
+                       char *escaped_str = NULL;
+
+                       ret = bt_value_string_get(env_field_value_obj,
+                               &str_value);
+
+                       if (ret) {
+                               goto loop_next;
+                       }
+
+                       escaped_str = g_strescape(str_value, NULL);
+
+                       if (!escaped_str) {
+                               goto loop_next;
+                       }
+
+                       g_string_append_printf(context->string,
+                               "\t%s = \"%s\";\n", entry_name, escaped_str);
+                       free(escaped_str);
+                       break;
+               }
+
+               default:
+                       goto loop_next;
+               }
+
+loop_next:
+               BT_PUT(env_field_value_obj);
+       }
+
+       g_string_append(context->string, "};\n\n");
+}
+
+char *bt_ctf_trace_get_metadata_string(struct bt_ctf_trace *trace)
+{
+       char *metadata = NULL;
+       struct metadata_context *context = NULL;
+       int err = 0;
+       size_t i;
+
+       if (!trace) {
+               goto end;
+       }
+
+       context = g_new0(struct metadata_context, 1);
+       if (!context) {
+               goto end;
+       }
+
+       context->field_name = g_string_sized_new(DEFAULT_IDENTIFIER_SIZE);
+       context->string = g_string_sized_new(DEFAULT_METADATA_STRING_SIZE);
+       g_string_append(context->string, "/* CTF 1.8 */\n\n");
+       if (append_trace_metadata(trace, context)) {
+               goto error;
+       }
+       append_env_metadata(trace, context);
+       g_ptr_array_foreach(trace->clocks,
+               (GFunc)bt_ctf_clock_class_serialize, context);
+
+       for (i = 0; i < trace->stream_classes->len; i++) {
+               err = bt_ctf_stream_class_serialize(
+                       trace->stream_classes->pdata[i], context);
+               if (err) {
+                       goto error;
+               }
+       }
+
+       metadata = context->string->str;
+error:
+       g_string_free(context->string, err ? TRUE : FALSE);
+       g_string_free(context->field_name, TRUE);
+       g_free(context);
+end:
+       return metadata;
+}
+
+enum bt_ctf_byte_order bt_ctf_trace_get_byte_order(struct bt_ctf_trace *trace)
+{
+       enum bt_ctf_byte_order ret = BT_CTF_BYTE_ORDER_UNKNOWN;
+
+       if (!trace) {
+               goto end;
+       }
+
+       ret = trace->native_byte_order;
+
+end:
+       return ret;
+}
+
+int bt_ctf_trace_set_byte_order(struct bt_ctf_trace *trace,
+               enum bt_ctf_byte_order byte_order)
+{
+       int ret = 0;
+
+       if (!trace || trace->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (byte_order != BT_CTF_BYTE_ORDER_LITTLE_ENDIAN &&
+                       byte_order != BT_CTF_BYTE_ORDER_BIG_ENDIAN &&
+                       byte_order != BT_CTF_BYTE_ORDER_NETWORK) {
+               ret = -1;
+               goto end;
+       }
+
+       trace->native_byte_order = byte_order;
+
+end:
+       return ret;
+}
+
+struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
+               struct bt_ctf_trace *trace)
+{
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (!trace) {
+               goto end;
+       }
+
+       bt_get(trace->packet_header_type);
+       field_type = trace->packet_header_type;
+end:
+       return field_type;
+}
+
+int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace,
+               struct bt_ctf_field_type *packet_header_type)
+{
+       int ret = 0;
+
+       if (!trace || trace->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       /* packet_header_type must be a structure. */
+       if (packet_header_type &&
+                       bt_ctf_field_type_get_type_id(packet_header_type) !=
+                               BT_CTF_TYPE_ID_STRUCT) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_put(trace->packet_header_type);
+       trace->packet_header_type = bt_get(packet_header_type);
+end:
+       return ret;
+}
+
+static
+int get_stream_class_count(void *element)
+{
+       return bt_ctf_trace_get_stream_class_count(
+                       (struct bt_ctf_trace *) element);
+}
+
+static
+void *get_stream_class(void *element, int i)
+{
+       return bt_ctf_trace_get_stream_class(
+                       (struct bt_ctf_trace *) element, i);
+}
+
+static
+int visit_stream_class(void *object, bt_ctf_visitor visitor,void *data)
+{
+       return bt_ctf_stream_class_visit(object, visitor, data);
+}
+
+int bt_ctf_trace_visit(struct bt_ctf_trace *trace,
+               bt_ctf_visitor visitor, void *data)
+{
+       int ret;
+       struct bt_ctf_object obj =
+                       { .object = trace, .type = BT_CTF_OBJECT_TYPE_TRACE };
+
+       if (!trace || !visitor) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = visitor_helper(&obj, get_stream_class_count,
+                       get_stream_class, visit_stream_class, visitor, data);
+end:
+       return ret;
+}
+
+static
+int invoke_listener(struct bt_ctf_object *object, void *data)
+{
+       struct listener_wrapper *listener_wrapper = data;
+
+       listener_wrapper->listener(object, listener_wrapper->data);
+       return 0;
+}
+
+int bt_ctf_trace_add_listener(struct bt_ctf_trace *trace,
+               bt_ctf_listener_cb listener, void *listener_data)
+{
+       int ret = 0;
+       struct listener_wrapper *listener_wrapper =
+                       g_new0(struct listener_wrapper, 1);
+
+       if (!trace || !listener || !listener_wrapper) {
+               ret = -1;
+               goto error;
+       }
+
+       listener_wrapper->listener = listener;
+       listener_wrapper->data = listener_data;
+
+       /* Visit the current schema. */
+       ret = bt_ctf_trace_visit(trace, invoke_listener, listener_wrapper);
+       if (ret) {
+               goto error;
+       }
+
+       /*
+        * Add listener to the array of callbacks which will be invoked on
+        * schema changes.
+        */
+       g_ptr_array_add(trace->listeners, listener_wrapper);
+       return ret;
+error:
+       g_free(listener_wrapper);
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_trace_object_modification(struct bt_ctf_object *object,
+               void *trace_ptr)
+{
+       size_t i;
+       struct bt_ctf_trace *trace = trace_ptr;
+
+       assert(trace);
+       assert(object);
+
+       if (trace->listeners->len == 0) {
+               goto end;
+       }
+
+       for (i = 0; i < trace->listeners->len; i++) {
+               struct listener_wrapper *listener =
+                               g_ptr_array_index(trace->listeners, i);
+
+               listener->listener(object, listener->data);
+       }
+end:
+       return 0;
+}
+
+BT_HIDDEN
+struct bt_ctf_field_type *get_field_type(enum field_type_alias alias)
+{
+       int ret;
+       unsigned int alignment, size;
+       struct bt_ctf_field_type *field_type = NULL;
+
+       if (alias >= NR_FIELD_TYPE_ALIAS) {
+               goto end;
+       }
+
+       alignment = field_type_aliases_alignments[alias];
+       size = field_type_aliases_sizes[alias];
+       field_type = bt_ctf_field_type_integer_create(size);
+       ret = bt_ctf_field_type_set_alignment(field_type, alignment);
+       if (ret) {
+               BT_PUT(field_type);
+       }
+end:
+       return field_type;
+}
+
+static
+void bt_ctf_trace_freeze(struct bt_ctf_trace *trace)
+{
+       int i;
+
+       bt_ctf_field_type_freeze(trace->packet_header_type);
+       bt_ctf_attributes_freeze(trace->environment);
+
+       for (i = 0; i < trace->clocks->len; i++) {
+               struct bt_ctf_clock_class *clock_class =
+                       g_ptr_array_index(trace->clocks, i);
+
+               bt_ctf_clock_class_freeze(clock_class);
+       }
+
+       trace->frozen = 1;
+}
+
+static
+int init_trace_packet_header(struct bt_ctf_trace *trace)
+{
+       int ret = 0;
+       struct bt_ctf_field *magic = NULL, *uuid_array = NULL;
+       struct bt_ctf_field_type *_uint32_t =
+               get_field_type(FIELD_TYPE_ALIAS_UINT32_T);
+       struct bt_ctf_field_type *_uint8_t =
+               get_field_type(FIELD_TYPE_ALIAS_UINT8_T);
+       struct bt_ctf_field_type *trace_packet_header_type =
+               bt_ctf_field_type_structure_create();
+       struct bt_ctf_field_type *uuid_array_type =
+               bt_ctf_field_type_array_create(_uint8_t, 16);
+
+       if (!trace_packet_header_type || !uuid_array_type) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
+               _uint32_t, "magic");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
+               uuid_array_type, "uuid");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_field_type_structure_add_field(trace_packet_header_type,
+               _uint32_t, "stream_id");
+       if (ret) {
+               goto end;
+       }
+
+       ret = bt_ctf_trace_set_packet_header_type(trace,
+               trace_packet_header_type);
+       if (ret) {
+               goto end;
+       }
+end:
+       bt_put(uuid_array_type);
+       bt_put(_uint32_t);
+       bt_put(_uint8_t);
+       bt_put(magic);
+       bt_put(uuid_array);
+       bt_put(trace_packet_header_type);
+       return ret;
+}
diff --git a/lib/ctf-ir/utils.c b/lib/ctf-ir/utils.c
new file mode 100644 (file)
index 0000000..318b12d
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+
+static
+const char * const reserved_keywords_str[] = {"align", "callsite",
+       "const", "char", "clock", "double", "enum", "env", "event",
+       "floating_point", "float", "integer", "int", "long", "short", "signed",
+       "stream", "string", "struct", "trace", "typealias", "typedef",
+       "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"};
+
+static GHashTable *reserved_keywords_set;
+static int init_done;
+static int global_data_refcount;
+
+static __attribute__((constructor))
+void trace_init(void)
+{
+       size_t i;
+       const size_t reserved_keywords_count =
+               sizeof(reserved_keywords_str) / sizeof(char *);
+
+       global_data_refcount++;
+       if (init_done) {
+               return;
+       }
+
+       reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal);
+       for (i = 0; i < reserved_keywords_count; i++) {
+               gpointer quark = GINT_TO_POINTER(g_quark_from_string(
+                       reserved_keywords_str[i]));
+
+               g_hash_table_insert(reserved_keywords_set, quark, quark);
+       }
+
+       init_done = 1;
+}
+
+static __attribute__((destructor))
+void trace_finalize(void)
+{
+       if (--global_data_refcount == 0) {
+               g_hash_table_destroy(reserved_keywords_set);
+       }
+}
+
+int bt_ctf_validate_identifier(const char *input_string)
+{
+       int ret = 0;
+       char *string = NULL;
+       char *save_ptr, *token;
+
+       if (!input_string || input_string[0] == '\0') {
+               ret = -1;
+               goto end;
+       }
+
+       string = strdup(input_string);
+       if (!string) {
+               ret = -1;
+               goto end;
+       }
+
+       token = strtok_r(string, " ", &save_ptr);
+       while (token) {
+               if (g_hash_table_lookup_extended(reserved_keywords_set,
+                       GINT_TO_POINTER(g_quark_from_string(token)),
+                       NULL, NULL)) {
+                       ret = -1;
+                       goto end;
+               }
+
+               token = strtok_r(NULL, " ", &save_ptr);
+       }
+end:
+       free(string);
+       return ret;
+}
diff --git a/lib/ctf-ir/validation.c b/lib/ctf-ir/validation.c
new file mode 100644 (file)
index 0000000..dc2a3a9
--- /dev/null
@@ -0,0 +1,600 @@
+/*
+ * validation.c
+ *
+ * Babeltrace - CTF IR: Validation of trace, stream class, and event class
+ *
+ * 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 <babeltrace/ctf-ir/validation-internal.h>
+#include <babeltrace/ctf-ir/resolve-internal.h>
+#include <babeltrace/ctf-ir/trace-internal.h>
+#include <babeltrace/ctf-ir/stream-class-internal.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/event-class-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/ref.h>
+
+#define _printf_error(fmt, args...) \
+       printf_verbose("[validation] " fmt, ## args)
+
+/*
+ * This function resolves and validates the field types of an event
+ * class. Only `event_context_type` and `event_payload_type` are
+ * resolved and validated; the other field types are used as eventual
+ * resolving targets.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_event_class_types(struct bt_value *environment,
+               struct bt_ctf_field_type *packet_header_type,
+               struct bt_ctf_field_type *packet_context_type,
+               struct bt_ctf_field_type *event_header_type,
+               struct bt_ctf_field_type *stream_event_ctx_type,
+               struct bt_ctf_field_type *event_context_type,
+               struct bt_ctf_field_type *event_payload_type)
+{
+       int ret = 0;
+
+       /* Resolve sequence type lengths and variant type tags first */
+       ret = bt_ctf_resolve_types(environment, packet_header_type,
+               packet_context_type, event_header_type, stream_event_ctx_type,
+               event_context_type, event_payload_type,
+               BT_CTF_RESOLVE_FLAG_EVENT_CONTEXT |
+               BT_CTF_RESOLVE_FLAG_EVENT_PAYLOAD);
+       if (ret) {
+               _printf_error("Cannot resolve event class types\n");
+               goto end;
+       }
+
+       /* Validate field types individually */
+       if (event_context_type) {
+               ret = bt_ctf_field_type_validate(event_context_type);
+               if (ret) {
+                       _printf_error("Invalid event context type\n");
+                       goto end;
+               }
+       }
+
+       if (event_payload_type) {
+               ret = bt_ctf_field_type_validate(event_payload_type);
+               if (ret) {
+                       _printf_error("Invalid event payload type\n");
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * This function resolves and validates the field types of a stream
+ * class. Only `packet_context_type`, `event_header_type`, and
+ * `stream_event_ctx_type` are resolved and validated; the other field
+ * type is used as an eventual resolving target.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_stream_class_types(struct bt_value *environment,
+               struct bt_ctf_field_type *packet_header_type,
+               struct bt_ctf_field_type *packet_context_type,
+               struct bt_ctf_field_type *event_header_type,
+               struct bt_ctf_field_type *stream_event_ctx_type)
+{
+       int ret = 0;
+
+       /* Resolve sequence type lengths and variant type tags first */
+       ret = bt_ctf_resolve_types(environment, packet_header_type,
+               packet_context_type, event_header_type, stream_event_ctx_type,
+               NULL, NULL,
+               BT_CTF_RESOLVE_FLAG_PACKET_CONTEXT |
+               BT_CTF_RESOLVE_FLAG_EVENT_HEADER |
+               BT_CTF_RESOLVE_FLAG_STREAM_EVENT_CTX);
+       if (ret) {
+               _printf_error("Cannot resolve stream class types\n");
+               goto end;
+       }
+
+       /* Validate field types individually */
+       if (packet_context_type) {
+               ret = bt_ctf_field_type_validate(packet_context_type);
+               if (ret) {
+                       _printf_error("Invalid stream packet context type\n");
+                       goto end;
+               }
+       }
+
+       if (event_header_type) {
+               ret = bt_ctf_field_type_validate(event_header_type);
+               if (ret) {
+                       _printf_error("Invalid stream event header type\n");
+                       goto end;
+               }
+       }
+
+       if (stream_event_ctx_type) {
+               ret = bt_ctf_field_type_validate(
+                       stream_event_ctx_type);
+               if (ret) {
+                       _printf_error("Invalid stream event context type\n");
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * This function resolves and validates the field types of a trace.
+ *
+ * All parameters are owned by the caller.
+ */
+static
+int validate_trace_types(struct bt_value *environment,
+               struct bt_ctf_field_type *packet_header_type)
+{
+       int ret = 0;
+
+       /* Resolve sequence type lengths and variant type tags first */
+       ret = bt_ctf_resolve_types(environment, packet_header_type,
+               NULL, NULL, NULL, NULL, NULL,
+               BT_CTF_RESOLVE_FLAG_PACKET_HEADER);
+       if (ret) {
+               _printf_error("Cannot resolve trace types\n");
+               goto end;
+       }
+
+       /* Validate field types individually */
+       if (packet_header_type) {
+               ret = bt_ctf_field_type_validate(packet_header_type);
+               if (ret) {
+                       _printf_error("Invalid trace packet header type\n");
+                       goto end;
+               }
+       }
+
+end:
+       return ret;
+}
+
+/*
+ * Checks whether or not `field_type` contains a variant or a sequence
+ * field type, recursively. Returns 1 if it's the case.
+ *
+ * `field_type` is owned by the caller.
+ */
+static
+int field_type_contains_sequence_or_variant_ft(struct bt_ctf_field_type *type)
+{
+       int ret = 0;
+       enum bt_ctf_type_id type_id = bt_ctf_field_type_get_type_id(type);
+
+       switch (type_id) {
+       case BT_CTF_TYPE_ID_SEQUENCE:
+       case BT_CTF_TYPE_ID_VARIANT:
+               ret = 1;
+               goto end;
+       case BT_CTF_TYPE_ID_ARRAY:
+       case BT_CTF_TYPE_ID_STRUCT:
+       {
+               int i;
+               int field_count = bt_ctf_field_type_get_field_count(type);
+
+               if (field_count < 0) {
+                       ret = -1;
+                       goto end;
+               }
+
+               for (i = 0; i < field_count; ++i) {
+                       struct bt_ctf_field_type *child_type =
+                               bt_ctf_field_type_get_field_at_index(type, i);
+
+                       ret = field_type_contains_sequence_or_variant_ft(
+                               child_type);
+                       BT_PUT(child_type);
+                       if (ret != 0) {
+                               goto end;
+                       }
+               }
+               break;
+       }
+       default:
+               break;
+       }
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+int bt_ctf_validate_class_types(struct bt_value *environment,
+               struct bt_ctf_field_type *packet_header_type,
+               struct bt_ctf_field_type *packet_context_type,
+               struct bt_ctf_field_type *event_header_type,
+               struct bt_ctf_field_type *stream_event_ctx_type,
+               struct bt_ctf_field_type *event_context_type,
+               struct bt_ctf_field_type *event_payload_type,
+               int trace_valid, int stream_class_valid, int event_class_valid,
+               struct bt_ctf_validation_output *output,
+               enum bt_ctf_validation_flag validate_flags)
+{
+       int ret = 0;
+       int contains_seq_var;
+       int valid_ret;
+
+       /* Clean output values */
+       memset(output, 0, sizeof(*output));
+
+       /* Set initial valid flags according to valid parameters */
+       if (trace_valid) {
+               output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
+       }
+
+       if (stream_class_valid) {
+               output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
+       }
+
+       if (event_class_valid) {
+               output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
+       }
+
+       /* Own the type parameters */
+       bt_get(packet_header_type);
+       bt_get(packet_context_type);
+       bt_get(event_header_type);
+       bt_get(stream_event_ctx_type);
+       bt_get(event_context_type);
+       bt_get(event_payload_type);
+
+       /* Validate trace */
+       if ((validate_flags & BT_CTF_VALIDATION_FLAG_TRACE) && !trace_valid) {
+               struct bt_ctf_field_type *packet_header_type_copy = NULL;
+
+               /* Create field type copies */
+               if (packet_header_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       packet_header_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               packet_header_type_copy = packet_header_type;
+                               bt_get(packet_header_type_copy);
+                               goto skip_packet_header_type_copy;
+                       }
+
+                       packet_header_type_copy =
+                               bt_ctf_field_type_copy(packet_header_type);
+                       if (!packet_header_type_copy) {
+                               ret = -1;
+                               _printf_error("Cannot copy packet header type\n");
+                               goto error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(packet_header_type_copy);
+               }
+
+skip_packet_header_type_copy:
+               /* Put original reference and move copy */
+               BT_MOVE(packet_header_type, packet_header_type_copy);
+
+               /* Validate trace field types */
+               valid_ret = validate_trace_types(environment,
+                       packet_header_type);
+               if (!valid_ret) {
+                       /* Trace is valid */
+                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_TRACE;
+               }
+       }
+
+       /* Validate stream class */
+       if ((validate_flags & BT_CTF_VALIDATION_FLAG_STREAM) &&
+                       !stream_class_valid) {
+               struct bt_ctf_field_type *packet_context_type_copy = NULL;
+               struct bt_ctf_field_type *event_header_type_copy = NULL;
+               struct bt_ctf_field_type *stream_event_ctx_type_copy = NULL;
+
+               if (packet_context_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       packet_context_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               packet_context_type_copy = packet_context_type;
+                               bt_get(packet_context_type_copy);
+                               goto skip_packet_context_type_copy;
+                       }
+
+                       packet_context_type_copy =
+                               bt_ctf_field_type_copy(packet_context_type);
+                       if (!packet_context_type_copy) {
+                               _printf_error("Cannot copy packet context type\n");
+                               goto sc_validation_error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(packet_context_type_copy);
+               }
+
+skip_packet_context_type_copy:
+               if (event_header_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       event_header_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               event_header_type_copy = event_header_type;
+                               bt_get(event_header_type_copy);
+                               goto skip_event_header_type_copy;
+                       }
+
+                       event_header_type_copy =
+                               bt_ctf_field_type_copy(event_header_type);
+                       if (!event_header_type_copy) {
+                               _printf_error("Cannot copy event header type\n");
+                               goto sc_validation_error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(event_header_type_copy);
+               }
+
+skip_event_header_type_copy:
+               if (stream_event_ctx_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       stream_event_ctx_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               stream_event_ctx_type_copy =
+                                       stream_event_ctx_type;
+                               bt_get(stream_event_ctx_type_copy);
+                               goto skip_stream_event_ctx_type_copy;
+                       }
+
+                       stream_event_ctx_type_copy =
+                               bt_ctf_field_type_copy(stream_event_ctx_type);
+                       if (!stream_event_ctx_type_copy) {
+                               _printf_error("Cannot copy stream event context type\n");
+                               goto sc_validation_error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(stream_event_ctx_type_copy);
+               }
+
+skip_stream_event_ctx_type_copy:
+               /* Put original references and move copies */
+               BT_MOVE(packet_context_type, packet_context_type_copy);
+               BT_MOVE(event_header_type, event_header_type_copy);
+               BT_MOVE(stream_event_ctx_type, stream_event_ctx_type_copy);
+
+               /* Validate stream class field types */
+               valid_ret = validate_stream_class_types(environment,
+                       packet_header_type, packet_context_type,
+                       event_header_type, stream_event_ctx_type);
+               if (!valid_ret) {
+                       /* Stream class is valid */
+                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_STREAM;
+               }
+
+               goto sc_validation_done;
+
+sc_validation_error:
+               BT_PUT(packet_context_type_copy);
+               BT_PUT(event_header_type_copy);
+               BT_PUT(stream_event_ctx_type_copy);
+               ret = -1;
+               goto error;
+       }
+
+sc_validation_done:
+       /* Validate event class */
+       if ((validate_flags & BT_CTF_VALIDATION_FLAG_EVENT) &&
+                       !event_class_valid) {
+               struct bt_ctf_field_type *event_context_type_copy = NULL;
+               struct bt_ctf_field_type *event_payload_type_copy = NULL;
+
+               if (event_context_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       event_context_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               event_context_type_copy = event_context_type;
+                               bt_get(event_context_type_copy);
+                               goto skip_event_context_type_copy;
+                       }
+
+                       event_context_type_copy =
+                               bt_ctf_field_type_copy(event_context_type);
+                       if (!event_context_type_copy) {
+                               _printf_error("Cannot copy event context type\n");
+                               goto ec_validation_error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(event_context_type_copy);
+               }
+
+skip_event_context_type_copy:
+               if (event_payload_type) {
+                       contains_seq_var =
+                               field_type_contains_sequence_or_variant_ft(
+                                       event_payload_type);
+                       if (contains_seq_var < 0) {
+                               ret = contains_seq_var;
+                               goto error;
+                       } else if (!contains_seq_var) {
+                               /* No copy is needed */
+                               event_payload_type_copy = event_payload_type;
+                               bt_get(event_payload_type_copy);
+                               goto skip_event_payload_type_copy;
+                       }
+
+                       event_payload_type_copy =
+                               bt_ctf_field_type_copy(event_payload_type);
+                       if (!event_payload_type_copy) {
+                               _printf_error("Cannot copy event payload type\n");
+                               goto ec_validation_error;
+                       }
+
+                       /*
+                        * Freeze this copy: if it's returned to the
+                        * caller, it cannot be modified any way since
+                        * it will be resolved.
+                        */
+                       bt_ctf_field_type_freeze(event_payload_type_copy);
+               }
+
+skip_event_payload_type_copy:
+               /* Put original references and move copies */
+               BT_MOVE(event_context_type, event_context_type_copy);
+               BT_MOVE(event_payload_type, event_payload_type_copy);
+
+               /* Validate event class field types */
+               valid_ret = validate_event_class_types(environment,
+                       packet_header_type, packet_context_type,
+                       event_header_type, stream_event_ctx_type,
+                       event_context_type, event_payload_type);
+               if (!valid_ret) {
+                       /* Event class is valid */
+                       output->valid_flags |= BT_CTF_VALIDATION_FLAG_EVENT;
+               }
+
+               goto ec_validation_done;
+
+ec_validation_error:
+               BT_PUT(event_context_type_copy);
+               BT_PUT(event_payload_type_copy);
+               ret = -1;
+               goto error;
+       }
+
+ec_validation_done:
+       /*
+        * Validation is complete. Move the field types that were used
+        * to validate (and that were possibly altered by the validation
+        * process) to the output values.
+        */
+       BT_MOVE(output->packet_header_type, packet_header_type);
+       BT_MOVE(output->packet_context_type, packet_context_type);
+       BT_MOVE(output->event_header_type, event_header_type);
+       BT_MOVE(output->stream_event_ctx_type, stream_event_ctx_type);
+       BT_MOVE(output->event_context_type, event_context_type);
+       BT_MOVE(output->event_payload_type, event_payload_type);
+
+       return ret;
+
+error:
+       BT_PUT(packet_header_type);
+       BT_PUT(packet_context_type);
+       BT_PUT(event_header_type);
+       BT_PUT(stream_event_ctx_type);
+       BT_PUT(event_context_type);
+       BT_PUT(event_payload_type);
+
+       return ret;
+}
+
+BT_HIDDEN
+void bt_ctf_validation_replace_types(struct bt_ctf_trace *trace,
+               struct bt_ctf_stream_class *stream_class,
+               struct bt_ctf_event_class *event_class,
+               struct bt_ctf_validation_output *output,
+               enum bt_ctf_validation_flag replace_flags)
+{
+       if ((replace_flags & BT_CTF_VALIDATION_FLAG_TRACE) && trace) {
+               bt_ctf_field_type_freeze(trace->packet_header_type);
+               BT_MOVE(trace->packet_header_type, output->packet_header_type);
+       }
+
+       if ((replace_flags & BT_CTF_VALIDATION_FLAG_STREAM) && stream_class) {
+               bt_ctf_field_type_freeze(stream_class->packet_context_type);
+               bt_ctf_field_type_freeze(stream_class->event_header_type);
+               bt_ctf_field_type_freeze(stream_class->event_context_type);
+               BT_MOVE(stream_class->packet_context_type,
+                       output->packet_context_type);
+               BT_MOVE(stream_class->event_header_type,
+                       output->event_header_type);
+               BT_MOVE(stream_class->event_context_type,
+                       output->stream_event_ctx_type);
+       }
+
+       if ((replace_flags & BT_CTF_VALIDATION_FLAG_EVENT) && event_class) {
+               bt_ctf_field_type_freeze(event_class->context);
+               bt_ctf_field_type_freeze(event_class->fields);
+               BT_MOVE(event_class->context, output->event_context_type);
+               BT_MOVE(event_class->fields, output->event_payload_type);
+       }
+}
+
+BT_HIDDEN
+void bt_ctf_validation_output_put_types(
+               struct bt_ctf_validation_output *output)
+{
+       BT_PUT(output->packet_header_type);
+       BT_PUT(output->packet_context_type);
+       BT_PUT(output->event_header_type);
+       BT_PUT(output->stream_event_ctx_type);
+       BT_PUT(output->event_context_type);
+       BT_PUT(output->event_payload_type);
+}
diff --git a/lib/ctf-ir/visitor.c b/lib/ctf-ir/visitor.c
new file mode 100644 (file)
index 0000000..115b54a
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * visitor.c
+ *
+ * Babeltrace CTF IR - Visitor
+ *
+ * Copyright 2016 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/visitor-internal.h>
+#include <babeltrace/ref.h>
+
+BT_HIDDEN
+int visitor_helper(struct bt_ctf_object *root,
+               bt_child_count_accessor child_counter,
+               bt_child_accessor child_accessor,
+               bt_child_visitor child_visitor,
+               bt_ctf_visitor visitor,
+               void *data)
+{
+       int ret, child_count, i;
+
+       ret = visitor(root, data);
+       if (ret) {
+               goto end;
+       }
+
+       child_count = child_counter(root->object);
+       if (child_count < 0) {
+               ret = child_count;
+               goto end;
+       }
+
+       for (i = 0; i < child_count; i++) {
+               void *child;
+
+               child = child_accessor(root->object, i);
+               if (!child) {
+                       ret = -1;
+                       goto end;
+               }
+               ret = child_visitor(child, visitor, data);
+               BT_PUT(child);
+               if (ret) {
+                       goto end;
+               }
+       }
+end:
+       return ret;
+}
+
+enum bt_ctf_object_type bt_ctf_object_get_type(struct bt_ctf_object *object)
+{
+       enum bt_ctf_object_type ret = BT_CTF_OBJECT_TYPE_UNKNOWN;
+
+       if (!object) {
+               goto end;
+       }
+
+       ret = object->type;
+end:
+       return ret;
+}
+
+void *bt_ctf_object_get_object(struct bt_ctf_object *object)
+{
+       void *ret = NULL;
+
+       if (!object) {
+               goto end;
+       }
+
+       ret = object->object;
+end:
+       return ret;
+}
diff --git a/lib/ctf-writer/Makefile.am b/lib/ctf-writer/Makefile.am
new file mode 100644 (file)
index 0000000..58b1f25
--- /dev/null
@@ -0,0 +1,18 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
+
+noinst_LTLIBRARIES = libctf-writer.la
+
+libctf_writer_la_SOURCES = \
+       clock.c \
+       writer.c \
+       functor.c \
+       serialize.c
+
+libctf_writer_la_LIBADD =
+
+if BABELTRACE_BUILD_WITH_LIBUUID
+libctf_writer_la_LIBADD += -luuid
+endif
+if BABELTRACE_BUILD_WITH_LIBC_UUID
+libctf_writer_la_LIBADD += -lc
+endif
diff --git a/lib/ctf-writer/clock.c b/lib/ctf-writer/clock.c
new file mode 100644 (file)
index 0000000..84125f2
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * clock.c
+ *
+ * Babeltrace CTF IR - Clock
+ *
+ * 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.
+ */
+
+#include <babeltrace/ctf-writer/clock-internal.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/clock-class-internal.h>
+#include <babeltrace/ctf-ir/utils.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_clock_destroy(struct bt_object *obj);
+
+struct bt_ctf_clock *bt_ctf_clock_create(const char *name)
+{
+       struct bt_ctf_clock *clock = NULL;
+
+       if (!name) {
+               goto error;
+       }
+
+       clock = g_new0(struct bt_ctf_clock, 1);
+
+       if (!clock) {
+               goto error;
+       }
+
+       bt_object_init(clock, bt_ctf_clock_destroy);
+       clock->value = 0;
+       clock->clock_class = bt_ctf_clock_class_create(name);
+       if (!clock->clock_class) {
+               goto error;
+       }
+       return clock;
+
+error:
+       BT_PUT(clock);
+       return clock;
+}
+
+const char *bt_ctf_clock_get_name(struct bt_ctf_clock *clock)
+{
+       const char *name = NULL;
+
+       if (clock) {
+               name = bt_ctf_clock_class_get_name(clock->clock_class);
+       }
+
+       return name;
+}
+
+const char *bt_ctf_clock_get_description(struct bt_ctf_clock *clock)
+{
+       const char *description = NULL;
+
+       if (clock) {
+               description = bt_ctf_clock_class_get_description(
+                       clock->clock_class);
+       }
+
+       return description;
+}
+
+int bt_ctf_clock_set_description(struct bt_ctf_clock *clock, const char *desc)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_description(clock->clock_class,
+                       desc);
+       }
+
+       return ret;
+}
+
+uint64_t bt_ctf_clock_get_frequency(struct bt_ctf_clock *clock)
+{
+       uint64_t freq = -1ULL;
+
+       if (clock) {
+               freq = bt_ctf_clock_class_get_frequency(clock->clock_class);
+       }
+
+       return freq;
+}
+
+int bt_ctf_clock_set_frequency(struct bt_ctf_clock *clock, uint64_t freq)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_frequency(clock->clock_class,
+                       freq);
+       }
+
+       return ret;
+}
+
+uint64_t bt_ctf_clock_get_precision(struct bt_ctf_clock *clock)
+{
+       uint64_t precision = -1ULL;
+
+       if (clock) {
+               precision = bt_ctf_clock_class_get_precision(
+                       clock->clock_class);
+       }
+
+       return precision;
+}
+
+int bt_ctf_clock_set_precision(struct bt_ctf_clock *clock, uint64_t precision)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_precision(clock->clock_class,
+                       precision);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_get_offset_s(struct bt_ctf_clock *clock, int64_t *offset_s)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_get_offset_s(clock->clock_class,
+                       offset_s);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_set_offset_s(struct bt_ctf_clock *clock, int64_t offset_s)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_offset_s(clock->clock_class,
+                       offset_s);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_get_offset(struct bt_ctf_clock *clock, int64_t *offset)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_get_offset_cycles(clock->clock_class,
+                       offset);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_set_offset(struct bt_ctf_clock *clock, int64_t offset)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_offset_cycles(clock->clock_class,
+                       offset);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_get_is_absolute(struct bt_ctf_clock *clock)
+{
+       int is_absolute = -1;
+
+       if (clock) {
+               is_absolute = bt_ctf_clock_class_get_is_absolute(
+                       clock->clock_class);
+       }
+
+       return is_absolute;
+}
+
+int bt_ctf_clock_set_is_absolute(struct bt_ctf_clock *clock, int is_absolute)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_is_absolute(clock->clock_class,
+                       is_absolute);
+       }
+
+       return ret;
+}
+
+const unsigned char *bt_ctf_clock_get_uuid(struct bt_ctf_clock *clock)
+{
+       const unsigned char *uuid = NULL;
+
+       if (clock) {
+               uuid = bt_ctf_clock_class_get_uuid(clock->clock_class);
+       }
+
+       return uuid;
+}
+
+int bt_ctf_clock_set_uuid(struct bt_ctf_clock *clock, const unsigned char *uuid)
+{
+       int ret = -1;
+
+       if (clock) {
+               ret = bt_ctf_clock_class_set_uuid(clock->clock_class, uuid);
+       }
+
+       return ret;
+}
+
+int bt_ctf_clock_set_time(struct bt_ctf_clock *clock, int64_t time)
+{
+       int ret = 0;
+       int64_t value;
+
+       if (!clock) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Common case where cycles are actually nanoseconds */
+       if (clock->clock_class->frequency == 1000000000) {
+               value = time;
+       } else {
+               value = (uint64_t) (((double) time *
+                       (double) clock->clock_class->frequency) / 1e9);
+       }
+
+       if (clock->value > value) {
+               /* Timestamps must be strictly monotonic. */
+               ret = -1;
+               goto end;
+       }
+
+       clock->value = value;
+end:
+       return ret;
+}
+
+void bt_ctf_clock_get(struct bt_ctf_clock *clock)
+{
+       bt_get(clock);
+}
+
+void bt_ctf_clock_put(struct bt_ctf_clock *clock)
+{
+       bt_put(clock);
+}
+
+BT_HIDDEN
+int bt_ctf_clock_get_value(struct bt_ctf_clock *clock, uint64_t *value)
+{
+       int ret = 0;
+
+       if (!clock || !value) {
+               ret = -1;
+               goto end;
+       }
+
+       *value = clock->value;
+end:
+       return ret;
+}
+
+static
+void bt_ctf_clock_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_clock *clock;
+
+       clock = container_of(obj, struct bt_ctf_clock, base);
+       bt_put(clock->clock_class);
+       g_free(clock);
+}
diff --git a/lib/ctf-writer/functor.c b/lib/ctf-writer/functor.c
new file mode 100644 (file)
index 0000000..3d99b63
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * functor.c
+ *
+ * Babeltrace CTF Writer
+ *
+ * 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 <glib.h>
+#include <babeltrace/ctf-writer/functor-internal.h>
+
+BT_HIDDEN
+void value_exists(gpointer element, gpointer search_query)
+{
+       if (element == ((struct search_query *)search_query)->value) {
+               ((struct search_query *)search_query)->found = 1;
+       }
+}
diff --git a/lib/ctf-writer/serialize.c b/lib/ctf-writer/serialize.c
new file mode 100644 (file)
index 0000000..6058dd3
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * serialize.c
+ *
+ * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
+ * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * The original author of the serialization functions for Babeltrace 1
+ * is Mathieu Desnoyers. Philippe Proulx modified the functions in 2017
+ * to use Babeltrace 2 objects.
+ *
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/fields.h>
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-writer/serialize-internal.h>
+#include <babeltrace/align.h>
+#include <babeltrace/mmap-align.h>
+#include <babeltrace/endian.h>
+#include <babeltrace/bitfield.h>
+#include <babeltrace/compat/fcntl.h>
+#include <glib.h>
+
+/* "Native" to CTF IR byte order */
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+# define MY_BT_CTF_BYTE_ORDER BT_CTF_BYTE_ORDER_LITTLE_ENDIAN
+#else
+# define MY_BT_CTF_BYTE_ORDER BT_CTF_BYTE_ORDER_BIG_ENDIAN
+#endif
+
+#if (FLT_RADIX != 2)
+# error "Unsupported floating point radix"
+#endif
+
+union intval {
+       int64_t signd;
+       uint64_t unsignd;
+};
+
+/*
+ * The aligned read/write functions are expected to be faster than the
+ * bitfield variants. They will be enabled eventually as an
+ * optimisation.
+ */
+static
+int aligned_integer_write(struct bt_ctf_stream_pos *pos,
+               union intval value, unsigned int alignment, unsigned int size,
+               bool is_signed, enum bt_ctf_byte_order byte_order)
+{
+       bool rbo = (byte_order != MY_BT_CTF_BYTE_ORDER); /* reverse byte order */
+
+       if (!bt_ctf_stream_pos_align(pos, alignment))
+               return -EFAULT;
+
+       if (!bt_ctf_stream_pos_access_ok(pos, size))
+               return -EFAULT;
+
+       assert(!(pos->offset % CHAR_BIT));
+       if (!is_signed) {
+               switch (size) {
+               case 8:
+               {
+                       uint8_t v = value.unsignd;
+
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 16:
+               {
+                       uint16_t v = value.unsignd;
+
+                       if (rbo)
+                               v = GUINT16_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 32:
+               {
+                       uint32_t v = value.unsignd;
+
+                       if (rbo)
+                               v = GUINT32_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 64:
+               {
+                       uint64_t v = value.unsignd;
+
+                       if (rbo)
+                               v = GUINT64_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               default:
+                       assert(false);
+               }
+       } else {
+               switch (size) {
+               case 8:
+               {
+                       uint8_t v = value.signd;
+
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 16:
+               {
+                       int16_t v = value.signd;
+
+                       if (rbo)
+                               v = GUINT16_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 32:
+               {
+                       int32_t v = value.signd;
+
+                       if (rbo)
+                               v = GUINT32_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               case 64:
+               {
+                       int64_t v = value.signd;
+
+                       if (rbo)
+                               v = GUINT64_SWAP_LE_BE(v);
+                       memcpy(bt_ctf_stream_pos_get_addr(pos), &v, sizeof(v));
+                       break;
+               }
+               default:
+                       assert(false);
+               }
+       }
+
+       if (!bt_ctf_stream_pos_move(pos, size))
+               return -EFAULT;
+       return 0;
+}
+
+static
+int integer_write(struct bt_ctf_stream_pos *pos, union intval value,
+       unsigned int alignment, unsigned int size, bool is_signed,
+       enum bt_ctf_byte_order byte_order)
+{
+       if (!(alignment % CHAR_BIT)
+           && !(size % CHAR_BIT)) {
+               return aligned_integer_write(pos, value, alignment,
+                       size, is_signed, byte_order);
+       }
+
+       if (!bt_ctf_stream_pos_align(pos, alignment))
+               return -EFAULT;
+
+       if (!bt_ctf_stream_pos_access_ok(pos, size))
+               return -EFAULT;
+
+       if (!is_signed) {
+               if (byte_order == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN)
+                       bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
+                               pos->mmap_base_offset, unsigned char,
+                               pos->offset, size, value.unsignd);
+               else
+                       bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
+                               pos->mmap_base_offset, unsigned char,
+                               pos->offset, size, value.unsignd);
+       } else {
+               if (byte_order == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN)
+                       bt_bitfield_write_le(mmap_align_addr(pos->base_mma) +
+                               pos->mmap_base_offset, unsigned char,
+                               pos->offset, size, value.signd);
+               else
+                       bt_bitfield_write_be(mmap_align_addr(pos->base_mma) +
+                               pos->mmap_base_offset, unsigned char,
+                               pos->offset, size, value.signd);
+       }
+
+       if (!bt_ctf_stream_pos_move(pos, size))
+               return -EFAULT;
+       return 0;
+}
+
+BT_HIDDEN
+int bt_ctf_field_integer_write(struct bt_ctf_field_integer *int_field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       struct bt_ctf_field_type *type = int_field->parent.type;
+       struct bt_ctf_field_type_integer *int_type = (void *) type;
+       enum bt_ctf_byte_order byte_order;
+       union intval value;
+
+       byte_order = int_type->user_byte_order;
+       if (byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
+               byte_order = native_byte_order;
+       }
+
+       value.signd = int_field->payload.signd;
+       value.unsignd = int_field->payload.unsignd;
+       return integer_write(pos, value, type->alignment,
+               int_type->size, int_type->is_signed,
+               byte_order);
+}
+
+BT_HIDDEN
+int bt_ctf_field_floating_point_write(
+               struct bt_ctf_field_floating_point *flt_field,
+               struct bt_ctf_stream_pos *pos,
+               enum bt_ctf_byte_order native_byte_order)
+{
+       struct bt_ctf_field_type *type = flt_field->parent.type;
+       struct bt_ctf_field_type_floating_point *flt_type = (void *) type;
+       enum bt_ctf_byte_order byte_order;
+       union intval value;
+       unsigned int size;
+
+       byte_order = flt_type->user_byte_order;
+       if (byte_order == BT_CTF_BYTE_ORDER_NATIVE) {
+               byte_order = native_byte_order;
+       }
+
+       if (flt_type->mant_dig == FLT_MANT_DIG) {
+               union u32f {
+                       uint32_t u;
+                       float f;
+               } u32f;
+
+               u32f.f = (float) flt_field->payload;
+               value.unsignd = u32f.u;
+               size = 32;
+       } else if (flt_type->mant_dig == DBL_MANT_DIG) {
+               union u64d {
+                       uint64_t u;
+                       double d;
+               } u64d;
+
+               u64d.d = flt_field->payload;
+               value.unsignd = u64d.u;
+               size = 64;
+       } else {
+               return -EINVAL;
+       }
+
+       return integer_write(pos, value, type->alignment, size, false,
+               byte_order);
+}
+
+BT_HIDDEN
+void bt_ctf_stream_pos_packet_seek(struct bt_ctf_stream_pos *pos, size_t index,
+       int whence)
+{
+       int ret;
+
+       assert(whence == SEEK_CUR && index == 0);
+
+       if (pos->base_mma) {
+               /* unmap old base */
+               ret = munmap_align(pos->base_mma);
+               if (ret) {
+                       assert(false);
+               }
+               pos->base_mma = NULL;
+       }
+
+       /* The writer will add padding */
+       pos->mmap_offset += pos->packet_size / CHAR_BIT;
+       pos->content_size = -1U;        /* Unknown at this point */
+       pos->packet_size = getpagesize() * 8 * CHAR_BIT;
+       do {
+               ret = bt_posix_fallocate(pos->fd, pos->mmap_offset,
+                       pos->packet_size / CHAR_BIT);
+       } while (ret == EINTR);
+       assert(ret == 0);
+       pos->offset = 0;
+
+       /* map new base. Need mapping length from header. */
+       pos->base_mma = mmap_align(pos->packet_size / CHAR_BIT, pos->prot,
+               pos->flags, pos->fd, pos->mmap_offset);
+       if (pos->base_mma == MAP_FAILED) {
+               assert(false);
+       }
+}
diff --git a/lib/ctf-writer/writer.c b/lib/ctf-writer/writer.c
new file mode 100644 (file)
index 0000000..854de43
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * writer.c
+ *
+ * Babeltrace CTF Writer
+ *
+ * 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-writer/clock-internal.h>
+#include <babeltrace/ctf-writer/writer-internal.h>
+#include <babeltrace/ctf-ir/field-types-internal.h>
+#include <babeltrace/ctf-ir/fields-internal.h>
+#include <babeltrace/ctf-writer/functor-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/ref.h>
+#include <babeltrace/compiler.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+static
+void bt_ctf_writer_destroy(struct bt_object *obj);
+
+struct bt_ctf_writer *bt_ctf_writer_create(const char *path)
+{
+       struct bt_ctf_writer *writer = NULL;
+
+       if (!path) {
+               goto error;
+       }
+
+       writer = g_new0(struct bt_ctf_writer, 1);
+       if (!writer) {
+               goto error;
+       }
+
+       bt_object_init(writer, bt_ctf_writer_destroy);
+       writer->path = g_string_new(path);
+       if (!writer->path) {
+               goto error_destroy;
+       }
+
+       writer->trace = bt_ctf_trace_create();
+       if (!writer->trace) {
+               goto error_destroy;
+       }
+
+       writer->trace->is_created_by_writer = 1;
+       bt_object_set_parent(writer->trace, writer);
+       bt_put(writer->trace);
+       /* Create trace directory if necessary and open a metadata file */
+       if (g_mkdir_with_parents(path, S_IRWXU | S_IRWXG)) {
+               perror("g_mkdir_with_parents");
+               goto error_destroy;
+       }
+
+       writer->trace_dir_fd = open(path, O_RDONLY, S_IRWXU | S_IRWXG);
+       if (writer->trace_dir_fd < 0) {
+               perror("open");
+               goto error_destroy;
+       }
+
+       writer->metadata_fd = openat(writer->trace_dir_fd, "metadata",
+               O_WRONLY | O_CREAT | O_TRUNC,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+
+       return writer;
+
+error_destroy:
+       unlinkat(writer->trace_dir_fd, "metadata", 0);
+       BT_PUT(writer);
+error:
+       return writer;
+}
+
+void bt_ctf_writer_destroy(struct bt_object *obj)
+{
+       struct bt_ctf_writer *writer;
+
+       writer = container_of(obj, struct bt_ctf_writer, base);
+       bt_ctf_writer_flush_metadata(writer);
+       if (writer->path) {
+               g_string_free(writer->path, TRUE);
+       }
+
+       if (writer->trace_dir_fd > 0) {
+               if (close(writer->trace_dir_fd)) {
+                       perror("close");
+               }
+       }
+
+       if (writer->metadata_fd > 0) {
+               if (close(writer->metadata_fd)) {
+                       perror("close");
+               }
+       }
+
+       bt_object_release(writer->trace);
+       g_free(writer);
+}
+
+struct bt_ctf_trace *bt_ctf_writer_get_trace(struct bt_ctf_writer *writer)
+{
+       struct bt_ctf_trace *trace = NULL;
+
+       if (!writer) {
+               goto end;
+       }
+
+       trace = writer->trace;
+       bt_get(trace);
+end:
+       return trace;
+}
+
+struct bt_ctf_stream *bt_ctf_writer_create_stream(struct bt_ctf_writer *writer,
+               struct bt_ctf_stream_class *stream_class)
+{
+       struct bt_ctf_stream *stream = NULL;
+       int stream_class_count;
+       bool stream_class_found = false;
+       int i;
+
+       if (!writer || !stream_class) {
+               goto error;
+       }
+
+       /* Make sure the stream class is part of the writer's trace */
+       stream_class_count = bt_ctf_trace_get_stream_class_count(writer->trace);
+       if (stream_class_count < 0) {
+               goto error;
+       }
+
+       for (i = 0; i < stream_class_count; i++) {
+               struct bt_ctf_stream_class *existing_stream_class =
+                       bt_ctf_trace_get_stream_class(writer->trace, i);
+
+               if (existing_stream_class == stream_class) {
+                       stream_class_found = true;
+               }
+
+               BT_PUT(existing_stream_class);
+
+               if (stream_class_found) {
+                       break;
+               }
+       }
+
+       if (!stream_class_found) {
+               int ret = bt_ctf_trace_add_stream_class(writer->trace,
+                       stream_class);
+
+               if (ret) {
+                       goto error;
+               }
+       }
+
+       stream = bt_ctf_stream_create(stream_class, NULL);
+       if (!stream) {
+               goto error;
+       }
+
+       return stream;
+
+error:
+        BT_PUT(stream);
+       return stream;
+}
+
+int bt_ctf_writer_add_environment_field(struct bt_ctf_writer *writer,
+               const char *name,
+               const char *value)
+{
+       int ret = -1;
+
+       if (!writer || !name || !value) {
+               goto end;
+       }
+
+       ret = bt_ctf_trace_set_environment_field_string(writer->trace,
+               name, value);
+end:
+       return ret;
+}
+
+int bt_ctf_writer_add_environment_field_int64(struct bt_ctf_writer *writer,
+               const char *name,
+               int64_t value)
+{
+       int ret = -1;
+
+       if (!writer || !name) {
+               goto end;
+       }
+
+       ret = bt_ctf_trace_set_environment_field_integer(writer->trace, name,
+               value);
+end:
+       return ret;
+}
+
+int bt_ctf_writer_add_clock(struct bt_ctf_writer *writer,
+               struct bt_ctf_clock *clock)
+{
+       int ret = -1;
+
+       if (!writer || !clock) {
+               goto end;
+       }
+
+       ret = bt_ctf_trace_add_clock_class(writer->trace, clock->clock_class);
+end:
+       return ret;
+}
+
+char *bt_ctf_writer_get_metadata_string(struct bt_ctf_writer *writer)
+{
+       char *metadata_string = NULL;
+
+       if (!writer) {
+               goto end;
+       }
+
+       metadata_string = bt_ctf_trace_get_metadata_string(
+               writer->trace);
+end:
+       return metadata_string;
+}
+
+void bt_ctf_writer_flush_metadata(struct bt_ctf_writer *writer)
+{
+       int ret;
+       char *metadata_string = NULL;
+
+       if (!writer) {
+               goto end;
+       }
+
+       metadata_string = bt_ctf_trace_get_metadata_string(
+               writer->trace);
+       if (!metadata_string) {
+               goto end;
+       }
+
+       if (lseek(writer->metadata_fd, 0, SEEK_SET) == (off_t)-1) {
+               perror("lseek");
+               goto end;
+       }
+
+       if (ftruncate(writer->metadata_fd, 0)) {
+               perror("ftruncate");
+               goto end;
+       }
+
+       ret = write(writer->metadata_fd, metadata_string,
+               strlen(metadata_string));
+       if (ret < 0) {
+               perror("write");
+               goto end;
+       }
+end:
+       g_free(metadata_string);
+}
+
+int bt_ctf_writer_set_byte_order(struct bt_ctf_writer *writer,
+               enum bt_ctf_byte_order byte_order)
+{
+       int ret = 0;
+
+       if (!writer || writer->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_trace_set_byte_order(writer->trace,
+               byte_order);
+end:
+       return ret;
+}
+
+void bt_ctf_writer_get(struct bt_ctf_writer *writer)
+{
+       bt_get(writer);
+}
+
+void bt_ctf_writer_put(struct bt_ctf_writer *writer)
+{
+       bt_put(writer);
+}
+
+BT_HIDDEN
+void bt_ctf_writer_freeze(struct bt_ctf_writer *writer)
+{
+       writer->frozen = 1;
+}
diff --git a/lib/debug-info.c b/lib/debug-info.c
deleted file mode 100644 (file)
index eff5134..0000000
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * Babeltrace - Debug Information State Tracker
- *
- * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
- * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
- * Copyright (c) 2016 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 <assert.h>
-#include <glib.h>
-#include <babeltrace/types.h>
-#include <babeltrace/ctf-ir/metadata.h>
-#include <babeltrace/debug-info.h>
-#include <babeltrace/bin-info.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/utils.h>
-
-struct proc_debug_info_sources {
-       /*
-        * Hash table: base address (pointer to uint64_t) to bin info; owned by
-        * proc_debug_info_sources.
-        */
-       GHashTable *baddr_to_bin_info;
-
-       /*
-        * Hash table: IP (pointer to uint64_t) to (struct debug_info_source *);
-        * owned by proc_debug_info_sources.
-        */
-       GHashTable *ip_to_debug_info_src;
-};
-
-struct debug_info {
-       /*
-        * Hash table of VPIDs (pointer to int64_t) to
-        * (struct ctf_proc_debug_infos*); owned by debug_info.
-        */
-       GHashTable *vpid_to_proc_dbg_info_src;
-       GQuark q_statedump_bin_info;
-       GQuark q_statedump_debug_link;
-       GQuark q_statedump_build_id;
-       GQuark q_statedump_start;
-       GQuark q_dl_open;
-       GQuark q_lib_load;
-       GQuark q_lib_unload;
-};
-
-static
-int debug_info_init(struct debug_info *info)
-{
-       info->q_statedump_bin_info = g_quark_from_string(
-                       "lttng_ust_statedump:bin_info");
-       info->q_statedump_debug_link = g_quark_from_string(
-                       "lttng_ust_statedump:debug_link)");
-       info->q_statedump_build_id = g_quark_from_string(
-                       "lttng_ust_statedump:build_id");
-       info->q_statedump_start = g_quark_from_string(
-                       "lttng_ust_statedump:start");
-       info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen");
-       info->q_lib_load = g_quark_from_string("lttng_ust_lib:load");
-       info->q_lib_unload = g_quark_from_string("lttng_ust_lib:unload");
-
-       return bin_info_init();
-}
-
-static
-void debug_info_source_destroy(struct debug_info_source *debug_info_src)
-{
-       if (!debug_info_src) {
-               return;
-       }
-
-       free(debug_info_src->func);
-       free(debug_info_src->src_path);
-       free(debug_info_src->bin_path);
-       free(debug_info_src->bin_loc);
-       g_free(debug_info_src);
-}
-
-static
-struct debug_info_source *debug_info_source_create_from_bin(struct bin_info *bin,
-               uint64_t ip)
-{
-       int ret;
-       struct debug_info_source *debug_info_src = NULL;
-       struct source_location *src_loc = NULL;
-
-       debug_info_src = g_new0(struct debug_info_source, 1);
-
-       if (!debug_info_src) {
-               goto end;
-       }
-
-       /* Lookup function name */
-       ret = bin_info_lookup_function_name(bin, ip, &debug_info_src->func);
-       if (ret) {
-               goto error;
-       }
-
-       /* Can't retrieve src_loc from ELF, or could not find binary, skip. */
-       if (!bin->is_elf_only || !debug_info_src->func) {
-               /* Lookup source location */
-               ret = bin_info_lookup_source_location(bin, ip, &src_loc);
-               printf_verbose("Failed to lookup source location (err: %i)\n", ret);
-       }
-
-       if (src_loc) {
-               debug_info_src->line_no = src_loc->line_no;
-
-               if (src_loc->filename) {
-                       debug_info_src->src_path = strdup(src_loc->filename);
-                       if (!debug_info_src->src_path) {
-                               goto error;
-                       }
-
-                       debug_info_src->short_src_path = get_filename_from_path(
-                                       debug_info_src->src_path);
-               }
-
-               source_location_destroy(src_loc);
-       }
-
-       if (bin->elf_path) {
-               debug_info_src->bin_path = strdup(bin->elf_path);
-               if (!debug_info_src->bin_path) {
-                       goto error;
-               }
-
-               debug_info_src->short_bin_path = get_filename_from_path(
-                               debug_info_src->bin_path);
-
-               ret = bin_info_get_bin_loc(bin, ip, &(debug_info_src->bin_loc));
-               if (ret) {
-                       goto error;
-               }
-       }
-
-end:
-       return debug_info_src;
-
-error:
-       debug_info_source_destroy(debug_info_src);
-       return NULL;
-}
-
-static
-void proc_debug_info_sources_destroy(
-               struct proc_debug_info_sources *proc_dbg_info_src)
-{
-       if (!proc_dbg_info_src) {
-               return;
-       }
-
-       if (proc_dbg_info_src->baddr_to_bin_info) {
-               g_hash_table_destroy(proc_dbg_info_src->baddr_to_bin_info);
-       }
-
-       if (proc_dbg_info_src->ip_to_debug_info_src) {
-               g_hash_table_destroy(proc_dbg_info_src->ip_to_debug_info_src);
-       }
-
-       g_free(proc_dbg_info_src);
-}
-
-static
-struct proc_debug_info_sources *proc_debug_info_sources_create(void)
-{
-       struct proc_debug_info_sources *proc_dbg_info_src = NULL;
-
-       proc_dbg_info_src = g_new0(struct proc_debug_info_sources, 1);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       proc_dbg_info_src->baddr_to_bin_info = g_hash_table_new_full(
-                       g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
-                       (GDestroyNotify) bin_info_destroy);
-       if (!proc_dbg_info_src->baddr_to_bin_info) {
-               goto error;
-       }
-
-       proc_dbg_info_src->ip_to_debug_info_src = g_hash_table_new_full(
-                       g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
-                       (GDestroyNotify) debug_info_source_destroy);
-       if (!proc_dbg_info_src->ip_to_debug_info_src) {
-               goto error;
-       }
-
-end:
-       return proc_dbg_info_src;
-
-error:
-       proc_debug_info_sources_destroy(proc_dbg_info_src);
-       return NULL;
-}
-
-static
-struct proc_debug_info_sources *proc_debug_info_sources_ht_get_entry(
-               GHashTable *ht, int64_t vpid)
-{
-       gpointer key = g_new0(int64_t, 1);
-       struct proc_debug_info_sources *proc_dbg_info_src = NULL;
-
-       if (!key) {
-               goto end;
-       }
-
-       *((int64_t *) key) = vpid;
-
-       /* Exists? Return it */
-       proc_dbg_info_src = g_hash_table_lookup(ht, key);
-       if (proc_dbg_info_src) {
-               goto end;
-       }
-
-       /* Otherwise, create and return it */
-       proc_dbg_info_src = proc_debug_info_sources_create();
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       g_hash_table_insert(ht, key, proc_dbg_info_src);
-       /* Ownership passed to ht */
-       key = NULL;
-end:
-       g_free(key);
-       return proc_dbg_info_src;
-}
-
-static
-struct debug_info_source *proc_debug_info_sources_get_entry(
-               struct proc_debug_info_sources *proc_dbg_info_src, uint64_t ip)
-{
-       struct debug_info_source *debug_info_src = NULL;
-       gpointer key = g_new0(uint64_t, 1);
-       GHashTableIter iter;
-       gpointer baddr, value;
-
-       if (!key) {
-               goto end;
-       }
-
-       *((uint64_t *) key) = ip;
-
-       /* Look in IP to debug infos hash table first. */
-       debug_info_src = g_hash_table_lookup(
-                       proc_dbg_info_src->ip_to_debug_info_src,
-                       key);
-       if (debug_info_src) {
-               goto end;
-       }
-
-       /* Check in all bin_infos. */
-       g_hash_table_iter_init(&iter, proc_dbg_info_src->baddr_to_bin_info);
-
-       while (g_hash_table_iter_next(&iter, &baddr, &value))
-       {
-               struct bin_info *bin = value;
-
-               if (!bin_info_has_address(value, ip)) {
-                       continue;
-               }
-
-               /*
-                * Found; add it to cache.
-                *
-                * FIXME: this should be bounded in size (and implement
-                * a caching policy), and entries should be prunned when
-                * libraries are unmapped.
-                */
-               debug_info_src = debug_info_source_create_from_bin(bin, ip);
-               if (debug_info_src) {
-                       g_hash_table_insert(
-                                       proc_dbg_info_src->ip_to_debug_info_src,
-                                       key, debug_info_src);
-                       /* Ownership passed to ht. */
-                       key = NULL;
-               }
-               break;
-       }
-
-end:
-       free(key);
-       return debug_info_src;
-}
-
-BT_HIDDEN
-struct debug_info_source *debug_info_query(struct debug_info *debug_info,
-               int64_t vpid, uint64_t ip)
-{
-       struct debug_info_source *dbg_info_src = NULL;
-       struct proc_debug_info_sources *proc_dbg_info_src;
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       dbg_info_src = proc_debug_info_sources_get_entry(
-                       proc_dbg_info_src, ip);
-       if (!dbg_info_src) {
-               goto end;
-       }
-
-end:
-       return dbg_info_src;
-}
-
-BT_HIDDEN
-struct debug_info *debug_info_create(void)
-{
-       int ret;
-       struct debug_info *debug_info;
-
-       debug_info = g_new0(struct debug_info, 1);
-       if (!debug_info) {
-               goto end;
-       }
-
-       debug_info->vpid_to_proc_dbg_info_src = g_hash_table_new_full(
-                       g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
-                       (GDestroyNotify) proc_debug_info_sources_destroy);
-       if (!debug_info->vpid_to_proc_dbg_info_src) {
-               goto error;
-       }
-
-       ret = debug_info_init(debug_info);
-       if (ret) {
-               goto error;
-       }
-
-end:
-       return debug_info;
-error:
-       g_free(debug_info);
-       return NULL;
-}
-
-BT_HIDDEN
-void debug_info_destroy(struct debug_info *debug_info)
-{
-       if (!debug_info) {
-               goto end;
-       }
-
-       if (debug_info->vpid_to_proc_dbg_info_src) {
-               g_hash_table_destroy(debug_info->vpid_to_proc_dbg_info_src);
-       }
-
-       g_free(debug_info);
-end:
-       return;
-}
-
-static
-void handle_statedump_build_id_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       struct proc_debug_info_sources *proc_dbg_info_src;
-       struct bt_definition *event_fields_def = NULL;
-       struct bt_definition *sec_def = NULL;
-       struct bt_definition *baddr_def = NULL;
-       struct bt_definition *vpid_def = NULL;
-       struct bt_definition *build_id_def = NULL;
-       struct definition_sequence *build_id_seq;
-       struct bin_info *bin = NULL;
-       int i;
-       int64_t vpid;
-       uint64_t baddr;
-       uint8_t *build_id = NULL;
-       uint64_t build_id_len;
-
-       event_fields_def = (struct bt_definition *) event_def->event_fields;
-       sec_def = (struct bt_definition *)
-                       event_def->stream->stream_event_context;
-
-       if (!event_fields_def || !sec_def) {
-               goto end;
-       }
-
-       baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
-       if (!baddr_def) {
-               goto end;
-       }
-
-       vpid_def = bt_lookup_definition(sec_def, "_vpid");
-       if (!vpid_def) {
-               goto end;
-       }
-
-       build_id_def = bt_lookup_definition(event_fields_def, "_build_id");
-       if (!build_id_def) {
-               goto end;
-       }
-
-       if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (build_id_def->declaration->id != BT_CTF_TYPE_ID_SEQUENCE) {
-               goto end;
-       }
-
-       baddr = bt_get_unsigned_int(baddr_def);
-       vpid = bt_get_signed_int(vpid_def);
-       build_id_seq = container_of(build_id_def,
-                       struct definition_sequence, p);
-       build_id_len = build_id_seq->length->value._unsigned;
-
-       build_id = g_malloc(build_id_len);
-       if (!build_id) {
-               goto end;
-       }
-
-       for (i = 0; i < build_id_len; ++i) {
-               struct bt_definition **field;
-
-               field = (struct bt_definition **) &g_ptr_array_index(
-                               build_id_seq->elems, i);
-               build_id[i] = bt_get_unsigned_int(*field);
-       }
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
-                       (gpointer) &baddr);
-       if (!bin) {
-               /*
-                * The build_id event comes after the bin has been
-                * created. If it isn't found, just ignore this event.
-                */
-               goto end;
-       }
-
-       bin_info_set_build_id(bin, build_id, build_id_len);
-
-end:
-       free(build_id);
-       return;
-}
-
-static
-void handle_statedump_debug_link_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       struct proc_debug_info_sources *proc_dbg_info_src;
-       struct bt_definition *event_fields_def = NULL;
-       struct bt_definition *sec_def = NULL;
-       struct bt_definition *baddr_def = NULL;
-       struct bt_definition *vpid_def = NULL;
-       struct bt_definition *filename_def = NULL;
-       struct bt_definition *crc32_def = NULL;
-       struct bin_info *bin = NULL;
-       int64_t vpid;
-       uint64_t baddr;
-       char *filename = NULL;
-       uint32_t crc32;
-
-       event_fields_def = (struct bt_definition *) event_def->event_fields;
-       sec_def = (struct bt_definition *)
-                       event_def->stream->stream_event_context;
-
-       if (!event_fields_def || !sec_def) {
-               goto end;
-       }
-
-       baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
-       if (!baddr_def) {
-               goto end;
-       }
-
-       vpid_def = bt_lookup_definition(sec_def, "_vpid");
-       if (!vpid_def) {
-               goto end;
-       }
-
-       filename_def = bt_lookup_definition(event_fields_def, "_filename");
-       if (!filename_def) {
-               goto end;
-       }
-
-       crc32_def = bt_lookup_definition(event_fields_def, "_crc32");
-       if (!crc32_def) {
-               goto end;
-       }
-
-       if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (filename_def->declaration->id != BT_CTF_TYPE_ID_STRING) {
-               goto end;
-       }
-
-       if (crc32_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       baddr = bt_get_unsigned_int(baddr_def);
-       vpid = bt_get_signed_int(vpid_def);
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
-                       (gpointer) &baddr);
-       if (!bin) {
-               /*
-                * The debug_link event comes after the bin has been
-                * created. If it isn't found, just ignore this event.
-                */
-               goto end;
-       }
-
-       filename = bt_get_string(filename_def);
-       crc32 = bt_get_unsigned_int(crc32_def);
-
-       bin_info_set_debug_link(bin, filename, crc32);
-
-end:
-       return;
-}
-
-static
-void handle_bin_info_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def, bool has_pic_field)
-{
-       struct bt_definition *baddr_def = NULL;
-       struct bt_definition *memsz_def = NULL;
-       struct bt_definition *path_def = NULL;
-       struct bt_definition *is_pic_def = NULL;
-       struct bt_definition *vpid_def = NULL;
-       struct bt_definition *event_fields_def = NULL;
-       struct bt_definition *sec_def = NULL;
-       struct proc_debug_info_sources *proc_dbg_info_src;
-       struct bin_info *bin;
-       uint64_t baddr, memsz;
-       int64_t vpid;
-       const char *path;
-       gpointer key = NULL;
-       bool is_pic;
-
-       event_fields_def = (struct bt_definition *) event_def->event_fields;
-       sec_def = (struct bt_definition *)
-               event_def->stream->stream_event_context;
-
-       if (!event_fields_def || !sec_def) {
-               goto end;
-       }
-
-       baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
-       if (!baddr_def) {
-               goto end;
-       }
-
-       memsz_def = bt_lookup_definition(event_fields_def, "_memsz");
-       if (!memsz_def) {
-               goto end;
-       }
-
-       path_def = bt_lookup_definition(event_fields_def, "_path");
-       if (!path_def) {
-               goto end;
-       }
-
-       if (has_pic_field) {
-               is_pic_def = bt_lookup_definition(event_fields_def, "_is_pic");
-               if (!is_pic_def) {
-                       goto end;
-               }
-
-               if (is_pic_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-                       goto end;
-               }
-
-               is_pic = (bt_get_unsigned_int(is_pic_def) == 1);
-       } else {
-               /*
-                * dlopen has no is_pic field, because the shared
-                * object is always PIC.
-                */
-               is_pic = true;
-       }
-
-       vpid_def = bt_lookup_definition(sec_def, "_vpid");
-       if (!vpid_def) {
-               goto end;
-       }
-
-       if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (memsz_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       if (path_def->declaration->id != BT_CTF_TYPE_ID_STRING) {
-               goto end;
-       }
-
-       if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       baddr = bt_get_unsigned_int(baddr_def);
-       memsz = bt_get_unsigned_int(memsz_def);
-       path = bt_get_string(path_def);
-       vpid = bt_get_signed_int(vpid_def);
-
-       if (!path) {
-               goto end;
-       }
-
-       if (memsz == 0) {
-               /* Ignore VDSO. */
-               goto end;
-       }
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       key = g_new0(uint64_t, 1);
-       if (!key) {
-               goto end;
-       }
-
-       *((uint64_t *) key) = baddr;
-
-       bin = g_hash_table_lookup(proc_dbg_info_src->baddr_to_bin_info,
-                       key);
-       if (bin) {
-               goto end;
-       }
-
-       bin = bin_info_create(path, baddr, memsz, is_pic);
-       if (!bin) {
-               goto end;
-       }
-
-       g_hash_table_insert(proc_dbg_info_src->baddr_to_bin_info,
-                       key, bin);
-       /* Ownership passed to ht. */
-       key = NULL;
-
-end:
-       g_free(key);
-       return;
-}
-
-static inline
-void handle_statedump_bin_info_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       handle_bin_info_event(debug_info, event_def, true);
-}
-
-static inline
-void handle_lib_load_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       handle_bin_info_event(debug_info, event_def, false);
-}
-
-static inline
-void handle_lib_unload_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       struct bt_definition *baddr_def = NULL;
-       struct bt_definition *event_fields_def = NULL;
-       struct bt_definition *sec_def = NULL;
-       struct bt_definition *vpid_def = NULL;
-       struct proc_debug_info_sources *proc_dbg_info_src;
-       uint64_t baddr;
-       int64_t vpid;
-       gpointer key_ptr = NULL;
-
-       event_fields_def = (struct bt_definition *) event_def->event_fields;
-       sec_def = (struct bt_definition *)
-                       event_def->stream->stream_event_context;
-       if (!event_fields_def || !sec_def) {
-               goto end;
-       }
-
-       baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
-       if (!baddr_def) {
-               goto end;
-       }
-
-       vpid_def = bt_lookup_definition(sec_def, "_vpid");
-       if (!vpid_def) {
-               goto end;
-       }
-
-       if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-       if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
-               goto end;
-       }
-
-       baddr = bt_get_unsigned_int(baddr_def);
-       vpid = bt_get_signed_int(vpid_def);
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       key_ptr = (gpointer) &baddr;
-       (void) g_hash_table_remove(proc_dbg_info_src->baddr_to_bin_info,
-                       key_ptr);
-end:
-       return;
-}
-
-static
-void handle_statedump_start(struct debug_info *debug_info,
-               struct ctf_event_definition *event_def)
-{
-       struct bt_definition *vpid_def = NULL;
-       struct bt_definition *sec_def = NULL;
-       struct proc_debug_info_sources *proc_dbg_info_src;
-       int64_t vpid;
-
-       sec_def = (struct bt_definition *)
-                       event_def->stream->stream_event_context;
-       if (!sec_def) {
-               goto end;
-       }
-
-       vpid_def = bt_lookup_definition(sec_def, "_vpid");
-       if (!vpid_def) {
-               goto end;
-       }
-
-       vpid = bt_get_signed_int(vpid_def);
-
-       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
-                       debug_info->vpid_to_proc_dbg_info_src, vpid);
-       if (!proc_dbg_info_src) {
-               goto end;
-       }
-
-       g_hash_table_remove_all(proc_dbg_info_src->baddr_to_bin_info);
-       g_hash_table_remove_all(proc_dbg_info_src->ip_to_debug_info_src);
-
-end:
-       return;
-}
-
-static
-void register_event_debug_infos(struct debug_info *debug_info,
-               struct ctf_event_definition *event)
-{
-       struct bt_definition *ip_def, *vpid_def;
-       int64_t vpid;
-       uint64_t ip;
-       struct bt_definition *sec_def;
-
-       /* Get stream event context definition. */
-       sec_def = (struct bt_definition *) event->stream->stream_event_context;
-       if (!sec_def) {
-               goto end;
-       }
-
-       /* Get "ip" and "vpid" definitions. */
-       vpid_def = bt_lookup_definition((struct bt_definition *) sec_def,
-                        "_vpid");
-       ip_def = bt_lookup_definition((struct bt_definition *) sec_def, "_ip");
-
-       if (!vpid_def || !ip_def) {
-                goto end;
-       }
-
-       vpid = bt_get_signed_int(vpid_def);
-       ip = bt_get_unsigned_int(ip_def);
-
-       /* Get debug info for this context. */
-       ((struct definition_integer *) ip_def)->debug_info_src =
-                       debug_info_query(debug_info, vpid, ip);
-
-end:
-       return;
-}
-
-BT_HIDDEN
-void debug_info_handle_event(struct debug_info *debug_info,
-               struct ctf_event_definition *event)
-{
-       struct ctf_event_declaration *event_class;
-       struct ctf_stream_declaration *stream_class;
-
-       if (!debug_info || !event) {
-               goto end;
-       }
-
-       stream_class = event->stream->stream_class;
-       event_class = g_ptr_array_index(stream_class->events_by_id,
-                       event->stream->event_id);
-
-       if (event_class->name == debug_info->q_statedump_bin_info) {
-               /* State dump */
-               handle_statedump_bin_info_event(debug_info, event);
-       } else if (event_class->name == debug_info->q_dl_open ||
-                       event_class->name == debug_info->q_lib_load) {
-               /*
-                * dl_open and lib_load events are both checked for since
-                * only dl_open was produced as of lttng-ust 2.8.
-                *
-                * lib_load, which is produced from lttng-ust 2.9+, is a lot
-                * more reliable since it will be emitted when other functions
-                * of the dlopen family are called (e.g. dlmopen) and when
-                * library are transitively loaded.
-                */
-               handle_lib_load_event(debug_info, event);
-       } else if (event_class->name == debug_info->q_statedump_start) {
-               /* Start state dump */
-               handle_statedump_start(debug_info, event);
-       } else if (event_class->name == debug_info->q_statedump_debug_link) {
-               /* Debug link info */
-               handle_statedump_debug_link_event(debug_info, event);
-       } else if (event_class->name == debug_info->q_statedump_build_id) {
-               /* Build ID info */
-               handle_statedump_build_id_event(debug_info, event);
-       } else if (event_class->name == debug_info-> q_lib_unload) {
-               handle_lib_unload_event(debug_info, event);
-       }
-
-       /* All events: register debug infos */
-       register_event_debug_infos(debug_info, event);
-
-end:
-       return;
-}
diff --git a/lib/iterator.c b/lib/iterator.c
deleted file mode 100644 (file)
index d439d7b..0000000
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * iterator.c
- *
- * Babeltrace Library
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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 <stdlib.h>
-#include <babeltrace/babeltrace.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/context.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/iterator-internal.h>
-#include <babeltrace/iterator.h>
-#include <babeltrace/prio_heap.h>
-#include <babeltrace/ctf/metadata.h>
-#include <babeltrace/ctf/events.h>
-#include <inttypes.h>
-
-static int babeltrace_filestream_seek(struct ctf_file_stream *file_stream,
-               const struct bt_iter_pos *begin_pos,
-               unsigned long stream_id);
-
-struct stream_saved_pos {
-       /*
-        * Use file_stream pointer to check if the trace collection we
-        * restore to match the one we saved from, for each stream.
-        */
-       struct ctf_file_stream *file_stream;
-       size_t cur_index;       /* current index in packet index */
-       ssize_t offset;         /* offset from base, in bits. EOF for end of file. */
-       uint64_t current_real_timestamp;
-       uint64_t current_cycles_timestamp;
-};
-
-struct bt_saved_pos {
-       struct trace_collection *tc;
-       GArray *stream_saved_pos;       /* Contains struct stream_saved_pos */
-};
-
-static int stream_read_event(struct ctf_file_stream *sin)
-{
-       int ret;
-
-       ret = sin->pos.parent.event_cb(&sin->pos.parent, &sin->parent);
-       if (ret == EOF)
-               return EOF;
-       else if (ret == EAGAIN)
-               /* Stream is inactive for now (live reading). */
-               return EAGAIN;
-       else if (ret) {
-               fprintf(stderr, "[error] Reading event failed.\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-/*
- * Return true if a < b, false otherwise.
- * If time stamps are exactly the same, compare by stream path. This
- * ensures we get the same result between runs on the same trace
- * collection on different environments.
- * The result will be random for memory-mapped traces since there is no
- * fixed path leading to those (they have empty path string).
- */
-static int stream_compare(void *a, void *b)
-{
-       struct ctf_file_stream *s_a = a, *s_b = b;
-
-       if (s_a->parent.real_timestamp < s_b->parent.real_timestamp) {
-               return 1;
-       } else if (likely(s_a->parent.real_timestamp > s_b->parent.real_timestamp)) {
-               return 0;
-       } else {
-               return strcmp(s_a->parent.path, s_b->parent.path);
-       }
-}
-
-void bt_iter_free_pos(struct bt_iter_pos *iter_pos)
-{
-       if (!iter_pos)
-               return;
-
-       if (iter_pos->type == BT_SEEK_RESTORE && iter_pos->u.restore) {
-               if (iter_pos->u.restore->stream_saved_pos) {
-                       g_array_free(
-                               iter_pos->u.restore->stream_saved_pos,
-                               TRUE);
-               }
-               g_free(iter_pos->u.restore);
-       }
-       g_free(iter_pos);
-}
-
-/*
- * seek_file_stream_by_timestamp
- *
- * Browse a filestream by index, if an index contains the timestamp passed in
- * argument, seek inside the corresponding packet it until we find the event we
- * are looking for (either the exact timestamp or the event just after the
- * timestamp).
- *
- * Return 0 if the seek succeded, EOF if we didn't find any packet
- * containing the timestamp, or a positive integer for error.
- *
- * TODO: this should be turned into a binary search! It is currently
- * doing a linear search in the packets. This is a O(n) operation on a
- * very frequent code path.
- */
-static int seek_file_stream_by_timestamp(struct ctf_file_stream *cfs,
-               uint64_t timestamp)
-{
-       struct ctf_stream_pos *stream_pos;
-       struct packet_index *index;
-       int i, ret;
-
-       stream_pos = &cfs->pos;
-       for (i = 0; i < stream_pos->packet_index->len; i++) {
-               index = &g_array_index(stream_pos->packet_index,
-                               struct packet_index, i);
-               if (index->ts_real.timestamp_end < timestamp)
-                       continue;
-
-               stream_pos->packet_seek(&stream_pos->parent, i, SEEK_SET);
-               do {
-                       ret = stream_read_event(cfs);
-               } while (cfs->parent.real_timestamp < timestamp && ret == 0);
-
-               /* Can return either EOF, 0, or error (> 0). */
-               return ret;
-       }
-       /*
-        * Cannot find the timestamp within the stream packets, return
-        * EOF.
-        */
-       return EOF;
-}
-
-/*
- * seek_ctf_trace_by_timestamp : for each file stream, seek to the event with
- * the corresponding timestamp
- *
- * Return 0 on success.
- * If the timestamp is not part of any file stream, return EOF to inform the
- * user the timestamp is out of the scope.
- * On other errors, return positive value.
- */
-static int seek_ctf_trace_by_timestamp(struct ctf_trace *tin,
-               uint64_t timestamp, struct ptr_heap *stream_heap)
-{
-       int i, j, ret;
-       int found = 0;
-       struct bt_trace_descriptor *td = &tin->parent;
-
-       if (td->interval_set) {
-               /*
-                * If this trace has an interval selected, don't allow seeks
-                * before the selected interval. We seek to the start of the
-                * interval, thereby presenting a shorter "virtual" trace.
-                */
-               timestamp = max(timestamp, td->interval_real.timestamp_begin);
-       }
-
-       /* for each stream_class */
-       for (i = 0; i < tin->streams->len; i++) {
-               struct ctf_stream_declaration *stream_class;
-
-               stream_class = g_ptr_array_index(tin->streams, i);
-               if (!stream_class)
-                       continue;
-               /* for each file_stream */
-               for (j = 0; j < stream_class->streams->len; j++) {
-                       struct ctf_stream_definition *stream;
-                       struct ctf_file_stream *cfs;
-
-                       stream = g_ptr_array_index(stream_class->streams, j);
-                       if (!stream)
-                               continue;
-                       cfs = container_of(stream, struct ctf_file_stream,
-                                       parent);
-                       ret = seek_file_stream_by_timestamp(cfs, timestamp);
-                       if (ret == 0) {
-                               /* Add to heap */
-                               ret = bt_heap_insert(stream_heap, cfs);
-                               if (ret) {
-                                       /* Return positive error. */
-                                       return -ret;
-                               }
-                               found = 1;
-                       } else if (ret > 0) {
-                               /*
-                                * Error in seek (not EOF), failure.
-                                */
-                               return ret;
-                       }
-                       /* on EOF just do not put stream into heap. */
-               }
-       }
-
-       return found ? 0 : EOF;
-}
-
-/*
- * Find timestamp of last event in the stream.
- *
- * Return value: 0 if OK, positive error value on error, EOF if no
- * events were found.
- */
-static int find_max_timestamp_ctf_file_stream(struct ctf_file_stream *cfs,
-               uint64_t *timestamp_end)
-{
-       int ret, count = 0, i;
-       uint64_t timestamp = 0;
-       struct ctf_stream_pos *stream_pos;
-
-       stream_pos = &cfs->pos;
-       /*
-        * We start by the last packet, and iterate backwards until we
-        * either find at least one event, or we reach the first packet
-        * (some packets can be empty).
-        */
-       for (i = stream_pos->packet_index->len - 1; i >= 0; i--) {
-               stream_pos->packet_seek(&stream_pos->parent, i, SEEK_SET);
-               count = 0;
-               /* read each event until we reach the end of the stream */
-               do {
-                       ret = stream_read_event(cfs);
-                       if (ret == 0) {
-                               count++;
-                               timestamp = cfs->parent.real_timestamp;
-                       }
-               } while (ret == 0);
-
-               /* Error */
-               if (ret > 0)
-                       goto end;
-               assert(ret == EOF);
-               if (count)
-                       break;
-       }
-
-       if (count) {
-               *timestamp_end = timestamp;
-               ret = 0;
-       } else {
-               /* Return EOF if no events were found */
-               ret = EOF;
-       }
-end:
-       return ret;
-}
-
-/*
- * Find the stream within a stream class that contains the event with
- * the largest timestamp, and save that timestamp.
- *
- * Return 0 if OK, EOF if no events were found in the streams, or
- * positive value on error.
- */
-static int find_max_timestamp_ctf_stream_class(
-               struct ctf_stream_declaration *stream_class,
-               struct ctf_file_stream **cfsp,
-               uint64_t *max_timestamp)
-{
-       int ret = EOF, i, found = 0;
-
-       for (i = 0; i < stream_class->streams->len; i++) {
-               struct ctf_stream_definition *stream;
-               struct ctf_file_stream *cfs;
-               uint64_t current_max_ts = 0;
-
-               stream = g_ptr_array_index(stream_class->streams, i);
-               if (!stream)
-                       continue;
-               cfs = container_of(stream, struct ctf_file_stream, parent);
-               ret = find_max_timestamp_ctf_file_stream(cfs, &current_max_ts);
-               if (ret == EOF)
-                       continue;
-               if (ret != 0)
-                       break;
-               if (current_max_ts >= *max_timestamp) {
-                       *max_timestamp = current_max_ts;
-                       *cfsp = cfs;
-                       found = 1;
-               }
-       }
-       assert(ret >= 0 || ret == EOF);
-       if (found) {
-               return 0;
-       }
-       return ret;
-}
-
-/*
- * seek_last_ctf_trace_collection: seek trace collection to last event.
- *
- * Return 0 if OK, EOF if no events were found, or positive error value
- * on error.
- */
-static int seek_last_ctf_trace_collection(struct trace_collection *tc,
-               struct ctf_file_stream **cfsp)
-{
-       int i, j, ret;
-       int found = 0;
-       uint64_t max_timestamp = 0;
-
-       if (!tc)
-               return 1;
-
-       /* For each trace in the trace_collection */
-       for (i = 0; i < tc->array->len; i++) {
-               struct ctf_trace *tin;
-               struct bt_trace_descriptor *td_read;
-
-               td_read = g_ptr_array_index(tc->array, i);
-               if (!td_read)
-                       continue;
-               tin = container_of(td_read, struct ctf_trace, parent);
-               /* For each stream_class in the trace */
-               for (j = 0; j < tin->streams->len; j++) {
-                       struct ctf_stream_declaration *stream_class;
-
-                       stream_class = g_ptr_array_index(tin->streams, j);
-                       if (!stream_class)
-                               continue;
-                       ret = find_max_timestamp_ctf_stream_class(stream_class,
-                                       cfsp, &max_timestamp);
-                       if (ret > 0)
-                               goto end;
-                       if (ret == 0)
-                               found = 1;
-                       assert(ret == EOF || ret == 0);
-               }
-       }
-       /*
-        * Now we know in which file stream the last event is located,
-        * and we know its timestamp.
-        */
-       if (!found) {
-               ret = EOF;
-       } else {
-               ret = seek_file_stream_by_timestamp(*cfsp, max_timestamp);
-               assert(ret == 0);
-       }
-end:
-       return ret;
-}
-
-int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos)
-{
-       struct trace_collection *tc;
-       int i, ret;
-
-       if (!iter || !iter_pos)
-               return -EINVAL;
-
-       switch (iter_pos->type) {
-       case BT_SEEK_RESTORE:
-               if (!iter_pos->u.restore)
-                       return -EINVAL;
-
-               bt_heap_free(iter->stream_heap);
-               ret = bt_heap_init(iter->stream_heap, 0, stream_compare);
-               if (ret < 0)
-                       goto error_heap_init;
-
-               for (i = 0; i < iter_pos->u.restore->stream_saved_pos->len;
-                               i++) {
-                       struct stream_saved_pos *saved_pos;
-                       struct ctf_stream_pos *stream_pos;
-                       struct ctf_stream_definition *stream;
-
-                       saved_pos = &g_array_index(
-                                       iter_pos->u.restore->stream_saved_pos,
-                                       struct stream_saved_pos, i);
-                       stream = &saved_pos->file_stream->parent;
-                       stream_pos = &saved_pos->file_stream->pos;
-
-                       stream_pos->packet_seek(&stream_pos->parent,
-                                       saved_pos->cur_index, SEEK_SET);
-
-                       /*
-                        * the timestamp needs to be restored after
-                        * packet_seek, because this function resets
-                        * the timestamp to the beginning of the packet
-                        */
-                       stream->real_timestamp = saved_pos->current_real_timestamp;
-                       stream->cycles_timestamp = saved_pos->current_cycles_timestamp;
-                       stream_pos->offset = saved_pos->offset;
-                       stream_pos->last_offset = LAST_OFFSET_POISON;
-
-                       stream->current.real.begin = 0;
-                       stream->current.real.end = 0;
-                       stream->current.cycles.begin = 0;
-                       stream->current.cycles.end = 0;
-
-                       stream->prev.real.begin = 0;
-                       stream->prev.real.end = 0;
-                       stream->prev.cycles.begin = 0;
-                       stream->prev.cycles.end = 0;
-
-                       printf_debug("restored to cur_index = %" PRId64 " and "
-                               "offset = %" PRId64 ", timestamp = %" PRIu64 "\n",
-                               stream_pos->cur_index,
-                               stream_pos->offset, stream->real_timestamp);
-
-                       ret = stream_read_event(saved_pos->file_stream);
-                       if (ret != 0) {
-                               goto error;
-                       }
-
-                       /* Add to heap */
-                       ret = bt_heap_insert(iter->stream_heap,
-                                       saved_pos->file_stream);
-                       if (ret)
-                               goto error;
-               }
-               return 0;
-       case BT_SEEK_TIME:
-               tc = iter->ctx->tc;
-
-               bt_heap_free(iter->stream_heap);
-               ret = bt_heap_init(iter->stream_heap, 0, stream_compare);
-               if (ret < 0)
-                       goto error_heap_init;
-
-               /* for each trace in the trace_collection */
-               for (i = 0; i < tc->array->len; i++) {
-                       struct ctf_trace *tin;
-                       struct bt_trace_descriptor *td_read;
-
-                       td_read = g_ptr_array_index(tc->array, i);
-                       if (!td_read)
-                               continue;
-                       tin = container_of(td_read, struct ctf_trace, parent);
-
-                       ret = seek_ctf_trace_by_timestamp(tin,
-                                       iter_pos->u.seek_time,
-                                       iter->stream_heap);
-                       /*
-                        * Positive errors are failure. Negative value
-                        * is EOF (for which we continue with other
-                        * traces). 0 is success. Note: on EOF, it just
-                        * means that no stream has been added to the
-                        * iterator for that trace, which is fine.
-                        */
-                       if (ret != 0 && ret != EOF)
-                               goto error;
-               }
-               return 0;
-       case BT_SEEK_BEGIN:
-               tc = iter->ctx->tc;
-               bt_heap_free(iter->stream_heap);
-               ret = bt_heap_init(iter->stream_heap, 0, stream_compare);
-               if (ret < 0)
-                       goto error_heap_init;
-
-               for (i = 0; i < tc->array->len; i++) {
-                       struct ctf_trace *tin;
-                       struct bt_trace_descriptor *td_read;
-                       int stream_id;
-
-                       td_read = g_ptr_array_index(tc->array, i);
-                       if (!td_read)
-                               continue;
-                       tin = container_of(td_read, struct ctf_trace, parent);
-
-                       /* Populate heap with each stream */
-                       for (stream_id = 0; stream_id < tin->streams->len;
-                                       stream_id++) {
-                               struct ctf_stream_declaration *stream;
-                               int filenr;
-
-                               stream = g_ptr_array_index(tin->streams,
-                                               stream_id);
-                               if (!stream)
-                                       continue;
-                               for (filenr = 0; filenr < stream->streams->len;
-                                               filenr++) {
-                                       struct ctf_file_stream *file_stream;
-                                       file_stream = g_ptr_array_index(
-                                                       stream->streams,
-                                                       filenr);
-                                       if (!file_stream)
-                                               continue;
-                                       ret = babeltrace_filestream_seek(
-                                                       file_stream, iter_pos,
-                                                       stream_id);
-                                       if (ret != 0 && ret != EOF) {
-                                               goto error;
-                                       }
-                                       if (ret == EOF) {
-                                               /* Do not add EOF streams */
-                                               continue;
-                                       }
-                                       ret = bt_heap_insert(iter->stream_heap, file_stream);
-                                       if (ret)
-                                               goto error;
-                               }
-                       }
-               }
-               break;
-       case BT_SEEK_LAST:
-       {
-               struct ctf_file_stream *cfs = NULL;
-
-               tc = iter->ctx->tc;
-               ret = seek_last_ctf_trace_collection(tc, &cfs);
-               if (ret != 0 || !cfs)
-                       goto error;
-               /* remove all streams from the heap */
-               bt_heap_free(iter->stream_heap);
-               /* Create a new empty heap */
-               ret = bt_heap_init(iter->stream_heap, 0, stream_compare);
-               if (ret < 0)
-                       goto error;
-               /* Insert the stream that contains the last event */
-               ret = bt_heap_insert(iter->stream_heap, cfs);
-               if (ret)
-                       goto error;
-               break;
-       }
-       default:
-               /* not implemented */
-               return -EINVAL;
-       }
-
-       return 0;
-
-error:
-       bt_heap_free(iter->stream_heap);
-error_heap_init:
-       if (bt_heap_init(iter->stream_heap, 0, stream_compare) < 0) {
-               bt_heap_free(iter->stream_heap);
-               g_free(iter->stream_heap);
-               iter->stream_heap = NULL;
-               ret = -ENOMEM;
-       }
-
-       return ret;
-}
-
-struct bt_iter_pos *bt_iter_get_pos(struct bt_iter *iter)
-{
-       struct bt_iter_pos *pos;
-       struct trace_collection *tc;
-       struct ctf_file_stream *file_stream = NULL, *removed;
-       struct ptr_heap iter_heap_copy;
-       int ret;
-
-       if (!iter)
-               return NULL;
-
-       tc = iter->ctx->tc;
-       pos = g_new0(struct bt_iter_pos, 1);
-       pos->type = BT_SEEK_RESTORE;
-       pos->u.restore = g_new0(struct bt_saved_pos, 1);
-       pos->u.restore->tc = tc;
-       pos->u.restore->stream_saved_pos = g_array_new(FALSE, TRUE,
-                       sizeof(struct stream_saved_pos));
-       if (!pos->u.restore->stream_saved_pos)
-               goto error;
-
-       ret = bt_heap_copy(&iter_heap_copy, iter->stream_heap);
-       if (ret < 0)
-               goto error_heap;
-
-       /* iterate over each stream in the heap */
-       file_stream = bt_heap_maximum(&iter_heap_copy);
-       while (file_stream != NULL) {
-               struct stream_saved_pos saved_pos;
-
-               assert(file_stream->pos.last_offset != LAST_OFFSET_POISON);
-               saved_pos.offset = file_stream->pos.last_offset;
-               saved_pos.file_stream = file_stream;
-               saved_pos.cur_index = file_stream->pos.cur_index;
-
-               saved_pos.current_real_timestamp = file_stream->parent.real_timestamp;
-               saved_pos.current_cycles_timestamp = file_stream->parent.cycles_timestamp;
-
-               g_array_append_val(
-                               pos->u.restore->stream_saved_pos,
-                               saved_pos);
-
-               printf_debug("stream : %" PRIu64 ", cur_index : %zd, "
-                               "offset : %zd, "
-                               "timestamp = %" PRIu64 "\n",
-                               file_stream->parent.stream_id,
-                               saved_pos.cur_index, saved_pos.offset,
-                               saved_pos.current_real_timestamp);
-
-               /* remove the stream from the heap copy */
-               removed = bt_heap_remove(&iter_heap_copy);
-               assert(removed == file_stream);
-
-               file_stream = bt_heap_maximum(&iter_heap_copy);
-       }
-       bt_heap_free(&iter_heap_copy);
-       return pos;
-
-error_heap:
-       g_array_free(pos->u.restore->stream_saved_pos, TRUE);
-error:
-       g_free(pos);
-       return NULL;
-}
-
-struct bt_iter_pos *bt_iter_create_time_pos(struct bt_iter *unused,
-               uint64_t timestamp)
-{
-       struct bt_iter_pos *pos;
-
-       pos = g_new0(struct bt_iter_pos, 1);
-       pos->type = BT_SEEK_TIME;
-       pos->u.seek_time = timestamp;
-       return pos;
-}
-
-/*
- * babeltrace_filestream_seek: seek a filestream to given position.
- *
- * The stream_id parameter is only useful for BT_SEEK_RESTORE.
- */
-static int babeltrace_filestream_seek(struct ctf_file_stream *file_stream,
-               const struct bt_iter_pos *begin_pos,
-               unsigned long stream_id)
-{
-       int ret = 0;
-
-       if (!file_stream || !begin_pos)
-               return -EINVAL;
-
-       switch (begin_pos->type) {
-       case BT_SEEK_CUR:
-               /*
-                * just insert into the heap we should already know
-                * the timestamps
-                */
-               break;
-       case BT_SEEK_BEGIN:
-               file_stream->pos.packet_seek(&file_stream->pos.parent,
-                               0, SEEK_SET);
-               ret = stream_read_event(file_stream);
-               break;
-       case BT_SEEK_TIME:
-       case BT_SEEK_RESTORE:
-       default:
-               assert(0); /* Not yet defined */
-       }
-
-       return ret;
-}
-
-int bt_iter_add_trace(struct bt_iter *iter,
-               struct bt_trace_descriptor *td_read)
-{
-       struct ctf_trace *tin;
-       int stream_id, ret = 0;
-
-       tin = container_of(td_read, struct ctf_trace, parent);
-
-       /* Populate heap with each stream */
-       for (stream_id = 0; stream_id < tin->streams->len;
-                       stream_id++) {
-               struct ctf_stream_declaration *stream;
-               int filenr;
-
-               stream = g_ptr_array_index(tin->streams, stream_id);
-               if (!stream)
-                       continue;
-               for (filenr = 0; filenr < stream->streams->len;
-                               filenr++) {
-                       struct ctf_file_stream *file_stream;
-                       struct bt_iter_pos pos;
-
-                       file_stream = g_ptr_array_index(stream->streams,
-                                       filenr);
-                       if (!file_stream)
-                               continue;
-
-                       pos.type = BT_SEEK_BEGIN;
-                       ret = babeltrace_filestream_seek(file_stream,
-                                       &pos, stream_id);
-
-                       if (ret == EOF) {
-                               ret = 0;
-                               continue;
-                       } else if (ret != 0 && ret != EAGAIN) {
-                               goto error;
-                       }
-                       /* Add to heap */
-                       ret = bt_heap_insert(iter->stream_heap, file_stream);
-                       if (ret)
-                               goto error;
-               }
-       }
-
-error:
-       return ret;
-}
-
-int bt_iter_init(struct bt_iter *iter,
-               struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos)
-{
-       int i;
-       int ret = 0;
-
-       if (!iter || !ctx || !ctx->tc || !ctx->tc->array)
-               return -EINVAL;
-
-       if (ctx->current_iterator) {
-               ret = -1;
-               goto error_ctx;
-       }
-
-       iter->stream_heap = g_new(struct ptr_heap, 1);
-       iter->end_pos = end_pos;
-       bt_context_get(ctx);
-       iter->ctx = ctx;
-
-       ret = bt_heap_init(iter->stream_heap, 0, stream_compare);
-       if (ret < 0)
-               goto error_heap_init;
-
-       for (i = 0; i < ctx->tc->array->len; i++) {
-               struct bt_trace_descriptor *td_read;
-
-               td_read = g_ptr_array_index(ctx->tc->array, i);
-               if (!td_read)
-                       continue;
-               ret = bt_iter_add_trace(iter, td_read);
-               if (ret < 0)
-                       goto error;
-       }
-
-       ctx->current_iterator = iter;
-       if (begin_pos && begin_pos->type != BT_SEEK_BEGIN) {
-               ret = bt_iter_set_pos(iter, begin_pos);
-               if (ret) {
-                       goto error;
-               }
-       }
-
-       return ret;
-
-error:
-       bt_heap_free(iter->stream_heap);
-error_heap_init:
-       g_free(iter->stream_heap);
-       iter->stream_heap = NULL;
-error_ctx:
-       return ret;
-}
-
-struct bt_iter *bt_iter_create(struct bt_context *ctx,
-               const struct bt_iter_pos *begin_pos,
-               const struct bt_iter_pos *end_pos)
-{
-       struct bt_iter *iter;
-       int ret;
-
-       if (!ctx)
-               return NULL;
-
-       iter = g_new0(struct bt_iter, 1);
-       ret = bt_iter_init(iter, ctx, begin_pos, end_pos);
-       if (ret) {
-               g_free(iter);
-               return NULL;
-       }
-       return iter;
-}
-
-void bt_iter_fini(struct bt_iter *iter)
-{
-       assert(iter);
-       if (iter->stream_heap) {
-               bt_heap_free(iter->stream_heap);
-               g_free(iter->stream_heap);
-       }
-       iter->ctx->current_iterator = NULL;
-       bt_context_put(iter->ctx);
-}
-
-void bt_iter_destroy(struct bt_iter *iter)
-{
-       assert(iter);
-       bt_iter_fini(iter);
-       g_free(iter);
-}
-
-int bt_iter_next(struct bt_iter *iter)
-{
-       struct ctf_file_stream *file_stream, *removed;
-       int ret;
-       bool event_outside_interval = false;
-
-       if (!iter)
-               return -EINVAL;
-
-       file_stream = bt_heap_maximum(iter->stream_heap);
-       if (!file_stream) {
-               /* end of file for all streams */
-               ret = 0;
-               goto end;
-       }
-
-       ret = stream_read_event(file_stream);
-       if (file_stream->pos.parent.trace &&
-                       file_stream->pos.parent.trace->interval_set) {
-               event_outside_interval =
-                               file_stream->parent.real_timestamp >
-                               file_stream->pos.parent.trace->interval_real.timestamp_end;
-       }
-       if (ret == EOF || event_outside_interval) {
-               removed = bt_heap_remove(iter->stream_heap);
-               assert(removed == file_stream);
-               ret = 0;
-               goto end;
-       } else if (ret == EAGAIN) {
-               /*
-                * Live streaming: the stream is inactive for now, we
-                * just updated the timestamp_end to skip over this
-                * stream up to a certain point in time.
-                *
-                * Since we can't guarantee that a stream will ever have
-                * any activity, we can't rely on the fact that
-                * bt_iter_next will be called for each stream and deal
-                * with inactive streams. So instead, we return 0 here
-                * to the caller and let the read API handle the
-                * retry case.
-                */
-               ret = 0;
-               goto reinsert;
-       } else if (ret) {
-               goto end;
-       }
-
-reinsert:
-       /* Reinsert the file stream into the heap, and rebalance. */
-       removed = bt_heap_replace_max(iter->stream_heap, file_stream);
-       assert(removed == file_stream);
-end:
-       return ret;
-}
diff --git a/lib/registry.c b/lib/registry.c
deleted file mode 100644 (file)
index bc2be95..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * BabelTrace
- *
- * Format Registry
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <glib.h>
-#include <errno.h>
-#include <stdio.h>
-#include <assert.h>
-
-struct walk_data {
-       FILE *fp;
-       int iter;
-};
-
-/*
- * Format registry hash table contains the registered formats. Format
- * registration is typically performed by a format plugin.
- */
-static GHashTable *format_registry;
-static int format_refcount;
-static int init_done;
-
-static __attribute__((constructor)) void format_init(void);
-
-static
-void format_refcount_inc(void)
-{
-       format_refcount++;
-}
-
-static
-void format_cleanup(void)
-{
-       if (format_registry)
-               g_hash_table_destroy(format_registry);
-}
-
-static
-void format_refcount_dec(void)
-{
-       if (!--format_refcount)
-               format_cleanup();
-}
-
-struct bt_format *bt_lookup_format(bt_intern_str name)
-{
-       if (!init_done)
-               return NULL;
-
-       return g_hash_table_lookup(format_registry,
-                                  (gconstpointer) GUINT_TO_POINTER(name));
-}
-
-static void show_format(gpointer key, gpointer value, gpointer user_data)
-{
-       struct walk_data *data = user_data;
-
-       fprintf(data->fp, "%s%s", data->iter ? ", " : "",
-               g_quark_to_string((GQuark) GPOINTER_TO_UINT(key)));
-       data->iter++;
-}
-
-void bt_fprintf_format_list(FILE *fp)
-{
-       struct walk_data data;
-
-       assert(fp);
-
-       data.fp = fp;
-       data.iter = 0;
-
-       fprintf(fp, "Formats available: ");
-       if (!init_done)
-               return;
-       g_hash_table_foreach(format_registry, show_format, &data);
-       if (data.iter == 0)
-               fprintf(fp, "<none>");
-       fprintf(fp, ".\n");
-}
-
-int bt_register_format(struct bt_format *format)
-{
-       if (!format)
-               return -EINVAL;
-
-       if (!init_done)
-               format_init();
-
-       if (bt_lookup_format(format->name))
-               return -EEXIST;
-
-       format_refcount_inc();
-       g_hash_table_insert(format_registry,
-                           GUINT_TO_POINTER(format->name),
-                           format);
-       return 0;
-}
-
-void bt_unregister_format(struct bt_format *format)
-{
-       assert(bt_lookup_format(format->name));
-       g_hash_table_remove(format_registry,
-                           GUINT_TO_POINTER(format->name));
-       format_refcount_dec();
-}
-
-/*
- * We cannot assume that the constructor and destructor order will be
- * right: another library might be loaded before us, and initialize us
- * from bt_register_format(). This is why we use a reference count to
- * handle cleanup of this module. The format_finalize destructor
- * refcount decrement matches format_init refcount increment.
- */
-static __attribute__((constructor))
-void format_init(void)
-{
-       if (init_done)
-               return;
-       format_refcount_inc();
-       format_registry = g_hash_table_new(g_direct_hash, g_direct_equal);
-       assert(format_registry);
-       init_done = 1;
-}
-
-static __attribute__((destructor))
-void format_finalize(void)
-{
-       format_refcount_dec();
-}
diff --git a/lib/trace-collection.c b/lib/trace-collection.c
deleted file mode 100644 (file)
index 213ece5..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * trace-collection.c
- *
- * Babeltrace Library
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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.h>
-#include <babeltrace/format.h>
-#include <babeltrace/context.h>
-#include <babeltrace/ctf/types.h>
-#include <babeltrace/ctf-text/types.h>
-#include <babeltrace/trace-collection.h>
-#include <babeltrace/ctf-ir/metadata.h>        /* for clocks */
-#include <babeltrace/clock-internal.h>
-
-#include <inttypes.h>
-
-struct clock_match {
-       GHashTable *clocks;
-       struct ctf_clock *clock_match;
-       struct trace_collection *tc;
-};
-
-static void check_clock_match(gpointer key, gpointer value, gpointer user_data)
-{
-       struct clock_match *match = user_data;
-       struct ctf_clock *clock_a = value, *clock_b;
-
-       if (clock_a->absolute) {
-               /*
-                * Absolute time references, such as NTP, are looked up
-                * by clock name.
-                */
-               clock_b = g_hash_table_lookup(match->clocks,
-                       GUINT_TO_POINTER(clock_a->name));
-               if (clock_b) {
-                       match->clock_match = clock_b;
-                       return;
-               }
-       } else if (clock_a->uuid != 0) {
-               /*
-                * Lookup the the trace clocks into the collection
-                * clocks.
-                */
-               clock_b = g_hash_table_lookup(match->clocks,
-                       GUINT_TO_POINTER(clock_a->uuid));
-               if (clock_b) {
-                       match->clock_match = clock_b;
-                       return;
-               }
-       }
-}
-
-static void clock_add(gpointer key, gpointer value, gpointer user_data)
-{
-       struct clock_match *clock_match = user_data;
-       GHashTable *tc_clocks = clock_match->clocks;
-       struct ctf_clock *t_clock = value;
-       GQuark v;
-
-       if (t_clock->absolute)
-               v = t_clock->name;
-       else
-               v = t_clock->uuid;
-       if (v) {
-               struct ctf_clock *tc_clock;
-
-               tc_clock = g_hash_table_lookup(tc_clocks,
-                               GUINT_TO_POINTER(v));
-               if (!tc_clock) {
-                       /*
-                        * For now we only support CTF that has one
-                        * single clock uuid or name (absolute ref) per
-                        * trace.
-                        */
-                       if (g_hash_table_size(tc_clocks) > 0) {
-                               fprintf(stderr, "[error] Only CTF traces with a single clock description are supported by this babeltrace version.\n");
-                       }
-                       if (!clock_match->tc->offset_nr) {
-                               clock_match->tc->offset_first = clock_offset_ns(t_clock);
-                               clock_match->tc->delta_offset_first_sum = 0;
-                               clock_match->tc->offset_nr++;
-                               clock_match->tc->single_clock_offset_avg =
-                                       clock_match->tc->offset_first;
-                       }
-                       g_hash_table_insert(tc_clocks,
-                               GUINT_TO_POINTER(v),
-                               value);
-               } else if (!t_clock->absolute) {
-                       int64_t diff_ns;
-
-                       /*
-                        * For non-absolute clocks, check that the
-                        * offsets match. If not, warn the user that we
-                        * do an arbitrary choice.
-                        */
-                       diff_ns = clock_offset_ns(tc_clock) - clock_offset_ns(t_clock);
-                       printf_debug("Clock \"%s\" offset between traces has a delta of %" PRIu64 " ns.",
-                               g_quark_to_string(tc_clock->name),
-                               diff_ns < 0 ? -diff_ns : diff_ns);
-                       if (diff_ns > 10000 || diff_ns < -10000) {
-                               fprintf(stderr, "[warning] Clock \"%s\" offset differs between traces (delta %" PRIu64 " ns). Using average.\n",
-                                       g_quark_to_string(tc_clock->name),
-                                       diff_ns < 0 ? -diff_ns : diff_ns);
-                       }
-                       /* Compute average */
-                       clock_match->tc->delta_offset_first_sum +=
-                               clock_offset_ns(t_clock) - clock_match->tc->offset_first;
-                       clock_match->tc->offset_nr++;
-                       clock_match->tc->single_clock_offset_avg =
-                               clock_match->tc->offset_first
-                               + (clock_match->tc->delta_offset_first_sum / clock_match->tc->offset_nr);
-                       /* Time need to use offset average */
-                       clock_match->tc->clock_use_offset_avg = 1;
-               }
-       }
-}
-
-/*
- * Whenever we add a trace to the trace collection, check that we can
- * correlate this trace with at least one other clock in the trace and
- * convert the index from cycles to real time.
- */
-int bt_trace_collection_add(struct trace_collection *tc,
-                       struct bt_trace_descriptor *trace)
-{
-       if (!tc || !trace)
-               return -EINVAL;
-
-       if (!trace->clocks)
-               return 0;
-
-       if (tc->array->len > 1) {
-               struct clock_match clock_match = {
-                       .clocks = tc->clocks,
-                       .clock_match = NULL,
-                       .tc = NULL,
-               };
-
-               /*
-                * With two or more traces, we need correlation info
-                * avalable.
-                */
-               g_hash_table_foreach(trace->clocks,
-                               check_clock_match,
-                               &clock_match);
-               if (!clock_match.clock_match) {
-                       fprintf(stderr, "[error] No clocks can be correlated and multiple traces are added to the collection. If you are certain those traces can be correlated, try using \"--clock-force-correlate\".\n");
-                       goto error;
-               }
-       }
-
-       g_ptr_array_add(tc->array, trace);
-       trace->collection = tc;
-
-       {
-               struct clock_match clock_match = {
-                       .clocks = tc->clocks,
-                       .clock_match = NULL,
-                       .tc = tc,
-               };
-
-               /*
-                * Add each clock from the trace clocks into the trace
-                * collection clocks.
-                */
-               g_hash_table_foreach(trace->clocks,
-                               clock_add,
-                               &clock_match);
-       }
-
-       return 0;
-error:
-       return -EPERM;
-}
-
-int bt_trace_collection_remove(struct trace_collection *tc,
-                           struct bt_trace_descriptor *td)
-{
-       if (!tc || !td)
-               return -EINVAL;
-
-       if (g_ptr_array_remove(tc->array, td)) {
-               return 0;
-       } else {
-               return -1;
-       }
-
-}
-
-void bt_init_trace_collection(struct trace_collection *tc)
-{
-       assert(tc);
-       tc->array = g_ptr_array_new();
-       tc->clocks = g_hash_table_new(g_direct_hash, g_direct_equal);
-       tc->single_clock_offset_avg = 0;
-       tc->offset_first = 0;
-       tc->delta_offset_first_sum = 0;
-       tc->offset_nr = 0;
-}
-
-/*
- * bt_finalize_trace_collection() closes the opened traces for read
- * and free the memory allocated for trace collection
- */
-void bt_finalize_trace_collection(struct trace_collection *tc)
-{
-       assert(tc);
-       g_ptr_array_free(tc->array, TRUE);
-       g_hash_table_destroy(tc->clocks);
-}
diff --git a/lib/trace-handle.c b/lib/trace-handle.c
deleted file mode 100644 (file)
index 4c41d2f..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * trace_handle.c
- *
- * Babeltrace Library
- *
- * Copyright 2012 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *         Julien Desfossez <julien.desfossez@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 <stdlib.h>
-#include <babeltrace/babeltrace.h>
-#include <babeltrace/context.h>
-#include <babeltrace/context-internal.h>
-#include <babeltrace/trace-handle.h>
-#include <babeltrace/trace-handle-internal.h>
-
-struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx)
-{
-       struct bt_trace_handle *th;
-
-       if (!ctx)
-               return NULL;
-
-       th = g_new0(struct bt_trace_handle, 1);
-       th->id = ctx->last_trace_handle_id++;
-       return th;
-}
-
-void bt_trace_handle_destroy(struct bt_trace_handle *th)
-{
-       g_free(th);
-}
-
-const char *bt_trace_handle_get_path(struct bt_context *ctx, int handle_id)
-{
-       struct bt_trace_handle *handle;
-
-       if (!ctx)
-               return NULL;
-
-       handle = g_hash_table_lookup(ctx->trace_handles,
-                       GUINT_TO_POINTER(handle_id));
-       if (!handle)
-               return NULL;
-       return handle->path;
-}
-
-int bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
-               int handle_id, enum bt_clock_type type,
-               int64_t *timestamp)
-{
-       struct bt_trace_handle *handle;
-       int ret = 0;
-
-       if (!ctx || !timestamp)
-               return -1;
-
-       handle = g_hash_table_lookup(ctx->trace_handles,
-                       GUINT_TO_POINTER(handle_id));
-       if (!handle) {
-               ret = -1;
-               goto end;
-       }
-       if (type == BT_CLOCK_REAL) {
-               *timestamp = handle->real_timestamp_begin;
-       } else if (type == BT_CLOCK_CYCLES) {
-               *timestamp = handle->cycles_timestamp_begin;
-       } else {
-               ret = -1;
-       }
-
-end:
-       return ret;
-}
-
-int bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
-               int handle_id, enum bt_clock_type type,
-               int64_t *timestamp)
-{
-       struct bt_trace_handle *handle;
-       int ret = 0;
-
-       if (!ctx || !timestamp)
-               return -1;
-
-       handle = g_hash_table_lookup(ctx->trace_handles,
-                       GUINT_TO_POINTER(handle_id));
-       if (!handle) {
-               ret = -1;
-               goto end;
-       }
-       if (type == BT_CLOCK_REAL) {
-               *timestamp = handle->real_timestamp_end;
-       } else if (type == BT_CLOCK_CYCLES) {
-               *timestamp = handle->cycles_timestamp_end;
-       } else {
-               ret = -1;
-       }
-
-end:
-       return ret;
-}
index bd665a11140357d3143fe4329c05e2ba4ebd2cc2..f53a6ab34060b9fb59c888cc576e6eaf184262f3 100644 (file)
@@ -13,6 +13,5 @@ libbabeltrace_plugin_ctf_la_LDFLAGS = \
 
 libbabeltrace_plugin_ctf_la_LIBADD = \
        $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
        fs/libbabeltrace-plugin-ctf-fs.la \
        lttng-live/libbabeltrace-plugin-ctf-lttng-live.la
index 1934b24dce782871784d0586f714f0f226052d9c..eb9c75543b239c4db0b6e403c283499f8f4469ef 100644 (file)
@@ -34,7 +34,7 @@
 #include <glib.h>
 #include <errno.h>
 #include <inttypes.h>
-#include <babeltrace/list.h>
+#include <babeltrace/list-internal.h>
 #include <babeltrace/babeltrace-internal.h>
 #include "scanner.h"
 #include "parser.h"
@@ -940,12 +940,12 @@ void yyerror(struct ctf_scanner *scanner, yyscan_t yyscanner, const char *str)
                "token \"%s\": %s\n",
                yyget_text(scanner->scanner), str);
 }
+
 BT_HIDDEN
 int yywrap(void)
 {
        return 1;
-} 
+}
 
 #define reparent_error(scanner, str)                           \
 do {                                                           \
@@ -1105,7 +1105,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %type <n> direct_declarator
 %type <n> type_declarator
 %type <n> direct_type_declarator
-%type <n> pointer      
+%type <n> pointer
 %type <n> ctf_assignment_expression_list
 %type <n> ctf_assignment_expression
 
@@ -2473,7 +2473,7 @@ direct_type_declarator:
                }
        ;
 
-pointer:       
+pointer:
                STAR
                {
                        $$ = make_node(scanner, NODE_POINTER);
index 14e9690be1ffddfb40b94c2d972f997cd2159ef1..c16c97065a868c5676c61289c2da091f58929fde 100644 (file)
 #include <glib.h>
 #include <inttypes.h>
 #include <errno.h>
-#include <babeltrace/ctf/metadata.h>
 #include <babeltrace/compat/uuid.h>
 #include <babeltrace/endian.h>
 #include <babeltrace/ref.h>
-#include <babeltrace/ctf/events-internal.h>
 #include <babeltrace/ctf-ir/trace.h>
 #include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf-ir/event.h>
index b9cca03f513f1cb725a169dca33a4c73fbf8c571..156e375c8cb8c6c63fdb5eff44d6773c927dadef 100644 (file)
@@ -13,5 +13,4 @@ libbabeltrace_plugin_muxer_la_LDFLAGS = \
        -version-info $(BABELTRACE_LIBRARY_VERSION)
 
 libbabeltrace_plugin_muxer_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+       $(top_builddir)/lib/libbabeltrace.la
index 0abdfb63834b7ebca60769c85ef3e48274aa991e..ecf823674d6c783318f35d883fd75f2e7f3a6a5e 100644 (file)
@@ -16,5 +16,4 @@ libbabeltrace_plugin_ctf_text_la_LDFLAGS = \
 
 libbabeltrace_plugin_ctf_text_la_LIBADD = \
        $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
        $(top_builddir)/common/libbabeltrace-common.la
index 99188070aadbc1a3de56ab1355b81ee9b59fc31a..8a9d1af2f9b06be7fa7cb502954664e530964149 100644 (file)
@@ -10,6 +10,5 @@ libbabeltrace_plugin_utils_la_LDFLAGS = \
        -version-info $(BABELTRACE_LIBRARY_VERSION)
 libbabeltrace_plugin_utils_la_LIBADD = \
        $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la \
        dummy/libbabeltrace-plugin-dummy-cc.la \
        trimmer/libbabeltrace-plugin-dummy-cc.la
index 62c4f05484904ece84944242512ec147519d3dd3..d2e23a77b3d0fad8dbf3c0d491f02df7c1818dfa 100644 (file)
@@ -15,5 +15,4 @@ libbabeltrace_plugin_ctf_writer_la_LDFLAGS = \
        -version-info $(BABELTRACE_LIBRARY_VERSION)
 
 libbabeltrace_plugin_ctf_writer_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+       $(top_builddir)/lib/libbabeltrace.la
index 7bb413ab9bb0fce4b7bd793ed3751f9fde4e6074..f15d6d85069bd5d9596746426aad216dbadc5ab0 100644 (file)
@@ -7,7 +7,6 @@ LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
 TESTS = bin/test_trace_read \
        bin/test_trace_read \
        bin/test_packet_seq_num \
-       bin/test_formats \
        bin/test_convert_args \
        bin/intersection/test_intersection \
        lib/test_bitfield \
index 0c80a42c1e453c303e07fc5e058a77ab7a2d763e..dc603904243a1e6cef5457f6d0cca36ffb9ca009 100644 (file)
@@ -1,3 +1,2 @@
 SUBDIRS = intersection
-check_SCRIPTS = test_trace_read test_packet_seq_num test_formats \
-       test_convert_args
+check_SCRIPTS = test_trace_read test_packet_seq_num test_convert_args
index cd53661eac9d051e58ea1bad50c5c8899c6cafea..c9c25a998ab06c33ed9eb3a976ac92b095af89ed 100644 (file)
@@ -10,12 +10,8 @@ noinst_LTLIBRARIES = libtestcommon.la
 # -Wl,--no-as-needed is needed for recent gold linker who seems to think
 # it knows better and considers libraries with constructors having
 # side-effects as dead code.
-test_seek_LDFLAGS = $(LD_NO_AS_NEEDED)
 COMMON_TEST_LDADD = $(LIBTAP) $(builddir)/libtestcommon.la \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
-
-test_seek_LDADD = $(COMMON_TEST_LDADD)
+       $(top_builddir)/lib/libbabeltrace.la
 
 test_bitfield_LDADD = $(LIBTAP) $(builddir)/libtestcommon.la
 
@@ -40,12 +36,11 @@ test_graph_topo_LDADD = $(COMMON_TEST_LDADD)
 
 test_cc_prio_map_LDADD = $(COMMON_TEST_LDADD)
 
-noinst_PROGRAMS = test_seek test_bitfield test_ctf_writer test_bt_values \
+noinst_PROGRAMS = test_bitfield test_ctf_writer test_bt_values \
        test_ctf_ir_ref test_bt_ctf_field_type_validation test_ir_visit \
        test_trace_listener test_bt_notification_heap test_plugin test_graph_topo \
        test_cc_prio_map
 
-test_seek_SOURCES = test_seek.c
 test_bitfield_SOURCES = test_bitfield.c
 test_ctf_writer_SOURCES = test_ctf_writer.c
 test_bt_values_SOURCES = test_bt_values.c
@@ -58,9 +53,7 @@ test_plugin_SOURCES = test_plugin.c
 test_graph_topo_SOURCES = test_graph_topo.c
 test_cc_prio_map_SOURCES = test_cc_prio_map.c
 
-check_SCRIPTS = test_seek_big_trace \
-               test_seek_empty_packet \
-               test_ctf_writer_complete \
+check_SCRIPTS = test_ctf_writer_complete \
                test_plugin_complete
 
 if ENABLE_DEBUG_INFO
index 0b8ebdf1206296691a84f963feb0cb44f5c2cd07..8c2829a365eb7f6e90f4a63c8fa583cdd7936f4c 100644 (file)
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <babeltrace/context.h>
-#include <babeltrace/iterator.h>
 #include <babeltrace/compat/dirent.h>
 #include <babeltrace/compat/limits.h>
 #include <sys/stat.h>
 
-struct bt_context *create_context_with_path(const char *path)
-{
-       struct bt_context *ctx;
-       int ret;
-
-       ctx = bt_context_create();
-       if (!ctx) {
-               return NULL;
-       }
-
-       ret = bt_context_add_trace(ctx, path, "ctf", NULL, NULL, NULL);
-       if (ret < 0) {
-               bt_context_put(ctx);
-               return NULL;
-       }
-       return ctx;
-}
-
 void recursive_rmdir(const char *path)
 {
        struct dirent *entry;
index 06ea63b56047a05fae93e8ed9c74bf27d42f3d7a..daa224f211ea100e142a9833258b191fb711b10d 100644 (file)
@@ -25,6 +25,5 @@
 struct bt_context;
 
 void recursive_rmdir(const char *path);
-struct bt_context *create_context_with_path(const char *path);
 
 #endif /* _TESTS_COMMON_H */
index 1909865637c5a8eda993d1f0fd1d5481bf0609c0..da148bf20cb71e851faf1632d5e65851bf06dd9d 100644 (file)
@@ -6,12 +6,10 @@ noinst_LTLIBRARIES = plugin-minimal.la plugin-sfs.la
 plugin_minimal_la_SOURCES = minimal.c
 plugin_minimal_la_LDFLAGS = -rpath / -avoid-version -module
 plugin_minimal_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+       $(top_builddir)/lib/libbabeltrace.la
 
 # source/filter/sink plugin
 plugin_sfs_la_SOURCES = sfs.c
 plugin_sfs_la_LDFLAGS = -rpath / -avoid-version -module
 plugin_sfs_la_LIBADD = \
-       $(top_builddir)/lib/libbabeltrace.la \
-       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+       $(top_builddir)/lib/libbabeltrace.la
index 649f559e393dd0d1f9437b496297f4eddd945a95..3726b44bd604f37a0fc45f7c984cfde2a326c145 100644 (file)
@@ -511,6 +511,9 @@ static void create_user_full(struct user *user)
 
        user->writer = bt_ctf_writer_create(trace_path);
        assert(user->writer);
+       ret = bt_ctf_writer_set_byte_order(user->writer,
+               BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+       assert(ret == 0);
        user->tc = bt_ctf_writer_get_trace(user->writer);
        assert(user->tc);
        user->sc = bt_ctf_stream_class_create("sc");
@@ -521,6 +524,7 @@ static void create_user_full(struct user *user)
        assert(!ret);
        ret = bt_ctf_stream_class_set_clock(user->sc, clock);
        assert(!ret);
+       BT_PUT(clock);
        user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
        assert(user->stream);
        user->ec = bt_ctf_event_class_create("ec");
index 724133e21ea4be78f96f774cead375d40f249601..d139b4ffba0fbbd4d60ce73928b9eb081da7e8de 100644 (file)
@@ -60,7 +60,7 @@
 #define DEFAULT_CLOCK_TIME 0
 #define DEFAULT_CLOCK_VALUE 0
 
-#define NR_TESTS 602
+#define NR_TESTS 601
 
 static int64_t current_time = 42;
 
@@ -86,123 +86,6 @@ end:
        return ret;
 }
 
-static
-void validate_metadata(char *parser_path, char *metadata_path)
-{
-       int ret = 0;
-       char parser_output_path[] = "/tmp/parser_output_XXXXXX";
-       int parser_output_fd = -1, metadata_fd = -1;
-
-       if (!metadata_path) {
-               ret = -1;
-               goto result;
-       }
-
-       parser_output_fd = mkstemp(parser_output_path);
-       metadata_fd = open(metadata_path, O_RDONLY);
-
-       unlink(parser_output_path);
-
-       if (parser_output_fd == -1 || metadata_fd == -1) {
-               diag("Failed create temporary files for metadata parsing.");
-               ret = -1;
-               goto result;
-       }
-
-       pid_t pid = fork();
-       if (pid) {
-               int status = 0;
-               waitpid(pid, &status, 0);
-               ret = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
-       } else {
-               /* ctf-parser-test expects a metadata string on stdin. */
-               ret = dup2(metadata_fd, STDIN_FILENO);
-               if (ret < 0) {
-                       perror("# dup2 metadata_fd to STDIN");
-                       goto result;
-               }
-
-               ret = dup2(parser_output_fd, STDOUT_FILENO);
-               if (ret < 0) {
-                       perror("# dup2 parser_output_fd to STDOUT");
-                       goto result;
-               }
-
-               ret = dup2(parser_output_fd, STDERR_FILENO);
-               if (ret < 0) {
-                       perror("# dup2 parser_output_fd to STDERR");
-                       goto result;
-               }
-
-               execl(parser_path, "ctf-parser-test", NULL);
-               perror("# Could not launch the ctf metadata parser process");
-               exit(-1);
-       }
-result:
-       ok(ret == 0, "Metadata string is valid");
-
-       if (ret && metadata_fd >= 0 && parser_output_fd >= 0) {
-               char *line;
-               size_t len = METADATA_LINE_SIZE;
-               FILE *metadata_fp = NULL, *parser_output_fp = NULL;
-
-               metadata_fp = fdopen(metadata_fd, "r");
-               if (!metadata_fp) {
-                       perror("fdopen on metadata_fd");
-                       goto close_fp;
-               }
-               metadata_fd = -1;
-
-               parser_output_fp = fdopen(parser_output_fd, "r");
-               if (!parser_output_fp) {
-                       perror("fdopen on parser_output_fd");
-                       goto close_fp;
-               }
-               parser_output_fd = -1;
-
-               line = malloc(len);
-               if (!line) {
-                       diag("malloc failure");
-               }
-
-               rewind(metadata_fp);
-
-               /* Output the metadata and parser output as diagnostic */
-               while (bt_getline(&line, &len, metadata_fp) > 0) {
-                       fprintf(stderr, "# %s", line);
-               }
-
-               rewind(parser_output_fp);
-               while (bt_getline(&line, &len, parser_output_fp) > 0) {
-                       fprintf(stderr, "# %s", line);
-               }
-
-               free(line);
-close_fp:
-               if (metadata_fp) {
-                       if (fclose(metadata_fp)) {
-                               diag("fclose failure");
-                       }
-               }
-               if (parser_output_fp) {
-                       if (fclose(parser_output_fp)) {
-                               diag("fclose failure");
-                       }
-               }
-       }
-
-       if (parser_output_fd >= 0) {
-               if (close(parser_output_fd)) {
-                       diag("close error");
-               }
-       }
-       if (metadata_fd >= 0) {
-               if (close(metadata_fd)) {
-                       diag("close error");
-               }
-       }
-}
-
 static
 void validate_trace(char *parser_path, char *trace_path)
 {
@@ -2683,6 +2566,8 @@ void test_create_writer_vs_non_writer_mode(void)
        /* Create writer, writer stream class, stream, and clock */
        writer = bt_ctf_writer_create(trace_path);
        assert(writer);
+       ret = bt_ctf_writer_set_byte_order(writer, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+       assert(!ret);
        writer_trace = bt_ctf_writer_get_trace(writer);
        ok(writer_trace, "bt_ctf_writer_get_trace() returns a trace");
        writer_sc = bt_ctf_stream_class_create("writer_sc");
@@ -2704,6 +2589,9 @@ void test_create_writer_vs_non_writer_mode(void)
        /* Create non-writer trace, stream class, stream, and clock */
        non_writer_trace = bt_ctf_trace_create();
        assert(non_writer_trace);
+       ret = bt_ctf_trace_set_byte_order(non_writer_trace,
+               BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+       assert(!ret);
        non_writer_sc = bt_ctf_stream_class_create("nonwriter_sc");
        assert(non_writer_sc);
        ret = bt_ctf_stream_class_set_event_header_type(non_writer_sc,
@@ -2924,8 +2812,8 @@ int main(int argc, char **argv)
        int64_t ret_int64_t;
        struct bt_value *obj;
 
-       if (argc < 3) {
-               printf("Usage: tests-ctf-writer path_to_ctf_parser_test path_to_babeltrace\n");
+       if (argc < 2) {
+               printf("Usage: tests-ctf-writer path_to_babeltrace\n");
                return -1;
        }
 
@@ -3550,9 +3438,8 @@ int main(int argc, char **argv)
        free(metadata_string);
        bt_put(stream_class);
 
-       validate_metadata(argv[1], metadata_path);
-       validate_trace(argv[2], trace_path);
+       validate_trace(argv[1], trace_path);
 
-       recursive_rmdir(trace_path);
+       //recursive_rmdir(trace_path);
        return 0;
 }
index 5bd1c97f24e0a2aa9669a72bb8e2cb5f40f20616..219a2f9f138a862c227d7d75938b38ef0ec093c7 100755 (executable)
@@ -17,7 +17,6 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #
 
-CTFPARSERTEST="@abs_top_builddir@/formats/ctf/metadata/ctf-parser-test"
 BTBIN="@abs_top_builddir@/converter/babeltrace"
 
-"@abs_top_builddir@/tests/lib/test_ctf_writer" "$CTFPARSERTEST" "$BTBIN"
+"@abs_top_builddir@/tests/lib/test_ctf_writer" "$BTBIN"
diff --git a/tests/lib/test_seek.c b/tests/lib/test_seek.c
deleted file mode 100644 (file)
index 7243c7f..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * test-seeks.c
- *
- * Lib BabelTrace - Seeks test program
- *
- * Copyright 2012 - Yannick Brosseau <yannick.brosseau@gmail.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 <babeltrace/context.h>
-#include <babeltrace/iterator.h>
-#include <babeltrace/ctf/iterator.h>
-#include <babeltrace/ctf/events-internal.h>
-#include <babeltrace/babeltrace-internal.h>    /* For symbol side-effects */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <babeltrace/compat/limits.h>
-
-#include <tap/tap.h>
-#include "common.h"
-
-#define NR_TESTS       36
-
-void run_seek_begin(char *path, uint64_t expected_begin)
-{
-       struct bt_context *ctx;
-       struct bt_ctf_iter *iter;
-       struct bt_ctf_event *event;
-       struct bt_iter_pos newpos;
-       int ret;
-       int64_t timestamp_begin;
-       int64_t timestamp_seek_begin;
-
-       /* Open the trace */
-       ctx = create_context_with_path(path);
-       if (!ctx) {
-               diag("Cannot create valid context");
-               return;
-       }
-
-       /* Create iterator with null begin and end */
-       iter = bt_ctf_iter_create(ctx, NULL, NULL);
-       if (!iter) {
-               diag("Cannot create valid iterator");
-               return;
-       }
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid");
-
-       /* Validate that the first timestamp is right */
-       ok1(bt_ctf_get_timestamp(event, &timestamp_begin) == 0);
-
-       ok1(timestamp_begin == expected_begin);
-
-       /* Validate that we get the same value after a seek begin */
-       newpos.type = BT_SEEK_BEGIN;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek begin retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp_seek_begin) == 0);
-
-       ok1(timestamp_begin == timestamp_seek_begin);
-
-       bt_context_put(ctx);
-}
-
-
-void run_seek_last(char *path, uint64_t expected_last)
-{
-       struct bt_context *ctx;
-       struct bt_ctf_iter *iter;
-       struct bt_ctf_event *event;
-       struct bt_iter_pos newpos;
-       int ret;
-       int64_t timestamp_last;
-
-       /* Open the trace */
-       ctx = create_context_with_path(path);
-       if (!ctx) {
-               diag("Cannot create valid context");
-               return;
-       }
-
-       /* Create iterator with null last and end */
-       iter = bt_ctf_iter_create(ctx, NULL, NULL);
-       if (!iter) {
-               diag("Cannot create valid iterator");
-               return;
-       }
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at beginning");
-
-       /* Seek to last */
-       newpos.type = BT_SEEK_LAST;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek last retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at last position");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp_last) == 0);
-
-       ok1(timestamp_last == expected_last);
-
-       /* Try to read next event */
-       ret = bt_iter_next(bt_ctf_get_iter(iter));
-
-       ok(ret == 0, "iter next should return an error");
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event == 0, "Event after last should be invalid");
-
-       bt_context_put(ctx);
-}
-
-void run_seek_time_at_last(char *path, uint64_t expected_last)
-{
-       struct bt_context *ctx;
-       struct bt_ctf_iter *iter;
-       struct bt_ctf_event *event;
-       struct bt_iter_pos newpos;
-       int ret;
-       int64_t timestamp_last;
-
-       /* Open the trace */
-       ctx = create_context_with_path(path);
-       if (!ctx) {
-               diag("Cannot create valid context");
-               return;
-       }
-
-       /* Create iterator with null last and end */
-       iter = bt_ctf_iter_create(ctx, NULL, NULL);
-       if (!iter) {
-               diag("Cannot create valid iterator");
-               return;
-       }
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at beginning");
-
-       /* Seek to last */
-       newpos.type = BT_SEEK_TIME;
-       newpos.u.seek_time = expected_last;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek time at last retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at last position");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp_last) == 0);
-
-       ok1(timestamp_last == expected_last);
-
-       /* Try to read next event */
-       ret = bt_iter_next(bt_ctf_get_iter(iter));
-
-       ok(ret == 0, "iter next should return an error");
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event == 0, "Event after last should be invalid");
-
-       bt_context_put(ctx);
-}
-
-void run_seek_cycles(char *path,
-               uint64_t expected_begin,
-               uint64_t expected_last)
-{
-       struct bt_context *ctx;
-       struct bt_ctf_iter *iter;
-       struct bt_ctf_event *event;
-       struct bt_iter_pos newpos;
-       int ret;
-       int64_t timestamp;
-
-       /* Open the trace */
-       ctx = create_context_with_path(path);
-       if (!ctx) {
-               diag("Cannot create valid context");
-               return;
-       }
-
-       /* Create iterator with null last and end */
-       iter = bt_ctf_iter_create(ctx, NULL, NULL);
-       if (!iter) {
-               diag("Cannot create valid iterator");
-               return;
-       }
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at beginning");
-
-       /* Seek to last */
-       newpos.type = BT_SEEK_LAST;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek last retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at last position");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp) == 0);
-
-       ok1(timestamp == expected_last);
-
-       /* Try to read next event */
-       ret = bt_iter_next(bt_ctf_get_iter(iter));
-
-       ok(ret == 0, "iter next should return an error");
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event == 0, "Event after last should be invalid");
-
-       /* Seek to BEGIN */
-       newpos.type = BT_SEEK_BEGIN;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek begin retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at first position");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp) == 0);
-
-       ok1(timestamp == expected_begin);
-
-       /* Seek last again */
-       newpos.type = BT_SEEK_LAST;
-       ret = bt_iter_set_pos(bt_ctf_get_iter(iter), &newpos);
-
-       ok(ret == 0, "Seek last retval %d", ret);
-
-       event = bt_ctf_iter_read_event(iter);
-
-       ok(event, "Event valid at last position");
-
-       ok1(bt_ctf_get_timestamp(event, &timestamp) == 0);
-
-       ok1(timestamp == expected_last);
-
-       bt_context_put(ctx);
-}
-
-int main(int argc, char **argv)
-{
-       char *path;
-       uint64_t expected_begin;
-       uint64_t expected_last;
-
-       /*
-        * Side-effects ensuring libs are not optimized away by static
-        * linking.
-        */
-       babeltrace_debug = 0;   /* libbabeltrace.la */
-       opt_clock_offset = 0;   /* libbabeltrace-ctf.la */
-
-       plan_tests(NR_TESTS);
-
-       if (argc < 4) {
-               diag("Invalid arguments: need a trace path and the start and last timestamp");
-               exit(1);
-       }
-
-       /* Parse arguments (Trace, begin timestamp) */
-       path = argv[1];
-
-       expected_begin = strtoull(argv[2], NULL, 0);
-       if (ULLONG_MAX == expected_begin && errno == ERANGE) {
-               diag("Invalid value for begin timestamp");
-               exit(1);
-       }
-
-       expected_last = strtoull(argv[3], NULL, 0);
-       if (ULLONG_MAX == expected_last && errno == ERANGE) {
-               diag("Invalid value for last timestamp");
-               exit(1);
-       }
-
-       run_seek_begin(path, expected_begin);
-       run_seek_time_at_last(path, expected_last);
-       run_seek_last(path, expected_last);
-       run_seek_cycles(path, expected_begin, expected_last);
-
-       return exit_status();
-}
index 8e640e382221c80b0a54b45fdea0a356f666c9ab..469399fb3ba9fd106b4785a0edb262bb7cb07b75 100644 (file)
@@ -247,6 +247,9 @@ int main(int argc, char **argv)
 
        ok(index + 1 == state.i, "trace modification has been invoked once after addition of an event class");
 
+       BT_PUT(sc3);
+       BT_PUT(ec5);
+       BT_PUT(ec4);
        BT_PUT(trace);
        return exit_status();
 }
diff --git a/types/Makefile.am b/types/Makefile.am
deleted file mode 100644 (file)
index 0417519..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libbabeltrace_types.la
-
-libbabeltrace_types_la_SOURCES = \
-       array.c \
-       enum.c \
-       float.c \
-       integer.c \
-       sequence.c \
-       string.c \
-       struct.c \
-       variant.c \
-       types.c
diff --git a/types/array.c b/types/array.c
deleted file mode 100644 (file)
index d514a60..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * array.c
- *
- * BabelTrace - Array Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <inttypes.h>
-
-static
-struct bt_definition *_array_definition_new(struct bt_declaration *declaration,
-                       struct definition_scope *parent_scope,
-                       GQuark field_name, int index, const char *root_name);
-static
-void _array_definition_free(struct bt_definition *definition);
-
-int bt_array_rw(struct bt_stream_pos *pos, struct bt_definition *definition)
-{
-       struct definition_array *array_definition =
-               container_of(definition, struct definition_array, p);
-       const struct declaration_array *array_declaration =
-               array_definition->declaration;
-       uint64_t i;
-       int ret;
-
-       /* No need to align, because the first field will align itself. */
-       for (i = 0; i < array_declaration->len; i++) {
-               struct bt_definition *field =
-                       g_ptr_array_index(array_definition->elems, i);
-               ret = generic_rw(pos, field);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static
-void _array_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_array *array_declaration =
-               container_of(declaration, struct declaration_array, p);
-
-       bt_free_declaration_scope(array_declaration->scope);
-       bt_declaration_unref(array_declaration->elem);
-       g_free(array_declaration);
-}
-
-struct declaration_array *
-       bt_array_declaration_new(size_t len,
-                             struct bt_declaration *elem_declaration,
-                             struct declaration_scope *parent_scope)
-{
-       struct declaration_array *array_declaration;
-       struct bt_declaration *declaration;
-
-       array_declaration = g_new(struct declaration_array, 1);
-       declaration = &array_declaration->p;
-       array_declaration->len = len;
-       bt_declaration_ref(elem_declaration);
-       array_declaration->elem = elem_declaration;
-       array_declaration->scope = bt_new_declaration_scope(parent_scope);
-       declaration->id = BT_CTF_TYPE_ID_ARRAY;
-       declaration->alignment = elem_declaration->alignment;
-       declaration->declaration_free = _array_declaration_free;
-       declaration->definition_new = _array_definition_new;
-       declaration->definition_free = _array_definition_free;
-       declaration->ref = 1;
-       return array_declaration;
-}
-
-static
-struct bt_definition *
-       _array_definition_new(struct bt_declaration *declaration,
-                             struct definition_scope *parent_scope,
-                             GQuark field_name, int index, const char *root_name)
-{
-       struct declaration_array *array_declaration =
-               container_of(declaration, struct declaration_array, p);
-       struct definition_array *array;
-       int ret;
-       int i;
-
-       array = g_new(struct definition_array, 1);
-       bt_declaration_ref(&array_declaration->p);
-       array->p.declaration = declaration;
-       array->declaration = array_declaration;
-       array->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       array->p.index = root_name ? INT_MAX : index;
-       array->p.name = field_name;
-       array->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       array->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-       ret = bt_register_field_definition(field_name, &array->p,
-                                       parent_scope);
-       assert(!ret);
-       array->string = NULL;
-       array->elems = NULL;
-
-       if (array_declaration->elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(array_declaration->elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       array->string = g_string_new("");
-               }
-       }
-
-       array->elems = g_ptr_array_sized_new(array_declaration->len);
-       g_ptr_array_set_size(array->elems, array_declaration->len);
-       for (i = 0; i < array_declaration->len; i++) {
-               struct bt_definition **field;
-               GString *str;
-               GQuark name;
-
-               str = g_string_new("");
-               g_string_printf(str, "[%u]", (unsigned int) i);
-               name = g_quark_from_string(str->str);
-               (void) g_string_free(str, TRUE);
-
-               field = (struct bt_definition **) &g_ptr_array_index(array->elems, i);
-               *field = array_declaration->elem->definition_new(array_declaration->elem,
-                                         array->p.scope,
-                                         name, i, NULL);
-               if (!*field)
-                       goto error;
-       }
-
-       return &array->p;
-
-error:
-       for (i--; i >= 0; i--) {
-               struct bt_definition *field;
-
-               field = g_ptr_array_index(array->elems, i);
-               field->declaration->definition_free(field);
-       }
-       (void) g_ptr_array_free(array->elems, TRUE);
-       bt_free_definition_scope(array->p.scope);
-       bt_declaration_unref(array->p.declaration);
-       g_free(array);
-       return NULL;
-}
-
-static
-void _array_definition_free(struct bt_definition *definition)
-{
-       struct definition_array *array =
-               container_of(definition, struct definition_array, p);
-       uint64_t i;
-
-       if (array->string)
-               (void) g_string_free(array->string, TRUE);
-       if (array->elems) {
-               for (i = 0; i < array->elems->len; i++) {
-                       struct bt_definition *field;
-
-                       field = g_ptr_array_index(array->elems, i);
-                       field->declaration->definition_free(field);
-               }
-               (void) g_ptr_array_free(array->elems, TRUE);
-       }
-       bt_free_definition_scope(array->p.scope);
-       bt_declaration_unref(array->p.declaration);
-       g_free(array);
-}
-
-uint64_t bt_array_len(struct definition_array *array)
-{
-       if (!array->elems)
-               return array->string->len;
-       return array->elems->len;
-}
-
-struct bt_definition *bt_array_index(struct definition_array *array, uint64_t i)
-{
-       if (!array->elems)
-               return NULL;
-       if (i >= array->elems->len)
-               return NULL;
-       return g_ptr_array_index(array->elems, i);
-}
-
-int bt_get_array_len(const struct bt_definition *field)
-{
-       struct definition_array *array_definition;
-       struct declaration_array *array_declaration;
-
-       array_definition = container_of(field, struct definition_array, p);
-       array_declaration = array_definition->declaration;
-
-       return array_declaration->len;
-}
-
-GString *bt_get_char_array(const struct bt_definition *field)
-{
-       struct definition_array *array_definition;
-       struct declaration_array *array_declaration;
-       struct bt_declaration *elem;
-
-       array_definition = container_of(field, struct definition_array, p);
-       array_declaration = array_definition->declaration;
-       elem = array_declaration->elem;
-       if (elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                               || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       if (integer_declaration->len == CHAR_BIT
-                                       && integer_declaration->p.alignment == CHAR_BIT) {
-
-                               return array_definition->string;
-                       }
-               }
-       }
-       fprintf(stderr, "[warning] Extracting string\n");
-       return NULL;
-}
diff --git a/types/enum.c b/types/enum.c
deleted file mode 100644 (file)
index 455e60a..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * enum.c
- *
- * BabelTrace - Enumeration Type
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-#include <glib.h>
-
-#if (__LONG_MAX__ == 2147483647L)
-#define WORD_SIZE      32
-#elif (__LONG_MAX__ == 9223372036854775807L)
-#define WORD_SIZE      64
-#else
-#error "Unknown long size."
-#endif
-
-static
-struct bt_definition *_enum_definition_new(struct bt_declaration *declaration,
-                                       struct definition_scope *parent_scope,
-                                       GQuark field_name, int index,
-                                       const char *root_name);
-static
-void _enum_definition_free(struct bt_definition *definition);
-
-static
-void enum_range_set_free(void *ptr)
-{
-       g_array_unref(ptr);
-}
-
-#if (WORD_SIZE == 32)
-static inline
-gpointer get_uint_v(uint64_t *v)
-{
-       return v;
-}
-
-static inline
-gpointer get_int_v(int64_t *v)
-{
-       return v;
-}
-
-static
-guint enum_val_hash(gconstpointer key)
-{
-       int64_t ukey = *(const int64_t *)key;
-
-       return (guint)ukey ^ (guint)(ukey >> 32);
-}
-
-static
-gboolean enum_val_equal(gconstpointer a, gconstpointer b)
-{
-       int64_t ua = *(const int64_t *)a;
-       int64_t ub = *(const int64_t *)b;
-
-       return ua == ub;
-}
-
-static
-void enum_val_free(void *ptr)
-{
-       g_free(ptr);
-}
-#else  /* WORD_SIZE != 32 */
-static inline
-gpointer get_uint_v(uint64_t *v)
-{
-       return (gpointer) *v;
-}
-
-static inline
-gpointer get_int_v(int64_t *v)
-{
-       return (gpointer) *v;
-}
-
-static
-guint enum_val_hash(gconstpointer key)
-{
-       return g_direct_hash(key);
-}
-
-static
-gboolean enum_val_equal(gconstpointer a, gconstpointer b)
-{
-       return g_direct_equal(a, b);
-}
-
-static
-void enum_val_free(void *ptr)
-{
-}
-#endif /* WORD_SIZE != 32 */
-
-/*
- * Returns a GArray or NULL.
- * Caller must release the GArray with g_array_unref().
- */
-GArray *bt_enum_uint_to_quark_set(const struct declaration_enum *enum_declaration,
-                              uint64_t v)
-{
-       struct enum_range_to_quark *iter;
-       GArray *qs, *ranges = NULL;
-
-       /* Single values lookup */
-       qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set,
-                                get_uint_v(&v));
-
-       /* Range lookup */
-       bt_list_for_each_entry(iter, &enum_declaration->table.range_to_quark, node) {
-               if (iter->range.start._unsigned > v || iter->range.end._unsigned < v)
-                       continue;
-               if (!ranges) {
-                       size_t qs_len = 0;
-
-                       if (qs)
-                               qs_len = qs->len;
-                       ranges = g_array_sized_new(FALSE, TRUE,
-                                       sizeof(GQuark),
-                                       qs_len + 1);
-                       g_array_set_size(ranges, qs_len + 1);
-                       if (qs)
-                               memcpy(ranges->data, qs->data,
-                                      sizeof(GQuark) * qs_len);
-                       g_array_index(ranges, GQuark, qs_len) = iter->quark;
-               } else {
-                       size_t qs_len = ranges->len;
-
-                       g_array_set_size(ranges, qs_len + 1);
-                       g_array_index(ranges, GQuark, qs_len) = iter->quark;
-               }
-       }
-       if (!ranges) {
-               if (!qs)
-                       return NULL;
-               ranges = qs;
-               g_array_ref(ranges);
-       }
-       return ranges;
-}
-
-/*
- * Returns a GArray or NULL.
- * Caller must release the GArray with g_array_unref().
- */
-GArray *bt_enum_int_to_quark_set(const struct declaration_enum *enum_declaration,
-                             int64_t v)
-{
-       struct enum_range_to_quark *iter;
-       GArray *qs, *ranges = NULL;
-
-       /* Single values lookup */
-       qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set,
-                                get_int_v(&v));
-
-       /* Range lookup */
-       bt_list_for_each_entry(iter, &enum_declaration->table.range_to_quark, node) {
-               if (iter->range.start._signed > v || iter->range.end._signed < v)
-                       continue;
-               if (!ranges) {
-                       size_t qs_len = 0;
-
-                       if (qs)
-                               qs_len = qs->len;
-                       ranges = g_array_sized_new(FALSE, TRUE,
-                                       sizeof(GQuark),
-                                       qs_len + 1);
-                       g_array_set_size(ranges, qs_len + 1);
-                       if (qs)
-                               memcpy(ranges->data, qs->data,
-                                      sizeof(GQuark) * qs_len);
-                       g_array_index(ranges, GQuark, qs_len) = iter->quark;
-               } else {
-                       size_t qs_len = ranges->len;
-
-                       g_array_set_size(ranges, qs_len + 1);
-                       g_array_index(ranges, GQuark, qs_len) = iter->quark;
-               }
-       }
-       if (!ranges) {
-               if (!qs)
-                       return NULL;
-               ranges = qs;
-               g_array_ref(ranges);
-       }
-       return ranges;
-}
-
-static
-void bt_enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_declaration,
-                        uint64_t v, GQuark q)
-{
-       uint64_t *valuep;
-       GArray *array;
-
-       array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set,
-                                   get_uint_v(&v));
-       if (!array) {
-               array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1);
-               g_array_set_size(array, 1);
-               g_array_index(array, GQuark, array->len - 1) = q;
-#if (WORD_SIZE == 32)
-               valuep = g_new(uint64_t, 1);
-               *valuep = v;
-#else  /* WORD_SIZE != 32 */
-               valuep = get_uint_v(&v);
-#endif /* WORD_SIZE != 32 */
-               g_hash_table_insert(enum_declaration->table.value_to_quark_set, valuep, array);
-       } else {
-               g_array_set_size(array, array->len + 1);
-               g_array_index(array, GQuark, array->len - 1) = q;
-       }
-}
-
-static
-void bt_enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declaration,
-                       int64_t v, GQuark q)
-{
-       int64_t *valuep;
-       GArray *array;
-
-       array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set,
-                                   get_int_v(&v));
-       if (!array) {
-               array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1);
-               g_array_set_size(array, 1);
-               g_array_index(array, GQuark, array->len - 1) = q;
-#if (WORD_SIZE == 32)
-               valuep = g_new(int64_t, 1);
-               *valuep = v;
-#else  /* WORD_SIZE != 32 */
-               valuep = get_int_v(&v);
-#endif /* WORD_SIZE != 32 */
-               g_hash_table_insert(enum_declaration->table.value_to_quark_set, valuep, array);
-       } else {
-               g_array_set_size(array, array->len + 1);
-               g_array_index(array, GQuark, array->len - 1) = q;
-       }
-}
-
-GArray *bt_enum_quark_to_range_set(const struct declaration_enum *enum_declaration,
-                               GQuark q)
-{
-       return g_hash_table_lookup(enum_declaration->table.quark_to_range_set,
-                                  (gconstpointer) GUINT_TO_POINTER(q));
-}
-
-static
-void bt_enum_signed_insert_range_to_quark(struct declaration_enum *enum_declaration,
-                        int64_t start, int64_t end, GQuark q)
-{
-       struct enum_range_to_quark *rtoq;
-
-       rtoq = g_new(struct enum_range_to_quark, 1);
-       bt_list_add(&rtoq->node, &enum_declaration->table.range_to_quark);
-       rtoq->range.start._signed = start;
-       rtoq->range.end._signed = end;
-       rtoq->quark = q;
-}
-
-static
-void bt_enum_unsigned_insert_range_to_quark(struct declaration_enum *enum_declaration,
-                        uint64_t start, uint64_t end, GQuark q)
-{
-       struct enum_range_to_quark *rtoq;
-
-       rtoq = g_new(struct enum_range_to_quark, 1);
-       bt_list_add(&rtoq->node, &enum_declaration->table.range_to_quark);
-       rtoq->range.start._unsigned = start;
-       rtoq->range.end._unsigned = end;
-       rtoq->quark = q;
-}
-
-void bt_enum_signed_insert(struct declaration_enum *enum_declaration,
-                        int64_t start, int64_t end, GQuark q)
-{
-       GArray *array;
-       struct enum_range *range;
-
-       if (start == end) {
-               bt_enum_signed_insert_value_to_quark_set(enum_declaration, start, q);
-       } else {
-               if (start > end) {
-                       uint64_t tmp;
-
-                       tmp = start;
-                       start = end;
-                       end = tmp;
-               }
-               bt_enum_signed_insert_range_to_quark(enum_declaration, start, end, q);
-       }
-
-       array = g_hash_table_lookup(enum_declaration->table.quark_to_range_set,
-                                   (gconstpointer) GUINT_TO_POINTER(q));
-       if (!array) {
-               array = g_array_sized_new(FALSE, TRUE,
-                                         sizeof(struct enum_range), 1);
-               g_hash_table_insert(enum_declaration->table.quark_to_range_set,
-                                   GUINT_TO_POINTER(q),
-                                   array);
-       }
-       g_array_set_size(array, array->len + 1);
-       range = &g_array_index(array, struct enum_range, array->len - 1);
-       range->start._signed = start;
-       range->end._signed = end;
-}
-
-void bt_enum_unsigned_insert(struct declaration_enum *enum_declaration,
-                         uint64_t start, uint64_t end, GQuark q)
-{
-       GArray *array;
-       struct enum_range *range;
-
-
-       if (start == end) {
-               bt_enum_unsigned_insert_value_to_quark_set(enum_declaration, start, q);
-       } else {
-               if (start > end) {
-                       uint64_t tmp;
-
-                       tmp = start;
-                       start = end;
-                       end = tmp;
-               }
-               bt_enum_unsigned_insert_range_to_quark(enum_declaration, start, end, q);
-       }
-
-       array = g_hash_table_lookup(enum_declaration->table.quark_to_range_set,
-                                   (gconstpointer) GUINT_TO_POINTER(q));
-       if (!array) {
-               array = g_array_sized_new(FALSE, TRUE,
-                                         sizeof(struct enum_range), 1);
-               g_hash_table_insert(enum_declaration->table.quark_to_range_set,
-                                   GUINT_TO_POINTER(q),
-                                   array);
-       }
-       g_array_set_size(array, array->len + 1);
-       range = &g_array_index(array, struct enum_range, array->len - 1);
-       range->start._unsigned = start;
-       range->end._unsigned = end;
-}
-
-size_t bt_enum_get_nr_enumerators(struct declaration_enum *enum_declaration)
-{
-       return g_hash_table_size(enum_declaration->table.quark_to_range_set);
-}
-
-static
-void _enum_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_enum *enum_declaration =
-               container_of(declaration, struct declaration_enum, p);
-       struct enum_range_to_quark *iter, *tmp;
-
-       g_hash_table_destroy(enum_declaration->table.value_to_quark_set);
-       bt_list_for_each_entry_safe(iter, tmp, &enum_declaration->table.range_to_quark, node) {
-               bt_list_del(&iter->node);
-               g_free(iter);
-       }
-       g_hash_table_destroy(enum_declaration->table.quark_to_range_set);
-       bt_declaration_unref(&enum_declaration->integer_declaration->p);
-       g_free(enum_declaration);
-}
-
-struct declaration_enum *
-       bt_enum_declaration_new(struct declaration_integer *integer_declaration)
-{
-       struct declaration_enum *enum_declaration;
-
-       enum_declaration = g_new(struct declaration_enum, 1);
-
-       enum_declaration->table.value_to_quark_set = g_hash_table_new_full(enum_val_hash,
-                                                           enum_val_equal,
-                                                           enum_val_free,
-                                                           enum_range_set_free);
-       BT_INIT_LIST_HEAD(&enum_declaration->table.range_to_quark);
-       enum_declaration->table.quark_to_range_set = g_hash_table_new_full(g_direct_hash,
-                                                       g_direct_equal,
-                                                       NULL, enum_range_set_free);
-       bt_declaration_ref(&integer_declaration->p);
-       enum_declaration->integer_declaration = integer_declaration;
-       enum_declaration->p.id = CTF_TYPE_ENUM;
-       enum_declaration->p.alignment = 1;
-       enum_declaration->p.declaration_free = _enum_declaration_free;
-       enum_declaration->p.definition_new = _enum_definition_new;
-       enum_declaration->p.definition_free = _enum_definition_free;
-       enum_declaration->p.ref = 1;
-       return enum_declaration;
-}
-
-static
-struct bt_definition *
-       _enum_definition_new(struct bt_declaration *declaration,
-                            struct definition_scope *parent_scope,
-                            GQuark field_name, int index,
-                            const char *root_name)
-{
-       struct declaration_enum *enum_declaration =
-               container_of(declaration, struct declaration_enum, p);
-       struct definition_enum *_enum;
-       struct bt_definition *definition_integer_parent;
-       int ret;
-
-       _enum = g_new(struct definition_enum, 1);
-       bt_declaration_ref(&enum_declaration->p);
-       _enum->p.declaration = declaration;
-       _enum->declaration = enum_declaration;
-       _enum->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       _enum->p.index = root_name ? INT_MAX : index;
-       _enum->p.name = field_name;
-       _enum->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       _enum->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-       _enum->value = NULL;
-       ret = bt_register_field_definition(field_name, &_enum->p,
-                                       parent_scope);
-       assert(!ret);
-       definition_integer_parent =
-               enum_declaration->integer_declaration->p.definition_new(&enum_declaration->integer_declaration->p,
-                               _enum->p.scope,
-                               g_quark_from_string("container"), 0, NULL);
-       _enum->integer = container_of(definition_integer_parent,
-                                     struct definition_integer, p);
-       return &_enum->p;
-}
-
-static
-void _enum_definition_free(struct bt_definition *definition)
-{
-       struct definition_enum *_enum =
-               container_of(definition, struct definition_enum, p);
-
-       bt_definition_unref(&_enum->integer->p);
-       bt_free_definition_scope(_enum->p.scope);
-       bt_declaration_unref(_enum->p.declaration);
-       if (_enum->value)
-               g_array_unref(_enum->value);
-       g_free(_enum);
-}
diff --git a/types/float.c b/types/float.c
deleted file mode 100644 (file)
index 99c2acc..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * float.c
- *
- * BabelTrace - Float Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <babeltrace/endian.h>
-
-static
-struct bt_definition *_float_definition_new(struct bt_declaration *declaration,
-                                  struct definition_scope *parent_scope,
-                                  GQuark field_name, int index,
-                                  const char *root_name);
-static
-void _float_definition_free(struct bt_definition *definition);
-
-static
-void _float_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_float *float_declaration =
-               container_of(declaration, struct declaration_float, p);
-
-       bt_declaration_unref(&float_declaration->exp->p);
-       bt_declaration_unref(&float_declaration->mantissa->p);
-       bt_declaration_unref(&float_declaration->sign->p);
-       g_free(float_declaration);
-}
-
-struct declaration_float *
-       bt_float_declaration_new(size_t mantissa_len,
-                      size_t exp_len, int byte_order, size_t alignment)
-{
-       struct declaration_float *float_declaration;
-       struct bt_declaration *declaration;
-
-       float_declaration = g_new(struct declaration_float, 1);
-       declaration = &float_declaration->p;
-       declaration->id = CTF_TYPE_FLOAT;
-       declaration->alignment = alignment;
-       declaration->declaration_free = _float_declaration_free;
-       declaration->definition_new = _float_definition_new;
-       declaration->definition_free = _float_definition_free;
-       declaration->ref = 1;
-       float_declaration->byte_order = byte_order;
-
-       float_declaration->sign = bt_integer_declaration_new(1,
-                                               byte_order, false, 1, 2,
-                                               CTF_STRING_NONE, NULL);
-       float_declaration->mantissa = bt_integer_declaration_new(mantissa_len - 1,
-                                               byte_order, false, 1, 10,
-                                               CTF_STRING_NONE, NULL);
-       float_declaration->exp = bt_integer_declaration_new(exp_len,
-                                               byte_order, true, 1, 10,
-                                               CTF_STRING_NONE, NULL);
-       return float_declaration;
-}
-
-static
-struct bt_definition *
-       _float_definition_new(struct bt_declaration *declaration,
-                             struct definition_scope *parent_scope,
-                             GQuark field_name, int index,
-                             const char *root_name)
-{
-       struct declaration_float *float_declaration =
-               container_of(declaration, struct declaration_float, p);
-       struct definition_float *_float;
-       struct bt_definition *tmp;
-
-       _float = g_new(struct definition_float, 1);
-       bt_declaration_ref(&float_declaration->p);
-       _float->p.declaration = declaration;
-       _float->declaration = float_declaration;
-       _float->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-       _float->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       if (float_declaration->byte_order == LITTLE_ENDIAN) {
-               tmp = float_declaration->mantissa->p.definition_new(&float_declaration->mantissa->p,
-                       _float->p.scope, g_quark_from_string("mantissa"), 0, NULL);
-               _float->mantissa = container_of(tmp, struct definition_integer, p);
-               tmp = float_declaration->exp->p.definition_new(&float_declaration->exp->p,
-                       _float->p.scope, g_quark_from_string("exp"), 1, NULL);
-               _float->exp = container_of(tmp, struct definition_integer, p);
-               tmp = float_declaration->sign->p.definition_new(&float_declaration->sign->p,
-                       _float->p.scope, g_quark_from_string("sign"), 2, NULL);
-               _float->sign = container_of(tmp, struct definition_integer, p);
-       } else {
-               tmp = float_declaration->sign->p.definition_new(&float_declaration->sign->p,
-                       _float->p.scope, g_quark_from_string("sign"), 0, NULL);
-               _float->sign = container_of(tmp, struct definition_integer, p);
-               tmp = float_declaration->exp->p.definition_new(&float_declaration->exp->p,
-                       _float->p.scope, g_quark_from_string("exp"), 1, NULL);
-               _float->exp = container_of(tmp, struct definition_integer, p);
-               tmp = float_declaration->mantissa->p.definition_new(&float_declaration->mantissa->p,
-                       _float->p.scope, g_quark_from_string("mantissa"), 2, NULL);
-               _float->mantissa = container_of(tmp, struct definition_integer, p);
-       }
-       _float->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       _float->p.index = root_name ? INT_MAX : index;
-       _float->p.name = field_name;
-       _float->value = 0.0;
-       if (parent_scope) {
-               int ret;
-
-               ret = bt_register_field_definition(field_name, &_float->p,
-                                               parent_scope);
-               assert(!ret);
-       }
-       return &_float->p;
-}
-
-static
-void _float_definition_free(struct bt_definition *definition)
-{
-       struct definition_float *_float =
-               container_of(definition, struct definition_float, p);
-
-       bt_definition_unref(&_float->sign->p);
-       bt_definition_unref(&_float->exp->p);
-       bt_definition_unref(&_float->mantissa->p);
-       bt_free_definition_scope(_float->p.scope);
-       bt_declaration_unref(_float->p.declaration);
-       g_free(_float);
-}
diff --git a/types/integer.c b/types/integer.c
deleted file mode 100644 (file)
index 52cc6bb..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * integer.c
- *
- * BabelTrace - Integer Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/align.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <stdint.h>
-
-static
-struct bt_definition *_integer_definition_new(struct bt_declaration *declaration,
-                              struct definition_scope *parent_scope,
-                              GQuark field_name, int index,
-                              const char *root_name);
-static
-void _integer_definition_free(struct bt_definition *definition);
-
-static
-void _integer_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_integer *integer_declaration =
-               container_of(declaration, struct declaration_integer, p);
-       g_free(integer_declaration);
-}
-
-struct declaration_integer *
-       bt_integer_declaration_new(size_t len, int byte_order,
-                        int signedness, size_t alignment, int base,
-                        enum ctf_string_encoding encoding,
-                        struct ctf_clock *clock)
-{
-       struct declaration_integer *integer_declaration;
-
-       integer_declaration = g_new0(struct declaration_integer, 1);
-       integer_declaration->p.id = CTF_TYPE_INTEGER;
-       integer_declaration->p.alignment = alignment;
-       integer_declaration->p.declaration_free = _integer_declaration_free;
-       integer_declaration->p.definition_free = _integer_definition_free;
-       integer_declaration->p.definition_new = _integer_definition_new;
-       integer_declaration->p.ref = 1;
-       integer_declaration->len = len;
-       integer_declaration->byte_order = byte_order;
-       integer_declaration->signedness = signedness;
-       integer_declaration->base = base;
-       integer_declaration->encoding = encoding;
-       integer_declaration->clock = clock;
-       return integer_declaration;
-}
-
-static
-struct bt_definition *
-       _integer_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name)
-{
-       struct declaration_integer *integer_declaration =
-               container_of(declaration, struct declaration_integer, p);
-       struct definition_integer *integer;
-       int ret;
-
-       integer = g_new0(struct definition_integer, 1);
-       bt_declaration_ref(&integer_declaration->p);
-       integer->p.declaration = declaration;
-       integer->declaration = integer_declaration;
-       integer->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       integer->p.index = root_name ? INT_MAX : index;
-       integer->p.name = field_name;
-       integer->p.path = bt_new_definition_path(parent_scope, field_name,
-                                       root_name);
-       integer->p.scope = NULL;
-       integer->value._unsigned = 0;
-       ret = bt_register_field_definition(field_name, &integer->p,
-                                       parent_scope);
-       assert(!ret);
-       return &integer->p;
-}
-
-static
-void _integer_definition_free(struct bt_definition *definition)
-{
-       struct definition_integer *integer =
-               container_of(definition, struct definition_integer, p);
-
-       bt_declaration_unref(integer->p.declaration);
-       g_free(integer);
-}
-
-enum ctf_string_encoding bt_get_int_encoding(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       return integer_declaration->encoding;
-}
-
-int bt_get_int_base(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       return integer_declaration->base;
-}
-
-size_t bt_get_int_len(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       return integer_declaration->len;
-}
-
-int bt_get_int_byte_order(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       return integer_declaration->byte_order;
-}
-
-int bt_get_int_signedness(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       return integer_declaration->signedness;
-}
-
-uint64_t bt_get_unsigned_int(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       if (!integer_declaration->signedness) {
-               return integer_definition->value._unsigned;
-       }
-       fprintf(stderr, "[warning] Extracting unsigned value from a signed int (%s)\n",
-               g_quark_to_string(field->name));
-       return (uint64_t)integer_definition->value._signed;
-}
-
-int64_t bt_get_signed_int(const struct bt_definition *field)
-{
-       struct definition_integer *integer_definition;
-       const struct declaration_integer *integer_declaration;
-
-       integer_definition = container_of(field, struct definition_integer, p);
-       integer_declaration = integer_definition->declaration;
-
-       if (integer_declaration->signedness) {
-               return integer_definition->value._signed;
-       }
-       fprintf(stderr, "[warning] Extracting signed value from an unsigned int (%s)\n", 
-               g_quark_to_string(field->name));
-       return (int64_t)integer_definition->value._unsigned;
-}
diff --git a/types/sequence.c b/types/sequence.c
deleted file mode 100644 (file)
index 825e4dc..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * sequence.c
- *
- * BabelTrace - Sequence Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <inttypes.h>
-
-static
-struct bt_definition *_sequence_definition_new(struct bt_declaration *declaration,
-                                       struct definition_scope *parent_scope,
-                                       GQuark field_name, int index,
-                                       const char *root_name);
-static
-void _sequence_definition_free(struct bt_definition *definition);
-
-int bt_sequence_rw(struct bt_stream_pos *pos, struct bt_definition *definition)
-{
-       struct definition_sequence *sequence_definition =
-               container_of(definition, struct definition_sequence, p);
-       const struct declaration_sequence *sequence_declaration =
-               sequence_definition->declaration;
-       uint64_t len, oldlen, i;
-       int ret;
-
-       len = sequence_definition->length->value._unsigned;
-       /*
-        * Yes, large sequences could be _painfully slow_ to parse due
-        * to memory allocation for each event read. At least, never
-        * shrink the sequence. Note: the sequence GArray len should
-        * never be used as indicator of the current sequence length.
-        * One should always look at the sequence->len->value._unsigned
-        * value for that.
-        */
-       oldlen = sequence_definition->elems->len;
-       if (oldlen < len)
-               g_ptr_array_set_size(sequence_definition->elems, len);
-
-       for (i = oldlen; i < len; i++) {
-               struct bt_definition **field;
-               GString *str;
-               GQuark name;
-
-               str = g_string_new("");
-               g_string_printf(str, "[%" PRIu64 "]", i);
-               name = g_quark_from_string(str->str);
-               (void) g_string_free(str, TRUE);
-
-               field = (struct bt_definition **) &g_ptr_array_index(sequence_definition->elems, i);
-               *field = sequence_declaration->elem->definition_new(sequence_declaration->elem,
-                                         sequence_definition->p.scope,
-                                         name, i, NULL);
-       }
-       for (i = 0; i < len; i++) {
-               struct bt_definition **field;
-
-               field = (struct bt_definition **) &g_ptr_array_index(sequence_definition->elems, i);
-               ret = generic_rw(pos, *field);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static
-void _sequence_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_sequence *sequence_declaration =
-               container_of(declaration, struct declaration_sequence, p);
-
-       bt_free_declaration_scope(sequence_declaration->scope);
-       g_array_free(sequence_declaration->length_name, TRUE);
-       bt_declaration_unref(sequence_declaration->elem);
-       g_free(sequence_declaration);
-}
-
-struct declaration_sequence *
-       bt_sequence_declaration_new(const char *length,
-                         struct bt_declaration *elem_declaration,
-                         struct declaration_scope *parent_scope)
-{
-       struct declaration_sequence *sequence_declaration;
-       struct bt_declaration *declaration;
-
-       sequence_declaration = g_new(struct declaration_sequence, 1);
-       declaration = &sequence_declaration->p;
-
-       sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark));
-       bt_append_scope_path(length, sequence_declaration->length_name);
-
-       bt_declaration_ref(elem_declaration);
-       sequence_declaration->elem = elem_declaration;
-       sequence_declaration->scope = bt_new_declaration_scope(parent_scope);
-       declaration->id = BT_CTF_TYPE_ID_SEQUENCE;
-       declaration->alignment = elem_declaration->alignment;
-       declaration->declaration_free = _sequence_declaration_free;
-       declaration->definition_new = _sequence_definition_new;
-       declaration->definition_free = _sequence_definition_free;
-       declaration->ref = 1;
-       return sequence_declaration;
-}
-
-static
-struct bt_definition *_sequence_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name)
-{
-       struct declaration_sequence *sequence_declaration =
-               container_of(declaration, struct declaration_sequence, p);
-       struct definition_sequence *sequence;
-       struct bt_definition *len_parent;
-       int ret;
-
-       sequence = g_new(struct definition_sequence, 1);
-       bt_declaration_ref(&sequence_declaration->p);
-       sequence->p.declaration = declaration;
-       sequence->declaration = sequence_declaration;
-       sequence->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       sequence->p.index = root_name ? INT_MAX : index;
-       sequence->p.name = field_name;
-       sequence->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       sequence->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-       ret = bt_register_field_definition(field_name, &sequence->p,
-                                       parent_scope);
-       assert(!ret);
-       len_parent = bt_lookup_path_definition(sequence->p.scope->scope_path,
-                                           sequence_declaration->length_name,
-                                           parent_scope);
-       if (!len_parent) {
-               printf("[error] Lookup for sequence length field failed.\n");
-               goto error;
-       }
-       sequence->length =
-               container_of(len_parent, struct definition_integer, p);
-       if (sequence->length->declaration->signedness) {
-               printf("[error] Sequence length field should be unsigned.\n");
-               goto error;
-       }
-       bt_definition_ref(len_parent);
-
-       sequence->string = NULL;
-       sequence->elems = NULL;
-
-       if (sequence_declaration->elem->id == BT_CTF_TYPE_ID_INTEGER) {
-               struct declaration_integer *integer_declaration =
-                       container_of(sequence_declaration->elem, struct declaration_integer, p);
-
-               if (integer_declaration->encoding == CTF_STRING_UTF8
-                     || integer_declaration->encoding == CTF_STRING_ASCII) {
-
-                       sequence->string = g_string_new("");
-
-                       if (integer_declaration->len == CHAR_BIT
-                           && integer_declaration->p.alignment == CHAR_BIT) {
-                               return &sequence->p;
-                       }
-               }
-       }
-
-       sequence->elems = g_ptr_array_new();
-       return &sequence->p;
-
-error:
-       bt_free_definition_scope(sequence->p.scope);
-       bt_declaration_unref(&sequence_declaration->p);
-       g_free(sequence);
-       return NULL;
-}
-
-static
-void _sequence_definition_free(struct bt_definition *definition)
-{
-       struct definition_sequence *sequence =
-               container_of(definition, struct definition_sequence, p);
-       struct bt_definition *len_definition = &sequence->length->p;
-       uint64_t i;
-
-       if (sequence->string)
-               (void) g_string_free(sequence->string, TRUE);
-       if (sequence->elems) {
-               for (i = 0; i < sequence->elems->len; i++) {
-                       struct bt_definition *field;
-
-                       field = g_ptr_array_index(sequence->elems, i);
-                       field->declaration->definition_free(field);
-               }
-               (void) g_ptr_array_free(sequence->elems, TRUE);
-       }
-       bt_definition_unref(len_definition);
-       bt_free_definition_scope(sequence->p.scope);
-       bt_declaration_unref(sequence->p.declaration);
-       g_free(sequence);
-}
-
-uint64_t bt_sequence_len(struct definition_sequence *sequence)
-{
-       return sequence->length->value._unsigned;
-}
-
-struct bt_definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i)
-{
-       if (!sequence->elems)
-               return NULL;
-       if (i >= sequence->length->value._unsigned)
-               return NULL;
-       assert(i < sequence->elems->len);
-       return g_ptr_array_index(sequence->elems, i);
-}
diff --git a/types/string.c b/types/string.c
deleted file mode 100644 (file)
index 5bbba98..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * string.c
- *
- * BabelTrace - String Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/align.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-
-static
-struct bt_definition *_string_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name);
-static
-void _string_definition_free(struct bt_definition *definition);
-
-static
-void _string_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_string *string_declaration =
-               container_of(declaration, struct declaration_string, p);
-       g_free(string_declaration);
-}
-
-struct declaration_string *
-       bt_string_declaration_new(enum ctf_string_encoding encoding)
-{
-       struct declaration_string *string_declaration;
-
-       string_declaration = g_new(struct declaration_string, 1);
-       string_declaration->p.id = CTF_TYPE_STRING;
-       string_declaration->p.alignment = CHAR_BIT;
-       string_declaration->p.declaration_free = _string_declaration_free;
-       string_declaration->p.definition_new = _string_definition_new;
-       string_declaration->p.definition_free = _string_definition_free;
-       string_declaration->p.ref = 1;
-       string_declaration->encoding = encoding;
-       return string_declaration;
-}
-
-static
-struct bt_definition *
-       _string_definition_new(struct bt_declaration *declaration,
-                              struct definition_scope *parent_scope,
-                              GQuark field_name, int index,
-                              const char *root_name)
-{
-       struct declaration_string *string_declaration =
-               container_of(declaration, struct declaration_string, p);
-       struct definition_string *string;
-       int ret;
-
-       string = g_new(struct definition_string, 1);
-       bt_declaration_ref(&string_declaration->p);
-       string->p.declaration = declaration;
-       string->declaration = string_declaration;
-       string->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       string->p.index = root_name ? INT_MAX : index;
-       string->p.name = field_name;
-       string->p.path = bt_new_definition_path(parent_scope, field_name,
-                                       root_name);
-       string->p.scope = NULL;
-       string->value = NULL;
-       string->len = 0;
-       string->alloc_len = 0;
-       ret = bt_register_field_definition(field_name, &string->p,
-                                       parent_scope);
-       assert(!ret);
-       return &string->p;
-}
-
-static
-void _string_definition_free(struct bt_definition *definition)
-{
-       struct definition_string *string =
-               container_of(definition, struct definition_string, p);
-
-       bt_declaration_unref(string->p.declaration);
-       g_free(string->value);
-       g_free(string);
-}
-
-enum ctf_string_encoding bt_get_string_encoding(const struct bt_definition *field)
-{
-       struct definition_string *string_definition;
-       const struct declaration_string *string_declaration;
-
-       string_definition = container_of(field, struct definition_string, p);
-       string_declaration = string_definition->declaration;
-
-       return string_declaration->encoding;
-}
-
-char *bt_get_string(const struct bt_definition *field)
-{
-       struct definition_string *string_definition =
-               container_of(field, struct definition_string, p);
-
-       assert(string_definition->value != NULL);
-
-       return string_definition->value;
-}
diff --git a/types/struct.c b/types/struct.c
deleted file mode 100644 (file)
index e2f6a1e..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * struct.c
- *
- * BabelTrace - Structure Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <errno.h>
-
-#ifndef max
-#define max(a, b)      ((a) < (b) ? (b) : (a))
-#endif
-
-static
-struct bt_definition *_struct_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name);
-static
-void _struct_definition_free(struct bt_definition *definition);
-
-int bt_struct_rw(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_struct *struct_definition =
-               container_of(definition, struct definition_struct, p);
-       unsigned long i;
-       int ret;
-
-       for (i = 0; i < struct_definition->fields->len; i++) {
-               struct bt_definition *field =
-                       g_ptr_array_index(struct_definition->fields, i);
-               ret = generic_rw(ppos, field);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
-
-static
-void _struct_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_struct *struct_declaration =
-               container_of(declaration, struct declaration_struct, p);
-       unsigned long i;
-
-       bt_free_declaration_scope(struct_declaration->scope);
-       g_hash_table_destroy(struct_declaration->fields_by_name);
-
-       for (i = 0; i < struct_declaration->fields->len; i++) {
-               struct declaration_field *declaration_field =
-                       &g_array_index(struct_declaration->fields,
-                                      struct declaration_field, i);
-               bt_declaration_unref(declaration_field->declaration);
-       }
-       g_array_free(struct_declaration->fields, true);
-       g_free(struct_declaration);
-}
-
-struct declaration_struct *
-       bt_struct_declaration_new(struct declaration_scope *parent_scope,
-                              uint64_t min_align)
-{
-       struct declaration_struct *struct_declaration;
-       struct bt_declaration *declaration;
-
-       struct_declaration = g_new(struct declaration_struct, 1);
-       declaration = &struct_declaration->p;
-       struct_declaration->fields_by_name = g_hash_table_new(g_direct_hash,
-                                                      g_direct_equal);
-       struct_declaration->fields = g_array_sized_new(FALSE, TRUE,
-                                               sizeof(struct declaration_field),
-                                               DEFAULT_NR_STRUCT_FIELDS);
-       struct_declaration->scope = bt_new_declaration_scope(parent_scope);
-       declaration->id = CTF_TYPE_STRUCT;
-       declaration->alignment = max(1, min_align);
-       declaration->declaration_free = _struct_declaration_free;
-       declaration->definition_new = _struct_definition_new;
-       declaration->definition_free = _struct_definition_free;
-       declaration->ref = 1;
-       return struct_declaration;
-}
-
-static
-struct bt_definition *
-       _struct_definition_new(struct bt_declaration *declaration,
-                              struct definition_scope *parent_scope,
-                              GQuark field_name, int index,
-                              const char *root_name)
-{
-       struct declaration_struct *struct_declaration =
-               container_of(declaration, struct declaration_struct, p);
-       struct definition_struct *_struct;
-       int i;
-       int ret;
-
-       _struct = g_new(struct definition_struct, 1);
-       bt_declaration_ref(&struct_declaration->p);
-       _struct->p.declaration = declaration;
-       _struct->declaration = struct_declaration;
-       _struct->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       _struct->p.index = root_name ? INT_MAX : index;
-       _struct->p.name = field_name;
-       _struct->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       _struct->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-
-       ret = bt_register_field_definition(field_name, &_struct->p,
-                                       parent_scope);
-       assert(!ret || ret == -EPERM);
-
-       _struct->fields = g_ptr_array_sized_new(DEFAULT_NR_STRUCT_FIELDS);
-       g_ptr_array_set_size(_struct->fields, struct_declaration->fields->len);
-       for (i = 0; i < struct_declaration->fields->len; i++) {
-               struct declaration_field *declaration_field =
-                       &g_array_index(struct_declaration->fields,
-                                      struct declaration_field, i);
-               struct bt_definition **field =
-                       (struct bt_definition **) &g_ptr_array_index(_struct->fields, i);
-
-               *field = declaration_field->declaration->definition_new(declaration_field->declaration,
-                                                         _struct->p.scope,
-                                                         declaration_field->name, i, NULL);
-               if (!*field)
-                       goto error;
-       }
-       return &_struct->p;
-
-error:
-       for (i--; i >= 0; i--) {
-               struct bt_definition *field = g_ptr_array_index(_struct->fields, i);
-               bt_definition_unref(field);
-       }
-       bt_free_definition_scope(_struct->p.scope);
-       bt_declaration_unref(&struct_declaration->p);
-       g_free(_struct);
-       return NULL;
-}
-
-static
-void _struct_definition_free(struct bt_definition *definition)
-{
-       struct definition_struct *_struct =
-               container_of(definition, struct definition_struct, p);
-       unsigned long i;
-
-       assert(_struct->fields->len == _struct->declaration->fields->len);
-       for (i = 0; i < _struct->fields->len; i++) {
-               struct bt_definition *field = g_ptr_array_index(_struct->fields, i);
-               bt_definition_unref(field);
-       }
-       bt_free_definition_scope(_struct->p.scope);
-       bt_declaration_unref(_struct->p.declaration);
-       g_ptr_array_free(_struct->fields, TRUE);
-       g_free(_struct);
-}
-
-void bt_struct_declaration_add_field(struct declaration_struct *struct_declaration,
-                          const char *field_name,
-                          struct bt_declaration *field_declaration)
-{
-       struct declaration_field *field;
-       unsigned long index;
-
-       g_array_set_size(struct_declaration->fields, struct_declaration->fields->len + 1);
-       index = struct_declaration->fields->len - 1;    /* last field (new) */
-       field = &g_array_index(struct_declaration->fields, struct declaration_field, index);
-       field->name = g_quark_from_string(field_name);
-       bt_declaration_ref(field_declaration);
-       field->declaration = field_declaration;
-       /* Keep index in hash rather than pointer, because array can relocate */
-       g_hash_table_insert(struct_declaration->fields_by_name,
-                           GUINT_TO_POINTER(field->name),
-                           GUINT_TO_POINTER(index));
-       /*
-        * Alignment of structure is the max alignment of declarations contained
-        * therein.
-        */
-       struct_declaration->p.alignment = max(struct_declaration->p.alignment,
-                                      field_declaration->alignment);
-}
-
-/*
- * bt_struct_declaration_lookup_field_index - returns field index
- *
- * Returns the index of a field in a structure, or -1 if it does not
- * exist.
- */
-int bt_struct_declaration_lookup_field_index(struct declaration_struct *struct_declaration,
-                                      GQuark field_name)
-{
-       gpointer index;
-       gboolean found;
-
-       found = g_hash_table_lookup_extended(struct_declaration->fields_by_name,
-                                   (gconstpointer) GUINT_TO_POINTER(field_name),
-                                   NULL, &index);
-       if (!found)
-               return -1;
-       return GPOINTER_TO_INT(index);
-}
-
-/*
- * field returned only valid as long as the field structure is not appended to.
- */
-struct declaration_field *
-       bt_struct_declaration_get_field_from_index(struct declaration_struct *struct_declaration,
-                                        int index)
-{
-       if (index < 0)
-               return NULL;
-       return &g_array_index(struct_declaration->fields, struct declaration_field, index);
-}
-
-/*
- * field returned only valid as long as the field structure is not appended to.
- */
-struct bt_definition *
-bt_struct_definition_get_field_from_index(const struct definition_struct *_struct,
-                                       int index)
-{
-       if (index < 0)
-               return NULL;
-       return g_ptr_array_index(_struct->fields, index);
-}
-
-uint64_t bt_struct_declaration_len(const struct declaration_struct *struct_declaration)
-{
-       return struct_declaration->fields->len;
-}
diff --git a/types/types.c b/types/types.c
deleted file mode 100644 (file)
index f58d2e4..0000000
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * types.c
- *
- * BabelTrace - Converter
- *
- * Types registry.
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/format.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/compat/limits.h>
-#include <glib.h>
-#include <errno.h>
-
-static
-GQuark prefix_quark(const char *prefix, GQuark quark)
-{
-       GQuark nq;
-       GString *str;
-       char *quark_str;
-
-       str = g_string_new(prefix);
-       g_string_append(str, g_quark_to_string(quark));
-       quark_str = g_string_free(str, FALSE);
-       nq = g_quark_from_string(quark_str);
-       g_free(quark_str);
-       return nq;
-}
-
-static
-struct bt_declaration *
-       bt_lookup_declaration_scope(GQuark declaration_name,
-               struct declaration_scope *scope)
-{
-       return g_hash_table_lookup(scope->typedef_declarations,
-                                  (gconstpointer) GUINT_TO_POINTER(declaration_name));
-}
-
-struct bt_declaration *bt_lookup_declaration(GQuark declaration_name,
-               struct declaration_scope *scope)
-{
-       struct bt_declaration *declaration;
-
-       while (scope) {
-               declaration = bt_lookup_declaration_scope(declaration_name,
-                                                      scope);
-               if (declaration)
-                       return declaration;
-               scope = scope->parent_scope;
-       }
-       return NULL;
-}
-
-int bt_register_declaration(GQuark name, struct bt_declaration *declaration,
-               struct declaration_scope *scope)
-{
-       if (!name)
-               return -EPERM;
-
-       /* Only lookup in local scope */
-       if (bt_lookup_declaration_scope(name, scope))
-               return -EEXIST;
-
-       g_hash_table_insert(scope->typedef_declarations,
-                           GUINT_TO_POINTER(name),
-                           declaration);
-       bt_declaration_ref(declaration);
-       return 0;
-}
-
-static
-struct bt_definition *
-       lookup_field_definition_scope(GQuark field_name,
-               struct definition_scope *scope)
-{
-       return g_hash_table_lookup(scope->definitions,
-                                  (gconstpointer) GUINT_TO_POINTER(field_name));
-}
-
-/*
- * Returns the index at which the paths differ.
- * If the value returned equals len, it means the paths are identical
- * from index 0 to len-1.
- */
-static int compare_paths(GArray *a, GArray *b, int len)
-{
-       int i;
-
-       assert(len <= a->len);
-       assert(len <= b->len);
-
-       for (i = 0; i < len; i++) {
-               GQuark qa, qb;
-
-               qa = g_array_index(a, GQuark, i);
-               qb = g_array_index(b, GQuark, i);
-               if (qa != qb)
-                       return i;
-       }
-       return i;
-}
-
-static int is_path_child_of(GArray *path, GArray *maybe_parent)
-{
-       int ret;
-
-       if (babeltrace_debug) {
-               int i, need_dot = 0;
-
-               printf_debug("Is path \"");
-               for (i = 0; i < path->len; need_dot = 1, i++)
-                       printf("%s%s", need_dot ? "." : "",
-                               g_quark_to_string(g_array_index(path, GQuark, i)));
-               need_dot = 0;
-               printf("\" child of \"");
-               for (i = 0; i < maybe_parent->len; need_dot = 1, i++)
-                       printf("%s%s", need_dot ? "." : "",
-                               g_quark_to_string(g_array_index(maybe_parent, GQuark, i)));
-               printf("\" ? ");
-       }
-
-       if (path->len <= maybe_parent->len) {
-               ret = 0;
-               goto end;
-       }
-       if (compare_paths(path, maybe_parent, maybe_parent->len)
-                       == maybe_parent->len)
-               ret = 1;
-       else
-               ret = 0;
-end:
-       if (babeltrace_debug)
-               printf("%s\n", ret ? "Yes" : "No");
-       return ret;
-}
-
-static struct definition_scope *
-       get_definition_scope(const struct bt_definition *definition)
-{
-       return definition->scope;
-}
-
-/*
- * OK, here is the fun. We want to lookup a field that is:
- * - either in the same dynamic scope:
- *   - either in the current scope, but prior to the current field.
- *   - or in a parent scope (or parent of parent ...) still in a field
- *     prior to the current field position within the parents.
- * - or in a different dynamic scope:
- *   - either in a upper dynamic scope (walk down a targeted scope from
- *     the dynamic scope root)
- *   - or in a lower dynamic scope (failure)
- * The dynamic scope roots are linked together, so we can access the
- * parent dynamic scope from the child dynamic scope by walking up to
- * the parent.
- * If we cannot find such a field that is prior to our current path, we
- * return NULL.
- *
- * cur_path: the path leading to the variant definition.
- * lookup_path: the path leading to the enum we want to look for.
- * scope: the definition scope containing the variant definition.
- */
-struct bt_definition *
-       bt_lookup_path_definition(GArray *cur_path,
-                              GArray *lookup_path,
-                              struct definition_scope *scope)
-{
-       struct bt_definition *definition, *lookup_definition;
-       GQuark last;
-       int index;
-
-       /* Going up in the hierarchy. Check where we come from. */
-       assert(is_path_child_of(cur_path, scope->scope_path));
-       assert(cur_path->len - scope->scope_path->len == 1);
-
-       /*
-        * First, check if the target name is size one, present in
-        * our parent path, located prior to us.
-        */
-       if (lookup_path->len == 1) {
-               last = g_array_index(lookup_path, GQuark, 0);
-               lookup_definition = lookup_field_definition_scope(last, scope);
-               last = g_array_index(cur_path, GQuark, cur_path->len - 1);
-               definition = lookup_field_definition_scope(last, scope);
-               assert(definition);
-               if (lookup_definition && lookup_definition->index < definition->index)
-                       return lookup_definition;
-               else
-                       return NULL;
-       }
-
-       while (scope) {
-               if (is_path_child_of(cur_path, scope->scope_path) &&
-                   cur_path->len - scope->scope_path->len == 1) {
-                       last = g_array_index(cur_path, GQuark, cur_path->len - 1);
-                       definition = lookup_field_definition_scope(last, scope);
-                       assert(definition);
-                       index = definition->index;
-               } else {
-                       /*
-                        * Getting to a dynamic scope parent. We are
-                        * guaranteed that the parent is entirely
-                        * located before the child.
-                        */
-                       index = -1;
-               }
-lookup:
-               if (is_path_child_of(lookup_path, scope->scope_path)) {
-                       /* Means we can lookup the field in this scope */
-                       last = g_array_index(lookup_path, GQuark,
-                                            scope->scope_path->len);
-                       lookup_definition = lookup_field_definition_scope(last, scope);
-                       if (!lookup_definition || ((index != -1) && lookup_definition->index >= index))
-                               return NULL;
-                       /* Found it! And it is prior to the current field. */
-                       if (lookup_path->len - scope->scope_path->len == 1) {
-                               /* Direct child */
-                               return lookup_definition;
-                       } else {
-                               scope = get_definition_scope(lookup_definition);
-                               /* Check if the definition has a sub-scope */
-                               if (!scope)
-                                       return NULL;
-                               /*
-                                * Don't compare index anymore, because we are
-                                * going within a scope that has been validated
-                                * to be entirely prior to the current scope.
-                                */
-                               cur_path = NULL;
-                               index = -1;
-                               goto lookup;
-                       }
-               } else {
-                       /* lookup_path is within an upper scope */
-                       cur_path = scope->scope_path;
-                       scope = scope->parent_scope;
-               }
-       }
-       return NULL;
-}
-
-int bt_register_field_definition(GQuark field_name, struct bt_definition *definition,
-               struct definition_scope *scope)
-{
-       if (!scope || !field_name)
-               return -EPERM;
-
-       /* Only lookup in local scope */
-       if (lookup_field_definition_scope(field_name, scope))
-               return -EEXIST;
-
-       g_hash_table_insert(scope->definitions,
-                           GUINT_TO_POINTER(field_name),
-                           definition);
-       /* Don't keep reference on definition */
-       return 0;
-}
-
-void bt_declaration_ref(struct bt_declaration *declaration)
-{
-       declaration->ref++;
-}
-
-void bt_declaration_unref(struct bt_declaration *declaration)
-{
-       if (!declaration)
-               return;
-       if (!--declaration->ref)
-               declaration->declaration_free(declaration);
-}
-
-void bt_definition_ref(struct bt_definition *definition)
-{
-       definition->ref++;
-}
-
-void bt_definition_unref(struct bt_definition *definition)
-{
-       if (!definition)
-               return;
-       if (!--definition->ref)
-               definition->declaration->definition_free(definition);
-}
-
-struct declaration_scope *
-       bt_new_declaration_scope(struct declaration_scope *parent_scope)
-{
-       struct declaration_scope *scope = g_new(struct declaration_scope, 1);
-
-       scope->typedef_declarations = g_hash_table_new_full(g_direct_hash,
-                                       g_direct_equal, NULL,
-                                       (GDestroyNotify) bt_declaration_unref);
-       scope->struct_declarations = g_hash_table_new_full(g_direct_hash,
-                                       g_direct_equal, NULL,
-                                       (GDestroyNotify) bt_declaration_unref);
-       scope->variant_declarations = g_hash_table_new_full(g_direct_hash,
-                                       g_direct_equal, NULL,
-                                       (GDestroyNotify) bt_declaration_unref);
-       scope->enum_declarations = g_hash_table_new_full(g_direct_hash,
-                                       g_direct_equal, NULL,
-                                       (GDestroyNotify) bt_declaration_unref);
-       scope->parent_scope = parent_scope;
-       return scope;
-}
-
-void bt_free_declaration_scope(struct declaration_scope *scope)
-{
-       g_hash_table_destroy(scope->enum_declarations);
-       g_hash_table_destroy(scope->variant_declarations);
-       g_hash_table_destroy(scope->struct_declarations);
-       g_hash_table_destroy(scope->typedef_declarations);
-       g_free(scope);
-}
-
-static
-struct declaration_struct *bt_lookup_struct_declaration_scope(GQuark struct_name,
-                                            struct declaration_scope *scope)
-{
-       return g_hash_table_lookup(scope->struct_declarations,
-                                  (gconstpointer) GUINT_TO_POINTER(struct_name));
-}
-
-struct declaration_struct *bt_lookup_struct_declaration(GQuark struct_name,
-                                      struct declaration_scope *scope)
-{
-       struct declaration_struct *declaration;
-
-       while (scope) {
-               declaration = bt_lookup_struct_declaration_scope(struct_name, scope);
-               if (declaration)
-                       return declaration;
-               scope = scope->parent_scope;
-       }
-       return NULL;
-}
-
-int bt_register_struct_declaration(GQuark struct_name,
-       struct declaration_struct *struct_declaration,
-       struct declaration_scope *scope)
-{
-       GQuark prefix_name;
-       int ret;
-
-       if (!struct_name)
-               return -EPERM;
-
-       /* Only lookup in local scope */
-       if (bt_lookup_struct_declaration_scope(struct_name, scope))
-               return -EEXIST;
-
-       g_hash_table_insert(scope->struct_declarations,
-                           GUINT_TO_POINTER(struct_name),
-                           struct_declaration);
-       bt_declaration_ref(&struct_declaration->p);
-
-       /* Also add in typedef/typealias scopes */
-       prefix_name = prefix_quark("struct ", struct_name);
-       ret = bt_register_declaration(prefix_name, &struct_declaration->p, scope);
-       assert(!ret);
-       return 0;
-}
-
-static
-struct declaration_untagged_variant *
-       bt_lookup_variant_declaration_scope(GQuark variant_name,
-               struct declaration_scope *scope)
-{
-       return g_hash_table_lookup(scope->variant_declarations,
-                                  (gconstpointer) GUINT_TO_POINTER(variant_name));
-}
-
-struct declaration_untagged_variant *
-       bt_lookup_variant_declaration(GQuark variant_name,
-               struct declaration_scope *scope)
-{
-       struct declaration_untagged_variant *declaration;
-
-       while (scope) {
-               declaration = bt_lookup_variant_declaration_scope(variant_name, scope);
-               if (declaration)
-                       return declaration;
-               scope = scope->parent_scope;
-       }
-       return NULL;
-}
-
-int bt_register_variant_declaration(GQuark variant_name,
-               struct declaration_untagged_variant *untagged_variant_declaration,
-               struct declaration_scope *scope)
-{
-       GQuark prefix_name;
-       int ret;
-
-       if (!variant_name)
-               return -EPERM;
-
-       /* Only lookup in local scope */
-       if (bt_lookup_variant_declaration_scope(variant_name, scope))
-               return -EEXIST;
-
-       g_hash_table_insert(scope->variant_declarations,
-                           GUINT_TO_POINTER(variant_name),
-                           untagged_variant_declaration);
-       bt_declaration_ref(&untagged_variant_declaration->p);
-
-       /* Also add in typedef/typealias scopes */
-       prefix_name = prefix_quark("variant ", variant_name);
-       ret = bt_register_declaration(prefix_name,
-                       &untagged_variant_declaration->p, scope);
-       assert(!ret);
-       return 0;
-}
-
-static
-struct declaration_enum *
-       bt_lookup_enum_declaration_scope(GQuark enum_name,
-               struct declaration_scope *scope)
-{
-       return g_hash_table_lookup(scope->enum_declarations,
-                                  (gconstpointer) GUINT_TO_POINTER(enum_name));
-}
-
-struct declaration_enum *
-       bt_lookup_enum_declaration(GQuark enum_name,
-               struct declaration_scope *scope)
-{
-       struct declaration_enum *declaration;
-
-       while (scope) {
-               declaration = bt_lookup_enum_declaration_scope(enum_name, scope);
-               if (declaration)
-                       return declaration;
-               scope = scope->parent_scope;
-       }
-       return NULL;
-}
-
-int bt_register_enum_declaration(GQuark enum_name,
-               struct declaration_enum *enum_declaration,
-               struct declaration_scope *scope)
-{
-       GQuark prefix_name;
-       int ret;
-
-       if (!enum_name)
-               return -EPERM;
-
-       /* Only lookup in local scope */
-       if (bt_lookup_enum_declaration_scope(enum_name, scope))
-               return -EEXIST;
-
-       g_hash_table_insert(scope->enum_declarations,
-                           GUINT_TO_POINTER(enum_name),
-                           enum_declaration);
-       bt_declaration_ref(&enum_declaration->p);
-
-       /* Also add in typedef/typealias scopes */
-       prefix_name = prefix_quark("enum ", enum_name);
-       ret = bt_register_declaration(prefix_name, &enum_declaration->p, scope);
-       assert(!ret);
-       return 0;
-}
-
-static struct definition_scope *
-       _bt_new_definition_scope(struct definition_scope *parent_scope,
-                             int scope_path_len)
-{
-       struct definition_scope *scope = g_new(struct definition_scope, 1);
-
-       scope->definitions = g_hash_table_new(g_direct_hash,
-                                       g_direct_equal);
-       scope->parent_scope = parent_scope;
-       scope->scope_path = g_array_sized_new(FALSE, TRUE, sizeof(GQuark),
-                                             scope_path_len);
-       g_array_set_size(scope->scope_path, scope_path_len);
-       return scope;
-}
-
-GQuark bt_new_definition_path(struct definition_scope *parent_scope,
-                          GQuark field_name, const char *root_name)
-{
-       GQuark path;
-       GString *str;
-       gchar *c_str;
-       int need_dot = 0;
-
-       str = g_string_new("");
-       if (root_name) {
-               g_string_append(str, root_name);
-               need_dot = 1;
-       } else if (parent_scope) {
-               int i;
-
-               for (i = 0; i < parent_scope->scope_path->len; i++) {
-                       GQuark q = g_array_index(parent_scope->scope_path,
-                                                GQuark, i);
-                       if (!q)
-                               continue;
-                       if (need_dot)
-                               g_string_append(str, ".");
-                       g_string_append(str, g_quark_to_string(q));
-                       need_dot = 1;
-               }
-       }
-       if (field_name) {
-               if (need_dot)
-                       g_string_append(str, ".");
-               g_string_append(str, g_quark_to_string(field_name));
-       }
-       c_str = g_string_free(str, FALSE);
-       if (c_str[0] == '\0')
-               return 0;
-       path = g_quark_from_string(c_str);
-       printf_debug("new definition path: %s\n", c_str);
-       g_free(c_str);
-       return path;
-}
-
-struct definition_scope *
-       bt_new_definition_scope(struct definition_scope *parent_scope,
-                            GQuark field_name, const char *root_name)
-{
-       struct definition_scope *scope;
-
-       if (root_name) {
-               scope = _bt_new_definition_scope(parent_scope, 0);
-               bt_append_scope_path(root_name, scope->scope_path);
-       } else {
-               int scope_path_len = 1;
-
-               assert(parent_scope);
-               scope_path_len += parent_scope->scope_path->len;
-               scope = _bt_new_definition_scope(parent_scope, scope_path_len);
-               memcpy(scope->scope_path->data, parent_scope->scope_path->data,
-                      sizeof(GQuark) * (scope_path_len - 1));
-               g_array_index(scope->scope_path, GQuark, scope_path_len - 1) =
-                       field_name;
-       }
-       if (babeltrace_debug) {
-               int i, need_dot = 0;
-
-               printf_debug("new definition scope: ");
-               for (i = 0; i < scope->scope_path->len; need_dot = 1, i++)
-                       printf("%s%s", need_dot ? "." : "",
-                               g_quark_to_string(g_array_index(scope->scope_path, GQuark, i)));
-               printf("\n");
-       }
-       return scope;
-}
-
-/*
- * in: path (dot separated), out: q (GArray of GQuark)
- */
-void bt_append_scope_path(const char *path, GArray *q)
-{
-       const char *ptrbegin, *ptrend = path;
-       GQuark quark;
-
-       for (;;) {
-               char *str;
-               size_t len;
-
-               ptrbegin = ptrend;
-               ptrend = strchr(ptrbegin, '.');
-               if (!ptrend)
-                       break;
-               len = ptrend - ptrbegin;
-               /* Don't accept two consecutive dots */
-               assert(len != 0);
-               str = g_new(char, len + 1);     /* include \0 */
-               memcpy(str, ptrbegin, len);
-               str[len] = '\0';
-               quark = g_quark_from_string(str);
-               g_array_append_val(q, quark);
-               g_free(str);
-               ptrend++;       /* skip current dot */
-       }
-       /* last. Check for trailing dot (and discard). */
-       if (ptrbegin[0] != '\0') {
-               quark = g_quark_from_string(ptrbegin);
-               g_array_append_val(q, quark);
-       }
-}
-
-void bt_free_definition_scope(struct definition_scope *scope)
-{
-       g_array_free(scope->scope_path, TRUE);
-       g_hash_table_destroy(scope->definitions);
-       g_free(scope);
-}
-
-struct bt_definition *bt_lookup_definition(const struct bt_definition *definition,
-                                    const char *field_name)
-{
-       struct definition_scope *scope = get_definition_scope(definition);
-
-       if (!scope)
-               return NULL;
-
-       return lookup_field_definition_scope(g_quark_from_string(field_name),
-                                            scope);
-}
-
-struct definition_integer *bt_lookup_integer(const struct bt_definition *definition,
-                                         const char *field_name,
-                                         int signedness)
-{
-       struct bt_definition *lookup;
-       struct definition_integer *lookup_integer;
-
-       lookup = bt_lookup_definition(definition, field_name);
-       if (!lookup)
-               return NULL;
-       if (lookup->declaration->id != BT_CTF_TYPE_ID_INTEGER)
-               return NULL;
-       lookup_integer = container_of(lookup, struct definition_integer, p);
-       if (lookup_integer->declaration->signedness != signedness)
-               return NULL;
-       return lookup_integer;
-}
-
-struct definition_enum *bt_lookup_enum(const struct bt_definition *definition,
-                                   const char *field_name,
-                                   int signedness)
-{
-       struct bt_definition *lookup;
-       struct definition_enum *lookup_enum;
-
-       lookup = bt_lookup_definition(definition, field_name);
-       if (!lookup)
-               return NULL;
-       if (lookup->declaration->id != BT_CTF_TYPE_ID_ENUM)
-               return NULL;
-       lookup_enum = container_of(lookup, struct definition_enum, p);
-       if (lookup_enum->integer->declaration->signedness != signedness)
-               return NULL;
-       return lookup_enum;
-}
-
-struct bt_definition *bt_lookup_variant(const struct bt_definition *definition,
-                                 const char *field_name)
-{
-       struct bt_definition *lookup;
-       struct definition_variant *bt_lookup_variant;
-
-       lookup = bt_lookup_definition(definition, field_name);
-       if (!lookup)
-               return NULL;
-       if (lookup->declaration->id != BT_CTF_TYPE_ID_VARIANT)
-               return NULL;
-       bt_lookup_variant = container_of(lookup, struct definition_variant, p);
-       lookup = bt_variant_get_current_field(bt_lookup_variant);
-       assert(lookup);
-       return lookup;
-}
diff --git a/types/variant.c b/types/variant.c
deleted file mode 100644 (file)
index f660e18..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * variant.c
- *
- * BabelTrace - Variant Type Converter
- *
- * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
- *
- * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
-#include <babeltrace/format.h>
-#include <babeltrace/types.h>
-#include <errno.h>
-
-static
-struct bt_definition *_variant_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name);
-static
-void _variant_definition_free(struct bt_definition *definition);
-
-int bt_variant_rw(struct bt_stream_pos *ppos, struct bt_definition *definition)
-{
-       struct definition_variant *variant_definition =
-               container_of(definition, struct definition_variant, p);
-       struct bt_definition *field;
-
-       field = bt_variant_get_current_field(variant_definition);
-       if (!field) {
-               return -EINVAL;
-       }
-       return generic_rw(ppos, field);
-}
-
-static
-void _untagged_variant_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_untagged_variant *untagged_variant_declaration =
-               container_of(declaration, struct declaration_untagged_variant, p);
-       unsigned long i;
-
-       bt_free_declaration_scope(untagged_variant_declaration->scope);
-       g_hash_table_destroy(untagged_variant_declaration->fields_by_tag);
-
-       for (i = 0; i < untagged_variant_declaration->fields->len; i++) {
-               struct declaration_field *declaration_field =
-                       &g_array_index(untagged_variant_declaration->fields,
-                                      struct declaration_field, i);
-               bt_declaration_unref(declaration_field->declaration);
-       }
-       g_array_free(untagged_variant_declaration->fields, true);
-       g_free(untagged_variant_declaration);
-}
-
-struct declaration_untagged_variant *bt_untagged_bt_variant_declaration_new(
-                                     struct declaration_scope *parent_scope)
-{
-       struct declaration_untagged_variant *untagged_variant_declaration;
-       struct bt_declaration *declaration;
-
-       untagged_variant_declaration = g_new(struct declaration_untagged_variant, 1);
-       declaration = &untagged_variant_declaration->p;
-       untagged_variant_declaration->fields_by_tag = g_hash_table_new(g_direct_hash,
-                                                      g_direct_equal);
-       untagged_variant_declaration->fields = g_array_sized_new(FALSE, TRUE,
-                                                sizeof(struct declaration_field),
-                                                DEFAULT_NR_STRUCT_FIELDS);
-       untagged_variant_declaration->scope = bt_new_declaration_scope(parent_scope);
-       declaration->id = CTF_TYPE_UNTAGGED_VARIANT;
-       declaration->alignment = 1;
-       declaration->declaration_free = _untagged_variant_declaration_free;
-       declaration->definition_new = NULL;
-       declaration->definition_free = NULL;
-       declaration->ref = 1;
-       return untagged_variant_declaration;
-}
-
-static
-void _variant_declaration_free(struct bt_declaration *declaration)
-{
-       struct declaration_variant *variant_declaration =
-               container_of(declaration, struct declaration_variant, p);
-
-       bt_declaration_unref(&variant_declaration->untagged_variant->p);
-       g_array_free(variant_declaration->tag_name, TRUE);
-       g_free(variant_declaration);
-}
-
-struct declaration_variant *
-       bt_variant_declaration_new(struct declaration_untagged_variant *untagged_variant, const char *tag)
-{
-       struct declaration_variant *variant_declaration;
-       struct bt_declaration *declaration;
-
-       variant_declaration = g_new(struct declaration_variant, 1);
-       declaration = &variant_declaration->p;
-       variant_declaration->untagged_variant = untagged_variant;
-       bt_declaration_ref(&untagged_variant->p);
-       variant_declaration->tag_name = g_array_new(FALSE, TRUE, sizeof(GQuark));
-       bt_append_scope_path(tag, variant_declaration->tag_name);
-       declaration->id = CTF_TYPE_VARIANT;
-       declaration->alignment = 1;
-       declaration->declaration_free = _variant_declaration_free;
-       declaration->definition_new = _variant_definition_new;
-       declaration->definition_free = _variant_definition_free;
-       declaration->ref = 1;
-       return variant_declaration;
-}
-
-static
-struct bt_definition *
-       _variant_definition_new(struct bt_declaration *declaration,
-                               struct definition_scope *parent_scope,
-                               GQuark field_name, int index,
-                               const char *root_name)
-{
-       struct declaration_variant *variant_declaration =
-               container_of(declaration, struct declaration_variant, p);
-       struct definition_variant *variant;
-       unsigned long i;
-       int ret;
-
-       variant = g_new(struct definition_variant, 1);
-       bt_declaration_ref(&variant_declaration->p);
-       variant->p.declaration = declaration;
-       variant->declaration = variant_declaration;
-       variant->p.ref = 1;
-       /*
-        * Use INT_MAX order to ensure that all fields of the parent
-        * scope are seen as being prior to this scope.
-        */
-       variant->p.index = root_name ? INT_MAX : index;
-       variant->p.name = field_name;
-       variant->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
-       variant->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
-
-       ret = bt_register_field_definition(field_name, &variant->p,
-                                       parent_scope);
-       assert(!ret);
-
-       variant->enum_tag = bt_lookup_path_definition(variant->p.scope->scope_path,
-                                                  variant_declaration->tag_name,
-                                                  parent_scope);
-                                             
-       if (!variant->enum_tag)
-               goto error;
-       bt_definition_ref(variant->enum_tag);
-       variant->fields = g_ptr_array_sized_new(variant_declaration->untagged_variant->fields->len);
-       g_ptr_array_set_size(variant->fields, variant_declaration->untagged_variant->fields->len);
-       for (i = 0; i < variant_declaration->untagged_variant->fields->len; i++) {
-               struct declaration_field *declaration_field =
-                       &g_array_index(variant_declaration->untagged_variant->fields,
-                                      struct declaration_field, i);
-               struct bt_definition **field =
-                       (struct bt_definition **) &g_ptr_array_index(variant->fields, i);
-
-               /*
-                * All child definition are at index 0, because they are
-                * various choices of the same field.
-                */
-               *field = declaration_field->declaration->definition_new(declaration_field->declaration,
-                                                 variant->p.scope,
-                                                 declaration_field->name, 0, NULL);
-               if (!*field)
-                       goto error;
-       }
-       variant->current_field = NULL;
-       return &variant->p;
-error:
-       bt_free_definition_scope(variant->p.scope);
-       bt_declaration_unref(&variant_declaration->p);
-       g_free(variant);
-       return NULL;
-}
-
-static
-void _variant_definition_free(struct bt_definition *definition)
-{
-       struct definition_variant *variant =
-               container_of(definition, struct definition_variant, p);
-       unsigned long i;
-
-       assert(variant->fields->len == variant->declaration->untagged_variant->fields->len);
-       for (i = 0; i < variant->fields->len; i++) {
-               struct bt_definition *field = g_ptr_array_index(variant->fields, i);
-               bt_definition_unref(field);
-       }
-       bt_definition_unref(variant->enum_tag);
-       bt_free_definition_scope(variant->p.scope);
-       bt_declaration_unref(variant->p.declaration);
-       g_ptr_array_free(variant->fields, TRUE);
-       g_free(variant);
-}
-
-void bt_untagged_variant_declaration_add_field(struct declaration_untagged_variant *untagged_variant_declaration,
-                           const char *field_name,
-                           struct bt_declaration *field_declaration)
-{
-       struct declaration_field *field;
-       unsigned long index;
-
-       g_array_set_size(untagged_variant_declaration->fields, untagged_variant_declaration->fields->len + 1);
-       index = untagged_variant_declaration->fields->len - 1;  /* last field (new) */
-       field = &g_array_index(untagged_variant_declaration->fields, struct declaration_field, index);
-       field->name = g_quark_from_string(field_name);
-       bt_declaration_ref(field_declaration);
-       field->declaration = field_declaration;
-       /* Keep index in hash rather than pointer, because array can relocate */
-       g_hash_table_insert(untagged_variant_declaration->fields_by_tag,
-                           GUINT_TO_POINTER(field->name),
-                           GUINT_TO_POINTER(index));
-       /*
-        * Alignment of variant is based on the alignment of its currently
-        * selected choice, so we leave variant alignment as-is (statically
-        * speaking).
-        */
-}
-
-struct declaration_field *
-bt_untagged_variant_declaration_get_field_from_tag(struct declaration_untagged_variant *untagged_variant_declaration, GQuark tag)
-{
-       gpointer index;
-       gboolean found;
-
-       found = g_hash_table_lookup_extended(
-                               untagged_variant_declaration->fields_by_tag,
-                               (gconstpointer) GUINT_TO_POINTER(tag), NULL, &index);
-
-       if (!found) {
-               return NULL;
-       }
-
-       return &g_array_index(untagged_variant_declaration->fields, struct declaration_field, GPOINTER_TO_UINT(index));
-}
-
-/*
- * field returned only valid as long as the field structure is not appended to.
- */
-struct bt_definition *bt_variant_get_current_field(struct definition_variant *variant)
-{
-       struct definition_enum *_enum =
-               container_of(variant->enum_tag, struct definition_enum, p);
-       struct declaration_variant *variant_declaration = variant->declaration;
-       unsigned long index;
-       GArray *tag_array;
-       GQuark tag;
-       gpointer orig_key, value;
-
-       tag_array = _enum->value;
-       if (!tag_array) {
-               /* Enumeration has unknown tag. */
-               fprintf(stderr, "[error] Enumeration used for variant has unknown tag.\n");
-               return NULL;
-       }
-       /*
-        * The 1 to 1 mapping from enumeration to value should have been already
-        * checked. (see TODO above)
-        */
-       assert(tag_array->len == 1);
-       tag = g_array_index(tag_array, GQuark, 0);
-       if (!g_hash_table_lookup_extended(variant_declaration->untagged_variant->fields_by_tag,
-                       (gconstpointer) GUINT_TO_POINTER(tag),
-                       &orig_key,
-                       &value)) {
-               /* Cannot find matching field. */
-               fprintf(stderr, "[error] Cannot find matching field for enum field \"%s\" in variant.\n",
-                       g_quark_to_string(tag));
-               return NULL;
-       }
-       index = GPOINTER_TO_UINT(value);
-       variant->current_field = g_ptr_array_index(variant->fields, index);
-       return variant->current_field;
-}
This page took 0.733994 seconds and 4 git commands to generate.