lib: add option field class and field types
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 12 Aug 2019 21:09:38 +0000 (17:09 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 15 Aug 2019 15:41:44 +0000 (11:41 -0400)
This patch adds the option field class (FC) and field to the available
library types.

An option field can contain or not another field. It is very similar to
a variant field in that it's a choice between two things.

CTF 2 will very likely have such a type, so Babeltrace 2.0 will be
ready.

Like a variant FC, an option FC can have a selector which must be a
reachable boolean FC.

When you create an option with bt_field_class_option_create(), you pass
the optional FC, which becomes frozen on success.

You can borrow the optional FC of an option FC with
bt_field_class_option_borrow_field_class_const(). If the option FC has a
selector FC, you can borrow the computed selector field path with
bt_field_class_option_borrow_selector_field_path_const().

To set whether or not an option field contains a field, call
bt_field_option_set_has_field(). You must call this function even if the
option field contains no field (with `BT_FALSE`) because field objects
are pooled and not reset for each message in production mode (similar to
how you must initially call bt_field_string_clear() before you call
bt_field_string_append()). Once you have called
bt_field_option_set_has_field() with `BT_TRUE`, you can borrow the
optional field with bt_field_option_borrow_field() to fill it.

On the const side, you can borrow an option field's optional field with
bt_field_option_borrow_field_const(). This function returns `NULL` if
the option field does not contain a field.

This patch also adds the
`BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT` field path item type.
Such a field path item means the current field of an option field.

This patch does not adapt existing plugins and the Python bindings to
use and wrap the new option FC and field; this work is reserved
for subsequent patches.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ie76312a53affe8343dd058bd4c38cd9a6074c4d7
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1897
Tested-by: jenkins <jenkins@lttng.org>
include/babeltrace2/trace-ir/field-class-const.h
include/babeltrace2/trace-ir/field-class.h
include/babeltrace2/trace-ir/field-const.h
include/babeltrace2/trace-ir/field-path-const.h
include/babeltrace2/trace-ir/field.h
src/lib/lib-logging.c
src/lib/trace-ir/field-class.c
src/lib/trace-ir/field-class.h
src/lib/trace-ir/field.c
src/lib/trace-ir/field.h
src/lib/trace-ir/resolve-field-path.c

index 688c61d1f7a0e3328d0917aeba45843da77a4ace..2dfade9fa899c6b8c389ea1d652e8cd8a5620c83 100644 (file)
@@ -47,6 +47,7 @@ typedef enum bt_field_class_type {
        BT_FIELD_CLASS_TYPE_STRUCTURE,
        BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
        BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
+       BT_FIELD_CLASS_TYPE_OPTION,
        BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR,
        BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
        BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
@@ -164,6 +165,14 @@ extern const bt_field_path *
 bt_field_class_array_dynamic_borrow_length_field_path_const(
                const bt_field_class *field_class);
 
+extern const bt_field_class *
+bt_field_class_option_borrow_field_class_const(
+               const bt_field_class *field_class);
+
+extern const bt_field_path *
+bt_field_class_option_borrow_selector_field_path_const(
+               const bt_field_class *field_class);
+
 extern uint64_t bt_field_class_variant_get_option_count(
                const bt_field_class *field_class);
 
index d2f43becf54542546f6b6b47410b3ece7fff641b..2047729661b8469dfd3d1c793a6cbeb36c3f7788 100644 (file)
@@ -116,6 +116,11 @@ extern bt_field_class *bt_field_class_array_dynamic_create(
 extern bt_field_class *bt_field_class_array_borrow_element_field_class(
                bt_field_class *field_class);
 
+extern bt_field_class *bt_field_class_option_create(
+               bt_trace_class *trace_class,
+               bt_field_class *content_field_class,
+               bt_field_class *selector_field_class);
+
 extern bt_field_class *bt_field_class_variant_create(
                bt_trace_class *trace_class,
                bt_field_class *selector_field_class);
index f3f1ef8d77698f2b2a5d90f2146373cc2a84ae22..01b7423947100b7f3f0f8ec416b39128945c645b 100644 (file)
@@ -84,6 +84,9 @@ extern const bt_field *
 bt_field_array_borrow_element_field_by_index_const(
                const bt_field *field, uint64_t index);
 
+extern const bt_field *
+bt_field_option_borrow_field_const(const bt_field *field);
+
 extern uint64_t bt_field_variant_get_selected_option_field_index(
                const bt_field *field);
 
index b1bd0154e470eb916f3a6741bfe7705e8e44cd94..f1a693523fe817e49c9f95ba41c6ccdfa506541e 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 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_CURRENT_OPTION_CONTENT,
 } bt_field_path_item_type;
 
 typedef enum bt_field_path_scope {
index 311c53a8bfbf5af25f9d5e2776b0fac00130e75b..58959be85293cb1fa431720746d58a99aa3e617f 100644 (file)
@@ -84,6 +84,10 @@ extern bt_field_array_dynamic_set_length_status
 bt_field_array_dynamic_set_length(
                bt_field *field, uint64_t length);
 
+extern void bt_field_option_set_has_field(bt_field *field, bt_bool has_field);
+
+extern bt_field *bt_field_option_borrow_field(bt_field *field);
+
 typedef enum bt_field_variant_select_option_field_by_index_status {
        BT_FIELD_VARIANT_SELECT_OPTION_FIELD_STATUS_OK          = __BT_FUNC_STATUS_OK,
 } bt_field_variant_select_option_field_by_index_status;
index 8b878655c77e1b6a0f22f5031e44351b1f9a43c0..c38948d60100ae01b0cffb933f28691d71a90201 100644 (file)
@@ -260,6 +260,29 @@ static inline void format_field_class(char **buf_ch, bool extended,
 
                break;
        }
+       case BT_FIELD_CLASS_TYPE_OPTION:
+       {
+               const struct bt_field_class_option *opt_fc =
+                       (const void *) field_class;
+
+               BUF_APPEND(", %scontent-fc-addr=%p, %scontent-fc-type=%s",
+                       PRFIELD(opt_fc->content_fc),
+                       PRFIELD(bt_common_field_class_type_string(opt_fc->content_fc->type)));
+
+               if (opt_fc->selector_fc) {
+                       SET_TMP_PREFIX("selector-fc-");
+                       format_field_class(buf_ch, extended, tmp_prefix,
+                               opt_fc->selector_fc);
+               }
+
+               if (opt_fc->selector_field_path) {
+                       SET_TMP_PREFIX("selector-field-path-");
+                       format_field_path(buf_ch, extended, tmp_prefix,
+                               opt_fc->selector_field_path);
+               }
+
+               break;
+       }
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
index 6afc32b82acbb2a57ddbec6e257a7f8a9166c18e..d78aefb3962bd7f37f0d92ae09f0dd6ac2cbf0e8 100644 (file)
@@ -1019,6 +1019,86 @@ bt_field_class_structure_member_borrow_field_class_const(
        return named_fc->fc;
 }
 
+static
+void destroy_option_field_class(struct bt_object *obj)
+{
+       struct bt_field_class_option *fc = (void *) obj;
+
+       BT_ASSERT(fc);
+       BT_LIB_LOGD("Destroying option field class object: %!+F", fc);
+       BT_LOGD_STR("Putting content field class.");
+       BT_OBJECT_PUT_REF_AND_RESET(fc->content_fc);
+       BT_LOGD_STR("Putting selector field path.");
+       BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
+       BT_LOGD_STR("Putting selector field class.");
+       BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc);
+       g_free(fc);
+}
+
+struct bt_field_class *bt_field_class_option_create(bt_trace_class *trace_class,
+               bt_field_class *content_fc, bt_field_class *selector_fc)
+{
+       struct bt_field_class_option *opt_fc = NULL;
+
+       BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
+       BT_ASSERT_PRE_NON_NULL(content_fc, "Content field class");
+       BT_LIB_LOGD("Creating option field class: "
+               "%![content-fc-]+F, %![sel-fc-]+F", content_fc, selector_fc);
+       opt_fc = g_new0(struct bt_field_class_option, 1);
+       if (!opt_fc) {
+               BT_LIB_LOGE_APPEND_CAUSE(
+                       "Failed to allocate one option field class.");
+               goto error;
+       }
+
+       init_field_class((void *) opt_fc, BT_FIELD_CLASS_TYPE_OPTION,
+               destroy_option_field_class);
+       opt_fc->content_fc = content_fc;
+       bt_object_get_no_null_check(opt_fc->content_fc);
+       bt_field_class_freeze(opt_fc->content_fc);
+
+       if (selector_fc) {
+               BT_ASSERT_PRE_FC_HAS_ID(selector_fc, BT_FIELD_CLASS_TYPE_BOOL,
+                       "Selector field class");
+               opt_fc->selector_fc = selector_fc;
+               bt_object_get_no_null_check(opt_fc->selector_fc);
+               bt_field_class_freeze(selector_fc);
+       }
+
+       BT_LIB_LOGD("Created option field class object: "
+               "%![opt-fc-]+F, %![sel-fc-]+F", opt_fc, selector_fc);
+       goto end;
+
+error:
+       BT_OBJECT_PUT_REF_AND_RESET(opt_fc);
+
+end:
+       return (void *) opt_fc;
+}
+
+const struct bt_field_class *bt_field_class_option_borrow_field_class_const(
+                       const struct bt_field_class *fc)
+{
+       struct bt_field_class_option *opt_fc = (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
+               "Field class");
+       return opt_fc->content_fc;
+}
+
+const struct bt_field_path *
+bt_field_class_option_borrow_selector_field_path_const(
+               const struct bt_field_class *fc)
+{
+       struct bt_field_class_option *opt_fc = (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
+               "Field class");
+       return opt_fc->selector_field_path;
+}
+
 static
 void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
 {
index 53041a1315608738f1864b3885d3eee90b15a8c0..f2be12c3453b2090306b9edf0c384ee40425616e 100644 (file)
@@ -290,13 +290,26 @@ struct bt_field_class_array_static {
 struct bt_field_class_array_dynamic {
        struct bt_field_class_array common;
 
-       /* Weak: never dereferenced, only use to find it elsewhere */
+       /* Owned by this */
        struct bt_field_class *length_fc;
 
        /* Owned by this */
        struct bt_field_path *length_field_path;
 };
 
+struct bt_field_class_option {
+       struct bt_field_class common;
+
+       /* Owned by this */
+       struct bt_field_class *content_fc;
+
+       /* Owned by this */
+       struct bt_field_class *selector_fc;
+
+       /* Owned by this */
+       struct bt_field_path *selector_field_path;
+};
+
 /* Variant FC (with selector) option: named field class + range set */
 struct bt_field_class_variant_with_selector_option {
        struct bt_named_field_class common;
index 95a76e49a95ee4177cf5ca68225b894141dc3fa6..664b1ab4cbd23af40ffd9b86fe33745c8d371247 100644 (file)
@@ -47,6 +47,9 @@ void reset_array_field(struct bt_field *field);
 static
 void reset_structure_field(struct bt_field *field);
 
+static
+void reset_option_field(struct bt_field *field);
+
 static
 void reset_variant_field(struct bt_field *field);
 
@@ -59,6 +62,9 @@ void set_array_field_is_frozen(struct bt_field *field, bool is_frozen);
 static
 void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
 
+static
+void set_option_field_is_frozen(struct bt_field *field, bool is_frozen);
+
 static
 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen);
 
@@ -71,6 +77,9 @@ bool array_field_is_set(const struct bt_field *field);
 static
 bool structure_field_is_set(const struct bt_field *field);
 
+static
+bool option_field_is_set(const struct bt_field *field);
+
 static
 bool variant_field_is_set(const struct bt_field *field);
 
@@ -116,6 +125,13 @@ struct bt_field_methods array_field_methods = {
        .reset = reset_array_field,
 };
 
+static
+struct bt_field_methods option_field_methods = {
+       .set_is_frozen = set_option_field_is_frozen,
+       .is_set = option_field_is_set,
+       .reset = reset_option_field,
+};
+
 static
 struct bt_field_methods variant_field_methods = {
        .set_is_frozen = set_variant_field_is_frozen,
@@ -144,6 +160,9 @@ struct bt_field *create_static_array_field(struct bt_field_class *);
 static
 struct bt_field *create_dynamic_array_field(struct bt_field_class *);
 
+static
+struct bt_field *create_option_field(struct bt_field_class *);
+
 static
 struct bt_field *create_variant_field(struct bt_field_class *);
 
@@ -159,6 +178,7 @@ struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = {
        [BT_FIELD_CLASS_TYPE_STRUCTURE]                         = create_structure_field,
        [BT_FIELD_CLASS_TYPE_STATIC_ARRAY]                      = create_static_array_field,
        [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY]                     = create_dynamic_array_field,
+       [BT_FIELD_CLASS_TYPE_OPTION]                            = create_option_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR]          = create_variant_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR]    = create_variant_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR]      = create_variant_field,
@@ -182,6 +202,9 @@ void destroy_structure_field(struct bt_field *field);
 static
 void destroy_array_field(struct bt_field *field);
 
+static
+void destroy_option_field(struct bt_field *field);
+
 static
 void destroy_variant_field(struct bt_field *field);
 
@@ -197,6 +220,7 @@ void (* const field_destroy_funcs[])(struct bt_field *) = {
        [BT_FIELD_CLASS_TYPE_STRUCTURE]                         = destroy_structure_field,
        [BT_FIELD_CLASS_TYPE_STATIC_ARRAY]                      = destroy_array_field,
        [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY]                     = destroy_array_field,
+       [BT_FIELD_CLASS_TYPE_OPTION]                            = destroy_option_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR]          = destroy_variant_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR]    = destroy_variant_field,
        [BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR]      = destroy_variant_field,
@@ -406,6 +430,37 @@ end:
        return (void *) struct_field;
 }
 
+static
+struct bt_field *create_option_field(struct bt_field_class *fc)
+{
+       struct bt_field_option *opt_field;
+       struct bt_field_class_option *opt_fc = (void *) fc;
+
+       BT_LIB_LOGD("Creating option field object: %![fc-]+F", fc);
+       opt_field = g_new0(struct bt_field_option, 1);
+       if (!opt_field) {
+               BT_LIB_LOGE_APPEND_CAUSE(
+                       "Failed to allocate one option field.");
+               goto end;
+       }
+
+       init_field((void *) opt_field, fc, &option_field_methods);
+       opt_field->content_field = bt_field_create(opt_fc->content_fc);
+       if (!opt_field->content_field) {
+               BT_LIB_LOGE_APPEND_CAUSE(
+                       "Failed to create option field's content field: "
+                       "%![opt-fc-]+F, %![content-fc-]+F",
+                       opt_fc, opt_fc->content_fc);
+               BT_OBJECT_PUT_REF_AND_RESET(opt_field);
+               goto end;
+       }
+
+       BT_LIB_LOGD("Created option field object: %!+f", opt_field);
+
+end:
+       return (void *) opt_field;
+}
+
 static
 struct bt_field *create_variant_field(struct bt_field_class *fc)
 {
@@ -907,6 +962,38 @@ const struct bt_field *bt_field_structure_borrow_member_field_by_name_const(
                (void *) field, name);
 }
 
+void bt_field_option_set_has_field(struct bt_field *field, bt_bool has_field)
+{
+       struct bt_field_option *opt_field = (void *) field;
+
+       BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+               BT_FIELD_CLASS_TYPE_OPTION, "Field");
+       BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
+
+       if (has_field) {
+               opt_field->selected_field = opt_field->content_field;
+       } else {
+               opt_field->selected_field = NULL;
+       }
+}
+
+struct bt_field *bt_field_option_borrow_field(struct bt_field *field)
+{
+       struct bt_field_option *opt_field = (void *) field;
+
+       BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+       BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+               BT_FIELD_CLASS_TYPE_OPTION, "Field");
+       return opt_field->selected_field;
+}
+
+const struct bt_field *bt_field_option_borrow_field_const(
+               const struct bt_field *field)
+{
+       return (const void *) bt_field_option_borrow_field((void *) field);
+}
+
 static inline
 struct bt_field *borrow_variant_field_selected_option_field(
                struct bt_field *field)
