lib: add option field classes with integer selectors
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 2 Oct 2019 18:30:17 +0000 (14:30 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 9 Oct 2019 18:14:29 +0000 (14:14 -0400)
This patch adds two new option field classes which have unsigned and
signed integer field classes as selectors. The purpose of this patch is
to be able to use the same selector for an option field class and a
contained, optional variant field class so that you can save space. For
example (pseudo-TSDL):

    enum : integer { size = 8; } {
        NONE,
        BANANA,
        APPLE,
    } tag;

    option <tag> {
        variant <tag> {
            string BANANA <1>;
            int APPLE <2>;
        } <1...0xff>;
    } opt_var;

Above, the optional variant field does not exist when the `tag` field is
0. If `tag` is anything else, then the variant field exists, and the
selected variant field's option also depends on this same value (1 and 2
select existing options).

Library changes
===============
There are now four option field classes:

Option without selector:
    Create with:

        bt_field_class *bt_field_class_option_without_selector_create(
            bt_trace_class *trace_class,
            bt_field_class *content_field_class);

Option with boolean selector:
    Create with:

        bt_field_class *bt_field_class_option_with_selector_bool_create(
            bt_trace_class *trace_class,
            bt_field_class *content_field_class,
            bt_field_class *selector_field_class);

    `selector_field_class` must be a boolean field class.

    By default, the selector is not reversed, in that when the selector
    boolean field is true, the option's field exists.

    You can reverse this logic with:

        void bt_field_class_option_with_selector_bool_set_selector_is_reversed(
            bt_field_class *field_class, bt_bool selector_is_reversed);

    You can get this property with:

        bt_bool
        bt_field_class_option_with_selector_bool_selector_is_reversed(
            const bt_field_class *field_class);

Option with unsigned integer selector:
Option with signed integer selector:
    Create with one of:

        bt_field_class *
        bt_field_class_option_with_selector_integer_unsigned_create(
            bt_trace_class *trace_class,
            bt_field_class *content_field_class,
            bt_field_class *selector_field_class,
            const bt_integer_range_set_unsigned *range_set);

        bt_field_class *
        bt_field_class_option_with_selector_integer_signed_create(
            bt_trace_class *trace_class,
            bt_field_class *content_field_class,
            bt_field_class *selector_field_class,
            const bt_integer_range_set_signed *range_set);

    For both versions:

    * `selector_field_class` must be an integer field class.

    * `range_set` tells, for such an option field, which values of the
      selector field make it contain the optional field.

    * `range_set` must contain at least one integer range.

    * On success, the function freezes `range_set`.

    You can borrow the integer range sets with:

        const bt_integer_range_set_unsigned *
        bt_field_class_option_with_selector_integer_unsigned_borrow_ranges_const(
            const bt_field_class *field_class);

        const bt_integer_range_set_signed *
        bt_field_class_option_with_selector_integer_signed_borrow_ranges_const(
            const bt_field_class *field_class);

Python bindings changes
=======================
There are new Python classes in `field_class.py` to wrap the new field
classes.

To create the new field classes, use:

* _TraceClass.create_option_without_selector_field_class()
* _TraceClass.create_option_with_bool_selector_field_class()
* _TraceClass.create_option_with_integer_selector_field_class()

_TraceClass.create_option_with_integer_selector_field_class() relies on
the type of `selector_fc` to create either an option with unsigned
integer selector field class or an option with signed integer selector
field class.

Notable component class changes
===============================
`flt.lttng-utils.debug-info`:
    Copies all option field classes and their properties.

`sink.text.details`:
    Writes all the option field class properties:

    * Whether or not the selector is reversed for an option with boolean
      selector field class.

      It looks like this:

          opt: Option (boolean selector) (Selector field path [Event payload: 2]):
            Selector is reversed: Yes
            Content: Unsigned integer (64-bit, Base 10)

    * The sorted integer ranges for an option with integer selector
      field class.

      It looks like this:

          opt: Option (signed integer selector) (Selector field path [Event payload: 1]):
            Selector ranges: [1, 1548] [1634] [2960, 3505]
            Content: Unsigned integer (64-bit, Base 10)

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I31e1deba974bf30274d567a73a00ea80d028f7ae
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2122
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
21 files changed:
include/babeltrace2/trace-ir/field-class-const.h
include/babeltrace2/trace-ir/field-class.h
src/bindings/python/bt2/bt2/__init__.py
src/bindings/python/bt2/bt2/field.py
src/bindings/python/bt2/bt2/field_class.py
src/bindings/python/bt2/bt2/trace_class.py
src/common/common.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
src/plugins/ctf/fs-sink/translate-trace-ir-to-ctf-ir.c
src/plugins/lttng-utils/debug-info/trace-ir-data-copy.c
src/plugins/lttng-utils/debug-info/trace-ir-metadata-field-class-copy.c
src/plugins/text/details/write.c
src/plugins/text/pretty/print.c
tests/bindings/python/bt2/test_field.py
tests/bindings/python/bt2/test_field_class.py
tests/bindings/python/bt2/test_package.py

