metababel 0.0.5 → 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 -12
- 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
|
@@ -5,7 +5,7 @@ module Babeltrace2Gen
|
|
|
5
5
|
INDENT_INCREMENT = ' '.freeze
|
|
6
6
|
|
|
7
7
|
def pr(str)
|
|
8
|
-
@@output << INDENT_INCREMENT * @@indent << str << "\n"
|
|
8
|
+
@@output << (INDENT_INCREMENT * @@indent) << str << "\n"
|
|
9
9
|
end
|
|
10
10
|
module_function :pr
|
|
11
11
|
|
|
@@ -28,7 +28,7 @@ module Babeltrace2Gen
|
|
|
28
28
|
def name_sanitized
|
|
29
29
|
raise unless @name
|
|
30
30
|
|
|
31
|
-
@name.gsub(/[^0-9A-Za-z
|
|
31
|
+
@name.gsub(/[^0-9A-Za-z-]/, '_')
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module HashRefinements
|
|
2
|
+
refine Hash do
|
|
3
|
+
# Special case for hash, default value of
|
|
4
|
+
# ':default_clock_class: {}'.
|
|
5
|
+
def match?(obj)
|
|
6
|
+
self == obj
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module Babeltrace2Gen
|
|
12
|
+
using HashRefinements
|
|
13
|
+
|
|
14
|
+
module BTMatch
|
|
15
|
+
def match?(match_obj)
|
|
16
|
+
attrs_syms = self.class::BT_MATCH_ATTRS
|
|
17
|
+
attrs = attrs_syms.map do |attr_sym|
|
|
18
|
+
match_attr = match_obj.send(attr_sym)
|
|
19
|
+
# In the model, but not in the match, assuming True
|
|
20
|
+
next true if match_attr.nil?
|
|
21
|
+
|
|
22
|
+
self_attr = send(attr_sym)
|
|
23
|
+
|
|
24
|
+
# Not matching because in the match but not in the model
|
|
25
|
+
next false if self_attr.nil?
|
|
26
|
+
|
|
27
|
+
# Continue the recursion
|
|
28
|
+
self_attr.match?(match_attr)
|
|
29
|
+
end.flatten
|
|
30
|
+
return false unless attrs.all?
|
|
31
|
+
|
|
32
|
+
attrs.filter { |a| a.is_a?(Babeltrace2Gen::GeneratedArg) }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module BTMatchMembers
|
|
37
|
+
def match?(match_obj)
|
|
38
|
+
# Object here have only one symbol, who cannot be nil
|
|
39
|
+
attr_sym = self.class::BT_MATCH_ATTRS[0]
|
|
40
|
+
|
|
41
|
+
self_members = send(attr_sym)
|
|
42
|
+
match_members = match_obj.send(attr_sym)
|
|
43
|
+
|
|
44
|
+
# Do the product of menbers to get the matching one
|
|
45
|
+
# We keep only the matching one.
|
|
46
|
+
args_matched = match_members.filter_map do |match_obj|
|
|
47
|
+
# Find all machings members
|
|
48
|
+
matches = self_members.filter { |member| member.match?(match_obj) }
|
|
49
|
+
# Check that one match_obj only match zero or one member.
|
|
50
|
+
unless matches.length < 2
|
|
51
|
+
raise "Match expression '#{match_obj.name}' must match only one member, '#{matches.length}' matched #{matches.map(&:name)}."
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# If not argument matched, then nil; otherwise, return the matched member.
|
|
55
|
+
matches.pop.bt_get_variable unless matches.empty?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# We didn't match anything
|
|
59
|
+
if args_matched.empty? || args_matched.uniq.length != match_members.length
|
|
60
|
+
false
|
|
61
|
+
# Same arguments in the model have been matched twice
|
|
62
|
+
elsif args_matched.uniq.length != args_matched.length
|
|
63
|
+
raise "Members '#{args_matched.uniq.map(&:name)}' matched multiple times in '#{match_members.map(&:name)}'. "
|
|
64
|
+
# Not all match mernbers found a matchings
|
|
65
|
+
elsif args_matched.uniq.length != match_members.length
|
|
66
|
+
false
|
|
67
|
+
else
|
|
68
|
+
args_matched
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require_relative 'bt2_generator_utils'
|
|
2
|
+
require_relative 'bt2_matching_utils'
|
|
2
3
|
|
|
3
4
|
module HashRefinements
|
|
4
5
|
refine Hash do
|
|
@@ -28,6 +29,10 @@ module Babeltrace2Gen
|
|
|
28
29
|
module BTLocator
|
|
29
30
|
attr_reader :parent, :variable
|
|
30
31
|
|
|
32
|
+
def rec_trace_class
|
|
33
|
+
is_a?(Babeltrace2Gen::BTTraceClass) ? self : @parent.rec_trace_class
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
def rec_stream_class
|
|
32
37
|
is_a?(Babeltrace2Gen::BTStreamClass) ? self : @parent.rec_stream_class
|
|
33
38
|
end
|
|
@@ -70,15 +75,21 @@ module Babeltrace2Gen
|
|
|
70
75
|
include BTLocator
|
|
71
76
|
include BTPrinter
|
|
72
77
|
include BTUtils
|
|
78
|
+
include BTMatch
|
|
73
79
|
extend BTFromH
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
BT_MATCH_ATTRS = [:environment]
|
|
82
|
+
|
|
83
|
+
attr_reader :stream_classes, :environment, :assigns_automatic_stream_class_id, :match
|
|
76
84
|
|
|
77
|
-
def initialize(parent:, stream_classes:, assigns_automatic_stream_class_id: nil)
|
|
85
|
+
def initialize(parent:, stream_classes:, environment: nil, assigns_automatic_stream_class_id: nil, match: false)
|
|
78
86
|
raise if parent
|
|
79
87
|
|
|
88
|
+
# match indicate if this model will be used to match another.
|
|
89
|
+
@match = match
|
|
80
90
|
@parent = nil
|
|
81
91
|
@assigns_automatic_stream_class_id = assigns_automatic_stream_class_id
|
|
92
|
+
@environment = BTEnvironmentClass.from_h(self, environment) if environment
|
|
82
93
|
@stream_classes = stream_classes.collect.with_index do |m, i|
|
|
83
94
|
if m[:id].nil? != (@assigns_automatic_stream_class_id.nil? || @assigns_automatic_stream_class_id)
|
|
84
95
|
raise "Incoherence between trace::assigns_automatic_stream_class_id and stream_class[#{i}]::id"
|
|
@@ -89,6 +100,8 @@ module Babeltrace2Gen
|
|
|
89
100
|
end
|
|
90
101
|
|
|
91
102
|
def get_declarator(variable:, self_component:)
|
|
103
|
+
raise NotImplementedError, "':environment' keyword not supported in downstream model" if environment
|
|
104
|
+
|
|
92
105
|
pr "#{variable} = bt_trace_class_create(#{self_component});"
|
|
93
106
|
bt_set_conditionally(@assigns_automatic_stream_class_id) do |v|
|
|
94
107
|
pr "bt_trace_class_set_assigns_automatic_stream_class_id(#{variable}, #{v});"
|
|
@@ -108,7 +121,12 @@ module Babeltrace2Gen
|
|
|
108
121
|
include BTUtils
|
|
109
122
|
include BTPrinter
|
|
110
123
|
include BTLocator
|
|
124
|
+
include BTMatch
|
|
111
125
|
extend BTFromH
|
|
126
|
+
|
|
127
|
+
BT_MATCH_ATTRS = %i[parent name packet_context_field_class event_common_context_field_class
|
|
128
|
+
default_clock_class]
|
|
129
|
+
|
|
112
130
|
attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :default_clock_class,
|
|
113
131
|
:id, :name, :get_getter
|
|
114
132
|
|
|
@@ -121,8 +139,6 @@ module Babeltrace2Gen
|
|
|
121
139
|
@parent = parent
|
|
122
140
|
@name = name
|
|
123
141
|
|
|
124
|
-
raise 'Two packet_context' if packet_context_field_class && packet_context
|
|
125
|
-
|
|
126
142
|
# Should put assert to check for struct
|
|
127
143
|
@packet_context_field_class = BTFieldClass.from_h(self, packet_context_field_class) if packet_context_field_class
|
|
128
144
|
|
|
@@ -135,7 +151,7 @@ module Babeltrace2Gen
|
|
|
135
151
|
@assigns_automatic_event_class_id = assigns_automatic_event_class_id
|
|
136
152
|
@event_classes = event_classes.collect do |ec|
|
|
137
153
|
if ec[:id].nil? != (@assigns_automatic_event_class_id.nil? || @assigns_automatic_event_class_id.nil)
|
|
138
|
-
raise '
|
|
154
|
+
raise 'Incorrect id scheme'
|
|
139
155
|
end
|
|
140
156
|
|
|
141
157
|
BTEventClass.from_h(self, ec)
|
|
@@ -164,6 +180,10 @@ module Babeltrace2Gen
|
|
|
164
180
|
end
|
|
165
181
|
|
|
166
182
|
if @packet_context_field_class
|
|
183
|
+
# Support for packets required for packet_context_field_class
|
|
184
|
+
# We do not support create_packet neither packet_beginning_default_clock_snapshot (BT_FALSE) nor packet_end_default_clock_snapshot (BT_FALSE)
|
|
185
|
+
pr "bt_stream_class_set_supports_packets(#{variable}, BT_TRUE, BT_FALSE, BT_FALSE);"
|
|
186
|
+
|
|
167
187
|
var_pc = "#{variable}_pc_fc"
|
|
168
188
|
scope do
|
|
169
189
|
pr "bt_field_class *#{var_pc};"
|
|
@@ -182,7 +202,7 @@ module Babeltrace2Gen
|
|
|
182
202
|
pr "bt_field_class_put_ref(#{var_ecc});"
|
|
183
203
|
end
|
|
184
204
|
end
|
|
185
|
-
# Need to do is
|
|
205
|
+
# Need to do is after common_context because it can refer members to those
|
|
186
206
|
bt_set_conditionally(@assigns_automatic_event_class_id) do |v|
|
|
187
207
|
pr "bt_stream_class_set_assigns_automatic_event_class_id(#{variable}, #{v});"
|
|
188
208
|
end
|
|
@@ -203,7 +223,7 @@ module Babeltrace2Gen
|
|
|
203
223
|
pr "bt_stream_class_put_ref(#{variable});"
|
|
204
224
|
end
|
|
205
225
|
|
|
206
|
-
# The getters code generated from event_common_context_field_class
|
|
226
|
+
# The getters code generated from event_common_context_field_class does not include
|
|
207
227
|
# the event variable name used by the getters. As we do not know the variable
|
|
208
228
|
# name that should be generated, we can not put it directly in the template,
|
|
209
229
|
# since, if the code generation generates another name we must update the
|
|
@@ -222,12 +242,24 @@ module Babeltrace2Gen
|
|
|
222
242
|
class BTEventClass
|
|
223
243
|
include BTPrinter
|
|
224
244
|
include BTLocator
|
|
245
|
+
include BTMatch
|
|
225
246
|
extend BTFromH
|
|
226
|
-
attr_reader :name, :specific_context_field_class, :payload_field_class
|
|
227
247
|
|
|
228
|
-
|
|
248
|
+
BT_MATCH_ATTRS = %i[parent name specific_context_field_class payload_field_class]
|
|
249
|
+
|
|
250
|
+
attr_reader :name, :specific_context_field_class, :payload_field_class, :set_id, :domain, :register
|
|
251
|
+
|
|
252
|
+
def initialize(parent:, name: nil, specific_context_field_class: nil, payload_field_class: nil, id: nil,
|
|
253
|
+
set_id: nil, domain: nil, register: true)
|
|
254
|
+
|
|
255
|
+
@set_id = set_id
|
|
256
|
+
@domain = domain
|
|
257
|
+
@register = register
|
|
258
|
+
|
|
229
259
|
@parent = parent
|
|
230
260
|
@name = name
|
|
261
|
+
raise 'Name is mandatory for BTEventClass' if name.nil? && !rec_trace_class.match
|
|
262
|
+
|
|
231
263
|
if specific_context_field_class
|
|
232
264
|
@specific_context_field_class = BTFieldClass.from_h(self,
|
|
233
265
|
specific_context_field_class)
|
|
@@ -238,7 +270,7 @@ module Babeltrace2Gen
|
|
|
238
270
|
end
|
|
239
271
|
|
|
240
272
|
def get_declarator(trace_class:, variable:, stream_class:)
|
|
241
|
-
# Store the variable name for
|
|
273
|
+
# Store the variable name for introspection purposes (PATH)
|
|
242
274
|
@variable = variable
|
|
243
275
|
if @id
|
|
244
276
|
pr "#{variable} = bt_event_class_create_with_id(#{stream_class}, #{@id});"
|
|
@@ -296,6 +328,15 @@ module Babeltrace2Gen
|
|
|
296
328
|
end
|
|
297
329
|
|
|
298
330
|
def get_getter(event:, arg_variables:)
|
|
331
|
+
if rec_trace_class.environment
|
|
332
|
+
trace = 'trace'
|
|
333
|
+
scope do
|
|
334
|
+
pr "const bt_stream *stream = bt_event_borrow_stream_const(#{event});"
|
|
335
|
+
pr "const bt_trace *#{trace} = bt_stream_borrow_trace_const(stream);"
|
|
336
|
+
rec_trace_class.environment.get_getter(trace: trace, arg_variables: arg_variables)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
299
340
|
if rec_stream_class.event_common_context_field_class
|
|
300
341
|
field = "#{event}_cc_f"
|
|
301
342
|
scope do
|
|
@@ -325,9 +366,12 @@ module Babeltrace2Gen
|
|
|
325
366
|
class BTFieldClass
|
|
326
367
|
include BTLocator
|
|
327
368
|
include BTPrinter
|
|
369
|
+
include BTMatch
|
|
328
370
|
using HashRefinements
|
|
329
371
|
|
|
330
|
-
|
|
372
|
+
BT_MATCH_ATTRS = %i[type cast_type cast_type_is_struct]
|
|
373
|
+
|
|
374
|
+
attr_accessor :cast_type_is_struct, :cast_type, :type
|
|
331
375
|
|
|
332
376
|
def initialize(parent:)
|
|
333
377
|
@parent = parent
|
|
@@ -335,7 +379,10 @@ module Babeltrace2Gen
|
|
|
335
379
|
|
|
336
380
|
def self.from_h(parent, model)
|
|
337
381
|
key = model.delete(:type)
|
|
338
|
-
|
|
382
|
+
# /!\ Recursion
|
|
383
|
+
is_match_model = parent.rec_trace_class.match
|
|
384
|
+
|
|
385
|
+
raise "No type in #{model}" unless key || is_match_model
|
|
339
386
|
|
|
340
387
|
h = {
|
|
341
388
|
'bool' => BTFieldClass::Bool,
|
|
@@ -354,14 +401,22 @@ module Babeltrace2Gen
|
|
|
354
401
|
'option_with_selector_field_bool' => BTFieldClass::Option::WithSelectorField::Bool,
|
|
355
402
|
'option_with_selector_field_unsigned' => BTFieldClass::Option::WithSelectorField::IntegerUnsigned,
|
|
356
403
|
'option_with_selector_field_signed' => BTFieldClass::Option::WithSelectorField::IntegerSigned,
|
|
357
|
-
'variant' => BTFieldClass::Variant
|
|
404
|
+
'variant' => BTFieldClass::Variant,
|
|
358
405
|
}.freeze
|
|
359
406
|
|
|
360
|
-
raise "No #{key} in FIELD_CLASS_NAME_MAP" unless h.include?(key)
|
|
407
|
+
raise "No #{key} in FIELD_CLASS_NAME_MAP" unless h.include?(key) || is_match_model
|
|
361
408
|
|
|
362
409
|
cast_type = model.delete(:cast_type)
|
|
363
|
-
|
|
410
|
+
cast_type_is_struct = model.delete(:cast_type_is_struct)
|
|
411
|
+
|
|
412
|
+
fc = h.include?(key) ? h[key].from_h(parent, model) : BTFieldClass::Default.new(parent: parent)
|
|
413
|
+
|
|
414
|
+
# Since key (:type) can be a string or a regex, we store
|
|
415
|
+
# the type into the field to apply string.match?(regex)
|
|
416
|
+
# in place of comparing field objects.
|
|
417
|
+
fc.type = key
|
|
364
418
|
fc.cast_type = cast_type if cast_type
|
|
419
|
+
fc.cast_type_is_struct = cast_type_is_struct if cast_type_is_struct
|
|
365
420
|
fc
|
|
366
421
|
end
|
|
367
422
|
|
|
@@ -395,11 +450,15 @@ module Babeltrace2Gen
|
|
|
395
450
|
def get_setter(field:, arg_variables:)
|
|
396
451
|
bt_func_get = self.class.instance_variable_get(:@bt_func) % 'set'
|
|
397
452
|
variable = bt_get_variable(arg_variables).name
|
|
398
|
-
|
|
399
|
-
pr "#{bt_func_get}(#{field}, #{variable});"
|
|
453
|
+
# We always explicitly cast to the proper bebeltrace type when sending messsages.
|
|
454
|
+
pr "#{bt_func_get}(#{field}, (#{self.class.instance_variable_get(:@bt_type)})#{variable});"
|
|
400
455
|
end
|
|
401
456
|
end
|
|
402
457
|
|
|
458
|
+
class BTFieldClass::Default < BTFieldClass
|
|
459
|
+
extend BTFromH
|
|
460
|
+
end
|
|
461
|
+
|
|
403
462
|
class BTFieldClass::Bool < BTFieldClass
|
|
404
463
|
extend BTFromH
|
|
405
464
|
|
|
@@ -525,6 +584,7 @@ module Babeltrace2Gen
|
|
|
525
584
|
|
|
526
585
|
class BTFieldClass::String < BTFieldClass
|
|
527
586
|
extend BTFromH
|
|
587
|
+
include BTUtils
|
|
528
588
|
|
|
529
589
|
@bt_type = 'const char*'
|
|
530
590
|
@bt_func = 'bt_field_string_%s_value'
|
|
@@ -532,6 +592,33 @@ module Babeltrace2Gen
|
|
|
532
592
|
def get_declarator(trace_class:, variable:)
|
|
533
593
|
pr "#{variable} = bt_field_class_string_create(#{trace_class});"
|
|
534
594
|
end
|
|
595
|
+
|
|
596
|
+
def get_getter(field:, arg_variables:)
|
|
597
|
+
return super(field: field, arg_variables: arg_variables) unless @cast_type_is_struct
|
|
598
|
+
|
|
599
|
+
bt_func_get = self.class.instance_variable_get(:@bt_func) % 'get'
|
|
600
|
+
variable = bt_get_variable(arg_variables).name
|
|
601
|
+
|
|
602
|
+
pr "// Dump string data to the struct."
|
|
603
|
+
pr "memcpy(&#{variable}, #{bt_func_get}(#{field}), sizeof(#{variable}));"
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
def get_setter(field:, arg_variables:)
|
|
607
|
+
return super(field: field, arg_variables: arg_variables) unless @cast_type_is_struct
|
|
608
|
+
|
|
609
|
+
variable = bt_get_variable(arg_variables).name
|
|
610
|
+
|
|
611
|
+
pr "// Dump data to a temporal string."
|
|
612
|
+
pr "char *#{field}_temp = malloc(sizeof(#{variable}));"
|
|
613
|
+
pr "assert(#{field}_temp != NULL && \"Out of memory\");"
|
|
614
|
+
pr "memcpy(#{field}_temp, &#{variable}, sizeof(#{variable}));"
|
|
615
|
+
pr ""
|
|
616
|
+
pr "// Set string field with dumped data."
|
|
617
|
+
pr "bt_field_string_clear(#{field});"
|
|
618
|
+
pr "bt_field_string_append_status #{field}_status = bt_field_string_append_with_length(#{field}, #{field}_temp, sizeof(#{variable}));"
|
|
619
|
+
pr "assert(#{field}_status == BT_FIELD_STRING_APPEND_STATUS_OK && \"Out of memory\");"
|
|
620
|
+
pr "free(#{field}_temp);"
|
|
621
|
+
end
|
|
535
622
|
end
|
|
536
623
|
|
|
537
624
|
class BTFieldClass::Array < BTFieldClass
|
|
@@ -637,21 +724,32 @@ module Babeltrace2Gen
|
|
|
637
724
|
end
|
|
638
725
|
|
|
639
726
|
class BTMemberClass
|
|
727
|
+
include BTMatch
|
|
640
728
|
include BTLocator
|
|
729
|
+
|
|
730
|
+
BT_MATCH_ATTRS = %i[name field_class]
|
|
731
|
+
|
|
641
732
|
attr_reader :parent, :name, :field_class
|
|
642
733
|
|
|
643
|
-
def initialize(parent:,
|
|
734
|
+
def initialize(parent:, field_class:, name: nil)
|
|
644
735
|
@parent = parent
|
|
645
|
-
@name = name
|
|
736
|
+
@name = name # Name can be nil in the matching callbacks
|
|
646
737
|
@field_class = BTFieldClass.from_h(self, field_class)
|
|
647
738
|
end
|
|
739
|
+
|
|
740
|
+
def bt_get_variable()
|
|
741
|
+
@field_class.bt_get_variable({})
|
|
742
|
+
end
|
|
648
743
|
end
|
|
649
744
|
|
|
650
745
|
class BTFieldClass::Structure < BTFieldClass
|
|
746
|
+
include BTMatchMembers
|
|
651
747
|
extend BTFromH
|
|
652
748
|
|
|
653
749
|
attr_reader :members
|
|
654
750
|
|
|
751
|
+
BT_MATCH_ATTRS = [:members]
|
|
752
|
+
|
|
655
753
|
def initialize(parent:, members: [])
|
|
656
754
|
@parent = parent
|
|
657
755
|
@members = members.collect { |m| BTMemberClass.new(parent: self, **m) }
|
|
@@ -803,4 +901,87 @@ module Babeltrace2Gen
|
|
|
803
901
|
end
|
|
804
902
|
end
|
|
805
903
|
end
|
|
904
|
+
|
|
905
|
+
class BTEnvironmentClass
|
|
906
|
+
include BTPrinter
|
|
907
|
+
include BTLocator
|
|
908
|
+
include BTMatchMembers
|
|
909
|
+
extend BTFromH
|
|
910
|
+
attr_reader :parent, :entries
|
|
911
|
+
|
|
912
|
+
BT_MATCH_ATTRS = [:entries]
|
|
913
|
+
|
|
914
|
+
def initialize(parent:, entries: [])
|
|
915
|
+
@parent = parent
|
|
916
|
+
@entries = entries.map { |entry| BTEntryClass.from_h(self, entry) }
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
def get_getter(trace:, arg_variables:)
|
|
920
|
+
scope do
|
|
921
|
+
@entries.each do |entry|
|
|
922
|
+
entry.get_getter(trace: trace, arg_variables: arg_variables)
|
|
923
|
+
end
|
|
924
|
+
end
|
|
925
|
+
end
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
class BTEntryClass
|
|
929
|
+
include BTPrinter
|
|
930
|
+
include BTMatch
|
|
931
|
+
using HashRefinements
|
|
932
|
+
|
|
933
|
+
BT_MATCH_ATTRS = %i[name type]
|
|
934
|
+
|
|
935
|
+
attr_accessor :name, :type
|
|
936
|
+
|
|
937
|
+
def initialize(parent:, name:, type:)
|
|
938
|
+
@parent = parent
|
|
939
|
+
@name = name
|
|
940
|
+
@type = type
|
|
941
|
+
end
|
|
942
|
+
|
|
943
|
+
def self.from_h(parent, model)
|
|
944
|
+
type = model.fetch(:type, nil)
|
|
945
|
+
is_match_model = parent.rec_trace_class.match
|
|
946
|
+
|
|
947
|
+
raise "No type in #{model}" unless type || is_match_model
|
|
948
|
+
|
|
949
|
+
h = { 'string' => BTEntryClass::String,
|
|
950
|
+
'integer_signed' => BTEntryClass::IntegerSigned }.freeze
|
|
951
|
+
|
|
952
|
+
raise "Type #{type} not supported" unless h.include?(type) || is_match_model
|
|
953
|
+
|
|
954
|
+
h.include?(type) ? h[type].from_h(parent, model) : BTEntryClass::Default.from_h(parent, model)
|
|
955
|
+
end
|
|
956
|
+
|
|
957
|
+
def get_getter(trace:, arg_variables:)
|
|
958
|
+
var_name = @name
|
|
959
|
+
arg_variables.fetch_append('outputs', bt_get_variable)
|
|
960
|
+
bt_func_get = self.class.instance_variable_get(:@bt_func)
|
|
961
|
+
pr "const bt_value *#{var_name}_value = bt_trace_borrow_environment_entry_value_by_name_const(#{trace}, \"#{var_name}\");"
|
|
962
|
+
pr "#{var_name} = #{bt_func_get}(#{var_name}_value);"
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
def bt_get_variable()
|
|
966
|
+
GeneratedArg.new(self.class.instance_variable_get(:@bt_type), @name)
|
|
967
|
+
end
|
|
968
|
+
end
|
|
969
|
+
|
|
970
|
+
class BTEntryClass::Default < BTEntryClass
|
|
971
|
+
extend BTFromH
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
class BTEntryClass::String < BTEntryClass
|
|
975
|
+
extend BTFromH
|
|
976
|
+
|
|
977
|
+
@bt_type = 'const char*'
|
|
978
|
+
@bt_func = 'bt_value_string_get'
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
class BTEntryClass::IntegerSigned < BTEntryClass
|
|
982
|
+
extend BTFromH
|
|
983
|
+
|
|
984
|
+
@bt_type = 'int64_t'
|
|
985
|
+
@bt_func = 'bt_value_integer_signed_get'
|
|
986
|
+
end
|
|
806
987
|
end
|
|
@@ -92,7 +92,7 @@ module Babeltrace2Gen
|
|
|
92
92
|
|
|
93
93
|
def initialize(name, usr_default_value)
|
|
94
94
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
95
|
-
if !usr_default_value.nil?
|
|
95
|
+
if !usr_default_value.nil? && !%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
|
|
|
@@ -109,7 +109,7 @@ module Babeltrace2Gen
|
|
|
109
109
|
def initialize(name, usr_default_value)
|
|
110
110
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
111
111
|
# Every object that can be converted to string is being supported.
|
|
112
|
-
if !usr_default_value.nil?
|
|
112
|
+
if !usr_default_value.nil? && !usr_default_value.respond_to?(:to_s)
|
|
113
113
|
raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} but provided '#{usr_default_value}'."
|
|
114
114
|
end
|
|
115
115
|
|
|
@@ -125,7 +125,7 @@ module Babeltrace2Gen
|
|
|
125
125
|
|
|
126
126
|
def initialize(name, usr_default_value)
|
|
127
127
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
128
|
-
if !usr_default_value.nil?
|
|
128
|
+
if !usr_default_value.nil? && (!usr_default_value.is_a?(Integer) || !usr_default_value.between?(0, (2**64) - 1))
|
|
129
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}'."
|
|
130
130
|
end
|
|
131
131
|
|
data/lib/metababel/version.rb
CHANGED
data/lib/metababel.rb
CHANGED
data/template/component.c.erb
CHANGED
|
@@ -1,68 +1,34 @@
|
|
|
1
|
-
#include "utarray.h"
|
|
2
|
-
#include "uthash.h"
|
|
3
|
-
#include <assert.h>
|
|
4
1
|
#include <babeltrace2/babeltrace.h>
|
|
5
2
|
#include <metababel/btx_component.h>
|
|
6
3
|
// stdio needed because `params_definition` contain fprintf
|
|
4
|
+
<% if params_definition %>
|
|
7
5
|
#include <stdio.h>
|
|
6
|
+
<% end %>
|
|
8
7
|
|
|
9
8
|
void btx_populate_params(common_data_t *common_data) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
(void)usr_params;
|
|
9
|
+
<% if params_definition %>
|
|
10
|
+
const bt_value *_params = common_data->params;
|
|
11
|
+
btx_params_t *_usr_params = common_data->btx_params;
|
|
14
12
|
<%= params_definition %>
|
|
13
|
+
<% end %>
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
<%
|
|
18
|
-
|
|
19
|
-
typedef void btx_dispatch_<%= e.name_sanitized %>_f(
|
|
20
|
-
UT_array *callbacks, common_data_t *common_data,
|
|
21
|
-
<%= e.args.map{ |s| s.type }.join(", ") %>);
|
|
22
|
-
|
|
23
|
-
static void btx_dispatch_<%= e.name_sanitized %>(
|
|
24
|
-
UT_array *callbacks, common_data_t *common_data,
|
|
25
|
-
<%= e.args.map{ |s| "#{s.type} #{s.name}" }.join(", ") %>) {
|
|
26
|
-
|
|
27
|
-
// Call all the callbacks who where registered
|
|
28
|
-
// Their type are declared in 'upstream.h'
|
|
29
|
-
<%= e.name_sanitized %>_callback_f **p = NULL;
|
|
30
|
-
while ((p = utarray_next(callbacks, p))) {
|
|
31
|
-
(*p)((void *)common_data, <%= e.args.map{ |s| s.name }.join(", ") %>);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
16
|
+
<% static_callback_types.each do |e| %>
|
|
34
17
|
|
|
35
18
|
void btx_register_callbacks_<%= e.name_sanitized %>(
|
|
36
|
-
void *btx_handle, <%= e.name_sanitized %>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
name_to_dispatcher_t **name_to_dispatcher =
|
|
40
|
-
&((common_data_t *)btx_handle)->name_to_dispatcher;
|
|
41
|
-
HASH_FIND_STR(*name_to_dispatcher, "<%= e.name %>", s);
|
|
42
|
-
if (!s) {
|
|
43
|
-
// We didn't find the dispatcher, so we need to:
|
|
44
|
-
// 1. Create it
|
|
45
|
-
s = (name_to_dispatcher_t *)malloc(sizeof(name_to_dispatcher_t));
|
|
46
|
-
s->name = "<%= e.name %>";
|
|
47
|
-
s->dispatcher = (void *)&btx_dispatch_<%= e.name_sanitized %>;
|
|
48
|
-
utarray_new(s->callbacks, &ut_ptr_icd);
|
|
49
|
-
// 2. Register it
|
|
50
|
-
HASH_ADD_KEYPTR(hh, *name_to_dispatcher, s->name, strlen(s->name), s);
|
|
51
|
-
// 3. Add the callbacks to the array
|
|
52
|
-
utarray_push_back(s->callbacks, &callback);
|
|
53
|
-
} else {
|
|
54
|
-
assert(false && "Only one callbacks for <%= e.name_sanitized %>");
|
|
55
|
-
}
|
|
19
|
+
void *btx_handle, <%= e.name_sanitized %>_static_callback_f *callback) {
|
|
20
|
+
((common_data_t *)btx_handle)->static_callbacks-><%= e.name_sanitized %> =
|
|
21
|
+
callback;
|
|
56
22
|
}
|
|
57
23
|
|
|
58
24
|
void btx_call_callbacks_<%= e.name_sanitized %>(
|
|
59
25
|
common_data_t *common_data,
|
|
60
26
|
<%= e.args.map{ |s| "#{s.type} #{s.name}" }.join(", ") %>) {
|
|
61
|
-
name_to_dispatcher_t *s = NULL;
|
|
62
|
-
HASH_FIND_STR(common_data->name_to_dispatcher, "<%= e.name %>", s);
|
|
63
27
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
28
|
+
<%= e.name_sanitized %>_static_callback_f *p =
|
|
29
|
+
common_data->static_callbacks-><%= e.name_sanitized %>;
|
|
30
|
+
if (p)
|
|
31
|
+
p( <%= "(void *)common_data," unless e.no_btx_handle %>
|
|
32
|
+
<%= e.args.map{ |s| s.name }.join(", ") %>);
|
|
67
33
|
}
|
|
68
34
|
<% end %>
|