@@ -1054,6 +1141,22 @@ void destroy_structure_field(struct bt_field *field)
        g_free(field);
 }
 
+static
+void destroy_option_field(struct bt_field *field)
+{
+       struct bt_field_option *opt_field = (void *) field;
+
+       BT_ASSERT(field);
+       BT_LIB_LOGD("Destroying option field object: %!+f", field);
+       bt_field_finalize(field);
+
+       if (opt_field->content_field) {
+               bt_field_destroy(opt_field->content_field);
+       }
+
+       g_free(field);
+}
+
 static
 void destroy_variant_field(struct bt_field *field)
 {
@@ -1132,6 +1235,16 @@ void reset_structure_field(struct bt_field *field)
        }
 }
 
+static
+void reset_option_field(struct bt_field *field)
+{
+       struct bt_field_option *opt_field = (void *) field;
+
+       BT_ASSERT(opt_field);
+       bt_field_reset(opt_field->content_field);
+       opt_field->selected_field = NULL;
+}
+
 static
 void reset_variant_field(struct bt_field *field)
 {
@@ -1179,12 +1292,23 @@ void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen)
                BT_LIB_LOGD("Setting structure field's member field's "
                        "frozen state: %![field-]+f, index=%" PRIu64,
                        member_field, i);
-               bt_field_set_is_frozen(member_field, is_frozen);
+               _bt_field_set_is_frozen(member_field, is_frozen);
        }
 
        set_single_field_is_frozen(field, is_frozen);
 }
 