index e7541848bed4248b5639ddc1ee9a360f33160866..c1a890504828bd4e6a6515452d7cbea1f6f826c6 100644 (file)
@@ -37,22 +37,25 @@ extern "C" {
 #endif
 
 typedef enum bt_field_class_type {
-       BT_FIELD_CLASS_TYPE_BOOL                                = 0,
-       BT_FIELD_CLASS_TYPE_BIT_ARRAY                           = 1,
-       BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER                    = 2,
-       BT_FIELD_CLASS_TYPE_SIGNED_INTEGER                      = 3,
-       BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION                = 4,
-       BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION                  = 5,
-       BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL               = 6,
-       BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL               = 7,
-       BT_FIELD_CLASS_TYPE_STRING                              = 8,
-       BT_FIELD_CLASS_TYPE_STRUCTURE                           = 9,
-       BT_FIELD_CLASS_TYPE_STATIC_ARRAY                        = 10,
-       BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY                       = 11,
-       BT_FIELD_CLASS_TYPE_OPTION                              = 12,
-       BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR            = 13,
-       BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR      = 14,
-       BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR        = 15,
+       BT_FIELD_CLASS_TYPE_BOOL                                        = 0,
+       BT_FIELD_CLASS_TYPE_BIT_ARRAY                                   = 1,
+       BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER                            = 2,
+       BT_FIELD_CLASS_TYPE_SIGNED_INTEGER                              = 3,
+       BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION                        = 4,
+       BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION                          = 5,
+       BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL                       = 6,
+       BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL                       = 7,
+       BT_FIELD_CLASS_TYPE_STRING                                      = 8,
+       BT_FIELD_CLASS_TYPE_STRUCTURE                                   = 9,
+       BT_FIELD_CLASS_TYPE_STATIC_ARRAY                                = 10,
+       BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY                               = 11,
+       BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR                     = 12,
+       BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR                   = 13,
+       BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR       = 14,
+       BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR         = 15,
+       BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR                    = 16,
+       BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR              = 17,
+       BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR                = 18,
 } bt_field_class_type;
 
 typedef enum bt_field_class_integer_preferred_display_base {
@@ -178,7 +181,19 @@ 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(
+bt_field_class_option_with_selector_borrow_selector_field_path_const(
+               const bt_field_class *field_class);
+
+extern bt_bool
+bt_field_class_option_with_selector_bool_selector_is_reversed(
+               const bt_field_class *field_class);
+
+extern const bt_integer_range_set_unsigned *
+bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
+               const bt_field_class *field_class);
+
+extern const bt_integer_range_set_signed *
+bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
                const bt_field_class *field_class);
 
 extern uint64_t bt_field_class_variant_get_option_count(
index 9e28a9b2070e9511e3b5bd917b7e000ec9f6950a..e6711b4afa403935ba2db3d90e9ed028ea1c948a 100644 (file)
@@ -136,11 +136,32 @@ 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(
+extern bt_field_class *bt_field_class_option_without_selector_create(
+               bt_trace_class *trace_class,
+               bt_field_class *content_field_class);
+
+extern bt_field_class *bt_field_class_option_with_selector_bool_create(
                bt_trace_class *trace_class,
                bt_field_class *content_field_class,
                bt_field_class *selector_field_class);
 
+extern void bt_field_class_option_with_selector_bool_set_selector_is_reversed(
+               bt_field_class *field_class, bt_bool selector_is_reversed);
+
+extern bt_field_class *
+bt_field_class_option_with_selector_integer_unsigned_create(
+               bt_trace_class *trace_class,
+               bt_field_class *content_field_class,
+               bt_field_class *selector_field_class,
+               const bt_integer_range_set_unsigned *range_set);
+
+extern bt_field_class *
+bt_field_class_option_with_selector_integer_signed_create(
+               bt_trace_class *trace_class,
+               bt_field_class *content_field_class,
+               bt_field_class *selector_field_class,
+               const bt_integer_range_set_signed *range_set);
+
 extern bt_field_class *bt_field_class_option_borrow_field_class(
                bt_field_class *field_class);
 
index e53f0aca55611868b40edcee70c168aa6a7ac7b4..4310f4693ad1064288bb2083a3d6c2840d663ea0 100644 (file)
@@ -92,6 +92,11 @@ from bt2.field_class import _SignedEnumerationFieldClass
 from bt2.field_class import _StringFieldClass
 from bt2.field_class import _StructureFieldClass
 from bt2.field_class import _OptionFieldClass
+from bt2.field_class import _OptionWithSelectorFieldClass
+from bt2.field_class import _OptionWithBoolSelectorFieldClass
+from bt2.field_class import _OptionWithIntegerSelectorFieldClass
+from bt2.field_class import _OptionWithUnsignedIntegerSelectorFieldClass
+from bt2.field_class import _OptionWithSignedIntegerSelectorFieldClass
 from bt2.field_class import _VariantFieldClass
 from bt2.field_class import _VariantFieldClassWithoutSelector
 from bt2.field_class import _VariantFieldClassWithSelector
@@ -112,6 +117,11 @@ from bt2.field_class import _SignedEnumerationFieldClassConst
 from bt2.field_class import _StringFieldClassConst
 from bt2.field_class import _StructureFieldClassConst
 from bt2.field_class import _OptionFieldClassConst
+from bt2.field_class import _OptionWithSelectorFieldClassConst
+from bt2.field_class import _OptionWithBoolSelectorFieldClassConst
+from bt2.field_class import _OptionWithIntegerSelectorFieldClassConst
+from bt2.field_class import _OptionWithUnsignedIntegerSelectorFieldClassConst
+from bt2.field_class import _OptionWithSignedIntegerSelectorFieldClassConst
 from bt2.field_class import _VariantFieldClassConst
 from bt2.field_class import _VariantFieldClassWithoutSelectorConst
 from bt2.field_class import _VariantFieldClassWithSelectorConst
index eb2b63a71a86ae752d763902aa5a05faff5d3664..83409b1b5cf099d47b650749750dbc601b3a54e5 100644 (file)
@@ -935,7 +935,10 @@ _TYPE_ID_TO_CONST_OBJ = {
     native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldConst,
     native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldConst,
     native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayFieldConst,
-    native_bt.FIELD_CLASS_TYPE_OPTION: _OptionFieldConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR: _OptionFieldConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR: _OptionFieldConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR: _OptionFieldConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR: _OptionFieldConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantFieldConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantFieldConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantFieldConst,
@@ -954,7 +957,10 @@ _TYPE_ID_TO_OBJ = {
     native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureField,
     native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayField,
     native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayField,
-    native_bt.FIELD_CLASS_TYPE_OPTION: _OptionField,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR: _OptionField,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR: _OptionField,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR: _OptionField,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR: _OptionField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantField,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantField,
index 12ecced041b85f99eb0f6ff2e3f2f1bb62096537..4268bbf732ef67065db130ee3b689ea49f339753 100644 (file)
@@ -505,24 +505,69 @@ class _OptionFieldClassConst(_FieldClassConst):
     _borrow_field_class_ptr = staticmethod(
         native_bt.field_class_option_borrow_field_class_const
     )
-    _borrow_selector_field_path = staticmethod(
-        native_bt.field_class_option_borrow_selector_field_path_const
-    )
 
     @property
     def field_class(self):
         elem_fc_ptr = self._borrow_field_class_ptr(self._ptr)
         return self._create_field_class_from_ptr_and_get_ref(elem_fc_ptr)
 
+
+class _OptionWithSelectorFieldClassConst(_OptionFieldClassConst):
+    _NAME = 'Const Option (with selector)'
+
     @property
     def selector_field_path(self):
-        ptr = self._borrow_selector_field_path(self._ptr)
+        ptr = native_bt.field_class_option_with_selector_borrow_selector_field_path_const(
+            self._ptr
+        )
         if ptr is None:
             return
 
         return bt2_field_path._FieldPathConst._create_from_ptr_and_get_ref(ptr)
 
 
+class _OptionWithBoolSelectorFieldClassConst(_OptionWithSelectorFieldClassConst):
+    _NAME = 'Const Option (with boolean selector)'
+
+    @property
+    def selector_is_reversed(self):
+        return bool(
+            native_bt.field_class_option_with_selector_bool_selector_is_reversed(
+                self._ptr
+            )
+        )
+
+
+class _OptionWithIntegerSelectorFieldClassConst(_OptionWithSelectorFieldClassConst):
+    _NAME = 'Const Option (with integer selector)'
+
+    @property
+    def ranges(self):
+        range_set_ptr = self._borrow_selector_ranges_ptr(self._ptr)
+        assert range_set_ptr is not None
+        return self._range_set_pycls._create_from_ptr_and_get_ref(range_set_ptr)
+
+
+class _OptionWithUnsignedIntegerSelectorFieldClassConst(
+    _OptionWithIntegerSelectorFieldClassConst
+):
+    _NAME = 'Const Option (with unsigned integer selector)'
+    _range_set_pycls = bt2_integer_range_set._UnsignedIntegerRangeSetConst
+    _borrow_selector_ranges_ptr = staticmethod(
+        native_bt.field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const
+    )
+
+
+class _OptionWithSignedIntegerSelectorFieldClassConst(
+    _OptionWithIntegerSelectorFieldClassConst
+):
+    _NAME = 'Const Option (with signed integer selector)'
+    _range_set_pycls = bt2_integer_range_set._SignedIntegerRangeSetConst
+    _borrow_selector_ranges_ptr = staticmethod(
+        native_bt.field_class_option_with_selector_integer_signed_borrow_selector_ranges_const
+    )
+
+
 class _OptionFieldClass(_OptionFieldClassConst, _FieldClass):
     _NAME = 'Option'
     _borrow_field_class_ptr = staticmethod(
@@ -533,6 +578,46 @@ class _OptionFieldClass(_OptionFieldClassConst, _FieldClass):
     )
 
 
+class _OptionWithSelectorFieldClass(
+    _OptionWithSelectorFieldClassConst, _OptionFieldClass
+):
+    _NAME = 'Option (with selector)'
+
+
+class _OptionWithBoolSelectorFieldClass(
+    _OptionWithBoolSelectorFieldClassConst, _OptionWithSelectorFieldClass
+):
+    _NAME = 'Option (with boolean selector)'
+
+    def _selector_is_reversed(self, selector_is_reversed):
+        utils._check_bool(selector_is_reversed)
+        native_bt.field_class_option_with_selector_bool_set_selector_is_reversed(
+            self._ptr, selector_is_reversed
+        )
+
+    _selector_is_reversed = property(fset=_selector_is_reversed)
+
+
+class _OptionWithIntegerSelectorFieldClass(
+    _OptionWithIntegerSelectorFieldClassConst, _OptionWithSelectorFieldClass
+):
+    _NAME = 'Option (with integer selector)'
+
+
+class _OptionWithUnsignedIntegerSelectorFieldClass(
+    _OptionWithUnsignedIntegerSelectorFieldClassConst,
+    _OptionWithIntegerSelectorFieldClass,
+):
+    _NAME = 'Option (with unsigned integer selector)'
+
+
+class _OptionWithSignedIntegerSelectorFieldClass(
+    _OptionWithSignedIntegerSelectorFieldClassConst,
+    _OptionWithIntegerSelectorFieldClass,
+):
+    _NAME = 'Option (with signed integer selector)'
+
+
 class _VariantFieldClassOptionConst:
     _create_field_class_from_ptr_and_get_ref = staticmethod(
         _create_field_class_from_const_ptr_and_get_ref
@@ -919,7 +1004,10 @@ _FIELD_CLASS_TYPE_TO_CONST_OBJ = {
     native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldClassConst,
     native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldClassConst,
     native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayFieldClassConst,
-    native_bt.FIELD_CLASS_TYPE_OPTION: _OptionFieldClassConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR: _OptionFieldClassConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR: _OptionWithBoolSelectorFieldClassConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR: _OptionWithUnsignedIntegerSelectorFieldClassConst,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR: _OptionWithSignedIntegerSelectorFieldClassConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantFieldClassWithoutSelectorConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantFieldClassWithUnsignedSelectorConst,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantFieldClassWithSignedSelectorConst,
@@ -938,7 +1026,10 @@ _FIELD_CLASS_TYPE_TO_OBJ = {
     native_bt.FIELD_CLASS_TYPE_STRUCTURE: _StructureFieldClass,
     native_bt.FIELD_CLASS_TYPE_STATIC_ARRAY: _StaticArrayFieldClass,
     native_bt.FIELD_CLASS_TYPE_DYNAMIC_ARRAY: _DynamicArrayFieldClass,
-    native_bt.FIELD_CLASS_TYPE_OPTION: _OptionFieldClass,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR: _OptionFieldClass,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR: _OptionWithBoolSelectorFieldClass,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR: _OptionWithUnsignedIntegerSelectorFieldClass,
+    native_bt.FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR: _OptionWithSignedIntegerSelectorFieldClass,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR: _VariantFieldClassWithoutSelector,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: _VariantFieldClassWithUnsignedSelector,
     native_bt.FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR: _VariantFieldClassWithSignedSelector,
index d510a36e1e2fbdddd96e94a5cbfb4f59847d4a52..ccf9f48ef519874d12fa0411c3e28565549be58a 100644 (file)
@@ -25,6 +25,7 @@
 from bt2 import native_bt, utils, object
 from bt2 import stream_class as bt2_stream_class
 from bt2 import field_class as bt2_field_class
+from bt2 import integer_range_set as bt2_integer_range_set
 from bt2 import trace as bt2_trace
 from bt2 import value as bt2_value
 import collections.abc
@@ -433,20 +434,53 @@ class _TraceClass(_TraceClassConst):
         self._set_field_class_user_attrs(fc, user_attributes)
         return fc
 
-    def create_option_field_class(
-        self, content_fc, selector_fc=None, user_attributes=None
+    def create_option_without_selector_field_class(
+        self, content_fc, user_attributes=None
     ):
         utils._check_type(content_fc, bt2_field_class._FieldClass)
+        ptr = native_bt.field_class_option_without_selector_create(
+            self._ptr, content_fc._ptr
+        )
+        self._check_field_class_create_status(ptr, 'option')
+        fc = bt2_field_class._create_field_class_from_ptr_and_get_ref(ptr)
+        self._set_field_class_user_attrs(fc, user_attributes)
+        return fc
 
-        selector_fc_ptr = None
+    def create_option_with_bool_selector_field_class(
+        self, content_fc, selector_fc, selector_is_reversed=False, user_attributes=None
+    ):
+        utils._check_type(content_fc, bt2_field_class._FieldClass)
+        utils._check_bool(selector_is_reversed)
+        utils._check_type(selector_fc, bt2_field_class._BoolFieldClass)
+        ptr = native_bt.field_class_option_with_selector_bool_create(
+            self._ptr, content_fc._ptr, selector_fc._ptr
+        )
+        self._check_field_class_create_status(ptr, 'option')
+        fc = bt2_field_class._create_field_class_from_ptr_and_get_ref(ptr)
+        self._set_field_class_user_attrs(fc, user_attributes)
+        fc._selector_is_reversed = selector_is_reversed
+        return fc
 
-        if selector_fc is not None:
-            utils._check_type(selector_fc, bt2_field_class._BoolFieldClass)
-            selector_fc_ptr = selector_fc._ptr
+    def create_option_with_integer_selector_field_class(
+        self, content_fc, selector_fc, ranges, user_attributes=None
+    ):
+        utils._check_type(content_fc, bt2_field_class._FieldClass)
+        utils._check_type(selector_fc, bt2_field_class._IntegerFieldClass)
+
+        if len(ranges) == 0:
+            raise ValueError('integer range set is empty')
+
+        if isinstance(selector_fc, bt2_field_class._UnsignedIntegerFieldClass):
+            utils._check_type(ranges, bt2_integer_range_set.UnsignedIntegerRangeSet)
+            ptr = native_bt.field_class_option_with_selector_integer_unsigned_create(
+                self._ptr, content_fc._ptr, selector_fc._ptr, ranges._ptr
+            )
+        else:
+            utils._check_type(ranges, bt2_integer_range_set.SignedIntegerRangeSet)
+            ptr = native_bt.field_class_option_with_selector_integer_signed_create(
+                self._ptr, content_fc._ptr, selector_fc._ptr, ranges._ptr
+            )
 
-        ptr = native_bt.field_class_option_create(
-            self._ptr, content_fc._ptr, selector_fc_ptr
-        )
         self._check_field_class_create_status(ptr, 'option')
         fc = bt2_field_class._create_field_class_from_ptr_and_get_ref(ptr)
         self._set_field_class_user_attrs(fc, user_attributes)
index 41815454e61b0b6e141746a5cfa1ba57715a0f87..dae93f52bebf309efee334e7f1261d18c026a5ac 100644 (file)
@@ -417,18 +417,22 @@ static inline
 const char *bt_common_field_class_type_string(enum bt_field_class_type class_type)
 {
        switch (class_type) {
+       case BT_FIELD_CLASS_TYPE_BOOL:
+               return "BOOL";
+       case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
+               return "BIT_ARRAY";
        case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
                return "UNSIGNED_INTEGER";
        case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
                return "SIGNED_INTEGER";
-       case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
-               return "SINGLE_PRECISION_REAL";
-       case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
-               return "DOUBLE_PRECISION_REAL";
        case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
                return "UNSIGNED_ENUMERATION";
        case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
                return "SIGNED_ENUMERATION";
+       case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
+               return "SINGLE_PRECISION_REAL";
+       case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
+               return "DOUBLE_PRECISION_REAL";
        case BT_FIELD_CLASS_TYPE_STRING:
                return "STRING";
        case BT_FIELD_CLASS_TYPE_STRUCTURE:
@@ -437,6 +441,14 @@ const char *bt_common_field_class_type_string(enum bt_field_class_type class_typ
                return "STATIC_ARRAY";
        case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
                return "DYNAMIC_ARRAY";
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+               return "OPTION_WITHOUT_SELECTOR";
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+               return "OPTION_WITH_BOOL_SELECTOR";
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+               return "OPTION_WITH_UNSIGNED_INTEGER_SELECTOR";
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
+               return "OPTION_WITH_SIGNED_INTEGER_SELECTOR";
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
                return "VARIANT_WITHOUT_SELECTOR";
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
index af30bd2f82c0817b43bf03f1b22bb325df65fc3e..dc0c97c5dcd573fcb7080122af4f40a4e9456b69 100644 (file)
@@ -260,7 +260,10 @@ static inline void format_field_class(char **buf_ch, bool extended,
 
                break;
        }
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                const struct bt_field_class_option *opt_fc =
                        (const void *) field_class;
@@ -269,16 +272,22 @@ static inline void format_field_class(char **buf_ch, bool extended,
                        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 (field_class->type !=
+                               BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
+                       const struct bt_field_class_option_with_selector *opt_with_sel_fc =
+                               (const void *) field_class;
 
-               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);
+                       if (opt_with_sel_fc->selector_fc) {
+                               SET_TMP_PREFIX("selector-fc-");
+                               format_field_class(buf_ch, extended, tmp_prefix,
+                                       opt_with_sel_fc->selector_fc);
+                       }
+
+                       if (opt_with_sel_fc->selector_field_path) {
+                               SET_TMP_PREFIX("selector-field-path-");
+                               format_field_path(buf_ch, extended, tmp_prefix,
+                                       opt_with_sel_fc->selector_field_path);
+                       }
                }
 
                break;
index ecb827a5fe836bd816730b9a587f2e4c23067d10..90f6034006c5bc5b16ab39920734d5b48a0f9a6b 100644 (file)
@@ -1153,30 +1153,83 @@ void destroy_option_field_class(struct bt_object *obj)
        finalize_field_class((void *) obj);
        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);
+
+       if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
+               struct bt_field_class_option_with_selector *with_sel_fc =
+                       (void *) obj;
+
+               BT_LOGD_STR("Putting selector field path.");
+               BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_field_path);
+               BT_LOGD_STR("Putting selector field class.");
+               BT_OBJECT_PUT_REF_AND_RESET(with_sel_fc->selector_fc);
+
+               if (fc->common.type != BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
+                       struct bt_field_class_option_with_selector_integer *with_int_sel_fc =
+                               (void *) obj;
+
+                       BT_LOGD_STR("Putting integer range set.");
+                       BT_OBJECT_PUT_REF_AND_RESET(with_int_sel_fc->range_set);
+               }
+       }
+
        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)
+static
+struct bt_field_class *create_option_field_class(
+               struct bt_trace_class *trace_class,
+               enum bt_field_class_type fc_type,
+               struct bt_field_class *content_fc,
+               struct 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;
+               "type=%s, %![content-fc-]+F, %![sel-fc-]+F",
+               bt_common_field_class_type_string(fc_type),
+               content_fc, selector_fc);
+
+       if (fc_type != BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
+               struct bt_field_class_option_with_selector *opt_with_sel_fc = NULL;
+
+               BT_ASSERT_PRE_NON_NULL(selector_fc, "Selector field class");
+
+               if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
+                       BT_ASSERT_PRE_FC_HAS_ID(selector_fc,
+                               BT_FIELD_CLASS_TYPE_BOOL,
+                               "Selector field class");
+                       opt_with_sel_fc = (void *) g_new0(
+                               struct bt_field_class_option_with_selector_bool, 1);
+               } else {
+                       BT_ASSERT_PRE_FC_IS_INT(selector_fc,
+                               "Selector field class");
+                       opt_with_sel_fc = (void *) g_new0(
+                               struct bt_field_class_option_with_selector_integer, 1);
+               }
+
+               if (!opt_with_sel_fc) {
+                       BT_LIB_LOGE_APPEND_CAUSE(
+                               "Failed to allocate one option with selector field class.");
+                       goto error;
+               }
+
+               opt_with_sel_fc->selector_fc = selector_fc;
+               bt_object_get_no_null_check(opt_with_sel_fc->selector_fc);
+               opt_fc = (void *) opt_with_sel_fc;
+       } else {
+               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;
+               }
        }
 
-       if (init_field_class((void *) opt_fc, BT_FIELD_CLASS_TYPE_OPTION,
+       BT_ASSERT(opt_fc);
+
+       if (init_field_class((void *) opt_fc, fc_type,
                        destroy_option_field_class)) {
                goto error;
        }
@@ -1186,10 +1239,6 @@ struct bt_field_class *bt_field_class_option_create(bt_trace_class *trace_class,
        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);
        }
 
@@ -1204,14 +1253,100 @@ end:
        return (void *) opt_fc;
 }
 
+struct bt_field_class *bt_field_class_option_without_selector_create(
+               struct bt_trace_class *trace_class,
+               struct bt_field_class *content_fc)
+{
+       return create_option_field_class(trace_class,
+               BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR,
+               content_fc, NULL);
+}
+
+struct bt_field_class *bt_field_class_option_with_selector_bool_create(
+               struct bt_trace_class *trace_class,
+               struct bt_field_class *content_fc,
+               struct bt_field_class *selector_fc)
+{
+       struct bt_field_class_option_with_selector_bool *fc =
+               (void *) create_option_field_class(trace_class,
+                       BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR,
+                       content_fc, selector_fc);
+
+       if (!fc) {
+               goto end;
+       }
+
+end:
+       return (void *) fc;
+}
+
+struct bt_field_class *
+bt_field_class_option_with_selector_integer_unsigned_create(
+               struct bt_trace_class *trace_class,
+               struct bt_field_class *content_fc,
+               struct bt_field_class *selector_fc,
+               const struct bt_integer_range_set_unsigned *u_range_set)
+{
+       struct bt_field_class_option_with_selector_integer *fc;
+       const struct bt_integer_range_set *range_set =
+               (const void *) u_range_set;
+
+       BT_ASSERT_PRE_NON_NULL(range_set, "Integer range set");
+       BT_ASSERT_PRE(range_set->ranges->len > 0,
+               "Integer range set is empty: %!+R", range_set);
+       fc = (void *) create_option_field_class(trace_class,
+               BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR,
+               content_fc, selector_fc);
+
+       if (!fc) {
+               goto end;
+       }
+
+       fc->range_set = range_set;
+       bt_object_get_no_null_check(fc->range_set);
+       bt_integer_range_set_freeze(range_set);
+
+end:
+       return (void *) fc;
+}
+
+struct bt_field_class *
+bt_field_class_option_with_selector_integer_signed_create(
+               struct bt_trace_class *trace_class,
+               struct bt_field_class *content_fc,
+               struct bt_field_class *selector_fc,
+               const struct bt_integer_range_set_signed *i_range_set)
+{
+       struct bt_field_class_option_with_selector_integer *fc;
+       const struct bt_integer_range_set *range_set =
+               (const void *) i_range_set;
+
+       BT_ASSERT_PRE_NON_NULL(range_set, "Integer range set");
+       BT_ASSERT_PRE(range_set->ranges->len > 0,
+               "Integer range set is empty: %!+R", range_set);
+       fc = (void *) create_option_field_class(trace_class,
+               BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR,
+               content_fc, selector_fc);
+
+       if (!fc) {
+               goto end;
+       }
+
+       fc->range_set = range_set;
+       bt_object_get_no_null_check(fc->range_set);
+       bt_integer_range_set_freeze(range_set);
+
+end:
+       return (void *) 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");
+       BT_ASSERT_PRE_FC_IS_OPTION(fc, "Field class");
        return opt_fc->content_fc;
 }
 
@@ -1221,23 +1356,69 @@ struct bt_field_class *bt_field_class_option_borrow_field_class(
        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");
+       BT_ASSERT_PRE_FC_IS_OPTION(fc, "Field class");
        return opt_fc->content_fc;
 }
 
 const struct bt_field_path *
-bt_field_class_option_borrow_selector_field_path_const(
+bt_field_class_option_with_selector_borrow_selector_field_path_const(
                const struct bt_field_class *fc)
 {
-       struct bt_field_class_option *opt_fc = (void *) fc;
+       const struct bt_field_class_option_with_selector *opt_fc =
+               (const 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");
+       BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL(fc, "Field class");
        return opt_fc->selector_field_path;
 }
 
+void bt_field_class_option_with_selector_bool_set_selector_is_reversed(
+               struct bt_field_class *fc, bt_bool sel_is_reversed)
+{
+       struct bt_field_class_option_with_selector_bool *opt_fc = (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_FC_HAS_ID(fc,
+               BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR, "Field class");
+       BT_ASSERT_PRE_DEV_FC_HOT(fc, "Field class");
+       opt_fc->sel_is_reversed = sel_is_reversed;
+}
+
+bt_bool bt_field_class_option_with_selector_bool_selector_is_reversed(
+               const struct bt_field_class *fc)
+{
+       struct bt_field_class_option_with_selector_bool *opt_fc = (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_FC_HAS_ID(fc,
+               BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR, "Field class");
+       return opt_fc->sel_is_reversed;
+}
+
+const struct bt_integer_range_set_unsigned *
+bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
+               const struct bt_field_class *fc)
+{
+       struct bt_field_class_option_with_selector_integer *opt_fc =
+               (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL(fc, "Field class");
+       return (const void *) opt_fc->range_set;
+}
+
+const struct bt_integer_range_set_signed *
+bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
+               const struct bt_field_class *fc)
+{
+       struct bt_field_class_option_with_selector_integer *opt_fc =
+               (void *) fc;
+
+       BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+       BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL(fc, "Field class");
+       return (const void *) opt_fc->range_set;
+}
+
 static
 void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
 {
index 568edaf9ac738a870580b05f28dc0a3ea0b76433..fa970d435d856a909fc57f2ae22a9d7c484cbda7 100644 (file)
 #define _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name)                          \
        _name " is not an array field class: %![fc-]+F"
 
+#define _BT_ASSERT_PRE_FC_IS_OPTION_COND(_fc)                          \
+       (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR)
+
+#define _BT_ASSERT_PRE_FC_IS_OPTION_FMT(_name)                         \
+       _name " is not an option field class: %![fc-]+F"
+
+#define _BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_COND(_fc)                 \
+       (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR)
+
+#define _BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_FMT(_name)                \
+       _name " is not an option field class with a selector: %![fc-]+F"
+
+#define _BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_COND(_fc)             \
+       (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR || \
+       ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR)
+
+#define _BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_FMT(_name)            \
+       _name " is not an option field class with an integer selector: %![fc-]+F"
+
 #define _BT_ASSERT_PRE_FC_IS_VARIANT_COND(_fc)                         \
        (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR || \
        ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR || \
        BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_ARRAY_COND(_fc),             \
                _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name), (_fc))
 
+#define BT_ASSERT_PRE_FC_IS_OPTION(_fc, _name)                         \
+       BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_OPTION_COND(_fc),            \
+               _BT_ASSERT_PRE_FC_IS_OPTION_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL(_fc, _name)                        \
+       BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_COND(_fc),   \
+               _BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL(_fc, _name)            \
+       BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_COND(_fc), \
+               _BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_FMT(_name), (_fc))
+
 #define BT_ASSERT_PRE_FC_IS_VARIANT(_fc, _name)                                \
        BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_VARIANT_COND(_fc),           \
                _BT_ASSERT_PRE_FC_IS_VARIANT_FMT(_name), (_fc))
        BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_ARRAY_COND(_fc),         \
                _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name), (_fc))
 
+#define BT_ASSERT_PRE_DEV_FC_IS_OPTION(_fc, _name)                     \
+       BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_OPTION_COND(_fc),        \
+               _BT_ASSERT_PRE_FC_IS_OPTION_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_DEV_FC_IS_OPTION_WITH_SEL(_fc, _name)            \
+       BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_COND(_fc), \
+               _BT_ASSERT_PRE_FC_IS_OPTION_WITH_SEL_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_DEV_FC_IS_OPTION_WITH_INT_SEL(_fc, _name)                \
+       BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_COND(_fc), \
+               _BT_ASSERT_PRE_FC_IS_OPTION_WITH_INT_SEL_FMT(_name), (_fc))
+
 #define BT_ASSERT_PRE_DEV_FC_IS_VARIANT(_fc, _name)                    \
        BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_VARIANT_COND(_fc),       \
                _BT_ASSERT_PRE_FC_IS_VARIANT_FMT(_name), (_fc))
@@ -312,6 +360,10 @@ struct bt_field_class_option {
 
        /* Owned by this */
        struct bt_field_class *content_fc;
+};
+
+struct bt_field_class_option_with_selector {
+       struct bt_field_class_option common;
 
        /* Owned by this */
        struct bt_field_class *selector_fc;
@@ -320,6 +372,20 @@ struct bt_field_class_option {
        struct bt_field_path *selector_field_path;
 };
 
+struct bt_field_class_option_with_selector_bool {
+       struct bt_field_class_option_with_selector common;
+
+       /* Owned by this */
+       bool sel_is_reversed;
+};
+
+struct bt_field_class_option_with_selector_integer {
+       struct bt_field_class_option_with_selector common;
+
+       /* Owned by this */
+       const struct bt_integer_range_set *range_set;
+};
+
 /* 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 f10b893ddacbf5b41e5cc9743e7121916eb3b14e..7c0c2d32e8325ef5c06e5d3f298470c64a91ed7b 100644 (file)
@@ -177,22 +177,25 @@ struct bt_field *create_variant_field(struct bt_field_class *);
 
 static
 struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = {
-       [BT_FIELD_CLASS_TYPE_BOOL]                              = create_bool_field,
-       [BT_FIELD_CLASS_TYPE_BIT_ARRAY]                         = create_bit_array_field,
-       [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER]                  = create_integer_field,
-       [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER]                    = create_integer_field,
-       [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION]              = create_integer_field,
-       [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION]                = create_integer_field,
-       [BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL]             = create_real_field,
-       [BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL]             = create_real_field,
-       [BT_FIELD_CLASS_TYPE_STRING]                            = create_string_field,
-       [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,
+       [BT_FIELD_CLASS_TYPE_BOOL]                                      = create_bool_field,
+       [BT_FIELD_CLASS_TYPE_BIT_ARRAY]                                 = create_bit_array_field,
+       [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER]                          = create_integer_field,
+       [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER]                            = create_integer_field,
+       [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION]                      = create_integer_field,
+       [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION]                        = create_integer_field,
+       [BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL]                     = create_real_field,
+       [BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL]                     = create_real_field,
+       [BT_FIELD_CLASS_TYPE_STRING]                                    = create_string_field,
+       [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_WITHOUT_SELECTOR]                   = create_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR]                 = create_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR]     = create_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR]       = 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,
 };
 
 static
@@ -224,22 +227,25 @@ void destroy_variant_field(struct bt_field *field);
 
 static
 void (* const field_destroy_funcs[])(struct bt_field *) = {
-       [BT_FIELD_CLASS_TYPE_BOOL]                              = destroy_bool_field,
-       [BT_FIELD_CLASS_TYPE_BIT_ARRAY]                         = destroy_bit_array_field,
-       [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER]                  = destroy_integer_field,
-       [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER]                    = destroy_integer_field,
-       [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION]              = destroy_integer_field,
-       [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION]                = destroy_integer_field,
-       [BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL]             = destroy_real_field,
-       [BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL]             = destroy_real_field,
-       [BT_FIELD_CLASS_TYPE_STRING]                            = destroy_string_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,
+       [BT_FIELD_CLASS_TYPE_BOOL]                                      = destroy_bool_field,
+       [BT_FIELD_CLASS_TYPE_BIT_ARRAY]                                 = destroy_bit_array_field,
+       [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER]                          = destroy_integer_field,
+       [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER]                            = destroy_integer_field,
+       [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION]                      = destroy_integer_field,
+       [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION]                        = destroy_integer_field,
+       [BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL]                     = destroy_real_field,
+       [BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL]                     = destroy_real_field,
+       [BT_FIELD_CLASS_TYPE_STRING]                                    = destroy_string_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_WITHOUT_SELECTOR]                   = destroy_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR]                 = destroy_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR]     = destroy_option_field,
+       [BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR]       = 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,
 };
 
 struct bt_field_class *bt_field_borrow_class(struct bt_field *field)
@@ -1060,8 +1066,7 @@ 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_IS_OPTION(field, "Field");
        BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
 
        if (has_field) {
@@ -1076,8 +1081,7 @@ 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");
+       BT_ASSERT_PRE_DEV_FIELD_IS_OPTION(field, "Field");
        return opt_field->selected_field;
 }
 
index ad25231cf82b0ac24f3772a089a4d608ee6eb35f..7bc83b3d679760d8572d4c9856eede9a825623a2 100644 (file)
                ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, \
                _name " is not an array field: %![field-]+f", (_field))
 
+#define BT_ASSERT_PRE_DEV_FIELD_IS_OPTION(_field, _name)               \
+       BT_ASSERT_PRE_DEV(                                              \
+               ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR || \
+               ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR || \
+               ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR || \
+               ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR, \
+               _name " is not an option field: %![field-]+f", (_field))
+
 #define BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(_field, _name)              \
        BT_ASSERT_PRE_DEV(                                              \
                ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR || \
index c61d6a6c4e57308d65e3fbe9a3e7fc196fa41074..c8cd67032eb4a5e77ce52d66fe10a1fca0553767 100644 (file)
@@ -47,7 +47,10 @@ bool find_field_class_recursive(struct bt_field_class *fc,
        }
 
        switch (fc->type) {
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                struct bt_field_class_option *opt_fc = (void *) fc;
                struct bt_field_path_item item = {
@@ -259,7 +262,10 @@ 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:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                struct bt_field_class_option *opt_fc = (void *) parent_fc;
 
@@ -323,7 +329,10 @@ 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_OPTION_WITHOUT_SELECTOR ||
+                               fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR ||
+                               fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR ||
+                               fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR ||
                                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) {
@@ -443,7 +452,10 @@ 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_OPTION_WITHOUT_SELECTOR ||
+                               tgt_fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR ||
+                               tgt_fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR ||
+                               tgt_fc->type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR ||
                                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) {
@@ -556,9 +568,11 @@ 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:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
-               struct bt_field_class_option *opt_fc = (void *) fc;
+               struct bt_field_class_option_with_selector *opt_fc = (void *) fc;
 
                if (opt_fc->selector_fc) {
                        BT_ASSERT(!opt_fc->selector_field_path);
@@ -611,7 +625,10 @@ int bt_resolve_field_paths(struct bt_field_class *fc,
 
        /* Recursive part */
        switch (fc->type) {
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                struct bt_field_class_option *opt_fc = (void *) fc;
 
index fa79548b83d8162271f4b935d34efc7d177c1a1c..1b0e8e7a3c5de3f8f1f4105a3dff3f2e18116cf8 100644 (file)
@@ -1334,7 +1334,10 @@ int translate_field_class(struct ctx *ctx)
        case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
                ret = translate_dynamic_array_field_class(ctx);
                break;
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
                ret = translate_option_field_class(ctx);
                break;
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
index a2b92f7c67f8392958d1fb967094222c9d298d0b..f17f8501d6f20aa07d458eaf15851ab5f31fb53f 100644 (file)
@@ -344,7 +344,10 @@ void copy_field_content(const bt_field *in_field, bt_field *out_field,
                }
                break;
        }
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                const bt_field *in_option_field;
                bt_field *out_option_field;
index dc757d03934be630b2242029d1acb2d07973c6de..c7680c8d962e24733b5d2c43ff8bd5c3affae8ed 100644 (file)
@@ -74,7 +74,10 @@ const bt_field_class *walk_field_path(struct trace_ir_metadata_maps *md_maps,
                                member);
                        break;
                }
-               case BT_FIELD_CLASS_TYPE_OPTION:
+               case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+               case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+               case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+               case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
                {
                        BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
                                BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
@@ -593,10 +596,14 @@ int field_class_option_copy(
                        "in-fc-addr=%p, out-fc-addr=%p",
                        in_field_class, out_field_class);
 
-       /*
-        * There is no content to copy. Keep this function call anyway for
-        * logging purposes.
-        */
+       if (bt_field_class_get_type(out_field_class) ==
+                       BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
+               bt_field_class_option_with_selector_bool_set_selector_is_reversed(
+                       out_field_class,
+                       bt_field_class_option_with_selector_bool_selector_is_reversed(
+                               in_field_class));
+       }
+
        BT_COMP_LOGD("Copied option field class: in-fc-addr=%p, "
                        "out-fc-addr=%p", in_field_class, out_field_class);
 
@@ -753,14 +760,14 @@ bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *
                                out_elem_fc, out_length_fc);
                break;
        }
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                const bt_field_class *in_content_fc =
                        bt_field_class_option_borrow_field_class_const(
                                        in_field_class);
-               const bt_field_path *in_selector_fp =
-                       bt_field_class_option_borrow_selector_field_path_const(
-                               in_field_class);
                bt_field_class *out_selector_fc = NULL;
                bt_field_class *out_content_fc;
                int ret;
@@ -780,20 +787,56 @@ bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *
                        goto error;
                }
 
-               if (in_selector_fp) {
-                       const bt_field_class *in_selector_fc =
-                               resolve_field_path_to_field_class(
-                                       in_selector_fp, md_maps);
+               if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
+                       out_field_class =
+                               bt_field_class_option_without_selector_create(
+                                       md_maps->output_trace_class,
+                                       out_content_fc);
+               } else {
+                       const bt_field_path *in_selector_fp =
+                               bt_field_class_option_with_selector_borrow_selector_field_path_const(
+                                       in_field_class);
+                       const bt_field_class *in_selector_fc;
 
+                       BT_ASSERT(in_selector_fp);
+                       in_selector_fc = resolve_field_path_to_field_class(
+                               in_selector_fp, md_maps);
                        BT_ASSERT(in_selector_fc);
                        out_selector_fc = g_hash_table_lookup(
                                md_maps->field_class_map, in_selector_fc);
                        BT_ASSERT(out_selector_fc);
+
+                       if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
+                               out_field_class =
+                                       bt_field_class_option_with_selector_bool_create(
+                                               md_maps->output_trace_class,
+                                               out_content_fc, out_selector_fc);
+                       } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR) {
+                               const bt_integer_range_set_unsigned *ranges =
+                                       bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
+                                               in_field_class);
+
+                               BT_ASSERT(ranges);
+                               out_field_class =
+                                       bt_field_class_option_with_selector_integer_unsigned_create(
+                                               md_maps->output_trace_class,
+                                               out_content_fc, out_selector_fc,
+                                               ranges);
+                       } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR) {
+                               const bt_integer_range_set_signed *ranges =
+                                       bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
+                                               in_field_class);
+
+                               BT_ASSERT(ranges);
+                               out_field_class =
+                                       bt_field_class_option_with_selector_integer_signed_create(
+                                               md_maps->output_trace_class,
+                                               out_content_fc, out_selector_fc,
+                                               ranges);
+                       }
                }
 
