lib: make variant field class option name optional with MIP > 0
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 17 May 2022 17:46:52 +0000 (13:46 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 4 Sep 2024 19:05:14 +0000 (15:05 -0400)
CTF2-SPEC-2.0 [1] calls for optionally named variant field class
option, therefore libbabeltrace2 should support this.

Before this patch, having a variant field class option name is a
precondition. This patch relaxes said precondition when the MIP version
is greater than zero.

Note that a structure field member class must still have a name.

[1]: https://diamon.org/ctf/CTF2-SPEC-2.0.html

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I7f6da1276f75e4c42f1e99c8d0ce1333c9bfee5f
Reviewed-on: https://review.lttng.org/c/babeltrace/+/8047
Reviewed-on: https://review.lttng.org/c/babeltrace/+/12690

include/babeltrace2/trace-ir/field-class.h
src/lib/trace-ir/field-class.c
src/lib/trace-ir/field-class.h

index 13533c8bb8df91557a70fa3773f7ec65c21d6d27..fa5cc22286d357d819e94f23389b7571f16fb78c 100644 (file)
@@ -1209,7 +1209,12 @@ Variant field classes have the following common property:
 
     - A name, unique amongst all the option names of the same
       variant field class.
+
+      The name is optional when the effective \bt_mip version of the
+      trace processing \bt_graph is&nbsp;1.
+
     - A field class.
+
     - User attributes.
 
     If an instance of the variant field class is linked to a selector
@@ -5070,12 +5075,22 @@ bt_field_class_variant_borrow_option_by_name_const(
 
 See the \ref api-tir-fc-var-prop-opts "options" property.
 
+This function may return \c NULL when the following are true:
+
+- The variant field class containing \bt_p{option} was created from a
+  \bt_trace_cls which was created from a \bt_comp which belongs
+  to a trace processing \bt_graph with the effective
+  \bt_mip version&nbsp;1.
+
+- \bt_p{option} has no name.
+
 @param[in] option
     Variant field class option of which to get the name.
 
 @returns
     @parblock
-    Name of \bt_p{option}.
+    Name of \bt_p{option}, or \c NULL if none
+    (possible under MIP&nbsp;1).
 
     The returned pointer remains valid as long as \bt_p{option} exists.
     @endparblock
@@ -5275,7 +5290,12 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
     Variant field class to which to append an option having
     the name \bt_p{name} and the field class \bt_p{option_field_class}.
 @param[in] name
+    @parblock
     Name of the option to append to \bt_p{field_class} (copied).
+
+    Can be \c NULL when the effective \bt_mip version of the trace
+    processing \bt_graph is&nbsp;1.
+    @endparblock
 @param[in] option_field_class
     Field class of the option to append to \bt_p{field_class}.
 
@@ -5288,8 +5308,13 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
 @bt_pre_hot{field_class}
 @bt_pre_is_var_wos_fc{field_class}
 @pre
+    <strong>If \bt_p{name} is not \c NULL</strong>, then
     \bt_p{field_class} has no option with the name \bt_p{name}.
-@bt_pre_not_null{name}
+@pre
+    <strong>If \bt_p{field_class} was created from a
+    \bt_trace_cls which was created from a \bt_comp which belongs
+    to a trace processing \bt_graph with the effective \bt_mip
+    version&nbsp;0</strong>, then \bt_p{name} is \em not \c NULL.
 @bt_pre_not_null{option_field_class}
 @bt_pre_fc_not_in_tc{option_field_class}
 
@@ -5464,7 +5489,12 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
     the name \bt_p{name}, the field class \bt_p{option_field_class},
     and the unsigned integer ranges \bt_p{ranges}.
 @param[in] name
+    @parblock
     Name of the option to append to \bt_p{field_class} (copied).
+
+    Can be \c NULL when the effective \bt_mip version of the trace
+    processing \bt_graph is&nbsp;1.
+    @endparblock
 @param[in] option_field_class
     Field class of the option to append to \bt_p{field_class}.
 @param[in] ranges
@@ -5480,8 +5510,13 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
 @bt_pre_hot{field_class}
 @bt_pre_is_var_wuis_fc{field_class}
 @pre
+    <strong>If \bt_p{name} is not \c NULL</strong>, then
     \bt_p{field_class} has no option with the name \bt_p{name}.
-@bt_pre_not_null{name}
+@pre
+    <strong>If \bt_p{field_class} was created from a
+    \bt_trace_cls which was created from a \bt_comp which belongs
+    to a trace processing \bt_graph with the effective \bt_mip
+    version&nbsp;0</strong>, then \bt_p{name} is \em not \c NULL.
 @bt_pre_not_null{option_field_class}
 @bt_pre_fc_not_in_tc{option_field_class}
 @bt_pre_not_null{ŗanges}
@@ -5712,7 +5747,12 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
     the name \bt_p{name} and the field class \bt_p{option_field_class},
     and the signed integer ranges \bt_p{ranges}.
 @param[in] name
+    @parblock
     Name of the option to append to \bt_p{field_class} (copied).
+
+    Can be \c NULL when the effective \bt_mip version of the trace
+    processing \bt_graph is&nbsp;1.
+    @endparblock
 @param[in] option_field_class
     Field class of the option to append to \bt_p{field_class}.
 @param[in] ranges
@@ -5728,8 +5768,13 @@ See the \ref api-tir-fc-var-prop-opts "options" property.
 @bt_pre_hot{field_class}
 @bt_pre_is_var_wsis_fc{field_class}
 @pre
+    <strong>If \bt_p{name} is not \c NULL</strong>, then
     \bt_p{field_class} has no option with the name \bt_p{name}.
-@bt_pre_not_null{name}
+@pre
+    <strong>If \bt_p{field_class} was created from a
+    \bt_trace_cls which was created from a \bt_comp which belongs
+    to a trace processing \bt_graph with the effective \bt_mip
+    version&nbsp;0</strong>, then \bt_p{name} is \em not \c NULL.
 @bt_pre_not_null{option_field_class}
 @bt_pre_fc_not_in_tc{option_field_class}
 @bt_pre_not_null{ŗanges}
index 8188906178d919760342c9597c15f5d5cf710c79..3f6f3d2ce6003146b19f249a819c2cbfd64082b3 100644 (file)
@@ -930,13 +930,15 @@ int init_named_field_class(struct bt_named_field_class *named_fc,
        int status = BT_FUNC_STATUS_OK;
 
        BT_ASSERT(named_fc);
-       BT_ASSERT(name);
        BT_ASSERT(fc);
-       named_fc->name = g_string_new(name);
-       if (!named_fc->name) {
-               BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
-               status = BT_FUNC_STATUS_MEMORY_ERROR;
-               goto end;
+
+       if (name) {
+               named_fc->name = g_string_new(name);
+               if (!named_fc->name) {
+                       BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
+                       status = BT_FUNC_STATUS_MEMORY_ERROR;
+                       goto end;
+               }
        }
 
        named_fc->user_attributes = bt_value_map_create();
@@ -1026,8 +1028,9 @@ int append_named_field_class_to_container_field_class(
        BT_ASSERT(named_fc);
        BT_ASSERT_PRE_DEV_FC_HOT_FROM_FUNC(api_func, container_fc);
        BT_ASSERT_PRE_FROM_FUNC(api_func, unique_entry_precond_id,
-               !bt_g_hash_table_contains(container_fc->name_to_index,
-                       named_fc->name->str),
+               !named_fc->name ||
+                       !bt_g_hash_table_contains(container_fc->name_to_index,
+                               named_fc->name->str),
                "Duplicate member/option name in structure/variant field class: "
                "%![container-fc-]+F, name=\"%s\"", container_fc,
                named_fc->name->str);
@@ -1039,8 +1042,17 @@ int append_named_field_class_to_container_field_class(
         */
        bt_field_class_freeze(named_fc->fc);
        g_ptr_array_add(container_fc->named_fcs, named_fc);
-       g_hash_table_insert(container_fc->name_to_index, named_fc->name->str,
-               GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
+
+       if (named_fc->name) {
+               /*
+                * MIP > 0: a variant field class option may have no
+                * name.
+                */
+               g_hash_table_insert(container_fc->name_to_index,
+                       named_fc->name->str,
+                       GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
+       }
+
        return BT_FUNC_STATUS_OK;
 }
 
@@ -1055,6 +1067,7 @@ bt_field_class_structure_append_member(
 
        BT_ASSERT_PRE_NO_ERROR();
        BT_ASSERT_PRE_FC_NON_NULL(fc);
+       BT_ASSERT_PRE_NAME_NON_NULL(name);
        BT_ASSERT_PRE_FC_IS_STRUCT("field-class", fc, "Field class");
        named_fc = create_named_field_class(name, member_fc);
        if (!named_fc) {
@@ -1176,6 +1189,7 @@ const char *bt_field_class_structure_member_get_name(
        const struct bt_named_field_class *named_fc = (const void *) member;
 
        BT_ASSERT_PRE_DEV_STRUCT_FC_MEMBER_NON_NULL(member);
+       BT_ASSERT_DBG(named_fc->name);
        return named_fc->name->str;
 }
 
@@ -1900,7 +1914,12 @@ bt_field_class_variant_without_selector_append_option(struct bt_field_class *fc,
 
        BT_ASSERT_PRE_NO_ERROR();
        BT_ASSERT_PRE_FC_NON_NULL(fc);
-       BT_ASSERT_PRE_NAME_NON_NULL(name);
+
+       /* Name is mandatory in MIP 0, optional later. */
+       if (fc->mip_version == 0) {
+               BT_ASSERT_PRE_NAME_NON_NULL(name);
+       }
+
        BT_ASSERT_PRE_NON_NULL("option-field-class", option_fc,
                "Option field class");
        BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
@@ -2028,7 +2047,12 @@ int append_option_to_variant_with_selector_field_field_class(
        bool has_overlap;
 
        BT_ASSERT(fc);
-       BT_ASSERT_PRE_NAME_NON_NULL_FROM_FUNC(api_func, name);
+
+       /* Name is mandatory in MIP 0, optional later. */
+       if (fc->mip_version == 0) {
+               BT_ASSERT_PRE_NAME_NON_NULL_FROM_FUNC(api_func, name);
+       }
+
        BT_ASSERT_PRE_NON_NULL_FROM_FUNC(api_func, "option-field-class",
                option_fc, "Option field class");
        BT_ASSERT_PRE_INT_RANGE_SET_NON_NULL_FROM_FUNC(api_func, range_set);
@@ -2230,7 +2254,9 @@ const char *bt_field_class_variant_option_get_name(
        const struct bt_named_field_class *named_fc = (const void *) option;
 
        BT_ASSERT_PRE_DEV_VAR_FC_OPT_NON_NULL(option);
-       return named_fc->name->str;
+
+       /* MIP > 0: a variant field class option may have no name */
+       return named_fc->name ? named_fc->name->str : NULL;
 }
 
 BT_EXPORT
index 32209ab98fa81e4a6f11fa9e43cd8d5f0bb11871..98c5697003e2a14611f6cdcda2f5b9a523f8a7ca 100644 (file)
@@ -115,6 +115,7 @@ struct bt_field_class_string {
 
 /* A named field class is a (name, field class) pair */
 struct bt_named_field_class {
+       /* MIP > 0: `NULL` if not set */
        GString *name;
 
        /* Owned by this */
@@ -137,6 +138,10 @@ struct bt_field_class_named_field_class_container {
        /*
         * Key: `const char *`, not owned by this (owned by named field
         * class objects contained in `named_fcs` below).
+        *
+        * MIP > 0: the size of this hash table may be less than the
+        * size of `named_fcs` below because, for a variant field class,
+        * its option names are optional.
         */
        GHashTable *name_to_index;
 
This page took 0.029665 seconds and 4 git commands to generate.