config.py: remove bit array field type's byte order property
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 8 Sep 2020 16:16:05 +0000 (12:16 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 8 Sep 2020 16:16:05 +0000 (12:16 -0400)
This patch removes the byte order property from the `_BitArrayFieldType`
class.

Instead, barectf always uses the configuration's target byte order.

As of this version of barectf, where all integral tracing function
parameters are copies, it makes no sense, for example, for a
little-endian CPU to write big-endian data.

The `byte-order` property is also removed in barectf 3 YAML field types.
I'm keeping it in barectf 2 YAML field types for backward compatibility,
but it's ignored now.

From a CTF consumer's perspective, this patch doesn't cause a noticeable
change: the decoded integral value is the same whatever the byte order.

From the barectf API's perspective, it makes the configuration objects
simpler. This patch effectively reverts 7fffc7d ("config: replace trace
type's default BO with configuration's target BO").

It is possible that barectf needs specific bit array field type byte
orders in the future, for example to copy some user payload as is
instead of copying each field; when this time comes, we can reintroduce
the property, adding a way to mark a bit array field type's byte order
as "target" (which would be the default), for example:

    my_ft = barectf.RealFieldType(32,
                                  byte_order=barectf.TARGET_BYTE_ORDER)

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
barectf/config.py
barectf/config_parse_v2.py
barectf/config_parse_v3.py
barectf/schemas/config/3/field-type.yaml
barectf/templates/c/serialize-write-bit-array-statements.j2
barectf/templates/metadata/int-ft.j2
barectf/templates/metadata/metadata.j2
barectf/templates/metadata/real-ft.j2
barectf/tsdl182gen.py

index 5a224287322e75d53ffb1211dfd255888a542d59..fbef355747568c3b3dd1d97a82575b7180e70a49 100644 (file)
@@ -49,19 +49,14 @@ class _FieldType:
 
 
 class _BitArrayFieldType(_FieldType):
-    def __init__(self, size: Count, byte_order: ByteOrder, alignment: Alignment = Alignment(1)):
+    def __init__(self, size: Count, alignment: Alignment = Alignment(1)):
         self._size = size
-        self._byte_order = byte_order
         self._alignment = alignment
 
     @property
     def size(self) -> Count:
         return self._size
 
-    @property
-    def byte_order(self) -> ByteOrder:
-        return self._byte_order
-
     @property
     def alignment(self) -> Alignment:
         return self._alignment
@@ -75,12 +70,12 @@ class DisplayBase(enum.Enum):
 
 
 class _IntegerFieldType(_BitArrayFieldType):
-    def __init__(self, size: Count, byte_order: ByteOrder, alignment: Optional[Alignment] = None,
+    def __init__(self, size: Count, alignment: Optional[Alignment] = None,
                  preferred_display_base: DisplayBase = DisplayBase.DECIMAL):
         if alignment is None:
             alignment = Alignment(8 if size % 8 == 0 else 1)
 
-        super().__init__(size, byte_order, alignment)
+        super().__init__(size, alignment)
         self._preferred_display_base = preferred_display_base
 
     @property
@@ -154,10 +149,10 @@ class EnumerationFieldTypeMappings(collections.abc.Mapping):
 
 
 class _EnumerationFieldType(_IntegerFieldType):
-    def __init__(self, size: Count, byte_order: ByteOrder, alignment: Optional[Alignment] = None,
+    def __init__(self, size: Count, alignment: Optional[Alignment] = None,
                  preferred_display_base: DisplayBase = DisplayBase.DECIMAL,
                  mappings: Optional[_EnumFtMappings] = None):
-        super().__init__(size, byte_order, alignment, preferred_display_base)
+        super().__init__(size, alignment, preferred_display_base)
         self._mappings = EnumerationFieldTypeMappings({})
 
         if mappings is not None:
@@ -412,12 +407,10 @@ class StreamTypePacketFeatures:
                  content_size_field_type: _DefaultableUIntFt = DEFAULT_FIELD_TYPE,
                  beginning_time_field_type: _OptDefaultableUIntFt = None,
                  end_time_field_type: _OptDefaultableUIntFt = None,
-                 discarded_events_counter_field_type: _OptDefaultableUIntFt = None,
-                 default_byte_order: Optional[ByteOrder] = None):
+                 discarded_events_counter_field_type: _OptDefaultableUIntFt = None):
         def get_ft(user_ft: _OptDefaultableUIntFt) -> _OptUIntFt:
             if user_ft == DEFAULT_FIELD_TYPE:
-                assert default_byte_order is not None
-                return UnsignedIntegerFieldType(64, typing.cast(ByteOrder, default_byte_order))
+                return UnsignedIntegerFieldType(64)
 
             return typing.cast(_OptUIntFt, user_ft)
 
@@ -450,12 +443,10 @@ class StreamTypePacketFeatures:
 
 class StreamTypeEventFeatures:
     def __init__(self, type_id_field_type: _OptDefaultableUIntFt = DEFAULT_FIELD_TYPE,
-                 time_field_type: _OptDefaultableUIntFt = None,
-                 default_byte_order: Optional[ByteOrder] = None):
+                 time_field_type: _OptDefaultableUIntFt = None):
         def get_ft(user_ft: _OptDefaultableUIntFt) -> _OptUIntFt:
             if user_ft == DEFAULT_FIELD_TYPE:
-                assert default_byte_order is not None
-                return UnsignedIntegerFieldType(64, typing.cast(ByteOrder, default_byte_order))
+                return UnsignedIntegerFieldType(64)
 
             return typing.cast(_OptUIntFt, user_ft)
 
@@ -473,15 +464,14 @@ class StreamTypeEventFeatures:
 
 class StreamTypeFeatures:
     def __init__(self, packet_features: Optional[StreamTypePacketFeatures] = None,
-                 event_features: Optional[StreamTypeEventFeatures] = None,
-                 default_byte_order: Optional[ByteOrder] = None):
+                 event_features: Optional[StreamTypeEventFeatures] = None):
         if packet_features is None:
-            self._packet_features = StreamTypePacketFeatures(default_byte_order=default_byte_order)
+            self._packet_features = StreamTypePacketFeatures()
         else:
             self._packet_features = packet_features
 
         if event_features is None:
-            self._event_features = StreamTypeEventFeatures(default_byte_order=default_byte_order)
+            self._event_features = StreamTypeEventFeatures()
         else:
             self._event_features = event_features
 
@@ -498,7 +488,6 @@ class StreamType(_UniqueByName):
     def __init__(self, name: str, event_types: Set[EventType],
                  default_clock_type: Optional[ClockType] = None,
                  features: Optional[StreamTypeFeatures] = None,
-                 default_feature_field_type_byte_order: Optional[ByteOrder] = None,
                  packet_context_field_type_extra_members: Optional[_StructFtMembers] = None,
                  event_common_context_field_type: _OptStructFt = None):
         self._id: Optional[Id] = None
@@ -512,7 +501,7 @@ class StreamType(_UniqueByName):
             assert ev_type._id is None
             ev_type._id = Id(index)
 
-        self._set_features(features, default_feature_field_type_byte_order)
+        self._set_features(features)
         self._packet_context_field_type_extra_members = StructureFieldTypeMembers({})
 
         if packet_context_field_type_extra_members is not None:
@@ -521,8 +510,7 @@ class StreamType(_UniqueByName):
         self._set_pkt_ctx_ft()
         self._set_ev_header_ft()
 
-    def _set_features(self, features: Optional[StreamTypeFeatures],
-                      default_byte_order: Optional[ByteOrder]):
+    def _set_features(self, features: Optional[StreamTypeFeatures]):
         if features is not None:
             self._features = features
             return None
@@ -539,10 +527,8 @@ class StreamType(_UniqueByName):
             pkt_end_time_ft = DEFAULT_FIELD_TYPE
 
         self._features = StreamTypeFeatures(StreamTypePacketFeatures(beginning_time_field_type=pkt_beginning_time_ft,
-                                                                     end_time_field_type=pkt_end_time_ft,
-                                                                     default_byte_order=default_byte_order),
-                                            StreamTypeEventFeatures(time_field_type=ev_time_ft,
-                                                                    default_byte_order=default_byte_order))
+                                                                     end_time_field_type=pkt_end_time_ft),
+                                            StreamTypeEventFeatures(time_field_type=ev_time_ft))
 
     def _set_ft_mapped_clk_type_name(self, ft: Optional[UnsignedIntegerFieldType]):
         if ft is None:
@@ -637,8 +623,7 @@ _OptUuidFt = Optional[Union[str, StaticArrayFieldType]]
 class TraceTypeFeatures:
     def __init__(self, magic_field_type: _OptDefaultableUIntFt = DEFAULT_FIELD_TYPE,
                  uuid_field_type: _OptUuidFt = None,
-                 stream_type_id_field_type: _OptDefaultableUIntFt = DEFAULT_FIELD_TYPE,
-                 default_byte_order: Optional[ByteOrder] = None):
+                 stream_type_id_field_type: _OptDefaultableUIntFt = DEFAULT_FIELD_TYPE):
         def get_field_type(user_ft: Optional[Union[str, _FieldType]],
                            create_default_ft: Callable[[], _FieldType]) -> _OptFt:
             if user_ft == DEFAULT_FIELD_TYPE:
@@ -647,16 +632,13 @@ class TraceTypeFeatures:
             return typing.cast(_OptFt, user_ft)
 
         def create_default_magic_ft():
-            assert default_byte_order is not None
-            return UnsignedIntegerFieldType(32, default_byte_order)
+            return UnsignedIntegerFieldType(32)
 
         def create_default_uuid_ft():
-            assert default_byte_order is not None
-            return StaticArrayFieldType(Count(16), UnsignedIntegerFieldType(8, default_byte_order))
+            return StaticArrayFieldType(Count(16), UnsignedIntegerFieldType(8))
 
         def create_default_stream_type_id_ft():
-            assert default_byte_order is not None
-            return UnsignedIntegerFieldType(64, default_byte_order)
+            return UnsignedIntegerFieldType(64)
 
         self._magic_field_type = typing.cast(_OptUIntFt, get_field_type(magic_field_type, create_default_magic_ft))
         self._uuid_field_type = typing.cast(Optional[StaticArrayFieldType],
@@ -680,8 +662,7 @@ class TraceTypeFeatures:
 
 class TraceType:
     def __init__(self, stream_types: Set[StreamType], uuid: _OptUuid = None,
-                 features: Optional[TraceTypeFeatures] = None,
-                 default_feature_field_type_byte_order: Optional[ByteOrder] = None):
+                 features: Optional[TraceTypeFeatures] = None):
         self._stream_types = frozenset(stream_types)
 
         # assign unique IDs
@@ -690,19 +671,17 @@ class TraceType:
             stream_type._id = Id(index)
 
         self._uuid = uuid
-        self._set_features(features, default_feature_field_type_byte_order)
+        self._set_features(features)
         self._set_pkt_header_ft()
 
-    def _set_features(self, features: Optional[TraceTypeFeatures],
-                      default_byte_order: Optional[ByteOrder]):
+    def _set_features(self, features: Optional[TraceTypeFeatures]):
         if features is not None:
             self._features = features
             return
 
         # automatic UUID field type because the trace type has a UUID
         uuid_ft = None if self._uuid is None else DEFAULT_FIELD_TYPE
-        self._features = TraceTypeFeatures(uuid_field_type=uuid_ft,
-                                           default_byte_order=default_byte_order)
+        self._features = TraceTypeFeatures(uuid_field_type=uuid_ft)
 
     def _set_pkt_header_ft(self):
         members = collections.OrderedDict()
index bd9104272801d19ba2996c0bde97318ed4319845..7c0c185793fb4061ab125b831903b14acf9ef9f8 100644 (file)
@@ -129,6 +129,9 @@ class _Parser(config_parse_common._Parser):
         # remove `encoding` property
         _del_prop_if_exists(v3_ft_node, 'encoding')
 
+        # remove `byte-order` property (always target BO in v3)
+        _del_prop_if_exists(v3_ft_node, 'byte-order')
+
         # remove `property-mappings` property
         _del_prop_if_exists(v3_ft_node, 'property-mappings')
 
index 1d636c7fbdb79b01afd4c5905b9519c12844f6d7..ad21cc836d055ae9c09ed95c3da0d06b6299909e 100644 (file)
@@ -131,13 +131,12 @@ class _Parser(barectf_config_parse_common._Parser):
                                     ft_type: Type[barectf_config._BitArrayFieldType],
                                     default_alignment: Optional[Alignment],
                                     *args) -> barectf_config._BitArrayFieldType:
-        byte_order = self._byte_order_from_node(ft_node['byte-order'])
         alignment = self._alignment_prop(ft_node, 'alignment')
 
         if alignment is None:
             alignment = default_alignment
 
-        return ft_type(ft_node['size'], byte_order, alignment, *args)
+        return ft_type(ft_node['size'], alignment, *args)
 
     # Creates an integer field type having the type `ft_type` from the
     # integer field type node `ft_node`, passing the additional `*args`
@@ -462,10 +461,8 @@ class _Parser(barectf_config_parse_common._Parser):
                                                                    pkt_content_size_ft,
                                                                    pkt_beginning_time_ft,
                                                                    pkt_end_time_ft,
-                                                                   pkt_discarded_events_counter_ft,
-                                                                   default_byte_order=self._target_byte_order)
-            ev_features = barectf_config.StreamTypeEventFeatures(ev_type_id_ft, ev_time_ft,
-                                                                 default_byte_order=self._target_byte_order)
+                                                                   pkt_discarded_events_counter_ft)
+            ev_features = barectf_config.StreamTypeEventFeatures(ev_type_id_ft, ev_time_ft)
             features = barectf_config.StreamTypeFeatures(pkt_features, ev_features)
 
             # create packet context (structure) field type extra members
@@ -510,7 +507,7 @@ class _Parser(barectf_config_parse_common._Parser):
                 ev_types.add(self._create_ev_type(ev_name, ev_type_node, ev_header_common_ctx_member_count))
 
             # create stream type
-            return barectf_config.StreamType(name, ev_types, def_clk_type, features, None,
+            return barectf_config.StreamType(name, ev_types, def_clk_type, features,
                                              pkt_ctx_ft_extra_members,
                                              self._try_create_struct_ft(stream_type_node,
                                                                         ev_common_ctx_ft_prop_name))
@@ -606,8 +603,7 @@ class _Parser(barectf_config_parse_common._Parser):
             except _ConfigurationParseError as exc:
                 _append_error_ctx(exc, '`$features` property')
 
-            features = barectf_config.TraceTypeFeatures(magic_ft, uuid_ft, stream_type_id_ft,
-                                                        default_byte_order=self._target_byte_order)
+            features = barectf_config.TraceTypeFeatures(magic_ft, uuid_ft, stream_type_id_ft)
 
             # create stream types
             stream_types = set()
@@ -1094,9 +1090,6 @@ class _Parser(barectf_config_parse_common._Parser):
                     parent_node[key] = 'string'
                 elif node == 'struct':
                     parent_node[key] = 'structure'
-            elif key == 'byte-order' and type(node) is str:
-                # byte order aliases
-                normalize_byte_order_prop(parent_node, key)
             elif key == 'preferred-display-base' and type(node) is str:
                 # display base aliases
                 if node == 'bin':
@@ -1116,104 +1109,10 @@ class _Parser(barectf_config_parse_common._Parser):
             if node is None:
                 del trace_node[prop_name]
 
-    # Substitutes missing/`None` `byte-order` properties with the
-    # configuration node's target byte order (`target-byte-order`
-    # property).
-    def _sub_ft_nodes_byte_order(self):
-        ba_ft_class_names = {
-            'unsigned-integer',
-            'signed-integer',
-            'unsigned-enumeration',
-            'signed-enumeration',
-            'real',
-        }
-
-        def set_ft_node_byte_order_prop(parent_node: _MapNode, key: str):
-            if key not in parent_node:
-                return
-
-            ft_node = parent_node[key]
-
-            if type(ft_node) is not collections.OrderedDict:
-                return
-
-            if ft_node['class'] in ba_ft_class_names:
-                prop_name = 'byte-order'
-                byte_order_node = ft_node.get(prop_name)
-
-                if byte_order_node is None:
-                    ft_node[prop_name] = self._target_byte_order_node
-
-            members_node = ft_node.get('members')
-
-            if members_node is not None:
-                set_struct_ft_node_members_byte_order_prop(members_node)
-
-            set_ft_node_byte_order_prop(ft_node, 'element-field-type')
-
-        def set_struct_ft_node_members_byte_order_prop(members_node: List[_MapNode]):
-            for member_node in members_node:
-                member_name, member_node = list(member_node.items())[0]
-
-                try:
-                    set_ft_node_byte_order_prop(member_node, 'field-type')
-                except _ConfigurationParseError as exc:
-                    _append_error_ctx(exc, f'Structure field type member `{member_name}`')
-
+    # Sets the parser's target byte order.
+    def _set_target_byte_order(self):
         self._target_byte_order_node = self.config_node['target-byte-order']
         self._target_byte_order = self._byte_order_from_node(self._target_byte_order_node)
-        features_prop_name = '$features'
-        features_node = self._trace_type_node.get(features_prop_name)
-
-        if features_node is not None:
-            try:
-                set_ft_node_byte_order_prop(features_node, 'magic-field-type')
-                set_ft_node_byte_order_prop(features_node, 'uuid-field-type')
-                set_ft_node_byte_order_prop(features_node, 'stream-type-id-field-type')
-            except _ConfigurationParseError as exc:
-                exc._append_ctx(exc, f'`{features_prop_name}` property')
-                _append_error_ctx(exc, 'Trace type')
-
-        for stream_type_name, stream_type_node in self._trace_type_node['stream-types'].items():
-            try:
-                features_node = stream_type_node.get(features_prop_name)
-
-                if features_node is not None:
-                    pkt_node = features_node.get('packet')
-
-                    if pkt_node is not None:
-                        set_ft_node_byte_order_prop(pkt_node, 'total-size-field-type')
-                        set_ft_node_byte_order_prop(pkt_node, 'content-size-field-type')
-                        set_ft_node_byte_order_prop(pkt_node, 'beginning-time-field-type')
-                        set_ft_node_byte_order_prop(pkt_node, 'end-time-field-type')
-                        set_ft_node_byte_order_prop(pkt_node,
-                                                    'discarded-events-counter-field-type')
-
-                    ev_node = features_node.get('event')
-
-                    if ev_node is not None:
-                        set_ft_node_byte_order_prop(ev_node, 'type-id-field-type')
-                        set_ft_node_byte_order_prop(ev_node, 'time-field-type')
-
-                prop_name = 'packet-context-field-type-extra-members'
-                pkt_ctx_ft_extra_members_node = stream_type_node.get(prop_name)
-
-                if pkt_ctx_ft_extra_members_node is not None:
-                    try:
-                        set_struct_ft_node_members_byte_order_prop(pkt_ctx_ft_extra_members_node)
-                    except _ConfigurationParseError as exc:
-                        _append_error_ctx(exc, f'`{pkt_ctx_ft_extra_members_node}` property')
-
-                set_ft_node_byte_order_prop(stream_type_node, 'event-common-context-field-type')
-
-                for ev_type_name, ev_type_node in stream_type_node['event-types'].items():
-                    try:
-                        set_ft_node_byte_order_prop(ev_type_node, 'specific-context-field-type')
-                        set_ft_node_byte_order_prop(ev_type_node, 'payload-field-type')
-                    except _ConfigurationParseError as exc:
-                        _append_error_ctx(exc, f'Event type `{ev_type_name}`')
-            except _ConfigurationParseError as exc:
-                _append_error_ctx(exc, f'Stream type `{stream_type_name}`')
 
     # Processes the inclusions of the event type node `ev_type_node`,
     # returning the effective node.
@@ -1385,9 +1284,8 @@ class _Parser(barectf_config_parse_common._Parser):
         # doesn't need to check for `None` nodes or enumerator aliases.
         self._normalize_props()
 
-        # Set `byte-order` properties of bit array field type nodes
-        # missing one.
-        self._sub_ft_nodes_byte_order()
+        # Set the target byte order.
+        self._set_target_byte_order()
 
         # Create a barectf configuration object from the configuration
         # node.
index cf29e39e9e7dac42a7f4f78da07a078c777bdc8f..4ab690d4d5661a3b8a57402f088f4b78f4c6b736 100644 (file)
@@ -37,8 +37,6 @@ definitions:
             $ref: https://barectf.org/schemas/config/common/common.json#/definitions/int-ft-size-prop
           alignment:
             $ref: https://barectf.org/schemas/config/common/common.json#/definitions/opt-int-min-1
-          byte-order:
-            $ref: https://barectf.org/schemas/config/common/common.json#/definitions/opt-byte-order-prop
         required:
           - size
   int-ft-props:
@@ -46,7 +44,6 @@ definitions:
       class: true
       size: true
       alignment: true
-      byte-order: true
       preferred-display-base: true
     additionalProperties: false
   int-ft:
@@ -88,7 +85,6 @@ definitions:
       class: true
       size: true
       alignment: true
-      byte-order: true
       preferred-display-base: true
       mappings: true
     additionalProperties: false
@@ -117,7 +113,6 @@ definitions:
       class: true
       size: true
       alignment: true
-      byte-order: true
       preferred-display-base: true
       mappings: true
     additionalProperties: false
@@ -169,7 +164,6 @@ definitions:
       class: true
       size: true
       alignment: true
-      byte-order: true
     additionalProperties: false
   string-ft-class-prop:
     type: string
index 006ab769355e2a33aeae61d6bd379bc4bfa60ecc..a822c28ad2903832df799cc4c7ea8aa984fcb229 100644 (file)
@@ -23,7 +23,7 @@
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  #}
 {% import 'common.j2' as common %}
-{% set bo = 'le' if op.ft.byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' %}
+{% set bo = 'le' if cfg.target_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' %}
 {% set c_type_non_const = c_type | replace('const ', '') %}
 bt_bitfield_write_{{ bo }}(&ctx->buf[_BITS_TO_BYTES(ctx->at)],
        uint8_t, {{ op.offset_in_byte }}, {{ op.ft.size }}, {{ c_type_non_const }},
index 968baff391eefedb1830ed3f079e5876f6861cd8..9b1ddf695ca8d1637b03015722376f17ad9349cc 100644 (file)
@@ -26,7 +26,7 @@ integer {
        signed = {{ 'true' if is_signed else 'false' }};
        size = {{ ft.size }};
        align = {{ ft.alignment }};
-       byte_order = {{ ft.byte_order | bo_str }};
+       byte_order = native;
        base = {{ ft.preferred_display_base | disp_base_int }};
 {% if ft._mapped_clk_type_name %}
        map = clock.{{ ft._mapped_clk_type_name }}.value;
index 240e0b16e959c309970b265fb384bec69ccef542..6cc8c6f7bc230b8b49c8cff6c642dd048e1ad5a3 100644 (file)
@@ -39,7 +39,7 @@
 trace {
        major = 1;
        minor = 8;
-       byte_order = {{ cfg.target_byte_order | bo_str }};
+       byte_order = {{ 'le' if cfg.target_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' }};
 {% if cfg.trace.type.uuid %}
        uuid = "{{ cfg.trace.type.uuid }}";
 {% endif %}
index 40f297e7ac170c47f73dcf3412a7d5bef2c51c26..b571abe3f733ac15b39f45e711d850c1681bb620 100644 (file)
@@ -26,5 +26,5 @@ floating_point {
        mant_dig = {{ 24 if ft.size == 32 else 53 }};
        exp_dig = {{ 8 if ft.size == 32 else 11 }};
        align = {{ ft.alignment }};
-       byte_order = {{ ft.byte_order | bo_str }};
+       byte_order = native;
 }
index 39fd64f8494e858a79d4b3dc233b587ace5f22fe..01ee04b5a7a019ad301e10cc174afbc11c061725 100644 (file)
@@ -27,13 +27,6 @@ from typing import List, Optional
 import typing
 
 
-def _filt_bo_str(bo: barectf_config.ByteOrder) -> str:
-    return {
-        barectf_config.ByteOrder.LITTLE_ENDIAN: 'le',
-        barectf_config.ByteOrder.BIG_ENDIAN: 'be',
-    }[bo]
-
-
 def _filt_disp_base_int(disp_base: barectf_config.DisplayBase) -> int:
     return {
         barectf_config.DisplayBase.BINARY: 2,
@@ -91,7 +84,6 @@ def _filt_ft_str(ft: barectf_config._FieldType) -> str:
 
 
 _TEMPL_FILTERS = {
-    'bo_str': _filt_bo_str,
     'disp_base_int': _filt_disp_base_int,
     'int_ft_str': _filt_int_ft_str,
     'ft_str': _filt_ft_str,
This page took 0.031167 seconds and 4 git commands to generate.