metababel 0.0.3 → 0.0.4

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: 3e44583997647f4d7d9e241dd5e066abc80586445283bd2846fa9fa453542de7
4
- data.tar.gz: a89855eeb46c35a71325937679b30bc0ef3fe46317cc1239419980b13f43a1b5
3
+ metadata.gz: 4a06ce284438f35303ef476971d820bd7ae1c2370b58181ba36146821d4423f7
4
+ data.tar.gz: 534aff0d21827f367caa9295051d886be08e624a24775e9c3fbd19da7fef97dc
5
5
  SHA512:
6
- metadata.gz: 8ece21929325026051ef4897d8f9871c19e5af621d963d1fcd8e57e8e481feb460e6fe3a02675eefb0bd44dc64505af329231ea22b52c54acbbfc7d9efcdaf2a
7
- data.tar.gz: 62fd169ca6e45a414b71228c2b6fc763bd0d18dd83fcbc6266d1663bb7303a8aa608f56863b3bbea0154d5862e4b80f26adbdbd6401b11541a658e200c278704
6
+ metadata.gz: edac518ba0bbec6c560f1e763bbf9df96d40e9b666f6c54db2fda8c71a1f9676a880e79f97a0aeb6c311db4c2cf3f2870d1643ae2f3e17514ac9fa9123001f71
7
+ data.tar.gz: 484cf07cd9e6930c2a54fc562e79420ceeb7a5a6a931e90576084cb6a252af2526ac3fddb41bcc080bb6c9879c20f248094f7455b6fca93424873b92dca61828
data/bin/metababel CHANGED
@@ -7,11 +7,22 @@ require 'metababel'
7
7
  require 'fileutils'
8
8
 
9
9
  def validate_model(yaml)
10
- raise "Invalid Model #{yaml}" unless yaml[:stream_classes].all? do |d|
11
- d.key?(:event_common_context_field_class) || d[:event_classes].all? do |d2|
12
- d2.key?(:payload_field_class)
13
- end
14
- end
10
+ # Stream and event classes must have a 'name' as minimum requirement.
11
+ raise "Missing 'name' attr in model #{yaml}" unless yaml[:stream_classes].all? do |d|
12
+ d.key?(:name) && d[:event_classes].all? do |d2|
13
+ d2.key?(:name)
14
+ end
15
+ end
16
+
17
+ # Event class name must be unique
18
+ events = yaml[:stream_classes].flat_map { |sc| sc[:event_classes] }.map { |e| e[:name] }
19
+ raise "Duplicated 'event' in model #{yaml}" unless events.length == events.uniq.length
20
+ end
21
+
22
+ class Array
23
+ def join_with_prefix(sep)
24
+ empty? ? '' : "#{sep}#{join(sep)}"
25
+ end
15
26
  end
16
27
 
17
28
  class Hash
@@ -33,7 +44,14 @@ class Hash
33
44
  end
34
45
  end
35
46
 
36
- EventInfo = Struct.new(:name, :args, :body, :index_stream_class, :index_event_class, :default_clock_class) do
47
+ EventClassInfo = Struct.new(:name, :args, :body, :index_stream_class, :index_event_class, :default_clock_class,
48
+ :args_to_free) do
49
+ def name_sanitized
50
+ name.gsub(/[^0-9A-Za-z-]/, '_')
51
+ end
52
+ end
53
+
54
+ StreamClassInfo = Struct.new(:name, :args, :body, :default_clock_class) do
37
55
  def name_sanitized
38
56
  name.gsub(/[^0-9A-Za-z-]/, '_')
39
57
  end
@@ -71,17 +89,28 @@ end
71
89
  # But we clean the white space empty line afterward \o/
72
90
  def wrote_event_dispatchers(folder, t)
73
91
  event_name = 'event'
74
- event_dispatchers = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
75
- arg_variables = []
76
- arg_variables << GeneratedArg.new("uint64_t", "timestamp") if default_clock_class
77
-
92
+ event_class_dispatchers = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
93
+ arg_variables = {}
78
94
  body = Babeltrace2Gen.context(indent: 1) do
79
95
  e.get_getter(event: event_name, arg_variables: arg_variables)
80
96
  end
81
- EventInfo.new(e.name, arg_variables, "\n" + body, index_stream_class, index_event_class)
97
+ EventClassInfo.new(e.name, arg_variables.fetch('outputs', []), body, index_stream_class, index_event_class, default_clock_class,
98
+ arg_variables.fetch('outputs_allocated', []))
82
99
  end
83
100
 