-               out_field_class = bt_field_class_option_create(
-                               md_maps->output_trace_class,
-                               out_content_fc, out_selector_fc);
+               BT_ASSERT(out_field_class);
                break;
        }
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
@@ -910,7 +953,10 @@ int copy_field_class_content_internal(
                ret = field_class_dynamic_array_copy(md_maps,
                                in_field_class, out_field_class);
                break;
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
                ret = field_class_option_copy(md_maps,
                                in_field_class, out_field_class);
                break;
index 1eab46b24e09977f8a76eedc575d06464c2768ef..8b18bf027d611d92957169030b6bc8c631d51195 100644 (file)
@@ -949,8 +949,17 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc)
        case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
                type = "Dynamic array";
                break;
-       case BT_FIELD_CLASS_TYPE_OPTION:
-               type = "Option";
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+               type = "Option (no selector)";
+               break;
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+               type = "Option (boolean selector)";
+               break;
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+               type = "Option (unsigned integer selector)";
+               break;
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
+               type = "Option (signed integer selector)";
                break;
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
                type = "Variant (no selector)";
@@ -1020,17 +1029,17 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc)
                }
 
                break;
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                const bt_field_path *selector_field_path =
-                       bt_field_class_option_borrow_selector_field_path_const(fc);
-
-               if (selector_field_path) {
-                       g_string_append(ctx->str, " (Selector field path ");
-                       write_field_path(ctx, selector_field_path);
-                       g_string_append_c(ctx->str, ')');
-               }
+                       bt_field_class_option_with_selector_borrow_selector_field_path_const(
+                               fc);
 
