lib: add field location API
authorSimon Marchi <simon.marchi@efficios.com>
Fri, 27 Oct 2023 19:18:06 +0000 (19:18 +0000)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 4 Sep 2024 19:05:14 +0000 (15:05 -0400)
Add API functions to create field location objects.

Field locations are created using bt_field_location_create.  The caller
must pass a trace class, which is used to verify that the MIP version
of the graph is >= 1.  The caller passes a (root) scope, and an array of
components, which are the names to get from the root of the scope to the
desired field.

Accessor functions are:

 - bt_field_location_get_scope
 - bt_field_location_get_component_count
 - bt_field_location_get_component_by_index

They are intended to be used by a component consuming a trace.

Philippe updated the documentation.

Change-Id: Iad554ce39e13194bd9cc056c2d6d43ba8b87effe
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/7316
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/7199

doc/api/libbabeltrace2/Doxyfile.in
include/Makefile.am
include/babeltrace2/babeltrace.h
include/babeltrace2/trace-ir/field-location.h [new file with mode: 0644]
include/babeltrace2/trace-ir/field-path.h
include/babeltrace2/types.h
src/Makefile.am
src/lib/assert-cond.h
src/lib/trace-ir/field-location.c [new file with mode: 0644]
src/lib/trace-ir/field-location.h [new file with mode: 0644]

index 5a4a1e40379b636cf0b7bb13c2810dcb78b97e5e..283f7a1cd6fa1edb7dff449c2137bc4d9e568095 100644 (file)
@@ -33,6 +33,7 @@ ALIASES                += bt_dt_opt="<strong><em>Optional</em></strong>:"
 ALIASES                += bt_man{2}="<a href=\"https://babeltrace.org/docs/v\bt_version_min_maj/man\2/\1.\2/\"><code><strong>\1</strong>(\2)</code></a>"
 ALIASES                += bt_cli="<a href=\"https://babeltrace.org/docs/v\bt_version_min_maj/man1/babeltrace2.1\"><code>babeltrace2</code></a>"
 ALIASES                += bt_voidp="<code>void&nbsp;*</code>"
+ALIASES                += bt_var{1}="<strong><em>\1</em></strong>"
 
 # Aliases: preconditions: general
 ALIASES                += bt_pre_not_null{1}="@pre \bt_p{\1} is \em not \c NULL."
@@ -288,6 +289,7 @@ ALIASES                += bt_cs="\link api-tir-cs clock snapshot\endlink"
 ALIASES                += bt_ev_cls="\link api-tir-ev-cls event class\endlink"
 ALIASES                += bt_ev="\link api-tir-ev event\endlink"
 ALIASES                += bt_field_path="\link api-tir-field-path field path\endlink"
+ALIASES                += bt_field_loc="\link api-tir-field-loc field location\endlink"
 ALIASES                += bt_pkt="\link api-tir-pkt packet\endlink"
 ALIASES                += bt_stream_cls="\link api-tir-stream-cls stream class\endlink"
 ALIASES                += bt_stream="\link api-tir-stream stream\endlink"
@@ -300,6 +302,7 @@ ALIASES                += bt_c_cs="\link api-tir-cs Clock snapshot\endlink"
 ALIASES                += bt_c_ev_cls="\link api-tir-ev-cls Event class\endlink"
 ALIASES                += bt_c_ev="\link api-tir-ev Event\endlink"
 ALIASES                += bt_c_field_path="\link api-tir-field-path Field path\endlink"
+ALIASES                += bt_c_field_loc="\link api-tir-field-loc Field location\endlink"
 ALIASES                += bt_c_pkt="\link api-tir-pkt Packet\endlink"
 ALIASES                += bt_c_stream_cls="\link api-tir-stream-cls Stream class\endlink"
 ALIASES                += bt_c_stream="\link api-tir-stream Stream\endlink"
@@ -312,6 +315,7 @@ ALIASES                += bt_p_cs="\link api-tir-cs clock snapshots\endlink"
 ALIASES                += bt_p_ev_cls="\link api-tir-ev-cls event classes\endlink"
 ALIASES                += bt_p_ev="\link api-tir-ev events\endlink"
 ALIASES                += bt_p_field_path="\link api-tir-field-path field paths\endlink"
