From: Simon Marchi Date: Fri, 27 Oct 2023 19:18:06 +0000 (+0000) Subject: lib: add field location API X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=81a0e204ecad332bc6ae013ecba2b9e5798808f5;p=babeltrace.git lib: add field location API 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 Reviewed-on: https://review.lttng.org/c/babeltrace/+/7316 Tested-by: jenkins Reviewed-by: Philippe Proulx Reviewed-on: https://review.lttng.org/c/babeltrace/+/7199 --- diff --git a/doc/api/libbabeltrace2/Doxyfile.in b/doc/api/libbabeltrace2/Doxyfile.in index 5a4a1e40..283f7a1c 100644 --- a/doc/api/libbabeltrace2/Doxyfile.in +++ b/doc/api/libbabeltrace2/Doxyfile.in @@ -33,6 +33,7 @@ ALIASES += bt_dt_opt="Optional:" ALIASES += bt_man{2}="\1(\2)" ALIASES += bt_cli="babeltrace2" ALIASES += bt_voidp="void *" +ALIASES += bt_var{1}="\1" # 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" \ diff --git a/include/Makefile.am b/include/Makefile.am index 3c4969cc..1b996433 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 \ diff --git a/include/babeltrace2/babeltrace.h b/include/babeltrace2/babeltrace.h index 82f62514..62d2bf76 100644 --- a/include/babeltrace2/babeltrace.h +++ b/include/babeltrace2/babeltrace.h @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include diff --git a/include/babeltrace2/trace-ir/field-location.h b/include/babeltrace2/trace-ir/field-location.h new file mode 100644 index 00000000..44b1cd1e --- /dev/null +++ b/include/babeltrace2/trace-ir/field-location.h @@ -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 instead." +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +@defgroup api-tir-field-loc Field location +@ingroup api-tir + +@brief + Location of a \bt_field. + +A field location indicates how to reach a +given \bt_field from a given root scope. + +@note + @parblock + Unlike a \bt_field_path, which is only available within a + trace processing \bt_graph with the effective \bt_mip (MIP) + version 0, a field location works with \bt_struct_field member + names, not with structure field member indexes. + + 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 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(). + +

Properties

+ +A field location has the following properties: + +
+
+ \anchor api-tir-field-loc-prop-root + Root scope +
+
+ 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(). +
+ +
+ \anchor api-tir-field-loc-prop-items + Items +
+
+ 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. +
+
+ +

\anchor api-tir-field-loc-proc Field location procedure

+ +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()): + +
+
#BT_FIELD_LOCATION_SCOPE_PACKET_CONTEXT
+
+ What bt_packet_borrow_context_field_const() returns for the + current \bt_pkt. +
+
#BT_FIELD_LOCATION_SCOPE_EVENT_COMMON_CONTEXT
+
+ What bt_event_borrow_common_context_field_const() returns + for the current \bt_ev. +
+
#BT_FIELD_LOCATION_SCOPE_EVENT_SPECIFIC_CONTEXT
+
+ What bt_event_borrow_specific_context_field_const() returns + for the current event. +
+
#BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD
+
+ What bt_event_borrow_payload_field_const() returns for the + current event. +
+
+ +-# 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()): + +
+
#BT_FIELD_CLASS_TYPE_BOOL
+
#BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER
+
#BT_FIELD_CLASS_TYPE_SIGNED_INTEGER
+
#BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION
+
#BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION
+
End the field location procedure.
+ +
#BT_FIELD_CLASS_TYPE_STRUCTURE
+
Continue.
+ +
#BT_FIELD_CLASS_TYPE_STATIC_ARRAY
+
#BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD
+
#BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD
+
+ 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}. +
+ +
#BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD
+
#BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD
+
#BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD
+
#BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD
+
+ Set \bt_var{CURFIELD} to the optional field of + \bt_var{CURFIELD} (as returned by + bt_field_option_borrow_field_const()). +
+ +
#BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD
+
#BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD
+
#BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD
+
+ Set \bt_var{CURFIELD} to the selected option field of + \bt_var{CURFIELD} (as returned by + bt_field_variant_borrow_selected_option_field_const()). +
+
+ +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} â‰¥ 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() — + 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() — + 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() — + 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() — + 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 */ diff --git a/include/babeltrace2/trace-ir/field-path.h b/include/babeltrace2/trace-ir/field-path.h index 039ceb50..7ff8adb2 100644 --- a/include/babeltrace2/trace-ir/field-path.h +++ b/include/babeltrace2/trace-ir/field-path.h @@ -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 0: use the + similar \bt_field_loc API within a graph with + the effective MIP version 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(), diff --git a/include/babeltrace2/types.h b/include/babeltrace2/types.h index 42e6bd48..68ca64dc 100644 --- a/include/babeltrace2/types.h +++ b/include/babeltrace2/types.h @@ -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; diff --git a/src/Makefile.am b/src/Makefile.am index 72a71463..e3c8e478 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/lib/assert-cond.h b/src/lib/assert-cond.h index 62437c5a..fa19c61a 100644 --- a/src/lib/assert-cond.h +++ b/src/lib/assert-cond.h @@ -560,6 +560,15 @@ 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" @@ -954,12 +963,28 @@ _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 index 00000000..50623513 --- /dev/null +++ b/src/lib/trace-ir/field-location.c @@ -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 index 00000000..df9faac6 --- /dev/null +++ b/src/lib/trace-ir/field-location.h @@ -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 +#include + +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 */