+               g_string_append(ctx->str, " (Selector field path ");
+               write_field_path(ctx, selector_field_path);
+               g_string_append_c(ctx->str, ')');
                break;
        }
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
@@ -1175,18 +1184,56 @@ void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc)
                write_field_class(ctx,
                        bt_field_class_array_borrow_element_field_class_const(fc));
                break;
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
+       {
+               const void *ranges = NULL;
+               bool selector_is_signed = false;
+
                if (wrote_user_attrs) {
                        write_nl(ctx);
                } else {
                        g_string_append(ctx->str, ":\n");
                }
 
+               if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
+                       write_bool_prop_line(ctx, "Selector is reversed",
+                               bt_field_class_option_with_selector_bool_selector_is_reversed(fc));
+               } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR) {
+                       ranges = bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(fc);
+               } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR) {
+                       ranges = bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(fc);
+                       selector_is_signed = true;
+               }
+
+               if (ranges) {
+                       GArray *sorted_ranges = range_set_to_int_ranges(
+                               ranges, selector_is_signed);
+                       uint64_t i;
+
+                       BT_ASSERT(sorted_ranges);
+                       BT_ASSERT(sorted_ranges->len > 0);
+                       write_prop_name_line(ctx, "Selector ranges");
+
+                       for (i = 0; i < sorted_ranges->len; i++) {
+                               write_sp(ctx);
+                               write_int_range(ctx,
+                                       int_range_at(sorted_ranges, i),
+                                       selector_is_signed);
+                       }
+
+                       write_nl(ctx);
+                       g_array_free(sorted_ranges, TRUE);
+               }
+
                write_prop_name_line(ctx, "Content");
                write_sp(ctx);
                write_field_class(ctx,
                        bt_field_class_option_borrow_field_class_const(fc));
                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:
@@ -1921,7 +1968,10 @@ void write_field(struct details_write_ctx *ctx, const bt_field *field,
                decr_indent(ctx);
                break;
        }
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
        {
                const bt_field *content_field =
                        bt_field_option_borrow_field_const(field);
index b89045d8c0d650e9ebf920c0b30bcec8299edf55..c098dd6ca993326f5fd054f014bdc3244ac3f3cc 100644 (file)
@@ -1059,7 +1059,10 @@ int print_field(struct pretty_component *pretty,
        }
        case BT_FIELD_CLASS_TYPE_STRUCTURE:
                return print_struct(pretty, field, print_names);
-       case BT_FIELD_CLASS_TYPE_OPTION:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
+       case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
                return print_option(pretty, field, print_names);
        case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
        case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
index 2af55fb241dd46a5d703bafd644cf0738693f5a1..a8d2fa021705e541c6129e20f37eba8a32e348d7 100644 (file)
@@ -2194,7 +2194,9 @@ class OptionFieldTestCase(unittest.TestCase):
         field.value = {'opt_field': 'hiboux'}
 
     def _create_fc(self, tc):
-        fc = tc.create_option_field_class(tc.create_string_field_class())
+        fc = tc.create_option_without_selector_field_class(
+            tc.create_string_field_class()
+        )
         top_fc = tc.create_structure_field_class()
         top_fc.append_member('opt_field', fc)
         return top_fc
index ef0f5647310a993a769fb7e48c114e86c4428b3d..1ea9bad294dec6875ee0773e7ed2eb6604e11107 100644 (file)
@@ -724,30 +724,36 @@ class StructureFieldClassTestCase(
         )
 
 
-class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
+class OptionWithoutSelectorFieldClassTestCase(_TestFieldClass, unittest.TestCase):
     @staticmethod
     def _const_value_setter(field):
         field.has_field = True
         field.value = 12
 
     def _create_default_field_class(self, *args, **kwargs):
-        return self._tc.create_option_field_class(self._content_fc, **kwargs)
+        return self._tc.create_option_without_selector_field_class(
+            self._content_fc, *args, **kwargs
+        )
 
     def _create_default_const_field_class(self, *args, **kwargs):
-        fc = self._tc.create_option_field_class(self._content_fc, **kwargs)
+        fc = self._tc.create_option_without_selector_field_class(
+            self._content_fc, *args, **kwargs
+        )
         return _create_const_field_class(self._tc, fc, self._const_value_setter)
 
     def setUp(self):
         self._tc = get_default_trace_class()
         self._content_fc = self._tc.create_signed_integer_field_class(23)
-        self._tag_fc = self._tc.create_bool_field_class()
 
     def test_create_default(self):
         fc = self._create_default_field_class()
         self.assertEqual(fc.field_class.addr, self._content_fc.addr)
-        self.assertIsNone(fc.selector_field_path, None)
         self.assertEqual(len(fc.user_attributes), 0)
 
+    def test_create_invalid_field_class(self):
+        with self.assertRaises(TypeError):
+            self._tc.create_option_without_selector_field_class(object())
+
     def test_attr_field_class(self):
         fc = self._create_default_field_class()
         self.assertIs(type(fc.field_class), bt2_field_class._SignedIntegerFieldClass)
@@ -758,8 +764,32 @@ class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
             type(fc.field_class), bt2_field_class._SignedIntegerFieldClassConst
         )
 
