Merge branch 'master' into bindings/python
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 16 Jan 2013 22:56:46 +0000 (17:56 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 16 Jan 2013 22:56:46 +0000 (17:56 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
113 files changed:
.gitignore
ChangeLog
LICENSE
Makefile.am
README
babeltrace.pc.in [new file with mode: 0644]
configure.ac
converter/babeltrace-log.c
converter/babeltrace.c
doc/API.txt
doc/Makefile.am
doc/development.txt [new file with mode: 0644]
extras/Makefile.am [new file with mode: 0644]
extras/valgrind/Makefile.am [new file with mode: 0644]
extras/valgrind/popt.supp [new file with mode: 0644]
formats/bt-dummy/bt-dummy.c
formats/ctf-text/ctf-text.c
formats/ctf-text/types/array.c
formats/ctf-text/types/enum.c
formats/ctf-text/types/float.c
formats/ctf-text/types/integer.c
formats/ctf-text/types/sequence.c
formats/ctf-text/types/string.c
formats/ctf-text/types/struct.c
formats/ctf-text/types/variant.c
formats/ctf/callbacks.c
formats/ctf/ctf.c
formats/ctf/events-private.h
formats/ctf/events.c
formats/ctf/iterator.c
formats/ctf/memstream.h
formats/ctf/metadata/ctf-ast.h
formats/ctf/metadata/ctf-lexer.l
formats/ctf/metadata/ctf-parser-test.c
formats/ctf/metadata/ctf-parser.y
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
formats/ctf/metadata/ctf-visitor-parent-links.c
formats/ctf/metadata/ctf-visitor-semantic-validator.c
formats/ctf/metadata/ctf-visitor-xml.c
formats/ctf/types/array.c
formats/ctf/types/enum.c
formats/ctf/types/float.c
formats/ctf/types/integer.c
formats/ctf/types/sequence.c
formats/ctf/types/string.c
formats/ctf/types/struct.c
formats/ctf/types/variant.c
include/babeltrace/align.h
include/babeltrace/babeltrace-internal.h
include/babeltrace/babeltrace.h
include/babeltrace/bitfield.h
include/babeltrace/clock-internal.h
include/babeltrace/clock-types.h
include/babeltrace/compiler.h
include/babeltrace/context-internal.h
include/babeltrace/context.h
include/babeltrace/ctf-ir/metadata.h
include/babeltrace/ctf-text/types.h
include/babeltrace/ctf/callbacks-internal.h
include/babeltrace/ctf/callbacks.h
include/babeltrace/ctf/events-internal.h
include/babeltrace/ctf/events.h
include/babeltrace/ctf/iterator.h
include/babeltrace/ctf/metadata.h
include/babeltrace/ctf/types.h
include/babeltrace/endian.h
include/babeltrace/format.h
include/babeltrace/iterator-internal.h
include/babeltrace/iterator.h
include/babeltrace/mmap-align.h
include/babeltrace/prio_heap.h
include/babeltrace/trace-collection.h
include/babeltrace/trace-handle-internal.h
include/babeltrace/trace-handle.h
include/babeltrace/types.h
include/babeltrace/uuid.h
lgpl-2.1.txt [new file with mode: 0644]
lib/babeltrace.c
lib/context.c
lib/iterator.c
lib/prio_heap/prio_heap.c
lib/registry.c
lib/trace-collection.c
lib/trace-handle.c
mit-license.txt
tests/Makefile.am
tests/ctf-traces/succeed/wk-heartbeat-u/metadata [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_0 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_1 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_2 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_3 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_4 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_5 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_6 [new file with mode: 0755]
tests/ctf-traces/succeed/wk-heartbeat-u/u_7 [new file with mode: 0755]
tests/lib/Makefile.am [new file with mode: 0644]
tests/lib/README.tap [new file with mode: 0644]
tests/lib/common.c [new file with mode: 0644]
tests/lib/common.h [new file with mode: 0644]
tests/lib/runall.sh [new file with mode: 0755]
tests/lib/tap.c [new file with mode: 0644]
tests/lib/tap.h [new file with mode: 0644]
tests/lib/test-seeks.c [new file with mode: 0644]
tests/runall.sh [new file with mode: 0755]
types/array.c
types/enum.c
types/float.c
types/integer.c
types/sequence.c
types/string.c
types/struct.c
types/types.c
types/variant.c

index d7b0ca1bead3f24a66be024f672a83088e5d4821..e4562869ae1de93909c82cf64dc475491c112e4a 100644 (file)
@@ -1,5 +1,6 @@
 /tests/test-bitfield
 *~
+/tests/lib/test-seeks
 *.o
 *.a
 *.la
index 1ad948eaca40234621d0815e745ba63b34467da0..a62ebebfc6a4c9f57080fa90eef634231c38c513 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,65 @@
+2012-01-11 Babeltrace 1.0.2
+       * Fix: add tests/lib missing files to Makefile.am
+
+2012-01-11 Babeltrace 1.0.1
+       * Provides a basic pkg-config file for libbabeltrace
+       * Fix erroneous warning/error messages
+       * Fix comment in context.h
+       * Cleanup: Remove whitespace at EOL from mit-license.txt
+       * Add missing permission notice in each source file
+       * Adding a test which do a sequence of seek BEGIN, LAST, BEGIN, LAST
+       * Run seek tests on a second trace file
+       * Add #define _GNU_SOURCE to remove warning about asprintf
+       * Include a test for SEEK_BEGIN and SEEK_LAST
+       * Fix: Report success even if we find at least one valid stream in find_max_timestamp_ctf_stream_class
+       * Fix SEEK_BEGIN for streams that do not contain any event
+
+2012-10-27 Babeltrace 1.0.0
+       * tests: add test traces to distribution tarball
+       * Document bash requirement for make check in README
+       * Add tests to make check
+       * Fix: add missing header size validation
+       * callbacks.c: handle extract_ctf_stream_event return value
+       * Cleanup: fix cppcheck warning
+       * Cleanup: fix cppcheck warnings
+       * fix double-free on error path
+
+2012-10-18 Babeltrace 1.0.0-rc6
+       * Add valgrind suppression file for libpopt
+       * Fix: unplug memory leak that causes popt-0.13 to segfault
+       * Fix: test all close/fclose ret val, fix double close
+       * Cleanup: add missing newline
+       * Fix: fd leak on trace close
+       * Fix memory leaks induced by lack of libpopt documentation
+       * babeltrace: fix poptGetOptArg memleak
+       * plugins: implement plugin unregister
+       * Doc: valgrind with babeltrace (glib workaround)
+       * callsites: fix memory leak
+       * Fix: free all the metadata-related memory
+       * Fix : Free the iterator callback arrays
+       * Fix : cleanup teardown of context
+       * Fix : protect static float and double declarations
+       * callsite: support instruction pointer field
+       * Document that list.h is LGPLv2.1, but entirely trivial
+       * Fix: callsite support: list multiple callsites
+       * Add callsite support
+       * Fix: Allow 64-bit packet offset
+       * Fix: emf uri: surround by " "
+       * Handle model.emf.uri event info
+       * Fix: Documentation cleanup
+       * Fix: misplaced C++ ifdef
+       * Fix babeltrace-log get big line when the input file last line don't have enter
+       * API Fix: bt_ctf_iter_read_event_flags
+       * Fix: get encoding for char arrays and sequences
+       * Fix: access to declaration from declaration_field
+       * Fix: get_declaration_* should not cast to field
+       * Fix babeltrace-log uninitialized memory (v2)
+       * Revert "Fix babeltrace-log uninitialized memory"
+       * Fix babeltrace-log uninitialized memory
+       * Fix: access field properties by declaration
+       * Fix: check return value of get_char_array
+       * Fix: C++ support to API header files
+
 2012-08-27 Babeltrace 1.0.0-rc5
        * Change default printout to add host, process names and vpid
        * Add support for trace:hostname field
diff --git a/LICENSE b/LICENSE
index d4af9bbf69cf3514bc173fe49e0514a6eaea509f..816d185e0886ebbbd6490b1affc10ef9839b1e7a 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -13,3 +13,10 @@ in both free and proprietary software. See mit-license.txt for details.
 
 Library test code is distributed under the GPLv2 license, as specified in the
 per-file license. See gpl-2.0.txt for details.
+
+* LGPLv2.1
+
+The file include/babeltrace/list.h is licensed under LGPLv2.1. It only
+contains trivial static inline functions and macros, and, therefore,
+including it does not make babeltrace a derivative work on this header.
+Please refer to the LGPLv2.1 license for details.
index 6584c5d2985c8498b01b63db94c9a0fd0c7829fd..d28fbc0f78f2e233e172bfc5b774c40eb0ae6011 100644 (file)
@@ -2,9 +2,12 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = include types lib formats converter bindings tests doc
+SUBDIRS = include types lib formats converter bindings tests doc extras
 
 dist_doc_DATA = ChangeLog LICENSE mit-license.txt gpl-2.0.txt \
                std-ext-lib.txt
 
 dist_noinst_DATA = CodingStyle
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = babeltrace.pc
diff --git a/README b/README
index 1687075bba2ce9b065d1ce1fec622800dec927af..9df02e7094b7f7748dbe644c540934bbc8111690 100644 (file)
--- a/README
+++ b/README
@@ -67,3 +67,5 @@ compile the git repository tree :
 If you get the tree from the repository, you will need to use the "bootstrap"
 script in the root of the tree. It calls all the GNU tools needed to prepare the
 tree configuration.
+
+Running "make check": bash is required.
diff --git a/babeltrace.pc.in b/babeltrace.pc.in
new file mode 100644 (file)
index 0000000..12349dd
--- /dev/null
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Babeltrace
+Description: libbabeltrace provides a reader for trace files, reading mainly the 
+Common Trace Format (CTF).
+Version: @PACKAGE_VERSION@
+Requires:
+Requires.private: uuid popt
+Libs: -L${libdir} -lbabeltrace -lbabeltrace-ctf
+Cflags: -I${includedir} 
+
index 24ee2a6290046c6baac0be9ef344f6bfd865dcea..aab61999ecf32229c65b4ae23dbabda58bb31066 100644 (file)
@@ -1,7 +1,7 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT([babeltrace],[1.0.0-rc5],[mathieu dot desnoyers at efficios dot com])
+AC_INIT([babeltrace],[1.0.2],[mathieu dot desnoyers at efficios dot com])
 AC_CONFIG_AUX_DIR([config])
 AC_CANONICAL_TARGET
 AC_CANONICAL_HOST
@@ -143,5 +143,9 @@ AC_CONFIG_FILES([
        bindings/Makefile
        bindings/python/Makefile
        tests/Makefile
+       tests/lib/Makefile
+       extras/Makefile
+       extras/valgrind/Makefile
+       babeltrace.pc
 ])
 AC_OUTPUT
index 6ac94e69236c3cb7f29d806aa0369b63bf5b2d4b..214871192b2e3034d90a16c5b99c0d8a1babea55 100644 (file)
  * 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.
+ *
  * Depends on glibc 2.10 for getline().
  */
 
@@ -33,6 +41,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
+#include <inttypes.h>
 
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/ctf/types.h>
@@ -53,6 +62,7 @@ static const char metadata_fmt[] =
 "/* CTF 1.8 */\n"
 "typealias integer { size = 8; align = 8; signed = false; } := uint8_t;\n"
 "typealias integer { size = 32; align = 32; signed = false; } := uint32_t;\n"
+"typealias integer { size = 64; align = 64; signed = false; } := uint64_t;\n"
 "\n"
 "trace {\n"
 "      major = %u;\n"                  /* major (e.g. 0) */
@@ -67,8 +77,8 @@ static const char metadata_fmt[] =
 "\n"
 "stream {\n"
 "      packet.context := struct {\n"
-"              uint32_t content_size;\n"
-"              uint32_t packet_size;\n"
+"              uint64_t content_size;\n"
+"              uint64_t packet_size;\n"
 "      };\n"
 "%s"                                   /* Stream event header (opt.) */
 "};\n"
@@ -136,24 +146,24 @@ void write_packet_context(struct ctf_stream_pos *pos)
 
        /* content_size */
        ctf_dummy_pos(pos, &dummy);
-       ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT);
-       ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT);
+       ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT);
+       ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT);
        assert(!ctf_pos_packet(&dummy));
        
-       ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT);
-       *(uint32_t *) ctf_get_pos_addr(pos) = -1U;      /* Not known yet */
-       pos->content_size_loc = (uint32_t *) ctf_get_pos_addr(pos);
-       ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT);
+       ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT);
+       *(uint64_t *) ctf_get_pos_addr(pos) = ~0ULL;    /* Not known yet */
+       pos->content_size_loc = (uint64_t *) ctf_get_pos_addr(pos);
+       ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT);
 
        /* packet_size */
        ctf_dummy_pos(pos, &dummy);
-       ctf_align_pos(&dummy, sizeof(uint32_t) * CHAR_BIT);
-       ctf_move_pos(&dummy, sizeof(uint32_t) * CHAR_BIT);
+       ctf_align_pos(&dummy, sizeof(uint64_t) * CHAR_BIT);
+       ctf_move_pos(&dummy, sizeof(uint64_t) * CHAR_BIT);
        assert(!ctf_pos_packet(&dummy));
        
-       ctf_align_pos(pos, sizeof(uint32_t) * CHAR_BIT);
-       *(uint32_t *) ctf_get_pos_addr(pos) = pos->packet_size;
-       ctf_move_pos(pos, sizeof(uint32_t) * CHAR_BIT);
+       ctf_align_pos(pos, sizeof(uint64_t) * CHAR_BIT);
+       *(uint64_t *) ctf_get_pos_addr(pos) = pos->packet_size;
+       ctf_move_pos(pos, sizeof(uint64_t) * CHAR_BIT);
 }
 
 static
@@ -162,13 +172,14 @@ void write_event_header(struct ctf_stream_pos *pos, char *line,
                        uint64_t *ts)
 {
        unsigned long sec, usec;
-       int ret;
 
        if (!s_timestamp)
                return;
 
        /* Only need to be executed on first pass (dummy) */
        if (pos->dummy) {
+               int ret;
+
                /* Extract time from input line */
                ret = sscanf(line, "[%lu.%lu] ", &sec, &usec);
                if (ret == 2) {
@@ -199,21 +210,25 @@ void trace_string(char *line, struct ctf_stream_pos *pos, size_t len)
        uint64_t ts = 0;
 
        printf_debug("read: %s\n", line);
-retry:
-       ctf_dummy_pos(pos, &dummy);
-       write_event_header(&dummy, line, &tline, len, &tlen, &ts);
-       ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT);
-       ctf_move_pos(&dummy, tlen * CHAR_BIT);
-       if (ctf_pos_packet(&dummy)) {
-               ctf_pos_pad_packet(pos);
-               write_packet_header(pos, s_uuid);
-               write_packet_context(pos);
-               if (attempt++ == 1) {
-                       fprintf(stderr, "[Error] Line too large for packet size (%zukB) (discarded)\n",
-                               pos->packet_size / CHAR_BIT / 1024);
-                       return;
+
+       for (;;) {
+               ctf_dummy_pos(pos, &dummy);
+               write_event_header(&dummy, line, &tline, len, &tlen, &ts);
+               ctf_align_pos(&dummy, sizeof(uint8_t) * CHAR_BIT);
+               ctf_move_pos(&dummy, tlen * CHAR_BIT);
+               if (ctf_pos_packet(&dummy)) {
+                       ctf_pos_pad_packet(pos);
+                       write_packet_header(pos, s_uuid);
+                       write_packet_context(pos);
+                       if (attempt++ == 1) {
+                               fprintf(stderr, "[Error] Line too large for packet size (%" PRIu64 "kB) (discarded)\n",
+                                       pos->packet_size / CHAR_BIT / 1024);
+                               return;
+                       }
+                       continue;
+               } else {
+                       break;
                }
-               goto retry;
        }
 
        write_event_header(pos, line, &tline, len, &tlen, &ts);
@@ -229,9 +244,14 @@ void trace_text(FILE *input, int output)
        ssize_t len;
        char *line = NULL, *nl;
        size_t linesize;
+       int ret;
 
-       ctf_init_pos(&pos, output, O_RDWR);
-
+       memset(&pos, 0, sizeof(pos));
+       ret = ctf_init_pos(&pos, output, O_RDWR);
+       if (ret) {
+               fprintf(stderr, "Error in ctf_init_pos\n");
+               return;
+       }
        write_packet_header(&pos, s_uuid);
        write_packet_context(&pos);
        for (;;) {
@@ -239,11 +259,17 @@ void trace_text(FILE *input, int output)
                if (len < 0)
                        break;
                nl = strrchr(line, '\n');
-               if (nl)
+               if (nl) {
                        *nl = '\0';
-               trace_string(line, &pos, nl - line + 1);
+                       trace_string(line, &pos, nl - line + 1);
+               } else {
+                       trace_string(line, &pos, strlen(line) + 1);
+               }
+       }
+       ret = ctf_fini_pos(&pos);
+       if (ret) {
+               fprintf(stderr, "Error in ctf_fini_pos\n");
        }
-       ctf_fini_pos(&pos);
 }
 
 static
@@ -341,7 +367,9 @@ int main(int argc, char **argv)
        print_metadata(metadata_fp);
        trace_text(stdin, fd);
 
-       close(fd);
+       ret = close(fd);
+       if (ret)
+               perror("close");
        exit(EXIT_SUCCESS);
 
        /* error handling */
index b8caa6a0bba2c55b8f312d38eaa282d1e4cc508a..fe7d39fa49b5b13d1fc7185c9f36e0a9c714ac8d 100644 (file)
  *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
  */
 
 #define _GNU_SOURCE
 #define PARTIAL_ERROR_SLEEP    3       /* 3 seconds */
 
 #define DEFAULT_FILE_ARRAY_SIZE        1
+
 static char *opt_input_format, *opt_output_format;
-/* Pointer into const argv */
-static const char *opt_input_format_arg, *opt_output_format_arg;
 
+/*
+ * We are not freeing opt_input_paths ipath elements when exiting from
+ * main() for backward compatibility with libpop 0.13, which does not
+ * allocate copies for arguments returned by poptGetArg(), and for
+ * general compatibility with the documented behavior. This is known to
+ * cause a small memory leak with libpop 0.16.
+ */
 static GPtrArray *opt_input_paths;
-static const char *opt_output_path;
+static char *opt_output_path;
 
 static struct format *fmt_read;
 
@@ -67,6 +81,9 @@ void strlower(char *str)
 
 enum {
        OPT_NONE = 0,
+       OPT_OUTPUT_PATH,
+       OPT_INPUT_FORMAT,
+       OPT_OUTPUT_FORMAT,
        OPT_HELP,
        OPT_LIST,
        OPT_VERBOSE,
@@ -82,11 +99,19 @@ enum {
        OPT_CLOCK_FORCE_CORRELATE,
 };
 
+/*
+ * We are _not_ using POPT_ARG_STRING ability to store directly into
+ * variables, because we want to cast the return to non-const, which is
+ * not possible without using poptGetOptArg explicitly. This helps us
+ * controlling memory allocation correctly without making assumptions
+ * about undocumented behaviors. poptGetOptArg is documented as
+ * requiring the returned const char * to be freed by the caller.
+ */
 static struct poptOption long_options[] = {
        /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
-       { "output", 'w', POPT_ARG_STRING, &opt_output_path, OPT_NONE, NULL, NULL },
-       { "input-format", 'i', POPT_ARG_STRING, &opt_input_format_arg, OPT_NONE, NULL, NULL },
-       { "output-format", 'o', POPT_ARG_STRING, &opt_output_format_arg, OPT_NONE, NULL, NULL },
+       { "output", 'w', POPT_ARG_STRING, NULL, OPT_NONE, NULL, NULL },
+       { "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL },
+       { "output-format", 'o', POPT_ARG_STRING, NULL, OPT_OUTPUT_FORMAT, NULL, NULL },
        { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
        { "list", 'l', POPT_ARG_NONE, NULL, OPT_LIST, NULL, NULL },
        { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL },
@@ -134,7 +159,7 @@ static void usage(FILE *fp)
        fprintf(fp, "                                        (default: payload,context)\n");
        fprintf(fp, "  -f, --fields name1<,name2,...> Print additional fields:\n");
        fprintf(fp, "                                     all, trace, trace:hostname, trace:domain,\n");
-       fprintf(fp, "                                     trace:procname, trace:vpid, loglevel.\n");
+       fprintf(fp, "                                     trace:procname, trace:vpid, loglevel, emf, callsite.\n");
        fprintf(fp, "                                     (default: trace:hostname,trace:procname,trace:vpid)\n");
        fprintf(fp, "      --clock-cycles             Timestamp in cycles\n");
        fprintf(fp, "      --clock-offset seconds     Clock offset in seconds\n");
@@ -151,6 +176,7 @@ static void usage(FILE *fp)
 static int get_names_args(poptContext *pc)
 {
        char *str, *strlist, *strctx;
+       int ret = 0;
 
        opt_payload_field_names = 0;
        opt_context_field_names = 0;
@@ -178,15 +204,20 @@ static int get_names_args(poptContext *pc)
                        opt_payload_field_names = 0;
                } else {
                        fprintf(stderr, "[error] unknown field name type %s\n", str);
-                       return -EINVAL;
+                       free(strlist);
+                       ret = -EINVAL;
+                       goto end;
                }
        } while ((str = strtok_r(NULL, ",", &strctx)));
-       return 0;
+end:
+       free(strlist);
+       return ret;
 }
 
 static int get_fields_args(poptContext *pc)
 {
        char *str, *strlist, *strctx;
+       int ret = 0;
 
        strlist = (char *) poptGetOptArg(*pc);
        if (!strlist) {
@@ -209,12 +240,19 @@ static int get_fields_args(poptContext *pc)
                        opt_trace_vpid_field = 1;
                else if (!strcmp(str, "loglevel"))
                        opt_loglevel_field = 1;
+               else if (!strcmp(str, "emf"))
+                       opt_emf_field = 1;
+               else if (!strcmp(str, "callsite"))
+                       opt_callsite_field = 1;
                else {
                        fprintf(stderr, "[error] unknown field type %s\n", str);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto end;
                }
        } while ((str = strtok_r(NULL, ",", &strctx)));
-       return 0;
+end:
+       free(strlist);
+       return ret;
 }
 
 /*
@@ -241,6 +279,27 @@ static int parse_options(int argc, char **argv)
 
        while ((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
+               case OPT_OUTPUT_PATH:
+                       opt_output_path = (char *) poptGetOptArg(pc);
+                       if (!opt_output_path) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+                       break;
+               case OPT_INPUT_FORMAT:
+                       opt_input_format = (char *) poptGetOptArg(pc);
+                       if (!opt_input_format) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+                       break;
+               case OPT_OUTPUT_FORMAT:
+                       opt_output_format = (char *) poptGetOptArg(pc);
+                       if (!opt_output_format) {
+                               ret = -EINVAL;
+                               goto end;
+                       }
+                       break;
                case OPT_HELP:
                        usage(stdout);
                        ret = 1;        /* exit cleanly */
@@ -275,10 +334,10 @@ static int parse_options(int argc, char **argv)
                        break;
                case OPT_CLOCK_OFFSET:
                {
-                       const char *str;
+                       char *str;
                        char *endptr;
 
-                       str = poptGetOptArg(pc);
+                       str = (char *) poptGetOptArg(pc);
                        if (!str) {
                                fprintf(stderr, "[error] Missing --clock-offset argument\n");
                                ret = -EINVAL;
@@ -289,8 +348,10 @@ static int parse_options(int argc, char **argv)
                        if (*endptr != '\0' || str == endptr || errno != 0) {
                                fprintf(stderr, "[error] Incorrect --clock-offset argument: %s\n", str);
                                ret = -EINVAL;
+                               free(str);
                                goto end;
                        }
+                       free(str);
                        break;
                }
                case OPT_CLOCK_SECONDS:
@@ -385,6 +446,7 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb,
 
        return 0;
 }
+
 /*
  * bt_context_add_traces_recursive: Open a trace recursively
  *
@@ -405,7 +467,6 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
 
        GArray *trace_ids;
        int ret = 0;
-       int i;
 
        /* Should lock traversed_paths mutex here if used in multithread */
 
@@ -416,6 +477,8 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
 
        /* Process the array if ntfw did not return a fatal error */
        if (ret >= 0) {
+               int i;
+
                for (i = 0; i < traversed_paths->len; i++) {
                        GString *trace_path = g_ptr_array_index(traversed_paths,
                                                                i);
@@ -436,6 +499,7 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
                        g_string_free(trace_path, TRUE);
                }
        }
+
        g_ptr_array_free(traversed_paths, TRUE);
        traversed_paths = NULL;
 
@@ -511,22 +575,10 @@ int main(int argc, char **argv)
        printf_verbose("Verbose mode active.\n");
        printf_debug("Debug mode active.\n");
 
-       if (opt_input_format_arg) {
-               opt_input_format = strdup(opt_input_format_arg);
-               if (!opt_input_format) {
-                       partial_error = 1;
-                       goto end;
-               }
+       if (opt_input_format)
                strlower(opt_input_format);
-       }
-       if (opt_output_format_arg) {
-               opt_output_format = strdup(opt_output_format_arg);
-               if (!opt_output_format) {
-                       partial_error = 1;
-                       goto end;
-               }
+       if (opt_output_format)
                strlower(opt_output_format);
-       }
 
        printf_verbose("Converting from directory(ies):\n");
        for (i = 0; i < opt_input_paths->len; i++) {
@@ -634,6 +686,7 @@ error_td_read:
 end:
        free(opt_input_format);
        free(opt_output_format);
+       free(opt_output_path);
        g_ptr_array_free(opt_input_paths, TRUE);
        if (partial_error)
                exit(EXIT_FAILURE);
index 5c06198ec1f3a721414fd221cdf089db143ff82c..e13e6adf3545d306e36c2496dd2feb50479d1eea 100644 (file)
@@ -28,6 +28,20 @@ TERMINOLOGY
 * A "trace handle" is a unique identifier representing a trace file.
   It allows the user to manipulate a trace directly.
 
+* The "declaration" of a field or an event, is the structure which contains
+  the representaion of an object as declared in the metadata. All the
+  declarations of all events and fields can be accessed as soon as the trace is
+  open, but of course they contain no trace data, just the layout.
+
+* The "definition" of a field or an event is the structure in which the actual
+  trace data is contained. When we read an event in the trace, we access its
+  definition and we can access all the field definitions contained in all the
+  scopes of this event to the get the actual data.
+
+* "Scopes" allow specifying the level at which the information about the
+  current event must be fetched: event header, event payload, event context,
+  stream context. Compound-type (arrays, structures, sequences and variants)
+  fields are relative scopes which contain fields.
 
 
 USAGE
@@ -76,6 +90,14 @@ creation will return NULL. The previous iterator must be destroyed before
 creation of the new iterator. In the future, creation of multiples iterators
 will be allowed.
 
+The bt_ctf_iter_read_event_flags() function has the same behaviour as
+bt_ctf_iter_read_event() but takes an additionnal flag pointer. This flag is
+used to inform the user if a special condition occured while reading the event.
+As of now, only the BT_ITER_LOST_EVENTS is handled, it informs the user that
+some events were discarded by the tracer. To get the number of events lost
+immediately prior to the last event read, the user can call the
+bt_ctf_get_lost_events_count() function.
+
 Finally, we have the bt_ctf_get_iter() function which returns a struct bt_iter
 with which the iterator can be moved using one of these functions:
        bt_iter_next(),         moves the iterator to the next event
@@ -117,8 +139,13 @@ variant)
 
 For more information on each scope, see the CTF specifications.
 
-The function to get a field list is the bt_ctf_get_field_list(). The function
-to get the definition of a specific field is bt_ctf_get_field().
+The bt_ctf_get_field_list() function gives access to the list of fields in the
+current event. The bt_ctf_get_field() function gives acces to of a specific
+field of an event.
+
+The bt_ctf_get_event_decl_list() and bt_ctf_get_decl_fields() functions give
+respectively access to the list of the events declared in a trace and the list
+of the fields declared in an event.
 
 Once the field is obtained, we can obtain its name and type using the
 bt_ctf_field_name() and bt_ctf_field_type() functions respectively. The
@@ -135,8 +162,8 @@ possible types are defined in the ctf_type_id enum:
        CTF_TYPE_SEQUENCE,
        NR_CTF_TYPES.
 
-Depending on the field type, we can get informations about the field with these
-functions:
+Depending on the field type, we can get informations about the field with the
+following functions:
        * bt_ctf_get_index()            return the element at the index
                                        position of an array of a sequence;
 
@@ -158,7 +185,13 @@ functions:
                                                CTF_STRING_ASCII,
                                                CTF_STRING_UNKNOWN.
 
-These functions give access to the value associated with a field :
+All of these functions require a field declaration as parameter, depending on
+the source type of data (struct definition* or struct bt_ctf_field_decl*), the
+user might have to call bt_ctf_get_decl_from_def() or
+bt_ctf_get_decl_from_field_decl().
+
+The following functions give access to the value associated with a field
+defintion:
        * bt_ctf_get_uint64();
        * bt_ctf_get_int64();
        * bt_ctf_get_char_array();
index 597c43e79922f8d31576f2a7c06a8d44dcd692a5..6077f6232f096646f3bba32198a9f95d02cb6b72 100644 (file)
@@ -1,3 +1,5 @@
 dist_man_MANS = babeltrace.1 babeltrace-log.1
 
 dist_doc_DATA = API.txt
+
+EXTRA_DIST = development.txt
diff --git a/doc/development.txt b/doc/development.txt
new file mode 100644 (file)
index 0000000..7b6c9e3
--- /dev/null
@@ -0,0 +1,21 @@
+This document describes some principles that should be respected when
+developing in Babeltrace.
+
+Memory usage :
+
+Since Babeltrace exports a library, we need to make sure that all allocated
+memory is freed, we do not want any memory leaks.
+Since Babeltrace uses the glib, it is necessary to assist a little valgrind
+when trying to identify memory leaks.
+
+libpopt has issues with inconsistency between versions. Namely, libpopt
+0.16 allocates memory for the string returned by poptgetArg(), but not
+libpopt 0.13. Therefore, we are providing a warning suppression file
+that covers this case in the extras/ directory of the source code.
+
+So the proper invocation of Babeltrace with Valgrind is :
+
+G_SLICE=always-malloc G_DEBUG=gc-friendly \
+       valgrind --leak-check=full \
+       --suppressions=path_to_babeltrace_src/extras/valgrind/popt.supp \
+       babeltrace
diff --git a/extras/Makefile.am b/extras/Makefile.am
new file mode 100644 (file)
index 0000000..3e142d4
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = valgrind
diff --git a/extras/valgrind/Makefile.am b/extras/valgrind/Makefile.am
new file mode 100644 (file)
index 0000000..47dcc33
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = popt.supp
diff --git a/extras/valgrind/popt.supp b/extras/valgrind/popt.supp
new file mode 100644 (file)
index 0000000..61b5465
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       <poptGetArg-within-popt>
+       Memcheck:Leak
+       fun:malloc
+       fun:poptGetNextOpt
+       fun:main
+}
+
index 2e94421f7366759b350608d15b7fb33924014fd5..b55dd696daee73847954e0df0c95be42125a072f 100644 (file)
  *
  * 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>
@@ -50,12 +58,13 @@ struct trace_descriptor *bt_dummy_open_trace(const char *path, int flags,
 }
 
 static
-void bt_dummy_close_trace(struct trace_descriptor *td)
+int bt_dummy_close_trace(struct trace_descriptor *td)
 {
        struct ctf_text_stream_pos *pos =
                container_of(td, struct ctf_text_stream_pos,
                        trace_descriptor);
        free(pos);
+       return 0;
 }
 
 static
@@ -74,4 +83,8 @@ void __attribute__((constructor)) bt_dummy_init(void)
        assert(!ret);
 }
 
-/* TODO: finalize */
+static
+void __attribute__((destructor)) bt_dummy_exit(void)
+{
+       bt_unregister_format(&bt_dummy_format);
+}
index 7211c97f955889a4d6c15e409f2df0a87b4ae275..d344c1c0ce7d193532165bec1cd02456a9cdb57c 100644 (file)
  *
  * 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>
@@ -49,6 +57,8 @@ int opt_all_field_names,
        opt_trace_hostname_field,
        opt_trace_default_fields = 1,
        opt_loglevel_field,
+       opt_emf_field,
+       opt_callsite_field,
        opt_delta_field = 1;
 
 enum field_item {
@@ -76,11 +86,12 @@ enum bt_loglevel {
         BT_LOGLEVEL_DEBUG                  = 14,
 };
 
-
+static
 struct trace_descriptor *ctf_text_open_trace(const char *path, int flags,
                void (*packet_seek)(struct stream_pos *pos, size_t index,
                        int whence), FILE *metadata_fp);
-void ctf_text_close_trace(struct trace_descriptor *descriptor);
+static
+int ctf_text_close_trace(struct trace_descriptor *descriptor);
 
 static
 rw_dispatch write_dispatch_table[] = {
@@ -116,6 +127,14 @@ void __attribute__((constructor)) init_quarks(void)
        Q_STREAM_PACKET_CONTEXT_PACKET_SIZE = g_quark_from_static_string("stream.packet.context.packet_size");
 }
 
+static
+struct ctf_callsite_dups *ctf_trace_callsite_lookup(struct ctf_trace *trace,
+                       GQuark callsite_name)
+{
+       return g_hash_table_lookup(trace->callsites,
+                       (gpointer) (unsigned long) callsite_name);
+}
+
 int print_field(struct definition *definition)
 {
        /* Print all fields in verbose mode */
@@ -385,6 +404,55 @@ int ctf_text_write_event(struct stream_pos *ppos, struct ctf_stream_definition *
                        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);
@@ -486,7 +554,7 @@ error:
        return ret;
 }
 
-
+static
 struct trace_descriptor *ctf_text_open_trace(const char *path, int flags,
                void (*packet_seek)(struct stream_pos *pos, size_t index,
                        int whence), FILE *metadata_fp)
@@ -523,14 +591,22 @@ error:
        return NULL;
 }
 
-void ctf_text_close_trace(struct trace_descriptor *td)
+static
+int ctf_text_close_trace(struct trace_descriptor *td)
 {
+       int ret;
        struct ctf_text_stream_pos *pos =
                container_of(td, struct ctf_text_stream_pos, trace_descriptor);
-       fclose(pos->fp);
+       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;
@@ -540,4 +616,8 @@ void __attribute__((constructor)) ctf_text_init(void)
        assert(!ret);
 }
 
-/* TODO: finalize */
+static
+void __attribute__((destructor)) ctf_text_exit(void)
+{
+       bt_unregister_format(&ctf_text_format);
+}
index 3aaa633143ef48ee997d9239e26eb5e699353120..97b557f1498806b6f4b8e8e9bef1bfc26882360d 100644 (file)
  *
  * 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>
index b973d494b195dcd67d65931979b3d28dc06996a7..9df8da84e40615058f2f1d3e061d76358af9ff56 100644 (file)
  *
  * 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>
@@ -30,7 +38,7 @@ int ctf_text_enum_write(struct stream_pos *ppos, struct definition *definition)
                enum_definition->integer;
        struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
        GArray *qs;
-       int i, ret;
+       int ret;
        int field_nr_saved;
 
        if (!print_field(definition))
@@ -53,6 +61,8 @@ int ctf_text_enum_write(struct stream_pos *ppos, struct definition *definition)
        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);
index 77651124d000e2bb41942efc7b3ec0385802b5c6..199b01337ada4622dba4170b4d3c43842f58f485 100644 (file)
  * 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
  */
 
index f56a753bbb47177b0ab2811600f3669a2b935ce7..0886b0628fffc6a5ffb8784f8fb610b401e41fd3 100644 (file)
  *
  * 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>
index 3fe5ff170c381e43f7276f9cf063a5588f50e604..20345ccee135815dff488a4d719207d1bae225c1 100644 (file)
  *
  * 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>
index 1ac38c46ff86da5e6f9b282fb73a08aba41104d2..44aeb40d640cf9c76764e92107172e2dcf550f10 100644 (file)
  *
  * 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>
index a10e4da1d9c6b0ee5735112c6cd118762c5374d0..8a9344eb01dd765fd3d1b4a07e32f4656141c130 100644 (file)
  *
  * 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>
index da069c8ac3e9395b9e7ad6b4b612c2447d602daf..89d518a9455fefba77c1298d15b29cffed104560 100644 (file)
  *
  * 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>
index 0c221f9da684e5dfe58b058548be4263fdbdabc7..71e3248868239fd806d6cceb2bdcce48e9e06886 100644 (file)
  *
  * 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>
@@ -188,6 +196,8 @@ void process_callbacks(struct bt_ctf_iter *iter,
        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) {
index f43fe91789d21d109c0adf407a0b7e951201ca39..18a560132582ac9002535658734b51cb3abe68e8 100644 (file)
  *
  * 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>
@@ -86,7 +94,7 @@ void ctf_set_handle(struct trace_descriptor *descriptor,
                struct bt_trace_handle *handle);
 
 static
-void ctf_close_trace(struct trace_descriptor *descriptor);
+int ctf_close_trace(struct trace_descriptor *descriptor);
 static
 uint64_t ctf_timestamp_begin(struct trace_descriptor *descriptor,
                struct bt_trace_handle *handle, enum bt_clock_type type);
@@ -548,7 +556,7 @@ error:
        return ret;
 }
 
-void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags)
+int ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags)
 {
        pos->fd = fd;
        if (fd >= 0) {
@@ -578,27 +586,29 @@ void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags)
        default:
                assert(0);
        }