84
- d = { event_dispatchers: event_dispatchers,
101
+ stream_classes_matching_dispatchers = t.stream_classes.map do |s|
102
+ arg_variables = {}
103
+ body = ''
104
+ if s.event_common_context_field_class
105
+ body = Babeltrace2Gen.context(indent: 1) do
106
+ s.get_getter(event: event_name, arg_variables: arg_variables)
107
+ end
108
+ end
109
+ StreamClassInfo.new(s.name, arg_variables.fetch('outputs', []), body, s.default_clock_class)
110
+ end
111
+
112
+ d = { event_class_dispatchers: event_class_dispatchers,
113
+ stream_classes_matching_dispatchers: stream_classes_matching_dispatchers,
85
114
  event_name: event_name }
86
115
 
87
116
  erb_render_and_save(d, 'upstream.h', folder)
@@ -91,13 +120,12 @@ end
91
120
  def wrote_creates(folder, t)
92
121
  event_name = 'event'
93
122
  downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
94
- arg_variables = []
123
+ arg_variables = {}
95
124
  body = Babeltrace2Gen.context(indent: 1) do
96
125
  e.get_setter(event: event_name, arg_variables: arg_variables)
97
126
  end
98
- arg_variables.insert(0,GeneratedArg.new("uint64_t", "timestamp")) if default_clock_class
99
-
100
- EventInfo.new(e.name, arg_variables, "\n" + body, index_stream_class, index_event_class, default_clock_class)
127
+ EventClassInfo.new(e.name, arg_variables.fetch('outputs', []), "\n" + body, index_stream_class, index_event_class,
128
+ default_clock_class)
101
129
  end
102
130
 
103
131
  body_declarator_classes = "\n" + Babeltrace2Gen.context(indent: 1) do
@@ -114,18 +142,18 @@ def wrote_creates(folder, t)
114
142
  end
115
143
 
116
144
  def wrote_component(options, d, folder)
117
- component_dispatchers = [EventInfo.new('initialize_usr_data',
118
- [GeneratedArg.new('void **', 'usr_data_p')]),
119
- EventInfo.new('finalize_usr_data',
120
- [GeneratedArg.new('void *', 'usr_data')]),
121
- EventInfo.new('read_params',
122
- [GeneratedArg.new('void *', 'usr_data'),
123
- GeneratedArg.new('btx_params_t *', 'usr_params')])]
145
+ component_dispatchers = [EventClassInfo.new('initialize_usr_data',
146
+ [GeneratedArg.new('void **', 'usr_data_p')]),
147
+ EventClassInfo.new('finalize_usr_data',
148
+ [GeneratedArg.new('void *', 'usr_data')]),
149
+ EventClassInfo.new('read_params',
150
+ [GeneratedArg.new('void *', 'usr_data'),
151
+ GeneratedArg.new('btx_params_t *', 'usr_params')])]
124
152
 
125
153
  if options[:component_type] == 'SOURCE'
126
- component_dispatchers << EventInfo.new('push_usr_messages',
127
- [GeneratedArg.new('void *', 'usr_data'),
128
- GeneratedArg.new('btx_source_status_t*', 'status')])
154
+ component_dispatchers << EventClassInfo.new('push_usr_messages',
155
+ [GeneratedArg.new('void *', 'usr_data'),
156
+ GeneratedArg.new('btx_source_status_t*', 'status')])
129
157
  end
130
158
 
131
159
  d2 = { component_dispatchers: component_dispatchers,
@@ -187,8 +215,9 @@ OptionParser.new do |opts|
187
215
  end.parse!
188
216
 
189
217
  raise OptionParser::MissingArgument if options[:component_type].nil?
218
+
190
219
  options[:plugin_name] ||= "metababel_#{options[:component_type].downcase}"
191
- options[:component_name] ||= "btx"
220
+ options[:component_name] ||= 'btx'
192
221
 
193
222
  # Babeltrace can be extended by plugins, which provide one or more component classes.
194
223
  base_folder = options[:folder] || "#{options[:component_type]}.#{options[:plugin_name]}.#{options[:component_name]}"
@@ -208,10 +237,10 @@ if options.key?(:params)
208
237
  d[:params_declaration] = c.get_struct_definition('params')
209
238
  d[:params_definition] = body
210
239
  else
211
- d[:params_declaration] = "char _dummy;"
240
+ d[:params_declaration] = 'char _dummy;'
212
241
  end
213
242
 
214
- erb_render_and_save(d, "#{options[:component_type].downcase}.c", base_folder, out_name: "main.c")
243
+ erb_render_and_save(d, "#{options[:component_type].downcase}.c", base_folder, out_name: 'main.c')
215
244
  erb_render_and_save({ options: options }, 'metababel.h', folder, prefix: '')
216
245
 
217
246
  wrote_component(options, d, folder)
@@ -1,5 +1,14 @@
1
1
  require_relative 'bt2_generator_utils'
2
2
 
3
+ module HashRefinements
4
+ refine Hash do
5
+ def fetch_append(key, item)
6
+ self[key] = fetch(key, []) << item
7
+ item
8
+ end
9
+ end
10
+ end
11
+
3
12
  module Babeltrace2Gen
4
13
  class GeneratedArg < Struct.new(:type, :name)
5
14
  end
@@ -31,32 +40,22 @@ module Babeltrace2Gen
31
40
  is_a?(Babeltrace2Gen::BTMemberClass) ? self : @parent.rec_menber_class
32
41
  end
33
42
 
34
- def find_field_class_path(path, variable)
35
- path.scan(/\["(\w+)"\]|\[(\d+)\]/).each do |m|
36
- # String
37
- if m.first
38
- pr "#{variable} = bt_field_class_structure_borrow_member_by_name(#{variable}, \"#{m.first}\");"
43
+ def resolve_path(path)
44
+ root, id = path.match(/^(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)\["?(.+)?"\]/).captures
45
+ field_class =
46
+ case root
47
+ when 'PACKET_CONTEXT'
48
+ rec_stream_class.packet_context_field_class
49
+ when 'EVENT_COMMON_CONTEXT'
50
+ rec_stream_class.event_common_context_field_class
51
+ when 'EVENT_SPECIFIC_CONTEXT'
52
+ rec_event_class.specific_context_field_class
53
+ when 'EVENT_PAYLOAD'
54
+ rec_event_class.payload_field_class
39
55
  else
40
- pr "#{variable} = bt_field_class_structure_borrow_member_by_index(#{variable}, #{m.last});"
56
+ raise "invalid path #{path}"
41
57
  end
42
- end
43
- end
44
-
45
- def find_field_class(path, variable)
46
- m = path.match(/\A(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)(.*)/)
47
- case m[1]
48
- when 'PACKET_CONTEXT'
49
- pr "#{variable} = #{rec_stream_class.packet_context_field_class.variable};"
50
- when 'EVENT_COMMON_CONTEXT'
51
- pr "#{variable} = #{rec_stream_class.event_common_context_field_class.variable};"
52
- when 'EVENT_SPECIFIC_CONTEXT'
53
- pr "#{variable} = #{rec_event_class.specific_context_field_class.varible};"
54
- when 'EVENT_PAYLOAD'
55
- pr "#{variable} = #{rec_event_class.payload_field_class.variable};"
56
- else
57
- raise "invalid path #{path}"
58
- end
59
- find_field_class_path(m[2], variable)
58
+ [field_class, id]
60
59
  end
61
60
  end
62
61
 
@@ -110,7 +109,8 @@ module Babeltrace2Gen
110
109
  include BTPrinter
111
110
  include BTLocator
112
111
  extend BTFromH
113
- attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :default_clock_class, :id, :name
112
+ attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :default_clock_class,
113
+ :id, :name, :get_getter
114
114
 
115
115
  def initialize(parent:, name: nil, packet_context_field_class: nil, event_common_context_field_class: nil,
116
116
  event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil,
@@ -202,6 +202,21 @@ module Babeltrace2Gen
202
202
 
203
203
  pr "bt_stream_class_put_ref(#{variable});"
204
204
  end
205
+
206
+ # The getters code generated from event_common_context_field_class do not include
207
+ # the event variable name used by the getters. As we do not know the variable
208
+ # name that should be generated, we can not put it directly in the template,
209
+ # since, if the code generation generates another name we must update the
210
+ # template in addition.
211
+ def get_getter(event:, arg_variables:)
212
+ return unless event_common_context_field_class
213
+
214
+ field = "#{event}_cc_f"
215
+ scope do
216
+ pr "const bt_field *#{field} = bt_event_borrow_common_context_field_const(#{event});"
217
+ event_common_context_field_class.get_getter(variable: field, arg_variables: arg_variables)
218
+ end
219
+ end
205
220
  end
206
221
 
207
222
  class BTEventClass
@@ -223,7 +238,7 @@ module Babeltrace2Gen
223
238
  end
224
239
 
225
240
  def get_declarator(trace_class:, variable:, stream_class:)
226
- # Store the variable name for instrocption purpose for LOCATION_PATH
241
+ # Store the variable name for instrospection purpose (PATH)
227
242
  @variable = variable
228
243
  if @id
229
244
  pr "#{variable} = bt_event_class_create_with_id(#{stream_class}, #{@id});"
@@ -243,14 +258,14 @@ module Babeltrace2Gen
243
258
  end
244
259
  end
245
260
 
246
- if @payload_field_class
247
- var_name = "#{variable}_p_fc"
248
- scope do
249
- pr "bt_field_class *#{var_name};"
250
- @payload_field_class.get_declarator(trace_class: trace_class, variable: var_name)
251
- pr "bt_event_class_set_payload_field_class(#{variable}, #{var_name});"
252
- pr "bt_field_class_put_ref(#{var_name});"
253
- end
261
+ return unless @payload_field_class
262
+
263
+ var_name = "#{variable}_p_fc"
264
+ scope do
265
+ pr "bt_field_class *#{var_name};"
266
+ @payload_field_class.get_declarator(trace_class: trace_class, variable: var_name)
267
+ pr "bt_event_class_set_payload_field_class(#{variable}, #{var_name});"
268
+ pr "bt_field_class_put_ref(#{var_name});"
254
269
  end
255
270
  end
256
271
 
@@ -271,12 +286,12 @@ module Babeltrace2Gen
271
286
  end
272
287
  end
273
288
 
274
- if @payload_field_class
275
- field = "#{event}_p_f"
276
- scope do
277
- pr "bt_field *#{field} = bt_event_borrow_payload_field(#{event});"
278
- @payload_field_class.get_setter(variable: field, arg_variables: arg_variables)
279
- end
289
+ return unless @payload_field_class
290
+
291
+ field = "#{event}_p_f"
292
+ scope do
293
+ pr "bt_field *#{field} = bt_event_borrow_payload_field(#{event});"
294
+ @payload_field_class.get_setter(variable: field, arg_variables: arg_variables)
280
295
  end
281
296
  end
282
297
 
@@ -297,12 +312,12 @@ module Babeltrace2Gen
297
312
  end
298
313
  end
299
314
 
300
- if @payload_field_class
301
- field = "#{event}_p_f"
302
- scope do
303
- pr "const bt_field *#{field} = bt_event_borrow_payload_field_const(#{event});"
304
- @payload_field_class.get_getter(variable: field, arg_variables: arg_variables)
305
- end
315
+ return unless @payload_field_class
316
+
317
+ field = "#{event}_p_f"
318
+ scope do
319
+ pr "const bt_field *#{field} = bt_event_borrow_payload_field_const(#{event});"
320
+ @payload_field_class.get_getter(variable: field, arg_variables: arg_variables)
306
321
  end
307
322
  end
308
323
  end
@@ -310,6 +325,7 @@ module Babeltrace2Gen
310
325
  class BTFieldClass
311
326
  include BTLocator
312
327
  include BTPrinter
328
+ using HashRefinements
313
329
 
314
330
  attr_accessor :cast_type
315
331
 
@@ -353,27 +369,32 @@ module Babeltrace2Gen
353
369
  raise NotImplementedError, self.class
354
370
  end
355
371
 
356
- def bt_get_variable(_field, arg_variables)
357
- if arg_variables.empty? || arg_variables.first.is_a?(GeneratedArg)
358
- variable = rec_menber_class.name
359
- type = @cast_type || self.class.instance_variable_get(:@bt_type)
360
- arg_variables << GeneratedArg.new(type, variable)
361
- variable
362
- else
363
- arg_variables.shift
364
- end
372
+ def bt_get_variable(arg_variables, is_array: false)
373
+ internal = arg_variables.fetch('internal', [])
374
+ return internal.shift unless internal.empty?
375
+
376
+ type =
377
+ if is_array
378
+ "#{element_field_class.class.instance_variable_get(:@bt_type)}*"
379
+ else
380
+ self.class.instance_variable_get(:@bt_type)
381
+ end
382
+ var = GeneratedArg.new(@cast_type || type, rec_menber_class.name)
383
+
384
+ arg_variables.fetch_append('outputs_allocated', var) if is_array
385
+ arg_variables.fetch_append('outputs', var)
365
386
  end
366
387
 
367
388
  def get_getter(field:, arg_variables:)
368
389
  bt_func_get = self.class.instance_variable_get(:@bt_func) % 'get'
369
- variable = bt_get_variable(field, arg_variables)
390
+ variable = bt_get_variable(arg_variables).name
370
391
  cast_func = @cast_type ? "(#{@cast_type})" : ''
371
392
  pr "#{variable} = #{cast_func}#{bt_func_get}(#{field});"
372
393
  end
373
394
 
374
395
  def get_setter(field:, arg_variables:)
375
396
  bt_func_get = self.class.instance_variable_get(:@bt_func) % 'set'
376
- variable = bt_get_variable(field, arg_variables)
397
+ variable = bt_get_variable(arg_variables).name
377
398
  cast_func = @cast_type ? "(#{self.class.instance_variable_get(:@bt_type)})" : ''
378
399
  pr "#{bt_func_get}(#{field}, #{variable});"
379
400
  end
@@ -418,9 +439,9 @@ module Babeltrace2Gen
418
439
 
419
440
  def get_declarator(variable:)
420
441
  pr "bt_field_class_integer_set_field_value_range(#{variable}, #{@field_value_range});" if @field_value_range
421
- if @preferred_display_base
422
- pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
423
- end
442
+ return unless @preferred_display_base
443
+
444
+ pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
424
445
  end
425
446
  end
426
447
 
@@ -546,13 +567,14 @@ module Babeltrace2Gen
546
567
  module WithLengthField
547
568
  attr_reader :length_field_path
548
569
  end
570
+ using HashRefinements
549
571
 
550
572
  def initialize(parent:, element_field_class:, length_field_path: nil)
551
573
  super(parent: parent, element_field_class: element_field_class)
552
- if length_field_path
553
- extend(WithLengthField)
554
- @length_field_path = length_field_path
555
- end
574
+ return unless length_field_path
575
+
576
+ extend(WithLengthField)
577
+ @length_field_path = length_field_path
556
578
  end
557
579
 
558
580
  def get_declarator(trace_class:, variable:)
@@ -563,13 +585,55 @@ module Babeltrace2Gen
563
585
  if @length_field_path
564
586
  element_field_class_variable_length = "#{element_field_class_variable}_length"
565
587
  pr "bt_field_class *#{element_field_class_variable_length};"
566
- find_field_class(@length_field_path, element_field_class_variable_length)
588
+ scope do
589
+ element_field_class_variable_length_sm = "#{element_field_class_variable_length}_sm"
590
+ pr "bt_field_class_structure_member *#{element_field_class_variable_length_sm};"
591
+ field_class, id = resolve_path(@length_field_path)
592
+ id.scan(/(\w+)|(\d+)/).each do |name, index|
593
+ # String
594
+ if name
595
+ pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_name(#{field_class.variable}, \"#{name}\");"
596
+ else
597
+ pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_index(#{field_class.variable}, #{index});"
598
+ end
599
+ end
600
+ pr "#{element_field_class_variable_length} = bt_field_class_structure_member_borrow_field_class(#{element_field_class_variable_length_sm});"
601
+ end
567
602
  pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, #{element_field_class_variable_length});"
603
+ pr "bt_field_class_put_ref(#{element_field_class_variable});"
568
604
  else
569
605
  pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, NULL);"
570
606
  end
571
607
  end
572
608
  end
609
+
610
+ def get_setter(field:, arg_variables:)
611
+ field_class, id = resolve_path(@length_field_path)
612
+ length_field = field_class[id]
613
+ pr "bt_field_array_dynamic_set_length(#{field}, #{length_field.name});"
614
+ usr_var = bt_get_variable(arg_variables, is_array: true)
615
+ pr "for(uint64_t _i=0; _i < #{length_field.name} ; _i++)"
616
+ scope do
617
+ v = "#{field}_e"
618
+ pr "bt_field* #{v} = bt_field_array_borrow_element_field_by_index(#{field}, _i);"
619
+ arg_variables.fetch_append('internal', GeneratedArg.new('', "#{usr_var.name}[_i]"))
620
+ @element_field_class.get_setter(field: v, arg_variables: arg_variables)
621
+ end
622
+ end
623
+
624
+ def get_getter(field:, arg_variables:)
625
+ length = "#{field}_length"
626
+ pr "uint64_t #{length} = bt_field_array_get_length(#{field});"
627
+ usr_var = bt_get_variable(arg_variables, is_array: true)
628
+ pr "#{usr_var.name} = (#{usr_var.type}) malloc(#{length} * sizeof(#{usr_var.name}));"
629
+ pr "for(uint64_t _i=0; _i < #{length} ; _i++)"
630
+ scope do
631
+ v = "#{field}_e"
632
+ pr "const bt_field* #{v} = bt_field_array_borrow_element_field_by_index_const(#{field}, _i);"
633
+ arg_variables.fetch_append('internal', GeneratedArg.new('', "#{usr_var.name}[_i]"))
634
+ @element_field_class.get_getter(field: v, arg_variables: arg_variables)
635
+ end
636
+ end
573
637
  end
574
638
 
575
639
  class BTMemberClass
@@ -595,10 +659,12 @@ module Babeltrace2Gen
595
659
 
596
660
  def [](index)
597
661
  case index
598
- when Integer
662
+ when ::Integer
599
663
  @members[index]
600
- when String
664
+ when ::String
601
665
  @members.find { |m| m.name == index }
666
+ else
667
+ raise("Unknow Type (#{index.class}) for index: #{index}")
602
668
  end
603
669
  end
604
670
 
@@ -28,10 +28,10 @@ module Babeltrace2Gen
28
28
 
29
29
  # Scalars are leafs, avoid recursion
30
30
  def self.from_h(model)
31
- new(model[:name],model.fetch(:default_value,nil))
31
+ new(model[:name], model.fetch(:default_value, nil))
32
32
  end
33
33
 
34
- def initialize(name,usr_default_value)
34
+ def initialize(name, usr_default_value)
35
35
  @name = name
36
36
  @usr_default_value = usr_default_value
37
37
  end
@@ -47,12 +47,12 @@ module Babeltrace2Gen
47
47
  pr "if (#{val} != NULL) {"
48
48
  pr " if (!#{bt_type_is}(#{val})) {"
49
49
  pr " fprintf(stderr,\"Bad value for command line argument '%s' the value must be '%s'. \\n\",\"#{@name}\",\"#{bt_type}\");"
50
- pr " exit(1);"
51
- pr " }"
50
+ pr ' exit(1);'
51
+ pr ' }'
52
52
  pr " #{name} = #{cast_func}bt_value_#{bt_type}_get(#{val});"
53
- pr "} else {"
53
+ pr '} else {'
54
54
  pr " #{name} = #{cast_func}#{default_value};"
55
- pr "}"
55
+ pr '}'
56
56
  end
57
57
  end
58
58
 
@@ -90,12 +90,13 @@ module Babeltrace2Gen
90
90
  @bt_return_type = 'bt_bool'
91
91
  @bt_default_value = 'BT_FALSE'
92
92
 
93
- def initialize(name,usr_default_value)
93
+ def initialize(name, usr_default_value)
94
94
  bt_type = self.class.instance_variable_get(:@bt_type)
95
- if !usr_default_value.nil? and !['BT_TRUE', 'BT_FALSE'].include? usr_default_value
95
+ if !usr_default_value.nil? and !%w[BT_TRUE BT_FALSE].include? usr_default_value
96
96
  raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} (BT_TRUE or BT_FALSE) but provided '#{usr_default_value}'."
97
97
  end
98
- super(name,usr_default_value)
98
+
99
+ super(name, usr_default_value)
99
100
  end
100
101
  end
101
102
 
@@ -105,13 +106,14 @@ module Babeltrace2Gen
105
106
  @bt_return_type = 'const char*'
106
107
  @bt_default_value = 'NULL'
107
108
 
108
- def initialize(name,usr_default_value)
109
+ def initialize(name, usr_default_value)
109
110
  bt_type = self.class.instance_variable_get(:@bt_type)
110
111
  # Every object that can be converted to string is being supported.
111
112
  if !usr_default_value.nil? and !usr_default_value.respond_to?(:to_s)
112
- raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} but provided '#{usr_default_value}'."
113
+ raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} but provided '#{usr_default_value}'."
113
114
  end
114
- super(name,usr_default_value.to_s.inspect)
115
+
116
+ super(name, usr_default_value.to_s.inspect)
115
117
  end
116
118
  end
117
119
 
@@ -121,12 +123,13 @@ module Babeltrace2Gen
121
123
  @bt_return_type = 'uint64_t'
122
124
  @bt_default_value = '0'
123
125
 
124
- def initialize(name,usr_default_value)
126
+ def initialize(name, usr_default_value)
125
127
  bt_type = self.class.instance_variable_get(:@bt_type)
126
- if !usr_default_value.nil? and (!usr_default_value.kind_of? Integer or !usr_default_value.between?(0,2**64-1))
127
- raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} and must be in [0,2^64-1], but provided '#{usr_default_value}'."
128
+ if !usr_default_value.nil? and (!usr_default_value.is_a? Integer or !usr_default_value.between?(0, 2**64 - 1))
129
+ raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} and must be in [0,2^64-1], but provided '#{usr_default_value}'."
128
130
  end