+
+class _OptionWithSelectorFieldClassTestCase(_TestFieldClass):
+    @staticmethod
+    def _const_value_setter(field):
+        field['opt'].has_field = True
+        field['opt'].value = 12
+
+    def _create_default_const_field_class(self, *args, **kwargs):
+        # Create a struct to contain the option and its selector else we can't
+        # create the non-const field necessary to get the the const field_class
+        struct_fc = self._tc.create_structure_field_class()
+        struct_fc.append_member('selecteux', self._tag_fc)
+        opt_fc = self._create_default_field_class(*args, **kwargs)
+        struct_fc.append_member('opt', opt_fc)
+
+        return _create_const_field_class(self._tc, struct_fc, self._const_value_setter)[
+            'opt'
+        ].field_class
+
+    def setUp(self):
+        self._tc = get_default_trace_class()
+        self._content_fc = self._tc.create_signed_integer_field_class(23)
+        self._tag_fc = self._create_tag_fc()
+
     def _create_field_class_for_field_path_test(self):
-        fc = self._create_default_field_class(selector_fc=self._tag_fc)
+        fc = self._create_default_field_class()
 
         foo_fc = self._tc.create_single_precision_real_field_class()
         bar_fc = self._tc.create_string_field_class()
@@ -771,7 +801,9 @@ class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
         inner_struct_fc.append_member('tag', self._tag_fc)
         inner_struct_fc.append_member('opt', fc)
 
-        opt_struct_array_fc = self._tc.create_option_field_class(inner_struct_fc)
+        opt_struct_array_fc = self._tc.create_option_without_selector_field_class(
+            inner_struct_fc
+        )
 
         outer_struct_fc = self._tc.create_structure_field_class()
         outer_struct_fc.append_member('foo', foo_fc)
@@ -810,13 +842,90 @@ class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
             fc.selector_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
         )
 
-    def test_create_invalid_field_class(self):
+
+class OptionWithBoolSelectorFieldClassTestCase(
+    _OptionWithSelectorFieldClassTestCase, unittest.TestCase
+):
+    def _create_default_field_class(self, *args, **kwargs):
+        return self._tc.create_option_with_bool_selector_field_class(
+            self._content_fc, self._tag_fc, *args, **kwargs
+        )
+
+    def _create_tag_fc(self):
+        return self._tc.create_bool_field_class()
+
+    def test_create_default(self):
+        fc = self._create_default_field_class()
+        self.assertEqual(fc.field_class.addr, self._content_fc.addr)
+        self.assertFalse(fc.selector_is_reversed)
+        self.assertEqual(len(fc.user_attributes), 0)
+
+    def test_create_selector_is_reversed_wrong_type(self):
+        with self.assertRaises(TypeError):
+            self._create_default_field_class(selector_is_reversed=23)
+
+    def test_create_invalid_selector_type(self):
+        with self.assertRaises(TypeError):
+            self._tc.create_option_with_bool_selector_field_class(self._content_fc, 17)
+
+    def test_attr_selector_is_reversed(self):
+        fc = self._create_default_field_class(selector_is_reversed=True)
+        self.assertTrue(fc.selector_is_reversed)
+
+    def test_const_attr_selector_is_reversed(self):
+        fc = self._create_default_const_field_class(selector_is_reversed=True)
+        self.assertTrue(fc.selector_is_reversed)
+
+
+class _OptionWithIntegerSelectorFieldClassTestCase(
+    _OptionWithSelectorFieldClassTestCase
+):
+    def _create_default_field_class(self, *args, **kwargs):
+        return self._tc.create_option_with_integer_selector_field_class(
+            self._content_fc, self._tag_fc, self._ranges, *args, **kwargs
+        )
+
+    def test_create_default(self):
+        fc = self._create_default_field_class()
+        self.assertEqual(fc.field_class.addr, self._content_fc.addr)
+        self.assertEqual(fc.ranges, self._ranges)
+        self.assertEqual(len(fc.user_attributes), 0)
+
+    def test_create_ranges_wrong_type(self):
         with self.assertRaises(TypeError):