+ALIASES                += bt_p_field_loc="\link api-tir-field-loc field locations\endlink"
 ALIASES                += bt_p_pkt="\link api-tir-pkt packets\endlink"
 ALIASES                += bt_p_stream_cls="\link api-tir-stream-cls stream classes\endlink"
 ALIASES                += bt_p_stream="\link api-tir-stream streams\endlink"
@@ -324,6 +328,7 @@ ALIASES                += bt_cp_cs="\link api-tir-cs Clock snapshots\endlink"
 ALIASES                += bt_cp_ev_cls="\link api-tir-ev-cls event classes\endlink"
 ALIASES                += bt_cp_ev="\link api-tir-ev Events\endlink"
 ALIASES                += bt_cp_field_path="\link api-tir-field-path Field paths\endlink"
+ALIASES                += bt_cp_field_loc="\link api-tir-field-loc Field locations\endlink"
 ALIASES                += bt_cp_pkt="\link api-tir-pkt Packets\endlink"
 ALIASES                += bt_cp_stream_cls="\link api-tir-stream-cls Stream classes\endlink"
 ALIASES                += bt_cp_stream="\link api-tir-stream Streams\endlink"
@@ -674,6 +679,7 @@ INPUT                   = "@srcdir@/dox/main-page.dox" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/field.h" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/field-class.h" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/field-path.h" \
+                          "@top_srcdir@/include/babeltrace2/trace-ir/field-location.h" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/packet.h" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/stream.h" \
                           "@top_srcdir@/include/babeltrace2/trace-ir/stream-class.h" \
index 3c4969ccd59d08a0f32cb6684bce6d5575b645b2..1b996433d5bd8e2887a31d40b87ba5e8b7dc8171 100644 (file)
@@ -41,6 +41,7 @@ babeltrace2traceirinclude_HEADERS = \
        babeltrace2/trace-ir/event-class.h \
        babeltrace2/trace-ir/event.h \
        babeltrace2/trace-ir/field-class.h \
+       babeltrace2/trace-ir/field-location.h \
        babeltrace2/trace-ir/field-path.h \
        babeltrace2/trace-ir/field.h \
        babeltrace2/trace-ir/packet.h \
index 82f625145351f1f5febe9388c75fb8ec0848a0bc..62d2bf76c0cbc1c4c95decc781ea6f0fc4269fc0 100644 (file)
@@ -78,6 +78,7 @@
 #include <babeltrace2/trace-ir/event-class.h>
 #include <babeltrace2/trace-ir/event.h>
 #include <babeltrace2/trace-ir/field-class.h>
+#include <babeltrace2/trace-ir/field-location.h>
 #include <babeltrace2/trace-ir/field-path.h>
 #include <babeltrace2/trace-ir/field.h>
 #include <babeltrace2/trace-ir/packet.h>