129
- super(name,usr_default_value)
131
+
132
+ super(name, usr_default_value)
130
133
  end
131
134
  end
132
135
  end
@@ -1,3 +1,3 @@
1
1
  module Metababel
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -3,7 +3,6 @@
3
3
  #include <assert.h>
4
4
  #include <babeltrace2/babeltrace.h>
5
5
  #include <metababel/btx_component.h>
6
- #include <stdbool.h>
7
6
  // stdio needed because `params_definition` contain fprintf
8
7
  #include <stdio.h>
9
8
 
@@ -3,6 +3,7 @@
3
3
  #include "utarray.h"
4
4
  #include "uthash.h"
5
5
  #include <babeltrace2/babeltrace.h>
6
+ #include <stdbool.h>
6
7
 
7
8
  #ifdef __cplusplus
8
9
  extern "C" {
@@ -83,6 +84,7 @@ typedef enum btx_source_status_e btx_source_status_t;
83
84
  <% elsif options[:component_type] == 'FILTER' %>
84
85
  struct common_data_s {
85
86
  name_to_dispatcher_t *name_to_dispatcher;
87
+ name_to_dispatcher_t *name_to_matching_dispatcher;
86
88
  void *usr_data;
87
89
  const bt_value *params;
88
90
  btx_params_t *btx_params;
@@ -132,6 +134,7 @@ typedef struct btx_message_iterator_s btx_message_iterator_t;
132
134
  <% elsif options[:component_type] == 'SINK' %>
133
135
  struct common_data_s {
134
136
  name_to_dispatcher_t *name_to_dispatcher;
137
+ name_to_dispatcher_t *name_to_matching_dispatcher;
135
138
  void *usr_data;
136
139
  const bt_value *params;
137
140
  btx_params_t *btx_params;
@@ -108,14 +108,14 @@ void btx_push_messages_stream_end(
108
108
 
109
109
  <% downstream_events.each do |e| %>
110
110
  static void btx_set_message_<%= e.name_sanitized %>(
111
- bt_event *<%= event_name %>,
112
- <%= e.args.map{ |s| "#{s.type} #{s.name}" }.join(", ") %>) {
111
+ bt_event *
112
+ <%= event_name %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>) {
113
113
  <%= e.body %>
114
114
  }
115
115
 
116
116
  void btx_push_message_<%= e.name_sanitized %>(
117
- void *btx_handle,
118
- <%= e.args.map{ |s| "#{s.type} #{s.name}" }.join(", ") %>) {
117
+ void *
118
+ btx_handle<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>) {
119
119
 
120
120
  common_data_t *common_data = (common_data_t *)btx_handle;
121
121
 
@@ -129,13 +129,13 @@ void btx_push_message_<%= e.name_sanitized %>(
129
129
  common_data->self_message_iterator, event_class, stream);
130
130
  <% else %>
131
131
  bt_message *message = bt_message_event_create_with_default_clock_snapshot(
132
- common_data->self_message_iterator, event_class, stream, timestamp);
132
+ common_data->self_message_iterator, event_class, stream, _timestamp);
133
133
  <% end %>
134
134
 
135
135
  bt_event *downstream_event = bt_message_event_borrow_event(message);
136
136
 
137
137
  btx_set_message_<%= e.name_sanitized %>(
138
- downstream_event, <%= e.args.map{ |s| s.name }.join(", ") %>);
138
+ downstream_event<%= e.args.map{ |s| s.name }.join_with_prefix(", ") %>);
139
139
 
140
140
  btx_message_iterator_t *message_iterator_private_data =
141
141
  bt_self_message_iterator_get_data(common_data->self_message_iterator);
@@ -29,8 +29,8 @@ void btx_push_messages_stream_end(
29
29
 
30
30
  <% downstream_events.each do |e| %>
31
31
  void btx_push_message_<%= e.name_sanitized %>(
32
- void *btx_handle,
33
- <%= e.args.map{ |s| "#{s.type} #{s.name}" }.join(", ") %>);
32
+ void *
33
+ btx_handle<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>);
34
34
  <% end %>
35
35
  #ifdef __cplusplus
36
36
  }
@@ -24,10 +24,15 @@ static inline bt_message_iterator_class_next_method_status
24
24
  filter_message_iterator_next_initializing(
25
25
  bt_self_message_iterator *self_message_iterator,
26
26
  bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
27
+
27
28
  /* Retrieve our private data from the message iterator's user data */
28
29
  btx_message_iterator_t *message_iterator_private_data =
29
30
  bt_self_message_iterator_get_data(self_message_iterator);
30
31
 
32
+ /* Begining of Stream */
33
+ btx_push_messages_stream_beginning(self_message_iterator,
34
+ message_iterator_private_data);
35
+
31
36
  /* Call Initialize user callback */
32
37
  btx_call_callbacks_initialize_usr_data(
33
38
  message_iterator_private_data->common_data,
@@ -100,6 +105,9 @@ filter_message_iterator_next_processing_reading(
100
105
  btx_call_callbacks_finalize_usr_data(
101
106
  message_iterator_private_data->common_data,
102
107
  message_iterator_private_data->common_data->usr_data);
108
+ /* End of Stream */
109
+ btx_push_messages_stream_end(self_message_iterator,
110
+ message_iterator_private_data);
103
111
  message_iterator_private_data->state = BTX_FILTER_STATE_FINALIZING;
104
112
  message_iterator_private_data->processing_state =
105
113
  BTX_FILTER_PROCESSING_STATE_FINISHED;
@@ -125,10 +133,12 @@ filter_message_iterator_next_processing_reading(
125
133
  upstream_i++) {
126
134
  /* Current message */
127
135
  const bt_message *upstream_message = upstream_messages[upstream_i];
128
- /* Move as is if it's not an event message */
136
+ /* Forward all non event-messages downstream */
129
137
  if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
130
- bt_message_put_ref(upstream_message);
138
+ btx_downstream_push_message(message_iterator_private_data,
139
+ upstream_message);
131
140
  continue;
141
+
132
142
  }
133
143
  /* Borrow the event message's event and its class */
134
144
  const bt_event *event =
@@ -136,11 +146,35 @@ filter_message_iterator_next_processing_reading(
136
146
  const bt_event_class *event_class = bt_event_borrow_class_const(event);
137
147
 
138
148
  /* Call dispatcher or forward message downstream */
139
- name_to_dispatcher_t *s = NULL;
149
+ bool is_callback_called = false;
140
150
  const char *class_name = bt_event_class_get_name(event_class);
141
- HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
142
- if (s) {
143
- (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, event);
151
+
152
+ {
153
+ name_to_dispatcher_t *s = NULL;
154
+ HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
155
+ if (s) {
156
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
157
+ &is_callback_called);
158
+ }
159
+ }
160
+
161
+ {
162
+ const bt_stream_class *stream_class =
163
+ bt_event_class_borrow_stream_class_const(event_class);
164
+ const char *stream_class_name = bt_stream_class_get_name(stream_class);
165
+
166
+ name_to_dispatcher_t *s = NULL;
167
+ HASH_FIND_STR(common_data->name_to_matching_dispatcher, stream_class_name,
168
+ s);
169
+ if (s) {
170
+ // is_callback_called will only be modified if at least one callback is
171
+ // called.
172
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
173
+ &is_callback_called);
174
+ }
175
+ }
176
+
177
+ if (is_callback_called) {
144
178
  /* The message have been consumed, we can discard it */
145
179
  bt_message_put_ref(upstream_message);
146
180
  } else {
@@ -379,13 +413,9 @@ static void filter_finalize(bt_self_component_filter *self_component_filter) {
379
413
  // We allocate it, we need to put ref
380
414
  bt_trace_put_ref(common_data->downstream_trace);
381
415
 
382
- // Delete name_to_dispatcher
383
- name_to_dispatcher_t *current, *tmp;
384
- HASH_ITER(hh, common_data->name_to_dispatcher, current, tmp) {
385
- HASH_DEL(common_data->name_to_dispatcher, current);
386
- utarray_free(current->callbacks);
387
- free(current);
388
- }
416
+ // Delete name_to_dispatchers
417
+ btx_delete_dispatchers(common_data);
418
+ btx_delete_matching_dispatchers(common_data);
389
419
 
390
420
  // We allocate it, we need to free it
391
421
  free(common_data->btx_params);
data/template/sink.c.erb CHANGED
@@ -48,24 +48,46 @@ sink_consume(bt_self_component_sink *self_component_sink) {
48
48
  }
49
49
  /* For each consumed message */
50
50
  for (uint64_t i = 0; i < message_count; i++) {
51
- const bt_message *message = messages[i];
52
- if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
53
- bt_message_put_ref(message);
51
+ const bt_message *upstream_message = messages[i];
52
+ if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
53
+ bt_message_put_ref(upstream_message);
54
54
  continue;
55
55
  }
56
56
 
57
57
  /* Borrow the event message's event and its class */
58
- const bt_event *event = bt_message_event_borrow_event_const(message);
58
+ const bt_event *event = bt_message_event_borrow_event_const(upstream_message);
59
59
  const bt_event_class *event_class = bt_event_borrow_class_const(event);
60
60
 
61
61
  /* Call dispatcher */
62
- name_to_dispatcher_t *s = NULL;
62
+ bool is_callback_called = false;
63
63
  const char *class_name = bt_event_class_get_name(event_class);
64
- HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
65
- if (s)
66
- (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, event);
67
64
 
68
- bt_message_put_ref(message);
65
+ {
66
+ name_to_dispatcher_t *s = NULL;
67
+ HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
68
+ if (s) {
69
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
70
+ &is_callback_called);
71
+ }
72
+ }
73
+
74
+ {
75
+ const bt_stream_class *stream_class =
76
+ bt_event_class_borrow_stream_class_const(event_class);
77
+ const char *stream_class_name = bt_stream_class_get_name(stream_class);
78
+
79
+ name_to_dispatcher_t *s = NULL;
80
+ HASH_FIND_STR(common_data->name_to_matching_dispatcher, stream_class_name,
81
+ s);
82
+ if (s) {
83
+ // is_callback_called will only be modified if at least one callback is
84
+ // called.
85
+ (*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
86
+ &is_callback_called);
87
+ }
88
+ }
89
+
90
+ bt_message_put_ref(upstream_message);
69
91
  }
70
92
  end:
71
93
  return status;
@@ -122,12 +144,8 @@ static void sink_finalize(bt_self_component_sink *self_component_sink) {
122
144
  btx_call_callbacks_finalize_usr_data(common_data, common_data->usr_data);
123
145
 
124
146
  // Delete name_to_dispatcher
125
- name_to_dispatcher_t *current, *tmp;
126
- HASH_ITER(hh, common_data->name_to_dispatcher, current, tmp) {
127
- HASH_DEL(common_data->name_to_dispatcher, current);
128
- utarray_free(current->callbacks);
129
- free(current);
130
- }
147
+ btx_delete_dispatchers(common_data);
148
+ btx_delete_matching_dispatchers(common_data);
131
149
 
132
150
  // We allocate it, we need to free it
133
151
  free(common_data->btx_params);
@@ -4,24 +4,44 @@
4
4
  #include <babeltrace2/babeltrace.h>
5
5
  #include <metababel/btx_component.h>
6
6
  #include <metababel/btx_upstream.h>
7
+ #include <stdbool.h>
8
+ #include <stdlib.h>
7
9
 
8
- <% event_dispatchers.each do |e| %>
9
- static void
10
- btx_dispatch_<%= e.name_sanitized %>(UT_array *callbacks,
11
- common_data_t *common_data,
12
- const bt_event *<%= event_name %>) {
10
+ <% event_class_dispatchers.each do |e| %>
11
+ static void btx_dispatch_<%= e.name_sanitized %>(
12
+ UT_array *callbacks, common_data_t *common_data,
13
+ const bt_message *upstream_message, bool *is_callback_called) {
13
14
 
14
15
  <% e.args.each do |s| %>
15
16
  <%= s.type %> <%= s.name %>;
16
17
  <% end %>
17
- <%= e.body %>
18
+
19
+ <%# Since now event is a variable, we need to check if the body will render variables that accesses it. %>
20
+ <% if not e.body.empty? %>
21
+ const bt_event *<%= event_name %> = bt_message_event_borrow_event_const(upstream_message);
22
+ <%= "\n" + e.body %>
23
+ <% end %>
24
+
25
+ <% if e.default_clock_class %>
26
+ int64_t _timestamp;
27
+ const bt_clock_snapshot *clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(upstream_message);
28
+ bt_clock_snapshot_get_ns_from_origin(clock_snapshot, &_timestamp);
29
+ <% end %>
18
30
  // Call all the callbacks who where registered
19
31
  // Their type are declared in 'upstream.h'
20
32
  <%= e.name_sanitized %>_callback_f **p = NULL;
21
33
  while ((p = utarray_next(callbacks, p))) {
22
- (*p)((void *)common_data, common_data->usr_data,
23
- <%= e.args.map{ |s| s.name }.join(", ") %>);
34
+ (*p)((void *)common_data,
35
+ common_data
36
+ ->usr_data<%= ', _timestamp' if e.default_clock_class %><%= e.args.map{ |s| s.name }.join_with_prefix(", ") %>);
24
37
  }
38
+
39
+ <% e.args_to_free.each do |s| %>
40
+ <%= "free(#{s.name});" %>
41
+ <% end %>
42
+
43
+ if (callbacks)
44
+ *is_callback_called = true;
25
45
  }
26
46
 
27
47
  void btx_register_callbacks_<%= e.name_sanitized %>(
@@ -45,3 +65,93 @@ void btx_register_callbacks_<%= e.name_sanitized %>(
45
65
  utarray_push_back(s->callbacks, &callback);
46
66
  }
47
67
  <% end %>
68
+
69
+ <% stream_classes_matching_dispatchers.each do |s| %>
70
+ void btx_matching_dispatch_<%= s.name_sanitized %>(UT_array *callbacks,
71
+ common_data_t *common_data,
72
+ const bt_message *upstream_message,
73
+ bool *is_callback_called) {
74
+
75
+ <% s.args.each do |a| %>
76
+ <%= a.type %> <%= a.name %>;
77
+ <% end %>
78
+ const bt_event *<%= event_name %> = bt_message_event_borrow_event_const(upstream_message);
79
+ <%= s.body %>
80
+ const bt_event_class *event_class = bt_event_borrow_class_const(<%= event_name %>);
81
+ const char *event_class_name = bt_event_class_get_name(event_class);
82
+
83
+ condition_to_callback_t **p = NULL;
84
+ while ((p = utarray_next(callbacks, p))) {
85
+ <%= s.name_sanitized %>_callback_condition_f *condition =
86
+ (<%= s.name_sanitized %>_callback_condition_f *)((*p)->condition);
87
+ <%= s.name_sanitized %>_conditioned_callback_f *callback =
88
+ (<%= s.name_sanitized %>_conditioned_callback_f *)((*p)->callback);
89
+ <% if s.default_clock_class %>
90
+ int64_t _timestamp;
91
+ const bt_clock_snapshot *clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(upstream_message);
92
+ bt_clock_snapshot_get_ns_from_origin(clock_snapshot, &_timestamp);
93
+ <% end %>
94
+ bool is_condition_met = false;
95
+ condition(
96
+ (void *)common_data, common_data->usr_data, event_class_name,
97
+ &is_condition_met<%= ', _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.name }.join_with_prefix(", ") %>);
98
+ if (is_condition_met) {
99
+ callback(
100
+ (void *)common_data, common_data->usr_data,
101
+ event_class_name<%= ', _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.name }.join_with_prefix(", ") %>);
102
+ *is_callback_called = true;
103
+ }
104
+ }
105
+ }
106
+
107
+ void btx_register_matching_callback_<%= s.name_sanitized %>(
108
+ void *btx_handle, <%= s.name_sanitized %>_callback_condition_f *condition,
109
+ <%= s.name_sanitized %>_conditioned_callback_f *callback) {
110
+ // Look-up our dispatcher
111
+ name_to_dispatcher_t *s = NULL;
112
+ name_to_dispatcher_t **name_to_matching_dispatcher =
113
+ &((common_data_t *)btx_handle)->name_to_matching_dispatcher;
114
+ HASH_FIND_STR(*name_to_matching_dispatcher, "<%= s.name_sanitized %>", s);
115
+ if (!s) {
116
+ // We didn't find the dispatcher, so we need to:
117
+ // 1. Create it
118
+ s = (name_to_dispatcher_t *)malloc(sizeof(name_to_dispatcher_t));
119
+ s->name = "<%= s.name_sanitized %>";
120
+ s->dispatcher = (void *)&btx_matching_dispatch_<%= s.name_sanitized %>;
121
+ utarray_new(s->callbacks, &ut_ptr_icd);
122
+ // 2. Register it
123
+ HASH_ADD_KEYPTR(hh, *name_to_matching_dispatcher, s->name, strlen(s->name),
124
+ s);
125
+ }
126
+ // Add the callbacks to the array
127
+ condition_to_callback_t *m =
128
+ (condition_to_callback_t *)malloc(sizeof(condition_to_callback_t));
129
+ m->condition = (void *)condition;
130
+ m->callback = (void *)callback;
131
+ utarray_push_back(s->callbacks, &m);
132
+ }
133
+ <% end %>
134
+
135
+ void btx_delete_dispatchers(common_data_t *common_data) {
136
+ name_to_dispatcher_t *current, *tmp;
137
+ HASH_ITER(hh, common_data->name_to_dispatcher, current, tmp) {
138
+ HASH_DEL(common_data->name_to_dispatcher, current);
139
+ utarray_free(current->callbacks);
140
+ free(current);
141
+ }
142
+ }
143
+
144
+ void btx_delete_matching_dispatchers(common_data_t *common_data) {
145
+ name_to_dispatcher_t *current, *tmp;
146
+ HASH_ITER(hh, common_data->name_to_matching_dispatcher, current, tmp) {
147
+ // Removes the item from the hash table.
148
+ HASH_DEL(common_data->name_to_matching_dispatcher, current);
149
+ // Deletes every condition, callback pair.
150
+ condition_to_callback_t **p = NULL;
151
+ while ((p = utarray_next(current->callbacks, p))) {
152
+ free(*p);
153
+ }
154
+ utarray_free(current->callbacks);
155
+ free(current);
156
+ }
157
+ }
@@ -6,17 +6,47 @@ extern "C" {
6
6
 
7
7
  // Dispatcher
8
8
  typedef void(dispatcher_t)(UT_array *callbacks, common_data_t *common_data,
9
- const bt_event *message);
9
+ const bt_message *upstream_message, bool *is_callback_called);
10
10
 
11
- <% event_dispatchers.each do |e| %>
11
+ <% event_class_dispatchers.each do |e| %>
12
12
  <%# The signature type of callbacks %>
13
- typedef void
14
- <%= e.name_sanitized %>_callback_f(void *btx_handle, void *usr_data,
15
- <%= e.args.map{ |s| s.type }.join(", ") %>);
13
+ typedef void <%= e.name_sanitized %>_callback_f(
14
+ void *btx_handle,
15
+ void *usr_data<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| s.type }.join_with_prefix(", ") %>);
16
16
  <%# The Function who register the callbacks to the dispatcher %>
17
- extern void btx_register_callbacks_<%= e.name_sanitized %>(
17
+ void btx_register_callbacks_<%= e.name_sanitized %>(
18
18
  void *btx_handle, <%= e.name_sanitized %>_callback_f *callback);
19
19
  <% end %>
20
+
21
+ void btx_delete_dispatchers(common_data_t *common_data);
22
+
23
+ // Matching dispatcher
24
+
25
+ struct condition_to_callback_s {
26
+ void *condition;
27
+ void *callback;
28
+ };
29
+ typedef struct condition_to_callback_s condition_to_callback_t;
30
+
31
+ <% stream_classes_matching_dispatchers.each do |s| %>
32
+ <%# The signature type of condition callbacks %>
33
+ typedef void <%= s.name_sanitized %>_callback_condition_f(
34
+ void *btx_handle, void *usr_data, const char *event_class_name,
35
+ bool *matched<%= ', int64_t _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.type }.join_with_prefix(", ") %>);
36
+
37
+ <%# The signature type of callbacks to be called if the condition is met %>
38
+ typedef void <%= s.name_sanitized %>_conditioned_callback_f(
39
+ void *btx_handle, void *usr_data,
40
+ const char *
41
+ event_class_name<%= ', int64_t _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.type }.join_with_prefix(", ") %>);
42
+
43
+ void btx_register_matching_callback_<%= s.name_sanitized %>(
44
+ void *btx_handle, <%= s.name_sanitized %>_callback_condition_f *condition,
45
+ <%= s.name_sanitized %>_conditioned_callback_f *callback);
46
+ <% end %>
47
+
48
+ void btx_delete_matching_dispatchers(common_data_t *common_data);
49
+
20
50
  #ifdef __cplusplus
21
51
  }
22
52
  #endif
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: 0.0.3
4
+ version: 0.0.4
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: 2023-05-03 00:00:00.000000000 Z
13
+ date: 2023-06-26 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description:
16
16
  email: