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 +4 -4
- data/bin/metababel +58 -29
- data/lib/metababel/bt2_stream_classes_generator.rb +133 -67
- data/lib/metababel/bt2_values_generator.rb +19 -16
- data/lib/metababel/version.rb +1 -1
- data/template/component.c.erb +0 -1
- data/template/component.h.erb +3 -0
- data/template/downstream.c.erb +6 -6
- data/template/downstream.h.erb +2 -2
- data/template/filter.c.erb +43 -13
- data/template/sink.c.erb +33 -15
- data/template/upstream.c.erb +118 -8
- data/template/upstream.h.erb +36 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a06ce284438f35303ef476971d820bd7ae1c2370b58181ba36146821d4423f7
|
|
4
|
+
data.tar.gz: 534aff0d21827f367caa9295051d886be08e624a24775e9c3fbd19da7fef97dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 = [
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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 <<
|
|
127
|
-
|
|
128
|
-
|
|
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] ||=
|
|
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] =
|
|
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:
|
|
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
|
|
35
|
-
path.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
56
|
+
raise "invalid path #{path}"
|
|
41
57
|
end
|
|
42
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
422
|
-
|
|
423
|
-
|
|
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
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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
|
-
|
|
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
|
|
51
|
-
pr
|
|
50
|
+
pr ' exit(1);'
|
|
51
|
+
pr ' }'
|
|
52
52
|
pr " #{name} = #{cast_func}bt_value_#{bt_type}_get(#{val});"
|
|
53
|
-
pr
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
113
|
+
raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} but provided '#{usr_default_value}'."
|
|
113
114
|
end
|
|
114
|
-
|
|
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.
|
|
127
|
-
|
|
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
|
-
|
|
131
|
+
|
|
132
|
+
super(name, usr_default_value)
|
|
130
133
|
end
|
|
131
134
|
end
|
|
132
135
|
end
|
data/lib/metababel/version.rb
CHANGED
data/template/component.c.erb
CHANGED
data/template/component.h.erb
CHANGED
|
@@ -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;
|
data/template/downstream.c.erb
CHANGED
|
@@ -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
|
|
112
|
-
|
|
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 *
|
|
118
|
-
|
|
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,
|
|
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
|
|
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);
|
data/template/downstream.h.erb
CHANGED
|
@@ -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 *
|
|
33
|
-
|
|
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
|
}
|
data/template/filter.c.erb
CHANGED
|
@@ -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
|
-
/*
|
|
136
|
+
/* Forward all non event-messages downstream */
|
|
129
137
|
if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
|
|
130
|
-
|
|
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
|
-
|
|
149
|
+
bool is_callback_called = false;
|
|
140
150
|
const char *class_name = bt_event_class_get_name(event_class);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
383
|
-
|
|
384
|
-
|
|
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 *
|
|
52
|
-
if (bt_message_get_type(
|
|
53
|
-
bt_message_put_ref(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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);
|
data/template/upstream.c.erb
CHANGED
|
@@ -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
|
-
<%
|
|
9
|
-
static void
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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,
|
|
23
|
-
|
|
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
|
+
}
|
data/template/upstream.h.erb
CHANGED
|
@@ -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
|
|
9
|
+
const bt_message *upstream_message, bool *is_callback_called);
|
|
10
10
|
|
|
11
|
-
<%
|
|
11
|
+
<% event_class_dispatchers.each do |e| %>
|
|
12
12
|
<%# The signature type of callbacks %>
|
|
13
|
-
typedef void
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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.
|
|
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-
|
|
13
|
+
date: 2023-06-26 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description:
|
|
16
16
|
email:
|