diff --git a/include/babeltrace2/trace-ir/field-location.h b/include/babeltrace2/trace-ir/field-location.h
new file mode 100644 (file)
index 0000000..44b1cd1
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2022-2024 EfficiOS Inc. and Linux Foundation
+ */
+
+#ifndef BABELTRACE2_TRACE_IR_FIELD_LOCATION_H
+#define BABELTRACE2_TRACE_IR_FIELD_LOCATION_H
+
+#ifndef __BT_IN_BABELTRACE_H
+# error "Please include <babeltrace2/babeltrace.h> instead."
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@defgroup api-tir-field-loc Field location
+@ingroup api-tir
+
+@brief
+    Location of a \bt_field.
+
+A <strong><em>field location</em></strong> indicates how to reach a
+given \bt_field from a given <em>root scope</em>.
+
+@note
+    @parblock
+    Unlike a \bt_field_path, which is only available within a
+    trace processing \bt_graph with the effective \bt_mip (MIP)
+    version&nbsp;0, a field location works with \bt_struct_field member
+    <em>names</em>, not with structure field member <em>indexes</em>.
+
+    This makes a field location more versatile than a field path,
+    rendering possible, for example, multiple \bt_p_uint_field to act as
+    candidates for the length field of a dynamic array field when
+    they're part of the same \bt_var_field.
+
+    The field location API is only available within a trace processing
+    graph with the effective MIP version&nbsp;1.
+    @endparblock
+
+A field location indicates how to reach:
+
+- The length field(s) of a \bt_darray_field (with a length field).
+- The selector field of a \bt_opt_field (with a selector field).
+- The selector field of a \bt_var_field (with a selector field).
+
+A field location is a \ref api-tir "trace IR" metadata object.
+
+A field location is a \ref api-fund-shared-object "shared object": get a
+new reference with bt_field_location_get_ref() and put an existing
+reference with bt_field_location_put_ref().
+
+The type of a field location is #bt_field_location.
+
+Create a field location with bt_field_location_create().
+
+<h1>Properties</h1>
+
+A field location has the following properties:
+
+<dl>
+  <dt>
+    \anchor api-tir-field-loc-prop-root
+    Root scope
+  </dt>
+  <dd>
+    Indicates from which \bt_struct_field to start a field location.
+
+    See \ref api-tir-field-loc-proc "Field location procedure" to
+    learn more.
+
+    Get the root scope of a field location with
+    bt_field_location_get_root_scope().
+  </dd>
+
+  <dt>
+    \anchor api-tir-field-loc-prop-items
+    Items
+  </dt>
+  <dd>
+    Each item in the item list of a field location indicates which
+    action to take to follow the location to the linked \bt_field.
+
+    A field location item is a string (a structure field member name).
+
+    See \ref api-tir-field-loc-proc "Field location procedure" to
+    learn more.
+
+    Get the number of items in a field location with
+    bt_field_location_get_item_count().
+
+    Get an item from a field location with
+    bt_field_location_get_item_by_index().
+
+    A field location item always belongs to the field location which
+    contains it.
+  </dd>
+</dl>
+
+<h1>\anchor api-tir-field-loc-proc Field location procedure</h1>
+
+To locate a field from another field \bt_var{SRCFIELD} using
+its field location \bt_var{FIELDLOC}:
+
+-# Let \bt_var{CURFIELD} be, depending on the
+   root scope of \bt_var{FIELDLOC}
+   (as returned by bt_field_location_get_root_scope()):
+
+   <dl>
+     <dt>#BT_FIELD_LOCATION_SCOPE_PACKET_CONTEXT</dt>
+     <dd>
+       What bt_packet_borrow_context_field_const() returns for the
+       current \bt_pkt.
+     </dd>
+     <dt>#BT_FIELD_LOCATION_SCOPE_EVENT_COMMON_CONTEXT</dt>
+     <dd>
+       What bt_event_borrow_common_context_field_const() returns
+       for the current \bt_ev.
+     </dd>
+     <dt>#BT_FIELD_LOCATION_SCOPE_EVENT_SPECIFIC_CONTEXT</dt>
+     <dd>
+       What bt_event_borrow_specific_context_field_const() returns
+       for the current event.
+     </dd>
+     <dt>#BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD</dt>
+     <dd>
+       What bt_event_borrow_payload_field_const() returns for the
+       current event.
+     </dd>
+   </dl>
+
+-# For each field location item \bt_var{NAME} in \bt_var{FIELDLOC} (use
+   bt_field_location_get_item_count() and
+   bt_field_location_get_item_by_index()):
+
+   -# Let \bt_var{CURFIELD} be the field of the structure field
+      member named \bt_var{NAME} within \bt_var{CURFIELD}
+      (as returned by
+      bt_field_structure_borrow_member_field_by_name_const()).
+
+   -# Depending on the class type of \bt_var{CURFIELD} (as returned by
+      bt_field_get_class_type()):
+
+      <dl>
+        <dt>#BT_FIELD_CLASS_TYPE_BOOL</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_SIGNED_INTEGER</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION</dt>
+        <dd>End the field location procedure.</dd>
+
+        <dt>#BT_FIELD_CLASS_TYPE_STRUCTURE</dt>
+        <dd>Continue.</dd>
+
+        <dt>#BT_FIELD_CLASS_TYPE_STATIC_ARRAY</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD</dt>
+        <dd>
+           While the class type of \bt_var{CURFIELD} is one of the
+           three above (that is, while \bt_var{CURFIELD} i
+           an array field):
+
+           - Set \bt_var{CURFIELD} to the element field of
+             \bt_var{CURFIELD} (as returned by
+             bt_field_array_borrow_element_field_by_index_const())
+             containing \bt_var{SRCFIELD}.
+        </dd>
+
+        <dt>#BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD</dt>
+        <dd>
+          Set \bt_var{CURFIELD} to the optional field of
+          \bt_var{CURFIELD} (as returned by
+          bt_field_option_borrow_field_const()).
+        </dd>
+
+        <dt>#BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD</dt>
+        <dt>#BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD</dt>
+        <dd>
+          Set \bt_var{CURFIELD} to the selected option field of
+          \bt_var{CURFIELD} (as returned by
+          bt_field_variant_borrow_selected_option_field_const()).
+        </dd>
+      </dl>
+
+After this procedure, \bt_var{CURFIELD} is the located field.
+*/
+
+/*! @{ */
+
+/*!
+@brief
+    Field location scope enumerators.
+*/
+typedef enum bt_field_location_scope {
+       /*!
+       @brief
+           Context of the current \bt_pkt.
+       */
+       BT_FIELD_LOCATION_SCOPE_PACKET_CONTEXT          = 0,
+
+       /*!
+       @brief
+           Common context of the current \bt_ev.
+       */
+       BT_FIELD_LOCATION_SCOPE_EVENT_COMMON_CONTEXT    = 1,
+
+       /*!
+       @brief
+           Specific context of the current event.
+       */
+       BT_FIELD_LOCATION_SCOPE_EVENT_SPECIFIC_CONTEXT  = 2,
+
+       /*!
+       @brief
+           Payload of the current event.
+       */
+       BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD           = 3,
+} bt_field_location_scope;
+
+/*!
+@brief
+    Creates a field location from the trace class \bt_p{trace_class}
+    using the scope \bt_p{scope} and the items \bt_p{items}.
+
+@param[in] trace_class
+    Trace class from which to create a field location.
+@param[in] root_scope
+    \link api-tir-field-loc-prop-root Root scope\endlink of the
+    field location to create.
+@param[in] items
+    @parblock
+    \link api-tir-field-loc-prop-items Items\endlink (copied) of the
+    field location to create.
+
+    \bt_p{item_count} is the number of elements in \bt_p{items}.
+    @endparblock
+@param[in] item_count
+    Number of elements in \bt_p{items}.
+
+@returns
+    New field location reference, or \c NULL on memory error.
+
+@bt_pre_not_null{trace_class}
+@bt_pre_tc_with_mip{trace_class, 0}
+@bt_pre_not_null{items}
+@pre
+    \bt_p{item_count}&nbsp;≥&nbsp;1.
+*/
+extern bt_field_location *bt_field_location_create(
+               bt_trace_class *trace_class,
+               bt_field_location_scope root_scope,
+               const char *const *items,
+               uint64_t item_count) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Returns the root scope of the field location \bt_p{field_location}.
+
+See the \ref api-tir-field-loc-prop-root "root scope" property.
+
+@param[in] field_location
+    Field location of which to get the root scope.
+
+@returns
+    Root scope of \bt_p{field_location}.
+
+@bt_pre_not_null{field_location}
+*/
+extern bt_field_location_scope bt_field_location_get_root_scope(
+               const bt_field_location *field_location) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Returns the number of items contained in the field location
+    \bt_p{field_location}.
+
+See the \ref api-tir-field-loc-prop-items "items" property.
+
+@param[in] field_location
+    Field location of which to get the number of contained items.
+
+@returns
+    Number of contained items in \bt_p{field_location}.
+
+@bt_pre_not_null{field_location}
+
+@sa bt_field_location_get_item_by_index() &mdash;
+    Returns an item by index from a field location.
+*/
+extern uint64_t bt_field_location_get_item_count(
+               const bt_field_location *field_location) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Borrows the item at index \bt_p{index} from the
+    field location \bt_p{field_location}.
+
+See the \ref api-tir-field-loc-prop-items "items" property.
+
+@param[in] field_location
+    Field location from which to borrow the item at index \bt_p{index}.
+@param[in] index
+    Index of the item to borrow from \bt_p{field_location}.
+
+@returns
+    @parblock
+    Item of \bt_p{field_location} at index \bt_p{index}.
+
+    The returned pointer remains valid as long as \bt_p{field_location}
+    exists.
+    @endparblock
+
+@bt_pre_not_null{field_location}
+@pre
+    \bt_p{index} is less than the number of items in
+    \bt_p{field_location}
+    (as returned by bt_field_location_get_item_count()).
+
+@sa bt_field_location_get_item_count() &mdash;
+    Returns the number of items contained in a field location.
+*/
+extern const char *bt_field_location_get_item_by_index(
+               const bt_field_location *field_location,
+               uint64_t index) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Increments the \ref api-fund-shared-object "reference count" of
+    the field location \bt_p{field_location}.
+
+@param[in] field_location
+    @parblock
+    Field location of which to increment the reference count.
+
+    Can be \c NULL.
+    @endparblock
+
+@sa bt_field_location_put_ref() &mdash;
+    Decrements the reference count of a field location.
+*/
+extern void bt_field_location_get_ref(
+               const bt_field_location *field_location) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Decrements the \ref api-fund-shared-object "reference count" of
+    the field location \bt_p{field_location}.
+
+@param[in] field_location
+    @parblock
+    Field location of which to decrement the reference count.
+
+    Can be \c NULL.
+    @endparblock
+
+@sa bt_field_location_get_ref() &mdash;
+    Increments the reference count of a field location.
+*/
+extern void bt_field_location_put_ref(
+               const bt_field_location *field_location) __BT_NOEXCEPT;
+
+/*!
+@brief
+    Decrements the reference count of the field location
+    \bt_p{_field_location}, and then sets \bt_p{_field_location} to
+    \c NULL.
+
+@param _field_location
+    @parblock
+    Field location of which to decrement the reference count.
+
+    Can contain \c NULL.
+    @endparblock
+
+@bt_pre_assign_expr{_field_location}
+*/
+#define BT_FIELD_LOCATION_PUT_REF_AND_RESET(_field_location)   \
+       do {                                                    \
+               bt_field_location_put_ref(_field_location);     \
+               (_field_location) = NULL;                       \
+       } while (0)
+
+/*!
+@brief
+    Decrements the reference count of the field location \bt_p{_dst},
+    sets \bt_p{_dst} to \bt_p{_src}, and then sets \bt_p{_src}
+    to \c NULL.
+
+This macro effectively moves a field location reference from the
+expression \bt_p{_src} to the expression \bt_p{_dst}, putting the
+existing \bt_p{_dst} reference.
+
+@param _dst
+    @parblock
+    Destination expression.
+
+    Can contain \c NULL.
+    @endparblock
+@param _src
+    @parblock
+    Source expression.
+
+    Can contain \c NULL.
+    @endparblock
+
+@bt_pre_assign_expr{_dst}
+@bt_pre_assign_expr{_src}
+*/
+#define BT_FIELD_LOCATION_MOVE_REF(_dst, _src)         \
+       do {                                            \
+               bt_field_location_put_ref(_dst);        \
+               (_dst) = (_src);                        \
+               (_src) = NULL;                          \
+       } while (0)
+
+/*! @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BABELTRACE2_TRACE_IR_FIELD_LOCATION_H */
index 039ceb5095fcc1f0a02a99b000ca1c7217687dd4..7ff8adb290ac6f4bd473f65cf7b4b91cfbc4eb3a 100644 (file)
@@ -37,6 +37,12 @@ More specifically, a field path indicates how to reach:
 - The selector field of a \bt_opt_field (with a selector field).
 - The selector field of a \bt_var_field (with a selector field).
 
