metababel 0.0.2 → 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: 5d2bc1142062b4ea5582787ac08f4297250cfacf0fd1cfef8a6d43facdbe0c91
4
- data.tar.gz: 1ca1c72dfb7094af76b7de63b78334e366e90cd1ad9f4749e9b9606fd2c91a6e
3
+ metadata.gz: 4a06ce284438f35303ef476971d820bd7ae1c2370b58181ba36146821d4423f7
4
+ data.tar.gz: 534aff0d21827f367caa9295051d886be08e624a24775e9c3fbd19da7fef97dc
5
5
  SHA512:
6
- metadata.gz: 81c2894b9df348051da07351eede13c30c861e846ed1cd1aa45d6b0d9cd9f0afe1b1a8ee667aa5cec08c825096e86eace166e1d70e7099027ba4d77833491d87
7
- data.tar.gz: 75b744ab367615c963951248d95828a8e51365efe9024ae6b88be3f72a857e73dc4c7aef0b84f60f39383f53d3978da8e324124acd94a8bc8c28dcc6c370cb63
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) 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
@@ -56,7 +74,7 @@ class Babeltrace2Gen::BTTraceClass
56
74
  def map_event_classes_with_index
57
75
  @stream_classes.map.with_index do |s, index_stream_class|
58
76
  s.event_classes.map.with_index do |e, index_event_class|
59
- yield(e, index_stream_class, index_event_class)
77
+ yield(e, index_stream_class, index_event_class, s.default_clock_class)
60
78
  end
61
79
  end.flatten
62
80
  end
@@ -71,15 +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|
75
- arg_variables = []
92
+ event_class_dispatchers = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
93
+ arg_variables = {}
76
94
  body = Babeltrace2Gen.context(indent: 1) do
77
95
  e.get_getter(event: event_name, arg_variables: arg_variables)
78
96
  end
79
- 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', []))
99
+ end
100
+
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)
80
110
  end
81
111
 
82
- d = { event_dispatchers: event_dispatchers,
112
+ d = { event_class_dispatchers: event_class_dispatchers,
113
+ stream_classes_matching_dispatchers: stream_classes_matching_dispatchers,
83
114
  event_name: event_name }
84
115
 
85
116
  erb_render_and_save(d, 'upstream.h', folder)
@@ -88,16 +119,17 @@ end
88
119
 
89
120
  def wrote_creates(folder, t)
90
121
  event_name = 'event'
91
- downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class|
92
- arg_variables = []
122
+ downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
123
+ arg_variables = {}
93
124
  body = Babeltrace2Gen.context(indent: 1) do
94
125
  e.get_setter(event: event_name, arg_variables: arg_variables)
95
126
  end
96
- EventInfo.new(e.name, arg_variables, "\n" + body, index_stream_class, index_event_class)
127
+ EventClassInfo.new(e.name, arg_variables.fetch('outputs', []), "\n" + body, index_stream_class, index_event_class,
128
+ default_clock_class)
97
129
  end
98
130
 
99
131
  body_declarator_classes = "\n" + Babeltrace2Gen.context(indent: 1) do
100
- t.get_declarator(variable: 'trace_class')
132
+ t.get_declarator(variable: 'trace_class', self_component: 'self_component')
101
133
  end
102
134
 
103
135
  d = { body_declarator_classes: body_declarator_classes,
@@ -110,18 +142,18 @@ def wrote_creates(folder, t)
110
142
  end
111
143
 
112
144
  def wrote_component(options, d, folder)
113
- component_dispatchers = [EventInfo.new('initialize_usr_data',
114
- [GeneratedArg.new('void **', 'usr_data_p')]),
115
- EventInfo.new('finalize_usr_data',
116
- [GeneratedArg.new('void *', 'usr_data')]),
117
- EventInfo.new('read_params',
118
- [GeneratedArg.new('void *', 'usr_data'),
119
- 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')])]
120
152
 
121
153
  if options[:component_type] == 'SOURCE'
122
- component_dispatchers << EventInfo.new('push_usr_messages',
123
- [GeneratedArg.new('void *', 'usr_data'),
124
- 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')])
125
157
  end
126
158
 
127
159
  d2 = { component_dispatchers: component_dispatchers,
@@ -183,8 +215,9 @@ OptionParser.new do |opts|
183
215
  end.parse!
184
216
 
185
217
  raise OptionParser::MissingArgument if options[:component_type].nil?
218
+
186
219
  options[:plugin_name] ||= "metababel_#{options[:component_type].downcase}"
187
- options[:component_name] ||= "btx"
220
+ options[:component_name] ||= 'btx'
188
221
 
189
222
  # Babeltrace can be extended by plugins, which provide one or more component classes.
190
223
  base_folder = options[:folder] || "#{options[:component_type]}.#{options[:plugin_name]}.#{options[:component_name]}"
@@ -203,9 +236,11 @@ if options.key?(:params)
203
236
  end
204
237
  d[:params_declaration] = c.get_struct_definition('params')
205
238
  d[:params_definition] = body
239
+ else
240
+ d[:params_declaration] = 'char _dummy;'
206
241
  end
207
242
 
208
- 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')
209
244
  erb_render_and_save({ options: options }, 'metababel.h', folder, prefix: '')
210
245
 
211
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
 
@@ -89,7 +88,8 @@ module Babeltrace2Gen
89
88
  end
90
89
  end
91
90
 
92
- def get_declarator(variable:)
91
+ def get_declarator(variable:, self_component:)
92
+ pr "#{variable} = bt_trace_class_create(#{self_component});"
93
93
  bt_set_conditionally(@assigns_automatic_stream_class_id) do |v|
94
94
  pr "bt_trace_class_set_assigns_automatic_stream_class_id(#{variable}, #{v});"
95
95
  end
@@ -98,7 +98,7 @@ module Babeltrace2Gen
98
98
  stream_class_name = "#{variable}_sc_#{i}"
99
99
  scope do
100
100
  pr "bt_stream_class *#{stream_class_name};"
101
- m.get_declarator(trace_class: variable, variable: stream_class_name)
101
+ m.get_declarator(variable: stream_class_name, self_component: self_component, trace_class: variable)
102
102
  end
103
103
  end
104
104
  end
@@ -109,10 +109,15 @@ module Babeltrace2Gen
109
109
  include BTPrinter
110
110
  include BTLocator
111
111
  extend BTFromH
112
- attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :id, :name
112
+ attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :default_clock_class,
113
+ :id, :name, :get_getter
113
114
 
114
115
  def initialize(parent:, name: nil, packet_context_field_class: nil, event_common_context_field_class: nil,
115
- event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil)
116
+ event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil,
117
+ default_clock_class: nil)
118
+ # Handle clock class property:
119
+ # https://babeltrace.org/docs/v2.0/libbabeltrace2/group__api-tir-clock-cls.html#gae0f705eb48cd65784da28b1906ca05a5
120
+
116
121
  @parent = parent
117
122
  @name = name
118
123
 
@@ -137,15 +142,26 @@ module Babeltrace2Gen
137
142
  end
138
143
  @assigns_automatic_stream_id = assigns_automatic_stream_id
139
144
  @id = id
145
+ @default_clock_class = default_clock_class
140
146
  end
141
147
 
142
- def get_declarator(trace_class:, variable:)
148
+ def get_declarator(variable:, trace_class:, self_component:)
143
149
  if @id
144
150
  pr "#{variable} = bt_stream_class_create_with_id(#{trace_class}, #{@id});"
145
151
  else
146
152
  pr "#{variable} = bt_stream_class_create(#{trace_class});"
147
153
  end
148
154
  pr "bt_stream_class_set_name(#{variable}, \"#{name}\");" if @name
155
+ if @default_clock_class
156
+ clock_class_name = "#{variable}_dcc"
157
+ scope do
158
+ pr "bt_clock_class *#{clock_class_name};"
159
+ # TODO: @default_clock_class.get_declarator(variable: clock_class_name, self_component: self_component)
160
+ pr "#{clock_class_name} = bt_clock_class_create(#{self_component});"
161
+ pr "bt_stream_class_set_default_clock_class(#{variable}, #{clock_class_name});"
162
+ pr "bt_clock_class_put_ref(#{clock_class_name});"
163
+ end
164
+ end
149
165
 
150
166
  if @packet_context_field_class
151
167
  var_pc = "#{variable}_pc_fc"
@@ -185,7 +201,21 @@ module Babeltrace2Gen
185
201
  end
186
202
 
187
203
  pr "bt_stream_class_put_ref(#{variable});"
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
188
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
189
219
  end
190
220
  end
191
221
 
@@ -208,7 +238,7 @@ module Babeltrace2Gen
208
238
  end
209
239
 
210
240
  def get_declarator(trace_class:, variable:, stream_class:)
211
- # Store the variable name for instrocption purpose for LOCATION_PATH
241
+ # Store the variable name for instrospection purpose (PATH)
212
242
  @variable = variable
213
243
  if @id
214
244
  pr "#{variable} = bt_event_class_create_with_id(#{stream_class}, #{@id});"
@@ -228,14 +258,14 @@ module Babeltrace2Gen
228
258
  end
229
259
  end
230
260
 
231
- if @payload_field_class
232
- var_name = "#{variable}_p_fc"
233
- scope do
234
- pr "bt_field_class *#{var_name};"
235
- @payload_field_class.get_declarator(trace_class: trace_class, variable: var_name)
236
- pr "bt_event_class_set_payload_field_class(#{variable}, #{var_name});"
237
- pr "bt_field_class_put_ref(#{var_name});"
238
- 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});"
239
269
  end
240
270
  end
241
271
 
@@ -256,12 +286,12 @@ module Babeltrace2Gen
256
286
  end
257
287
  end
258
288
 
259
- if @payload_field_class
260
- field = "#{event}_p_f"
261
- scope do
262
- pr "bt_field *#{field} = bt_event_borrow_payload_field(#{event});"
263
- @payload_field_class.get_setter(variable: field, arg_variables: arg_variables)
264
- 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)
265
295
  end
266
296
  end
267
297
 
@@ -282,12 +312,12 @@ module Babeltrace2Gen
282
312
  end
283
313
  end
284
314
 
285
- if @payload_field_class
286
- field = "#{event}_p_f"
287
- scope do
288
- pr "const bt_field *#{field} = bt_event_borrow_payload_field_const(#{event});"
289
- @payload_field_class.get_getter(variable: field, arg_variables: arg_variables)
290
- 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)
291
321
  end
292
322
  end
293
323
  end
@@ -295,6 +325,7 @@ module Babeltrace2Gen
295
325
  class BTFieldClass
296
326
  include BTLocator
297
327
  include BTPrinter
328
+ using HashRefinements
298
329
 
299
330
  attr_accessor :cast_type
300
331
 
@@ -338,27 +369,32 @@ module Babeltrace2Gen
338
369
  raise NotImplementedError, self.class
339
370
  end
340
371
 
341
- def bt_get_variable(_field, arg_variables)
342
- if arg_variables.empty? || arg_variables.first.is_a?(GeneratedArg)
343
- variable = rec_menber_class.name
344
- type = @cast_type || self.class.instance_variable_get(:@bt_type)
345
- arg_variables << GeneratedArg.new(type, variable)
346
- variable
347
- else
348
- arg_variables.shift
349
- 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)
350
386
  end
351
387
 
352
388
  def get_getter(field:, arg_variables:)
353
389
  bt_func_get = self.class.instance_variable_get(:@bt_func) % 'get'
354
- variable = bt_get_variable(field, arg_variables)
390
+ variable = bt_get_variable(arg_variables).name
355
391
  cast_func = @cast_type ? "(#{@cast_type})" : ''
356
392
  pr "#{variable} = #{cast_func}#{bt_func_get}(#{field});"
357
393
  end
358
394
 
359
395
  def get_setter(field:, arg_variables:)
360
396
  bt_func_get = self.class.instance_variable_get(:@bt_func) % 'set'
361
- variable = bt_get_variable(field, arg_variables)
397
+ variable = bt_get_variable(arg_variables).name
362
398
  cast_func = @cast_type ? "(#{self.class.instance_variable_get(:@bt_type)})" : ''
363
399
  pr "#{bt_func_get}(#{field}, #{variable});"
364
400
  end
@@ -403,9 +439,9 @@ module Babeltrace2Gen
403
439
 
404
440
  def get_declarator(variable:)
405
441
  pr "bt_field_class_integer_set_field_value_range(#{variable}, #{@field_value_range});" if @field_value_range
406
- if @preferred_display_base
407
- pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
408
- end
442
+ return unless @preferred_display_base
443
+
444
+ pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
409
445
  end
410
446
  end
411
447
 
@@ -531,13 +567,14 @@ module Babeltrace2Gen
531
567
  module WithLengthField
532
568
  attr_reader :length_field_path
533
569
  end
570
+ using HashRefinements
534
571
 
535
572
  def initialize(parent:, element_field_class:, length_field_path: nil)
536
573
  super(parent: parent, element_field_class: element_field_class)
537
- if length_field_path
538
- extend(WithLengthField)
539
- @length_field_path = length_field_path
540
- end
574
+ return unless length_field_path
575
+
576
+ extend(WithLengthField)
577
+ @length_field_path = length_field_path
541
578
  end
542
579
 
543
580
  def get_declarator(trace_class:, variable:)
@@ -548,13 +585,55 @@ module Babeltrace2Gen
548
585
  if @length_field_path
549
586
  element_field_class_variable_length = "#{element_field_class_variable}_length"
550
587
  pr "bt_field_class *#{element_field_class_variable_length};"
551
- 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
552
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});"
553
604
  else