+       return 0;
 }
 
-void ctf_fini_pos(struct ctf_stream_pos *pos)
+int ctf_fini_pos(struct ctf_stream_pos *pos)
 {
-       int ret;
-
        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));
-                       assert(0);
+                       return -1;
                }
        }
        if (pos->packet_cycles_index)
                (void) g_array_free(pos->packet_cycles_index, TRUE);
        if (pos->packet_real_index)
                (void) g_array_free(pos->packet_real_index, TRUE);
+       return 0;
 }
 
 /*
@@ -699,6 +709,9 @@ void ctf_packet_seek(struct stream_pos *stream_pos, size_t index, int whence)
                        break;
                }
                case SEEK_SET:
+                       packet_index = &g_array_index(pos->packet_cycles_index,
+                                       struct packet_index, index);
+                       pos->last_events_discarded = packet_index->events_discarded;
                        pos->cur_index = index;
                        file_stream->parent.prev_real_timestamp = 0;
                        file_stream->parent.prev_real_timestamp_end = 0;
@@ -897,6 +910,9 @@ int ctf_open_trace_metadata_packet_read(struct ctf_trace *td, FILE *in,
                        return -EINVAL;
        }
 
+       if ((header.content_size / CHAR_BIT) < header_sizeof(header))
+               return -EINVAL;
+
        toread = (header.content_size / CHAR_BIT) - header_sizeof(header);
 
        for (;;) {
@@ -970,11 +986,20 @@ int ctf_open_trace_metadata_stream_read(struct ctf_trace *td, FILE **fp,
        /* close to flush the buffer */
        ret = babeltrace_close_memstream(buf, &size, out);
        if (ret < 0) {
+               int closeret;
+
                perror("babeltrace_flush_memstream");
-               fclose(in);
-               return -errno;
+               ret = -errno;
+               closeret = fclose(in);
+               if (closeret) {
+                       perror("Error in fclose");
+               }
+               return ret;
+       }
+       ret = fclose(in);
+       if (ret) {
+               perror("Error in fclose");
        }
-       fclose(in);
        /* open for reading */
        *fp = babeltrace_fmemopen(*buf, strlen(*buf), "rb");
        if (!*fp) {
@@ -993,7 +1018,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td,
        struct ctf_file_stream *metadata_stream;
        FILE *fp;
        char *buf = NULL;
-       int ret = 0;
+       int ret = 0, closeret;
 
        metadata_stream = g_new0(struct ctf_file_stream, 1);
        metadata_stream->pos.last_offset = LAST_OFFSET_POISON;
@@ -1003,7 +1028,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td,
        } else {
                fprintf(stderr, "[error] packet_seek function undefined.\n");
                ret = -1;
-               goto end_stream;
+               goto end_free;
        }
 
        if (metadata_fp) {
@@ -1014,7 +1039,8 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td,
                metadata_stream->pos.fd = openat(td->dirfd, "metadata", O_RDONLY);
                if (metadata_stream->pos.fd < 0) {
                        fprintf(stderr, "Unable to open metadata.\n");
-                       return metadata_stream->pos.fd;
+                       ret = -1;
+                       goto end_free;
                }
 
                fp = fdopen(metadata_stream->pos.fd, "r");
@@ -1024,6 +1050,8 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td,
                        ret = -errno;
                        goto end_stream;
                }
+               /* fd now belongs to fp */
+               metadata_stream->pos.fd = -1;
        }
        if (babeltrace_debug)
                yydebug = 1;
@@ -1084,12 +1112,21 @@ end:
        ctf_scanner_free(scanner);
 end_scanner_alloc:
 end_packet_read:
-       if (fp)
-               fclose(fp);
+       if (fp) {
+               closeret = fclose(fp);
+               if (closeret) {
+                       perror("Error on fclose");
+               }
+       }
        free(buf);
 end_stream:
-       if (metadata_stream->pos.fd >= 0)
-               close(metadata_stream->pos.fd);
+       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;
@@ -1264,6 +1301,7 @@ int create_stream_packet_index(struct ctf_trace *td,
                packet_index.timestamp_begin = 0;
                packet_index.timestamp_end = 0;
                packet_index.events_discarded = 0;
+               packet_index.events_discarded_len = 0;
 
                /* read and check header, set stream id (and check) */
                if (file_stream->parent.trace_packet_header) {
@@ -1478,7 +1516,7 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags,
                void (*packet_seek)(struct stream_pos *pos, size_t index,
                        int whence))
 {
-       int ret, fd;
+       int ret, fd, closeret;
        struct ctf_file_stream *file_stream;
        struct stat statbuf;
 
@@ -1512,7 +1550,9 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags,
                goto error_def;
        }
 
-       ctf_init_pos(&file_stream->pos, fd, flags);
+       ret = ctf_init_pos(&file_stream->pos, fd, flags);
+       if (ret)
+               goto error_def;
        ret = create_trace_definitions(td, &file_stream->parent);
        if (ret)
                goto error_def;
@@ -1532,11 +1572,17 @@ error_index:
        if (file_stream->parent.trace_packet_header)
                definition_unref(&file_stream->parent.trace_packet_header->p);
 error_def:
-       ctf_fini_pos(&file_stream->pos);
+       closeret = ctf_fini_pos(&file_stream->pos);
+       if (closeret) {
+               fprintf(stderr, "Error on ctf_fini_pos\n");
+       }
        g_free(file_stream);
 fd_is_dir_ok:
 fstat_error:
-       close(fd);
+       closeret = close(fd);
+       if (closeret) {
+               perror("Error on fd close");
+       }
 error:
        return ret;
 }
@@ -1547,7 +1593,7 @@ int ctf_open_trace_read(struct ctf_trace *td,
                void (*packet_seek)(struct stream_pos *pos, size_t index,
                        int whence), FILE *metadata_fp)
 {
-       int ret;
+       int ret, closeret;
        struct dirent *dirent;
        struct dirent *diriter;
        size_t dirent_len;
@@ -1620,9 +1666,15 @@ int ctf_open_trace_read(struct ctf_trace *td,
 readdir_error:
        free(dirent);
 error_metadata:
-       close(td->dirfd);
+       closeret = close(td->dirfd);
+       if (closeret) {
+               perror("Error on fd close");
+       }
 error_dirfd:
-       closedir(td->dir);
+       closeret = closedir(td->dir);
+       if (closeret) {
+               perror("Error on closedir");
+       }
 error:
        return ret;
 }
@@ -1878,19 +1930,32 @@ int ctf_convert_index_timestamp(struct trace_descriptor *tdp)
 }
 
 static
-void ctf_close_file_stream(struct ctf_file_stream *file_stream)
+int ctf_close_file_stream(struct ctf_file_stream *file_stream)
 {
-       ctf_fini_pos(&file_stream->pos);
-       close(file_stream->pos.fd);
+       int ret;
+
+       ret = ctf_fini_pos(&file_stream->pos);
+       if (ret) {
+               fprintf(stderr, "Error on ctf_fini_pos\n");
+               return -1;
+       }
+       ret = close(file_stream->pos.fd);
+       if (ret) {
+               perror("Error closing file fd");
+               return -1;
+       }
+       return 0;
 }
 
 static
-void ctf_close_trace(struct trace_descriptor *tdp)
+int ctf_close_trace(struct trace_descriptor *tdp)
 {
        struct ctf_trace *td = container_of(tdp, struct ctf_trace, parent);
-       int i;
+       int ret;
 
        if (td->streams) {
+               int i;
+
                for (i = 0; i < td->streams->len; i++) {
                        struct ctf_stream_declaration *stream;
                        int j;
@@ -1900,37 +1965,27 @@ void ctf_close_trace(struct trace_descriptor *tdp)
                                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);
-                               ctf_close_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;
                        }
-
-               }
-               g_ptr_array_free(td->streams, TRUE);
-       }
-
-       if (td->event_declarations) {
-               for (i = 0; i < td->event_declarations->len; i++) {
-                       struct bt_ctf_event_decl *event;
-
-                       event = g_ptr_array_index(td->event_declarations, i);
-                       if (event->context_decl)
-                               g_ptr_array_free(event->context_decl, TRUE);
-                       if (event->fields_decl)
-                               g_ptr_array_free(event->fields_decl, TRUE);
-                       if (event->packet_header_decl)
-                               g_ptr_array_free(event->packet_header_decl, TRUE);
-                       if (event->event_context_decl)
-                               g_ptr_array_free(event->event_context_decl, TRUE);
-                       if (event->event_header_decl)
-                               g_ptr_array_free(event->event_header_decl, TRUE);
-                       if (event->packet_context_decl)
-                               g_ptr_array_free(event->packet_context_decl, TRUE);
-                       g_free(event);
                }
-               g_ptr_array_free(td->event_declarations, TRUE);
        }
-       closedir(td->dir);
+       ctf_destroy_metadata(td);
+       ret = close(td->dirfd);
+       if (ret) {
+               perror("Error closing dirfd");
+               return ret;
+       }
+       ret = closedir(td->dir);
+       if (ret) {
+               perror("Error closedir");
+               return ret;
+       }
        g_free(td);
+       return 0;
 }
 
 static
@@ -1953,6 +2008,7 @@ void ctf_set_handle(struct trace_descriptor *descriptor,
        td->handle = handle;
 }
 
+static
 void __attribute__((constructor)) ctf_init(void)
 {
        int ret;
@@ -1962,4 +2018,8 @@ void __attribute__((constructor)) ctf_init(void)
        assert(!ret);
 }
 
-/* TODO: finalize */
+static
+void __attribute__((destructor)) ctf_exit(void)
+{
+       bt_unregister_format(&ctf_format);
+}
index a3caf7aed9092796e2e79e95b999a678c5d45baf..201b2b3692850dd739188a54c148063d3d5a31d2 100644 (file)
  *
  * 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>
index c281db54a2844feb249b39b7ee9958a7b697d286..ac7dce46828daf103adea381e30e2c84f31f50ab 100644 (file)
  *
  * 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>
@@ -41,8 +49,8 @@ __thread int bt_ctf_last_field_error = 0;
 const struct definition *bt_ctf_get_top_level_scope(const struct bt_ctf_event *ctf_event,
                enum bt_ctf_scope scope)
 {
-       struct definition *tmp = NULL;
-       struct ctf_event_definition *event;
+       const struct definition *tmp = NULL;
+       const struct ctf_event_definition *event;
 
        if (!ctf_event)
                return NULL;
@@ -92,7 +100,7 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
                const struct definition *scope,
                const char *field)
 {
-       struct definition *def;
+       const struct definition *def;
        char *field_underscore;
 
        if (!ctf_event || !scope || !field)
@@ -110,10 +118,10 @@ const struct definition *bt_ctf_get_field(const struct bt_ctf_event *ctf_event,
                def = lookup_definition(scope, field_underscore);
                g_free(field_underscore);
        }
-       if (bt_ctf_field_type(bt_ctf_get_field_decl(def)) == CTF_TYPE_VARIANT) {
-               struct definition_variant *variant_definition;
+       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,
-                               struct definition_variant, p);
+                               const struct definition_variant, p);
                return variant_definition->current_field;
        }
        return def;
@@ -128,12 +136,12 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
        if (!ctf_event || !field)
                return NULL;
 
-       if (bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_ARRAY) {
+       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 = array_index(array_definition, index);
-       } else if (bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_SEQUENCE) {
+       } 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);
@@ -144,9 +152,9 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *ctf_event,
 
 const char *bt_ctf_event_name(const struct bt_ctf_event *ctf_event)
 {
-       struct ctf_event_declaration *event_class;
-       struct ctf_stream_declaration *stream_class;
-       struct ctf_event_definition *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;
@@ -182,7 +190,7 @@ int bt_ctf_get_field_list(const struct bt_ctf_event *ctf_event,
        if (!ctf_event || !scope || !list || !count)
                return -EINVAL;
 
-       switch (bt_ctf_field_type(bt_ctf_get_field_decl(scope))) {
+       switch (bt_ctf_field_type(bt_ctf_get_decl_from_def(scope))) {
        case CTF_TYPE_INTEGER:
        case CTF_TYPE_FLOAT:
        case CTF_TYPE_STRING:
@@ -270,15 +278,15 @@ error:
 struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event)
 {
        struct bt_context *ret = NULL;
-       struct ctf_file_stream *cfs;
-       struct ctf_trace *trace;
-       struct ctf_event_definition *event;
+       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, struct ctf_file_stream,
+       cfs = container_of(event->stream, const struct ctf_file_stream,
                        parent);
        trace = cfs->parent.stream_class->trace;
        if (trace->ctx)
@@ -290,15 +298,15 @@ struct bt_context *bt_ctf_event_get_context(const struct bt_ctf_event *ctf_event
 int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event)
 {
        int ret = -1;
-       struct ctf_file_stream *cfs;
-       struct ctf_trace *trace;
-       struct ctf_event_definition *event;
+       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, struct ctf_file_stream,
+       cfs = container_of(event->stream, const struct ctf_file_stream,
                        parent);
        trace = cfs->parent.stream_class->trace;
        if (trace->handle)
@@ -309,7 +317,7 @@ int bt_ctf_event_get_handle_id(const struct bt_ctf_event *ctf_event)
 
 uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event)
 {
-       struct ctf_event_definition *event;
+       const struct ctf_event_definition *event;
 
        if (!ctf_event)
                return -1ULL;
@@ -323,7 +331,7 @@ uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *ctf_event)
 
 uint64_t bt_ctf_get_cycles(const struct bt_ctf_event *ctf_event)
 {
-       struct ctf_event_definition *event;
+       const struct ctf_event_definition *event;
 
        if (!ctf_event)
                return -1ULL;
@@ -349,133 +357,110 @@ int bt_ctf_field_get_error(void)
        return ret;
 }
 
-static struct declaration_integer *get_declaration_integer(const struct declaration *decl)
+static const struct declaration_integer *
+get_declaration_integer(const struct declaration *decl)
 {
-       struct declaration_field *field_decl;
-       struct declaration_integer *ret = NULL;
-
-       if (decl && bt_ctf_field_type(decl) == CTF_TYPE_INTEGER) {
-               field_decl = (struct declaration_field *) decl;
-               ret = ((struct declaration_integer *) field_decl->declaration);
-       }
-
-       return ret;
+       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_INTEGER)
+               return NULL;
+       return container_of(decl, const struct declaration_integer, p);
 }
 
-static struct declaration_string *get_declaration_string(const struct declaration *decl)
+static const struct declaration_string *
+get_declaration_string(const struct declaration *decl)
 {
-       struct declaration_field *field_decl;
-       struct declaration_string *ret = NULL;
-
-       if (decl && bt_ctf_field_type(decl) == CTF_TYPE_STRING) {
-               field_decl = (struct declaration_field *) decl;
-               ret = ((struct declaration_string *) field_decl->declaration);
-       }
-
-       return ret;
+       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_STRING)
+               return NULL;
+       return container_of(decl, const struct declaration_string, p);
 }
 
-static struct declaration_array *get_declaration_array(const struct declaration *decl)
+static const struct declaration_array *
+get_declaration_array(const struct declaration *decl)
 {
-       struct declaration_field *field_decl;
-       struct declaration_array *ret = NULL;
-
-       if (decl && bt_ctf_field_type(decl) == CTF_TYPE_ARRAY) {
-               field_decl = (struct declaration_field *) decl;
-               ret = ((struct declaration_array *) field_decl->declaration);
-       }
+       if (!decl || bt_ctf_field_type(decl) != CTF_TYPE_ARRAY)
+               return NULL;
+       return container_of(decl, const struct declaration_array, p);
+}
 
-       return ret;
+static const struct declaration_sequence *
+get_declaration_sequence(const struct 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 declaration *decl)
 {
-       int ret;
-       struct declaration_integer *integer;
+       const struct declaration_integer *integer;
 
        integer = get_declaration_integer(decl);
-       if (integer) {
-               ret = integer->signedness;
-       } else {
-               ret = -EINVAL;
+       if (!integer) {
                bt_ctf_field_set_error(-EINVAL);
+               return -EINVAL;
        }
-
-       return ret;
+       return integer->signedness;
 }
 
 int bt_ctf_get_int_base(const struct declaration *decl)
 {
-       int ret;
-       struct declaration_integer *integer;
+       const struct declaration_integer *integer;
 
        integer = get_declaration_integer(decl);
-       if (integer) {
-               ret = integer->base;
-       } else {
-               ret = -EINVAL;
+       if (!integer) {
                bt_ctf_field_set_error(-EINVAL);
+               return -EINVAL;
        }
-
-       return ret;
+       return integer->base;
 }
 
 int bt_ctf_get_int_byte_order(const struct declaration *decl)
 {
-       int ret;
-       struct declaration_integer *integer;
+       const struct declaration_integer *integer;
 
        integer = get_declaration_integer(decl);
-       if (integer) {
-               ret = integer->byte_order;
-       } else {
-               ret = -EINVAL;
+       if (!integer) {
                bt_ctf_field_set_error(-EINVAL);
+               return -EINVAL;
        }
-
-       return ret;
+       return integer->byte_order;
 }
 
 ssize_t bt_ctf_get_int_len(const struct declaration *decl)
 {
-       ssize_t ret;
-       struct declaration_integer *integer;
+       const struct declaration_integer *integer;
 
        integer = get_declaration_integer(decl);
-       if (integer) {
-               ret = (ssize_t) integer->len;
-       } else {
-               ret = -EINVAL;
+       if (!integer) {
                bt_ctf_field_set_error(-EINVAL);
+               return -EINVAL;
        }
-
-       return ret;
+       return (ssize_t) integer->len;
 }
 
 const struct definition *bt_ctf_get_enum_int(const struct definition *field)
 {
-       struct definition_enum *def_enum;
+       const struct definition_enum *def_enum;
 
-       if (!field || bt_ctf_field_type(bt_ctf_get_field_decl(field)) != CTF_TYPE_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, struct definition_enum, p);
+       def_enum = container_of(field, const struct definition_enum, p);
        return &def_enum->integer->p;
 }
 
 const char *bt_ctf_get_enum_str(const struct definition *field)
 {
-       struct definition_enum *def_enum;
-       struct declaration_enum *decl_enum;
+       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_field_decl(field)) != CTF_TYPE_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, struct definition_enum, p);
+       def_enum = container_of(field, const struct definition_enum, p);
        decl_enum = def_enum->declaration;
        if (get_int_signedness(&def_enum->integer->p)) {
                array = enum_int_to_quark_set(decl_enum,
@@ -503,27 +488,49 @@ const char *bt_ctf_get_enum_str(const struct definition *field)
 enum ctf_string_encoding bt_ctf_get_encoding(const struct declaration *decl)
 {
        enum ctf_string_encoding ret = 0;
-       struct declaration_integer *integer;
-       struct declaration_string *string;
+       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;
 
-       if (bt_ctf_field_type(decl) == CTF_TYPE_INTEGER) {
-               integer = get_declaration_integer(decl);
-               if (integer) {
-                       ret = integer->encoding;
-               } else {
+       type = bt_ctf_field_type(decl);
+
+       switch (type) {
+       case CTF_TYPE_ARRAY:
+               array = get_declaration_array(decl);
+               if (!array)
                        goto error;
-               }
-       } else if (bt_ctf_field_type(decl) == CTF_TYPE_STRING) {
+               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) {
-                       ret = string->encoding;
-               } else {
+               if (!string)
                        goto error;
-               }
-       } else {
+               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;
@@ -535,21 +542,12 @@ error:
 
 int bt_ctf_get_array_len(const struct declaration *decl)
 {
-       int ret;
-       struct declaration_array *array;
+       const struct declaration_array *array;
 
-       if (decl && bt_ctf_field_type(decl) == CTF_TYPE_ARRAY) {
-               array = get_declaration_array(decl);
-               if (array) {
-                       ret = array->len;
-               } else {
-                       goto error;
-               }
-       } else {
+       array = get_declaration_array(decl);
+       if (!array)
                goto error;
-       }
-
-       return ret;
+       return array->len;
 
 error:
        bt_ctf_field_set_error(-EINVAL);
@@ -560,7 +558,7 @@ uint64_t bt_ctf_get_uint64(const struct definition *field)
 {
        uint64_t ret = 0;
 
-       if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_INTEGER)
+       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
                ret = get_unsigned_int(field);
        else
                bt_ctf_field_set_error(-EINVAL);
@@ -572,13 +570,12 @@ int64_t bt_ctf_get_int64(const struct definition *field)
 {
        int64_t ret = 0;
 
-       if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_INTEGER)
+       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_INTEGER)
                ret = get_signed_int(field);
        else
                bt_ctf_field_set_error(-EINVAL);
 
        return ret;
-
 }
 
 char *bt_ctf_get_char_array(const struct definition *field)
@@ -586,7 +583,7 @@ char *bt_ctf_get_char_array(const struct definition *field)
        char *ret = NULL;
        GString *char_array;
 
-       if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_ARRAY) {
+       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_ARRAY) {
                char_array = get_char_array(field);
                if (char_array) {
                        ret = char_array->str;
@@ -603,7 +600,7 @@ char *bt_ctf_get_string(const struct definition *field)
 {
        char *ret = NULL;
 
-       if (field && bt_ctf_field_type(bt_ctf_get_field_decl(field)) == CTF_TYPE_STRING)
+       if (field && bt_ctf_field_type(bt_ctf_get_decl_from_def(field)) == CTF_TYPE_STRING)
                ret = get_string(field);
        else
                bt_ctf_field_set_error(-EINVAL);
@@ -770,10 +767,19 @@ const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field)
        return rem_(g_quark_to_string(((struct declaration_field *) field)->name));
 }
 
-const struct declaration *bt_ctf_get_field_decl(const struct definition *def)
+const struct declaration *bt_ctf_get_decl_from_def(const struct definition *def)
 {
        if (def)
                return def->declaration;
 
        return NULL;
 }
+
+const struct 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;
+}
index ec74e59029381e73acc5cbf97a7c43ae4889fedf..0534d013acc601220dd41986aea26805a7169d88 100644 (file)
  *
  * 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>
@@ -47,7 +55,8 @@ struct bt_ctf_iter *bt_ctf_iter_create(struct bt_context *ctx,
                g_free(iter);
                return NULL;
        }
-       iter->callbacks = g_array_new(0, 1, sizeof(struct bt_stream_callbacks));
+       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();
@@ -81,6 +90,8 @@ void bt_ctf_iter_destroy(struct bt_ctf_iter *iter)
                }
                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);
@@ -94,11 +105,13 @@ struct bt_iter *bt_ctf_get_iter(struct bt_ctf_iter *iter)
        return &iter->parent;
 }
 
-struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
+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
@@ -116,6 +129,24 @@ struct bt_ctf_event *bt_ctf_iter_read_event(struct bt_ctf_iter *iter)
        ret->parent = g_ptr_array_index(stream->events_by_id,
                        stream->event_id);
 
+       if (flags)
+               *flags = 0;
+       if (!file_stream->pos.packet_cycles_index)
+               packet_index = NULL;
+       else
+               packet_index = &g_array_index(file_stream->pos.packet_cycles_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;
 
@@ -126,3 +157,16 @@ end:
 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;
+}
index 8b3920796fc9fd7f17b1fcbbaea438256cd30b6f..d2a96cb5d37b57bc62ebcedaccb3bc90d107bd7d 100644 (file)
  *
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
  */
 
 #define _GNU_SOURCE
index 8d2e5d776b838232de8ec5f5c08f18043f786618..d5a0544a9d6d05f98f35dbe3bd7f68c194d9c09d 100644 (file)
@@ -41,6 +41,7 @@ enum node_type {
        NODE_ENV,
        NODE_TRACE,
        NODE_CLOCK,
+       NODE_CALLSITE,
 
        NODE_CTF_EXPRESSION,
        NODE_UNARY_EXPRESSION,
@@ -91,6 +92,7 @@ struct ctf_node {
                        struct bt_list_head stream;
                        struct bt_list_head event;
                        struct bt_list_head clock;
+                       struct bt_list_head callsite;
                } root;
                struct {
                        /*
@@ -127,6 +129,13 @@ struct ctf_node {
                         */
                        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 */
@@ -298,5 +307,6 @@ int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node);
 int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node);
 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
                        struct ctf_trace *trace, int byte_order);
+int ctf_destroy_metadata(struct ctf_trace *trace);
 
 #endif /* _CTF_AST_H */
index bedda4ada67198883724b5ab1cd10b9a7134eebb..26aa1bce2322d2571a9b57b24d614484009e3cdc 100644 (file)
  *
  * 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>
@@ -112,6 +120,7 @@ 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;
index 72c45885dc939f62c1622fd0aea08e6ad7895d77..45dbe6818da4cb72ccc42194fb44b3617844103a 100644 (file)
  *
  * 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>
index 28b7bebe60309e2420c45dc5d0ffb8e1cace28b1..e7dfd80cf847aeea3bcd9ff14d21219984023a3d 100644 (file)
  *
  * 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>
@@ -72,6 +80,7 @@ static const char *node_type_to_str[] = {
        [ NODE_STREAM ] = "NODE_STREAM",
        [ NODE_TRACE ] = "NODE_TRACE",
        [ NODE_CLOCK ] = "NODE_CLOCK",
+       [ NODE_CALLSITE ] = "NODE_CALLSITE",
        [ NODE_CTF_EXPRESSION ] = "NODE_CTF_EXPRESSION",
        [ NODE_UNARY_EXPRESSION ] = "NODE_UNARY_EXPRESSION",
        [ NODE_TYPEDEF ] = "NODE_TYPEDEF",
@@ -261,6 +270,9 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner,
        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);
@@ -347,6 +359,9 @@ static int reparent_ctf_expression(struct ctf_node *node,
        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;
@@ -405,6 +420,9 @@ static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent)
        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;
@@ -460,6 +478,9 @@ static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent)
        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;
@@ -508,6 +529,7 @@ static int reparent_type_specifier(struct ctf_node *node,
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_VARIANT:
        case NODE_STRUCT:
        case NODE_TYPEDEF:
@@ -557,6 +579,9 @@ static int reparent_type_specifier_list(struct ctf_node *node,
        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;
@@ -626,6 +651,7 @@ static int reparent_type_declarator(struct ctf_node *node,
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_VARIANT:
        case NODE_STRUCT:
        case NODE_TYPEALIAS:
@@ -705,6 +731,13 @@ static int set_parent_node(struct ctf_node *node,
                        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);
@@ -825,6 +858,7 @@ static struct ctf_ast *ctf_ast_alloc(void)
        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;
 }
 
@@ -834,6 +868,7 @@ static void ctf_ast_free(struct ctf_ast *ast)
 
        bt_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc)
                free(node);
+       free(ast);
 }
 
 int ctf_scanner_append_ast(struct ctf_scanner *scanner)
@@ -913,7 +948,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
  */
 %expect 2
 %start file
-%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN 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 CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN
+%token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN 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 DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN
 %token <gs> IDENTIFIER ID_TYPE
 %token ERROR
 %union
@@ -935,6 +970,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner)
 %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
@@ -1031,6 +1067,8 @@ keywords:
                {       $$ = yylval.gs;         }
        |       CLOCK
                {       $$ = yylval.gs;         }
+       |       CALLSITE
+               {       $$ = yylval.gs;         }
        |       TOK_ALIGN
                {       $$ = yylval.gs;         }
        ;
@@ -1232,6 +1270,8 @@ declaration:
                {       $$ = $1;        }
        |       clock_declaration
                {       $$ = $1;        }
+       |       callsite_declaration
+               {       $$ = $1;        }
        |       declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON
                {
                        struct ctf_node *list;
@@ -1399,6 +1439,29 @@ clock_declaration_end:
                {       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
                {
index ea8148b257953320431154df55d82bf80eb718f9..c32aa990fc23b952f9e5c827532796e1d22c28d1 100644 (file)
  *
  * 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>
@@ -508,6 +516,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
                                fprintf(fd, "[error] %s: cannot create array declaration.\n", __func__);
                                return NULL;
                        }
+                       declaration_unref(nested_declaration);
                        declaration = &array_declaration->p;
                        break;
                }
@@ -520,9 +529,12 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
                        sequence_declaration = 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;
                        }
+                       declaration_unref(nested_declaration);
                        declaration = &sequence_declaration->p;
+                       g_free(length_name);
                        break;
                }
                default:
@@ -571,6 +583,7 @@ int ctf_struct_type_declarators_visit(FILE *fd, int depth,
                struct_declaration_add_field(struct_declaration,
                                             g_quark_to_string(field_name),
                                             field_declaration);
+               declaration_unref(field_declaration);
        }
        return 0;
 }
@@ -604,10 +617,10 @@ int ctf_variant_type_declarators_visit(FILE *fd, int depth,
                        return -EINVAL;
                }
 
-
                untagged_variant_declaration_add_field(untagged_variant_declaration,
                                              g_quark_to_string(field_name),
                                              field_declaration);
+               declaration_unref(field_declaration);
        }
        return 0;
 }
@@ -647,6 +660,7 @@ int ctf_typedef_visit(FILE *fd, int depth, struct declaration_scope *scope,
                        type_declaration->declaration_free(type_declaration);
                        return ret;
                }
+               declaration_unref(type_declaration);
        }
        return 0;
 }
@@ -711,6 +725,7 @@ int ctf_typealias_visit(FILE *fd, int depth, struct declaration_scope *scope,
        err = register_declaration(alias_q, type_declaration, scope);
        if (err)
                goto error;
+       declaration_unref(type_declaration);
        return 0;
 
 error:
@@ -816,7 +831,6 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
 {
        struct declaration_struct *struct_declaration;
        struct ctf_node *iter;
-       int ret;
 
        /*
         * For named struct (without body), lookup in
@@ -828,6 +842,7 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
                struct_declaration =
                        lookup_struct_declaration(g_quark_from_string(name),
                                                  declaration_scope);
+               declaration_ref(&struct_declaration->p);
                return &struct_declaration->p;
        } else {
                uint64_t min_align_value = 0;
@@ -843,6 +858,8 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
                        }
                }
                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__);
@@ -853,12 +870,16 @@ struct declaration *ctf_declaration_struct_visit(FILE *fd,
                struct_declaration = 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 = register_struct_declaration(g_quark_from_string(name),
                                        struct_declaration,
                                        declaration_scope);
@@ -882,7 +903,6 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd,
        struct declaration_untagged_variant *untagged_variant_declaration;
        struct declaration_variant *variant_declaration;
        struct ctf_node *iter;
-       int ret;
 
        /*
         * For named variant (without body), lookup in
@@ -894,6 +914,7 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd,
                untagged_variant_declaration =
                        lookup_variant_declaration(g_quark_from_string(name),
                                                   declaration_scope);
+               declaration_ref(&untagged_variant_declaration->p);
        } else {
                /* For unnamed variant, create type */
                /* For named variant (with body), create type and add to declaration scope */
@@ -907,12 +928,16 @@ struct declaration *ctf_declaration_variant_visit(FILE *fd,
                }
                untagged_variant_declaration = untagged_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 = register_variant_declaration(g_quark_from_string(name),
                                        untagged_variant_declaration,
                                        declaration_scope);
@@ -1042,7 +1067,6 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
        struct last_enum_value last_value;
        struct ctf_node *iter;
        GQuark dummy_id;
-       int ret;
 
        /*
         * For named enum (without body), lookup in
@@ -1054,6 +1078,7 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
                enum_declaration =
                        lookup_enum_declaration(g_quark_from_string(name),
                                                declaration_scope);
+               declaration_ref(&enum_declaration->p);
                return &enum_declaration->p;
        } else {
                /* For unnamed enum, create type */
@@ -1097,16 +1122,21 @@ struct declaration *ctf_declaration_enum_visit(FILE *fd, int depth,
                        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 = register_enum_declaration(g_quark_from_string(name),
                                        enum_declaration,
                                        declaration_scope);
                        assert(!ret);
+                       declaration_unref(&enum_declaration->p);
                }
                return &enum_declaration->p;
        }
@@ -1134,6 +1164,7 @@ struct declaration *ctf_declaration_type_specifier_visit(FILE *fd, int depth,
        id_q = g_quark_from_string(str_c);
        g_free(str_c);
        declaration = lookup_declaration(id_q, declaration_scope);
+       declaration_ref(declaration);
        return declaration;
 }
 
@@ -1741,6 +1772,23 @@ int ctf_event_declaration_visit(FILE *fd, int depth, struct ctf_node *node, stru
                        }
                        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 */
@@ -2416,6 +2464,176 @@ void clock_free(gpointer data)
        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 (!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;
+
+       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,
+               (gpointer) (unsigned long) 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,
+                       (gpointer) (unsigned long) 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)
@@ -2458,6 +2676,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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;
 
@@ -2473,6 +2692,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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;
 
@@ -2488,6 +2708,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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, "sysname")) {
                        char *right;
 
@@ -2503,6 +2724,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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;
 
@@ -2518,6 +2740,7 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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;
 
@@ -2533,12 +2756,14 @@ int ctf_env_declaration_visit(FILE *fd, int depth, struct ctf_node *node,
                        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);
                                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;
@@ -2636,7 +2861,6 @@ int ctf_root_declaration_visit(FILE *fd, int depth, struct ctf_node *node, struc
        return 0;
 }
 
-/* TODO: missing metadata "destroy" (memory leak) */
 int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
                struct ctf_trace *trace, int byte_order)
 {
@@ -2648,6 +2872,8 @@ int ctf_visitor_construct_metadata(FILE *fd, int depth, struct ctf_node *node,
        trace->byte_order = byte_order;
        trace->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 = new_declaration_scope(NULL);
@@ -2697,6 +2923,14 @@ retry:
                                goto error;
                        }
                }
+               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;
@@ -2738,6 +2972,110 @@ retry:
 
 error:
        free_declaration_scope(trace->root_declaration_scope);
+       g_hash_table_destroy(trace->callsites);
        g_hash_table_destroy(trace->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)
+                                               definition_unref(&event->event_fields->p);
+                                       if (&event->event_context->p)
+                                               definition_unref(&event->event_context->p);
+                                       g_free(event);
+                               }
+                               if (&stream_def->trace_packet_header->p)
+                                       definition_unref(&stream_def->trace_packet_header->p);
+                               if (&stream_def->stream_event_header->p)
+                                       definition_unref(&stream_def->stream_event_header->p);
+                               if (&stream_def->stream_packet_context->p)
+                                       definition_unref(&stream_def->stream_packet_context->p);
+                               if (&stream_def->stream_event_context->p)
+                                       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)
+                               declaration_unref(&stream->event_header_decl->p);
+                       if (stream->event_context_decl)
+                               declaration_unref(&stream->event_context_decl->p);
+                       if (stream->packet_context_decl)
+                               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);
+                       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)
+                               declaration_unref(&event->fields_decl->p);
+                       if (event->context_decl)
+                               declaration_unref(&event->context_decl->p);
+                       free_declaration_scope(event->declaration_scope);
+
+                       g_free(event);
+               }
+               g_ptr_array_free(trace->event_declarations, TRUE);
+       }
+       if (trace->packet_header_decl)
+               declaration_unref(&trace->packet_header_decl->p);
+
+       free_declaration_scope(trace->root_declaration_scope);
+       free_declaration_scope(trace->declaration_scope);
+
+       g_hash_table_destroy(trace->callsites);
+       g_hash_table_destroy(trace->clocks);
+
+       metadata_stream = container_of(trace->metadata, struct ctf_file_stream, parent);
+       g_free(metadata_stream);
+
+       return 0;
+}
index 766ce42f1aa16930deecddbe1c1d81cb110595ea..953727e84c3eccc809328f7f7ca6f82e8c7e0cc7 100644 (file)
  *
  * 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>
@@ -211,6 +219,12 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
                        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:
@@ -253,6 +267,14 @@ int ctf_visitor_parent_links(FILE *fd, int depth, struct ctf_node *node)
                                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++;
index 3db7fd7751eaa29672de85c317db11384b5ac030..13b2fc55adeb9a9b8b2207fb83ea06328aaa108f 100644 (file)
  *
  * 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>
@@ -110,6 +118,7 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_TYPEDEF:
        case NODE_TYPEALIAS_TARGET:
        case NODE_TYPEALIAS_ALIAS:
@@ -214,6 +223,7 @@ int ctf_visitor_type_specifier_list(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
        case NODE_TYPE_SPECIFIER:
@@ -255,6 +265,7 @@ int ctf_visitor_type_specifier(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
        case NODE_TYPE_SPECIFIER:
@@ -337,6 +348,7 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENV:
        case NODE_TRACE:
        case NODE_CLOCK:
+       case NODE_CALLSITE:
        case NODE_CTF_EXPRESSION:
        case NODE_UNARY_EXPRESSION:
        case NODE_TYPEALIAS:
@@ -516,7 +528,20 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                                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) {
@@ -526,6 +551,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENV:
                case NODE_TRACE:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_FLOATING_POINT:
                case NODE_INTEGER:
                case NODE_STRING:
@@ -593,6 +619,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENUMERATOR:
                case NODE_ENUM:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_ENV:
                default:
                        goto errinval;
@@ -699,6 +726,7 @@ int _ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
                case NODE_ENUMERATOR:
                case NODE_ENUM:
                case NODE_CLOCK:
+               case NODE_CALLSITE:
                case NODE_ENV:
                default:
                        goto errinval;
index 428a89560e9baa1bf0aa25ff881462609c8af851..0276f836806fa8a1f97d7c03d8a22044adee0821 100644 (file)
  *
  * 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>
@@ -443,6 +451,17 @@ int ctf_visitor_print_xml(FILE *fd, int depth, struct ctf_node *node)
                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:
index e5b428cc57571b05283bb7a8b1dc5b2b13bdc73b..d5b6ed46b44d25d81e87840cb1675e17bea612c7 100644 (file)
  *
  * 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>
index e0a2b4d49d9cfc9049caa6c8011c0bb410f081c0..e4e7ac85bb72f094d1ee197e7276cfbe95aa5493 100644 (file)
  *
  * 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>
index 9ad4e602f0df705276ee45bbf92cfe7b154e921e..0cf9caeb6c7795212c53dc7d540c1a9fdd53b36e 100644 (file)
  * 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
  */
 
@@ -25,6 +33,7 @@
 #include <float.h>     /* C99 floating point definitions */
 #include <limits.h>    /* C99 limits */
 #include <babeltrace/endian.h>
+#include <pthread.h>
 
 /*
  * This library is limited to binary representation of floating point values.
@@ -58,13 +67,35 @@ union doubleIEEE754 {
 #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 sign_start, exp_start, mantissa_start, 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);
+}
+
 int _ctf_float_copy(struct stream_pos *destp,
                    struct definition_float *dest_definition,
                    struct stream_pos *srcp,
@@ -148,6 +179,7 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition)
        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(
@@ -160,7 +192,8 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition)
                                NULL, 0, 0, "__tmpfloat");
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto end;
        }
        tmpfloat = container_of(tmpdef, struct definition_float, p);
        memset(&destp, 0, sizeof(destp));
@@ -178,9 +211,14 @@ int ctf_float_read(struct stream_pos *ppos, struct definition *definition)
                float_definition->value = u.vd;
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto end_unref;
        }
+
+end_unref:
        definition_unref(tmpdef);
+end:
+       float_unlock();
        return ret;
 }
 
@@ -198,6 +236,7 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition)
        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(
@@ -210,7 +249,8 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition)
                                NULL, 0, 0, "__tmpfloat");
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto end;
        }
        tmpfloat = container_of(tmpdef, struct definition_float, p);
        ctf_init_pos(&srcp, -1, O_RDONLY);
@@ -225,11 +265,16 @@ int ctf_float_write(struct stream_pos *ppos, struct definition *definition)
                u.vd = float_definition->value;
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto end_unref;
        }
        ctf_align_pos(pos, float_declaration->p.alignment);
        ret = _ctf_float_copy(ppos, float_definition, &srcp.parent, tmpfloat);
+
+end_unref:
        definition_unref(tmpdef);
+end:
+       float_unlock();
        return ret;
 }
 
index 71ac0f448c0a446b59edf9a5b86688763dde33db..66036ae2511004fafe8bd3056cb848949f11a209 100644 (file)
  *
  * 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>
index 6aa5750cdb10d6a8373a16fd7ac517325ef590c8..7f12bbceade30ce1727504b3a8d36d9d2b1fc094 100644 (file)
  *
  * 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>
index 3b54a2df680ea5acffbba3c6f932aff1f2da096c..357e273a4e8929a130445ed764f6473e61ea0892 100644 (file)
  *
  * 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>
index adce6cbabb32211cddf296d6ab4dd36bdf1fd451..21ce96f6d9eae370ebf0cd5ffe5d10000caab387 100644 (file)
  *
  * 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>
index d2ef7714dd8622407ca4a8255ef38168c5e449b8..297f26ff5feb3f9e739e82fb8c7582f3dec6dfca 100644 (file)
  *
  * 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>
index c5589c43aca6253a42470cb6b42214d5763ac943..f6a19662f650d4a3144e8530e78b525d73eaf0dd 100644 (file)
  *
  * 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>
index 9f14177dc1431f8e519dd41b26063751f2bf7828..c567d3952d532ed8aabb16005f6f16f4ad7b4218 100644 (file)
  *
  * 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 <glib.h>
@@ -62,6 +70,8 @@ extern int opt_all_field_names,
        opt_trace_hostname_field,
        opt_trace_default_fields,
        opt_loglevel_field,
+       opt_emf_field,
+       opt_callsite_field,
        opt_delta_field,
        opt_clock_cycles,
        opt_clock_seconds,
index 8eae53842f8ecb3062dde8a6b90af2329b467553..365382e5164403b2fc3f8a2fccdec619b1db624a 100644 (file)
  *
  * 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/context.h>
index d14d562db55e2534f7fb1b415049571a87242737..40c1161489d66d6d56cba1fe1ba1803973289b18 100644 (file)
  *
  * 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>    /* C99 5.2.4.2 Numerical limits */
index 6fbc7c32c95143ba2e8ef455a2c65bc358e89432..002cc7fd848bd26c291c298ac22ce7ff33ee7b56 100644 (file)
  *
  * 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
index e1fbfb7d405ca38d95a8536a7038137e6b29f2db..8a3921aad5ef604b15580f7140261715940b8402 100644 (file)
  *
  * 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
index 2211fe3ad8498c6719124c60ce39e4144871481a..09189bce084077b6b1b7a67e70c72c2917f606d4 100644 (file)
  *
  * 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 <stddef.h>    /* for offsetof */
index 95d629b86a18e73b5eb97a796e4c226b20d19fda..17d620279ac972d8e739d357130ae453d2720267 100644 (file)
  *
  * 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>
index bc7de3a0e84c5de89967cae08cc020d7e18145ac..f29ccf083f034c5e73a36132b42103668a3dfa19 100644 (file)
  *
  * 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>
@@ -64,7 +72,7 @@ struct bt_context *bt_context_create(void);
  *
  * 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 set to NULL when path is NULL.
+ * 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.
index 63a6c2a9b4a9b9aa0d28259fd9ca8adb39937e3e..fc555fdd96f5e79cef3ddc9cae20e70a19628929 100644 (file)
  *
  * 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>
@@ -32,6 +40,7 @@ struct ctf_trace;
 struct ctf_stream_declaration;
 struct ctf_event_declaration;
 struct ctf_clock;
+struct ctf_callsite;
 
 struct ctf_stream_definition {
        struct ctf_stream_declaration *stream_class;
@@ -101,6 +110,40 @@ struct ctf_clock {
        } 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;         \
@@ -141,6 +184,7 @@ struct ctf_trace {
        GPtrArray *streams;                     /* Array of struct ctf_stream_declaration pointers */
        struct ctf_stream_definition *metadata;
        GHashTable *clocks;
+       GHashTable *callsites;
        struct ctf_clock *single_clock;         /* currently supports only one clock */
        struct trace_collection *collection;    /* Container of this trace */
        GPtrArray *event_declarations;          /* Array of all the struct bt_ctf_event_decl */
@@ -237,12 +281,14 @@ struct ctf_event_declaration {
        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;
 };
 
index b9c9cc30dfb79f296579268526331283baa8df02..d69af90523220b33ee03dc18b3fd039583add267 100644 (file)
  *
  * 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>
index b76f82e180ce8ea208ef0b0a7508470a3fcb6872..0390b9a4ef3d22309c873a172fbbc48bf14125f5 100644 (file)
  *
  * 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>
index 128d597b0c87b22f5e11656cb76607ddb9ab7a0c..c178767ced7d00ea7ed412522eed09c7803ed441 100644 (file)
  *
  * 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>
index aaa09262321dfc32f62dddb185430bc7d4e771f3..0356906f3432eb6192bf13e997dfe1c6858a32d9 100644 (file)
  *
  * 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>
@@ -68,6 +76,7 @@ struct bt_ctf_iter {
         * bt_iter.
         */
        GPtrArray *dep_gc;
+       uint64_t events_lost;
 };
 
 #endif /*_BABELTRACE_CTF_EVENTS_INTERNAL_H */
index e63bae13d92efd293d8dc569e61e707497fe1699..19d73612b45d78695d5508e5fc6788a855cea3f3 100644 (file)
  *
  * 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>
@@ -109,9 +117,9 @@ uint64_t bt_ctf_get_timestamp(const struct bt_ctf_event *event);
 /*
  * 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 compound type: array, sequence,
- * structure, or variant.
+ * 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.
@@ -147,10 +155,17 @@ const struct definition *bt_ctf_get_index(const struct bt_ctf_event *event,
 const char *bt_ctf_field_name(const struct definition *def);
 
 /*
- * bt_ctf_get_field_decl: return the declaration of a field or NULL
- * on error
+ * bt_ctf_get_decl_from_def: return the declaration of a field from
+ * its definition or NULL on error
+ */
+const struct declaration *bt_ctf_get_decl_from_def(const struct 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 declaration *bt_ctf_get_field_decl(const struct definition *def);
+const struct 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
@@ -184,7 +199,8 @@ int bt_ctf_get_int_byte_order(const struct declaration *decl);
 ssize_t bt_ctf_get_int_len(const struct declaration *decl);
 
 /*
- * bt_ctf_get_encoding: return the encoding of an int or a string.
+ * 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 declaration *decl);
@@ -224,10 +240,16 @@ char *bt_ctf_get_string(const struct definition *field);
 int bt_ctf_field_get_error(void);
 
 /*
- * bt_ctf_get_event_decl_list: set list pointer to an array of bt_ctf_event_decl
- * pointers and set count to the number of elements in the array.
+ * 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,
@@ -239,10 +261,15 @@ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx,
 const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event);
 
 /*
- * bt_ctf_get_decl_fields: set list pointer to an array of bt_ctf_field_decl
- * pointers and set count to the number of elements in the array.
+ * 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 bt_ctf_scope scope,
index 9370583a58df3e6042b92f74932305234ba0bc51..ec6aac776e99e80cdb25cbe97463872ab722fe3f 100644 (file)
  *
  * 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>
@@ -74,6 +82,28 @@ void bt_ctf_iter_destroy(struct bt_ctf_iter *iter);
  */
 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
index 5262f44a19e2264a8a4c9dd01524bc18373c3af9..1b78762b2a9e1da9a12dc793c10a92507b6b1558 100644 (file)
  *
  * 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>
index 94231555c10dad3763a785b837040d08f410d52e..6b8752e2d60ce8136b05ac07ddfb6428f056c870 100644 (file)
  *
  * 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 <unistd.h>
 #include <glib.h>
 #include <stdio.h>
+#include <inttypes.h>
 #include <babeltrace/mmap-align.h>
 
-#define LAST_OFFSET_POISON     ((ssize_t) -1L)
+#define LAST_OFFSET_POISON     ((int64_t) ~0ULL)
 
 struct bt_stream_callbacks;
 
 struct packet_index {
        off_t offset;           /* offset of the packet in the file, in bytes */
-       off_t data_offset;      /* offset of data within the packet, in bits */
+       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 timestamp_begin;
        uint64_t timestamp_end;
        uint64_t events_discarded;
-       size_t events_discarded_len;    /* length of the field, in bits */
+       uint64_t events_discarded_len;  /* length of the field, in bits */
 };
 
 /*
@@ -60,13 +69,14 @@ struct ctf_stream_pos {
        /* 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 */
-       size_t packet_size;     /* current packet size, in bits */
-       size_t content_size;    /* current content size, in bits */
-       uint32_t *content_size_loc; /* pointer to current content size */
+       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 */
-       ssize_t offset;         /* offset from base, in bits. EOF for end of file. */
-       ssize_t last_offset;    /* offset before the last read_event */
-       size_t cur_index;       /* current index in packet index */
+       int64_t offset;         /* offset from base, in bits. EOF for end of file. */
+       int64_t last_offset;    /* offset before the last read_event */
+       uint64_t cur_index;     /* current index in packet index */
+       uint64_t last_events_discarded; /* last known amount of event discarded */
        void (*packet_seek)(struct stream_pos *pos, size_t index,
                        int whence); /* function called to switch packet */
 
@@ -97,8 +107,8 @@ int ctf_sequence_write(struct stream_pos *pos, struct definition *definition);
 
 void ctf_packet_seek(struct stream_pos *pos, size_t index, int whence);
 
-void ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags);
-void ctf_fini_pos(struct ctf_stream_pos *pos);
+int ctf_init_pos(struct ctf_stream_pos *pos, int fd, int open_flags);
+int ctf_fini_pos(struct ctf_stream_pos *pos);
 
 /*
  * move_pos - move position of a relative bit offset
@@ -106,9 +116,9 @@ void ctf_fini_pos(struct ctf_stream_pos *pos);
  * TODO: allow larger files by updating base too.
  */
 static inline
-void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset)
+void ctf_move_pos(struct ctf_stream_pos *pos, uint64_t bit_offset)
 {
-       printf_debug("ctf_move_pos test EOF: %zd\n", pos->offset);
+       printf_debug("ctf_move_pos test EOF: %" PRId64 "\n", pos->offset);
        if (unlikely(pos->offset == EOF))
                return;
 
@@ -121,16 +131,16 @@ void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset)
                 */
                if ((pos->prot == PROT_WRITE)
                        && (unlikely(pos->offset + bit_offset >= pos->packet_size))) {
-                       printf_debug("ctf_packet_seek (before call): %zd\n",
+                       printf_debug("ctf_packet_seek (before call): %" PRId64 "\n",
                                     pos->offset);
                        ctf_packet_seek(&pos->parent, 0, SEEK_CUR);
-                       printf_debug("ctf_packet_seek (after call): %zd\n",
+                       printf_debug("ctf_packet_seek (after call): %" PRId64 "\n",
                                     pos->offset);
                        return;
                }
        }
        pos->offset += bit_offset;
-       printf_debug("ctf_move_pos after increment: %zd\n", pos->offset);
+       printf_debug("ctf_move_pos after increment: %" PRId64 "\n", pos->offset);
 }
 
 /*
@@ -139,7 +149,7 @@ void ctf_move_pos(struct ctf_stream_pos *pos, size_t bit_offset)
  * TODO: allow larger files by updating base too.
  */
 static inline
-void ctf_align_pos(struct ctf_stream_pos *pos, size_t bit_offset)
+void ctf_align_pos(struct ctf_stream_pos *pos, uint64_t bit_offset)
 {
        ctf_move_pos(pos, offset_align(pos->offset, bit_offset));
 }
@@ -180,7 +190,7 @@ void ctf_pos_pad_packet(struct ctf_stream_pos *pos)
 }
 
 static inline
-int ctf_pos_access_ok(struct ctf_stream_pos *pos, size_t bit_len)
+int ctf_pos_access_ok(struct ctf_stream_pos *pos, uint64_t bit_len)
 {
        if (unlikely(pos->offset == EOF))
                return 0;
@@ -198,10 +208,10 @@ 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): %zd\n",
+               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): %zd\n",
+               printf_debug("ctf_packet_seek (after call): %" PRId64 "\n",
                             pos->offset);
        }
 }
index 7df67f557a0efac48a7c56011a184af4f2256193..9eee0c1e0531b8db505def566ee816723951d0d3 100644 (file)
  *
  * 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 __FreeBSD__
index ef340da115b9432abdad0f35d6e5e94a3d23e52b..c6faca71d9ada4774e82483e5f527904037a6761 100644 (file)
  *
  * 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>
@@ -62,7 +70,7 @@ struct format {
                        void (*packet_seek)(struct stream_pos *pos,
                                size_t index, int whence),
                        FILE *metadata_fp);
-       void (*close_trace)(struct trace_descriptor *descriptor);
+       int (*close_trace)(struct trace_descriptor *descriptor);
        void (*set_context)(struct trace_descriptor *descriptor,
                        struct bt_context *ctx);
        void (*set_handle)(struct trace_descriptor *descriptor,
@@ -77,8 +85,8 @@ struct format {
 extern struct format *bt_lookup_format(bt_intern_str qname);
 extern void bt_fprintf_format_list(FILE *fp);
 extern int bt_register_format(struct format *format);
+extern void bt_unregister_format(struct format *format);
 
-/* TBD: format unregistration */
 #ifdef __cplusplus
 }
 #endif
index 8000875ec5cefa76897f418448dfde77ab83be23..2b0b2f23c2b5460b55ce86e9b5ad78a7c15af0a2 100644 (file)
  *
  * 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>
index 3f7984fbe66ea00c01e6e5c95090acbf07f634fc..360a9c70a5a159eed3bd11b00e1bfa97060084c8 100644 (file)
  *
  * 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>
 extern "C" {
 #endif
 
+/* Flags for the iterator read_event */
+enum {
+       BT_ITER_FLAG_LOST_EVENTS        = (1 << 0),
+};
+
 /* Forward declarations */
 struct bt_iter;
 struct bt_saved_pos;
index d0e883a456ecc888fa8e08546e6e4d7b1b14801f..f7c18fa6f10fe09518d189752d9a7b8d1588c8ce 100644 (file)
  *
  * 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>
index 347a2ced5fa302482878fd75160c0aa61c17c1b4..90aec8f8cacd976edb08a0ec06b404da2a677ccc 100644 (file)
  *
  * 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>
index 0542d03c044ca6e0daddf41de30ce6cf2830437f..2ac9ba6a315883286a1580a74e12d3c80d489196 100644 (file)
  *
  * 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
index 362008227b214adc9e38f4477506996a93d2dc6a..2b5a5ae198e75163458c0f696184c92e11b9f23d 100644 (file)
  *
  * 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>
index 426800d84e4cf1d01056b6310233bf1eefd2ad92..96e4a81bc167b272b3569473e3f9ecade58aa80d 100644 (file)
  *
  * 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>
@@ -54,7 +62,7 @@ uint64_t bt_trace_handle_get_timestamp_begin(struct bt_context *ctx,
 
 /*
  * bt_trace_handle_get_timestamp_end : returns the destruction timestamp
- * (in anoseconds or cycles depending on type) of the buffers of a trace
+ * (in nanoseconds or cycles depending on type) of the buffers of a trace
  * or -1ULL on error.
  */
 uint64_t bt_trace_handle_get_timestamp_end(struct bt_context *ctx,
index a0ad283d1a064831e4f1c2ecee877cd51e8fdbe0..b42ba03e066ef65cd7b18d4f0d8fed5e0f82a345 100644 (file)
  *
  * 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>
index 4a020210268247752f9402df48ff7b71e18f3ac4..2ce74670796506645c1527d48743e8f0f06d6a22 100644 (file)
  *
  * 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 <config.h>
diff --git a/lgpl-2.1.txt b/lgpl-2.1.txt
new file mode 100644 (file)
index 0000000..84f5523
--- /dev/null
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
index 82f01f9b4fc795f89bf59ffd57144313b83a8564..0bcfd1d231aed9f4b3ce9dfaab5dac0c71cd87ed 100644 (file)
  *
  * 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>
index 0f727a180a53c5834c07ff2830544b61b7c73f97..5516e494f2bbb74c68be2a7924e2fa091935cf3e 100644 (file)
  *
  * 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>
@@ -67,7 +75,7 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path,
        struct trace_descriptor *td;
        struct format *fmt;
        struct bt_trace_handle *handle;
-       int ret;
+       int ret, closeret;
 
        if (!ctx || !format_name || (!path && !stream_list))
                return -EINVAL;
@@ -82,16 +90,16 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path,
        if (path) {
                td = fmt->open_trace(path, O_RDONLY, packet_seek, NULL);
                if (!td) {
-                       fprintf(stderr, "[warning] [Context] Cannot open_trace of the format %s .\n\n",
-                                       path);
+                       fprintf(stderr, "[warning] [Context] Cannot open_trace of format %s at path %s.\n\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_trace of the format %s .\n\n",
-                                       path);
+                       fprintf(stderr, "[error] [Context] Cannot open_mmap_trace of format %s.\n\n",
+                                       format_name);
                        ret = -1;
                        goto end;
                }
@@ -103,7 +111,7 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path,
                fprintf(stderr, "[error] [Context] Creating trace handle %s .\n\n",
                                path);
                ret = -1;
-               goto end;
+               goto error;
        }
        handle->format = fmt;
        handle->td = td;
@@ -123,11 +131,11 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path,
                handle);
        ret = trace_collection_add(ctx->tc, td);
        if (ret != 0)
-               goto end;
+               goto error;
 
        ret = fmt->convert_index_timestamp(td);
        if (ret < 0)
-               goto end;
+               goto error;
 
        handle->real_timestamp_begin = fmt->timestamp_begin(td, handle, BT_CLOCK_REAL);
        handle->real_timestamp_end = fmt->timestamp_end(td, handle, BT_CLOCK_REAL);
@@ -135,6 +143,12 @@ int bt_context_add_trace(struct bt_context *ctx, const char *path,
        handle->cycles_timestamp_end = fmt->timestamp_end(td, handle, BT_CLOCK_CYCLES);
 
        return handle->id;
+
+error:
+       closeret = fmt->close_trace(td);
+       if (closeret) {
+               fprintf(stderr, "Error in close_trace callback\n");
+       }
 end:
        return ret;
 }
@@ -142,6 +156,7 @@ end:
 int bt_context_remove_trace(struct bt_context *ctx, int handle_id)
 {
        struct bt_trace_handle *handle;
+       int ret;
 
        if (!ctx)
                return -EINVAL;
@@ -154,8 +169,11 @@ int bt_context_remove_trace(struct bt_context *ctx, int handle_id)
        /* Remove from containers */
        trace_collection_remove(ctx->tc, handle->td);
        /* Close the trace */
-       handle->format->close_trace(handle->td);
-
+       ret = handle->format->close_trace(handle->td);
+       if (ret) {
+               fprintf(stderr, "Error in close_trace callback\n");
+               return ret;
+       }
        /* Remove and free the handle */
        g_hash_table_remove(ctx->trace_handles,
                        (gpointer) (unsigned long) handle_id);
@@ -168,7 +186,8 @@ void bt_context_destroy(struct bt_context *ctx)
        assert(ctx);
        finalize_trace_collection(ctx->tc);
 
-       /* Remote all traces. The g_hash_table_destroy will call
+       /*
+        * Remove all traces. The g_hash_table_destroy will call
         * bt_trace_handle_destroy on each elements.
         */
        g_hash_table_destroy(ctx->trace_handles);
index b57be035057923a5bee693c3e3889a4ef1f8d26b..41a46020f6c690b4cc253044d845c0919e34cf0f 100644 (file)
  *
  * 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>
@@ -253,7 +261,7 @@ static int find_max_timestamp_ctf_stream_class(
                struct ctf_file_stream **cfsp,
                uint64_t *max_timestamp)
 {
-       int ret = EOF, i;
+       int ret = EOF, i, found = 0;
 
        for (i = 0; i < stream_class->streams->len; i++) {
                struct ctf_stream_definition *stream;
@@ -272,9 +280,13 @@ static int find_max_timestamp_ctf_stream_class(
                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;
 }
 
@@ -381,8 +393,8 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos)
                        stream->prev_cycles_timestamp = 0;
                        stream->prev_cycles_timestamp_end = 0;
 
-                       printf_debug("restored to cur_index = %zd and "
-                               "offset = %zd, timestamp = %" PRIu64 "\n",
+                       printf_debug("restored to cur_index = %" PRId64 " and "
+                               "offset = %" PRId64 ", timestamp = %" PRIu64 "\n",
                                stream_pos->cur_index,
                                stream_pos->offset, stream->real_timestamp);
 
@@ -471,6 +483,10 @@ int bt_iter_set_pos(struct bt_iter *iter, const struct bt_iter_pos *iter_pos)
                                        if (ret != 0 && ret != EOF) {
                                                goto error;
                                        }
+                                       if (ret == EOF) {
+                                               /* Do not add EOF streams */
+                                               continue;
+                                       }
                                        ret = heap_insert(iter->stream_heap, file_stream);
                                        if (ret)
                                                goto error;
index 092f0095f874844d58ba5460b16b31eadfddd3ff..43b4e8a4d509bbda62e2f696d9b8327ae6bf003c 100644 (file)
  *
  * 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/prio_heap.h>
index 3cef63d93cb0966b783819b6e402201303062ab1..28af184f8c5da58c7122637a0353a09cc13b5453 100644 (file)
  *
  * 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>
@@ -29,16 +37,35 @@ struct walk_data {
        int iter;
 };
 
-static int init_done;
-void __attribute__((constructor)) format_init(void);
-void __attribute__((destructor)) format_finalize(void);
-
 /*
  * Format registry hash table contains the registered formats. Format
  * registration is typically performed by a format plugin.
- * TODO: support plugin unload (unregistration of formats).
  */
-GHashTable *format_registry;
+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 format *bt_lookup_format(bt_intern_str name)
 {
@@ -87,22 +114,41 @@ int bt_register_format(struct format *format)
        if (bt_lookup_format(format->name))
                return -EEXIST;
 
+       format_refcount_inc();
        g_hash_table_insert(format_registry,
                            (gpointer) (unsigned long) format->name,
                            format);
        return 0;
 }
 
+void bt_unregister_format(struct format *format)
+{
+       assert(bt_lookup_format(format->name));
+       g_hash_table_remove(format_registry,
+                           (gpointer) (unsigned long) 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)
 {
-       g_hash_table_destroy(format_registry);
+       format_refcount_dec();
 }
index 9b60986f5018e98c54e870c471cf498d36d79839..4f1379c5a43d73cb4e0bcae9053339bf533f7802 100644 (file)
  *
  * 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>
index f981adda410ab19266c2213c6ce50cae09a0b73d..0da565b02000e230eb9322dbc34bc3dffe5c0f5e 100644 (file)
  *
  * 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>
@@ -41,6 +49,7 @@ struct bt_trace_handle *bt_trace_handle_create(struct bt_context *ctx)
 
 void bt_trace_handle_destroy(struct bt_trace_handle *th)
 {
+       th->format->close_trace(th->td);
        g_free(th);
 }
 
index 5ea7f89af934f17dc7336b5947e0afc814343fb3..5f26899ac1e41b165edfbb0793732dfb6efa2127 100644 (file)
@@ -16,4 +16,4 @@ 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. 
+SOFTWARE.
index 642dd983de46de4edf3a82c1bcfe73242ce6184c..47891e90af0945d3accf10f7d3cd0fe1351af031 100644 (file)
@@ -1,5 +1,12 @@
 AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
 
+SUBDIRS = lib
+
 noinst_PROGRAMS = test-bitfield
 
 test_bitfield_SOURCES = test-bitfield.c
+
+EXTRA_DIST = runall.sh ctf-traces/**
+
+check-am:
+       ./runall.sh
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/metadata b/tests/ctf-traces/succeed/wk-heartbeat-u/metadata
new file mode 100755 (executable)
index 0000000..e35f463
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/metadata differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_0 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_0
new file mode 100755 (executable)
index 0000000..3af2cdc
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_0 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_1 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_1
new file mode 100755 (executable)
index 0000000..7b74c03
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_1 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_2 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_2
new file mode 100755 (executable)
index 0000000..13a69fc
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_2 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_3 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_3
new file mode 100755 (executable)
index 0000000..1cdde72
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_3 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_4 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_4
new file mode 100755 (executable)
index 0000000..c136034
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_4 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_5 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_5
new file mode 100755 (executable)
index 0000000..a0a5881
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_5 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_6 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_6
new file mode 100755 (executable)
index 0000000..b1c8520
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_6 differ
diff --git a/tests/ctf-traces/succeed/wk-heartbeat-u/u_7 b/tests/ctf-traces/succeed/wk-heartbeat-u/u_7
new file mode 100755 (executable)
index 0000000..05f7393
Binary files /dev/null and b/tests/ctf-traces/succeed/wk-heartbeat-u/u_7 differ
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
new file mode 100644 (file)
index 0000000..f7e32c2
--- /dev/null
@@ -0,0 +1,18 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
+
+noinst_LIBRARIES = libtestcommon.a
+
+libtestcommon_a_SOURCES = tap.c tap.h common.c common.h
+
+test_seeks_LDADD = libtestcommon.a \
+       $(top_builddir)/lib/libbabeltrace.la \
+       $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+
+noinst_PROGRAMS = test-seeks
+
+test_seeks_SOURCES = test-seeks.c
+
+EXTRA_DIST = README.tap
+
+check-am:
+       ./runall.sh
diff --git a/tests/lib/README.tap b/tests/lib/README.tap
new file mode 100644 (file)
index 0000000..e99e7b2
--- /dev/null
@@ -0,0 +1,2 @@
+tap.c and tap.h were taken from
+http://jc.ngo.org.uk/trac-bin/trac.cgi/wiki/LibTap
diff --git a/tests/lib/common.c b/tests/lib/common.c
new file mode 100644 (file)
index 0000000..25bf735
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * common.c
+ *
+ * Lib BabelTrace - Common function to all tests
+ *
+ * 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.
+ */
+#define _GNU_SOURCE
+
+#include <babeltrace/context.h>
+#include <babeltrace/iterator.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;
+}
diff --git a/tests/lib/common.h b/tests/lib/common.h
new file mode 100644 (file)
index 0000000..25a02ff
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * common.h
+ *
+ * Lib BabelTrace - Common function to all tests
+ *
+ * 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.
+ */
+#ifndef _TESTS_COMMON_H
+#define _TESTS_COMMON_H
+
+struct bt_context;
+
+struct bt_context *create_context_with_path(const char *path);
+
+#endif /* _TESTS_COMMON_H */
diff --git a/tests/lib/runall.sh b/tests/lib/runall.sh
new file mode 100755 (executable)
index 0000000..34503bb
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+# run Seeks tests
+# With a trace than contains empty packets
+./test-seeks ../ctf-traces/succeed/wk-heartbeat-u/ 1351532897586558519 1351532897591331194
+# With a bigger trace
+./test-seeks ../ctf-traces/succeed/lttng-modules-2.0-pre5/ 61334174524234 61336381998396
\ No newline at end of file
diff --git a/tests/lib/tap.c b/tests/lib/tap.c
new file mode 100644 (file)
index 0000000..a430951
--- /dev/null
@@ -0,0 +1,427 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "tap.h"
+
+static int no_plan = 0;
+static int skip_all = 0;
+static int have_plan = 0;
+static unsigned int test_count = 0; /* Number of tests that have been run */
+static unsigned int e_tests = 0; /* Expected number of tests to run */
+static unsigned int failures = 0; /* Number of tests that failed */
+static char *todo_msg = NULL;
+static char *todo_msg_fixed = "libtap malloc issue";
+static int todo = 0;
+static int test_died = 0;
+
+/* Encapsulate the pthread code in a conditional.  In the absence of
+   libpthread the code does nothing */
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+static pthread_mutex_t M = PTHREAD_MUTEX_INITIALIZER;
+# define LOCK pthread_mutex_lock(&M);
+# define UNLOCK pthread_mutex_unlock(&M);
+#else
+# define LOCK
+# define UNLOCK
+#endif
+
+static void _expected_tests(unsigned int);
+static void _tap_init(void);
+static void _cleanup(void);
+
+/*
+ * Generate a test result.
+ *
+ * ok -- boolean, indicates whether or not the test passed.
+ * test_name -- the name of the test, may be NULL
+ * test_comment -- a comment to print afterwards, may be NULL
+ */
+unsigned int
+_gen_result(int ok, const char *func, char *file, unsigned int line,
+           char *test_name, ...)
+{
+       va_list ap;
+       char *local_test_name = NULL;
+       char *c;
+       int name_is_digits;
+
+       LOCK;
+
+       test_count++;
+
+       /* Start by taking the test name and performing any printf()
+          expansions on it */
+       if(test_name != NULL) {
+               va_start(ap, test_name);
+               vasprintf(&local_test_name, test_name, ap);
+               va_end(ap);
+
+               /* Make sure the test name contains more than digits
+                  and spaces.  Emit an error message and exit if it
+                  does */
+               if(local_test_name) {
+                       name_is_digits = 1;
+                       for(c = local_test_name; *c != '\0'; c++) {
+                               if(!isdigit(*c) && !isspace(*c)) {
+                                       name_is_digits = 0;
+                                       break;
+                               }
+                       }
+
+                       if(name_is_digits) {
+                               diag("    You named your test '%s'.  You shouldn't use numbers for your test names.", local_test_name);
+                               diag("    Very confusing.");
+                       }
+               }
+       }
+
+       if(!ok) {
+               printf("not ");
+               failures++;
+       }
+
+       printf("ok %d", test_count);
+
+       if(test_name != NULL) {
+               printf(" - ");
+
+               /* Print the test name, escaping any '#' characters it
+                  might contain */
+               if(local_test_name != NULL) {
+                       flockfile(stdout);
+                       for(c = local_test_name; *c != '\0'; c++) {
+                               if(*c == '#')
+                                       fputc('\\', stdout);
+                               fputc((int)*c, stdout);
+                       }
+                       funlockfile(stdout);
+               } else {        /* vasprintf() failed, use a fixed message */
+                       printf("%s", todo_msg_fixed);
+               }
+       }
+
+       /* If we're in a todo_start() block then flag the test as being
+          TODO.  todo_msg should contain the message to print at this
+          point.  If it's NULL then asprintf() failed, and we should
+          use the fixed message.
+
+          This is not counted as a failure, so decrement the counter if
+          the test failed. */
+       if(todo) {
+               printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed);
+               if(!ok)
+                       failures--;
+       }
+
+       printf("\n");
+
+       if(!ok) {
+               if(getenv("HARNESS_ACTIVE") != NULL)
+                       fputs("\n", stderr);
+
+               diag("    Failed %stest (%s:%s() at line %d)",
+                    todo ? "(TODO) " : "", file, func, line);
+       }
+       free(local_test_name);
+
+       UNLOCK;
+
+       /* We only care (when testing) that ok is positive, but here we
+          specifically only want to return 1 or 0 */
+       return ok ? 1 : 0;
+}
+
+/*
+ * Initialise the TAP library.  Will only do so once, however many times it's
+ * called.
+ */
+void
+_tap_init(void)
+{
+       static int run_once = 0;
+
+       if(!run_once) {
+               atexit(_cleanup);
+
+               /* stdout needs to be unbuffered so that the output appears
+                  in the same place relative to stderr output as it does
+                  with Test::Harness */
+               setbuf(stdout, 0);
+               run_once = 1;
+       }
+}
+
+/*
+ * Note that there's no plan.
+ */
+int
+plan_no_plan(void)
+{
+
+       LOCK;
+
+       _tap_init();
+
+       if(have_plan != 0) {
+               fprintf(stderr, "You tried to plan twice!\n");
+               test_died = 1;
+               UNLOCK;
+               exit(255);
+       }
+
+       have_plan = 1;
+       no_plan = 1;
+
+       UNLOCK;
+
+       return 1;
+}
+
+/*
+ * Note that the plan is to skip all tests
+ */
+int
+plan_skip_all(char *reason)
+{
+
+       LOCK;
+
+       _tap_init();
+
+       skip_all = 1;
+
+       printf("1..0");
+
+       if(reason != NULL)
+               printf(" # Skip %s", reason);
+
+       printf("\n");
+
+       UNLOCK;
+
+       exit(0);
+}
+
+/*
+ * Note the number of tests that will be run.
+ */
+int
+plan_tests(unsigned int tests)
+{
+
+       LOCK;
+
+       _tap_init();
+
+       if(have_plan != 0) {
+               fprintf(stderr, "You tried to plan twice!\n");
+               test_died = 1;
+               UNLOCK;
+               exit(255);
+       }
+
+       if(tests == 0) {
+               fprintf(stderr, "You said to run 0 tests!  You've got to run something.\n");
+               test_died = 1;
+               UNLOCK;
+               exit(255);
+       }
+
+       have_plan = 1;
+
+       _expected_tests(tests);
+
+       UNLOCK;
+
+       return e_tests;
+}
+
+unsigned int
+diag(char *fmt, ...)
+{
+       va_list ap;
+
+       fputs("# ", stderr);
+
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+
+       fputs("\n", stderr);
+
+       return 0;
+}
+
+void
+_expected_tests(unsigned int tests)
+{
+
+       printf("1..%d\n", tests);
+       e_tests = tests;
+}
+
+int
+skip(unsigned int n, char *fmt, ...)
+{
+       va_list ap;
+       char *skip_msg;
+
+       LOCK;
+
+       va_start(ap, fmt);
+       asprintf(&skip_msg, fmt, ap);
+       va_end(ap);
+
+       while(n-- > 0) {
+               test_count++;
+               printf("ok %d # skip %s\n", test_count,
+                      skip_msg != NULL ?
+                      skip_msg : "libtap():malloc() failed");
+       }
+
+       free(skip_msg);
+
+       UNLOCK;
+
+       return 1;
+}
+
+void
+todo_start(char *fmt, ...)
+{
+       va_list ap;
+
+       LOCK;
+
+       va_start(ap, fmt);
+       vasprintf(&todo_msg, fmt, ap);
+       va_end(ap);
+
+       todo = 1;
+
+       UNLOCK;
+}
+
+void
+todo_end(void)
+{
+
+       LOCK;
+
+       todo = 0;
+       free(todo_msg);
+
+       UNLOCK;
+}
+
+int
+exit_status(void)
+{
+       int r;
+
+       LOCK;
+
+       /* If there's no plan, just return the number of failures */
+       if(no_plan || !have_plan) {
+               UNLOCK;
+               return failures;
+       }
+
+       /* Ran too many tests?  Return the number of tests that were run
+          that shouldn't have been */
+       if(e_tests < test_count) {
+               r = test_count - e_tests;
+               UNLOCK;
+               return r;
+       }
+
+       /* Return the number of tests that failed + the number of tests
+          that weren't run */
+       r = failures + e_tests - test_count;
+       UNLOCK;
+
+       return r;
+}
+
+/*
+ * Cleanup at the end of the run, produce any final output that might be
+ * required.
+ */
+void
+_cleanup(void)
+{
+
+       LOCK;
+
+       /* If plan_no_plan() wasn't called, and we don't have a plan,
+          and we're not skipping everything, then something happened
+          before we could produce any output */
+       if(!no_plan && !have_plan && !skip_all) {
+               diag("Looks like your test died before it could output anything.");
+               UNLOCK;
+               return;
+       }
+
+       if(test_died) {
+               diag("Looks like your test died just after %d.", test_count);
+               UNLOCK;
+               return;
+       }
+
+
+       /* No plan provided, but now we know how many tests were run, and can
+          print the header at the end */
+       if(!skip_all && (no_plan || !have_plan)) {
+               printf("1..%d\n", test_count);
+       }
+
+       if((have_plan && !no_plan) && e_tests < test_count) {
+               diag("Looks like you planned %d %s but ran %d extra.",
+                    e_tests, e_tests == 1 ? "test" : "tests", test_count - e_tests);
+               UNLOCK;
+               return;
+       }
+
+       if((have_plan || !no_plan) && e_tests > test_count) {
+               diag("Looks like you planned %d %s but only ran %d.",
+                    e_tests, e_tests == 1 ? "test" : "tests", test_count);
+               UNLOCK;
+               return;
+       }
+
+       if(failures)
+               diag("Looks like you failed %d %s of %d.",
+                    failures, failures == 1 ? "test" : "tests", test_count);
+
+       UNLOCK;
+}
diff --git a/tests/lib/tap.h b/tests/lib/tap.h
new file mode 100644 (file)
index 0000000..0f05943
--- /dev/null
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 Nik Clayton
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* '## __VA_ARGS__' is a gcc'ism. C99 doesn't allow the token pasting
+   and requires the caller to add the final comma if they've ommitted
+   the optional arguments */
+#ifdef __GNUC__
+# define ok(e, test, ...) ((e) ?                                       \
+                          _gen_result(1, __func__, __FILE__, __LINE__, \
+                                      test, ## __VA_ARGS__) :          \
+                          _gen_result(0, __func__, __FILE__, __LINE__, \
+                                      test, ## __VA_ARGS__))
+
+# define ok1(e) ((e) ?                                                 \
+                _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
+                _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
+
+# define pass(test, ...) ok(1, test, ## __VA_ARGS__);
+# define fail(test, ...) ok(0, test, ## __VA_ARGS__);
+
+# define skip_start(test, n, fmt, ...)                 \
+       do {                                            \
+               if((test)) {                            \
+                       skip(n, fmt, ## __VA_ARGS__);   \
+                       continue;                       \
+               }
+#elif __STDC_VERSION__ >= 199901L /* __GNUC__ */
+# define ok(e, ...) ((e) ?                                             \
+                    _gen_result(1, __func__, __FILE__, __LINE__,       \
+                                __VA_ARGS__) :                         \
+                    _gen_result(0, __func__, __FILE__, __LINE__,       \
+                                __VA_ARGS__))
+
+# define ok1(e) ((e) ?                                                 \
+                _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
+                _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
+
+# define pass(...) ok(1, __VA_ARGS__);
+# define fail(...) ok(0, __VA_ARGS__);
+
+# define skip_start(test, n, ...)                      \
+       do {                                            \
+               if((test)) {                            \
+                       skip(n,  __VA_ARGS__);          \
+                       continue;                       \
+               }
+#else /* __STDC_VERSION__ */
+# error "Needs gcc or C99 compiler for variadic macros."
+#endif /* __STDC_VERSION__ */
+
+#define skip_end() } while(0);
+
+unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...);
+
+int plan_no_plan(void);
+int plan_skip_all(char *);
+int plan_tests(unsigned int);
+
+unsigned int diag(char *, ...);
+
+int skip(unsigned int, char *, ...);
+
+void todo_start(char *, ...);
+void todo_end(void);
+
+int exit_status(void);
diff --git a/tests/lib/test-seeks.c b/tests/lib/test-seeks.c
new file mode 100644 (file)
index 0000000..47bb42e
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <babeltrace/context.h>
+#include <babeltrace/iterator.h>
+#include <babeltrace/ctf/iterator.h>
+#include <babeltrace/ctf/events.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "common.h"
+#include "tap.h"
+
+#define NR_TESTS       23
+
+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;
+       uint64_t timestamp_begin;
+       uint64_t timestamp_seek_begin;
+
+       /* Open the trace */
+       ctx = create_context_with_path(path);
+       if (!ctx) {
+               plan_skip_all("Cannot create valid context");
+       }
+
+       /* Create iterator with null begin and end */
+       iter = bt_ctf_iter_create(ctx, NULL, NULL);
+       if (!iter) {
+               plan_skip_all("Cannot create valid iterator");
+       }
+
+       event = bt_ctf_iter_read_event(iter);
+
+       ok(event, "Event valid");
+
+       /* Validate that the first timestamp is right */
+       timestamp_begin = bt_ctf_get_timestamp(event);
+
+       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");
+
+       timestamp_seek_begin = bt_ctf_get_timestamp(event);
+
+       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;
+       uint64_t timestamp_last;
+
+       /* Open the trace */
+       ctx = create_context_with_path(path);
+       if (!ctx) {
+               plan_skip_all("Cannot create valid context");
+       }
+
+       /* Create iterator with null last and end */
+       iter = bt_ctf_iter_create(ctx, NULL, NULL);
+       if (!iter) {
+               plan_skip_all("Cannot create valid iterator");
+       }
+
+       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");
+
+       timestamp_last = bt_ctf_get_timestamp(event);
+
+       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;
+       uint64_t timestamp;
+
+       /* Open the trace */
+       ctx = create_context_with_path(path);
+       if (!ctx) {
+               plan_skip_all("Cannot create valid context");
+       }
+
+       /* Create iterator with null last and end */
+       iter = bt_ctf_iter_create(ctx, NULL, NULL);
+       if (!iter) {
+               plan_skip_all("Cannot create valid iterator");
+       }
+
+       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");
+
+       timestamp = bt_ctf_get_timestamp(event);
+
+       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");
+
+       timestamp = bt_ctf_get_timestamp(event);
+
+       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");
+
+       timestamp = bt_ctf_get_timestamp(event);
+
+       ok1(timestamp == expected_last);
+
+       bt_context_put(ctx);
+}
+
+int main(int argc, char **argv)
+{
+       char *path;
+       uint64_t expected_begin;
+       uint64_t expected_last;
+
+       plan_tests(NR_TESTS);
+
+       if (argc < 4) {
+               plan_skip_all("Invalid arguments: need a trace path and the start and last timestamp");
+
+       }
+
+       /* Parse arguments (Trace, begin timestamp) */
+       path = argv[1];
+
+       expected_begin = strtoull(argv[2], NULL, 0);
+       if (ULLONG_MAX == expected_begin && errno == ERANGE) {
+               plan_skip_all("Invalid value for begin timestamp");
+       }
+
+       expected_last = strtoull(argv[3], NULL, 0);
+       if (ULLONG_MAX == expected_last && errno == ERANGE) {
+               plan_skip_all("Invalid value for last timestamp");
+       }
+
+       run_seek_begin(path, expected_begin);
+       run_seek_last(path, expected_last);
+       run_seek_cycles(path, expected_begin, expected_last);
+
+       return exit_status();
+}
diff --git a/tests/runall.sh b/tests/runall.sh
new file mode 100755 (executable)
index 0000000..b2af656
--- /dev/null
@@ -0,0 +1,97 @@
+#!/bin/bash
+
+TESTDIR=$(dirname $0)
+DIR=$(readlink -f ${TESTDIR})
+BABELTRACE_BIN=${DIR}/../converter/babeltrace
+CTF_TRACES=${DIR}/ctf-traces
+
+function print_ok ()
+{
+       # Check if we are a terminal
+       if [ -t 1 ]; then
+               echo -e "\e[1;32mOK\e[0m"
+       else
+               echo -e "OK"
+       fi
+}
+
+function print_fail ()
+{
+       # Check if we are a terminal
+       if [ -t 1 ]; then
+               echo -e "\e[1;31mFAIL\e[0m"
+       else
+               echo -e "FAIL"
+       fi
+}
+
+function test_check ()
+{
+       if [ $? -ne 0 ] ; then
+               print_fail
+               return 1
+       else
+               print_ok
+               return 0
+       fi
+}
+
+function test_check_fail ()
+{
+       if [ $? -ne 1 ] ; then
+               print_fail
+               return 1
+       else
+               print_ok
+               return 0
+       fi
+}
+
+function run_babeltrace ()
+{
+       ${BABELTRACE_BIN} $* > /dev/null 2>&1
+       return $?
+}
+
+echo -e "Running test-bitfield..."
+./test-bitfield
+test_check
+if [ $? -ne 0 ]; then
+       exit 1
+fi
+
+#run babeltrace expects success
+echo -e "Running babeltrace without argument..."
+run_babeltrace
+test_check
+if [ $? -ne 0 ]; then
+       exit 1
+fi
+
+for a in ${CTF_TRACES}/succeed/*; do
+       echo -e "Running babeltrace for trace ${a}..."
+       run_babeltrace ${a}
+       test_check
+       if [ $? -ne 0 ]; then
+               exit 1
+       fi
+done
+
+#run babeltrace expects failure
+echo -e "Running babeltrace with bogus argument..."
+run_babeltrace --bogusarg
+test_check_fail
+if [ $? -ne 0 ]; then
+       exit 1
+fi
+
+for a in ${CTF_TRACES}/fail/*; do
+       echo -e "Running babeltrace for trace ${a}..."
+       run_babeltrace ${a}
+       test_check_fail
+       if [ $? -ne 0 ]; then
+               exit 1
+       fi
+done
+
+exit 0
index 047adac21902c7d7f438fc14a1e55099181280f1..3a92ef769fff5684680b616c0391678226709ecc 100644 (file)
  *
  * 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>
index 4e3cc45c7849dbc93168bdfbbf725e82c6ff0a12..ca0143d4f5a53849136b7195bde96c2a62b93240 100644 (file)
  *
  * 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>
index 3e49a4b1fbc7c2c995cb7adc490de0fe49d61d6b..028749bc92a177f91237283797a234a65fd21284 100644 (file)
  *
  * 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>
@@ -83,7 +91,6 @@ struct definition *
                container_of(declaration, struct declaration_float, p);
        struct definition_float *_float;
        struct definition *tmp;
-       int ret;
 
        _float = g_new(struct definition_float, 1);
        declaration_ref(&float_declaration->p);
@@ -121,6 +128,8 @@ struct definition *
        _float->p.name = field_name;
        _float->value = 0.0;
        if (parent_scope) {
+               int ret;
+
                ret = register_field_definition(field_name, &_float->p,
                                                parent_scope);
                assert(!ret);
index 212d8d489ce35f04562ff7e10ddfb26a09c95d31..337641d7a3123018f14fc3f933285da8d35484ad 100644 (file)
  *
  * 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>
index bd49d2a6507f116a5f916a423785761e06fd1cb5..0e84b1d18ceb092fe28af8c45ce1eb8a9fcba23c 100644 (file)
  *
  * 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>
@@ -206,8 +214,8 @@ void _sequence_definition_free(struct definition *definition)
                        field = g_ptr_array_index(sequence->elems, i);
                        field->declaration->definition_free(field);
                }
+               (void) g_ptr_array_free(sequence->elems, TRUE);
        }
-       (void) g_ptr_array_free(sequence->elems, TRUE);
        definition_unref(len_definition);
        free_definition_scope(sequence->p.scope);
        declaration_unref(sequence->p.declaration);
index daaeef5aa7514f00762e08b9cb79835663647645..4860740616ae97631c1a0c61ffd6f61a10ef8220 100644 (file)
  *
  * 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>
index f360407c46f3ed956285689ae3847c9b5d01625a..138da167509ae25c8cf0f218b4ca5ccfeaf63978 100644 (file)
  *
  * 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>
@@ -169,6 +177,7 @@ void _struct_definition_free(struct definition *definition)
        }
        free_definition_scope(_struct->p.scope);
        declaration_unref(_struct->p.declaration);
+       g_ptr_array_free(_struct->fields, TRUE);
        g_free(_struct);
 }
 
index 450c93ba6b5206c9edcdd8fb726e92c0b029d73a..55990271dccb153a9d0562f23edd672db4c37a26 100644 (file)
  *
  * 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>
@@ -32,10 +40,13 @@ 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));
-       nq = g_quark_from_string(g_string_free(str, FALSE));
+       quark_str = g_string_free(str, FALSE);
+       nq = g_quark_from_string(quark_str);
+       g_free(quark_str);
        return nq;
 }
 
@@ -114,10 +125,10 @@ static int compare_paths(GArray *a, GArray *b, int len)
 
 static int is_path_child_of(GArray *path, GArray *maybe_parent)
 {
-       int i, ret;
+       int ret;
 
        if (babeltrace_debug) {
-               int need_dot = 0;
+               int i, need_dot = 0;
 
                printf_debug("Is path \"");
                for (i = 0; i < path->len; need_dot = 1, i++)
@@ -494,7 +505,6 @@ GQuark new_definition_path(struct definition_scope *parent_scope,
        GQuark path;
        GString *str;
        gchar *c_str;
-       int i;
        int need_dot = 0;
 
        str = g_string_new("");
@@ -502,6 +512,8 @@ GQuark new_definition_path(struct definition_scope *parent_scope,
                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);
index faf70dde200e6bbff757ecc889e1132e5dca5cde..55b4b1f058820c0c7089202dc029478d31a0e96b 100644 (file)
  *
  * 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>
@@ -90,8 +98,9 @@ void _variant_declaration_free(struct declaration *declaration)
        struct declaration_variant *variant_declaration =
                container_of(declaration, struct declaration_variant, p);
 
-       _untagged_variant_declaration_free(&variant_declaration->untagged_variant->p);
+       declaration_unref(&variant_declaration->untagged_variant->p);
        g_array_free(variant_declaration->tag_name, TRUE);
+       g_free(variant_declaration);
 }
 
 struct declaration_variant *
@@ -244,6 +253,7 @@ void _variant_definition_free(struct definition *definition)
        definition_unref(variant->enum_tag);
        free_definition_scope(variant->p.scope);
        declaration_unref(variant->p.declaration);
+       g_ptr_array_free(variant->fields, TRUE);
        g_free(variant);
 }
 
This page took 0.234923 seconds and 4 git commands to generate.