-            self._tc.create_option_field_class(object())
+            self._tc.create_option_with_integer_selector_field_class(
+                self._content_fc, self._tag_fc, 23
+            )
+
+    def test_create_ranges_empty(self):
+        with self.assertRaises(ValueError):
+            self._tc.create_option_with_integer_selector_field_class(
+                self._content_fc, self._tag_fc, type(self._ranges)()
+            )
 
     def test_create_invalid_selector_type(self):
         with self.assertRaises(TypeError):
-            self._tc.create_option_field_class(self._content_fc, 17)
+            self._tc.create_option_with_bool_selector_field_class(self._content_fc, 17)
+
+    def test_attr_ranges(self):
+        fc = self._create_default_field_class()
+        print(type(fc.ranges), type(self._ranges))
+        self.assertEqual(fc.ranges, self._ranges)
+
+    def test_const_attr_ranges(self):
+        fc = self._create_default_const_field_class()
+        self.assertEqual(fc.ranges, self._ranges)
+
+
+class OptionWithUnsignedIntegerSelectorFieldClassTestCase(
+    _OptionWithIntegerSelectorFieldClassTestCase, unittest.TestCase
+):
+    def setUp(self):
+        self._ranges = bt2.UnsignedIntegerRangeSet([(1, 3), (18, 44)])
+        super().setUp()
+
+    def _create_tag_fc(self):
+        return self._tc.create_unsigned_integer_field_class()
 
 
 class VariantFieldClassWithoutSelectorTestCase(
index b2d91592784e857222c9b3ac03d6b22ed9ef3b94..d4700af55ad1715f8783932dc1eba74e1b094a10 100644 (file)
@@ -228,6 +228,21 @@ class PackageTestCase(unittest.TestCase):
     def test_has__OptionFieldClass(self):
         self._assert_in_bt2('_OptionFieldClass')
 
+    def test_has__OptionWithSelectorFieldClass(self):
+        self._assert_in_bt2('_OptionWithSelectorFieldClass')
+
+    def test_has__OptionWithBoolSelectorFieldClass(self):
+        self._assert_in_bt2('_OptionWithBoolSelectorFieldClass')
+
+    def test_has__OptionWithIntegerSelectorFieldClass(self):
+        self._assert_in_bt2('_OptionWithIntegerSelectorFieldClass')
+
+    def test_has__OptionWithUnsignedIntegerSelectorFieldClass(self):
+        self._assert_in_bt2('_OptionWithUnsignedIntegerSelectorFieldClass')
+
+    def test_has__OptionWithSignedIntegerSelectorFieldClass(self):
+        self._assert_in_bt2('_OptionWithSignedIntegerSelectorFieldClass')
+
     def test_has__VariantFieldClass(self):
         self._assert_in_bt2('_VariantFieldClass')
 
@@ -288,6 +303,21 @@ class PackageTestCase(unittest.TestCase):
     def test_has__OptionFieldClassConst(self):
         self._assert_in_bt2('_OptionFieldClassConst')
 
+    def test_has__OptionWithSelectorFieldClassConst(self):
+        self._assert_in_bt2('_OptionWithSelectorFieldClassConst')
+
+    def test_has__OptionWithBoolSelectorFieldClassConst(self):
+        self._assert_in_bt2('_OptionWithBoolSelectorFieldClassConst')
+
+    def test_has__OptionWithIntegerSelectorFieldClassConst(self):
+        self._assert_in_bt2('_OptionWithIntegerSelectorFieldClassConst')
+
+    def test_has__OptionWithUnsignedIntegerSelectorFieldClassConst(self):
+        self._assert_in_bt2('_OptionWithUnsignedIntegerSelectorFieldClassConst')
+
+    def test_has__OptionWithSignedIntegerSelectorFieldClassConst(self):
+        self._assert_in_bt2('_OptionWithSignedIntegerSelectorFieldClassConst')
+
     def test_has__VariantFieldClassConst(self):
         self._assert_in_bt2('_VariantFieldClassConst')
 
This page took 0.052359 seconds and 4 git commands to generate.