554
605
  pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, NULL);"
555
606
  end
556
607
  end
557
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
558
637
  end
559
638
 
560
639
  class BTMemberClass
@@ -580,10 +659,12 @@ module Babeltrace2Gen
580
659
 
581
660
  def [](index)
582
661
  case index
583
- when Integer
662
+ when ::Integer
584
663
  @members[index]
585
- when String
664
+ when ::String
586
665
  @members.find { |m| m.name == index }
666
+ else
667
+ raise("Unknow Type (#{index.class}) for index: #{index}")
587
668
  end
588
669
  end
589
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.2'
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;
@@ -37,7 +37,7 @@ void btx_downstream_push_message(
37
37
 
38
38
  bt_trace_class *
39
39
  btx_downstream_trace_class_create_rec(bt_self_component *self_component) {
40
- bt_trace_class *trace_class = bt_trace_class_create(self_component);
40
+ bt_trace_class *trace_class;
41
41
  <%= body_declarator_classes %>
42
42
  return trace_class;
43
43
  }
@@ -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
 
@@ -124,13 +124,18 @@ void btx_push_message_<%= e.name_sanitized %>(
124
124
  bt_stream_class *stream_class = bt_stream_borrow_class(stream);
125
125
  bt_event_class *event_class = bt_stream_class_borrow_event_class_by_index(
126
126
  stream_class, <%= e.index_event_class %>);
127
-
127
+ <% if !e.default_clock_class %>
128
128
  bt_message *message = bt_message_event_create(
129
129
  common_data->self_message_iterator, event_class, stream);
130
+ <% else %>
131
+ bt_message *message = bt_message_event_create_with_default_clock_snapshot(
132
+ common_data->self_message_iterator, event_class, stream, _timestamp);
133
+ <% end %>
134
+
130
135
  bt_event *downstream_event = bt_message_event_borrow_event(message);
131
136
 
132
137
  btx_set_message_<%= e.name_sanitized %>(
133
- downstream_event, <%= e.args.map{ |s| s.name }.join(", ") %>);
138
+ downstream_event<%= e.args.map{ |s| s.name }.join_with_prefix(", ") %>);
134
139
 
135
140
  btx_message_iterator_t *message_iterator_private_data =
136
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 {
@@ -241,7 +275,7 @@ filter_initialize(bt_self_component_filter *self_component_filter,
241
275
 
242
276
  /* Allocate a private data structure */
243
277
  common_data_t *common_data = calloc(1, sizeof(common_data_t));
244
- common_data->btx_params = calloc(1,sizeof(btx_params_t));
278
+ common_data->btx_params = calloc(1, sizeof(btx_params_t));
245
279
  common_data->params = params;
246
280
  // Read parameters
247
281
  btx_populate_params(common_data);
@@ -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;
@@ -80,7 +102,7 @@ sink_initialize(bt_self_component_sink *self_component_sink,
80
102
  const bt_value *params, void *initialize_method_data) {
81
103
  /* Allocate a private data structure */
82
104
  common_data_t *common_data = calloc(1, sizeof(common_data_t));
83
- common_data->btx_params = calloc(1,sizeof(btx_params_t));
105
+ common_data->btx_params = calloc(1, sizeof(btx_params_t));
84
106
  common_data->params = params;
85
107
  // Read parameters
86
108
  btx_populate_params(common_data);
@@ -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);
@@ -93,7 +93,7 @@ source_initialize(bt_self_component_source *self_component_source,
93
93
  const bt_value *params, void *initialize_method_data) {
94
94
  /* Allocate a private data structure */
95
95
  common_data_t *common_data = calloc(1, sizeof(common_data_t));
96
- common_data->btx_params = calloc(1,sizeof(btx_params_t));
96
+ common_data->btx_params = calloc(1, sizeof(btx_params_t));
97
97
  common_data->params = params;
98
98
  // Read parameters
99
99
  btx_populate_params(common_data);
@@ -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.2
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-01 00:00:00.000000000 Z
13
+ date: 2023-06-26 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description:
16
16
  email:
@@ -55,8 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
57
  requirements: []
58
- rubyforge_project:
59
- rubygems_version: 2.7.6.3
58
+ rubygems_version: 3.3.3
60
59
  signing_key:
61
60
  specification_version: 4
62
61
  summary: Helper for creation Babeltrace plugins