metababel 1.1.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fef536b3f7091c580764b9e74b5a33cdfa268231fba8678a6097f71038b83ec
4
- data.tar.gz: f715e0f2921b5542f0069e7b1a43624699d6381418a5052bface9c657d601f2d
3
+ metadata.gz: 59de2133e8a84ac9fb121c0a66ab94c7f8e8dc84b59d85f5dfc21fe68d7ff600
4
+ data.tar.gz: c18c4499cef1af36847f4dc4ced58107e3e52ec5cd9d3e8bfe69f1d3d50ef793
5
5
  SHA512:
6
- metadata.gz: 1a802b99efa22f8e34def1c7ec1610fc0a3e25897f14f48faa80156a3af32e5696e297a2d95b6053f05e6b0015814aa067332d01af1623bbb5461d9e608e609e
7
- data.tar.gz: 85206279e0e3b4971721c04b40bf484a23d103bb062f2e4ae3983b8a498673ab0ad34f304a6defe0943b7b8996fe40b9cc160840ffc139e44209185512230284
6
+ metadata.gz: d7ed22589acca08ad6ab56f7db2e209cdb13ffd4b4b1ddf11964c412ba6383b387dbf7a928aea61a12ac182dd057d43535756df896c616f4280b94b2d365b51d
7
+ data.tar.gz: '0291a811c6adc80c0ffa94bd4c04af15c66990efc491f479b6ac9e83fe40968bebb5da964a9fdfd1dfa4270990bf86772e2e72b137c458388da341ae7261d1c3'
@@ -44,23 +44,45 @@ module Babeltrace2Gen
44
44
  def rec_member_class
45
45
  is_a?(Babeltrace2Gen::BTMemberClass) ? self : @parent.rec_member_class
46
46
  end
47
+ end
48
+
49
+ class BTFieldLocation
50
+ include BTLocator
51
+ include BTPrinter
47
52
 
48
- def resolve_path(path)
49
- root, id = path.match(/^(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)\["?(.+)?"\]/).captures
53
+ # root_scope is the full babeltrace enum name, e.g.
54
+ # BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD (mirrors the C bt_field_location API).
55
+ attr_reader :root_scope, :items
56
+
57
+ def initialize(parent:, root_scope:, items:)
58
+ raise "nested field locations are not supported (items: #{items})" unless items.size == 1
59
+
60
+ @parent = parent
61
+ @root_scope = root_scope
62
+ @items = items
63
+ end
64
+
65
+ def member
50
66
  field_class =
51
- case root
52
- when 'PACKET_CONTEXT'
67
+ case @root_scope.to_s
68
+ when 'BT_FIELD_LOCATION_SCOPE_PACKET_CONTEXT'
53
69
  rec_stream_class.packet_context_field_class
54
- when 'EVENT_COMMON_CONTEXT'
70
+ when 'BT_FIELD_LOCATION_SCOPE_EVENT_COMMON_CONTEXT'
55
71
  rec_stream_class.event_common_context_field_class
56
- when 'EVENT_SPECIFIC_CONTEXT'
72
+ when 'BT_FIELD_LOCATION_SCOPE_EVENT_SPECIFIC_CONTEXT'
57
73
  rec_event_class.specific_context_field_class
58
- when 'EVENT_PAYLOAD'
74
+ when 'BT_FIELD_LOCATION_SCOPE_EVENT_PAYLOAD'
59
75
  rec_event_class.payload_field_class
60
76
  else
61
- raise "invalid path #{path}"
77
+ raise "invalid field-location root scope #{@root_scope}"
62
78
  end
63
- [field_class, id]
79
+ field_class[@items.first]
80
+ end
81
+
82
+ def get_declarator(trace_class:, variable:)
83
+ items_var = "#{variable}_items"
84
+ pr "const char *const #{items_var}[] = { #{@items.map { |i| "\"#{i}\"" }.join(', ')} };"
85
+ pr "#{variable} = bt_field_location_create(#{trace_class}, #{@root_scope}, #{items_var}, #{@items.length});"
64
86
  end