+@note
+    The field path API is only available within a trace processing
+    \bt_graph with the effective \bt_mip (MIP) version&nbsp;0: use the
+    similar \bt_field_loc API within a graph with
+    the effective MIP version&nbsp;1.
+
 You can borrow the field path from the \ref api-tir-fc "classes" of such
 fields with
 bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const(),
index 42e6bd48f286eb1783dc00f8a233a9c4a5756a09..68ca64dcf08b68981c09cfc509c2dfaa5f19aa6f 100644 (file)
@@ -44,6 +44,7 @@ typedef struct bt_field_class_structure_member bt_field_class_structure_member;
 typedef struct bt_field_class_variant_option bt_field_class_variant_option;
 typedef struct bt_field_class_variant_with_selector_field_integer_signed_option bt_field_class_variant_with_selector_field_integer_signed_option;
 typedef struct bt_field_class_variant_with_selector_field_integer_unsigned_option bt_field_class_variant_with_selector_field_integer_unsigned_option;
+typedef struct bt_field_location bt_field_location;
 typedef struct bt_field_path bt_field_path;
 typedef struct bt_field_path_item bt_field_path_item;
 typedef struct bt_graph bt_graph;
index 72a714639917b72780ee75115de709bb1ad39237..e3c8e4787cfd41e9429ff6b1b287238442fd2b01 100644 (file)
@@ -456,6 +456,8 @@ lib_libbabeltrace2_la_SOURCES = \
        lib/trace-ir/field-class.c \
        lib/trace-ir/field-class.h \
        lib/trace-ir/field.h \
