BT_FIELD_CLASS_TYPE_STRUCTURE,
BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
- BT_FIELD_CLASS_TYPE_VARIANT,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
} bt_field_class_type;
typedef enum bt_field_class_integer_preferred_display_base {
bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
const bt_field_class *field_class, uint64_t index);
+extern const bt_field_class_unsigned_enumeration_mapping *
+bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const(
+ const bt_field_class *field_class, const char *label);
+
extern const bt_field_class_signed_enumeration_mapping *
bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
const bt_field_class *field_class, uint64_t index);
+extern const bt_field_class_signed_enumeration_mapping *
+bt_field_class_signed_enumeration_borrow_mapping_by_label_const(
+ const bt_field_class *field_class, const char *label);
+
static inline
const bt_field_class_enumeration_mapping *
bt_field_class_unsigned_enumeration_mapping_as_mapping_const(
extern const char *bt_field_class_enumeration_mapping_get_label(
const bt_field_class_enumeration_mapping *mapping);
-extern uint64_t bt_field_class_enumeration_mapping_get_range_count(
- const bt_field_class_enumeration_mapping *mapping);
-
-extern void
-bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- const bt_field_class_unsigned_enumeration_mapping *mapping,
- uint64_t index, uint64_t *lower, uint64_t *upper);
+extern const bt_integer_range_set_unsigned *
+bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ const bt_field_class_unsigned_enumeration_mapping *mapping);
-extern void
-bt_field_class_signed_enumeration_mapping_get_range_by_index(
- const bt_field_class_signed_enumeration_mapping *mapping,
- uint64_t index, int64_t *lower, int64_t *upper);
+extern const bt_integer_range_set_signed *
+bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ const bt_field_class_signed_enumeration_mapping *mapping);
typedef enum bt_field_class_enumeration_get_mapping_labels_for_value_status {
BT_FIELD_CLASS_ENUMERATION_GET_MAPPING_LABELS_BY_VALUE_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
bt_field_class_dynamic_array_borrow_length_field_path_const(
const bt_field_class *field_class);
-extern const bt_field_path *
-bt_field_class_variant_borrow_selector_field_path_const(
- const bt_field_class *field_class);
-
extern uint64_t bt_field_class_variant_get_option_count(
const bt_field_class *field_class);
bt_field_class_variant_borrow_option_by_name_const(
const bt_field_class *field_class, const char *name);
+extern const bt_field_class_variant_with_unsigned_selector_option *
+bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
+ const bt_field_class *field_class, uint64_t index);
+
+extern const bt_field_class_variant_with_unsigned_selector_option *
+bt_field_class_variant_with_unsigned_selector_borrow_option_by_name_const(
+ const bt_field_class *field_class, const char *name);
+
+extern const bt_field_class_variant_with_signed_selector_option *
+bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ const bt_field_class *field_class, uint64_t index);
+
+extern const bt_field_class_variant_with_signed_selector_option *
+bt_field_class_variant_with_signed_selector_borrow_option_by_name_const(
+ const bt_field_class *field_class, const char *name);
+
extern const char *bt_field_class_variant_option_get_name(
const bt_field_class_variant_option *option);
bt_field_class_variant_option_borrow_field_class_const(
const bt_field_class_variant_option *option);
+extern const bt_field_path *
+bt_field_class_variant_with_selector_borrow_selector_field_path_const(
+ const bt_field_class *field_class);
+
+extern const bt_integer_range_set_unsigned *
+bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ const bt_field_class_variant_with_unsigned_selector_option *option);
+
+static inline
+const bt_field_class_variant_option *
+bt_field_class_variant_with_unsigned_selector_option_as_option_const(
+ const bt_field_class_variant_with_unsigned_selector_option *option)
+{
+ return __BT_UPCAST_CONST(bt_field_class_variant_option, option);
+}
+
+extern const bt_integer_range_set_signed *
+bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ const bt_field_class_variant_with_signed_selector_option *option);
+
+static inline
+const bt_field_class_variant_option *
+bt_field_class_variant_with_signed_selector_option_as_option_const(
+ const bt_field_class_variant_with_signed_selector_option *option)
+{
+ return __BT_UPCAST_CONST(bt_field_class_variant_option, option);
+}
+
extern void bt_field_class_get_ref(const bt_field_class *field_class);
extern void bt_field_class_put_ref(const bt_field_class *field_class);
extern bt_field_class *bt_field_class_signed_enumeration_create(
bt_trace_class *trace_class);
-typedef enum bt_field_class_enumeration_map_range_status {
- BT_FIELD_CLASS_ENUMERATION_MAP_RANGE_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
- BT_FIELD_CLASS_ENUMERATION_MAP_RANGE_STATUS_OK = __BT_FUNC_STATUS_OK,
-} bt_field_class_enumeration_map_range_status;
+typedef enum bt_field_class_enumeration_add_mapping_status {
+ BT_FIELD_CLASS_ENUMERATION_ADD_MAPPING_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
+ BT_FIELD_CLASS_ENUMERATION_ADD_MAPPING_STATUS_OK = __BT_FUNC_STATUS_OK,
+} bt_field_class_enumeration_add_mapping_status;
-extern bt_field_class_enumeration_map_range_status
-bt_field_class_unsigned_enumeration_map_range(
+extern bt_field_class_enumeration_add_mapping_status
+bt_field_class_unsigned_enumeration_add_mapping(
bt_field_class *field_class, const char *label,
- uint64_t range_lower, uint64_t range_upper);
+ const bt_integer_range_set_unsigned *range_set);
-extern bt_field_class_enumeration_map_range_status
-bt_field_class_signed_enumeration_map_range(
+extern bt_field_class_enumeration_add_mapping_status
+bt_field_class_signed_enumeration_add_mapping(
bt_field_class *field_class, const char *label,
- int64_t range_lower, int64_t range_upper);
+ const bt_integer_range_set_signed *range_set);
extern bt_field_class *bt_field_class_string_create(
bt_trace_class *trace_class);
typedef enum bt_field_class_dynamic_array_set_length_field_class_status {
BT_FIELD_CLASS_DYNAMIC_ARRAY_SET_LENGTH_FIELD_CLASS_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
- BT_FIELD_CLASS_DYNAMIC_ARRAY_SET_LENGTH_FIELD_CLASS_STATUS_OK = __BT_FUNC_STATUS_OK,
+ BT_FIELD_CLASS_DYNAMIC_ARRAY_SET_LENGTH_FIELD_CLASS_STATUS_OK = __BT_FUNC_STATUS_OK,
} bt_field_class_dynamic_array_set_length_field_class_status;
extern bt_field_class_dynamic_array_set_length_field_class_status
bt_field_class *length_field_class);
extern bt_field_class *bt_field_class_variant_create(
- bt_trace_class *trace_class);
-
-typedef enum bt_field_class_variant_set_selector_field_class_status {
- BT_FIELD_CLASS_VARIANT_SET_SELECTOR_FIELD_CLASS_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
- BT_FIELD_CLASS_VARIANT_SET_SELECTOR_FIELD_CLASS_STATUS_OK = __BT_FUNC_STATUS_OK,
-} bt_field_class_variant_set_selector_field_class_status;
-
-extern bt_field_class_variant_set_selector_field_class_status
-bt_field_class_variant_set_selector_field_class(bt_field_class *field_class,
+ bt_trace_class *trace_class,
bt_field_class *selector_field_class);
-typedef enum bt_field_class_variant_append_option_status {
- BT_FIELD_CLASS_VARIANT_APPEND_OPTION_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
- BT_FIELD_CLASS_VARIANT_APPEND_OPTION_STATUS_OK = __BT_FUNC_STATUS_OK,
-} bt_field_class_variant_append_option_status;
+typedef enum bt_field_class_variant_without_selector_append_option_status {
+ BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
+ BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK = __BT_FUNC_STATUS_OK,
+} bt_field_class_variant_without_selector_append_option_status;
-extern bt_field_class_variant_append_option_status
-bt_field_class_variant_append_option(
- bt_field_class *var_field_class,
- const char *name, bt_field_class *field_class);
+extern bt_field_class_variant_without_selector_append_option_status
+bt_field_class_variant_without_selector_append_option(
+ bt_field_class *var_field_class, const char *name,
+ bt_field_class *field_class);
-extern bt_field_class_variant_option *
-bt_field_class_variant_borrow_option_by_index(
- bt_field_class *field_class, uint64_t index);
+typedef enum bt_field_class_variant_with_selector_append_option_status {
+ BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
+ BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK = __BT_FUNC_STATUS_OK,
+} bt_field_class_variant_with_selector_append_option_status;
-extern bt_field_class_variant_option *
-bt_field_class_variant_borrow_option_by_name(
- bt_field_class *field_class, const char *name);
+extern bt_field_class_variant_with_selector_append_option_status
+bt_field_class_variant_with_unsigned_selector_append_option(
+ bt_field_class *var_field_class, const char *name,
+ bt_field_class *field_class,
+ const bt_integer_range_set_unsigned *range_set);
-extern bt_field_class *bt_field_class_variant_option_borrow_field_class(
- bt_field_class_variant_option *option);
+extern bt_field_class_variant_with_selector_append_option_status
+bt_field_class_variant_with_signed_selector_append_option(
+ bt_field_class *var_field_class, const char *name,
+ bt_field_class *field_class,
+ const bt_integer_range_set_signed *range_set);
#ifdef __cplusplus
}
bt_field_variant_borrow_selected_option_field_const(
const bt_field *field);
+extern const bt_field_class_variant_option *
+bt_field_variant_borrow_selected_class_option_const(
+ const bt_field *field);
+
+extern const bt_field_class_variant_with_unsigned_selector_option *
+bt_field_variant_with_unsigned_selector_borrow_selected_class_option_const(
+ const bt_field *field);
+
+extern const bt_field_class_variant_with_signed_selector_option *
+bt_field_variant_with_signed_selector_borrow_selected_class_option_const(
+ const bt_field *field);
+
#ifdef __cplusplus
}
#endif
bt_field_dynamic_array_set_length(
bt_field *field, uint64_t length);
-typedef enum bt_field_variant_select_option_field_status {
+typedef enum bt_field_variant_select_option_field_by_index_status {
BT_FIELD_VARIANT_SELECT_OPTION_FIELD_STATUS_OK = __BT_FUNC_STATUS_OK,
-} bt_field_variant_select_option_field_status;
+} bt_field_variant_select_option_field_by_index_status;
-extern bt_field_variant_select_option_field_status
-bt_field_variant_select_option_field(
+extern bt_field_variant_select_option_field_by_index_status
+bt_field_variant_select_option_field_by_index(
bt_field *field, uint64_t index);
extern bt_field *bt_field_variant_borrow_selected_option_field(
typedef struct bt_component_sink bt_component_sink;
typedef struct bt_component_source bt_component_source;
typedef struct bt_connection bt_connection;
+typedef struct bt_error bt_error;
+typedef struct bt_error_cause bt_error_cause;
typedef struct bt_event bt_event;
typedef struct bt_event_class bt_event_class;
typedef struct bt_event_header_field bt_event_header_field;
-typedef struct bt_error bt_error;
-typedef struct bt_error_cause bt_error_cause;
typedef struct bt_field bt_field;
typedef struct bt_field_class bt_field_class;
typedef struct bt_field_class_enumeration_mapping bt_field_class_enumeration_mapping;
typedef struct bt_field_class_signed_enumeration_mapping bt_field_class_signed_enumeration_mapping;
-typedef struct bt_field_class_unsigned_enumeration_mapping bt_field_class_unsigned_enumeration_mapping;
typedef struct bt_field_class_structure_member bt_field_class_structure_member;
+typedef struct bt_field_class_unsigned_enumeration_mapping bt_field_class_unsigned_enumeration_mapping;
typedef struct bt_field_class_variant_option bt_field_class_variant_option;
+typedef struct bt_field_class_variant_with_signed_selector_option bt_field_class_variant_with_signed_selector_option;
+typedef struct bt_field_class_variant_with_unsigned_selector_option bt_field_class_variant_with_unsigned_selector_option;
typedef struct bt_field_path bt_field_path;
typedef struct bt_field_path_item bt_field_path_item;
typedef struct bt_graph bt_graph;
@selected_option_index.setter
def selected_option_index(self, index):
- native_bt.field_variant_select_option_field(self._ptr, index)
+ native_bt.field_variant_select_option_field_by_index(self._ptr, index)
@property
def selected_option(self):
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_VARIANT: _VariantField,
+ 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,
}
import collections.abc
import bt2.field
import bt2.field_path
+import bt2.integer_range_set
import bt2
_is_single_precision = property(fset=_is_single_precision)
-class _EnumerationFieldClassMappingRange:
- def __init__(self, lower, upper):
- self._lower = lower
- self._upper = upper
-
- @property
- def lower(self):
- return self._lower
-
- @property
- def upper(self):
- return self._upper
-
- def __eq__(self, other):
- return self.lower == other.lower and self.upper == other.upper
-
-
-class _EnumerationFieldClassMapping(collections.abc.Set):
+# an enumeration field class mapping does not have a reference count, so
+# we copy the properties here to avoid eventual memory access errors.
+class _EnumerationFieldClassMapping:
def __init__(self, mapping_ptr):
- self._mapping_ptr = mapping_ptr
+ base_mapping_ptr = self._as_enumeration_field_class_mapping_ptr(mapping_ptr)
+ self._label = native_bt.field_class_enumeration_mapping_get_label(base_mapping_ptr)
+ assert self._label is not None
+ ranges_ptr = self._mapping_borrow_ranges_ptr(mapping_ptr)
+ assert ranges_ptr is not None
+ self._ranges = self._ranges_type._create_from_ptr_and_get_ref(ranges_ptr)
@property
def label(self):
- mapping_ptr = self._as_enumeration_field_class_mapping_ptr(self._mapping_ptr)
- label = native_bt.field_class_enumeration_mapping_get_label(mapping_ptr)
- assert label is not None
- return label
+ return self._label
- def __len__(self):
- mapping_ptr = self._as_enumeration_field_class_mapping_ptr(self._mapping_ptr)
- return native_bt.field_class_enumeration_mapping_get_range_count(mapping_ptr)
-
- def __contains__(self, other_range):
- for curr_range in self:
- if curr_range == other_range:
- return True
- return False
-
- def __iter__(self):
- for idx in range(len(self)):
- lower, upper = self._get_range_by_index(self._mapping_ptr, idx)
- yield _EnumerationFieldClassMappingRange(lower, upper)
+ @property
+ def ranges(self):
+ return self._ranges
class _UnsignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping):
+ _ranges_type = bt2.integer_range_set.UnsignedIntegerRangeSet
_as_enumeration_field_class_mapping_ptr = staticmethod(native_bt.field_class_unsigned_enumeration_mapping_as_mapping_const)
- _get_range_by_index = staticmethod(native_bt.field_class_unsigned_enumeration_mapping_get_range_by_index)
+ _mapping_borrow_ranges_ptr = staticmethod(native_bt.field_class_unsigned_enumeration_mapping_borrow_ranges_const)
class _SignedEnumerationFieldClassMapping(_EnumerationFieldClassMapping):
+ _ranges_type = bt2.integer_range_set.SignedIntegerRangeSet
_as_enumeration_field_class_mapping_ptr = staticmethod(native_bt.field_class_signed_enumeration_mapping_as_mapping_const)
- _get_range_by_index = staticmethod(native_bt.field_class_signed_enumeration_mapping_get_range_by_index)
+ _mapping_borrow_ranges_ptr = staticmethod(native_bt.field_class_signed_enumeration_mapping_borrow_ranges_const)
class _EnumerationFieldClass(_IntegerFieldClass, collections.abc.Mapping):
def __len__(self):
count = native_bt.field_class_enumeration_get_mapping_count(self._ptr)
- assert(count >= 0)
+ assert count >= 0
return count
- def map_range(self, label, lower, upper=None):
+ def add_mapping(self, label, ranges):
utils._check_str(label)
+ utils._check_type(ranges, self._range_set_type)
- if upper is None:
- upper = lower
+ if label in self:
+ raise bt2.Error("duplicate mapping label '{}'".format(label))
- status = self._map_range(self._ptr, label, lower, upper)
+ status = self._add_mapping(self._ptr, label, ranges._ptr)
utils._handle_func_status(status,
- "cannot add mapping to enumeration field class object")
+ 'cannot add mapping to enumeration field class object')
- def labels_for_value(self, value):
+ def mappings_for_value(self, value):
status, labels = self._get_mapping_labels_for_value(self._ptr, value)
- utils._handle_func_status(status, "cannot get mapping labels")
- return labels
+ utils._handle_func_status(status, 'cannot get mapping labels for value {}'.format(value))
+ return [self[label] for label in labels]
def __iter__(self):
for idx in range(len(self)):
mapping = self._get_mapping_by_index(self._ptr, idx)
yield mapping.label
- def __getitem__(self, key):
- utils._check_str(key)
- for idx in range(len(self)):
- mapping = self._get_mapping_by_index(self._ptr, idx)
- if mapping.label == key:
- return mapping
+ def __getitem__(self, label):
+ utils._check_str(label)
+ mapping = self._get_mapping_by_label(self._ptr, label)
- raise KeyError(key)
+ if mapping is None:
+ raise KeyError(label)
+
+ return mapping
def __iadd__(self, mappings):
- for mapping in mappings.values():
- for range in mapping:
- self.map_range(mapping.label, range.lower, range.upper)
+ for label, ranges in mappings:
+ self.add_mapping(label, ranges)
return self
class _UnsignedEnumerationFieldClass(_EnumerationFieldClass, _UnsignedIntegerFieldClass):
_NAME = 'Unsigned enumeration'
+ _range_set_type = bt2.integer_range_set.UnsignedIntegerRangeSet
+ _add_mapping = staticmethod(native_bt.field_class_unsigned_enumeration_add_mapping)
@staticmethod
def _get_mapping_by_index(enum_ptr, index):
return _UnsignedEnumerationFieldClassMapping(mapping_ptr)
@staticmethod
- def _map_range(enum_ptr, label, lower, upper):
- utils._check_uint64(lower)
- utils._check_uint64(upper)
- return native_bt.field_class_unsigned_enumeration_map_range(enum_ptr, label, lower, upper)
+ def _get_mapping_by_label(enum_ptr, label):
+ mapping_ptr = native_bt.field_class_unsigned_enumeration_borrow_mapping_by_label_const(enum_ptr, label)
+
+ if mapping_ptr is None:
+ return
+
+ return _UnsignedEnumerationFieldClassMapping(mapping_ptr)
@staticmethod
def _get_mapping_labels_for_value(enum_ptr, value):
class _SignedEnumerationFieldClass(_EnumerationFieldClass, _SignedIntegerFieldClass):
_NAME = 'Signed enumeration'
+ _range_set_type = bt2.integer_range_set.SignedIntegerRangeSet
+ _add_mapping = staticmethod(native_bt.field_class_signed_enumeration_add_mapping)
@staticmethod
def _get_mapping_by_index(enum_ptr, index):
return _SignedEnumerationFieldClassMapping(mapping_ptr)
@staticmethod
- def _map_range(enum_ptr, label, lower, upper):
- utils._check_int64(lower)
- utils._check_int64(upper)
- return native_bt.field_class_signed_enumeration_map_range(enum_ptr, label, lower, upper)
+ def _get_mapping_by_label(enum_ptr, label):
+ mapping_ptr = native_bt.field_class_signed_enumeration_borrow_mapping_by_label_const(enum_ptr, label)
+
+ if mapping_ptr is None:
+ return
+
+ return _SignedEnumerationFieldClassMapping(mapping_ptr)
@staticmethod
def _get_mapping_labels_for_value(enum_ptr, value):
_NAME = 'String'
-class _FieldContainer(collections.abc.Mapping):
+class _StructureFieldClassMember:
+ def __init__(self, name, field_class):
+ self._name = name
+ self._field_class = field_class
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def field_class(self):
+ return self._field_class
+
+
+class _StructureFieldClass(_FieldClass, collections.abc.Mapping):
+ _NAME = 'Structure'
+
+ def append_member(self, name, field_class):
+ utils._check_str(name)
+ utils._check_type(field_class, _FieldClass)
+
+ if name in self:
+ raise bt2.Error("duplicate member name '{}'".format(name))
+
+ status = native_bt.field_class_structure_append_member(self._ptr, name, field_class._ptr)
+ utils._handle_func_status(status,
+ 'cannot append member to structure field class object')
+
def __len__(self):
- count = self._get_element_count(self._ptr)
+ count = native_bt.field_class_structure_get_member_count(self._ptr)
assert count >= 0
return count
+ @staticmethod
+ def _create_member_from_ptr(member_ptr):
+ name = native_bt.field_class_structure_member_get_name(member_ptr)
+ assert name is not None
+ fc_ptr = native_bt.field_class_structure_member_borrow_field_class_const(member_ptr)
+ assert fc_ptr is not None
+ fc = _create_field_class_from_ptr_and_get_ref(fc_ptr)
+ return _StructureFieldClassMember(name, fc)
+
def __getitem__(self, key):
if not isinstance(key, str):
- raise TypeError("key should be a 'str' object, got {}".format(key.__class__.__name__))
+ raise TypeError("key must be a 'str' object, got '{}'".format(key.__class__.__name__))
- ptr = self._borrow_field_class_ptr_by_name(key)
+ member_ptr = native_bt.field_class_structure_borrow_member_by_name_const(self._ptr, key)
- if ptr is None:
+ if member_ptr is None:
raise KeyError(key)
- return _create_field_class_from_ptr_and_get_ref(ptr)
-
- def _borrow_field_class_ptr_by_name(self, key):
- element_ptr = self._borrow_element_by_name(self._ptr, key)
- if element_ptr is None:
- return
-
- return self._element_borrow_field_class(element_ptr)
+ return self._create_member_from_ptr(member_ptr)
def __iter__(self):
for idx in range(len(self)):
- element_ptr = self._borrow_element_by_index(self._ptr, idx)
- assert element_ptr is not None
+ member_ptr = native_bt.field_class_structure_borrow_member_by_index_const(self._ptr, idx)
+ assert member_ptr is not None
+ yield native_bt.field_class_structure_member_get_name(member_ptr)
- yield self._element_get_name(element_ptr)
-
- def _append_element_common(self, name, field_class):
- utils._check_str(name)
- utils._check_type(field_class, _FieldClass)
- status = self._append_element(self._ptr, name, field_class._ptr)
- utils._handle_func_status(status,
- "cannot add field to {} field class object".format(self._NAME.lower()))
-
- def __iadd__(self, fields):
- for name, field_class in fields.items():
- self._append_element_common(name, field_class)
+ def __iadd__(self, members):
+ for name, field_class in members:
+ self.append_member(name, field_class)
return self
- def _at_index(self, index):
+ def member_at_index(self, index):
utils._check_uint64(index)
- if index < 0 or index >= len(self):
+ if index >= len(self):
raise IndexError
- element_ptr = self._borrow_element_by_index(self._ptr, index)
- assert element_ptr is not None
+ member_ptr = native_bt.field_class_structure_borrow_member_by_index_const(self._ptr, index)
+ assert member_ptr is not None
+ return self._create_member_from_ptr(member_ptr)
+
- field_class_ptr = self._element_borrow_field_class(element_ptr)
+class _VariantFieldClassOption:
+ def __init__(self, name, field_class):
+ self._name = name
+ self._field_class = field_class
- return _create_field_class_from_ptr_and_get_ref(field_class_ptr)
+ @property
+ def name(self):
+ return self._name
+ @property
+ def field_class(self):
+ return self._field_class
-class _StructureFieldClass(_FieldClass, _FieldContainer):
- _NAME = 'Structure'
- _borrow_element_by_index = staticmethod(native_bt.field_class_structure_borrow_member_by_index_const)
- _borrow_element_by_name = staticmethod(native_bt.field_class_structure_borrow_member_by_name_const)
- _element_get_name = staticmethod(native_bt.field_class_structure_member_get_name)
- _element_borrow_field_class = staticmethod(native_bt.field_class_structure_member_borrow_field_class_const)
- _get_element_count = staticmethod(native_bt.field_class_structure_get_member_count)
- _append_element = staticmethod(native_bt.field_class_structure_append_member)
- def append_member(self, name, field_class):
- return self._append_element_common(name, field_class)
+class _VariantFieldClassWithSelectorOption(_VariantFieldClassOption):
+ def __init__(self, name, field_class, ranges):
+ super().__init__(name, field_class)
+ self._ranges = ranges
- def member_at_index(self, index):
- return self._at_index(index)
+ @property
+ def ranges(self):
+ return self._ranges
-class _VariantFieldClass(_FieldClass, _FieldContainer):
+class _VariantFieldClass(_FieldClass, collections.abc.Mapping):
_NAME = 'Variant'
- _borrow_element_by_index = staticmethod(native_bt.field_class_variant_borrow_option_by_index_const)
- _borrow_element_by_name = staticmethod(native_bt.field_class_variant_borrow_option_by_name_const)
- _element_get_name = staticmethod(native_bt.field_class_variant_option_get_name)
- _element_borrow_field_class = staticmethod(native_bt.field_class_variant_option_borrow_field_class_const)
- _get_element_count = staticmethod(native_bt.field_class_variant_get_option_count)
- _append_element = staticmethod(native_bt.field_class_variant_append_option)
+ _borrow_option_by_name_ptr = staticmethod(native_bt.field_class_variant_borrow_option_by_name_const)
+ _borrow_member_by_index_ptr = staticmethod(native_bt.field_class_variant_borrow_option_by_index_const)
- def append_option(self, name, field_class):
- return self._append_element_common(name, field_class)
+ @staticmethod
+ def _as_option_ptr(opt_ptr):
+ return opt_ptr
+
+ def _create_option_from_ptr(self, opt_ptr):
+ name = native_bt.field_class_variant_option_get_name(opt_ptr)
+ assert name is not None
+ fc_ptr = native_bt.field_class_variant_option_borrow_field_class_const(opt_ptr)
+ assert fc_ptr is not None
+ fc = _create_field_class_from_ptr_and_get_ref(fc_ptr)
+ return _VariantFieldClassOption(name, fc)
+
+ def __len__(self):
+ count = native_bt.field_class_variant_get_option_count(self._ptr)
+ assert count >= 0
+ return count
+
+ def __getitem__(self, key):
+ if not isinstance(key, str):
+ raise TypeError("key must be a 'str' object, got '{}'".format(key.__class__.__name__))
+
+ opt_ptr = self._borrow_option_by_name_ptr(self._ptr, key)
+
+ if opt_ptr is None:
+ raise KeyError(key)
+
+ return self._create_option_from_ptr(opt_ptr)
+
+ def __iter__(self):
+ for idx in range(len(self)):
+ opt_ptr = self._borrow_member_by_index_ptr(self._ptr, idx)
+ assert opt_ptr is not None
+ base_opt_ptr = self._as_option_ptr(opt_ptr)
+ yield native_bt.field_class_variant_option_get_name(base_opt_ptr)
def option_at_index(self, index):
- return self._at_index(index)
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ opt_ptr = self._borrow_member_by_index_ptr(self._ptr, index)
+ assert opt_ptr is not None
+ return self._create_option_from_ptr(opt_ptr)
+
+
+class _VariantFieldClassWithoutSelector(_VariantFieldClass):
+ _NAME = 'Variant (without selector)'
+
+ def append_option(self, name, field_class):
+ utils._check_str(name)
+ utils._check_type(field_class, _FieldClass)
+
+ if name in self:
+ raise bt2.Error("duplicate option name '{}'".format(name))
+
+ status = native_bt.field_class_variant_without_selector_append_option(self._ptr, name, field_class._ptr)
+ utils._handle_func_status(status,
+ 'cannot append option to variant field class object')
+
+ def __iadd__(self, options):
+ for name, field_class in options:
+ self.append_option(name, field_class)
+
+ return self
+
+
+class _VariantFieldClassWithSelector(_VariantFieldClass):
+ _NAME = 'Variant (with selector)'
+
+ def _create_option_from_ptr(self, opt_ptr):
+ base_opt_ptr = self._as_option_ptr(opt_ptr)
+ name = native_bt.field_class_variant_option_get_name(base_opt_ptr)
+ assert name is not None
+ fc_ptr = native_bt.field_class_variant_option_borrow_field_class_const(base_opt_ptr)
+ assert fc_ptr is not None
+ fc = _create_field_class_from_ptr_and_get_ref(fc_ptr)
+ range_set_ptr = self._option_borrow_ranges_ptr(opt_ptr)
+ assert range_set_ptr is not None
+ range_set = self._range_set_type._create_from_ptr_and_get_ref(range_set_ptr)
+ return _VariantFieldClassWithSelectorOption(name, fc, range_set)
@property
def selector_field_path(self):
- ptr = native_bt.field_class_variant_borrow_selector_field_path_const(self._ptr)
+ ptr = native_bt.field_class_variant_with_selector_borrow_selector_field_path_const(self._ptr)
+
if ptr is None:
return
return bt2.field_path._FieldPath._create_from_ptr_and_get_ref(ptr)
- def _set_selector_field_class(self, selector_fc):
- utils._check_type(selector_fc, bt2.field_class._EnumerationFieldClass)
- status = native_bt.field_class_variant_set_selector_field_class(self._ptr, selector_fc._ptr)
+ def append_option(self, name, field_class, ranges):
+ utils._check_str(name)
+ utils._check_type(field_class, _FieldClass)
+ utils._check_type(ranges, self._range_set_type)
+
+ if name in self:
+ raise bt2.Error("duplicate option name '{}'".format(name))
+
+ if len(ranges) == 0:
+ raise ValueError('range set is empty')
+
+ # TODO: check overlaps (precondition of self._append_option())
+
+ status = self._append_option(self._ptr, name, field_class._ptr, ranges._ptr)
utils._handle_func_status(status,
- "cannot set variant selector field type")
+ 'cannot append option to variant field class object')
+
+ def __iadd__(self, options):
+ for name, field_class, ranges in options:
+ self.append_option(name, field_class, ranges)
+
+ return self
+
+
+class _VariantFieldClassWithUnsignedSelector(_VariantFieldClassWithSelector):
+ _NAME = 'Variant (with unsigned selector)'
+ _borrow_option_by_name_ptr = staticmethod(native_bt.field_class_variant_with_unsigned_selector_borrow_option_by_name_const)
+ _borrow_member_by_index_ptr = staticmethod(native_bt.field_class_variant_with_unsigned_selector_borrow_option_by_index_const)
+ _as_option_ptr = staticmethod(native_bt.field_class_variant_with_unsigned_selector_option_as_option_const)
+ _append_option = staticmethod(native_bt.field_class_variant_with_unsigned_selector_append_option)
+ _option_borrow_ranges_ptr = staticmethod(native_bt.field_class_variant_with_unsigned_selector_option_borrow_ranges_const)
+ _range_set_type = bt2.integer_range_set.UnsignedIntegerRangeSet
+
- _selector_field_class = property(fset=_set_selector_field_class)
+class _VariantFieldClassWithSignedSelector(_VariantFieldClassWithSelector):
+ _NAME = 'Variant (with signed selector)'
+ _borrow_option_by_name_ptr = staticmethod(native_bt.field_class_variant_with_signed_selector_borrow_option_by_name_const)
+ _borrow_member_by_index_ptr = staticmethod(native_bt.field_class_variant_with_signed_selector_borrow_option_by_index_const)
+ _as_option_ptr = staticmethod(native_bt.field_class_variant_with_signed_selector_option_as_option_const)
+ _append_option = staticmethod(native_bt.field_class_variant_with_signed_selector_append_option)
+ _option_borrow_ranges_ptr = staticmethod(native_bt.field_class_variant_with_signed_selector_option_borrow_ranges_const)
+ _range_set_type = bt2.integer_range_set.SignedIntegerRangeSet
class _ArrayFieldClass(_FieldClass):
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_VARIANT: _VariantFieldClass,
+ 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,
}
}
}
-/* Output argument typemap for value output (always appends) */
-%typemap(in, numinputs=0)
- (const bt_field_class_signed_enumeration_mapping_ranges **)
- (bt_field_class_signed_enumeration_mapping_ranges *temp_value = NULL) {
- $1 = &temp_value;
-}
-
-%typemap(argout)
- (const bt_field_class_signed_enumeration_mapping_ranges **) {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result,
- SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
- SWIGTYPE_p_bt_field_class_signed_enumeration_mapping_ranges, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
-/* Output argument typemap for value output (always appends) */
-%typemap(in, numinputs=0)
- (const bt_field_class_unsigned_enumeration_mapping_ranges **)
- (bt_field_class_unsigned_enumeration_mapping_ranges *temp_value = NULL) {
- $1 = &temp_value;
-}
-
-%typemap(argout)
- (const bt_field_class_unsigned_enumeration_mapping_ranges **) {
- if (*$1) {
- /* SWIG_Python_AppendOutput() steals the created object */
- $result = SWIG_Python_AppendOutput($result,
- SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
- SWIGTYPE_p_bt_field_class_unsigned_enumeration_mapping_ranges, 0));
- } else {
- /* SWIG_Python_AppendOutput() steals Py_None */
- Py_INCREF(Py_None);
- $result = SWIG_Python_AppendOutput($result, Py_None);
- }
-}
-
%include <babeltrace2/trace-ir/field-class-const.h>
%include <babeltrace2/trace-ir/field-class.h>
import bt2
from bt2 import native_bt, utils, object
import bt2.stream_class
+import bt2.field_class
import collections.abc
import functools
return obj
def create_variant_field_class(self, selector_fc=None):
- ptr = native_bt.field_class_variant_create(self._ptr)
- self._check_create_status(ptr, 'variant')
- obj = bt2.field_class._VariantFieldClass._create_from_ptr(ptr)
+ selector_fc_ptr = None
if selector_fc is not None:
- obj._selector_field_class = selector_fc
+ utils._check_type(selector_fc, bt2.field_class._IntegerFieldClass)
+ selector_fc_ptr = selector_fc._ptr
- return obj
+ ptr = native_bt.field_class_variant_create(self._ptr, selector_fc_ptr)
+ self._check_create_status(ptr, 'variant')
+ return bt2.field_class._create_field_class_from_ptr_and_get_ref(ptr)
# Add a listener to be called when the trace class is destroyed.
return "BT_FIELD_CLASS_TYPE_STATIC_ARRAY";
case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
return "BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY";
- case BT_FIELD_CLASS_TYPE_VARIANT:
- return "BT_FIELD_CLASS_TYPE_VARIANT";
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
+ return "BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR";
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
+ return "BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR";
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
+ return "BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR";
default:
return "(unknown)";
}
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
const struct bt_field_class_variant *var_fc =
(const void *) field_class;
PRFIELD(var_fc->common.named_fcs->len));
}
- if (var_fc->selector_fc) {
- SET_TMP_PREFIX("selector-fc-");
- format_field_class(buf_ch, extended, tmp_prefix,
- var_fc->selector_fc);
- }
+ if (field_class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
+ field_class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
+ const struct bt_field_class_variant_with_selector *var_with_sel_fc =
+ (const void *) var_fc;
- if (var_fc->selector_field_path) {
- SET_TMP_PREFIX("selector-field-path-");
- format_field_path(buf_ch, extended, tmp_prefix,
- var_fc->selector_field_path);
+ if (var_with_sel_fc->selector_fc) {
+ SET_TMP_PREFIX("selector-fc-");
+ format_field_class(buf_ch, extended, tmp_prefix,
+ var_with_sel_fc->selector_fc);
+ }
+
+ if (var_with_sel_fc->selector_field_path) {
+ SET_TMP_PREFIX("selector-field-path-");
+ format_field_path(buf_ch, extended, tmp_prefix,
+ var_with_sel_fc->selector_field_path);
+ }
}
break;
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
const struct bt_field_variant *var_field = (const void *) field;
#include "field-path.h"
#include "utils.h"
#include "lib/func-status.h"
+#include "lib/integer-range-set.h"
enum bt_field_class_type bt_field_class_get_type(
const struct bt_field_class *fc)
bt_object_release_func release_func)
{
BT_ASSERT(fc);
- BT_ASSERT(bt_field_class_has_known_type(fc));
BT_ASSERT(release_func);
bt_object_init_shared(&fc->base, release_func);
fc->type = type;
if (mapping->label) {
g_string_free(mapping->label, TRUE);
+ mapping->label = NULL;
}
- if (mapping->ranges) {
- g_array_free(mapping->ranges, TRUE);
- }
+ BT_OBJECT_PUT_REF_AND_RESET(mapping->range_set);
}
static
return (const void *) BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index);
}
-const char *bt_field_class_enumeration_mapping_get_label(
- const struct bt_field_class_enumeration_mapping *mapping)
+static
+const struct bt_field_class_enumeration_mapping *
+borrow_enumeration_field_class_mapping_by_label(
+ const struct bt_field_class_enumeration *fc, const char *label)
{
- BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
- return mapping->label->str;
+ struct bt_field_class_enumeration_mapping *mapping = NULL;
+ uint64_t i;
+
+ BT_ASSERT(fc);
+ BT_ASSERT_PRE_DEV_NON_NULL(label, "Label");
+
+ for (i = 0; i < fc->mappings->len; i++) {
+ struct bt_field_class_enumeration_mapping *this_mapping =
+ BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i);
+
+ if (strcmp(this_mapping->label->str, label) == 0) {
+ mapping = this_mapping;
+ goto end;
+ }
+ }
+
+end:
+ return mapping;
}
-uint64_t bt_field_class_enumeration_mapping_get_range_count(
- const struct bt_field_class_enumeration_mapping *mapping)
+const struct bt_field_class_signed_enumeration_mapping *
+bt_field_class_signed_enumeration_borrow_mapping_by_label_const(
+ const struct bt_field_class *fc, const char *label)
{
- BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
- return (uint64_t) mapping->ranges->len;
+ BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
+ "Field class");
+ return (const void *) borrow_enumeration_field_class_mapping_by_label(
+ (const void *) fc, label);
}
-static inline
-void get_enumeration_field_class_mapping_range_at_index(
- const struct bt_field_class_enumeration_mapping *mapping,
- uint64_t index, uint64_t *lower, uint64_t *upper)
+const struct bt_field_class_unsigned_enumeration_mapping *
+bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const(
+ const struct bt_field_class *fc, const char *label)
{
- const struct bt_field_class_enumeration_mapping_range *range;
+ BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field class");
+ return (const void *) borrow_enumeration_field_class_mapping_by_label(
+ (const void *) fc, label);
+}
- BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Ranges");
- BT_ASSERT_PRE_DEV_NON_NULL(lower, "Range's lower (output)");
- BT_ASSERT_PRE_DEV_NON_NULL(upper, "Range's upper (output)");
- BT_ASSERT_PRE_DEV_VALID_INDEX(index, mapping->ranges->len);
- range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index);
- *lower = range->lower.u;
- *upper = range->upper.u;
+const char *bt_field_class_enumeration_mapping_get_label(
+ const struct bt_field_class_enumeration_mapping *mapping)
+{
+ BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
+ return mapping->label->str;
}
-void bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- const struct bt_field_class_unsigned_enumeration_mapping *ranges,
- uint64_t index, uint64_t *lower, uint64_t *upper)
+const struct bt_integer_range_set_unsigned *
+bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ const struct bt_field_class_unsigned_enumeration_mapping *u_mapping)
{
- get_enumeration_field_class_mapping_range_at_index(
- (const void *) ranges, index, lower, upper);
+ const struct bt_field_class_enumeration_mapping *mapping =
+ (const void *) u_mapping;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
+ return (const void *) mapping->range_set;
}
-void bt_field_class_signed_enumeration_mapping_get_range_by_index(
- const struct bt_field_class_signed_enumeration_mapping *ranges,
- uint64_t index, int64_t *lower, int64_t *upper)
+const struct bt_integer_range_set_signed *
+bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ const struct bt_field_class_signed_enumeration_mapping *s_mapping)
{
- get_enumeration_field_class_mapping_range_at_index(
- (const void *) ranges, index,
- (uint64_t *) lower, (uint64_t *) upper);
+ const struct bt_field_class_enumeration_mapping *mapping =
+ (const void *) s_mapping;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(mapping, "Enumeration field class mapping");
+ return (const void *) mapping->range_set;
}
enum bt_field_class_enumeration_get_mapping_labels_for_value_status
const struct bt_field_class_enumeration_mapping *mapping =
BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
- for (j = 0; j < mapping->ranges->len; j++) {
- const struct bt_field_class_enumeration_mapping_range *range =
- BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
- mapping, j);
+ for (j = 0; j < mapping->range_set->ranges->len; j++) {
+ const struct bt_integer_range *range = (const void *)
+ BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
+ mapping->range_set, j);
if (value >= range->lower.u &&
value <= range->upper.u) {
const struct bt_field_class_enumeration_mapping *mapping =
BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
- for (j = 0; j < mapping->ranges->len; j++) {
- const struct bt_field_class_enumeration_mapping_range *range =
- BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(
- mapping, j);
+ for (j = 0; j < mapping->range_set->ranges->len; j++) {
+ const struct bt_integer_range *range = (const void *)
+ BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
+ mapping->range_set, j);
if (value >= range->lower.i &&
value <= range->upper.i) {
return BT_FUNC_STATUS_OK;
}
-static inline
-enum bt_field_class_enumeration_map_range_status
-add_mapping_to_enumeration_field_class(
- struct bt_field_class *fc,
- const char *label, uint64_t lower, uint64_t upper)
+static
+bool enumeration_field_class_has_mapping_with_label(
+ const struct bt_field_class_enumeration *enum_fc,
+ const char *label)
{
- int ret = BT_FUNC_STATUS_OK;
uint64_t i;
- struct bt_field_class_enumeration *enum_fc = (void *) fc;
- struct bt_field_class_enumeration_mapping *mapping = NULL;
- struct bt_field_class_enumeration_mapping_range *range;
+ bool exists = false;
- BT_ASSERT(fc);
- BT_ASSERT_PRE_NON_NULL(label, "Label");
+ BT_ASSERT(enum_fc);
+ BT_ASSERT(label);
- /* Find existing mapping identified by this label */
for (i = 0; i < enum_fc->mappings->len; i++) {
struct bt_field_class_enumeration_mapping *mapping_candidate =
BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i);
if (strcmp(mapping_candidate->label->str, label) == 0) {
- mapping = mapping_candidate;
- break;
+ exists = true;
+ goto end;
}
}
- if (!mapping) {
- /* Create new mapping for this label */
- g_array_set_size(enum_fc->mappings, enum_fc->mappings->len + 1);
- mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc,
- enum_fc->mappings->len - 1);
- mapping->ranges = g_array_new(FALSE, TRUE,
- sizeof(struct bt_field_class_enumeration_mapping_range));
- if (!mapping->ranges) {
- finalize_enumeration_field_class_mapping(mapping);
- g_array_set_size(enum_fc->mappings,
- enum_fc->mappings->len - 1);
- ret = BT_FUNC_STATUS_MEMORY_ERROR;
- goto end;
- }
+end:
+ return exists;
+}
- mapping->label = g_string_new(label);
- if (!mapping->label) {
- finalize_enumeration_field_class_mapping(mapping);
- g_array_set_size(enum_fc->mappings,
- enum_fc->mappings->len - 1);
- ret = BT_FUNC_STATUS_MEMORY_ERROR;
- goto end;
- }
+static inline
+enum bt_field_class_enumeration_add_mapping_status
+add_mapping_to_enumeration_field_class(struct bt_field_class *fc,
+ const char *label, const struct bt_integer_range_set *range_set)
+{
+ enum bt_field_class_enumeration_add_mapping_status status =
+ BT_FUNC_STATUS_OK;
+ struct bt_field_class_enumeration *enum_fc = (void *) fc;
+ struct bt_field_class_enumeration_mapping mapping = { 0 };
+
+ BT_ASSERT(fc);
+ BT_ASSERT_PRE_NON_NULL(label, "Label");
+ BT_ASSERT_PRE_NON_NULL(range_set, "Range set");
+ BT_ASSERT_PRE(!enumeration_field_class_has_mapping_with_label(
+ enum_fc, label),
+ "Duplicate mapping name in enumeration field class: "
+ "%![enum-fc-]+F, label=\"%s\"", fc, label);
+ mapping.range_set = range_set;
+ bt_object_get_ref(mapping.range_set);
+ mapping.label = g_string_new(label);
+ if (!mapping.label) {
+ finalize_enumeration_field_class_mapping(&mapping);
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
+ goto end;
}
- /* Add range */
- BT_ASSERT(mapping);
- g_array_set_size(mapping->ranges, mapping->ranges->len + 1);
- range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping,
- mapping->ranges->len - 1);
- range->lower.u = lower;
- range->upper.u = upper;
+ g_array_append_val(enum_fc->mappings, mapping);
BT_LIB_LOGD("Added mapping to enumeration field class: "
- "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", "
- "upper-unsigned=%" PRIu64, fc, label, lower, upper);
+ "%![fc-]+F, label=\"%s\"", fc, label);
end:
- return ret;
+ return status;
}
-enum bt_field_class_enumeration_map_range_status
-bt_field_class_unsigned_enumeration_map_range(
+enum bt_field_class_enumeration_add_mapping_status
+bt_field_class_unsigned_enumeration_add_mapping(
struct bt_field_class *fc, const char *label,
- uint64_t range_lower, uint64_t range_upper)
+ const struct bt_integer_range_set_unsigned *range_set)
{
- struct bt_field_class_enumeration *enum_fc = (void *) fc;
-
BT_ASSERT_PRE_NON_NULL(fc, "Field class");
BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION,
"Field class");
- BT_ASSERT_PRE(range_lower <= range_upper,
- "Range's upper bound is less than lower bound: "
- "upper=%" PRIu64 ", lower=%" PRIu64,
- range_lower, range_upper);
- BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range,
- range_lower),
- "Range's lower bound is outside the enumeration field class's value range: "
- "%![fc-]+F, lower=%" PRIu64, fc, range_lower);
- BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range,
- range_upper),
- "Range's upper bound is outside the enumeration field class's value range: "
- "%![fc-]+F, upper=%" PRIu64, fc, range_upper);
- return add_mapping_to_enumeration_field_class(fc, label, range_lower,
- range_upper);
-}
-
-enum bt_field_class_enumeration_map_range_status
-bt_field_class_signed_enumeration_map_range(
+ return add_mapping_to_enumeration_field_class(fc, label,
+ (const void *) range_set);
+}
+
+enum bt_field_class_enumeration_add_mapping_status
+bt_field_class_signed_enumeration_add_mapping(
struct bt_field_class *fc, const char *label,
- int64_t range_lower, int64_t range_upper)
+ const struct bt_integer_range_set_signed *range_set)
{
- struct bt_field_class_enumeration *enum_fc = (void *) fc;
-
BT_ASSERT_PRE_NON_NULL(fc, "Field class");
BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION,
"Field class");
- BT_ASSERT_PRE(range_lower <= range_upper,
- "Range's upper bound is less than lower bound: "
- "upper=%" PRId64 ", lower=%" PRId64,
- range_lower, range_upper);
- BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range,
- range_lower),
- "Range's lower bound is outside the enumeration field class's value range: "
- "%![fc-]+F, lower=%" PRId64, fc, range_lower);
- BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range,
- range_upper),
- "Range's upper bound is outside the enumeration field class's value range: "
- "%![fc-]+F, upper=%" PRId64, fc, range_upper);
- return add_mapping_to_enumeration_field_class(fc, label, range_lower,
- range_upper);
+ return add_mapping_to_enumeration_field_class(fc, label,
+ (const void *) range_set);
}
static
int init_named_field_classes_container(
struct bt_field_class_named_field_class_container *fc,
enum bt_field_class_type type,
- bt_object_release_func release_func)
+ bt_object_release_func fc_release_func,
+ GDestroyNotify named_fc_destroy_func)
{
int ret = 0;
- init_field_class((void *) fc, type, release_func);
- fc->named_fcs = g_array_new(FALSE, TRUE,
- sizeof(struct bt_named_field_class));
+ init_field_class((void *) fc, type, fc_release_func);
+ fc->named_fcs = g_ptr_array_new_with_free_func(named_fc_destroy_func);
if (!fc->named_fcs) {
- BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GArray.");
+ BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
ret = -1;
goto end;
}
if (named_fc->name) {
g_string_free(named_fc->name, TRUE);
+ named_fc->name = NULL;
}
BT_LOGD_STR("Putting named field class's field class.");
BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc);
}
+static
+void destroy_named_field_class(gpointer ptr)
+{
+ if (ptr) {
+ finalize_named_field_class(ptr);
+ g_free(ptr);
+ }
+}
+
+static
+void destroy_variant_with_selector_option(gpointer ptr)
+{
+ struct bt_field_class_variant_with_selector_option *opt = ptr;
+
+ if (ptr) {
+ finalize_named_field_class(&opt->common);
+ BT_OBJECT_PUT_REF_AND_RESET(opt->range_set);
+ g_free(ptr);
+ }
+}
+
static
void finalize_named_field_classes_container(
struct bt_field_class_named_field_class_container *fc)
{
- uint64_t i;
-
BT_ASSERT(fc);
if (fc->named_fcs) {
- for (i = 0; i < fc->named_fcs->len; i++) {
- finalize_named_field_class(
- &g_array_index(fc->named_fcs,
- struct bt_named_field_class, i));
- }
+ g_ptr_array_free(fc->named_fcs, TRUE);
+ fc->named_fcs = NULL;
- g_array_free(fc->named_fcs, TRUE);
}
if (fc->name_to_index) {
g_hash_table_destroy(fc->name_to_index);
+ fc->name_to_index = NULL;
}
}
}
ret = init_named_field_classes_container((void *) struct_fc,
- BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class);
+ BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class,
+ destroy_named_field_class);
if (ret) {
+ /* init_named_field_classes_container() logs errors */
goto error;
}
}
static
-int append_named_field_class_to_container_field_class(
- struct bt_field_class_named_field_class_container *container_fc,
+int init_named_field_class(struct bt_named_field_class *named_fc,
const char *name, struct bt_field_class *fc)
{
- int ret = BT_FUNC_STATUS_OK;
- struct bt_named_field_class *named_fc;
- GString *name_str;
+ int status = BT_FUNC_STATUS_OK;
- BT_ASSERT(container_fc);
- BT_ASSERT_PRE_DEV_FC_HOT(container_fc, "Field class");
- BT_ASSERT_PRE_NON_NULL(name, "Name");
- BT_ASSERT_PRE_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc->name_to_index,
- name),
- "Duplicate member/option name in structure/variant field class: "
- "%![container-fc-]+F, name=\"%s\"", container_fc, name);
- name_str = g_string_new(name);
- if (!name_str) {
+ 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.");
- ret = BT_FUNC_STATUS_MEMORY_ERROR;
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
goto end;
}
- g_array_set_size(container_fc->named_fcs,
- container_fc->named_fcs->len + 1);
- named_fc = &g_array_index(container_fc->named_fcs,
- struct bt_named_field_class, container_fc->named_fcs->len - 1);
- named_fc->name = name_str;
named_fc->fc = fc;
- bt_object_get_no_null_check(fc);
- g_hash_table_insert(container_fc->name_to_index, named_fc->name->str,
- GUINT_TO_POINTER(container_fc->named_fcs->len - 1));
+ bt_object_get_no_null_check(named_fc->fc);
+ bt_named_field_class_freeze(named_fc);
- /*
- * Freeze the field class, but not the named field class (the
- * user can still modify it, if possible, until the container
- * itself is frozen).
- */
- bt_field_class_freeze(fc);
+end:
+ return status;
+}
+
+static
+struct bt_named_field_class *create_named_field_class(const char *name,
+ struct bt_field_class *fc)
+{
+ struct bt_named_field_class *named_fc = g_new0(
+ struct bt_named_field_class, 1);
+
+ if (!named_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate a named field class.");
+ goto error;
+ }
+
+ if (init_named_field_class(named_fc, name, fc)) {
+ /* init_named_field_class() logs errors */
+ goto error;
+ }
+
+ goto end;
+
+error:
+ destroy_named_field_class(named_fc);
+ named_fc = NULL;
end:
- return ret;
+ return named_fc;
+}
+
+static
+struct bt_field_class_variant_with_selector_option *
+create_variant_with_selector_option(
+ const char *name, struct bt_field_class *fc,
+ const struct bt_integer_range_set *range_set)
+{
+ struct bt_field_class_variant_with_selector_option *opt = g_new0(
+ struct bt_field_class_variant_with_selector_option, 1);
+
+ BT_ASSERT(range_set);
+
+ if (!opt) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate a named field class.");
+ goto error;
+ }
+
+ if (init_named_field_class(&opt->common, name, fc)) {
+ goto error;
+ }
+
+ opt->range_set = range_set;
+ bt_object_get_no_null_check(opt->range_set);
+ bt_integer_range_set_freeze(range_set);
+ goto end;
+
+error:
+ destroy_variant_with_selector_option(opt);
+ opt = NULL;
+
+end:
+ return opt;
+}
+
+static
+int append_named_field_class_to_container_field_class(
+ struct bt_field_class_named_field_class_container *container_fc,
+ struct bt_named_field_class *named_fc)
+{
+ BT_ASSERT(container_fc);
+ BT_ASSERT(named_fc);
+ BT_ASSERT_PRE_DEV_FC_HOT(container_fc, "Field class");
+ BT_ASSERT_PRE(!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);
+ 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));
+ return BT_FUNC_STATUS_OK;
}
enum bt_field_class_structure_append_member_status
struct bt_field_class *fc, const char *name,
struct bt_field_class *member_fc)
{
+ enum bt_field_class_structure_append_member_status status;
+ struct bt_named_field_class *named_fc = NULL;
BT_ASSERT_PRE_NON_NULL(fc, "Field class");
BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE,
"Field class");
- return append_named_field_class_to_container_field_class((void *) fc,
- name, member_fc);
+ named_fc = create_named_field_class(name, member_fc);
+ if (!named_fc) {
+ /* create_named_field_class() logs errors */
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
+ goto end;
+ }
+
+ status = append_named_field_class_to_container_field_class((void *) fc,
+ named_fc);
+ if (status == BT_FUNC_STATUS_OK) {
+ /* Moved to the container */
+ named_fc = NULL;
+ }
+
+end:
+ return status;
}
uint64_t bt_field_class_structure_get_member_count(
{
BT_ASSERT(fc);
BT_ASSERT_PRE_DEV_VALID_INDEX(index, fc->named_fcs->len);
- return BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, index);
+ return fc->named_fcs->pdata[index];
}
const struct bt_field_class_structure_member *
goto end;
}
- named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc,
- GPOINTER_TO_UINT(value));
+ named_fc = fc->named_fcs->pdata[GPOINTER_TO_UINT(value)];
end:
return named_fc;
return named_fc->fc;
}
-struct bt_field_class *
-bt_field_class_structure_member_borrow_field_class(
- struct bt_field_class_structure_member *member)
+static
+void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
{
- struct bt_named_field_class *named_fc = (void *) member;
-
- BT_ASSERT_PRE_DEV_NON_NULL(member, "Structure field class member");
- return named_fc->fc;
+ BT_ASSERT(var_fc);
+ BT_LIB_LOGD("Finalizing variant field class object: %!+F", var_fc);
+ finalize_named_field_classes_container((void *) var_fc);
}
static
struct bt_field_class_variant *fc = (void *) obj;
BT_ASSERT(fc);
- BT_LIB_LOGD("Destroying variant field class object: %!+F", fc);
- finalize_named_field_classes_container((void *) fc);
+ finalize_variant_field_class(fc);
+ g_free(fc);
+}
+
+static
+void destroy_variant_with_selector_field_class(struct bt_object *obj)
+{
+ struct bt_field_class_variant_with_selector *fc = (void *) obj;
+
+ BT_ASSERT(fc);
+ finalize_variant_field_class(&fc->common);
BT_LOGD_STR("Putting selector field path.");
BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path);
BT_LOGD_STR("Putting selector field class.");
}
struct bt_field_class *bt_field_class_variant_create(
- bt_trace_class *trace_class)
+ bt_trace_class *trace_class, bt_field_class *selector_fc)
{
int ret;
struct bt_field_class_variant *var_fc = NULL;
+ struct bt_field_class_variant_with_selector *var_with_sel_fc = NULL;
+ enum bt_field_class_type fc_type;
BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
- BT_LOGD_STR("Creating default variant field class object.");
- var_fc = g_new0(struct bt_field_class_variant, 1);
- if (!var_fc) {
- BT_LIB_LOGE_APPEND_CAUSE(
- "Failed to allocate one variant field class.");
- goto error;
+
+ if (selector_fc) {
+ BT_ASSERT_PRE_FC_IS_INT(selector_fc, "Selector field class");
}
- ret = init_named_field_classes_container((void *) var_fc,
- BT_FIELD_CLASS_TYPE_VARIANT, destroy_variant_field_class);
- if (ret) {
- goto error;
+ BT_LIB_LOGD("Creating default variant field class: %![sel-fc-]+F",
+ selector_fc);
+
+ if (selector_fc) {
+ var_with_sel_fc = g_new0(
+ struct bt_field_class_variant_with_selector, 1);
+ if (!var_with_sel_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one variant field class with selector.");
+ goto error;
+ }
+
+ if (selector_fc->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
+ selector_fc->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
+ fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR;
+ } else {
+ fc_type = BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR;
+ }
+
+ ret = init_named_field_classes_container(
+ (void *) var_with_sel_fc, fc_type,
+ destroy_variant_with_selector_field_class,
+ destroy_variant_with_selector_option);
+ if (ret) {
+ /* init_named_field_classes_container() logs errors */
+ goto error;
+ }
+
+ var_with_sel_fc->selector_fc = selector_fc;
+ bt_object_get_no_null_check(var_with_sel_fc->selector_fc);
+ bt_field_class_freeze(selector_fc);
+ var_fc = (void *) var_with_sel_fc;
+ } else {
+ var_fc = g_new0(struct bt_field_class_variant, 1);
+ if (!var_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one variant field class without selector.");
+ goto error;
+ }
+
+ ret = init_named_field_classes_container((void *) var_fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR,
+ destroy_variant_field_class, destroy_named_field_class);
+ if (ret) {
+ /* init_named_field_classes_container() logs errors */
+ goto error;
+ }
}
- BT_LIB_LOGD("Created variant field class object: %!+F", var_fc);
+ BT_ASSERT(var_fc);
+ BT_LIB_LOGD("Created default variant field class with selector object: "
+ "%![var-fc-]+F, %![sel-fc-]+F", var_fc, selector_fc);
goto end;
error:
return (void *) var_fc;
}
-enum bt_field_class_variant_set_selector_field_class_status
-bt_field_class_variant_set_selector_field_class(
- struct bt_field_class *fc,
- struct bt_field_class *selector_fc)
-{
- struct bt_field_class_variant *var_fc = (void *) fc;
-
- BT_ASSERT_PRE_NON_NULL(fc, "Variant field class");
- BT_ASSERT_PRE_NON_NULL(selector_fc, "Selector field class");
- BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
- BT_ASSERT_PRE_FC_IS_ENUM(selector_fc, "Selector field class");
- BT_ASSERT_PRE_DEV_FC_HOT(fc, "Variant field class");
- var_fc->selector_fc = selector_fc;
- bt_object_get_no_null_check(selector_fc);
- bt_field_class_freeze(selector_fc);
- return BT_FUNC_STATUS_OK;
+enum bt_field_class_variant_without_selector_append_option_status
+bt_field_class_variant_without_selector_append_option(struct bt_field_class *fc,
+ const char *name, struct bt_field_class *option_fc)
+{
+ enum bt_field_class_variant_without_selector_append_option_status status;
+ struct bt_named_field_class *named_fc = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(option_fc, "Option field class");
+ BT_ASSERT_PRE_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR, "Field class");
+ named_fc = create_named_field_class(name, option_fc);
+ if (!named_fc) {
+ /* create_named_field_class() logs errors */
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
+ goto end;
+ }
+
+ status = append_named_field_class_to_container_field_class((void *) fc,
+ named_fc);
+ if (status == BT_FUNC_STATUS_OK) {
+ /* Moved to the container */
+ named_fc = NULL;
+ }
+
+end:
+ if (named_fc) {
+ destroy_named_field_class(named_fc);
+ }
+
+ return status;
}
-enum bt_field_class_variant_append_option_status
-bt_field_class_variant_append_option(
- struct bt_field_class *fc,
- const char *name, struct bt_field_class *option_fc)
+static
+int ranges_overlap(GPtrArray *var_fc_opts, const struct bt_integer_range_set *range_set,
+ bool is_signed, bool *has_overlap)
+{
+ int status = BT_FUNC_STATUS_OK;
+ struct bt_integer_range_set *full_range_set;
+ uint64_t i;
+
+ *has_overlap = false;
+
+ /*
+ * Build a single range set with all the ranges and test for
+ * overlaps.
+ */
+ if (is_signed) {
+ full_range_set = (void *) bt_integer_range_set_signed_create();
+ } else {
+ full_range_set = (void *) bt_integer_range_set_unsigned_create();
+ }
+
+ if (!full_range_set) {
+ BT_LOGE_STR("Failed to create a range set.");
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
+ goto end;
+ }
+
+ /* Add existing option ranges */
+ for (i = 0; i < var_fc_opts->len; i++) {
+ struct bt_field_class_variant_with_selector_option *opt =
+ var_fc_opts->pdata[i];
+ uint64_t j;
+
+ for (j = 0; j < opt->range_set->ranges->len; j++) {
+ struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
+ opt->range_set, j);
+
+ if (is_signed) {
+ status = bt_integer_range_set_signed_add_range(
+ (void *) full_range_set, range->lower.i,
+ range->upper.i);
+ } else {
+ status = bt_integer_range_set_unsigned_add_range(
+ (void *) full_range_set, range->lower.u,
+ range->upper.u);
+ }
+
+ if (status) {
+ goto end;
+ }
+ }
+ }
+
+ /* Add new ranges */
+ for (i = 0; i < range_set->ranges->len; i++) {
+ struct bt_integer_range *range = BT_INTEGER_RANGE_SET_RANGE_AT_INDEX(
+ range_set, i);
+
+ if (is_signed) {
+ status = bt_integer_range_set_signed_add_range(
+ (void *) full_range_set, range->lower.i,
+ range->upper.i);
+ } else {
+ status = bt_integer_range_set_unsigned_add_range(
+ (void *) full_range_set, range->lower.u,
+ range->upper.u);
+ }
+
+ if (status) {
+ goto end;
+ }
+ }
+
+ /* Check overlaps */
+ if (is_signed) {
+ *has_overlap = bt_integer_range_set_signed_has_overlaps(full_range_set);
+ } else {
+ *has_overlap = bt_integer_range_set_unsigned_has_overlaps(
+ full_range_set);
+ }
+
+end:
+ bt_object_put_ref(full_range_set);
+ return status;
+}
+
+static
+int append_option_to_variant_with_selector_field_class(
+ struct bt_field_class *fc, const char *name,
+ struct bt_field_class *option_fc,
+ const struct bt_integer_range_set *range_set,
+ enum bt_field_class_type expected_type)
{
+ int status;
+ struct bt_field_class_variant_with_selector *var_fc = (void *) fc;
+ struct bt_field_class_variant_with_selector_option *opt = NULL;
+ bool has_overlap;
BT_ASSERT_PRE_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
- return append_named_field_class_to_container_field_class((void *) fc,
- name, option_fc);
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE_NON_NULL(option_fc, "Option field class");
+ BT_ASSERT_PRE_NON_NULL(range_set, "Range set");
+ BT_ASSERT_PRE_FC_HAS_ID(fc, expected_type, "Field class");
+ BT_ASSERT_PRE(range_set->ranges->len > 0,
+ "Range set is empty: addr=%p", range_set);
+ status = ranges_overlap(var_fc->common.common.named_fcs, range_set,
+ expected_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
+ &has_overlap);
+ if (status) {
+ /* ranges_overlap() logs errors */
+ goto end;
+ }
+
+ BT_ASSERT_PRE(!has_overlap,
+ "Range set's ranges and existing ranges have an overlap: "
+ "addr=%p", range_set);
+ opt = create_variant_with_selector_option(name, option_fc, range_set);
+ if (!opt) {
+ /* create_variant_with_selector_option() logs errors */
+ status = BT_FUNC_STATUS_MEMORY_ERROR;
+ goto end;
+ }
+
+ status = append_named_field_class_to_container_field_class((void *) fc,
+ &opt->common);
+ if (status == BT_FUNC_STATUS_OK) {
+ /* Moved to the container */
+ opt = NULL;
+ }
+
+end:
+ if (opt) {
+ destroy_variant_with_selector_option(opt);
+ }
+
+ return status;
+}
+
+enum bt_field_class_variant_with_selector_append_option_status
+bt_field_class_variant_with_unsigned_selector_append_option(
+ struct bt_field_class *fc, const char *name,
+ struct bt_field_class *option_fc,
+ const struct bt_integer_range_set_unsigned *range_set)
+{
+ return append_option_to_variant_with_selector_field_class(fc,
+ name, option_fc, (const void *) range_set,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR);
+}
+
+enum bt_field_class_variant_with_selector_append_option_status
+bt_field_class_variant_with_signed_selector_append_option(
+ struct bt_field_class *fc, const char *name,
+ struct bt_field_class *option_fc,
+ const struct bt_integer_range_set_signed *range_set)
+{
+ return append_option_to_variant_with_selector_field_class(fc,
+ name, option_fc, (const void *) range_set,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR);
+}
+
+uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
+{
+ const struct bt_field_class_variant *var_fc = (const void *) fc;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
+ return (uint64_t) var_fc->common.named_fcs->len;
}
const struct bt_field_class_variant_option *
const struct bt_field_class *fc, const char *name)
{
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT,
- "Field class");
+ BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
return (const void *)
borrow_named_field_class_from_container_field_class_by_name(
(void *) fc, name);
}
-struct bt_field_class_variant_option *
-bt_field_class_variant_borrow_option_by_name(
- struct bt_field_class *fc, const char *name)
+const struct bt_field_class_variant_option *
+bt_field_class_variant_borrow_option_by_index_const(
+ const struct bt_field_class *fc, uint64_t index)
{
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
- return (void *)
- borrow_named_field_class_from_container_field_class_by_name(
- (void *) fc, name);
+ BT_ASSERT_PRE_DEV_FC_IS_VARIANT(fc, "Field class");
+ return (const void *)
+ borrow_named_field_class_from_container_field_class_at_index(
+ (void *) fc, index);
}
-uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc)
+const struct bt_field_class_variant_with_unsigned_selector_option *
+bt_field_class_variant_with_unsigned_selector_borrow_option_by_name_const(
+ const struct bt_field_class *fc, const char *name)
{
- const struct bt_field_class_variant *var_fc = (const void *) fc;
-
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
- return (uint64_t) var_fc->common.named_fcs->len;
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
+ "Field class");
+ return (const void *)
+ borrow_named_field_class_from_container_field_class_by_name(
+ (void *) fc, name);
}
-const struct bt_field_class_variant_option *
-bt_field_class_variant_borrow_option_by_index_const(
+const struct bt_field_class_variant_with_unsigned_selector_option *
+bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
const struct bt_field_class *fc, uint64_t index)
{
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
+ "Field class");
return (const void *)
borrow_named_field_class_from_container_field_class_at_index(
(void *) fc, index);
}
-struct bt_field_class_variant_option *
-bt_field_class_variant_borrow_option_by_index(
- struct bt_field_class *fc, uint64_t index)
+const struct bt_field_class_variant_with_signed_selector_option *
+bt_field_class_variant_with_signed_selector_borrow_option_by_name_const(
+ const struct bt_field_class *fc, const char *name)
{
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class");
- return (void *)
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
+ "Field class");
+ return (const void *)
+ borrow_named_field_class_from_container_field_class_by_name(
+ (void *) fc, name);
+}
+
+const struct bt_field_class_variant_with_signed_selector_option *
+bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ const struct bt_field_class *fc, uint64_t index)
+{
+ BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
+ "Field class");
+ return (const void *)
borrow_named_field_class_from_container_field_class_at_index(
(void *) fc, index);
}
return named_fc->fc;
}
-struct bt_field_class *
-bt_field_class_variant_option_borrow_field_class(
- struct bt_field_class_variant_option *option)
+const struct bt_integer_range_set_unsigned *
+bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ const struct bt_field_class_variant_with_unsigned_selector_option *option)
{
- struct bt_named_field_class *named_fc = (void *) option;
+ const struct bt_field_class_variant_with_selector_option *opt =
+ (const void *) option;
BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
- return named_fc->fc;
+ return (const void *) opt->range_set;
+}
+
+const struct bt_integer_range_set_signed *
+bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ const struct bt_field_class_variant_with_signed_selector_option *option)
+{
+ const struct bt_field_class_variant_with_selector_option *opt =
+ (const void *) option;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(option, "Variant field class option");
+ return (const void *) opt->range_set;
}
const struct bt_field_path *
-bt_field_class_variant_borrow_selector_field_path_const(
+bt_field_class_variant_with_selector_borrow_selector_field_path_const(
const struct bt_field_class *fc)
{
- const struct bt_field_class_variant *var_fc = (const void *) fc;
+ const struct bt_field_class_variant_with_selector *var_fc =
+ (const void *) fc;
BT_ASSERT_PRE_DEV_NON_NULL(fc, "Field class");
- BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT,
- "Field class");
+ BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(fc, "Field class");
return var_fc->selector_field_path;
}
BT_ASSERT(element_fc);
init_field_class((void *) fc, type, release_func);
fc->element_fc = element_fc;
- bt_object_get_no_null_check(element_fc);
+ bt_object_get_no_null_check(fc->element_fc);
bt_field_class_freeze(element_fc);
}
BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc, "Length field class");
BT_ASSERT_PRE_DEV_FC_HOT(fc, "Dynamic array field class");
array_fc->length_fc = length_fc;
- bt_object_get_no_null_check(length_fc);
+ bt_object_get_no_null_check(array_fc->length_fc);
bt_field_class_freeze(length_fc);
return BT_FUNC_STATUS_OK;
}
switch (fc->type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
struct bt_field_class_named_field_class_container *container_fc =
(void *) fc;
uint64_t i;
for (i = 0; i < container_fc->named_fcs->len; i++) {
- struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
- container_fc, i);
-
- bt_named_field_class_freeze(named_fc);
+ bt_named_field_class_freeze(
+ container_fc->named_fcs->pdata[i]);
}
break;
switch (fc->type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
struct bt_field_class_named_field_class_container *container_fc =
(void *) fc;
for (i = 0; i < container_fc->named_fcs->len; i++) {
struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
- container_fc, i);
+ container_fc->named_fcs->pdata[i];
bt_field_class_make_part_of_trace_class(named_fc->fc);
}
#include <babeltrace2/trace-ir/clock-class.h>
#include <babeltrace2/trace-ir/field-class.h>
#include "common/macros.h"
+#include "common/common.h"
#include "lib/object.h"
#include <babeltrace2/types.h>
#include <stdint.h>
#define _BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_FMT(_name) \
_name " is not an unsigned integer field class: %![fc-]+F"
+
+#define _BT_ASSERT_PRE_FC_IS_SIGNED_INT_COND(_fc) \
+ (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || \
+ ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION)
+
+#define _BT_ASSERT_PRE_FC_IS_SIGNED_INT_FMT(_name) \
+ _name " is not a signed integer field class: %![fc-]+F"
+
#define _BT_ASSERT_PRE_FC_IS_ENUM_COND(_fc) \
(((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION || \
((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION)
#define _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name) \
_name " is not an array field class: %![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 || \
+ ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR)
+
+#define _BT_ASSERT_PRE_FC_IS_VARIANT_FMT(_name) \
+ _name " is not a variant field class: %![fc-]+F"
+
+#define _BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_COND(_fc) \
+ (((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR || \
+ ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR)
+
+#define _BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_FMT(_name) \
+ _name " is not a variant field class with a selector: %![fc-]+F"
+
#define _BT_ASSERT_PRE_FC_HAS_ID_COND(_fc, _type) \
(((const struct bt_field_class *) (_fc))->type == (_type))
#define BT_ASSERT_PRE_FC_IS_INT(_fc, _name) \
BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_INT_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_INT_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_INT_FMT(_name), (_fc))
#define BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(_fc, _name) \
BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_FC_IS_SIGNED_INT(_fc, _name) \
+ BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_SIGNED_INT_COND(_fc), \
+ _BT_ASSERT_PRE_FC_IS_SIGNED_INT_FMT(_name), (_fc))
#define BT_ASSERT_PRE_FC_IS_ENUM(_fc, _name) \
BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_ENUM_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_ENUM_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_ENUM_FMT(_name), (_fc))
#define BT_ASSERT_PRE_FC_IS_ARRAY(_fc, _name) \
BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_ARRAY_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_ARRAY_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))
+
+#define BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL(_fc, _name) \
+ BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_COND(_fc), \
+ _BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_FMT(_name), (_fc))
#define BT_ASSERT_PRE_FC_HAS_ID(_fc, _type, _name) \
BT_ASSERT_PRE(_BT_ASSERT_PRE_FC_HAS_ID_COND((_fc), (_type)), \
- _BT_ASSERT_PRE_FC_HAS_ID_FMT(_name), \
- bt_common_field_class_type_string(_type), (_fc))
+ _BT_ASSERT_PRE_FC_HAS_ID_FMT(_name), \
+ bt_common_field_class_type_string(_type), (_fc))
#define BT_ASSERT_PRE_DEV_FC_IS_INT(_fc, _name) \
BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_INT_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_INT_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_INT_FMT(_name), (_fc))
#define BT_ASSERT_PRE_DEV_FC_IS_UNSIGNED_INT(_fc, _name) \
BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_UNSIGNED_INT_FMT(_name), (_fc))
+
+#define BT_ASSERT_PRE_DEV_FC_IS_SIGNED_INT(_fc, _name) \
+ BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_SIGNED_INT_COND(_fc), \
+ _BT_ASSERT_PRE_FC_IS_SIGNED_INT_FMT(_name), (_fc))
#define BT_ASSERT_PRE_DEV_FC_IS_ENUM(_fc, _name) \
BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_ENUM_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_ENUM_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_ENUM_FMT(_name), (_fc))
#define BT_ASSERT_PRE_DEV_FC_IS_ARRAY(_fc, _name) \
BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_ARRAY_COND(_fc), \
- _BT_ASSERT_PRE_FC_IS_ARRAY_FMT(_name), (_fc))
+ _BT_ASSERT_PRE_FC_IS_ARRAY_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))
+
+#define BT_ASSERT_PRE_DEV_FC_IS_VARIANT_WITH_SEL(_fc, _name) \
+ BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_COND(_fc), \
+ _BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_FMT(_name), (_fc))
#define BT_ASSERT_PRE_DEV_FC_HAS_ID(_fc, _type, _name) \
BT_ASSERT_PRE_DEV(_BT_ASSERT_PRE_FC_HAS_ID_COND((_fc), (_type)), \
- _BT_ASSERT_PRE_FC_HAS_ID_FMT(_name), \
- bt_common_field_class_type_string(_type), (_fc))
+ _BT_ASSERT_PRE_FC_HAS_ID_FMT(_name), \
+ bt_common_field_class_type_string(_type), (_fc))
#define BT_ASSERT_PRE_DEV_FC_HOT(_fc, _name) \
BT_ASSERT_PRE_DEV_HOT((const struct bt_field_class *) (_fc), \
(_name), ": %!+F", (_fc))
-#define BT_FIELD_CLASS_NAMED_FC_AT_INDEX(_fc, _index) \
- (&g_array_index(((struct bt_field_class_named_field_class_container *) (_fc))->named_fcs, \
- struct bt_named_field_class, (_index)))
-
#define BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(_fc, _index) \
(&g_array_index(((struct bt_field_class_enumeration *) (_fc))->mappings, \
struct bt_field_class_enumeration_mapping, (_index)))
enum bt_field_class_integer_preferred_display_base base;
};
-struct bt_field_class_enumeration_mapping_range {
- union {
- uint64_t u;
- int64_t i;
- } lower;
-
- union {
- uint64_t u;
- int64_t i;
- } upper;
-};
-
struct bt_field_class_enumeration_mapping {
GString *label;
- /* Array of `struct bt_field_class_enumeration_mapping_range` */
- GArray *ranges;
+ /* Owner by this */
+ const struct bt_integer_range_set *range_set;
};
struct bt_field_class_unsigned_enumeration_mapping;
struct bt_field_class_structure_member;
struct bt_field_class_variant_option;
+struct bt_field_class_variant_with_unsigned_selector_option;
+struct bt_field_class_variant_with_signed_selector_option;
-/*
- * This is the base field class for a container of named field classes.
- * Structure and variant field classes inherit this.
- */
struct bt_field_class_named_field_class_container {
struct bt_field_class common;
/*
* Key: `const char *`, not owned by this (owned by named field
- * type objects contained in `named_fcs` below).
+ * class objects contained in `named_fcs` below).
*/
GHashTable *name_to_index;
- /* Array of `struct bt_named_field_class` */
- GArray *named_fcs;
+ /* Array of `struct bt_named_field_class *` */
+ GPtrArray *named_fcs;
};
struct bt_field_class_structure {
struct bt_field_path *length_field_path;
};
+/* Variant FC (with selector) option: named field class + range set */
+struct bt_field_class_variant_with_selector_option {
+ struct bt_named_field_class common;
+
+ /* Owned by this */
+ const struct bt_integer_range_set *range_set;
+};
+
struct bt_field_class_variant {
+ /*
+ * Depending on the variant field class type, the contained
+ * named field classes are of type
+ * `struct bt_named_field_class *` if the variant field class
+ * doesn't have a selector, or
+ * `struct bt_field_class_variant_with_selector_option *`
+ * if it has.
+ */
struct bt_field_class_named_field_class_container common;
+};
- /* Weak: never dereferenced, only use to find it elsewhere */
- struct bt_field_class *selector_fc;
+struct bt_field_class_variant_with_selector {
+ struct bt_field_class_variant common;
+
+ /*
+ * Owned by this, but never dereferenced: only use to find it
+ * elsewhere.
+ */
+ const struct bt_field_class *selector_fc;
/* Owned by this */
struct bt_field_path *selector_field_path;
};
-static inline
-bool bt_field_class_has_known_type(const struct bt_field_class *fc)
-{
- return fc->type >= BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER &&
- fc->type <= BT_FIELD_CLASS_TYPE_VARIANT;
-}
-
BT_HIDDEN
void _bt_field_class_freeze(const struct bt_field_class *field_class);
static
struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = {
- [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_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_VARIANT] = create_variant_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_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_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
static
void (* const field_destroy_funcs[])(struct bt_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_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_VARIANT] = destroy_variant_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_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_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(const struct bt_field *field)
struct bt_field *field = NULL;
BT_ASSERT(fc);
- BT_ASSERT(bt_field_class_has_known_type(fc));
field = field_create_funcs[fc->type](fc);
if (!field) {
BT_LIB_LOGE_APPEND_CAUSE("Cannot create field object from field class: "
for (i = 0; i < fc->named_fcs->len; i++) {
struct bt_field *field;
- struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, i);
+ struct bt_named_field_class *named_fc = fc->named_fcs->pdata[i];
field = bt_field_create(named_fc->fc);
if (!field) {
struct bt_field_variant *var_field = (void *) field;
BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
- BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
- BT_FIELD_CLASS_TYPE_VARIANT, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
BT_ASSERT_PRE_DEV(var_field->selected_field,
"Variant field has no selected field: %!+f", field);
return var_field->selected_field;
return borrow_variant_field_selected_option_field((void *) field);
}
-enum bt_field_variant_select_option_field_status
-bt_field_variant_select_option_field(
+static
+const struct bt_field_class_variant_option *
+borrow_variant_field_selected_class_option(const struct bt_field *field)
+{
+ const struct bt_field_class_named_field_class_container *container_fc;
+ const struct bt_field_variant *var_field = (const void *) field;
+
+ BT_ASSERT(field);
+ BT_ASSERT_PRE_DEV(var_field->selected_field,
+ "Variant field has no selected field: %!+f", field);
+ container_fc = (const void *) field->class;
+ return container_fc->named_fcs->pdata[var_field->selected_index];
+}
+
+const struct bt_field_class_variant_option *
+bt_field_variant_borrow_selected_class_option_const(
+ const struct bt_field *field)
+{
+ BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
+ return borrow_variant_field_selected_class_option(field);
+}
+
+const struct bt_field_class_variant_with_unsigned_selector_option *
+bt_field_variant_with_unsigned_selector_borrow_selected_class_option_const(
+ const struct bt_field *field)
+{
+ BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR, "Field");
+ return (const void *) borrow_variant_field_selected_class_option(field);
+}
+
+const struct bt_field_class_variant_with_signed_selector_option *
+bt_field_variant_with_signed_selector_borrow_selected_class_option_const(
+ const struct bt_field *field)
+{
+ BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+ BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR, "Field");
+ return (const void *) borrow_variant_field_selected_class_option(field);
+}
+
+enum bt_field_variant_select_option_field_by_index_status
+bt_field_variant_select_option_field_by_index(
struct bt_field *field, uint64_t index)
{
struct bt_field_variant *var_field = (void *) field;
BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
- BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
- BT_FIELD_CLASS_TYPE_VARIANT, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
BT_ASSERT_PRE_DEV_VALID_INDEX(index, var_field->fields->len);
var_field->selected_field = var_field->fields->pdata[index];
const struct bt_field_variant *var_field = (const void *) field;
BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
- BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
- BT_FIELD_CLASS_TYPE_VARIANT, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_IS_VARIANT(field, "Field");
BT_ASSERT_PRE_DEV(var_field->selected_field,
"Variant field has no selected field: %!+f", field);
return var_field->selected_index;
void bt_field_destroy(struct bt_field *field)
{
BT_ASSERT(field);
- BT_ASSERT(bt_field_class_has_known_type(field->class));
field_destroy_funcs[field->class->type](field);
}
((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_VARIANT(_field, _name) \
+ BT_ASSERT_PRE_DEV( \
+ ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR || \
+ ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR || \
+ ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR, \
+ _name " is not a variant field: %![field-]+f", (_field))
+
#define BT_ASSERT_PRE_DEV_FIELD_IS_SET(_field, _name) \
BT_ASSERT_PRE_DEV(bt_field_is_set(_field), \
_name " is not set: %!+f", (_field))
goto end;
}
- BT_ASSERT(bt_field_class_has_known_type(field->class));
BT_ASSERT(field->methods->is_set);
is_set = field->methods->is_set(field);
switch (fc->type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
struct bt_field_class_named_field_class_container *container_fc =
(void *) fc;
for (i = 0; i < container_fc->named_fcs->len; i++) {
struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
- container_fc, i);
+ container_fc->named_fcs->pdata[i];
struct bt_field_path_item item = {
.type = BT_FIELD_PATH_ITEM_TYPE_INDEX,
.index = i,
switch (parent_fc->type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
+ struct bt_field_class_named_field_class_container *container_fc =
+ (void *) parent_fc;
struct bt_named_field_class *named_fc;
BT_ASSERT(fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX);
- named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(parent_fc,
- fp_item->index);
+ named_fc = container_fc->named_fcs->pdata[fp_item->index];
child_fc = named_fc->fc;
break;
}
if (fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
- fc->type == BT_FIELD_CLASS_TYPE_VARIANT) {
+ 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) {
is_valid = false;
goto end;
}
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_VARIANT) {
+ 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) {
is_valid = false;
goto end;
}
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
{
- struct bt_field_class_variant *var_fc = (void *) fc;
+ struct bt_field_class_variant_with_selector *var_fc =
+ (void *) fc;
if (var_fc->selector_fc) {
BT_ASSERT(!var_fc->selector_field_path);
var_fc->selector_field_path =
resolve_field_path(fc,
- var_fc->selector_fc, ctx);
+ (void *) var_fc->selector_fc, ctx);
if (!var_fc->selector_field_path) {
ret = -1;
goto end;
/* Recursive part */
switch (fc->type) {
case BT_FIELD_CLASS_TYPE_STRUCTURE:
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
struct bt_field_class_named_field_class_container *container_fc =
(void *) fc;
for (i = 0; i < container_fc->named_fcs->len; i++) {
struct bt_named_field_class *named_fc =
- BT_FIELD_CLASS_NAMED_FC_AT_INDEX(
- container_fc, i);
+ container_fc->named_fcs->pdata[i];
ret = bt_resolve_field_paths(named_fc->fc, ctx);
if (ret) {
/*
* Converts a path token list to a field path object. The path token
* list is relative from `fc`. The index of the source looking for its
- * target within `fc` is indicated by `src_index`. This can be `INT64_MAX`
- * if the source is contained in `fc`.
+ * target within `fc` is indicated by `src_index`. This can be
+ * `INT64_MAX` if the source is contained in `fc`.
*
* `field_path` is an output parameter owned by the caller that must be
* filled here.
child_index = -1;
} else {
child_index =
- ctf_field_class_compound_get_field_class_index_from_name(
+ ctf_field_class_compound_get_field_class_index_from_orig_name(
fc, ft_name);
if (child_index < 0) {
/*
for (i = 0; i < fc->mappings->len; i++) {
struct ctf_field_class_enum_mapping *mapping =
ctf_field_class_enum_borrow_mapping_by_index(fc, i);
+ void *range_set;
+ uint64_t range_i;
if (fc->base.is_signed) {
- ret = bt_field_class_signed_enumeration_map_range(
- ir_fc, mapping->label->str,
- mapping->range.lower.i, mapping->range.upper.i);
+ range_set = bt_integer_range_set_signed_create();
} else {
- ret = bt_field_class_unsigned_enumeration_map_range(
- ir_fc, mapping->label->str,
- mapping->range.lower.u, mapping->range.upper.u);
+ range_set = bt_integer_range_set_unsigned_create();
+ }
+
+ BT_ASSERT(range_set);
+
+ for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
+ struct ctf_range *range =
+ ctf_field_class_enum_mapping_borrow_range_by_index(
+ mapping, range_i);
+
+ if (fc->base.is_signed) {
+ ret = bt_integer_range_set_signed_add_range(
+ range_set, range->lower.i,
+ range->upper.i);
+ } else {
+ ret = bt_integer_range_set_unsigned_add_range(
+ range_set, range->lower.u,
+ range->upper.u);
+ }
+
+ BT_ASSERT(ret == 0);
+ }
+
+ if (fc->base.is_signed) {
+ ret = bt_field_class_signed_enumeration_add_mapping(
+ ir_fc, mapping->label->str, range_set);
+ BT_RANGE_SET_SIGNED_PUT_REF_AND_RESET(range_set);
+ } else {
+ ret = bt_field_class_unsigned_enumeration_add_mapping(
+ ir_fc, mapping->label->str, range_set);
+ BT_RANGE_SET_UNSIGNED_PUT_REF_AND_RESET(range_set);
}
BT_ASSERT(ret == 0);
return ir_fc;
}
+static inline
+const void *find_ir_enum_field_class_mapping_by_label(const bt_field_class *fc,
+ const char *label, bool is_signed)
+{
+ const void *mapping = NULL;
+ uint64_t i;
+
+ for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) {
+ const bt_field_class_enumeration_mapping *this_mapping;
+ const void *spec_this_mapping;
+
+ if (is_signed) {
+ spec_this_mapping =
+ bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
+ fc, i);
+ this_mapping =
+ bt_field_class_signed_enumeration_mapping_as_mapping_const(
+ spec_this_mapping);
+ } else {
+ spec_this_mapping =
+ bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
+ fc, i);
+ this_mapping =
+ bt_field_class_unsigned_enumeration_mapping_as_mapping_const(
+ spec_this_mapping);
+ }
+
+ BT_ASSERT(this_mapping);
+ BT_ASSERT(spec_this_mapping);
+
+ if (strcmp(bt_field_class_enumeration_mapping_get_label(
+ this_mapping), label) == 0) {
+ mapping = spec_this_mapping;
+ goto end;
+ }
+ }
+
+end:
+ return mapping;
+}
+
static inline
bt_field_class *ctf_field_class_variant_to_ir(struct ctx *ctx,
struct ctf_field_class_variant *fc)
{
int ret;
- bt_field_class *ir_fc = bt_field_class_variant_create(ctx->ir_tc);
+ bt_field_class *ir_fc;
uint64_t i;
-
- BT_ASSERT(ir_fc);
+ bt_field_class *ir_tag_fc = NULL;
if (fc->tag_path.root != CTF_SCOPE_PACKET_HEADER &&
fc->tag_path.root != CTF_SCOPE_EVENT_HEADER) {
- ret = bt_field_class_variant_set_selector_field_class(
- ir_fc, borrow_ir_fc_from_field_path(ctx,
- &fc->tag_path));
- BT_ASSERT(ret == 0);
+ ir_tag_fc = borrow_ir_fc_from_field_path(ctx, &fc->tag_path);
+ BT_ASSERT(ir_tag_fc);
}
+ ir_fc = bt_field_class_variant_create(ctx->ir_tc, ir_tag_fc);
+ BT_ASSERT(ir_fc);
+
for (i = 0; i < fc->options->len; i++) {
struct ctf_named_field_class *named_fc =
ctf_field_class_variant_borrow_option_by_index(fc, i);
BT_ASSERT(named_fc->fc->in_ir);
option_ir_fc = ctf_field_class_to_ir(ctx, named_fc->fc);
BT_ASSERT(option_ir_fc);
- ret = bt_field_class_variant_append_option(
- ir_fc, named_fc->name->str, option_ir_fc);
+
+ if (ir_tag_fc) {
+ /*
+ * At this point the trace IR selector
+ * (enumeration) field class already exists if
+ * the variant is tagged (`ir_tag_fc`). This one
+ * already contains range sets for its mappings,
+ * so we just reuse the same, finding them by
+ * matching a variant field class's option's
+ * _original_ name (with a leading underscore,
+ * possibly) with a selector field class's
+ * mapping name.
+ */
+ if (fc->tag_fc->base.is_signed) {
+ const bt_field_class_signed_enumeration_mapping *mapping =
+ find_ir_enum_field_class_mapping_by_label(
+ ir_tag_fc,
+ named_fc->orig_name->str, true);
+ const bt_integer_range_set_signed *range_set;
+
+ BT_ASSERT(mapping);
+ range_set =
+ bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ mapping);
+ BT_ASSERT(range_set);
+ ret = bt_field_class_variant_with_signed_selector_append_option(
+ ir_fc, named_fc->name->str,
+ option_ir_fc, range_set);
+ } else {
+ const bt_field_class_unsigned_enumeration_mapping *mapping =
+ find_ir_enum_field_class_mapping_by_label(
+ ir_tag_fc,
+ named_fc->orig_name->str,
+ false);
+ const bt_integer_range_set_unsigned *range_set;
+
+ BT_ASSERT(mapping);
+ range_set =
+ bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ mapping);
+ BT_ASSERT(range_set);
+ ret = bt_field_class_variant_with_unsigned_selector_append_option(
+ ir_fc, named_fc->name->str,
+ option_ir_fc, range_set);
+ }
+ } else {
+ ret = bt_field_class_variant_without_selector_append_option(
+ ir_fc, named_fc->name->str, option_ir_fc);
+ }
+
BT_ASSERT(ret == 0);
bt_field_class_put_ref(option_ir_fc);
}
struct ctf_field_class_enum_mapping {
GString *label;
- struct ctf_range range;
+
+ /* Array of `struct ctf_range` */
+ GArray *ranges;
};
struct ctf_field_class_enum {
};
struct ctf_named_field_class {
+ /* Original name which can include a leading `_` */
+ GString *orig_name;
+
+ /* Name as translated to trace IR (leading `_` removed) */
GString *name;
/* Owned by this */
BT_ASSERT(named_fc);
named_fc->name = g_string_new(NULL);
BT_ASSERT(named_fc->name);
+ named_fc->orig_name = g_string_new(NULL);
+ BT_ASSERT(named_fc->orig_name);
}
static inline
g_string_free(named_fc->name, TRUE);
}
+ if (named_fc->orig_name) {
+ g_string_free(named_fc->orig_name, TRUE);
+ }
+
ctf_field_class_destroy(named_fc->fc);
}
BT_ASSERT(mapping);
mapping->label = g_string_new(NULL);
BT_ASSERT(mapping->label);
+ mapping->ranges = g_array_new(FALSE, TRUE, sizeof(struct ctf_range));
+ BT_ASSERT(mapping->ranges);
}
static inline
if (mapping->label) {
g_string_free(mapping->label, TRUE);
}
+
+ if (mapping->ranges) {
+ g_array_free(mapping->ranges, TRUE);
+ }
}
static inline
}
static inline
-void ctf_field_class_enum_append_mapping(struct ctf_field_class_enum *fc,
- const char *label, uint64_t u_lower, uint64_t u_upper)
+struct ctf_range *ctf_field_class_enum_mapping_borrow_range_by_index(
+ struct ctf_field_class_enum_mapping *mapping, uint64_t index)
{
- struct ctf_field_class_enum_mapping *mapping;
-
- BT_ASSERT(fc);
- BT_ASSERT(label);
- g_array_set_size(fc->mappings, fc->mappings->len + 1);
-
- mapping = &g_array_index(fc->mappings,
- struct ctf_field_class_enum_mapping, fc->mappings->len - 1);
- _ctf_field_class_enum_mapping_init(mapping);
- g_string_assign(mapping->label, label);
- mapping->range.lower.u = u_lower;
- mapping->range.upper.u = u_upper;
+ BT_ASSERT(mapping);
+ BT_ASSERT(index < mapping->ranges->len);
+ return &g_array_index(mapping->ranges, struct ctf_range, index);
}
static inline
index);
}
+static inline
+struct ctf_field_class_enum_mapping *ctf_field_class_enum_borrow_mapping_by_label(
+ struct ctf_field_class_enum *fc, const char *label)
+{
+ struct ctf_field_class_enum_mapping *ret_mapping = NULL;
+ uint64_t i;
+
+ BT_ASSERT(fc);
+ BT_ASSERT(label);
+
+ for (i = 0; i < fc->mappings->len; i++) {
+ struct ctf_field_class_enum_mapping *mapping =
+ ctf_field_class_enum_borrow_mapping_by_index(fc, i);
+
+ if (strcmp(mapping->label->str, label) == 0) {
+ ret_mapping = mapping;
+ goto end;
+ }
+ }
+
+end:
+ return ret_mapping;
+}
+
+static inline
+void ctf_field_class_enum_map_range(struct ctf_field_class_enum *fc,
+ const char *label, uint64_t u_lower, uint64_t u_upper)
+{
+ struct ctf_field_class_enum_mapping *mapping = NULL;
+ struct ctf_range range = {
+ .lower.u = u_lower,
+ .upper.u = u_upper,
+ };
+ uint64_t i;
+
+ BT_ASSERT(fc);
+ BT_ASSERT(label);
+
+ for (i = 0; i < fc->mappings->len; i++) {
+ mapping = ctf_field_class_enum_borrow_mapping_by_index(
+ fc, i);
+
+ if (strcmp(mapping->label->str, label) == 0) {
+ break;
+ }
+ }
+
+ if (i == fc->mappings->len) {
+ mapping = NULL;
+ }
+
+ if (!mapping) {
+ g_array_set_size(fc->mappings, fc->mappings->len + 1);
+ mapping = ctf_field_class_enum_borrow_mapping_by_index(
+ fc, fc->mappings->len - 1);
+ _ctf_field_class_enum_mapping_init(mapping);
+ g_string_assign(mapping->label, label);
+ }
+
+ g_array_append_val(mapping->ranges, range);
+}
+
static inline
struct ctf_named_field_class *ctf_field_class_struct_borrow_member_by_index(
struct ctf_field_class_struct *fc, uint64_t index)
return int_fc;
}
+static inline
+void _ctf_named_field_class_unescape_orig_name(
+ struct ctf_named_field_class *named_fc)
+{
+ const char *name = named_fc->orig_name->str;
+
+ if (name[0] == '_') {
+ name++;
+ }
+
+ g_string_assign(named_fc->name, name);
+}
static inline
void ctf_field_class_struct_append_member(struct ctf_field_class_struct *fc,
- const char *name, struct ctf_field_class *member_fc)
+ const char *orig_name, struct ctf_field_class *member_fc)
{
struct ctf_named_field_class *named_fc;
BT_ASSERT(fc);
- BT_ASSERT(name);
+ BT_ASSERT(orig_name);
g_array_set_size(fc->members, fc->members->len + 1);
named_fc = &g_array_index(fc->members, struct ctf_named_field_class,
fc->members->len - 1);
_ctf_named_field_class_init(named_fc);
- g_string_assign(named_fc->name, name);
+ g_string_assign(named_fc->orig_name, orig_name);
+ _ctf_named_field_class_unescape_orig_name(named_fc);
named_fc->fc = member_fc;
if (member_fc->alignment > fc->base.alignment) {
static inline
void ctf_field_class_variant_append_option(struct ctf_field_class_variant *fc,
- const char *name, struct ctf_field_class *option_fc)
+ const char *orig_name, struct ctf_field_class *option_fc)
{
struct ctf_named_field_class *named_fc;
BT_ASSERT(fc);
- BT_ASSERT(name);
+ BT_ASSERT(orig_name);
g_array_set_size(fc->options, fc->options->len + 1);
named_fc = &g_array_index(fc->options, struct ctf_named_field_class,
fc->options->len - 1);
_ctf_named_field_class_init(named_fc);
- g_string_assign(named_fc->name, name);
+ g_string_assign(named_fc->orig_name, orig_name);
+ _ctf_named_field_class_unescape_orig_name(named_fc);
named_fc->fc = option_fc;
}
fc->tag_fc = tag_fc;
for (option_i = 0; option_i < fc->options->len; option_i++) {
- uint64_t mapping_i;
+ uint64_t range_i;
struct ctf_named_field_class *named_fc =
ctf_field_class_variant_borrow_option_by_index(
fc, option_i);
+ struct ctf_field_class_enum_mapping *mapping;
- for (mapping_i = 0; mapping_i < tag_fc->mappings->len;
- mapping_i++) {
- struct ctf_field_class_enum_mapping *mapping =
- ctf_field_class_enum_borrow_mapping_by_index(
- tag_fc, mapping_i);
+ mapping = ctf_field_class_enum_borrow_mapping_by_label(
+ tag_fc, named_fc->orig_name->str);
+ if (!mapping) {
+ continue;
+ }
- if (strcmp(named_fc->name->str,
- mapping->label->str) == 0) {
- struct ctf_field_class_variant_range range;
+ for (range_i = 0; range_i < mapping->ranges->len;
+ range_i++) {
+ struct ctf_range *range =
+ ctf_field_class_enum_mapping_borrow_range_by_index(
+ mapping, range_i);
+ struct ctf_field_class_variant_range var_range;
- range.range = mapping->range;
- range.option_index = option_i;
- g_array_append_val(fc->ranges, range);
- }
+ var_range.range = *range;
+ var_range.option_index = option_i;
+ g_array_append_val(fc->ranges, var_range);
}
}
}
}
static inline
-int64_t ctf_field_class_compound_get_field_class_index_from_name(
- struct ctf_field_class *fc, const char *name)
+int64_t ctf_field_class_compound_get_field_class_index_from_orig_name(
+ struct ctf_field_class *fc, const char *orig_name)
{
int64_t ret_index = -1;
uint64_t i;
ctf_field_class_struct_borrow_member_by_index(
struct_fc, i);
- if (strcmp(name, named_fc->name->str) == 0) {
+ if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
ret_index = (int64_t) i;
goto end;
}
ctf_field_class_variant_borrow_option_by_index(
var_fc, i);
- if (strcmp(name, named_fc->name->str) == 0) {
+ if (strcmp(orig_name, named_fc->orig_name->str) == 0) {
ret_index = (int64_t) i;
goto end;
}
ctf_field_class_int_copy_content((void *) copy_fc, (void *) fc);
for (i = 0; i < fc->mappings->len; i++) {
+ uint64_t range_i;
+
struct ctf_field_class_enum_mapping *mapping =
&g_array_index(fc->mappings,
struct ctf_field_class_enum_mapping, i);
- ctf_field_class_enum_append_mapping(copy_fc, mapping->label->str,
- mapping->range.lower.u, mapping->range.upper.u);
+ for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
+ struct ctf_range *range =
+ &g_array_index(mapping->ranges,
+ struct ctf_range, range_i);
+
+ ctf_field_class_enum_map_range(copy_fc,
+ mapping->label->str, range->lower.u,
+ range->upper.u);
+ }
}
return copy_fc;
int visit_field_class_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
struct ctf_field_class **decl);
-static
-char *remove_underscores_from_field_ref(struct ctx *ctx, const char *field_ref)
-{
- const char *in_ch;
- char *out_ch;
- char *ret;
- enum {
- UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE,
- UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE,
- } state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
-
- BT_ASSERT(field_ref);
- ret = calloc(strlen(field_ref) + 1, 1);
- if (!ret) {
- BT_COMP_LOGE("Failed to allocate a string: size=%zu",
- strlen(field_ref) + 1);
- goto end;
- }
-
- in_ch = field_ref;
- out_ch = ret;
-
- while (*in_ch != '\0') {
- switch (*in_ch) {
- case ' ':
- case '\t':
- /* Remove whitespace */
- in_ch++;
- continue;
- case '_':
- if (state == UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE) {
- in_ch++;
- state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
- continue;
- }
-
- goto copy;
- case '.':
- state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
- goto copy;
- default:
- state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
- goto copy;
- }
-
-copy:
- *out_ch = *in_ch;
- in_ch++;
- out_ch++;
- }
-
-end:
- return ret;
-}
-
static
int is_unary_string(struct bt_list_head *head)
{
const char *id =
node_field_class_declarator->u.field_class_declarator.u.id;
- if (id[0] == '_') {
- id++;
- }
-
*field_name = g_quark_from_string(id);
} else {
*field_name = 0;
nested_decl = NULL;
decl = (void *) array_decl;
} else {
- char *length_name_no_underscore =
- remove_underscores_from_field_ref(ctx,
- length_name);
- if (!length_name_no_underscore) {
- /*
- * remove_underscores_from_field_ref()
- * logs errors
- */
- ret = -EINVAL;
- goto error;
- }
seq_decl = ctf_field_class_sequence_create();
BT_ASSERT(seq_decl);
seq_decl->base.elem_fc = nested_decl;
nested_decl = NULL;
g_string_assign(seq_decl->length_ref,
- length_name_no_underscore);
- free(length_name_no_underscore);
+ length_name);
decl = (void *) seq_decl;
}
* At this point, we have a fresh untagged variant; nobody
* else owns it. Set its tag now.
*/
- char *tag_no_underscore =
- remove_underscores_from_field_ref(ctx, tag);
-
- if (!tag_no_underscore) {
- /* remove_underscores_from_field_ref() logs errors */
- goto error;
- }
-
- g_string_assign(untagged_variant_decl->tag_ref,
- tag_no_underscore);
- free(tag_no_underscore);
+ g_string_assign(untagged_variant_decl->tag_ref, tag);
*variant_decl = untagged_variant_decl;
untagged_variant_decl = NULL;
}
.value.u = 0,
};
const char *label = enumerator->u.enumerator.id;
- const char *effective_label = label;
struct bt_list_head *values = &enumerator->u.enumerator.values;
bt_list_for_each_entry(iter, values, siblings) {
last->value.u = end.value.u + 1;
}
- if (label[0] == '_') {
- /*
- * Strip the first underscore of any enumeration field
- * class's label in case this enumeration FC is used as
- * a variant FC tag later. The variant FC choice names
- * could also start with `_`, in which case the prefix
- * is removed, and it the resulting choice name needs to
- * match tag labels.
- */
- effective_label = &label[1];
- }
-
- ctf_field_class_enum_append_mapping(enum_decl, effective_label,
+ ctf_field_class_enum_map_range(enum_decl, label,
start.value.u, end.value.u);
return 0;
next_field = bt_field_array_borrow_element_field_by_index(
base_field, index);
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
BT_ASSERT(index == 0);
next_field = bt_field_variant_borrow_selected_option_field(
base_field);
if (selected_option->fc->in_ir) {
bt_field *var_field = stack_top(notit->stack)->base;
- ret = bt_field_variant_select_option_field(
+ ret = bt_field_variant_select_option_field_by_index(
var_field, option_index);
if (ret) {
BT_COMP_LOGW("Cannot select variant field's option field: "
fc->tag_ref = g_string_new(NULL);
BT_ASSERT(fc->tag_ref);
fc->tag_is_before =
- bt_field_class_variant_borrow_selector_field_path_const(ir_fc) ==
- NULL;
+ bt_field_class_get_type(fc->base.ir_fc) ==
+ BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR;
return fc;
}
return trace;
}
-static inline
-bool fs_sink_ctf_ist_valid_identifier(const char *name)
-{
- const char *at;
- uint64_t i;
- bool ist_valid = true;
- static const char *reserved_keywords[] = {
- "align",
- "callsite",
- "const",
- "char",
- "clock",
- "double",
- "enum",
- "env",
- "event",
- "floating_point",
- "float",
- "integer",
- "int",
- "long",
- "short",
- "signed",
- "stream",
- "string",
- "struct",
- "trace",
- "typealias",
- "typedef",
- "unsigned",
- "variant",
- "void",
- "_Bool",
- "_Complex",
- "_Imaginary",
- };
-
- /* Make sure the name is not a reserved keyword */
- for (i = 0; i < sizeof(reserved_keywords) / sizeof(*reserved_keywords);
- i++) {
- if (strcmp(name, reserved_keywords[i]) == 0) {
- ist_valid = false;
- goto end;
- }
- }
-
- /* Make sure the name is not an empty string */
- if (strlen(name) == 0) {
- ist_valid = false;
- goto end;
- }
-
- /* Make sure the name starts with a letter or `_` */
- if (!isalpha(name[0]) && name[0] != '_') {
- ist_valid = false;
- goto end;
- }
-
- /* Make sure the name only contains letters, digits, and `_` */
- for (at = name; *at != '\0'; at++) {
- if (!isalnum(*at) && *at != '_') {
- ist_valid = false;
- goto end;
- }
- }
-
-end:
- return ist_valid;
-}
-
-static inline
-int fs_sink_ctf_protect_name(GString *name)
-{
- int ret = 0;
-
- if (!fs_sink_ctf_ist_valid_identifier(name->str)) {
- ret = -1;
- goto end;
- }
-
- /* Prepend `_` to protect it */
- g_string_prepend_c(name, '_');
-
-end:
- return ret;
-}
-
#endif /* BABELTRACE_PLUGIN_CTF_FS_SINK_FS_SINK_CTF_META_H */
const char *label;
const bt_field_class_enumeration_mapping *mapping;
const bt_field_class_unsigned_enumeration_mapping *u_mapping;
- const bt_field_class_signed_enumeration_mapping *i_mapping;
+ const bt_field_class_signed_enumeration_mapping *s_mapping;
+ const bt_integer_range_set *ranges;
+ const bt_integer_range_set_unsigned *u_ranges;
+ const bt_integer_range_set_signed *s_ranges;
uint64_t range_count;
uint64_t range_i;
if (is_signed) {
- i_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
+ s_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
ir_fc, i);
mapping = bt_field_class_signed_enumeration_mapping_as_mapping_const(
- i_mapping);
+ s_mapping);
+ s_ranges = bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ s_mapping);
+ ranges = bt_integer_range_set_signed_as_range_set_const(
+ s_ranges);
} else {
u_mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
ir_fc, i);
mapping = bt_field_class_unsigned_enumeration_mapping_as_mapping_const(
u_mapping);
+ u_ranges = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ u_mapping);
+ ranges = bt_integer_range_set_unsigned_as_range_set_const(
+ u_ranges);
}
label = bt_field_class_enumeration_mapping_get_label(
mapping);
- range_count =
- bt_field_class_enumeration_mapping_get_range_count(
- mapping);
+ range_count = bt_integer_range_set_get_range_count(
+ ranges);
for (range_i = 0; range_i < range_count; range_i++) {
append_indent(ctx);
-
- /*
- * Systematically prepend `_` to the
- * mapping's label as this could be used
- * as the tag of a subsequent variant
- * field class and variant FC option
- * names are systematically protected
- * with a leading `_`.
- *
- * FIXME: This is temporary as the
- * library's API should change to
- * decouple variant FC option names from
- * selector FC labels. The current
- * drawback is that an original label
- * `HELLO` becomes `_HELLO` in the
- * generated metadata, therefore tools
- * expecting `HELLO` could fail.
- */
- g_string_append(ctx->tsdl, "\"_");
+ g_string_append(ctx->tsdl, "\"");
append_quoted_string_content(ctx, label);
g_string_append(ctx->tsdl, "\" = ");
if (is_signed) {
+ const bt_integer_range_signed *range;
int64_t lower, upper;
- bt_field_class_signed_enumeration_mapping_get_range_by_index(
- i_mapping, range_i,
- &lower, &upper);
+ range = bt_integer_range_set_signed_borrow_range_by_index_const(
+ s_ranges, range_i);
+ lower = bt_integer_range_signed_get_lower(
+ range);
+ upper = bt_integer_range_signed_get_upper(
+ range);
if (lower == upper) {
g_string_append_printf(
lower, upper);
}
} else {
+ const bt_integer_range_unsigned *range;
uint64_t lower, upper;
- bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- u_mapping, range_i,
- &lower, &upper);
+ range = bt_integer_range_set_unsigned_borrow_range_by_index_const(
+ u_ranges, range_i);
+ lower = bt_integer_range_unsigned_get_lower(
+ range);
+ upper = bt_integer_range_unsigned_get_upper(
+ range);
if (lower == upper) {
g_string_append_printf(
return is_reserved;
}
+static const char *reserved_tsdl_keywords[] = {
+ "align",
+ "callsite",
+ "const",
+ "char",
+ "clock",
+ "double",
+ "enum",
+ "env",
+ "event",
+ "floating_point",
+ "float",
+ "integer",
+ "int",
+ "long",
+ "short",
+ "signed",
+ "stream",
+ "string",
+ "struct",
+ "trace",
+ "typealias",
+ "typedef",
+ "unsigned",
+ "variant",
+ "void",
+ "_Bool",
+ "_Complex",
+ "_Imaginary",
+};
+
+static inline
+bool ist_valid_identifier(const char *name)
+{
+ const char *at;
+ uint64_t i;
+ bool ist_valid = true;
+
+ /* Make sure the name is not a reserved keyword */
+ for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords);
+ i++) {
+ if (strcmp(name, reserved_tsdl_keywords[i]) == 0) {
+ ist_valid = false;
+ goto end;
+ }
+ }
+
+ /* Make sure the name is not an empty string */
+ if (strlen(name) == 0) {
+ ist_valid = false;
+ goto end;
+ }
+
+ /* Make sure the name starts with a letter or `_` */
+ if (!isalpha(name[0]) && name[0] != '_') {
+ ist_valid = false;
+ goto end;
+ }
+
+ /* Make sure the name only contains letters, digits, and `_` */
+ for (at = name; *at != '\0'; at++) {
+ if (!isalnum(*at) && *at != '_') {
+ ist_valid = false;
+ goto end;
+ }
+ }
+
+end:
+ return ist_valid;
+}
+
+static inline
+bool must_protect_identifier(const char *name)
+{
+ uint64_t i;
+ bool must_protect = false;
+
+ /* Protect a reserved keyword */
+ for (i = 0; i < sizeof(reserved_tsdl_keywords) / sizeof(*reserved_tsdl_keywords);
+ i++) {
+ if (strcmp(name, reserved_tsdl_keywords[i]) == 0) {
+ must_protect = true;
+ goto end;
+ }
+ }
+
+ /* Protect an identifier which already starts with `_` */
+ if (name[0] == '_') {
+ must_protect = true;
+ goto end;
+ }
+
+end:
+ return must_protect;
+}
+
static inline
int cur_path_stack_push(struct ctx *ctx,
- uint64_t index_in_parent, const char *ir_name,
- const bt_field_class *ir_fc,
+ uint64_t index_in_parent, const char *name,
+ bool force_protect_name, const bt_field_class *ir_fc,
struct fs_sink_ctf_field_class *parent_fc)
{
int ret = 0;
g_array_set_size(ctx->cur_path, ctx->cur_path->len + 1);
field_path_elem = cur_path_stack_top(ctx);
field_path_elem->index_in_parent = index_in_parent;
- field_path_elem->name = g_string_new(ir_name);
+ field_path_elem->name = g_string_new(NULL);
+
+ if (name) {
+ if (force_protect_name) {
+ g_string_assign(field_path_elem->name, "_");
+ }
+
+ g_string_append(field_path_elem->name, name);
- if (ir_name) {
if (ctx->cur_scope == BT_SCOPE_PACKET_CONTEXT) {
- if (is_reserved_member_name(ir_name, "packet_size") ||
- is_reserved_member_name(ir_name, "content_size") ||
- is_reserved_member_name(ir_name, "timestamp_begin") ||
- is_reserved_member_name(ir_name, "timestamp_end") ||
- is_reserved_member_name(ir_name, "events_discarded") ||
- is_reserved_member_name(ir_name, "packet_seq_num")) {
+ if (is_reserved_member_name(name, "packet_size") ||
+ is_reserved_member_name(name, "content_size") ||
+ is_reserved_member_name(name, "timestamp_begin") ||
+ is_reserved_member_name(name, "timestamp_end") ||
+ is_reserved_member_name(name, "events_discarded") ||
+ is_reserved_member_name(name, "packet_seq_num")) {
BT_COMP_LOGE("Unsupported reserved TSDL structure field class member "
"or variant field class option name: name=\"%s\"",
- ir_name);
+ name);
ret = -1;
goto end;
}
}
- ret = fs_sink_ctf_protect_name(field_path_elem->name);
- if (ret) {
+ if (!ist_valid_identifier(field_path_elem->name->str)) {
+ ret = -1;
BT_COMP_LOGE("Unsupported non-TSDL structure field class member "
"or variant field class option name: name=\"%s\"",
- ir_name);
+ field_path_elem->name->str);
goto end;
}
}
*/
static
int create_relative_field_ref(struct ctx *ctx,
- const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref)
+ const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref,
+ struct fs_sink_ctf_field_class **user_tgt_fc)
{
int ret = 0;
struct fs_sink_ctf_field_class *tgt_fc = NULL;
if (named_fc->fc == tgt_fc) {
g_string_assign(tgt_field_ref,
tgt_fc_name);
+
+ if (user_tgt_fc) {
+ *user_tgt_fc = tgt_fc;
+ }
} else {
/*
* Using only the target field
*/
static
int create_absolute_field_ref(struct ctx *ctx,
- const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref)
+ const bt_field_path *tgt_ir_field_path, GString *tgt_field_ref,
+ struct fs_sink_ctf_field_class **user_tgt_fc)
{
int ret = 0;
struct fs_sink_ctf_field_class *fc = NULL;
fc = named_fc->fc;
}
+ if (user_tgt_fc) {
+ *user_tgt_fc = fc;
+ }
+
end:
return ret;
}
static
void resolve_field_class(struct ctx *ctx,
const bt_field_path *tgt_ir_field_path,
- GString *tgt_field_ref, bool *create_before)
+ GString *tgt_field_ref, bool *create_before,
+ struct fs_sink_ctf_field_class **user_tgt_fc)
{
int ret;
bt_scope tgt_scope;
* requesting field class (fallback).
*/
ret = create_relative_field_ref(ctx, tgt_ir_field_path,
- tgt_field_ref);
+ tgt_field_ref, user_tgt_fc);
if (ret) {
ret = create_absolute_field_ref(ctx, tgt_ir_field_path,
- tgt_field_ref);
+ tgt_field_ref, user_tgt_fc);
if (ret) {
*create_before = true;
ret = 0;
}
} else {
ret = create_absolute_field_ref(ctx, tgt_ir_field_path,
- tgt_field_ref);
+ tgt_field_ref, user_tgt_fc);
/* It must always work in previous scopes */
BT_ASSERT(ret == 0);
name = bt_field_class_structure_member_get_name(member);
memb_ir_fc = bt_field_class_structure_member_borrow_field_class_const(
member);
- ret = cur_path_stack_push(ctx, i, name, memb_ir_fc,
+ ret = cur_path_stack_push(ctx, i, name, true, memb_ir_fc,
(void *) struct_fc);
if (ret) {
BT_COMP_LOGE("Cannot translate structure field class member: "
return ret;
}
+/*
+ * This function returns whether or not a given field class `tag_fc`
+ * is valid as the tag field class of the variant field class `fc`.
+ *
+ * CTF 1.8 requires that the tag field class be an enumeration field
+ * class and that, for each variant field class option's range set, the
+ * tag field class contains a mapping which has the option's name and an
+ * equal range set.
+ */
+static inline
+bool _is_variant_field_class_tag_valid(
+ struct fs_sink_ctf_field_class_variant *fc,
+ struct fs_sink_ctf_field_class *tag_fc)
+{
+ bool is_valid = true;
+ bt_field_class_type ir_tag_fc_type = bt_field_class_get_type(
+ tag_fc->ir_fc);
+ uint64_t i;
+ GString *escaped_opt_name = g_string_new(NULL);
+
+ BT_ASSERT(escaped_opt_name);
+
+ if (ir_tag_fc_type != BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION &&
+ ir_tag_fc_type != BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) {
+ is_valid = false;
+ goto end;
+ }
+
+ for (i = 0; i < bt_field_class_variant_get_option_count(
+ fc->base.ir_fc); i++) {
+ const bt_field_class_variant_option *var_opt_base =
+ bt_field_class_variant_borrow_option_by_index_const(
+ fc->base.ir_fc, i);
+ const char *opt_name = bt_field_class_variant_option_get_name(
+ var_opt_base);
+
+ /*
+ * If the option is named `name` in trace IR, then it
+ * was _possibly_ named `_name` originally if it comes
+ * from `src.ctf.fs`. This means the corresponding
+ * enumeration field class mapping was also named
+ * `_name`, but this one didn't change, as enumeration
+ * FC mapping names are not escaped; they are literal
+ * strings.
+ *
+ * The `sink.ctf.fs` component escapes all the variant
+ * FC option names with `_`. Therefore the
+ * _escaped name_ must match the original enumeration
+ * FC mapping name.
+ */
+ g_string_assign(escaped_opt_name, "_");
+ g_string_append(escaped_opt_name, opt_name);
+
+ if (ir_tag_fc_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
+ const bt_field_class_variant_with_unsigned_selector_option *var_opt =
+ bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
+ fc->base.ir_fc, i);
+ const bt_field_class_unsigned_enumeration_mapping *mapping;
+ const bt_integer_range_set_unsigned *opt_ranges;
+ const bt_integer_range_set_unsigned *mapping_ranges;
+
+ mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_label_const(
+ tag_fc->ir_fc, escaped_opt_name->str);
+ if (!mapping) {
+ is_valid = false;
+ goto end;
+ }
+
+ opt_ranges = bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ var_opt);
+ mapping_ranges = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ mapping);
+ if (!bt_integer_range_set_unsigned_compare(opt_ranges,
+ mapping_ranges)) {
+ is_valid = false;
+ goto end;
+ }
+ } else {
+ const bt_field_class_variant_with_signed_selector_option *var_opt =
+ bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ fc->base.ir_fc, i);
+ const bt_field_class_signed_enumeration_mapping *mapping;
+ const bt_integer_range_set_signed *opt_ranges;
+ const bt_integer_range_set_signed *mapping_ranges;
+
+ mapping = bt_field_class_signed_enumeration_borrow_mapping_by_label_const(
+ tag_fc->ir_fc, escaped_opt_name->str);
+ if (!mapping) {
+ is_valid = false;
+ goto end;
+ }
+
+ opt_ranges = bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ var_opt);
+ mapping_ranges = bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ mapping);
+ if (!bt_integer_range_set_signed_compare(opt_ranges,
+ mapping_ranges)) {
+ is_valid = false;
+ goto end;
+ }
+ }
+ }
+
+end:
+ return is_valid;
+}
+
+/*
+ * This function indicates whether or not a given variant FC option name
+ * must be protected (with the `_` prefix).
+ *
+ * One of the goals of `sink.ctf.fs` is to write a CTF trace which is as
+ * close as possible to an original CTF trace as decoded by
+ * `src.ctf.fs`.
+ *
+ * This scenario is valid in CTF 1.8:
+ *
+ * enum {
+ * HELLO,
+ * MEOW
+ * } tag;
+ *
+ * variant <tag> {
+ * int HELLO;
+ * string MEOW;
+ * };
+ *
+ * Once in trace IR, the enumeration FC mapping names and variant FC
+ * option names are kept as is. For this reason, we don't want to
+ * protect the variant FC option names here (by prepending `_`): this
+ * would make the variant FC option name and the enumeration FC mapping
+ * name not match.
+ *
+ * This scenario is also valid in CTF 1.8:
+ *
+ * enum {
+ * _HELLO,
+ * MEOW
+ * } tag;
+ *
+ * variant <tag> {
+ * int _HELLO;
+ * string MEOW;
+ * };
+ *
+ * Once in trace IR, the enumeration FC mapping names are kept as is,
+ * but the `_HELLO` variant FC option name becomes `HELLO` (unprotected
+ * for presentation, as recommended by CTF 1.8). When going back to
+ * TSDL, we need to protect `HELLO` so that it becomes `_HELLO` to match
+ * the corresponding enumeration FC mapping name.
+ *
+ * This scenario is also valid in CTF 1.8:
+ *
+ * enum {
+ * __HELLO,
+ * MEOW
+ * } tag;
+ *
+ * variant <tag> {
+ * int __HELLO;
+ * string MEOW;
+ * };
+ *
+ * Once in trace IR, the enumeration FC mapping names are kept as is,
+ * but the `__HELLO` variant FC option name becomes `_HELLO`
+ * (unprotected). When going back to TSDL, we need to protect `_HELLO`
+ * so that it becomes `__HELLO` to match the corresponding enumeration
+ * FC mapping name.
+ *
+ * `src.ctf.fs` always uses the _same_ integer range sets for a selector
+ * FC mapping and a corresponding variant FC option. We can use that
+ * fact to find the original variant FC option names by matching variant
+ * FC options and enumeration FC mappings by range set.
+ */
+static
+int must_protect_variant_option_name(const bt_field_class *ir_var_fc,
+ const bt_field_class *ir_tag_fc, uint64_t opt_i,
+ GString *name_buf, bool *must_protect)
+{
+ int ret = 0;
+ uint64_t i;
+ bt_field_class_type ir_var_fc_type;
+ const void *opt_ranges = NULL;
+ const char *mapping_label = NULL;
+ const char *ir_opt_name;
+ const bt_field_class_variant_option *base_var_opt;
+ bool force_protect = false;
+
+ *must_protect = false;
+ ir_var_fc_type = bt_field_class_get_type(ir_var_fc);
+ base_var_opt = bt_field_class_variant_borrow_option_by_index_const(
+ ir_var_fc, opt_i);
+ BT_ASSERT(base_var_opt);
+ ir_opt_name = bt_field_class_variant_option_get_name(base_var_opt);
+ BT_ASSERT(ir_opt_name);
+
+ /*
+ * Check if the variant FC option name is required to be
+ * protected (reserved TSDL keyword or starts with `_`). In that
+ * case, the name of the selector FC mapping we find must match
+ * exactly the protected name.
+ */
+ force_protect = must_protect_identifier(ir_opt_name);
+ if (force_protect) {
+ *must_protect = true;
+ g_string_assign(name_buf, "_");
+ g_string_append(name_buf, ir_opt_name);
+ } else {
+ g_string_assign(name_buf, ir_opt_name);
+ }
+
+ /* Borrow option's ranges */
+ if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR) {
+ /* No ranges: we're done */
+ goto end;
+ } if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
+ const bt_field_class_variant_with_unsigned_selector_option *var_opt =
+ bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
+ ir_var_fc, opt_i);
+ opt_ranges =
+ bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ var_opt);
+ } else {
+ const bt_field_class_variant_with_signed_selector_option *var_opt =
+ bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ ir_var_fc, opt_i);
+ opt_ranges =
+ bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ var_opt);
+ }
+
+ /* Find corresponding mapping by range set in selector FC */
+ for (i = 0; i < bt_field_class_enumeration_get_mapping_count(ir_tag_fc);
+ i++) {
+ if (ir_var_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
+ const bt_field_class_enumeration_mapping *mapping_base;
+ const bt_field_class_unsigned_enumeration_mapping *mapping;
+ const bt_integer_range_set_unsigned *mapping_ranges;
+
+ mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
+ ir_tag_fc, i);
+ mapping_ranges = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ mapping);
+
+ if (bt_integer_range_set_unsigned_compare(opt_ranges,
+ mapping_ranges)) {
+ /* We have a winner */
+ mapping_base =
+ bt_field_class_unsigned_enumeration_mapping_as_mapping_const(
+ mapping);
+ mapping_label =
+ bt_field_class_enumeration_mapping_get_label(
+ mapping_base);
+ break;
+ }
+ } else {
+ const bt_field_class_enumeration_mapping *mapping_base;
+ const bt_field_class_signed_enumeration_mapping *mapping;
+ const bt_integer_range_set_signed *mapping_ranges;
+
+ mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
+ ir_tag_fc, i);
+ mapping_ranges = bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ mapping);
+
+ if (bt_integer_range_set_signed_compare(opt_ranges,
+ mapping_ranges)) {
+ /* We have a winner */
+ mapping_base =
+ bt_field_class_signed_enumeration_mapping_as_mapping_const(
+ mapping);
+ mapping_label =
+ bt_field_class_enumeration_mapping_get_label(
+ mapping_base);
+ break;
+ }
+ }
+ }
+
+ if (!mapping_label) {
+ /* Range set not found: invalid selector for CTF 1.8 */
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * If the enumeration FC mapping name is not the same as the
+ * variant FC option name and we didn't protect already, try
+ * protecting the option name and check again.
+ */
+ if (strcmp(mapping_label, name_buf->str) != 0) {
+ if (force_protect) {
+ ret = -1;
+ goto end;
+ }
+
+ if (mapping_label[0] == '\0') {
+ ret = -1;
+ goto end;
+ }
+
+ g_string_assign(name_buf, "_");
+ g_string_append(name_buf, ir_opt_name);
+
+ if (strcmp(mapping_label, name_buf->str) != 0) {
+ ret = -1;
+ goto end;
+ }
+
+ /*
+ * If this comes from a `src.ctf.fs` source, it looks
+ * like the variant FC option name was initially
+ * protected: protect it again when going back to TSDL.
+ */
+ *must_protect = true;
+ }
+
+end:
+ return ret;
+}
+
static inline
int translate_variant_field_class(struct ctx *ctx)
{
fs_sink_ctf_field_class_variant_create_empty(
cur_path_stack_top(ctx)->ir_fc,
cur_path_stack_top(ctx)->index_in_parent);
+ bt_field_class_type ir_fc_type;
+ const bt_field_path *ir_selector_field_path = NULL;
+ struct fs_sink_ctf_field_class *tgt_fc = NULL;
+ GString *name_buf = g_string_new(NULL);
+ bt_value *prot_opt_names = bt_value_array_create();
+ uint64_t opt_count;
BT_ASSERT(fc);
+ BT_ASSERT(name_buf);
+ BT_ASSERT(prot_opt_names);
+ ir_fc_type = bt_field_class_get_type(fc->base.ir_fc);
+ opt_count = bt_field_class_variant_get_option_count(fc->base.ir_fc);
+
+ if (ir_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
+ ir_fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
+ ir_selector_field_path = bt_field_class_variant_with_selector_borrow_selector_field_path_const(
+ fc->base.ir_fc);
+ BT_ASSERT(ir_selector_field_path);
+ }
/* Resolve tag field class before appending to parent */
- resolve_field_class(ctx,
- bt_field_class_variant_borrow_selector_field_path_const(
- fc->base.ir_fc), fc->tag_ref, &fc->tag_is_before);
+ resolve_field_class(ctx, ir_selector_field_path, fc->tag_ref,
+ &fc->tag_is_before, &tgt_fc);
+
+ if (ir_selector_field_path && tgt_fc) {
+ uint64_t mapping_count;
+ uint64_t option_count;
+
+ /* CTF 1.8: selector FC must be an enumeration FC */
+ bt_field_class_type type = bt_field_class_get_type(
+ tgt_fc->ir_fc);
+
+ if (type != BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION &&
+ type != BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) {
+ fc->tag_is_before = true;
+ goto validate_opts;
+ }
+
+ /*
+ * Call must_protect_variant_option_name() for each
+ * option below. In that case we also want selector FC
+ * to contain as many mappings as the variant FC has
+ * options.
+ */
+ mapping_count = bt_field_class_enumeration_get_mapping_count(
+ tgt_fc->ir_fc);
+ option_count = bt_field_class_variant_get_option_count(
+ fc->base.ir_fc);
+
+ if (mapping_count != option_count) {
+ fc->tag_is_before = true;
+ goto validate_opts;
+ }
+ } else {
+ /*
+ * No compatible selector field class for CTF 1.8:
+ * create the appropriate selector field class.
+ */
+ fc->tag_is_before = true;
+ }
+
+validate_opts:
+ /*
+ * First pass: detect any option name clash with option name
+ * protection. In that case, we don't fail: just create the
+ * selector field class before the variant field class.
+ *
+ * After this, `prot_opt_names` contains the final option names,
+ * potentially protected if needed. They can still be invalid
+ * TSDL identifiers however; this will be checked by
+ * cur_path_stack_push().
+ */
+ for (i = 0; i < opt_count; i++) {
+ bool must_protect = false;
+
+ ret = must_protect_variant_option_name(fc->base.ir_fc,
+ tgt_fc->ir_fc, i, name_buf, &must_protect);
+ if (ret) {
+ fc->tag_is_before = true;
+ }
+
+ ret = bt_value_array_append_string_element(prot_opt_names,
+ name_buf->str);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ for (i = 0; i < opt_count; i++) {
+ uint64_t j;
+ const bt_value *opt_name_a =
+ bt_value_array_borrow_element_by_index_const(
+ prot_opt_names, i);
+
+ for (j = 0; j < opt_count; j++) {
+ const bt_value *opt_name_b;
+
+ if (i == j) {
+ continue;
+ }
+ opt_name_b =
+ bt_value_array_borrow_element_by_index_const(
+ prot_opt_names, j);
+ if (bt_value_compare(opt_name_a, opt_name_b)) {
+ /*
+ * Variant FC option names are not
+ * unique when protected.
+ */
+ fc->tag_is_before = true;
+ goto append_to_parent;
+ }
+ }
+ }
+
+append_to_parent:
append_to_parent_field_class(ctx, (void *) fc);
- for (i = 0; i < bt_field_class_variant_get_option_count(fc->base.ir_fc);
- i++) {
+ for (i = 0; i < opt_count; i++) {
const bt_field_class_variant_option *opt;
- const char *name;
const bt_field_class *opt_ir_fc;
+ const bt_value *prot_opt_name_val =
+ bt_value_array_borrow_element_by_index_const(
+ prot_opt_names, i);
+ const char *prot_opt_name = bt_value_string_get(
+ prot_opt_name_val);
+ BT_ASSERT(prot_opt_name);
opt = bt_field_class_variant_borrow_option_by_index_const(
fc->base.ir_fc, i);
- name = bt_field_class_variant_option_get_name(opt);
opt_ir_fc = bt_field_class_variant_option_borrow_field_class_const(
opt);
- ret = cur_path_stack_push(ctx, i, name, opt_ir_fc, (void *) fc);
+
+ /*
+ * We don't ask cur_path_stack_push() to protect the
+ * option name because it's already protected at this
+ * point.
+ */
+ ret = cur_path_stack_push(ctx, i, prot_opt_name, false,
+ opt_ir_fc, (void *) fc);
if (ret) {
BT_COMP_LOGE("Cannot translate variant field class option: "
- "name=\"%s\"", name);
+ "name=\"%s\"", prot_opt_name);
goto end;
}
ret = translate_field_class(ctx);
if (ret) {
BT_COMP_LOGE("Cannot translate variant field class option: "
- "name=\"%s\"", name);
+ "name=\"%s\"", prot_opt_name);
goto end;
}
}
end:
+ if (name_buf) {
+ g_string_free(name_buf, TRUE);
+ }
+
+ bt_value_put_ref(prot_opt_names);
return ret;
}
BT_ASSERT(fc);
append_to_parent_field_class(ctx, (void *) fc);
- ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, elem_ir_fc,
+ ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc,
(void *) fc);
if (ret) {
BT_COMP_LOGE_STR("Cannot translate static array field class element.");
resolve_field_class(ctx,
bt_field_class_dynamic_array_borrow_length_field_path_const(
fc->base.base.ir_fc),
- fc->length_ref, &fc->length_is_before);
+ fc->length_ref, &fc->length_is_before, NULL);
append_to_parent_field_class(ctx, (void *) fc);
- ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, elem_ir_fc,
+ ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, elem_ir_fc,
(void *) fc);
if (ret) {
BT_COMP_LOGE_STR("Cannot translate dynamic array field class element.");
case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
ret = translate_dynamic_array_field_class(ctx);
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
ret = translate_variant_field_class(ctx);
break;
default:
BT_ASSERT(*fc);
ctx->cur_scope = scope;
BT_ASSERT(ctx->cur_path->len == 0);
- ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, ir_fc, NULL);
+ ret = cur_path_stack_push(ctx, UINT64_C(-1), NULL, false, ir_fc, NULL);
if (ret) {
BT_COMP_LOGE("Cannot translate scope structure field class: "
"scope=%d", scope);
if (name) {
/* Try original name, protected */
+ g_string_assign((*out_sc)->default_clock_class_name,
+ "");
+
+ if (must_protect_identifier(name)) {
+ g_string_assign(
+ (*out_sc)->default_clock_class_name,
+ "_");
+ }
+
g_string_assign((*out_sc)->default_clock_class_name,
name);
- ret = fs_sink_ctf_protect_name(
- (*out_sc)->default_clock_class_name);
- if (ret) {
+ if (!ist_valid_identifier(
+ (*out_sc)->default_clock_class_name->str)) {
/* Invalid: create a new name */
make_unique_default_clock_class_name(*out_sc);
ret = 0;
bt_trace_borrow_environment_entry_by_index_const(
ir_trace, i, &name, &val);
- if (!fs_sink_ctf_ist_valid_identifier(name)) {
+ if (!ist_valid_identifier(name)) {
BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, fs_sink->log_level,
fs_sink->self_comp,
"Unsupported trace class's environment entry name: "
}
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
- bt_field_variant_select_option_field_status sel_opt_status;
+ bt_field_variant_select_option_field_by_index_status sel_opt_status;
uint64_t in_selected_option_idx;
const bt_field *in_option_field;
bt_field *out_option_field;
in_selected_option_idx =
bt_field_variant_get_selected_option_field_index(
in_field);
- sel_opt_status = bt_field_variant_select_option_field(out_field,
+ sel_opt_status = bt_field_variant_select_option_field_by_index(out_field,
in_selected_option_idx);
if (sel_opt_status !=
BT_FIELD_VARIANT_SELECT_OPTION_FIELD_STATUS_OK) {
member);
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
{
const bt_field_class_variant_option *option;
enum_mapping_count = bt_field_class_enumeration_get_mapping_count(in_field_class);
for (i = 0; i < enum_mapping_count; i++) {
const char *label;
+ const bt_integer_range_set_unsigned *range_set;
const bt_field_class_unsigned_enumeration_mapping *u_mapping;
const bt_field_class_enumeration_mapping *mapping;
- uint64_t range_index, range_count;
- /* Get the ranges and the range count. */
u_mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
in_field_class, i);
mapping = bt_field_class_unsigned_enumeration_mapping_as_mapping_const(
u_mapping);
- range_count =
- bt_field_class_enumeration_mapping_get_range_count(
- mapping);
- label = bt_field_class_enumeration_mapping_get_label(
- mapping);
-
- /*
- * Iterate over all the ranges to add them to copied field
- * class.
- */
- for (range_index = 0; range_index < range_count; range_index++) {
- uint64_t lower, upper;
- bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- u_mapping, range_index, &lower, &upper);
-
- BT_COMP_LOGD("Copying range in enumeration field class: "
- "label=%s, lower=%"PRId64", upper=%"PRId64,
- label, lower, upper);
-
- /* Add the label and its range to the copy field class. */
- if (bt_field_class_unsigned_enumeration_map_range(
- out_field_class, label, lower, upper) !=
- BT_FIELD_CLASS_ENUMERATION_MAP_RANGE_STATUS_OK) {
- BT_COMP_LOGE_STR("Failed to add range to unsigned "
- "enumeration.");
- BT_FIELD_CLASS_PUT_REF_AND_RESET(out_field_class);
- ret = -1;
- goto error;
- }
+ label = bt_field_class_enumeration_mapping_get_label(mapping);
+ range_set = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ u_mapping);
+ ret = bt_field_class_unsigned_enumeration_add_mapping(
+ out_field_class, label, range_set);
+ if (ret) {
+ goto error;
}
}
bt_field_class_enumeration_get_mapping_count(in_field_class);
for (i = 0; i < enum_mapping_count; i++) {
const char *label;
- const bt_field_class_signed_enumeration_mapping *i_mapping;
+ const bt_integer_range_set_signed *range_set;
+ const bt_field_class_signed_enumeration_mapping *s_mapping;
const bt_field_class_enumeration_mapping *mapping;
- uint64_t range_index, range_count;
- /* Get the ranges and the range count. */
- i_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
+ s_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
in_field_class, i);
mapping = bt_field_class_signed_enumeration_mapping_as_mapping_const(
- i_mapping);
- range_count =
- bt_field_class_enumeration_mapping_get_range_count(
- mapping);
- label = bt_field_class_enumeration_mapping_get_label(
- mapping);
-
- /*
- * Iterate over all the ranges to add them to copied field
- * class.
- */
- for (range_index = 0; range_index < range_count; range_index++) {
- int64_t lower, upper;
- bt_field_class_signed_enumeration_mapping_get_range_by_index(
- i_mapping, range_index, &lower, &upper);
-
- BT_COMP_LOGD("Copying range in enumeration field class: "
- "label=%s, lower=%"PRId64", upper=%"PRId64,
- label, lower, upper);
-
- /* Add the label and its range to the copy field class. */
- if (bt_field_class_signed_enumeration_map_range(
- out_field_class, label, lower, upper) !=
- BT_FIELD_CLASS_ENUMERATION_MAP_RANGE_STATUS_OK) {
- BT_COMP_LOGE_STR("Failed to add range to signed "
- "enumeration.");
- BT_FIELD_CLASS_PUT_REF_AND_RESET(out_field_class);
- ret = -1;
- goto error;
- }
+ s_mapping);
+ label = bt_field_class_enumeration_mapping_get_label(mapping);
+ range_set = bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ s_mapping);
+ ret = bt_field_class_signed_enumeration_add_mapping(
+ out_field_class, label, range_set);
+ if (ret) {
+ goto error;
}
}
{
bt_field_class *out_tag_field_class = NULL;
uint64_t i, variant_option_count;
- const bt_field_path *tag_fp;
- const bt_field_class *tag_fc;
+ bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
int ret = 0;
BT_COMP_LOGD("Copying content of variant field class: "
"in-fc-addr=%p, out-fc-addr=%p",
in_field_class, out_field_class);
-
- tag_fp = bt_field_class_variant_borrow_selector_field_path_const(
- in_field_class);
- if (tag_fp) {
- tag_fc = resolve_field_path_to_field_class(tag_fp,
- md_maps);
-
- out_tag_field_class = g_hash_table_lookup(
- md_maps->field_class_map, tag_fc);
- if (!out_tag_field_class) {
- BT_COMP_LOGE_STR("Cannot find the tag field class.");
- ret = -1;
- goto error;
- }
- bt_field_class_variant_set_selector_field_class(out_field_class,
- out_tag_field_class);
- }
-
variant_option_count =
bt_field_class_variant_get_option_count(in_field_class);
for (i = 0; i < variant_option_count; i++) {
goto error;
}
- if (bt_field_class_variant_append_option(
- out_field_class, option_name,
- out_option_field_class) !=
- BT_FIELD_CLASS_VARIANT_APPEND_OPTION_STATUS_OK) {
- BT_COMP_LOGE_STR("Cannot append option to variant field class'");
- BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
- ret = -1;
- goto error;
+ if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
+ const bt_field_class_variant_with_unsigned_selector_option *spec_opt =
+ bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
+ in_field_class, i);
+ const bt_integer_range_set_unsigned *ranges =
+ bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ spec_opt);
+
+ if (bt_field_class_variant_with_unsigned_selector_append_option(
+ out_field_class, option_name,
+ out_option_field_class, ranges) !=
+ BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
+ BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned selector'");
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
+ ret = -1;
+ goto error;
+ }
+ } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
+ const bt_field_class_variant_with_signed_selector_option *spec_opt =
+ bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ in_field_class, i);
+ const bt_integer_range_set_signed *ranges =
+ bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ spec_opt);
+
+ if (bt_field_class_variant_with_signed_selector_append_option(
+ out_field_class, option_name,
+ out_option_field_class, ranges) !=
+ BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
+ BT_COMP_LOGE_STR("Cannot append option to variant field class with signed selector'");
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
+ ret = -1;
+ goto error;
+ }
+ } else {
+ BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR);
+
+ if (bt_field_class_variant_without_selector_append_option(
+ out_field_class, option_name,
+ out_option_field_class) !=
+ BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK) {
+ BT_COMP_LOGE_STR("Cannot append option to variant field class'");
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
+ ret = -1;
+ goto error;
+ }
}
}
const bt_field_class *in_field_class)
{
bt_field_class *out_field_class = NULL;
+ bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
in_field_class);
- switch(bt_field_class_get_type(in_field_class)) {
+ switch (fc_type) {
case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
out_field_class = bt_field_class_unsigned_integer_create(
md_maps->output_trace_class);
out_elem_fc);
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
+ {
+ bt_field_class *out_sel_fc = NULL;
+
+ if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
+ fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
+ const bt_field_class *in_sel_fc;
+ const bt_field_path *sel_fp =
+ bt_field_class_variant_with_selector_borrow_selector_field_path_const(
+ in_field_class);
+
+ BT_ASSERT(sel_fp);
+ in_sel_fc = resolve_field_path_to_field_class(sel_fp,
+ md_maps);
+ BT_ASSERT(in_sel_fc);
+ out_sel_fc = g_hash_table_lookup(
+ md_maps->field_class_map, in_sel_fc);
+ BT_ASSERT(out_sel_fc);
+ }
+
out_field_class = bt_field_class_variant_create(
- md_maps->output_trace_class);
+ md_maps->output_trace_class, out_sel_fc);
break;
+ }
default:
abort();
}
ret = field_class_dynamic_array_copy(md_maps,
in_field_class, out_field_class);
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
ret = field_class_variant_copy(md_maps,
in_field_class, out_field_class);
break;
}
}
-struct enum_field_class_mapping_range {
+struct int_range {
union {
uint64_t u;
int64_t i;
/* Weak */
const char *label;
- /* Array of `struct enum_field_class_mapping_range` */
+ /* Array of `struct int_range` */
GArray *ranges;
};
}
static
-gint compare_enum_field_class_mapping_ranges_signed(
- struct enum_field_class_mapping_range *a,
- struct enum_field_class_mapping_range *b)
+gint compare_int_ranges_signed(struct int_range *a, struct int_range *b)
{
if (a->lower.i < b->lower.i) {
}
static
-gint compare_enum_field_class_mapping_ranges_unsigned(
- struct enum_field_class_mapping_range *a,
- struct enum_field_class_mapping_range *b)
+gint compare_int_ranges_unsigned(struct int_range *a, struct int_range *b)
{
if (a->lower.u < b->lower.u) {
return -1;
}
}
+static
+GArray *range_set_to_int_ranges(const void *spec_range_set, bool is_signed)
+{
+ uint64_t i;
+ const bt_integer_range_set *range_set;
+ GArray *ranges = g_array_new(FALSE, TRUE, sizeof(struct int_range));
+
+ if (!ranges) {
+ goto end;
+ }
+
+ if (is_signed) {
+ range_set = bt_integer_range_set_signed_as_range_set_const(
+ spec_range_set);
+ } else {
+ range_set = bt_integer_range_set_unsigned_as_range_set_const(
+ spec_range_set);
+ }
+
+ for (i = 0; i < bt_integer_range_set_get_range_count(range_set); i++) {
+ struct int_range range;
+
+ if (is_signed) {
+ const bt_integer_range_signed *orig_range =
+ bt_integer_range_set_signed_borrow_range_by_index_const(
+ spec_range_set, i);
+
+ range.lower.i = bt_integer_range_signed_get_lower(orig_range);
+ range.upper.i = bt_integer_range_signed_get_upper(orig_range);
+ } else {
+ const bt_integer_range_unsigned *orig_range =
+ bt_integer_range_set_unsigned_borrow_range_by_index_const(
+ spec_range_set, i);
+
+ range.lower.u = bt_integer_range_unsigned_get_lower(orig_range);
+ range.upper.u = bt_integer_range_unsigned_get_upper(orig_range);
+ }
+
+ g_array_append_val(ranges, range);
+ }
+
+ if (is_signed) {
+ g_array_sort(ranges, (GCompareFunc) compare_int_ranges_signed);
+ } else {
+ g_array_sort(ranges,
+ (GCompareFunc) compare_int_ranges_unsigned);
+ }
+
+end:
+ return ranges;
+}
+
static
void destroy_enum_field_class_mapping(struct enum_field_class_mapping *mapping)
{
}
static
-void write_enum_field_class_mapping_range(struct details_write_ctx *ctx,
- struct enum_field_class_mapping_range *range, bool is_signed)
+struct int_range *int_range_at(GArray *ranges, uint64_t index)
+{
+ return &g_array_index(ranges, struct int_range, index);
+}
+
+static
+void write_int_range(struct details_write_ctx *ctx,
+ struct int_range *range, bool is_signed)
{
g_string_append(ctx->str, "[");
write_int_prop_value(ctx, range->lower.u);
}
- g_string_append(ctx->str, ", ");
+ if (range->lower.u != range->upper.u) {
+ g_string_append(ctx->str, ", ");
- if (is_signed) {
- write_int_prop_value(ctx, range->upper.i);
- } else {
- write_int_prop_value(ctx, range->upper.u);
+ if (is_signed) {
+ write_int_prop_value(ctx, range->upper.i);
+ } else {
+ write_int_prop_value(ctx, range->upper.u);
+ }
}
g_string_append(ctx->str, "]");
*/
for (i = 0; i < bt_field_class_enumeration_get_mapping_count(fc); i++) {
const void *fc_mapping;
+ const void *fc_range_set;
struct enum_field_class_mapping *mapping = g_new0(
struct enum_field_class_mapping, 1);
BT_ASSERT(mapping);
- mapping->ranges = g_array_new(FALSE, TRUE,
- sizeof(struct enum_field_class_mapping_range));
- BT_ASSERT(mapping->ranges);
if (is_signed) {
fc_mapping = bt_field_class_signed_enumeration_borrow_mapping_by_index_const(
fc, i);
+ fc_range_set = bt_field_class_signed_enumeration_mapping_borrow_ranges_const(
+ fc_mapping);
} else {
fc_mapping = bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const(
fc, i);
+ fc_range_set = bt_field_class_unsigned_enumeration_mapping_borrow_ranges_const(
+ fc_mapping);
}
mapping->label = bt_field_class_enumeration_mapping_get_label(
bt_field_class_signed_enumeration_mapping_as_mapping_const(
fc_mapping));
-
- for (range_i = 0;
- range_i < bt_field_class_enumeration_mapping_get_range_count(
- bt_field_class_signed_enumeration_mapping_as_mapping_const(fc_mapping));
- range_i++) {
- struct enum_field_class_mapping_range range;
-
- if (is_signed) {
- bt_field_class_signed_enumeration_mapping_get_range_by_index(
- fc_mapping, range_i,
- &range.lower.i, &range.upper.i);
- } else {
- bt_field_class_unsigned_enumeration_mapping_get_range_by_index(
- fc_mapping, range_i,
- &range.lower.u, &range.upper.u);
- }
-
- g_array_append_val(mapping->ranges, range);
- }
-
+ mapping->ranges = range_set_to_int_ranges(fc_range_set,
+ is_signed);
+ BT_ASSERT(mapping->ranges);
g_ptr_array_add(mappings, mapping);
}
- /* Sort mappings, and for each mapping, sort ranges */
+ /* Sort mappings (ranges are already sorted within mappings) */
g_ptr_array_sort(mappings,
(GCompareFunc) compare_enum_field_class_mappings);
- for (i = 0; i < mappings->len; i++) {
- struct enum_field_class_mapping *mapping = mappings->pdata[i];
-
- if (is_signed) {
- g_array_sort(mapping->ranges,
- (GCompareFunc)
- compare_enum_field_class_mapping_ranges_signed);
- } else {
- g_array_sort(mapping->ranges,
- (GCompareFunc)
- compare_enum_field_class_mapping_ranges_unsigned);
- }
- }
-
/* Write mappings */
for (i = 0; i < mappings->len; i++) {
struct enum_field_class_mapping *mapping = mappings->pdata[i];
write_nl(ctx);
write_compound_member_name(ctx, mapping->label);
- if (mapping->ranges->len == 1) {
- /* Single one: write on same line */
- write_sp(ctx);
- write_enum_field_class_mapping_range(ctx,
- &g_array_index(mapping->ranges,
- struct enum_field_class_mapping_range,
- 0), is_signed);
- continue;
- }
-
- incr_indent(ctx);
-
for (range_i = 0; range_i < mapping->ranges->len; range_i++) {
- write_nl(ctx);
- write_indent(ctx);
- write_enum_field_class_mapping_range(ctx,
- &g_array_index(mapping->ranges,
- struct enum_field_class_mapping_range,
- range_i), is_signed);
+ write_sp(ctx);
+ write_int_range(ctx,
+ int_range_at(mapping->ranges, range_i),
+ is_signed);
}
-
- decr_indent(ctx);
}
g_ptr_array_free(mappings, TRUE);
}
static
-void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc,
- const char *name)
+void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc);
+
+static
+void write_variant_field_class_option(struct details_write_ctx *ctx,
+ const bt_field_class *fc, uint64_t index)
{
- uint64_t i;
- const char *type;
bt_field_class_type fc_type = bt_field_class_get_type(fc);
+ const bt_field_class_variant_option *option =
+ bt_field_class_variant_borrow_option_by_index_const(
+ fc, index);
+ const void *orig_ranges;
+ GArray *int_ranges = NULL;
+ bool is_signed;
- /* Write field class's name */
- if (name) {
- write_compound_member_name(ctx, name);
+ write_nl(ctx);
+ write_compound_member_name(ctx,
+ bt_field_class_variant_option_get_name(option));
+
+ if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
+ const bt_field_class_variant_with_unsigned_selector_option *spec_opt =
+ bt_field_class_variant_with_unsigned_selector_borrow_option_by_index_const(
+ fc, index);
+
+ orig_ranges =
+ bt_field_class_variant_with_unsigned_selector_option_borrow_ranges_const(
+ spec_opt);
+ is_signed = false;
+ } else {
+ const bt_field_class_variant_with_signed_selector_option *spec_opt =
+ bt_field_class_variant_with_signed_selector_borrow_option_by_index_const(
+ fc, index);
+
+ orig_ranges =
+ bt_field_class_variant_with_signed_selector_option_borrow_ranges_const(
+ spec_opt);
+ is_signed = true;
+ }
+
+ if (orig_ranges) {
+ uint64_t i;
+
+ int_ranges = range_set_to_int_ranges(orig_ranges, is_signed);
+ BT_ASSERT(int_ranges);
+
+ for (i = 0; i < int_ranges->len; i++) {
+ struct int_range *range = int_range_at(int_ranges, i);
+
+ write_sp(ctx);
+ write_int_range(ctx, range, is_signed);
+ }
+
+ g_string_append(ctx->str, ": ");
+ } else {
write_sp(ctx);
}
+ write_field_class(ctx,
+ bt_field_class_variant_option_borrow_field_class_const(option));
+
+ if (int_ranges) {
+ g_array_free(int_ranges, TRUE);
+ }
+}
+
+static
+void write_variant_field_class(struct details_write_ctx *ctx,
+ const bt_field_class *fc)
+{
+ bt_field_class_type fc_type = bt_field_class_get_type(fc);
+ uint64_t option_count =
+ bt_field_class_variant_get_option_count(fc);
+ const bt_field_path *sel_field_path = NULL;
+
+ if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR) {
+ sel_field_path =
+ bt_field_class_variant_with_selector_borrow_selector_field_path_const(
+ fc);
+ BT_ASSERT(sel_field_path);
+ }
+
+ g_string_append(ctx->str, " (");
+ write_uint_prop_value(ctx, option_count);
+ g_string_append_printf(ctx->str, " option%s, ",
+ plural(option_count));
+
+ if (sel_field_path) {
+ g_string_append(ctx->str, "Selector field path ");
+ write_field_path(ctx, sel_field_path);
+ }
+
+ g_string_append_c(ctx->str, ')');
+
+ if (option_count > 0) {
+ uint64_t i;
+
+ g_string_append_c(ctx->str, ':');
+ incr_indent(ctx);
+
+ for (i = 0; i < option_count; i++) {
+ write_variant_field_class_option(ctx, fc, i);
+ }
+
+ decr_indent(ctx);
+ }
+}
+
+static
+void write_field_class(struct details_write_ctx *ctx, const bt_field_class *fc)
+{
+ uint64_t i;
+ const char *type;
+ bt_field_class_type fc_type = bt_field_class_get_type(fc);
+
/* Write field class's type */
switch (fc_type) {
case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
type = "Dynamic array";
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
- type = "Variant";
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
+ type = "Variant (no selector)";
+ break;
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
+ type = "Variant (unsigned selector)";
+ break;
+ case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
+ type = "Variant (signed selector)";
break;
default:
abort();
fc, i);
write_nl(ctx);
- write_field_class(ctx,
- bt_field_class_structure_member_borrow_field_class_const(member),
+ write_compound_member_name(ctx,
bt_field_class_structure_member_get_name(member));
+ write_sp(ctx);
+ write_field_class(ctx,
+ bt_field_class_structure_member_borrow_field_class_const(member));
}
decr_indent(ctx);
g_string_append_c(ctx->str, ':');
write_nl(ctx);
incr_indent(ctx);
+ write_compound_member_name(ctx, "Element");
+ write_sp(ctx);
write_field_class(ctx,
- bt_field_class_array_borrow_element_field_class_const(fc),
- "Element");
+ bt_field_class_array_borrow_element_field_class_const(fc));
decr_indent(ctx);
break;
- case BT_FIELD_CLASS_TYPE_VARIANT:
- {
- uint64_t option_count =
- bt_field_class_variant_get_option_count(fc);
- const bt_field_path *sel_field_path =
- bt_field_class_variant_borrow_selector_field_path_const(
- fc);
-
- g_string_append(ctx->str, " (");
- write_uint_prop_value(ctx, option_count);
- g_string_append_printf(ctx->str, " option%s, ",
- plural(option_count));
-
- if (sel_field_path) {
- g_string_append(ctx->str, "Selector field path ");
- write_field_path(ctx, sel_field_path);
- }
-
- g_string_append_c(ctx->str, ')');
-
- if (option_count > 0) {
- g_string_append_c(ctx->str, ':');
- incr_indent(ctx);
-
- for (i = 0; i < option_count; i++) {
- const bt_field_class_variant_option *option =
- bt_field_class_variant_borrow_option_by_index_const(
- fc, i);
-
- write_nl(ctx);
- write_field_class(ctx,
- bt_field_class_variant_option_borrow_field_class_const(option),
- bt_field_class_variant_option_get_name(option));
- }
-
- decr_indent(ctx);
- }
-
+ 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:
+ write_variant_field_class(ctx, fc);
break;
- }
default:
break;
}
write_indent(ctx);
write_prop_name(ctx, name);
g_string_append(ctx->str, ": ");
- write_field_class(ctx, fc, NULL);
+ write_field_class(ctx, fc);
write_nl(ctx);
}
decr_indent(ctx);
break;
}
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
write_field(ctx,
bt_field_variant_borrow_selected_option_field_const(
field), NULL);
case BT_FIELD_CLASS_TYPE_STRUCTURE:
return print_struct(pretty, field, print_names, filter_fields,
filter_array_len);
- case BT_FIELD_CLASS_TYPE_VARIANT:
+ 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:
return print_variant(pretty, field, print_names);
case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
return print_array(pretty, field, print_names);
+#5149916
+
SUBDIRS = utils lib bitfield ctf-writer plugins
# Directories added to EXTRA_DIST will be recursively copied to the distribution.
cc = None
if with_cc:
cc = tc.create_structure_field_class()
- cc += OrderedDict((
+ cc += [
('cpu_id', tc.create_signed_integer_field_class(8)),
('stuff', tc.create_real_field_class()),
- ))
+ ]
# packet context (stream-class-defined)
pc = None
if with_packet:
pc = tc.create_structure_field_class()
- pc += OrderedDict((
+ pc += [
('something', tc.create_unsigned_integer_field_class(8)),
('something_else', tc.create_real_field_class()),
- ))
+ ]
stream_class = tc.create_stream_class(default_clock_class=clock_class,
event_common_context_field_class=cc,
sc = None
if with_sc:
sc = tc.create_structure_field_class()
- sc += OrderedDict((
+ sc += [
('ant', tc.create_signed_integer_field_class(16)),
('msg', tc.create_string_field_class()),
- ))
+ ]
# event payload
ep = None
if with_ep:
ep = tc.create_structure_field_class()
- ep += OrderedDict((
+ ep += [
('giraffe', tc.create_signed_integer_field_class(32)),
('gnu', tc.create_signed_integer_field_class(8)),
('mosquito', tc.create_signed_integer_field_class(8)),
- ))
+ ]
event_class = stream_class.create_event_class(name='garou',
specific_context_field_class=sc,
class SignedEnumerationFieldTestCase(_TestIntegerFieldCommon, unittest.TestCase):
def _create_fc(self, tc):
fc = tc.create_signed_enumeration_field_class(32)
- fc.map_range('something', 17)
- fc.map_range('speaker', 12, 16)
- fc.map_range('can', 18, 2540)
- fc.map_range('whole range', -(2 ** 31), (2 ** 31) - 1)
- fc.map_range('zip', -45, 1001)
+ fc.add_mapping('something', bt2.SignedIntegerRangeSet([(17, 17)]))
+ fc.add_mapping('speaker', bt2.SignedIntegerRangeSet([(12, 16)]))
+ fc.add_mapping('can', bt2.SignedIntegerRangeSet([(18, 2540)]))
+ fc.add_mapping('whole range', bt2.SignedIntegerRangeSet([(-(2 ** 31), (2 ** 31) - 1)]))
+ fc.add_mapping('zip', bt2.SignedIntegerRangeSet([(-45, 1001)]))
return fc
def setUp(self):
class VariantFieldTestCase(unittest.TestCase):
def _create_fc(self, tc):
- selector_fc = tc.create_signed_enumeration_field_class(field_value_range=32)
- selector_fc.map_range('corner', 23)
- selector_fc.map_range('zoom', 17, 20)
- selector_fc.map_range('mellotron', 1001)
- selector_fc.map_range('giorgio', 2000, 3000)
-
ft0 = tc.create_signed_integer_field_class(32)
ft1 = tc.create_string_field_class()
ft2 = tc.create_real_field_class()
ft3 = tc.create_signed_integer_field_class(17)
-
fc = tc.create_variant_field_class()
fc.append_option('corner', ft0)
fc.append_option('zoom', ft1)
fc.append_option('mellotron', ft2)
fc.append_option('giorgio', ft3)
- fc.selector_field_class = selector_fc
-
top_fc = tc.create_structure_field_class()
- top_fc.append_member('selector_field', selector_fc)
top_fc.append_member('variant_field', fc)
return top_fc
import bt2.field
import unittest
import bt2
+import collections
from utils import get_default_trace_class
#
# [(lower0, upper0), (lower1, upper1), ...]
-def enum_mapping_to_list(mapping):
- return sorted([(x.lower, x.upper) for x in mapping])
+def enum_mapping_to_set(mapping):
+ return {(x.lower, x.upper) for x in mapping.ranges}
-class EnumerationFieldClassTestCase(_TestIntegerFieldClassProps):
+class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps):
def setUp(self):
self._tc = get_default_trace_class()
+ self._spec_set_up()
+ self._fc = self._create_func()
def test_create_from_invalid_type(self):
with self.assertRaises(TypeError):
self._create_func('coucou')
def test_add_mapping_simple(self):
- self._fc.map_range('hello', 24)
+ self._fc.add_mapping('hello', self._ranges1)
mapping = self._fc['hello']
self.assertEqual(mapping.label, 'hello')
-
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(24, 24)])
+ self.assertEqual(mapping.ranges, self._ranges1)
def test_add_mapping_simple_kwargs(self):
- self._fc.map_range(label='hello', lower=17, upper=23)
+ self._fc.add_mapping(label='hello', ranges=self._ranges1)
mapping = self._fc['hello']
self.assertEqual(mapping.label, 'hello')
+ self.assertEqual(mapping.ranges, self._ranges1)
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(17, 23)])
+ def test_add_mapping_invalid_name(self):
+ with self.assertRaises(TypeError):
+ self._fc.add_mapping(17, self._ranges1)
- def test_add_mapping_range(self):
- self._fc.map_range('hello', 21, 199)
- mapping = self._fc['hello']
- self.assertEqual(mapping.label, 'hello')
+ def test_add_mapping_invalid_range(self):
+ with self.assertRaises(TypeError):
+ self._fc.add_mapping('allo', 'meow')
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(21, 199)])
+ def test_add_mapping_dup_label(self):
+ with self.assertRaises(bt2.Error):
+ self._fc.add_mapping('a', self._ranges1)
+ self._fc.add_mapping('a', self._ranges2)
- def test_add_mapping_invalid_name(self):
+ def test_add_mapping_invalid_ranges_signedness(self):
with self.assertRaises(TypeError):
- self._fc.map_range(17, 21, 199)
+ self._fc.add_mapping('allo', self._inval_ranges)
def test_iadd(self):
- enum_fc = self._tc.create_signed_enumeration_field_class(field_value_range=16)
- enum_fc.map_range('c', 4, 5)
- enum_fc.map_range('d', 6, 18)
- enum_fc.map_range('e', 20, 27)
- self._fc.map_range('a', 0, 2)
- self._fc.map_range('b', 3)
- self._fc += enum_fc
+ self._fc.add_mapping('c', self._ranges1)
- self.assertEqual(self._fc['a'].label, 'a')
- self.assertEqual(enum_mapping_to_list(self._fc['a']), [(0, 2)])
-
- self.assertEqual(self._fc['b'].label, 'b')
- self.assertEqual(enum_mapping_to_list(self._fc['b']), [(3, 3)])
+ self._fc += [
+ ('d', self._ranges2),
+ ('e', self._ranges3),
+ ]
+ self.assertEqual(len(self._fc), 3)
self.assertEqual(self._fc['c'].label, 'c')
- self.assertEqual(enum_mapping_to_list(self._fc['c']), [(4, 5)])
-
+ self.assertEqual(self._fc['c'].ranges, self._ranges1)
self.assertEqual(self._fc['d'].label, 'd')
- self.assertEqual(enum_mapping_to_list(self._fc['d']), [(6, 18)])
-
+ self.assertEqual(self._fc['d'].ranges, self._ranges2)
self.assertEqual(self._fc['e'].label, 'e')
- self.assertEqual(enum_mapping_to_list(self._fc['e']), [(20, 27)])
+ self.assertEqual(self._fc['e'].ranges, self._ranges3)
def test_bool_op(self):
self.assertFalse(self._fc)
- self._fc.map_range('a', 0)
+ self._fc.add_mapping('a', self._ranges1)
self.assertTrue(self._fc)
def test_len(self):
- self._fc.map_range('a', 0)
- self._fc.map_range('b', 1)
- self._fc.map_range('c', 2)
+ self._fc.add_mapping('a', self._ranges1)
+ self._fc.add_mapping('b', self._ranges2)
+ self._fc.add_mapping('c', self._ranges3)
self.assertEqual(len(self._fc), 3)
def test_getitem(self):
- self._fc.map_range('a', 0)
- self._fc.map_range('b', 1, 3)
- self._fc.map_range('a', 5)
- self._fc.map_range('a', 17, 123)
- self._fc.map_range('C', 5)
+ self._fc.add_mapping('a', self._ranges1)
+ self._fc.add_mapping('b', self._ranges2)
+ self._fc.add_mapping('c', self._ranges3)
mapping = self._fc['a']
-
self.assertEqual(mapping.label, 'a')
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(0, 0), (5, 5), (17, 123)])
+ self.assertEqual(mapping.ranges, self._ranges1)
+ def test_getitem_nonexistent(self):
with self.assertRaises(KeyError):
self._fc['doesnotexist']
- def test_contains(self):
- self._fc.map_range('a', 0)
- self._fc.map_range('a', 2, 23)
- self._fc.map_range('b', 2)
- self._fc.map_range('c', 5)
-
- a_mapping = self._fc['a']
- b_mapping = self._fc['b']
- first_range = next(iter(a_mapping))
-
- self.assertIn(first_range, a_mapping)
- self.assertNotIn(first_range, b_mapping)
-
def test_iter(self):
- self._fc.map_range('a', 1, 5)
- self._fc.map_range('b', 10, 17)
- self._fc.map_range('c', 20, 1504)
-
- self._fc.map_range('d', 22510, 99999)
+ self._fc.add_mapping('a', self._ranges1)
+ self._fc.add_mapping('b', self._ranges2)
+ self._fc.add_mapping('c', self._ranges3)
# This exercises iteration.
labels = sorted(self._fc)
- self.assertEqual(labels, ['a', 'b', 'c', 'd'])
+ self.assertEqual(labels, ['a', 'b', 'c'])
def test_find_by_value(self):
- self._fc.map_range('a', 0)
- self._fc.map_range('b', 1, 3)
- self._fc.map_range('c', 5, 19)
- self._fc.map_range('d', 8, 15)
- self._fc.map_range('e', 10, 21)
- self._fc.map_range('f', 0)
- self._fc.map_range('g', 14)
-
- labels = self._fc.labels_for_value(14)
-
- expected_labels = ['c', 'd', 'e', 'g']
-
- self.assertTrue(all(label in labels for label in expected_labels))
-
-
-class UnsignedEnumerationFieldClassTestCase(EnumerationFieldClassTestCase, unittest.TestCase):
- def setUp(self):
- super().setUp()
+ self._fc.add_mapping('a', self._ranges1)
+ self._fc.add_mapping('b', self._ranges2)
+ self._fc.add_mapping('c', self._ranges3)
+ mappings = self._fc.mappings_for_value(self._value_in_range_1_and_3)
+ labels = set([mapping.label for mapping in mappings])
+ expected_labels = set(['a', 'c'])
+ self.assertEqual(labels, expected_labels)
+
+
+class UnsignedEnumerationFieldClassTestCase(_EnumerationFieldClassTestCase, unittest.TestCase):
+ def _spec_set_up(self):
+ self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
+ self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
+ self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 22), (48, 99)])
+ self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, -5), (48, 1928)])
+ self._value_in_range_1_and_3 = 20
self._create_func = self._tc.create_unsigned_enumeration_field_class
- self._fc = self._tc.create_unsigned_enumeration_field_class()
-
- def test_add_mapping_invalid_signedness_lower(self):
- with self.assertRaises(ValueError):
- self._fc.map_range('hello', -21, 199)
- def test_add_mapping_invalid_signedness_upper(self):
- with self.assertRaises(ValueError):
- self._fc.map_range('hello', 21, -199)
-
-class SignedEnumerationFieldClassTestCase(EnumerationFieldClassTestCase, unittest.TestCase):
- def setUp(self):
- super().setUp()
+class SignedEnumerationFieldClassTestCase(_EnumerationFieldClassTestCase, unittest.TestCase):
+ def _spec_set_up(self):
+ self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
+ self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
+ self._ranges3 = bt2.SignedIntegerRangeSet([(-100, -1), (8, 16), (48, 99)])
+ self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
+ self._value_in_range_1_and_3 = -7
self._create_func = self._tc.create_signed_enumeration_field_class
- self._fc = self._tc.create_signed_enumeration_field_class()
-
- def test_add_mapping_simple_signed(self):
- self._fc.map_range('hello', -24)
- mapping = self._fc['hello']
- self.assertEqual(mapping.label, 'hello')
-
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(-24, -24)])
-
- def test_add_mapping_range_signed(self):
- self._fc.map_range('hello', -21, 199)
- mapping = self._fc['hello']
- self.assertEqual(mapping.label, 'hello')
- ranges = enum_mapping_to_list(mapping)
- self.assertEqual(ranges, [(-21, 199)])
class StringFieldClassTestCase(unittest.TestCase):
self.assertIsNotNone(self._fc)
-class _TestFieldContainer():
+class _TestElementContainer():
+ def setUp(self):
+ self._tc = get_default_trace_class()
+ self._fc = self._create_default_fc()
+
+ def test_create_default(self):
+ self.assertIsNotNone(self._fc)
+
def test_append_element(self):
int_field_class = self._tc.create_signed_integer_field_class(32)
self._append_element_method(self._fc, 'int32', int_field_class)
- field_class = self._fc['int32']
+ field_class = self._fc['int32'].field_class
self.assertEqual(field_class.addr, int_field_class.addr)
- def test_append_elemenbt_kwargs(self):
+ def test_append_element_kwargs(self):
int_field_class = self._tc.create_signed_integer_field_class(32)
self._append_element_method(self._fc, name='int32', field_class=int_field_class)
- field_class = self._fc['int32']
+ field_class = self._fc['int32'].field_class
self.assertEqual(field_class.addr, int_field_class.addr)
def test_append_element_invalid_name(self):
with self.assertRaises(TypeError):
self._append_element_method(self._fc, 'yes', object())
+ def test_append_element_dup_name(self):
+ sub_fc1 = self._tc.create_string_field_class()
+ sub_fc2 = self._tc.create_string_field_class()
+
+ with self.assertRaises(bt2.Error):
+ self._append_element_method(self._fc, 'yes', sub_fc1)
+ self._append_element_method(self._fc, 'yes', sub_fc2)
+
def test_iadd(self):
- struct_fc = self._tc.create_structure_field_class()
- c_field_class = self._tc.create_string_field_class()
- d_field_class = self._tc.create_signed_enumeration_field_class(field_value_range=32)
- e_field_class = self._tc.create_structure_field_class()
- self._append_element_method(struct_fc, 'c_string', c_field_class)
- self._append_element_method(struct_fc, 'd_enum', d_field_class)
- self._append_element_method(struct_fc, 'e_struct', e_field_class)
+ other_fc = self._create_default_fc()
a_field_class = self._tc.create_real_field_class()
b_field_class = self._tc.create_signed_integer_field_class(17)
self._append_element_method(self._fc, 'a_float', a_field_class)
self._append_element_method(self._fc, 'b_int', b_field_class)
- self._fc += struct_fc
- self.assertEqual(self._fc['a_float'].addr, a_field_class.addr)
- self.assertEqual(self._fc['b_int'].addr, b_field_class.addr)
- self.assertEqual(self._fc['c_string'].addr, c_field_class.addr)
- self.assertEqual(self._fc['d_enum'].addr, d_field_class.addr)
- self.assertEqual(self._fc['e_struct'].addr, e_field_class.addr)
+ c_field_class = self._tc.create_string_field_class()
+ d_field_class = self._tc.create_signed_enumeration_field_class(field_value_range=32)
+ e_field_class = self._tc.create_structure_field_class()
+ self._fc += [
+ ('c_string', c_field_class),
+ ('d_enum', d_field_class),
+ ('e_struct', e_field_class),
+ ]
+ self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
+ self.assertEqual(self._fc['a_float'].name, 'a_float')
+ self.assertEqual(self._fc['b_int'].field_class.addr, b_field_class.addr)
+ self.assertEqual(self._fc['b_int'].name, 'b_int')
+ self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
+ self.assertEqual(self._fc['c_string'].name, 'c_string')
+ self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
+ self.assertEqual(self._fc['d_enum'].name, 'd_enum')
+ self.assertEqual(self._fc['e_struct'].field_class.addr, e_field_class.addr)
+ self.assertEqual(self._fc['e_struct'].name, 'e_struct')
def test_bool_op(self):
self.assertFalse(self._fc)
self.assertTrue(self._fc)
def test_len(self):
- fc = self._tc.create_string_field_class()
- self._append_element_method(self._fc, 'a', fc)
- self._append_element_method(self._fc, 'b', fc)
- self._append_element_method(self._fc, 'c', fc)
+ self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
+ self._append_element_method(self._fc, 'b', self._tc.create_string_field_class())
+ self._append_element_method(self._fc, 'c', self._tc.create_string_field_class())
self.assertEqual(len(self._fc), 3)
def test_getitem(self):
self._append_element_method(self._fc, 'a', a_fc)
self._append_element_method(self._fc, 'b', b_fc)
self._append_element_method(self._fc, 'c', c_fc)
- self.assertEqual(self._fc['b'].addr, b_fc.addr)
+ self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
+ self.assertEqual(self._fc['b'].name, 'b')
def test_getitem_invalid_key_type(self):
with self.assertRaises(TypeError):
a_fc = self._tc.create_signed_integer_field_class(32)
b_fc = self._tc.create_string_field_class()
c_fc = self._tc.create_real_field_class()
- fields = (
+ elements = (
('a', a_fc),
('b', b_fc),
('c', c_fc),
)
- for field in fields:
- self._append_element_method(self._fc, *field)
+ for elem in elements:
+ self._append_element_method(self._fc, *elem)
- for (name, fc_field_class), field in zip(self._fc.items(), fields):
- self.assertEqual(name, field[0])
- self.assertEqual(fc_field_class.addr, field[1].addr)
+ for (name, element), test_elem in zip(self._fc.items(), elements):
+ self.assertEqual(element.name, test_elem[0])
+ self.assertEqual(name, element.name)
+ self.assertEqual(element.field_class.addr, test_elem[1].addr)
def test_at_index(self):
a_fc = self._tc.create_signed_integer_field_class(32)
self._append_element_method(self._fc, 'c', c_fc)
self._append_element_method(self._fc, 'a', a_fc)
self._append_element_method(self._fc, 'b', b_fc)
- self.assertEqual(self._at_index_method(self._fc, 1).addr, a_fc.addr)
+ elem = self._at_index_method(self._fc, 1)
+ self.assertEqual(elem.field_class.addr, a_fc.addr)
+ self.assertEqual(elem.name, 'a')
def test_at_index_invalid(self):
self._append_element_method(self._fc, 'c', self._tc.create_signed_integer_field_class(32))
self._at_index_method(self._fc, len(self._fc))
-class StructureFieldClassTestCase(_TestFieldContainer, unittest.TestCase):
+class StructureFieldClassTestCase(_TestElementContainer, unittest.TestCase):
+ _append_element_method = staticmethod(bt2.field_class._StructureFieldClass.append_member)
+ _at_index_method = staticmethod(bt2.field_class._StructureFieldClass.member_at_index)
+
+ def _create_default_fc(self):
+ return self._tc.create_structure_field_class()
+
+
+class VariantFieldClassWithoutSelectorTestCase(_TestElementContainer, unittest.TestCase):
+ _append_element_method = staticmethod(bt2.field_class._VariantFieldClassWithoutSelector.append_option)
+ _at_index_method = staticmethod(bt2.field_class._VariantFieldClassWithoutSelector.option_at_index)
+
+ def _create_default_fc(self):
+ return self._tc.create_variant_field_class()
+
+
+class _VariantFieldClassWithSelectorTestCase:
def setUp(self):
- self._append_element_method = bt2.field_class._StructureFieldClass.append_member
- self._at_index_method = bt2.field_class._StructureFieldClass.member_at_index
self._tc = get_default_trace_class()
- self._fc = self._tc.create_structure_field_class()
+ self._spec_set_up()
+ self._fc = self._create_default_fc()
+
+ def _create_default_fc(self):
+ return self._tc.create_variant_field_class(self._selector_fc)
def test_create_default(self):
self.assertIsNotNone(self._fc)
+ def test_append_element(self):
+ str_field_class = self._tc.create_string_field_class()
+ self._fc.append_option('str', str_field_class, self._ranges1)
+ opt = self._fc['str']
+ self.assertEqual(opt.field_class.addr, str_field_class.addr)
+ self.assertEqual(opt.name, 'str')
+ self.assertEqual(opt.ranges.addr, self._ranges1.addr)
+
+ def test_append_element_kwargs(self):
+ int_field_class = self._tc.create_signed_integer_field_class(32)
+ self._fc.append_option(name='int32', field_class=int_field_class,
+ ranges=self._ranges1)
+ opt = self._fc['int32']
+ self.assertEqual(opt.field_class.addr, int_field_class.addr)
+ self.assertEqual(opt.name, 'int32')
+ self.assertEqual(opt.ranges.addr, self._ranges1.addr)
+
+ def test_append_element_invalid_name(self):
+ sub_fc = self._tc.create_string_field_class()
-class VariantFieldClassTestCase(_TestFieldContainer, unittest.TestCase):
- def setUp(self):
- self._append_element_method = bt2.field_class._VariantFieldClass.append_option
- self._at_index_method = bt2.field_class._VariantFieldClass.option_at_index
- self._tc = get_default_trace_class()
- self._fc = self._tc.create_variant_field_class()
+ with self.assertRaises(TypeError):
+ self._fc.append_option(self._fc, 23, sub_fc)
- def test_create_default(self):
- fc = self._tc.create_variant_field_class()
+ def test_append_element_invalid_field_class(self):
+ with self.assertRaises(TypeError):
+ self._fc.append_option(self._fc, 'yes', object())
- self.assertIsNone(fc.selector_field_path)
+ def test_append_element_invalid_ranges(self):
+ sub_fc = self._tc.create_string_field_class()
- def _create_field_class_for_field_path_test(self):
+ with self.assertRaises(TypeError):
+ self._fc.append_option(self._fc, sub_fc, 'lel')
+
+ def test_append_element_dup_name(self):
+ sub_fc1 = self._tc.create_string_field_class()
+ sub_fc2 = self._tc.create_string_field_class()
+
+ with self.assertRaises(bt2.Error):
+ self._fc.append_option('yes', sub_fc1, self._ranges1)
+ self._fc.append_option('yes', sub_fc2, self._ranges2)
+
+ def test_append_element_invalid_ranges_signedness(self):
+ sub_fc = self._tc.create_string_field_class()
+
+ with self.assertRaises(TypeError):
+ self._fc.append_option(self._fc, sub_fc, self._inval_ranges)
+
+ def test_iadd(self):
+ other_fc = self._create_default_fc()
+ a_field_class = self._tc.create_real_field_class()
+ self._fc.append_option('a_float', a_field_class, self._ranges1)
+ c_field_class = self._tc.create_string_field_class()
+ d_field_class = self._tc.create_signed_enumeration_field_class(field_value_range=32)
+ self._fc += [
+ ('c_string', c_field_class, self._ranges2),
+ ('d_enum', d_field_class, self._ranges3),
+ ]
+ self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
+ self.assertEqual(self._fc['a_float'].name, 'a_float')
+ self.assertEqual(self._fc['a_float'].ranges, self._ranges1)
+ self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
+ self.assertEqual(self._fc['c_string'].name, 'c_string')
+ self.assertEqual(self._fc['c_string'].ranges, self._ranges2)
+ self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
+ self.assertEqual(self._fc['d_enum'].name, 'd_enum')
+ self.assertEqual(self._fc['d_enum'].ranges, self._ranges3)
+
+ def test_bool_op(self):
+ self.assertFalse(self._fc)
+ self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
+ self.assertTrue(self._fc)
+
+ def test_len(self):
+ self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
+ self._fc.append_option('b', self._tc.create_string_field_class(), self._ranges2)
+ self._fc.append_option('c', self._tc.create_string_field_class(), self._ranges3)
+ self.assertEqual(len(self._fc), 3)
+
+ def test_getitem(self):
+ a_fc = self._tc.create_signed_integer_field_class(32)
+ b_fc = self._tc.create_string_field_class()
+ c_fc = self._tc.create_real_field_class()
+ self._fc.append_option('a', a_fc, self._ranges1)
+ self._fc.append_option('b', b_fc, self._ranges2)
+ self._fc.append_option('c', c_fc, self._ranges3)
+ self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
+ self.assertEqual(self._fc['b'].name, 'b')
+ self.assertEqual(self._fc['b'].ranges.addr, self._ranges2.addr)
+
+ def test_getitem_invalid_key_type(self):
+ with self.assertRaises(TypeError):
+ self._fc[0]
+
+ def test_getitem_invalid_key(self):
+ with self.assertRaises(KeyError):
+ self._fc['no way']
+
+ def test_contains(self):
+ self.assertFalse('a' in self._fc)
+ self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
+ self.assertTrue('a' in self._fc)
+
+ def test_iter(self):
+ a_fc = self._tc.create_signed_integer_field_class(32)
+ b_fc = self._tc.create_string_field_class()
+ c_fc = self._tc.create_real_field_class()
+ opts = (
+ ('a', a_fc, self._ranges1),
+ ('b', b_fc, self._ranges2),
+ ('c', c_fc, self._ranges3),
+ )
+
+ for opt in opts:
+ self._fc.append_option(*opt)
+
+ for (name, opt), test_opt in zip(self._fc.items(), opts):
+ self.assertEqual(opt.name, test_opt[0])
+ self.assertEqual(name, opt.name)
+ self.assertEqual(opt.field_class.addr, test_opt[1].addr)
+ self.assertEqual(opt.ranges.addr, test_opt[2].addr)
+
+ def test_at_index(self):
+ a_fc = self._tc.create_signed_integer_field_class(32)
+ b_fc = self._tc.create_string_field_class()
+ c_fc = self._tc.create_real_field_class()
+ self._fc.append_option('c', c_fc, self._ranges1)
+ self._fc.append_option('a', a_fc, self._ranges2)
+ self._fc.append_option('b', b_fc, self._ranges3)
+ self.assertEqual(self._fc.option_at_index(1).field_class.addr, a_fc.addr)
+ self.assertEqual(self._fc.option_at_index(1).name, 'a')
+ self.assertEqual(self._fc.option_at_index(1).ranges.addr, self._ranges2.addr)
+
+ def test_at_index_invalid(self):
+ self._fc.append_option('c', self._tc.create_signed_integer_field_class(32), self._ranges3)
+
+ with self.assertRaises(TypeError):
+ self._fc.option_at_index('yes')
+
+ def test_at_index_out_of_bounds_after(self):
+ self._fc.append_option('c', self._tc.create_signed_integer_field_class(32), self._ranges3)
+
+ with self.assertRaises(IndexError):
+ self._fc.option_at_index(len(self._fc))
+
+ def _fill_default_fc_for_field_path_test(self):
# Create something equivalent to:
#
# struct outer_struct_fc {
# real foo;
# struct inner_struct_fc {
- # enum { first = 1, second = 2..434 } selector;
+ # [u]int64_t selector;
# string bar;
# string baz;
- # variant<selector> {
- # real a;
- # int21_t b;
- # uint34_t c;
+ # variant <selector> {
+ # real a; // selected with self._ranges1
+ # int21_t b; // selected with self._ranges2
+ # uint34_t c; // selected with self._ranges3
# } variant;
# } inner_struct[2];
# };
- selector_fc = self._tc.create_unsigned_enumeration_field_class(field_value_range=42)
- selector_fc.map_range('first', 1)
- selector_fc.map_range('second', 2, 434)
-
- fc = self._tc.create_variant_field_class(selector_fc)
- fc.append_option('a', self._tc.create_real_field_class())
- fc.append_option('b', self._tc.create_signed_integer_field_class(21))
- fc.append_option('c', self._tc.create_unsigned_integer_field_class(34))
+ self._fc.append_option('a', self._tc.create_real_field_class(), self._ranges1)
+ self._fc.append_option('b', self._tc.create_signed_integer_field_class(21), self._ranges2)
+ self._fc.append_option('c', self._tc.create_unsigned_integer_field_class(34), self._ranges3)
foo_fc = self._tc.create_real_field_class()
bar_fc = self._tc.create_string_field_class()
baz_fc = self._tc.create_string_field_class()
inner_struct_fc = self._tc.create_structure_field_class()
- inner_struct_fc.append_member('selector', selector_fc)
+ inner_struct_fc.append_member('selector', self._selector_fc)
inner_struct_fc.append_member('bar', bar_fc)
inner_struct_fc.append_member('baz', baz_fc)
- inner_struct_fc.append_member('variant', fc)
+ inner_struct_fc.append_member('variant', self._fc)
inner_struct_array_fc = self._tc.create_static_array_field_class(inner_struct_fc, 2)
# The path to the selector field is resolved when the sequence is
# actually used, for example in a packet context.
- self._tc.create_stream_class(supports_packets=True, packet_context_field_class=outer_struct_fc)
-
- return fc
+ self._tc.create_stream_class(supports_packets=True,
+ packet_context_field_class=outer_struct_fc)
def test_selector_field_path_length(self):
- fc = self._create_field_class_for_field_path_test()
- self.assertEqual(len(fc.selector_field_path), 3)
+ self._fill_default_fc_for_field_path_test()
+ self.assertEqual(len(self._fc.selector_field_path), 3)
def test_selector_field_path_iter(self):
- fc = self._create_field_class_for_field_path_test()
- path_items = list(fc.selector_field_path)
+ self._fill_default_fc_for_field_path_test()
+ path_items = list(self._fc.selector_field_path)
self.assertEqual(len(path_items), 3)
self.assertEqual(path_items[2].index, 0)
def test_selector_field_path_root_scope(self):
- fc = self._create_field_class_for_field_path_test()
- self.assertEqual(fc.selector_field_path.root_scope, bt2.field_path.Scope.PACKET_CONTEXT)
+ self._fill_default_fc_for_field_path_test()
+ self.assertEqual(self._fc.selector_field_path.root_scope, bt2.field_path.Scope.PACKET_CONTEXT)
+
+
+class VariantFieldClassWithUnsignedSelectorTestCase(_VariantFieldClassWithSelectorTestCase, unittest.TestCase):
+ def _spec_set_up(self):
+ self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
+ self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
+ self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
+ self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, 16), (48, 99)])
+ self._selector_fc = self._tc.create_unsigned_integer_field_class()
+
+
+class VariantFieldClassWithSignedSelectorTestCase(_VariantFieldClassWithSelectorTestCase, unittest.TestCase):
+ def _spec_set_up(self):
+ self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
+ self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
+ self._ranges3 = bt2.SignedIntegerRangeSet([(8, 16), (48, 99)])
+ self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
+ self._selector_fc = self._tc.create_signed_integer_field_class()
class StaticArrayFieldClassTestCase(unittest.TestCase):
self._ec = self._sc.create_event_class(name='salut')
self._my_int_ft = self._tc.create_signed_integer_field_class(32)
payload_ft = self._tc.create_structure_field_class()
- payload_ft += collections.OrderedDict([
+ payload_ft += [
('my_int', self._my_int_ft),
- ])
+ ]
self._ec.payload_field_type = payload_ft
self._stream = self._t.create_stream(self._sc)
self._packet = self._stream.create_packet()
# Create payload field class
my_int_fc = tc.create_signed_integer_field_class(32)
payload_fc = tc.create_structure_field_class()
- payload_fc += collections.OrderedDict([
+ payload_fc += [
('my_int', my_int_fc),
- ])
+ ]
ec = sc.create_event_class(name='salut', payload_field_class=payload_fc)
# Create payload field class
my_int_ft = trace_class.create_signed_integer_field_class(32)
payload_ft = trace_class.create_structure_field_class()
- payload_ft += collections.OrderedDict([
+ payload_ft += [
('my_int', my_int_ft),
- ])
+ ]
event_class = stream_class.create_event_class(name='salut', payload_field_class=payload_ft)
# stream event context
sec = tc.create_structure_field_class()
- sec += OrderedDict((
+ sec += [
('cpu_id', tc.create_signed_integer_field_class(8)),
('stuff', tc.create_real_field_class()),
- ))
+ ]
# packet context
pc = None
if with_pc:
pc = tc.create_structure_field_class()
- pc += OrderedDict((
+ pc += [
('something', tc.create_signed_integer_field_class(8)),
('something_else', tc.create_real_field_class()),
('events_discarded', tc.create_unsigned_integer_field_class(64)),
('packet_seq_num', tc.create_unsigned_integer_field_class(64)),
- ))
+ ]
# stream class
sc = tc.create_stream_class(default_clock_class=clock_class,
# event context
ec = tc.create_structure_field_class()
- ec += OrderedDict((
+ ec += [
('ant', tc.create_signed_integer_field_class(16)),
('msg', tc.create_string_field_class()),
- ))
+ ]
# event payload
ep = tc.create_structure_field_class()
- ep += OrderedDict((
+ ep += [
('giraffe', tc.create_signed_integer_field_class(32)),
('gnu', tc.create_signed_integer_field_class(8)),
('mosquito', tc.create_signed_integer_field_class(8)),
- ))
+ ]
# event class
event_class = sc.create_event_class(name='ec', payload_field_class=ep)
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = be;
+};
+
+event {
+ name = yo;
+ fields := struct {
+ enum : integer { size = 8; } {
+ COSSETTE,
+ PELCHAT,
+ VOISINE,
+ } tag;
+
+ variant <tag> {
+ string COSSETTE;
+ string PELCHAT;
+ string VOISINE;
+ } var;
+ };
+};
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = be;
+};
+
+event {
+ name = yo;
+ fields := struct {
+ enum : integer { size = 8; } {
+ COSSETTE,
+ PELCHAT,
+ _VOISINE,
+ } tag;
+
+ variant <tag> {
+ string COSSETTE;
+ string PELCHAT;
+ string _VOISINE;
+ } var;
+ };
+};
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = be;
+};
+
+event {
+ name = yo;
+ fields := struct {
+ enum : integer { size = 8; } {
+ _align,
+ _callsite,
+ _const,
+ _char,
+ _clock,
+ _double,
+ _enum,
+ _env,
+ _event,
+ _floating_point,
+ _float,
+ _integer,
+ _int,
+ _long,
+ _short,
+ _signed,
+ _stream,
+ _string,
+ _struct,
+ _trace,
+ _typealias,
+ _typedef,
+ _unsigned,
+ _variant,
+ _void,
+ __Bool,
+ __Complex,
+ __Imaginary,
+ } tag;
+
+ variant <tag> {
+ string _align;
+ string _callsite;
+ string _const;
+ string _char;
+ string _clock;
+ string _double;
+ string _enum;
+ string _env;
+ string _event;
+ string _floating_point;
+ string _float;
+ string _integer;
+ string _int;
+ string _long;
+ string _short;
+ string _signed;
+ string _stream;
+ string _string;
+ string _struct;
+ string _trace;
+ string _typealias;
+ string _typedef;
+ string _unsigned;
+ string _variant;
+ string _void;
+ string __Bool;
+ string __Complex;
+ string __Imaginary;
+ } var;
+ };
+};
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = be;
+};
+
+event {
+ name = yo;
+ fields := struct {
+ enum : integer { size = 8; } {
+ COSSETTE,
+ _PELCHAT,
+ __PELCHAT,
+ } tag;
+
+ variant <tag> {
+ string COSSETTE;
+ string _PELCHAT;
+ string __PELCHAT;
+ } var;
+ };
+};
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = be;
+};
+
+event {
+ name = yo;
+ fields := struct {
+ enum : integer { size = 8; } {
+ COSSETTE,
+ __PELCHAT,
+ VOISINE,
+ } tag;
+
+ variant <tag> {
+ string COSSETTE;
+ string __PELCHAT;
+ string VOISINE;
+ } var;
+ };
+};
Supports discarded packets: Yes
Discarded packets have default clock snapshots: Yes
Default clock class:
- Name: _default
+ Name: default
Frequency (Hz): 1,000,000,000
Precision (cycles): 1
Offset (s): 0
Supports discarded packets: Yes
Discarded packets have default clock snapshots: Yes
Default clock class:
- Name: _default
+ Name: default
Frequency (Hz): 1,000,000,000
Precision (cycles): 1
Offset (s): 0
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: No
+ Event class `yo` (ID 0):
+ Payload field class: Structure (2 members):
+ tag: Unsigned enumeration (8-bit, Base 10, 3 mappings):
+ COSSETTE: [0]
+ PELCHAT: [1]
+ VOISINE: [2]
+ var: Variant (unsigned selector) (3 options, Selector field path [Event payload: 0]):
+ COSSETTE: [0]: String
+ PELCHAT: [1]: String
+ VOISINE: [2]: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `yo` (Class ID 0):
+ Payload:
+ tag: 1
+ var: Daniel Lavoie
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: No
+ Event class `yo` (ID 0):
+ Payload field class: Structure (2 members):
+ tag: Unsigned enumeration (8-bit, Base 10, 3 mappings):
+ COSSETTE: [0]
+ PELCHAT: [1]
+ _VOISINE: [2]
+ var: Variant (unsigned selector) (3 options, Selector field path [Event payload: 0]):
+ COSSETTE: [0]: String
+ PELCHAT: [1]: String
+ VOISINE: [2]: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `yo` (Class ID 0):
+ Payload:
+ tag: 1
+ var: Daniel Lavoie
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: No
+ Event class `yo` (ID 0):
+ Payload field class: Structure (2 members):
+ tag: Unsigned enumeration (8-bit, Base 10, 28 mappings):
+ __Bool: [25]
+ __Complex: [26]
+ __Imaginary: [27]
+ _align: [0]
+ _callsite: [1]
+ _char: [3]
+ _clock: [4]
+ _const: [2]
+ _double: [5]
+ _enum: [6]
+ _env: [7]
+ _event: [8]
+ _float: [10]
+ _floating_point: [9]
+ _int: [12]
+ _integer: [11]
+ _long: [13]
+ _short: [14]
+ _signed: [15]
+ _stream: [16]
+ _string: [17]
+ _struct: [18]
+ _trace: [19]
+ _typealias: [20]
+ _typedef: [21]
+ _unsigned: [22]
+ _variant: [23]
+ _void: [24]
+ var: Variant (unsigned selector) (28 options, Selector field path [Event payload: 0]):
+ align: [0]: String
+ callsite: [1]: String
+ const: [2]: String
+ char: [3]: String
+ clock: [4]: String
+ double: [5]: String
+ enum: [6]: String
+ env: [7]: String
+ event: [8]: String
+ floating_point: [9]: String
+ float: [10]: String
+ integer: [11]: String
+ int: [12]: String
+ long: [13]: String
+ short: [14]: String
+ signed: [15]: String
+ stream: [16]: String
+ string: [17]: String
+ struct: [18]: String
+ trace: [19]: String
+ typealias: [20]: String
+ typedef: [21]: String
+ unsigned: [22]: String
+ variant: [23]: String
+ void: [24]: String
+ _Bool: [25]: String
+ _Complex: [26]: String
+ _Imaginary: [27]: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `yo` (Class ID 0):
+ Payload:
+ tag: 1
+ var: Daniel Lavoie
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: No
+ Event class `yo` (ID 0):
+ Payload field class: Structure (2 members):
+ tag: Unsigned enumeration (8-bit, Base 10, 3 mappings):
+ COSSETTE: [0]
+ _PELCHAT: [1]
+ __PELCHAT: [2]
+ var: Variant (unsigned selector) (3 options, Selector field path [Event payload: 0]):
+ COSSETTE: [0]: String
+ PELCHAT: [1]: String
+ _PELCHAT: [2]: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `yo` (Class ID 0):
+ Payload:
+ tag: 1
+ var: Daniel Lavoie
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: No
+ Event class `yo` (ID 0):
+ Payload field class: Structure (2 members):
+ tag: Unsigned enumeration (8-bit, Base 10, 3 mappings):
+ COSSETTE: [0]
+ VOISINE: [2]
+ __PELCHAT: [1]
+ var: Variant (unsigned selector) (3 options, Selector field path [Event payload: 0]):
+ COSSETTE: [0]: String
+ _PELCHAT: [1]: String
+ VOISINE: [2]: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `yo` (Class ID 0):
+ Payload:
+ tag: 1
+ var: Daniel Lavoie
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
this_dir_relative="plugins/sink.ctf.fs/succeed"
this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+succeed_traces="$BT_CTF_TRACES_PATH/succeed"
-test_ctf_gen_single() {
- name="$1"
- temp_gen_trace_dir="$(mktemp -d)"
- temp_out_trace_dir="$(mktemp -d)"
-
- diag "Generating trace '$name'"
-
- if ! "$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir"; then
- # this is not part of the test itself; it must not fail
- echo "ERROR: \"$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir\" failed" >&2
- rm -rf "$temp_gen_trace_dir"
- rm -rf "$temp_out_trace_dir"
- exit 1
- fi
+test_ctf_single() {
+ local name="$1"
+ local in_trace_dir="$2"
+ local temp_out_trace_dir="$(mktemp -d)"
diag "Converting trace '$name' to CTF through 'sink.ctf.fs'"
- "$BT_TESTS_BT2_BIN" >/dev/null "$temp_gen_trace_dir" -o ctf -w "$temp_out_trace_dir"
+ "$BT_TESTS_BT2_BIN" >/dev/null "$in_trace_dir" -o ctf -w "$temp_out_trace_dir"
ret=$?
ok $ret "'sink.ctf.fs' component succeeds with input trace '$name'"
converted_test_name="Converted trace '$name' gives the expected output"
if [ $ret -eq 0 ]; then
bt_diff_details_ctf_single "$expect_dir/trace-$name.expect" \
"$temp_out_trace_dir" \
- "-p" "with-uuid=no,with-trace-name=no,with-stream-name=no"
+ '-p' 'with-uuid=no,with-trace-name=no,with-stream-name=no'
ok $? "$converted_test_name"
else
fail "$converted_test_name"
fi
- rm -rf "$temp_gen_trace_dir"
rm -rf "$temp_out_trace_dir"
}
-plan_tests 4
+test_ctf_existing_single() {
+ local name="$1"
+ local trace_dir="$succeed_traces/$name"
+
+ test_ctf_single "$name" "$trace_dir"
+}
+
+test_ctf_gen_single() {
+ local name="$1"
+ local temp_gen_trace_dir="$(mktemp -d)"
+
+ diag "Generating trace '$name'"
+
+ if ! "$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir"; then
+ # this is not part of the test itself; it must not fail
+ echo "ERROR: \"$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir\" failed" >&2
+ rm -rf "$temp_gen_trace_dir"
+ exit 1
+ fi
+
+ test_ctf_single "$name" "$temp_gen_trace_dir"
+ rm -rf "$temp_gen_trace_dir"
+}
+
+plan_tests 14
test_ctf_gen_single float
test_ctf_gen_single double
+test_ctf_existing_single meta-variant-no-underscore
+test_ctf_existing_single meta-variant-one-underscore
+test_ctf_existing_single meta-variant-reserved-keywords
+test_ctf_existing_single meta-variant-same-with-underscore
+test_ctf_existing_single meta-variant-two-underscores