65
87
  end
66
88
 
@@ -394,6 +416,8 @@ module Babeltrace2Gen
394
416
  'string' => BTFieldClass::String,
395
417
  'array_static' => BTFieldClass::Array::Static,
396
418
  'array_dynamic' => BTFieldClass::Array::Dynamic,
419
+ 'blob_static' => BTFieldClass::Blob::Static,
420
+ 'blob_dynamic' => BTFieldClass::Blob::Dynamic,
397
421
  'structure' => BTFieldClass::Structure,
398
422
  'option_without_selector_field' => BTFieldClass::Option::WithoutSelectorField,
399
423
  'option_with_selector_field_bool' => BTFieldClass::Option::WithSelectorField::Bool,
@@ -718,17 +742,17 @@ module Babeltrace2Gen
718
742
  extend BTFromH
719
743
 
720
744
  module WithLengthField
721
- attr_reader :length_field_path
745
+ attr_reader :length_field_location
722
746
  end
723
747
  using HashRefinements
724
748
 
725
- def initialize(parent:, element_field_class:, length_field_path: nil)
749
+ def initialize(parent:, element_field_class:, length_field_location: nil)
726
750
  super(parent: parent, element_field_class: element_field_class)
727
- return unless length_field_path
751
+ return unless length_field_location
728
752
 
729
753
  extend(WithLengthField)
730
754
 
731
- @length_field_path = length_field_path
755
+ @length_field_location = BTFieldLocation.new(parent: self, **length_field_location)
732
756
  end
733
757
 
734
758
  def get_declarator(trace_class:, variable:)
@@ -736,34 +760,26 @@ module Babeltrace2Gen
736
760
  scope do
737
761
  pr "bt_field_class *#{element_field_class_variable};"
738
762
  @element_field_class.get_declarator(trace_class: trace_class, variable: element_field_class_variable)
739
- if @length_field_path
740
- element_field_class_variable_length = "#{element_field_class_variable}_length"
741
- pr "bt_field_class *#{element_field_class_variable_length};"
763
+ if @length_field_location
764
+ # MIP 1: reference the length field via a field-location instead of a
765
+ # length field class (bt_field_class_array_dynamic_create is MIP 0 only).
766
+ loc = "#{element_field_class_variable}_length_loc"
767
+ pr "const bt_field_location *#{loc};"
742
768
  scope do