+       lib/trace-ir/field-location.c \
+       lib/trace-ir/field-location.h \
        lib/trace-ir/field-path.c \
        lib/trace-ir/field-path.h \
        lib/trace-ir/field-wrapper.c \
index 62437c5aaf6a76a7e12014b894cf17a8f8d25db5..fa19c61ac046831c0a30bda34f9c7278e418f3be 100644 (file)
        BT_ASSERT_PRE_DEV_NON_NULL(_BT_ASSERT_PRE_VAR_FC_OPT_ID, (_fc), \
                _BT_ASSERT_PRE_VAR_FC_OPT_NAME)
 
+/* Field location */
+#define _BT_ASSERT_PRE_FL_NAME "Field location"
+#define _BT_ASSERT_PRE_FL_ID   "field-location"
+
+/* Asserts that `_fl` is non-NULL */
+#define BT_ASSERT_PRE_FL_NON_NULL(_fl)                                 \
+       BT_ASSERT_PRE_NON_NULL(_BT_ASSERT_PRE_FL_ID, (_fl),             \
+               _BT_ASSERT_PRE_FL_NAME)
+
 #define _BT_ASSERT_PRE_FP_NAME "Field path"
 #define _BT_ASSERT_PRE_FP_ID   "field-path"
 
                _mip_version == _val,                           \
                "MIP version is not equal to %" PRIu64, _val)
 
+/*
+ * Asserts that the given MIP version `_mip_version` is greater than or equal
+ * to `_val`.
+ */
+#define BT_ASSERT_PRE_MIP_VERSION_GE(_mip_version, _val)                       \
+       BT_ASSERT_PRE(_BT_ASSERT_PRE_MIP_VERSION_VALID_ID,                      \
+               _mip_version >= _val,                                           \
+               "MIP version is less than %" PRIu64, _val)
+
 /*
  * Asserts that the effective MIP version for `_trace_class` is equal to `_val`.
  */
 #define BT_ASSERT_PRE_TC_MIP_VERSION_EQ(_trace_class, _val)            \
        BT_ASSERT_PRE_MIP_VERSION_EQ((_trace_class)->mip_version, _val)
 
+/*
+ * Asserts that the effective MIP version for `_trace_class` is greater than or
+ * equal to `_val`.
+ */
+#define BT_ASSERT_PRE_TC_MIP_VERSION_GE(_trace_class, _val)            \
+       BT_ASSERT_PRE_MIP_VERSION_GE((_trace_class)->mip_version, _val)
+
 /*
  * Asserts that the effective MIP version for `_field_class` is equal to `_val`.
  */
diff --git a/src/lib/trace-ir/field-location.c b/src/lib/trace-ir/field-location.c
new file mode 100644 (file)
index 0000000..5062351
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2022 EfficiOS Inc. and Linux Foundation
+ */
+
+#define BT_LOG_TAG "LIB/FIELD-LOCATION"
+#include "lib/logging.h"
+#include "lib/assert-cond.h"
+#include "lib/object.h"
+#include "lib/graph/graph.h"
+#include "lib/trace-ir/trace-class.h"
+#include "compat/compiler.h"
+
+#include "field-location.h"
+
+static
+void destroy_field_location(bt_object *object)
+{
+       struct bt_field_location *field_location =
+               (struct bt_field_location *) object;
+
+       if (field_location->items) {
+               g_ptr_array_free(field_location->items, TRUE);
+       }
+
+       g_free(field_location);
+}
+
+BT_EXPORT
+bt_field_location *bt_field_location_create(
+               bt_trace_class *trace_class,
+               bt_field_location_scope scope,
+               const char *const *items,
+               uint64_t item_count)
+{
+       struct bt_field_location *field_location = NULL;
+       uint64_t i;
+
+       BT_LOGD_STR("Creating field location object.");
+
+       BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
+       BT_ASSERT_PRE("item-count-ge-1", item_count >= 1,
+               "Item count is 0");
+
+       field_location = g_new0(struct bt_field_location, 1);
+       if (!field_location) {
+               BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one field location.");
+               goto error;
+       }
+
+       bt_object_init_shared(&field_location->base, destroy_field_location);
+       field_location->scope = scope;
+
+       field_location->items = g_ptr_array_new_with_free_func(g_free);
+       if (!field_location->items) {
+               BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one GPtrArray.");
+               goto error;
+       }
+
+       for (i = 0; i < item_count; ++i) {
+               gchar *item = g_strdup(items[i]);
+
+               g_ptr_array_add(field_location->items, item);
+       }
+
+       goto end;
+
+error:
+       BT_FIELD_LOCATION_PUT_REF_AND_RESET(field_location);
+
+end:
+       return field_location;
+}
+
+BT_EXPORT
+bt_field_location_scope bt_field_location_get_root_scope(
+               const bt_field_location *location)
+{
+       BT_ASSERT_PRE_FL_NON_NULL(location);
+
+       return location->scope;
+}
+
+BT_EXPORT
+uint64_t bt_field_location_get_item_count(
+               const bt_field_location *location)
+{
+       BT_ASSERT_PRE_FL_NON_NULL(location);
+
+       return location->items->len;
+}
+
+BT_EXPORT
+const char *bt_field_location_get_item_by_index(
+               const bt_field_location *location, uint64_t index)
+{
+       BT_ASSERT_PRE_FL_NON_NULL(location);
+       BT_ASSERT_PRE_VALID_INDEX(index, location->items->len);
+
+       return location->items->pdata[index];
+}
+
+BT_EXPORT
+void bt_field_location_get_ref(const bt_field_location *field_location)
+{
+       bt_object_get_ref(field_location);
+}
+
+BT_EXPORT
+void bt_field_location_put_ref(const bt_field_location *field_location)
+{
+       bt_object_put_ref(field_location);
+}
diff --git a/src/lib/trace-ir/field-location.h b/src/lib/trace-ir/field-location.h
new file mode 100644 (file)
index 0000000..df9faac
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright 2022 EfficiOS, Inc.
+ *
+ * The Common Trace Format (CTF) Specification is available at
+ * http://www.efficios.com/ctf
+ */
+
+#ifndef BABELTRACE_LIB_TRACE_IR_FIELD_LOCATION_H
+#define BABELTRACE_LIB_TRACE_IR_FIELD_LOCATION_H
+
+#include "lib/object.h"
+#include <babeltrace2/trace-ir/field-location.h>
+#include <glib.h>
+
+struct bt_field_location
+{
+       struct bt_object base;
+       enum bt_field_location_scope scope;
+
+       /* Array of `char *`, owned by this. */
+       GPtrArray *items;
+};
+
+#endif /* BABELTRACE_LIB_TRACE_IR_FIELD_LOCATION_H */
This page took 0.033397 seconds and 4 git commands to generate.