+static
+void set_option_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+       struct bt_field_option *opt_field = (void *) field;
+
+       BT_LIB_LOGD("Setting option field's frozen state: "
+               "%![field-]+f, is-frozen=%d", field, is_frozen);
+       _bt_field_set_is_frozen(opt_field->content_field, is_frozen);
+       set_single_field_is_frozen(field, is_frozen);
+}
+
 static
 void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
 {
@@ -1200,7 +1324,7 @@ void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen)
                BT_LIB_LOGD("Setting variant field's option field's "
                        "frozen state: %![field-]+f, index=%" PRIu64,
                        option_field, i);
-               bt_field_set_is_frozen(option_field, is_frozen);
+               _bt_field_set_is_frozen(option_field, is_frozen);
        }
 
        set_single_field_is_frozen(field, is_frozen);
@@ -1221,7 +1345,7 @@ void set_array_field_is_frozen(struct bt_field *field, bool is_frozen)
                BT_LIB_LOGD("Setting array field's element field's "
                        "frozen state: %![field-]+f, index=%" PRIu64,
                        elem_field, i);
-               bt_field_set_is_frozen(elem_field, is_frozen);
+               _bt_field_set_is_frozen(elem_field, is_frozen);
        }
 
        set_single_field_is_frozen(field, is_frozen);
@@ -1265,6 +1389,21 @@ end:
        return is_set;
 }
 
+static
+bool option_field_is_set(const struct bt_field *field)
+{
+       const struct bt_field_option *opt_field = (const void *) field;
+       bool is_set = false;
+
+       BT_ASSERT(field);
+
+       if (opt_field->selected_field) {
+               is_set = bt_field_is_set(opt_field->selected_field);
+       }
+
+       return is_set;
+}
+
 static
 bool variant_field_is_set(const struct bt_field *field)
 {
index 352514effc2f52dc13b321eb41014bdc08a85fc3..2882e778f5a4ebdd88d6feb7a59e092cc587843f 100644 (file)
@@ -131,6 +131,16 @@ struct bt_field_structure {
        GPtrArray *fields;
 };
 
+struct bt_field_option {
+       struct bt_field common;
+
+       /* Owned by this */
+       struct bt_field *content_field;
+
+       /* Weak: equal to `content_field` above or `NULL` */
+       struct bt_field *selected_field;
+};
+
 struct bt_field_variant {
        struct bt_field common;
 
index 8865a2a5b89586632cc9bbce314e9d13d9c5e259..c49b0245de156ff7502eef14d26e0c37f3de07c8 100644 (file)
@@ -47,6 +47,25 @@ bool find_field_class_recursive(struct bt_field_class *fc,
        }
 
        switch (fc->type) {
+       case BT_FIELD_CLASS_TYPE_OPTION:
+       {
+               struct bt_field_class_option *opt_fc = (void *) fc;
+
+               struct bt_field_path_item item = {
+                       .type = BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT,
+                       .index = UINT64_C(-1),
+               };
+
+               bt_field_path_append_item(field_path, &item);
+               found = find_field_class_recursive(opt_fc->content_fc,
+                       tgt_fc, field_path);
+               if (found) {
+                       goto end;
+               }
+
+               bt_field_path_remove_last_item(field_path);
+               break;
+       }
        case BT_FIELD_CLASS_TYPE_STRUCTURE:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
@@ -241,6 +260,15 @@ struct bt_field_class *borrow_child_field_class(
        struct bt_field_class *child_fc = NULL;
 
        switch (parent_fc->type) {
+       case BT_FIELD_CLASS_TYPE_OPTION:
+       {
+               struct bt_field_class_option *opt_fc = (void *) parent_fc;
+
+               BT_ASSERT(fp_item->type ==
+                       BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
+               child_fc = opt_fc->content_fc;
+               break;
+       }
        case BT_FIELD_CLASS_TYPE_STRUCTURE:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
@@ -296,6 +324,7 @@ bool target_field_path_in_different_scope_has_struct_fc_only(
 
                if (fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
                                fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
+                               fc->type == BT_FIELD_CLASS_TYPE_OPTION ||
                                fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR ||
                                fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
                                fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
@@ -415,6 +444,7 @@ bool lca_to_target_has_struct_fc_only(struct bt_field_path *src_field_path,
 
                if (tgt_fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
                                tgt_fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
+                               tgt_fc->type == BT_FIELD_CLASS_TYPE_OPTION ||
                                tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR ||
                                tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
                                tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
@@ -527,6 +557,22 @@ int bt_resolve_field_paths(struct bt_field_class *fc,
 
        /* Resolving part for dynamic array and variant field classes */
        switch (fc->type) {
+       case BT_FIELD_CLASS_TYPE_OPTION:
+       {
+               struct bt_field_class_option *opt_fc = (void *) fc;
+
+               if (opt_fc->selector_fc) {
+                       BT_ASSERT(!opt_fc->selector_field_path);
+                       opt_fc->selector_field_path = resolve_field_path(
+                               fc, opt_fc->selector_fc, ctx);
+                       if (!opt_fc->selector_field_path) {
+                               ret = -1;
+                               goto end;
+                       }
+               }
+
+               break;
+       }
        case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
        {
                struct bt_field_class_array_dynamic *dyn_array_fc = (void *) fc;
@@ -566,6 +612,13 @@ int bt_resolve_field_paths(struct bt_field_class *fc,
 
        /* Recursive part */
        switch (fc->type) {
+       case BT_FIELD_CLASS_TYPE_OPTION:
+       {
+               struct bt_field_class_option *opt_fc = (void *) fc;
+
+               ret = bt_resolve_field_paths(opt_fc->content_fc, ctx);
+               break;
+       }
        case BT_FIELD_CLASS_TYPE_STRUCTURE:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
This page took 0.035132 seconds and 4 git commands to generate.