g_string_append_printf(str, "[%s", bt_common_scope_string(
bt_field_path_get_root_scope(path)));
- for (i = 0; i < bt_field_path_get_index_count(path); i++) {
- g_string_append_printf(str, ", %" PRIu64,
- bt_field_path_get_index_by_index(path, i));
+ for (i = 0; i < bt_field_path_get_item_count(path); i++) {
+ const struct bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_const(path, i);
+
+ switch (bt_field_path_item_get_type(fp_item)) {
+ case BT_FIELD_PATH_ITEM_TYPE_INDEX:
+ g_string_append_printf(str, ", %" PRIu64,
+ bt_field_path_item_index_get_index(fp_item));
+ break;
+ case BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT:
+ g_string_append(str, ", <CUR>");
+ break;
+ default:
+ abort();
+ }
}
g_string_append(str, "]");
#include <stdint.h>
-/* For bt_field_path */
+/* For bt_field_path, bt_field_path_item */
#include <babeltrace/types.h>
#ifdef __cplusplus
extern "C" {
#endif
+typedef enum bt_field_path_item_type {
+ BT_FIELD_PATH_ITEM_TYPE_INDEX,
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT,
+} bt_field_path_item_type;
+
typedef enum bt_scope {
BT_SCOPE_PACKET_CONTEXT,
BT_SCOPE_EVENT_COMMON_CONTEXT,
extern bt_scope bt_field_path_get_root_scope(
const bt_field_path *field_path);
-extern uint64_t bt_field_path_get_index_count(
+extern uint64_t bt_field_path_get_item_count(
const bt_field_path *field_path);
-extern uint64_t bt_field_path_get_index_by_index(
+extern const bt_field_path_item *bt_field_path_borrow_item_by_index_const(
const bt_field_path *field_path, uint64_t index);
+extern bt_field_path_item_type bt_field_path_item_get_type(
+ const bt_field_path_item *field_path_item);
+
+extern uint64_t bt_field_path_item_index_get_index(
+ const bt_field_path_item *field_path_item);
+
extern void bt_field_path_get_ref(const bt_field_path *field_path);
extern void bt_field_path_put_ref(const bt_field_path *field_path);
#include <babeltrace/assert-internal.h>
#include <glib.h>
+struct bt_field_path_item {
+ enum bt_field_path_item_type type;
+ uint64_t index;
+};
+
struct bt_field_path {
struct bt_object base;
enum bt_scope root;
- /* Array of `uint64_t` (indexes) */
- GArray *indexes;
+ /* Array of `struct bt_field_path_item` (items) */
+ GArray *items;
};
BT_HIDDEN
struct bt_field_path *bt_field_path_create(void);
static inline
-uint64_t bt_field_path_get_index_by_index_inline(
+struct bt_field_path_item *bt_field_path_borrow_item_by_index_inline(
const struct bt_field_path *field_path, uint64_t index)
{
BT_ASSERT(field_path);
- BT_ASSERT(index < field_path->indexes->len);
- return g_array_index(field_path->indexes, uint64_t, index);
+ BT_ASSERT(index < field_path->items->len);
+ return &g_array_index(field_path->items, struct bt_field_path_item,
+ index);
+}
+
+static inline
+void bt_field_path_append_item(struct bt_field_path *field_path,
+ struct bt_field_path_item *item)
+{
+ BT_ASSERT(field_path);
+ BT_ASSERT(item);
+ g_array_append_val(field_path->items, *item);
+}
+
+static inline
+void bt_field_path_remove_last_item(struct bt_field_path *field_path)
+{
+ BT_ASSERT(field_path);
+ BT_ASSERT(field_path->items->len > 0);
+ g_array_set_size(field_path->items, field_path->items->len - 1);
}
+static inline
+const char *bt_field_path_item_type_string(enum bt_field_path_item_type type)
+{
+ switch (type) {
+ case BT_FIELD_PATH_ITEM_TYPE_INDEX:
+ return "BT_FIELD_PATH_ITEM_TYPE_INDEX";
+ case BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT:
+ return "BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT";
+ default:
+ return "(unknown)";
+ }
+};
+
#endif /* BABELTRACE_TRACE_IR_FIELD_PATH_INTERNAL */
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_path bt_field_path;
+typedef struct bt_field_path_item bt_field_path_item;
typedef struct bt_graph bt_graph;
typedef struct bt_message bt_message;
typedef struct bt_message_iterator bt_message_iterator;
{
uint64_t i;
- if (field_path->indexes) {
- BT_ASSERT(field_path->indexes);
- BUF_APPEND(", %sindex-count=%u",
- PRFIELD(field_path->indexes->len));
+ if (field_path->items) {
+ BT_ASSERT(field_path->items);
+ BUF_APPEND(", %sitem-count=%u",
+ PRFIELD(field_path->items->len));
}
- if (!extended || !field_path->indexes) {
+ if (!extended || !field_path->items) {
return;
}
BUF_APPEND(", %spath=[%s",
PRFIELD(bt_common_scope_string(field_path->root)));
- for (i = 0; i < field_path->indexes->len; i++) {
- uint64_t index = bt_field_path_get_index_by_index_inline(
- field_path, i);
-
- BUF_APPEND(", %" PRIu64, index);
+ for (i = 0; i < bt_field_path_get_item_count(field_path); i++) {
+ const struct bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_const(field_path, i);
+
+ switch (bt_field_path_item_get_type(fp_item)) {
+ case BT_FIELD_PATH_ITEM_TYPE_INDEX:
+ BUF_APPEND(", %" PRIu64,
+ bt_field_path_item_index_get_index(fp_item));
+ break;
+ case BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT:
+ BUF_APPEND("%s", ", <CUR>");
+ break;
+ default:
+ abort();
+ }
}
BUF_APPEND("%s", "]");
BT_ASSERT(field_path);
BT_LIB_LOGD("Destroying field path: %!+P", field_path);
- g_array_free(field_path->indexes, TRUE);
- field_path->indexes = NULL;
+ g_array_free(field_path->items, TRUE);
+ field_path->items = NULL;
g_free(field_path);
}
}
bt_object_init_shared(&field_path->base, destroy_field_path);
- field_path->indexes = g_array_new(FALSE, FALSE, sizeof(uint64_t));
- if (!field_path->indexes) {
+ field_path->items = g_array_new(FALSE, FALSE,
+ sizeof(struct bt_field_path_item));
+ if (!field_path->items) {
BT_LOGE_STR("Failed to allocate a GArray.");
goto error;
}
return field_path->root;
}
-uint64_t bt_field_path_get_index_count(const struct bt_field_path *field_path)
+uint64_t bt_field_path_get_item_count(const struct bt_field_path *field_path)
{
BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
- return (uint64_t) field_path->indexes->len;
+ return (uint64_t) field_path->items->len;
}
-uint64_t bt_field_path_get_index_by_index(
+const struct bt_field_path_item *bt_field_path_borrow_item_by_index_const(
const struct bt_field_path *field_path, uint64_t index)
{
BT_ASSERT_PRE_NON_NULL(field_path, "Field path");
- BT_ASSERT_PRE_VALID_INDEX(index, field_path->indexes->len);
- return bt_field_path_get_index_by_index_inline(field_path, index);
+ BT_ASSERT_PRE_VALID_INDEX(index, field_path->items->len);
+ return bt_field_path_borrow_item_by_index_inline(field_path, index);
+}
+
+enum bt_field_path_item_type bt_field_path_item_get_type(
+ const struct bt_field_path_item *field_path_item)
+{
+ BT_ASSERT_PRE_NON_NULL(field_path_item, "Field path item");
+ return field_path_item->type;
+}
+
+uint64_t bt_field_path_item_index_get_index(
+ const struct bt_field_path_item *field_path_item)
+{
+ BT_ASSERT_PRE_NON_NULL(field_path_item, "Field path item");
+ BT_ASSERT_PRE(field_path_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX,
+ "Field path item is not an index field path item: "
+ "addr=%p, type=%s", field_path_item,
+ bt_field_path_item_type_string(field_path_item->type));
+ return field_path_item->index;
}
void bt_field_path_get_ref(const struct bt_field_path *field_path)
struct bt_named_field_class *named_fc =
BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
container_fc, i);
+ struct bt_field_path_item item = {
+ .type = BT_FIELD_PATH_ITEM_TYPE_INDEX,
+ .index = i,
+ };
- g_array_append_val(field_path->indexes, i);
+ bt_field_path_append_item(field_path, &item);
found = find_field_class_recursive(named_fc->fc,
tgt_fc, field_path);
if (found) {
goto end;
}
- g_array_set_size(field_path->indexes,
- field_path->indexes->len - 1);
+ bt_field_path_remove_last_item(field_path);
}
break;
case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
{
struct bt_field_class_array *array_fc = (void *) fc;
+ struct bt_field_path_item item = {
+ .type = BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT,
+ .index = UINT64_C(-1),
+ };
+ bt_field_path_append_item(field_path, &item);
found = find_field_class_recursive(array_fc->element_fc,
tgt_fc, field_path);
+ if (found) {
+ goto end;
+ }
+
+ bt_field_path_remove_last_item(field_path);
break;
}
default:
BT_ASSERT(tgt_field_path->root == src_field_path->root);
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
-
- if (tgt_index > src_index) {
- is_valid = false;
- goto end;
+ for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
+ tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
+ struct bt_field_path_item *src_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ src_field_path, src_i);
+ struct bt_field_path_item *tgt_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ tgt_field_path, tgt_i);
+
+ if (src_fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX &&
+ tgt_fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX) {
+ if (tgt_fp_item->index > src_fp_item->index) {
+ is_valid = false;
+ goto end;
+ }
}
src_i++;
BT_ASSERT_PRE_FUNC
static inline
-struct bt_field_class *borrow_child_field_class(struct bt_field_class *parent_fc,
- uint64_t index, bool *advance)
+struct bt_field_class *borrow_child_field_class(
+ struct bt_field_class *parent_fc,
+ struct bt_field_path_item *fp_item)
{
struct bt_field_class *child_fc = NULL;
case BT_FIELD_CLASS_TYPE_STRUCTURE:
case BT_FIELD_CLASS_TYPE_VARIANT:
{
- struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(parent_fc, index);
+ struct bt_named_field_class *named_fc;
+ BT_ASSERT(fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX);
+ named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(parent_fc,
+ fp_item->index);
child_fc = named_fc->fc;
- *advance = true;
break;
}
case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
{
struct bt_field_class_array *array_fc = (void *) parent_fc;
+ BT_ASSERT(fp_item->type ==
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
child_fc = array_fc->element_fc;
- *advance = false;
break;
}
default:
fc = borrow_root_field_class(ctx, tgt_field_path->root);
- while (i < tgt_field_path->indexes->len) {
- uint64_t index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, i);
- bool advance;
+ for (i = 0; i < tgt_field_path->items->len; i++) {
+ struct bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ tgt_field_path, i);
if (fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
goto end;
}
- fc = borrow_child_field_class(fc, index, &advance);
-
- if (advance) {
- i++;
- }
+ BT_ASSERT(fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX);
+ fc = borrow_child_field_class(fc, fp_item);
}
end:
BT_ASSERT(src_fc);
BT_ASSERT(tgt_fc);
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
+ for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
+ tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
+ struct bt_field_path_item *src_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ src_field_path, src_i);
+ struct bt_field_path_item *tgt_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ tgt_field_path, tgt_i);
if (src_fc != tgt_fc) {
if (!prev_fc) {
}
prev_fc = src_fc;
- src_fc = borrow_child_field_class(src_fc, src_index, &advance);
-
- if (advance) {
- src_i++;
- }
-
- tgt_fc = borrow_child_field_class(tgt_fc, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
+ src_fc = borrow_child_field_class(src_fc, src_fp_item);
+ tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
}
end:
BT_ASSERT(src_fc == tgt_fc);
/* Find LCA */
- while (src_i < src_field_path->indexes->len &&
- tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t src_index = bt_field_path_get_index_by_index_inline(
- src_field_path, src_i);
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
+ for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
+ tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
+ struct bt_field_path_item *src_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ src_field_path, src_i);
+ struct bt_field_path_item *tgt_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ tgt_field_path, tgt_i);
if (src_i != tgt_i) {
/* Next field class is different: LCA is `tgt_fc` */
break;
}
- src_fc = borrow_child_field_class(src_fc, src_index, &advance);
-
- if (advance) {
- src_i++;
- }
-
- tgt_fc = borrow_child_field_class(tgt_fc, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
+ src_fc = borrow_child_field_class(src_fc, src_fp_item);
+ tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
}
/* Only structure field classes to the target */
- while (tgt_i < tgt_field_path->indexes->len) {
- bool advance;
- uint64_t tgt_index = bt_field_path_get_index_by_index_inline(
- tgt_field_path, tgt_i);
+ for (; tgt_i < tgt_field_path->items->len; tgt_i++) {
+ struct bt_field_path_item *tgt_fp_item =
+ bt_field_path_borrow_item_by_index_inline(
+ tgt_field_path, tgt_i);
if (tgt_fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
tgt_fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
goto end;
}
- tgt_fc = borrow_child_field_class(tgt_fc, tgt_index, &advance);
-
- if (advance) {
- tgt_i++;
- }
+ tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
}
end:
i = 0;
- while (i < bt_field_path_get_index_count(tgt_ir_field_path)) {
- uint64_t index = bt_field_path_get_index_by_index(
- tgt_ir_field_path, i);
+ while (i < bt_field_path_get_item_count(tgt_ir_field_path)) {
+ const bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_const(
+ tgt_ir_field_path, i);
struct fs_sink_ctf_named_field_class *named_fc = NULL;
BT_ASSERT(tgt_fc);
+ BT_ASSERT(fp_item);
switch (tgt_fc->type) {
case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT:
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index(
- (void *) tgt_fc, index);
+ (void *) tgt_fc,
+ bt_field_path_item_index_get_index(fp_item));
break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index(
- (void *) tgt_fc, index);
+ (void *) tgt_fc,
+ bt_field_path_item_index_get_index(fp_item));
break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY:
case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE:
struct fs_sink_ctf_field_class_array_base *array_base_fc =
(void *) tgt_fc;
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
tgt_fc = array_base_fc->elem_fc;
break;
}
BT_ASSERT(fc);
- for (i = 0; i < bt_field_path_get_index_count(tgt_ir_field_path); i++) {
- uint64_t index = bt_field_path_get_index_by_index(
- tgt_ir_field_path, i);
+ for (i = 0; i < bt_field_path_get_item_count(tgt_ir_field_path); i++) {
+ const bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_const(
+ tgt_ir_field_path, i);
struct fs_sink_ctf_named_field_class *named_fc = NULL;
+ if (bt_field_path_item_get_type(fp_item) !=
+ BT_FIELD_PATH_ITEM_TYPE_INDEX) {
+ /* Not supported by TSDL 1.8 */
+ ret = -1;
+ goto end;
+ }
+
switch (fc->type) {
case FS_SINK_CTF_FIELD_CLASS_TYPE_STRUCT:
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
named_fc = fs_sink_ctf_field_class_struct_borrow_member_by_index(
- (void *) fc, index);
+ (void *) fc,
+ bt_field_path_item_index_get_index(fp_item));
break;
case FS_SINK_CTF_FIELD_CLASS_TYPE_VARIANT:
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
named_fc = fs_sink_ctf_field_class_variant_borrow_option_by_index(
- (void *) fc, index);
+ (void *) fc,
+ bt_field_path_item_index_get_index(fp_item));
break;
- case FS_SINK_CTF_FIELD_CLASS_TYPE_ARRAY:
- case FS_SINK_CTF_FIELD_CLASS_TYPE_SEQUENCE:
- /* Not supported by TSDL 1.8 */
- ret = -1;
- goto end;
default:
abort();
}
const bt_field_class *walk_field_path(const bt_field_path *fp,
const bt_field_class *fc)
{
- uint64_t i, fp_index_count;
+ uint64_t i, fp_item_count;
const bt_field_class *curr_fc;
BT_ASSERT(bt_field_class_get_type(fc) == BT_FIELD_CLASS_TYPE_STRUCTURE);
BT_LOGD("Walking field path on field class: fp-addr=%p, fc-addr=%p",
fp, fc);
- fp_index_count = bt_field_path_get_index_count(fp);
+ fp_item_count = bt_field_path_get_item_count(fp);
curr_fc = fc;
- for (i = 0; i < fp_index_count; i++) {
+ for (i = 0; i < fp_item_count; i++) {
bt_field_class_type fc_type = bt_field_class_get_type(curr_fc);
- uint64_t curr_index = bt_field_path_get_index_by_index(fp, i);
+ const bt_field_path_item *fp_item =
+ bt_field_path_borrow_item_by_index_const(fp, i);
switch (fc_type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
{
- const bt_field_class_structure_member *member =
- bt_field_class_structure_borrow_member_by_index_const(
- curr_fc, curr_index);
+ const bt_field_class_structure_member *member;
+
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
+ member = bt_field_class_structure_borrow_member_by_index_const(
+ curr_fc,
+ bt_field_path_item_index_get_index(fp_item));
curr_fc = bt_field_class_structure_member_borrow_field_class_const(
member);
break;
}
case BT_FIELD_CLASS_TYPE_VARIANT:
{
- const bt_field_class_variant_option *option =
- bt_field_class_variant_borrow_option_by_index_const(
- curr_fc, curr_index);
+ const bt_field_class_variant_option *option;
+
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_INDEX);
+ option = bt_field_class_variant_borrow_option_by_index_const(
+ curr_fc,
+ bt_field_path_item_index_get_index(fp_item));
curr_fc = bt_field_class_variant_option_borrow_field_class_const(
option);
break;
}
+ case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
+ {
+ BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
+ curr_fc = bt_field_class_array_borrow_element_field_class_const(
+ curr_fc);
+ break;
+ }
default:
abort();
}