metababel 0.1.0 → 1.0.1
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/README.md +13 -1
- data/bin/metababel +380 -165
- data/lib/metababel/bt2_generator_utils.rb +2 -2
- data/lib/metababel/bt2_matching_utils.rb +72 -0
- data/lib/metababel/{bt2_stream_classes_generator.rb → bt2_trace_class_generator.rb} +200 -19
- data/lib/metababel/bt2_values_generator.rb +3 -3
- data/lib/metababel/version.rb +1 -1
- data/lib/metababel.rb +1 -1
- data/template/component.c.erb +15 -49
- data/template/component.h.erb +43 -17
- data/template/downstream.c.erb +49 -19
- data/template/downstream.h.erb +11 -1
- data/template/filter.c.erb +29 -37
- data/template/sink.c.erb +17 -37
- data/template/source.c.erb +19 -12
- data/template/upstream.c.erb +62 -111
- data/template/upstream.h.erb +10 -36
- metadata +8 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8622843bd93dc9b0e2ed91f3ad7bb444ea2216ba183651d17773de232749a187
|
|
4
|
+
data.tar.gz: 762a87b56229cee6bebe99ebb5358610672a6fb2a171718c3255ad079391ba85
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0fbe1685dafbc6d45e03a494607efa1010cde5973167f394150322b36d784eb23305664b8adea0ef12d90c0552a61d726cb1fce83620211f8827c1e4101f0ee0
|
|
7
|
+
data.tar.gz: cb578b9f45359fd1a93d219761f41ecdb0e0670150be69c731f4d5c1c2695e3ade918e2b5e825701cff380dcaaad6f76c09638628664f3d879f009191e9f9b58
|
data/README.md
CHANGED
|
@@ -57,4 +57,16 @@ stateDiagram-v2
|
|
|
57
57
|
|
|
58
58
|
At finalization we will call the `btx_user_finalization(struct xprof_common_data *common_data)`
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
# Callbacks Registration and Calling order
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
0 register_callback
|
|
64
|
+
1 call_initialize_component # Cannot Push
|
|
65
|
+
2 call_read_params
|
|
66
|
+
3 stream_begin
|
|
67
|
+
4 call_initialize_processing # Can Push
|
|
68
|
+
5 call_callbacks
|
|
69
|
+
5 call_finalize_processing # Can Push
|
|
70
|
+
6 stream_end
|
|
71
|
+
7 call_finalize_component # Cannot push
|
|
72
|
+
```
|
data/bin/metababel
CHANGED
|
@@ -5,19 +5,8 @@ require 'optparse'
|
|
|
5
5
|
require 'erb'
|
|
6
6
|
require 'metababel'
|
|
7
7
|
require 'fileutils'
|
|
8
|
-
|
|
9
|
-
|
|
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
|
|
8
|
+
require 'set'
|
|
9
|
+
require 'ostruct'
|
|
21
10
|
|
|
22
11
|
class Array
|
|
23
12
|
def join_with_prefix(sep)
|
|
@@ -44,19 +33,113 @@ class Hash
|
|
|
44
33
|
end
|
|
45
34
|
end
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
class Babeltrace2Gen::BTTraceClass
|
|
37
|
+
def filter_map_event_classes_with_index
|
|
38
|
+
@stream_classes.map.with_index do |s, index_stream_class|
|
|
39
|
+
s.event_classes.filter_map.with_index do |e, index_event_class|
|
|
40
|
+
yield(e, index_stream_class, index_event_class, s.default_clock_class)
|
|
41
|
+
end
|
|
42
|
+
end.flatten(1)
|
|
51
43
|
end
|
|
52
44
|
end
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
def sanitize(str)
|
|
47
|
+
str.gsub(/[^0-9A-Za-z-]/, '_')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class BaseDispatch
|
|
55
51
|
def name_sanitized
|
|
56
|
-
name
|
|
52
|
+
sanitize(@name)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# https://ruby-doc.org/3.2.2/Hash.html#class-Hash-label-User-Defined+Hash+Keys
|
|
56
|
+
def ==(other)
|
|
57
|
+
self.class === other and
|
|
58
|
+
instance_variables.all? { |s| instance_variable_get(s) == other.instance_variable_get(s) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
alias eql? ==
|
|
62
|
+
|
|
63
|
+
def hash
|
|
64
|
+
instance_variables.reduce(0) { |a, b| a ^ instance_variable_get(b).hash }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class StaticDispatcher < BaseDispatch
|
|
69
|
+
attr_reader :name, :args, :no_btx_handle
|
|
70
|
+
|
|
71
|
+
def initialize(name, args, no_btx_handle: false)
|
|
72
|
+
@name = name
|
|
73
|
+
@args = args
|
|
74
|
+
@no_btx_handle = no_btx_handle
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class DispatchType < BaseDispatch
|
|
79
|
+
attr_reader :name, :args, :id, :matched_dispatchers
|
|
80
|
+
|
|
81
|
+
def initialize(name, args, id, matched_dispatchers)
|
|
82
|
+
@name = name
|
|
83
|
+
@args = args
|
|
84
|
+
@id = id
|
|
85
|
+
@matched_dispatchers = matched_dispatchers
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class Dispatcher < BaseDispatch
|
|
90
|
+
attr_reader :event_nane, :event, :name,
|
|
91
|
+
:index_stream_class, :index_event_class,
|
|
92
|
+
:default_clock_class,
|
|
93
|
+
:dispatch_types
|
|
94
|
+
|
|
95
|
+
def initialize(event, event_name,
|
|
96
|
+
mode,
|
|
97
|
+
index_stream_class, index_event_class, default_clock_class)
|
|
98
|
+
@event = event
|
|
99
|
+
@event_name = event_name
|
|
100
|
+
@mode = mode
|
|
101
|
+
@index_stream_class = index_stream_class
|
|
102
|
+
@index_event_class = index_event_class
|
|
103
|
+
@default_clock_class = default_clock_class
|
|
104
|
+
@dispatch_types = []
|
|
105
|
+
@name = event.name
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def body_args
|
|
109
|
+
@body_args ||= begin
|
|
110
|
+
arg_variables = {}
|
|
111
|
+
body = Babeltrace2Gen.context(indent: 1) do
|
|
112
|
+
if @mode == 'setter'
|
|
113
|
+
@event.get_setter(event: @event_name, arg_variables: arg_variables)
|
|
114
|
+
elsif @mode == 'getter'
|
|
115
|
+
@event.get_getter(event: @event_name, arg_variables: arg_variables)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
[arg_variables, body]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# We preprent an empty new line from the body as a hack, to correct the indentation
|
|
123
|
+
# Indeeed the <%= body %> will be indented, but we don't don't want it,
|
|
124
|
+
# in the body string is already indented
|
|
125
|
+
# But we clean the white space empty line afterward \o/
|
|
126
|
+
def body
|
|
127
|
+
"\n" + body_args[1]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def args
|
|
131
|
+
evt_args = []
|
|
132
|
+
evt_args += [GeneratedArg.new('int64_t', '_timestamp')] if @default_clock_class
|
|
133
|
+
evt_args += body_args[0].fetch('outputs', [])
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def args_to_free
|
|
137
|
+
body_args[0].fetch('outputs_allocated', [])
|
|
57
138
|
end
|
|
58
139
|
end
|
|
59
140
|
|
|
141
|
+
GeneratedArg = Struct.new(:type, :name)
|
|
142
|
+
|
|
60
143
|
def erb_render_and_save(vars,
|
|
61
144
|
basename, out_folder, out_name: nil, prefix: 'btx_')
|
|
62
145
|
template = File.read(File.join(__dir__, "../template/#{basename}.erb"))
|
|
@@ -65,202 +148,334 @@ def erb_render_and_save(vars,
|
|
|
65
148
|
# The regex remove the lines who are not indented
|
|
66
149
|
# Maybe related to `https://github.com/ruby/erb/issues/24`
|
|
67
150
|
str = ERB.new(template, trim_mode: '<>').result_with_hash(vars).gsub(/^ +$\n/, '')
|
|
68
|
-
File.
|
|
69
|
-
f.write(str)
|
|
70
|
-
end
|
|
151
|
+
File.write(File.join(out_folder, "#{prefix}#{out_name || basename}"), str)
|
|
71
152
|
end
|
|
72
153
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
s.event_classes.map.with_index do |e, index_event_class|
|
|
77
|
-
yield(e, index_stream_class, index_event_class, s.default_clock_class)
|
|
78
|
-
end
|
|
79
|
-
end.flatten
|
|
80
|
-
end
|
|
81
|
-
end
|
|
154
|
+
def parse_argv
|
|
155
|
+
# Display help if no arguments.
|
|
156
|
+
ARGV << '-h' if ARGV.empty?
|
|
82
157
|
|
|
83
|
-
|
|
84
|
-
|
|
158
|
+
options = {}
|
|
159
|
+
|
|
160
|
+
options[:disable_callbaks] = ['on_downstream'].to_set
|
|
85
161
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
event_class_dispatchers = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
93
|
-
arg_variables = {}
|
|
94
|
-
body = Babeltrace2Gen.context(indent: 1) do
|
|
95
|
-
e.get_getter(event: event_name, arg_variables: arg_variables)
|
|
162
|
+
OptionParser.new do |opts|
|
|
163
|
+
opts.banner = 'Usage: example.rb [options]'
|
|
164
|
+
|
|
165
|
+
opts.on('-h', '--help', 'Prints this help') do
|
|
166
|
+
puts opts
|
|
167
|
+
exit
|
|
96
168
|
end
|
|
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
169
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
body = Babeltrace2Gen.context(indent: 1) do
|
|
106
|
-
s.get_getter(event: event_name, arg_variables: arg_variables)
|
|
107
|
-
end
|
|
170
|
+
opts.on('-v', '--version', 'Prints this help') do
|
|
171
|
+
puts "Ruby: #{RUBY_VERSION}"
|
|
172
|
+
puts "Metababel: #{Metababel::VERSION}"
|
|
173
|
+
exit
|
|
108
174
|
end
|
|
109
|
-
StreamClassInfo.new(s.name, arg_variables.fetch('outputs', []), body, s.default_clock_class)
|
|
110
|
-
end
|
|
111
175
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
176
|
+
opts.on('-t', '--component TYPE', '[Mandatory] Node within a trace processing graph.') do |p|
|
|
177
|
+
options[:component_type] = p
|
|
178
|
+
end
|
|
115
179
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
end
|
|
180
|
+
opts.on('-u', '--upstreams PATH', Array, '[Mandatory] Path to the bt2 YAML files for the upstream model.') do |p|
|
|
181
|
+
options[:upstreams] = p
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
opts.on('-d', '--downstream PATH', '[Optional] Path to the bt2 YAML file for the downstream model.') do |p|
|
|
185
|
+
options[:downstream] = p
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
opts.on('-p', '--plugin-name PATH', '[Optional] Name of the bt2 plugin created.') do |p|
|
|
189
|
+
options[:plugin_name] = p
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
opts.on('-c', '--component-name PATH', '[Optional] Name of the bt2 componant created.') do |p|
|
|
193
|
+
options[:component_name] = p
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
opts.on('--params PATH', '[Optional] Paht to the bt2 YAML params definition.') do |p|
|
|
197
|
+
options[:params] = p
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
opts.on('-m', '--matching PATH', '[Optional] Path to bt2 YAML matching-callbacks definitions.') do |p|
|
|
201
|
+
options[:matching] = p
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
opts.on('-o', '--output FOLDER', '[Optional] Output folder path.') do |p|
|
|
205
|
+
options[:folder] = p
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
opts.on('-i', '--usr-data-header NAME', '[Optional] User datatypes definitions.') do |p|
|
|
209
|
+
options[:usr_data_header] = p
|
|
210
|
+
end
|
|
119
211
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
123
|
-
arg_variables = {}
|
|
124
|
-
body = Babeltrace2Gen.context(indent: 1) do
|
|
125
|
-
e.get_setter(event: event_name, arg_variables: arg_variables)
|
|
212
|
+
opts.on('--enable-callbacks NAME', Array, '[Optional] Enable some callbacks type') do |p|
|
|
213
|
+
options[:disable_callbaks] -= p.to_set
|
|
126
214
|
end
|
|
127
|
-
|
|
128
|
-
|
|
215
|
+
|
|
216
|
+
end.parse!
|
|
217
|
+
|
|
218
|
+
raise OptionParser::MissingArgument if options[:component_type].nil?
|
|
219
|
+
|
|
220
|
+
options[:plugin_name] ||= "metababel_#{options[:component_type].downcase}"
|
|
221
|
+
options[:component_name] ||= 'btx'
|
|
222
|
+
|
|
223
|
+
options
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def get_dispatch_type(em, default_clock_class, context)
|
|
227
|
+
dispatchers = em.domain ? OpenStruct.new(context).instance_eval(em.domain) : context['all']
|
|
228
|
+
raise "Nil or empty event set for '#{em.set_id}'." unless dispatchers.is_a?(Set)
|
|
229
|
+
|
|
230
|
+
matched_dispatchers, signatures = dispatchers.filter_map do |dispatcher|
|
|
231
|
+
extracted_args = dispatcher.event.match?(em)
|
|
232
|
+
[dispatcher, extracted_args] if extracted_args
|
|
233
|
+
end.transpose
|
|
234
|
+
|
|
235
|
+
if !matched_dispatchers || matched_dispatchers.empty?
|
|
236
|
+
raise "No event matched '#{em.set_id}', at least one matching event required."
|
|
129
237
|
end
|
|
130
238
|
|
|
131
|
-
|
|
132
|
-
|
|
239
|
+
# Verify the uniqueness of signatures.
|
|
240
|
+
# Note that `s.type` takes into account the `cast_type`
|
|
241
|
+
# (see TestMatchingConflictingSignatures for more details)
|
|
242
|
+
unique_signatures = signatures.uniq
|
|
243
|
+
unless unique_signatures.size == 1
|
|
244
|
+
signatures_str = unique_signatures.map { |s| "(#{s.map(&:type).join(', ')})" }.join(', ')
|
|
245
|
+
raise "Conflicting signatures for '#{em.set_id}', found #{unique_signatures.size} signatures, only one allowed: '#{signatures_str}'"
|
|
133
246
|
end
|
|
134
247
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
248
|
+
# Modify the dispatcher to add the new dispatchType
|
|
249
|
+
name = em.set_id
|
|
250
|
+
dispatch_type_args = []
|
|
251
|
+
dispatch_type_args += [GeneratedArg.new('int64_t', '_timestamp')] if default_clock_class
|
|
252
|
+
dispatch_type_args += [GeneratedArg.new('const char *', '_event_class_name')]
|
|
253
|
+
dispatch_type_args += signatures.pop
|
|
254
|
+
|
|
255
|
+
dispatch_type = DispatchType.new(
|
|
256
|
+
name, dispatch_type_args, "matching_#{sanitize(name)}", matched_dispatchers
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Update context for further events filtering.
|
|
260
|
+
context[dispatch_type.name] = dispatch_type.matched_dispatchers.to_set
|
|
261
|
+
|
|
262
|
+
# Exclude unnecessary rendering.
|
|
263
|
+
return false unless em.register
|
|
139
264
|
|
|
140
|
-
|
|
141
|
-
|
|
265
|
+
matched_dispatchers.each { |dispatcher| dispatcher.dispatch_types << dispatch_type }
|
|
266
|
+
|
|
267
|
+
dispatch_type
|
|
142
268
|
end
|
|
143
269
|
|
|
144
|
-
def
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
GeneratedArg.new('btx_params_t *', 'usr_params')])]
|
|
152
|
-
|
|
153
|
-
if options[:component_type] == 'SOURCE'
|
|
154
|
-
component_dispatchers << EventClassInfo.new('push_usr_messages',
|
|
155
|
-
[GeneratedArg.new('void *', 'usr_data'),
|
|
156
|
-
GeneratedArg.new('btx_source_status_t*', 'status')])
|
|
157
|
-
end
|
|
270
|
+
def validate_model(yaml)
|
|
271
|
+
# Stream and event classes must have a 'name' as minimum requirement.
|
|
272
|
+
raise "Missing 'name' attr in model #{yaml}" unless yaml[:stream_classes].all? do |d|
|
|
273
|
+
d.key?(:name) && d[:event_classes].all? do |d2|
|
|
274
|
+
d2.key?(:name)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
158
277
|
|
|
159
|
-
|
|
160
|
-
|
|
278
|
+
# Event class name must be unique
|
|
279
|
+
events = yaml[:stream_classes].flat_map { |sc| sc[:event_classes] }.map { |e| e[:name] }
|
|
280
|
+
raise "Duplicated 'event' in model #{yaml}" unless events.length == events.uniq.length
|
|
161
281
|
|
|
162
|
-
|
|
163
|
-
erb_render_and_save(d2.update(d).update(options: options), 'component.c', folder)
|
|
282
|
+
yaml
|
|
164
283
|
end
|
|
165
284
|
|
|
166
|
-
|
|
167
|
-
|
|
285
|
+
def load_models(models)
|
|
286
|
+
yaml = [models].flatten
|
|
287
|
+
.map { |f| YAML.load_file(f) }
|
|
288
|
+
.reduce({}) { |s, y| s.deep_merge(y) { |_key, old, new| old + new } }
|
|
289
|
+
validate_model(yaml)
|
|
290
|
+
end
|
|
168
291
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
opts.banner = 'Usage: example.rb [options]'
|
|
292
|
+
class ContextBuilder
|
|
293
|
+
attr_accessor :cli_options
|
|
172
294
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
exit
|
|
295
|
+
def initialize
|
|
296
|
+
@cli_options = parse_argv
|
|
176
297
|
end
|
|
177
298
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
299
|
+
def base_folder
|
|
300
|
+
@base_folder ||= begin
|
|
301
|
+
f = @cli_options[:folder] || "#{@cli_options[:component_type]}.#{@cli_options[:plugin_name]}.#{@cli_options[:component_name]}"
|
|
302
|
+
FileUtils.mkdir_p(f)
|
|
303
|
+
f
|
|
304
|
+
end
|
|
182
305
|
end
|
|
183
306
|
|
|
184
|
-
|
|
185
|
-
|
|
307
|
+
def folder
|
|
308
|
+
@folder ||= begin
|
|
309
|
+
f = "#{base_folder}/metababel"
|
|
310
|
+
FileUtils.mkdir_p(f)
|
|
311
|
+
f
|
|
312
|
+
end
|
|
186
313
|
end
|
|
187
314
|
|
|
188
|
-
|
|
189
|
-
options
|
|
315
|
+
def options
|
|
316
|
+
{ options: @cli_options }
|
|
190
317
|
end
|
|
191
318
|
|
|
192
|
-
|
|
193
|
-
|
|
319
|
+
def params
|
|
320
|
+
@params ||= if @cli_options.key?(:params)
|
|
321
|
+
y = YAML.load_file(@cli_options[:params])
|
|
322
|
+
c = Babeltrace2Gen::BTValueCLass.from_h(y)
|
|
323
|
+
body = Babeltrace2Gen.context(indent: 1) do
|
|
324
|
+
c.get('_usr_params', '_params')
|
|
325
|
+
end
|
|
326
|
+
{ params_declaration: c.get_struct_definition('_params'),
|
|
327
|
+
params_definition: body }
|
|
328
|
+
else
|
|
329
|
+
{ params_declaration: nil, params_definition: nil }
|
|
330
|
+
end
|
|
194
331
|
end
|
|
195
332
|
|
|
196
|
-
|
|
197
|
-
|
|
333
|
+
def trace_matcher
|
|
334
|
+
@trace_matcher ||= if @cli_options.key?(:matching)
|
|
335
|
+
data = YAML.load_file(@cli_options[:matching])
|
|
336
|
+
data[:match] = true
|
|
337
|
+
Babeltrace2Gen::BTTraceClass.from_h(nil, data)
|
|
338
|
+
else
|
|
339
|
+
Babeltrace2Gen::BTTraceClass.new(parent: nil, stream_classes: [])
|
|
340
|
+
end
|
|
198
341
|
end
|
|
199
342
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
343
|
+
def callback_types
|
|
344
|
+
@callback_types ||= begin
|
|
345
|
+
callback_types = ['generic']
|
|
346
|
+
if @cli_options.key?(:matching)
|
|
347
|
+
event_classes = trace_matcher.stream_classes.map(&:event_classes).flatten(1).filter do |em|
|
|
348
|
+
raise "Key ':set_id' required for matching events." unless em.set_id
|
|
203
349
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
350
|
+
em.register
|
|
351
|
+
end
|
|
352
|
+
callback_types += event_classes.map { |em| "matching_#{sanitize(em.set_id)}" }
|
|
353
|
+
end
|
|
207
354
|
|
|
208
|
-
|
|
209
|
-
|
|
355
|
+
static_callbacks = [StaticDispatcher.new('initialize_component',
|
|
356
|
+
[GeneratedArg.new('void **', 'usr_data_p')],
|
|
357
|
+
no_btx_handle: true),
|
|
358
|
+
StaticDispatcher.new('finalize_component',
|
|
359
|
+
[GeneratedArg.new('void *', 'usr_data')],
|
|
360
|
+
no_btx_handle: true),
|
|
361
|
+
StaticDispatcher.new('read_params',
|
|
362
|
+
[GeneratedArg.new('void *', 'usr_data'),
|
|
363
|
+
GeneratedArg.new('btx_params_t *', 'usr_params')],
|
|
364
|
+
no_btx_handle: true)]
|
|
365
|
+
# Usefull to push message
|
|
366
|
+
if %w[SOURCE FILTER].include?(@cli_options[:component_type])
|
|
367
|
+
static_callbacks += [StaticDispatcher.new('initialize_processing',
|
|
368
|
+
[GeneratedArg.new('void *', 'usr_data_p')]),
|
|
369
|
+
StaticDispatcher.new('finalize_processing',
|
|
370
|
+
[GeneratedArg.new('void *', 'usr_data')])]
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
if %w[SOURCE].include?(@cli_options[:component_type])
|
|
374
|
+
static_callbacks << StaticDispatcher.new('push_usr_messages',
|
|
375
|
+
[GeneratedArg.new('void *', 'usr_data'),
|
|
376
|
+
GeneratedArg.new('btx_source_status_t*', 'status')])
|
|
377
|
+
|
|
378
|
+
end
|
|
379
|
+
{ callback_types: callback_types,
|
|
380
|
+
static_callback_types: static_callbacks }
|
|
381
|
+
end
|
|
210
382
|
end
|
|
211
383
|
|
|
212
|
-
|
|
213
|
-
|
|
384
|
+
def downstream
|
|
385
|
+
@downstream ||= begin
|
|
386
|
+
raise 'Missing downstream model' unless @cli_options[:downstream]
|
|
387
|
+
|
|
388
|
+
y = load_models(@cli_options[:downstream])
|
|
389
|
+
t = Babeltrace2Gen::BTTraceClass.from_h(nil, y)
|
|
390
|
+
|
|
391
|
+
event_name = '_event'
|
|
392
|
+
downstream_events = t.filter_map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
393
|
+
Dispatcher.new(e, event_name, 'setter', index_stream_class, index_event_class, default_clock_class)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
body_declarator_classes = "\n" + Babeltrace2Gen.context(indent: 1) do
|
|
397
|
+
t.get_declarator(variable: '_trace_class', self_component: '_self_component')
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
{ body_declarator_classes: body_declarator_classes,
|
|
401
|
+
downstream_events: downstream_events,
|
|
402
|
+
stream_classes: t.stream_classes,
|
|
403
|
+
event_name: event_name }
|
|
404
|
+
end
|
|
214
405
|
end
|
|
215
|
-
end.parse!
|
|
216
406
|
|
|
217
|
-
|
|
407
|
+
def upstream
|
|
408
|
+
@upstream ||= begin
|
|
409
|
+
raise 'Missing upstreams models' unless @cli_options[:upstreams]
|
|
218
410
|
|
|
219
|
-
|
|
220
|
-
|
|
411
|
+
y = load_models(@cli_options[:upstreams])
|
|
412
|
+
t = Babeltrace2Gen::BTTraceClass.from_h(nil, y)
|
|
221
413
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
414
|
+
event_name = '_event'
|
|
415
|
+
dispatchers, automatic_dispatch_types = t.filter_map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
416
|
+
dispatcher = Dispatcher.new(e, event_name, 'getter', index_stream_class, index_event_class,
|
|
417
|
+
default_clock_class)
|
|
418
|
+
dispatch_type = DispatchType.new(e.name, dispatcher.args, 'generic', [dispatcher])
|
|
419
|
+
dispatcher.dispatch_types << dispatch_type
|
|
420
|
+
|
|
421
|
+
[dispatcher, dispatch_type]
|
|
422
|
+
end.transpose
|
|
423
|
+
|
|
424
|
+
context = { 'all' => dispatchers.to_set }
|
|
425
|
+
matching_dispatch_types = trace_matcher.filter_map_event_classes_with_index do |em, _, _, default_clock_class|
|
|
426
|
+
# We mutate context across iterations.
|
|
427
|
+
get_dispatch_type(em, default_clock_class, context)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
{ dispatchers: dispatchers,
|
|
431
|
+
dispatch_types: automatic_dispatch_types + matching_dispatch_types,
|
|
432
|
+
event_name: event_name }
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def get_context(list_symbols)
|
|
437
|
+
d = {}
|
|
438
|
+
d.update(options) if list_symbols.include?('options')
|
|
439
|
+
d.update(params) if list_symbols.include?('params')
|
|
440
|
+
d.update(callback_types) if list_symbols.include?('callback_types')
|
|
441
|
+
d.update(static_callback_types) if list_symbols.include?('static_callback_types')
|
|
442
|
+
d.update(downstream) if list_symbols.include?('downstream')
|
|
443
|
+
d.update(upstream) if list_symbols.include?('upstream')
|
|
444
|
+
d
|
|
236
445
|
end
|
|
237
|
-
d[:params_declaration] = c.get_struct_definition('params')
|
|
238
|
-
d[:params_definition] = body
|
|
239
|
-
else
|
|
240
|
-
d[:params_declaration] = 'char _dummy;'
|
|
241
446
|
end
|
|
242
447
|
|
|
243
|
-
|
|
244
|
-
erb_render_and_save(
|
|
448
|
+
def wrote_upstream(cb)
|
|
449
|
+
erb_render_and_save(cb.get_context(%w[upstream]), 'upstream.h', cb.folder)
|
|
450
|
+
erb_render_and_save(cb.get_context(%w[upstream]), 'upstream.c', cb.folder)
|
|
451
|
+
end
|
|
245
452
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
453
|
+
def wrote_downstream(cb)
|
|
454
|
+
erb_render_and_save(cb.get_context(%w[downstream options]), 'downstream.h', cb.folder)
|
|
455
|
+
erb_render_and_save(cb.get_context(%w[downstream options]), 'downstream.c', cb.folder)
|
|
456
|
+
end
|
|
249
457
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
458
|
+
def wrote_component(cb)
|
|
459
|
+
erb_render_and_save(cb.get_context(%w[options params callback_types]), 'component.h',
|
|
460
|
+
cb.folder)
|
|
461
|
+
erb_render_and_save(cb.get_context(%w[options params callback_types]), 'component.c',
|
|
462
|
+
cb.folder)
|
|
254
463
|
end
|
|
255
464
|
|
|
256
|
-
|
|
257
|
-
|
|
465
|
+
def wrote_main(cb)
|
|
466
|
+
erb_render_and_save(cb.get_context(%w[params options]), "#{cb.cli_options[:component_type].downcase}.c",
|
|
467
|
+
cb.base_folder, out_name: 'main.c')
|
|
468
|
+
end
|
|
258
469
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
end
|
|
263
|
-
validate_model(y)
|
|
264
|
-
t = Babeltrace2Gen::BTTraceClass.from_h(nil, y)
|
|
265
|
-
wrote_event_dispatchers(folder, t)
|
|
470
|
+
def wrote_header(cb)
|
|
471
|
+
erb_render_and_save(cb.get_context(%w[options]), 'metababel.h',
|
|
472
|
+
cb.folder, prefix: '')
|
|
266
473
|
end
|
|
474
|
+
|
|
475
|
+
# Babeltrace can be extended by plugins, which provide one or more component classes.
|
|
476
|
+
context_builder = ContextBuilder.new
|
|
477
|
+
wrote_header(context_builder)
|
|
478
|
+
wrote_main(context_builder)
|
|
479
|
+
wrote_component(context_builder)
|
|
480
|
+
wrote_downstream(context_builder) if %w[SOURCE FILTER].include?(context_builder.cli_options[:component_type])
|
|
481
|
+
wrote_upstream(context_builder) if %w[FILTER SINK].include?(context_builder.cli_options[:component_type])
|