743
- element_field_class_variable_length_sm = "#{element_field_class_variable_length}_sm"
744
- pr "bt_field_class_structure_member *#{element_field_class_variable_length_sm};"
745
- field_class, id = resolve_path(@length_field_path)
746
- id.scan(/(\w+)|(\d+)/).each do |name, index|
747
- # String
748
- if name
749
- pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_name(#{field_class.variable}, \"#{name}\");"
750
- else
751
- pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_index(#{field_class.variable}, #{index});"
752
- end
753
- end
754
- pr "#{element_field_class_variable_length} = bt_field_class_structure_member_borrow_field_class(#{element_field_class_variable_length_sm});"
769
+ @length_field_location.get_declarator(trace_class: trace_class, variable: loc)
755
770
  end
756
- pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, #{element_field_class_variable_length});"
771
+ pr "#{variable} = bt_field_class_array_dynamic_with_length_field_location_create(#{trace_class}, #{element_field_class_variable}, #{loc});"
772
+ pr "bt_field_location_put_ref(#{loc});"
757
773
  pr "bt_field_class_put_ref(#{element_field_class_variable});"
758
774
  else
759
- pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, NULL);"
775
+ pr "#{variable} = bt_field_class_array_dynamic_without_length_field_location_create(#{trace_class}, #{element_field_class_variable});"
776
+ pr "bt_field_class_put_ref(#{element_field_class_variable});"
760
777
  end
761
778
  end
762
779
  end
763
780
 
764
781
  def get_setter(field:, arg_variables:)
765
- field_class, id = resolve_path(@length_field_path)
766
- length_field = field_class[id]
782
+ length_field = @length_field_location.member
767
783
  pr "bt_field_array_dynamic_set_length(#{field}, #{length_field.name});"
768
784
  usr_var = bt_get_variable(arg_variables, is_array: true)
769
785
  pr "for(uint64_t _i=0; _i < #{length_field.name} ; _i++)"
@@ -790,6 +806,92 @@ module Babeltrace2Gen
790
806
  end
791
807
  end
792
808
 
809
+ # BLOB fields (CTF2 / MIP 1): a raw byte buffer with an associated IANA media
810
+ # type. Used by THAPI to record structs/unions and opaque byte buffers as
811
+ # uninterpreted bytes instead of smuggling them through text sequences.
812
+ class BTFieldClass::Blob < BTFieldClass
813
+ DEFAULT_MEDIA_TYPE = 'application/octet-stream'
814
+
815
+ attr_reader :media_type
816
+
817
+ # Emit the media-type assignment shared by static and dynamic blobs.
818
+ def declare_media_type(variable)
819
+ pr "bt_field_class_blob_set_media_type(#{variable}, \"#{@media_type || DEFAULT_MEDIA_TYPE}\");"
820
+ end
821
+ end
822
+
823
+ class BTFieldClass::Blob::Static < BTFieldClass::Blob
824
+ extend BTFromH
825
+
826
+ attr_reader :length
827
+
828
+ def initialize(parent:, length:, media_type: nil)
829
+ @parent = parent
830
+ @length = length
831
+ @media_type = media_type
832
+ end
833
+
834
+ def get_declarator(trace_class:, variable:)
835
+ pr "#{variable} = bt_field_class_blob_static_create(#{trace_class}, #{@length});"
836
+ declare_media_type(variable)
837
+ end
838
+
839
+ # A fixed-length blob carries the raw bytes of a struct/union; reconstruct it
840
+ # by memcpy, mirroring BTFieldClass::String with cast_type_is_struct.
841
+ def get_setter(field:, arg_variables:)
842
+ variable = bt_get_variable(arg_variables).name
843
+ pr "memcpy(bt_field_blob_get_data(#{field}), &#{variable}, #{@length});"
844
+ end
845
+
846
+ def get_getter(field:, arg_variables:)
847
+ variable = bt_get_variable(arg_variables).name
848
+ pr "memcpy(&#{variable}, bt_field_blob_get_data_const(#{field}), #{@length});"
849
+ end
850
+ end
851
+
852
+ class BTFieldClass::Blob::Dynamic < BTFieldClass::Blob
853
+ extend BTFromH
854
+
855
+ attr_reader :length_field_location
856
+
857
+ @bt_type = 'uint8_t*'
858
+
859
+ def initialize(parent:, length_field_location: nil, media_type: nil)
860
+ @parent = parent
861
+ @length_field_location = BTFieldLocation.new(parent: self, **length_field_location) if length_field_location
862
+ @media_type = media_type
863
+ end
864
+
865
+ def get_declarator(trace_class:, variable:)
866
+ if @length_field_location
867
+ loc = "#{variable}_length_loc"
868
+ pr "const bt_field_location *#{loc};"
869
+ scope do
870
+ @length_field_location.get_declarator(trace_class: trace_class, variable: loc)
871
+ end
872
+ pr "#{variable} = bt_field_class_blob_dynamic_with_length_field_location_create(#{trace_class}, #{loc});"
873
+ pr "bt_field_location_put_ref(#{loc});"
874
+ else
875
+ pr "#{variable} = bt_field_class_blob_dynamic_without_length_field_location_create(#{trace_class});"
876
+ end
877
+ declare_media_type(variable)
878
+ end
879
+
880
+ def get_setter(field:, arg_variables:)
881
+ length_field = @length_field_location.member
882
+ usr_var = bt_get_variable(arg_variables)
883
+ pr "bt_field_blob_dynamic_set_length(#{field}, #{length_field.name});"
884
+ pr "memcpy(bt_field_blob_get_data(#{field}), #{usr_var.name}, #{length_field.name});"
885
+ end
886
+
887
+ # The returned pointer is valid until the field is modified, so hand it to the
888
+ # callback directly instead of copying (mirrors BTFieldClass::String).
889
+ def get_getter(field:, arg_variables:)
890
+ usr_var = bt_get_variable(arg_variables)
891
+ pr "#{usr_var.name} = (#{usr_var.type})bt_field_blob_get_data_const(#{field});"
892
+ end
893
+ end
894
+
793
895
  class BTMemberClass
794
896
  include BTMatch
795
897
  include BTLocator
@@ -46,12 +46,10 @@ module Babeltrace2Gen
46
46
  default_value = @usr_default_value || bt_default_value
47
47
 
48
48
  pr "if (#{val} != NULL) {"
49
- if bt_type_is
50
- pr " if (#{bt_type_is}(#{val}) != BT_TRUE) {"
51
- pr " fprintf(stderr,\"Bad value for command line argument '%s' the value must be '%s'. \\n\",\"#{@name}\",\"#{bt_type}\");"
52
- pr ' exit(1);'
53
- pr ' }'
54
- end
49
+ pr " if (#{bt_type_is}(#{val}) != BT_TRUE) {"
50
+ pr " fprintf(stderr,\"Bad value for command line argument '%s' the value must be '%s'. \\n\",\"#{@name}\",\"#{bt_type}\");"
51
+ pr ' exit(1);'
52
+ pr ' }'
55
53
  pr " #{name} = #{cast_func}bt_value_#{bt_type}_get(#{val});"
56
54
  pr '} else {'
57
55
  pr " #{name} = #{cast_func}#{default_value};"
@@ -122,9 +120,9 @@ module Babeltrace2Gen
122
120
 
123
121
  class BTValueCLass::IntegerUnsigned < BTValueCLass::Scalar
124
122
  @bt_type = 'integer_unsigned'
125
- @bt_type_is = nil # 'bt_value_is_unsigned_integer'. Workarround `isIntegerUnsigned` broken
123
+ @bt_type_is = 'bt_value_is_unsigned_integer'
126
124
  @bt_return_type = 'uint64_t'
127
- @bt_default_value = '0'
125
+ @bt_default_value = '+0'
128
126
 
129
127
  def initialize(name, usr_default_value)
130
128
  bt_type = self.class.instance_variable_get(:@bt_type)
@@ -1,3 +1,3 @@
1
1
  module Metababel
2
- VERSION = '1.1.4'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -523,6 +523,20 @@ static void filter_message_iterator_finalize(
523
523
  free(message_iterator_private_data);
524
524
  }
525
525
 
526
+ /* Advertise support for MIP version 1, required for CTF2 features such as
527
+ * BLOB fields. Without this method a component defaults to MIP 0 only. */
528
+ static bt_component_class_get_supported_mip_versions_method_status
529
+ filter_get_supported_mip_versions(
530
+ bt_self_component_class_filter *self_component_class,
531
+ const bt_value *params, void *initialize_method_data,
532
+ bt_logging_level logging_level,
533
+ bt_integer_range_set_unsigned *supported_versions) {
534
+ if (bt_integer_range_set_unsigned_add_range(supported_versions, 1, 1) !=
535
+ BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_OK)
536
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_MEMORY_ERROR;
537
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
538
+ }
539
+
526
540
  /* Mandatory */
527
541
  BT_PLUGIN_MODULE();
528
542
 
@@ -530,6 +544,8 @@ BT_PLUGIN(<%= options[:'plugin-name'] %>);
530
544
  BT_PLUGIN_FILTER_COMPONENT_CLASS(<%= options[:'component-name'] %>,
531
545
  filter_message_iterator_next);
532
546
 
547
+ BT_PLUGIN_FILTER_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD(
548
+ <%= options[:'component-name'] %>, filter_get_supported_mip_versions);
533
549
  BT_PLUGIN_FILTER_COMPONENT_CLASS_INITIALIZE_METHOD(
534
550
  <%= options[:'component-name'] %>, filter_initialize);
535
551
  BT_PLUGIN_FILTER_COMPONENT_CLASS_FINALIZE_METHOD(
data/template/sink.c.erb CHANGED
@@ -160,12 +160,28 @@ sink_graph_is_configured(bt_self_component_sink *self_component_sink) {
160
160
  return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
161
161
  }
162
162
 
163
+ /* Advertise support for MIP version 1, required for CTF2 features such as
164
+ * BLOB fields. Without this method a component defaults to MIP 0 only. */
165
+ static bt_component_class_get_supported_mip_versions_method_status
166
+ sink_get_supported_mip_versions(
167
+ bt_self_component_class_sink *self_component_class,
168
+ const bt_value *params, void *initialize_method_data,
169
+ bt_logging_level logging_level,
170
+ bt_integer_range_set_unsigned *supported_versions) {
171
+ if (bt_integer_range_set_unsigned_add_range(supported_versions, 1, 1) !=
172
+ BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_OK)
173
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_MEMORY_ERROR;
174
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
175
+ }
176
+
163
177
  /* Mandatory */
164
178
  BT_PLUGIN_MODULE();
165
179
 
166
180
  BT_PLUGIN(<%= options[:'plugin-name'] %>);
167
181
  BT_PLUGIN_SINK_COMPONENT_CLASS(<%= options[:'component-name'] %>, sink_consume);
168
182
 
183
+ BT_PLUGIN_SINK_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD(
184
+ <%= options[:'component-name'] %>, sink_get_supported_mip_versions);
169
185
  BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(
170
186
  <%= options[:'component-name'] %>, sink_initialize);
171
187
  BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(
@@ -206,6 +206,20 @@ static void source_message_iterator_finalize(
206
206
  free(message_iterator_private_data);
207
207
  }
208
208
 
209
+ /* Advertise support for MIP version 1, required for CTF2 features such as
210
+ * BLOB fields. Without this method a component defaults to MIP 0 only. */
211
+ static bt_component_class_get_supported_mip_versions_method_status
212
+ source_get_supported_mip_versions(
213
+ bt_self_component_class_source *self_component_class,
214
+ const bt_value *params, void *initialize_method_data,
215
+ bt_logging_level logging_level,
216
+ bt_integer_range_set_unsigned *supported_versions) {
217
+ if (bt_integer_range_set_unsigned_add_range(supported_versions, 1, 1) !=
218
+ BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_OK)
219
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_MEMORY_ERROR;
220
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
221
+ }
222
+
209
223
  /* Mandatory */
210
224
  BT_PLUGIN_MODULE();
211
225
 
@@ -213,6 +227,8 @@ BT_PLUGIN(<%= options[:'plugin-name'] %>);
213
227
  BT_PLUGIN_SOURCE_COMPONENT_CLASS(<%= options[:'component-name'] %>,
214
228
  source_message_iterator_next);
215
229
 
230
+ BT_PLUGIN_SOURCE_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD(
231
+ <%= options[:'component-name'] %>, source_get_supported_mip_versions);
216
232
  BT_PLUGIN_SOURCE_COMPONENT_CLASS_INITIALIZE_METHOD(
217
233
  <%= options[:'component-name'] %>, source_initialize);
218
234
  BT_PLUGIN_SOURCE_COMPONENT_CLASS_FINALIZE_METHOD(
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metababel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Applencourt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-11-03 00:00:00.000000000 Z
13
+ date: 2026-09-21 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description:
16
16
  email:
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  requirements: []
63
- rubygems_version: 3.3.3
63
+ rubygems_version: 3.5.16
64
64
  signing_key:
65
65
  specification_version: 4
66
66
  summary: Helper for creation Babeltrace plugins