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.
@@ -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
- attr_reader :stream_classes, :assigns_automatic_stream_class_id
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 'Incorect id scheme'
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 afert packet an devent_common_context because it can refer members to those
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 do not include
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
- def initialize(parent:, name: nil, specific_context_field_class: nil, payload_field_class: nil, id: nil)
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 instrospection purpose (PATH)
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
- attr_accessor :cast_type
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
- raise "No type in #{model}" unless key
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
- fc = h[key].from_h(parent, model)
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
- cast_func = @cast_type ? "(#{self.class.instance_variable_get(:@bt_type)})" : ''
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:, name:, field_class:)
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? and !%w[BT_TRUE BT_FALSE].include? usr_default_value
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? and !usr_default_value.respond_to?(:to_s)
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? and (!usr_default_value.is_a? Integer or !usr_default_value.between?(0, 2**64 - 1))
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
 
@@ -1,3 +1,3 @@
1
1
  module Metababel
2
- VERSION = '0.0.5'
2
+ VERSION = '1.0.1'
3
3
  end
data/lib/metababel.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  require 'metababel/bt2_generator_utils'
2
- require 'metababel/bt2_stream_classes_generator'
2
+ require 'metababel/bt2_trace_class_generator'
3
3
  require 'metababel/bt2_values_generator'
4
4
  require 'metababel/version'
@@ -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
- const bt_value *params = common_data->params;
11
- btx_params_t *usr_params = common_data->btx_params;
12
- (void)params;
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
- <% component_dispatchers.each do |e| %>
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 %>_callback_f *callback) {
37
- // Look-up our dispatcher
38
- name_to_dispatcher_t *s = NULL;
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
- if (s)
65
- (*((btx_dispatch_<%= e.name_sanitized %>_f(*))(s->dispatcher)))(
66
- s->callbacks, common_data, <%= e.args.map{ |s| s.name }.join(", ") %>);
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 %>