metababel 0.0.0

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.
@@ -0,0 +1,716 @@
1
+ require_relative 'bt2_generator_utils'
2
+
3
+ module Babeltrace2Gen
4
+ class GeneratedArg < Struct.new(:type, :name)
5
+ end
6
+
7
+ module BTFromH
8
+ def from_h(parent, model)
9
+ new(parent: parent, **model)
10
+ end
11
+ end
12
+
13
+ module BTUtils
14
+ def bt_set_conditionally(guard)
15
+ yield guard ? 'BT_TRUE' : 'BT_FALSE' unless guard.nil?
16
+ end
17
+ end
18
+
19
+ module BTLocator
20
+ attr_reader :parent, :variable
21
+
22
+ def rec_stream_class
23
+ is_a?(Babeltrace2Gen::BTStreamClass) ? self : @parent.rec_stream_class
24
+ end
25
+
26
+ def rec_event_class
27
+ is_a?(Babeltrace2Gen::BTEventClass) ? self : @parent.rec_event_class
28
+ end
29
+
30
+ def rec_menber_class
31
+ is_a?(Babeltrace2Gen::BTMemberClass) ? self : @parent.rec_menber_class
32
+ end
33
+
34
+ def find_field_class_path(path, variable)
35
+ path.scan(/\["(\w+)"\]|\[(\d+)\]/).each do |m|
36
+ # String
37
+ if m.first
38
+ pr "#{variable} = bt_field_class_structure_borrow_member_by_name(#{variable}, \"#{m.first}\");"
39
+ else
40
+ pr "#{variable} = bt_field_class_structure_borrow_member_by_index(#{variable}, #{m.last});"
41
+ end
42
+ end
43
+ end
44
+
45
+ def find_field_class(path, variable)
46
+ m = path.match(/\A(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)(.*)/)
47
+ case m[1]
48
+ when 'PACKET_CONTEXT'
49
+ pr "#{variable} = #{rec_stream_class.packet_context_field_class.variable};"
50
+ when 'EVENT_COMMON_CONTEXT'
51
+ pr "#{variable} = #{rec_stream_class.event_common_context_field_class.variable};"
52
+ when 'EVENT_SPECIFIC_CONTEXT'
53
+ pr "#{variable} = #{rec_event_class.specific_context_field_class.varible};"
54
+ when 'EVENT_PAYLOAD'
55
+ pr "#{variable} = #{rec_event_class.payload_field_class.variable};"
56
+ else
57
+ raise "invalid path #{path}"
58
+ end
59
+ find_field_class_path(m[2], variable)
60
+ end
61
+ end
62
+
63
+ # ______ _____ _____ _
64
+ # | ___ \_ _| / __ \ |
65
+ # | |_/ / | | | / \/ | __ _ ___ ___ ___ ___
66
+ # | ___ \ | | | | | |/ _` / __/ __|/ _ \/ __|
67
+ # | |_/ / | | | \__/\ | (_| \__ \__ \ __/\__ \
68
+ # \____/ \_/ \____/_|\__,_|___/___/\___||___/
69
+ #
70
+ class BTTraceClass
71
+ include BTLocator
72
+ include BTPrinter
73
+ include BTUtils
74
+ extend BTFromH
75
+
76
+ attr_reader :stream_classes, :assigns_automatic_stream_class_id
77
+
78
+ def initialize(parent:, stream_classes:, assigns_automatic_stream_class_id: nil)
79
+ raise if parent
80
+
81
+ @parent = nil
82
+ @assigns_automatic_stream_class_id = assigns_automatic_stream_class_id
83
+ @stream_classes = stream_classes.collect.with_index do |m, i|
84
+ if m[:id].nil? != (@assigns_automatic_stream_class_id.nil? || @assigns_automatic_stream_class_id)
85
+ raise "Incoherence between trace::assigns_automatic_stream_class_id and stream_class[#{i}]::id"
86
+ end
87
+
88
+ BTStreamClass.from_h(self, m)
89
+ end
90
+ end
91
+
92
+ def get_declarator(variable:)
93
+ bt_set_conditionally(@assigns_automatic_stream_class_id) do |v|
94
+ pr "bt_trace_class_set_assigns_automatic_stream_class_id(#{variable}, #{v});"
95
+ end
96
+
97
+ @stream_classes.each_with_index do |m, i|
98
+ stream_class_name = "#{variable}_sc_#{i}"
99
+ scope do
100
+ pr "bt_stream_class *#{stream_class_name};"
101
+ m.get_declarator(trace_class: variable, variable: stream_class_name)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ class BTStreamClass
108
+ include BTUtils
109
+ include BTPrinter
110
+ include BTLocator
111
+ extend BTFromH
112
+ attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :id, :name
113
+
114
+ def initialize(parent:, name: nil, packet_context_field_class: nil, event_common_context_field_class: nil,
115
+ event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil)
116
+ @parent = parent
117
+ @name = name
118
+
119
+ raise 'Two packet_context' if packet_context_field_class && packet_context
120
+
121
+ # Should put assert to check for struct
122
+ @packet_context_field_class = BTFieldClass.from_h(self, packet_context_field_class) if packet_context_field_class
123
+
124
+ # Should put assert to check for struct
125
+ if event_common_context_field_class
126
+ @event_common_context_field_class = BTFieldClass.from_h(self,
127
+ event_common_context_field_class)
128
+ end
129
+
130
+ @assigns_automatic_event_class_id = assigns_automatic_event_class_id
131
+ @event_classes = event_classes.collect do |ec|
132
+ if ec[:id].nil? != (@assigns_automatic_event_class_id.nil? || @assigns_automatic_event_class_id.nil)
133
+ raise 'Incorect id scheme'
134
+ end
135
+
136
+ BTEventClass.from_h(self, ec)
137
+ end
138
+ @assigns_automatic_stream_id = assigns_automatic_stream_id
139
+ @id = id
140
+ end
141
+
142
+ def get_declarator(trace_class:, variable:)
143
+ if @id
144
+ pr "#{variable} = bt_stream_class_create_with_id(#{trace_class}, #{@id});"
145
+ else
146
+ pr "#{variable} = bt_stream_class_create(#{trace_class});"
147
+ end
148
+ pr "bt_stream_class_set_name(#{variable}, \"#{name}\");" if @name
149
+
150
+ if @packet_context_field_class
151
+ var_pc = "#{variable}_pc_fc"
152
+ scope do
153
+ pr "bt_field_class *#{var_pc};"
154
+ @packet_context_field_class.get_declarator(trace_class: trace_class, variable: var_pc)
155
+ pr "bt_stream_class_set_packet_context_field_class(#{variable}, #{var_pc});"
156
+ end
157
+ end
158
+
159
+ if @event_common_context_field_class
160
+ var_ecc = "#{variable}_ecc_fc"
161
+ scope do
162
+ pr "bt_field_class *#{var_ecc};"
163
+ @event_common_context_field_class.get_declarator(trace_class: trace_class, variable: var_ecc)
164
+ pr "bt_stream_class_set_event_common_context_field_class(#{variable}, #{var_ecc});"
165
+ end
166
+ end
167
+ # Need to do is afert packet an devent_common_context because it can refer members to those
168
+ bt_set_conditionally(@assigns_automatic_event_class_id) do |v|
169
+ pr "bt_stream_class_set_assigns_automatic_event_class_id(#{variable}, #{v});"
170
+ end
171
+
172
+ @event_classes.each_with_index do |ec, i|
173
+ var_name = "#{variable}_ec_#{i}"
174
+ scope do
175
+ pr "bt_event_class *#{var_name};"
176
+ ec.get_declarator(trace_class: trace_class, variable: var_name, stream_class: variable)
177
+ end
178
+ end
179
+
180
+ bt_set_conditionally(@assigns_automatic_stream_id) do |v|
181
+ pr "bt_stream_class_set_assigns_automatic_stream_id(#{variable}, #{v});"
182
+ end
183
+ end
184
+ end
185
+
186
+ class BTEventClass
187
+ include BTPrinter
188
+ include BTLocator
189
+ extend BTFromH
190
+ attr_reader :name, :specific_context_field_class, :payload_field_class
191
+
192
+ def initialize(parent:, name: nil, specific_context_field_class: nil, payload_field_class: nil, id: nil)
193
+ @parent = parent
194
+ @name = name
195
+ if specific_context_field_class
196
+ @specific_context_field_class = BTFieldClass.from_h(self,
197
+ specific_context_field_class)
198
+ end
199
+ @payload_field_class = BTFieldClass.from_h(self, payload_field_class) if payload_field_class
200
+
201
+ @id = id
202
+ end
203
+
204
+ def get_declarator(trace_class:, variable:, stream_class:)
205
+ # Store the variable name for instrocption purpose for LOCATION_PATH
206
+ @variable = variable
207
+ if @id
208
+ pr "#{variable} = bt_event_class_create_with_id(#{stream_class}, #{@id});"
209
+ else
210
+ pr "#{variable} = bt_event_class_create(#{stream_class});"
211
+ end
212
+
213
+ pr "bt_event_class_set_name(#{variable}, \"#{@name}\");" if @name
214
+
215
+ if @specific_context_field_class
216
+ var_name = "#{variable}_sc_fc"
217
+ scope do
218
+ pr "bt_field_class *#{var_name};"
219
+ @specific_context_field_class.get_declarator(trace_class: trace_class, variable: var_name)
220
+ pr "bt_event_class_set_specific_context_field_class(#{variable}, #{var_name});"
221
+ end
222
+ end
223
+
224
+ if @payload_field_class
225
+ var_name = "#{variable}_p_fc"
226
+ scope do
227
+ pr "bt_field_class *#{var_name};"
228
+ @payload_field_class.get_declarator(trace_class: trace_class, variable: var_name)
229
+ pr "bt_event_class_set_payload_field_class(#{variable}, #{var_name});"
230
+ end
231
+ end
232
+ end
233
+
234
+ def get_setter(event:, arg_variables:)
235
+ if rec_stream_class.event_common_context_field_class
236
+ field = "#{event}_cc_f"
237
+ scope do
238
+ pr "bt_field *#{field} = bt_event_borrow_common_context_field(#{event});"
239
+ rec_stream_class.event_common_context_field_class.get_setter(variable: field, arg_variables: arg_variables)
240
+ end
241
+ end
242
+
243
+ if @specific_context_field_class
244
+ field = "#{event}_sc_f"
245
+ scope do
246
+ pr "bt_field *#{field} = bt_event_borrow_specific_context_field(#{event});"
247
+ @specific_context_field_class.get_setter(variable: field, arg_variables: arg_variables)
248
+ end
249
+ end
250
+
251
+ if @payload_field_class
252
+ field = "#{event}_p_f"
253
+ scope do
254
+ pr "bt_field *#{field} = bt_event_borrow_payload_field(#{event});"
255
+ @payload_field_class.get_setter(variable: field, arg_variables: arg_variables)
256
+ end
257
+ end
258
+ end
259
+
260
+ def get_getter(event:, arg_variables:)
261
+ if rec_stream_class.event_common_context_field_class
262
+ field = "#{event}_cc_f"
263
+ scope do
264
+ pr "const bt_field *#{field} = bt_event_borrow_common_context_field_const(#{event});"
265
+ rec_stream_class.event_common_context_field_class.get_getter(variable: field, arg_variables: arg_variables)
266
+ end
267
+ end
268
+
269
+ if @specific_context_field_class
270
+ field = "#{event}_sc_f"
271
+ scope do
272
+ pr "const bt_field *#{field} = bt_event_borrow_specific_context_field_const(#{event});"
273
+ @specific_context_field_class.get_getter(variable: field, arg_variables: arg_variables)
274
+ end
275
+ end
276
+
277
+ if @payload_field_class
278
+ field = "#{event}_p_f"
279
+ scope do
280
+ pr "const bt_field *#{field} = bt_event_borrow_payload_field_const(#{event});"
281
+ @payload_field_class.get_getter(variable: field, arg_variables: arg_variables)
282
+ end
283
+ end
284
+ end
285
+ end
286
+
287
+ class BTFieldClass
288
+ include BTLocator
289
+ include BTPrinter
290
+
291
+ attr_accessor :cast_type
292
+
293
+ def initialize(parent:)
294
+ @parent = parent
295
+ end
296
+
297
+ def self.from_h(parent, model)
298
+ key = model.delete(:type)
299
+ raise "No type in #{model}" unless key
300
+
301
+ h = {
302
+ 'bool' => BTFieldClass::Bool,
303
+ 'bit_array' => BTFieldClass::BitArray,
304
+ 'integer_unsigned' => BTFieldClass::Integer::Unsigned,
305
+ 'integer_signed' => BTFieldClass::Integer::Signed,
306
+ 'single' => BTFieldClass::Real::SinglePrecision,
307
+ 'double' => BTFieldClass::Real::DoublePrecision,
308
+ 'enumeration_unsigned' => BTFieldClass::Enumeration::Unsigned,
309
+ 'enumeration_signed' => BTFieldClass::Enumeration::Signed,
310
+ 'string' => BTFieldClass::String,
311
+ 'array_static' => BTFieldClass::Array::Static,
312
+ 'array_dynamic' => BTFieldClass::Array::Dynamic,
313
+ 'structure' => BTFieldClass::Structure,
314
+ 'option_without_selector_field' => BTFieldClass::Option::WithoutSelectorField,
315
+ 'option_with_selector_field_bool' => BTFieldClass::Option::WithSelectorField::Bool,
316
+ 'option_with_selector_field_unsigned' => BTFieldClass::Option::WithSelectorField::IntegerUnsigned,
317
+ 'option_with_selector_field_signed' => BTFieldClass::Option::WithSelectorField::IntegerSigned,
318
+ 'variant' => BTFieldClass::Variant
319
+ }.freeze
320
+
321
+ raise "No #{key} in FIELD_CLASS_NAME_MAP" unless h.include?(key)
322
+
323
+ cast_type = model.delete(:cast_type)
324
+ fc = h[key].from_h(parent, model)
325
+ fc.cast_type = cast_type if cast_type
326
+ fc
327
+ end
328
+
329
+ def get_declarator(*args, **dict)
330
+ raise NotImplementedError, self.class
331
+ end
332
+
333
+ def bt_get_variable(_field, arg_variables)
334
+ if arg_variables.empty? || arg_variables.first.is_a?(GeneratedArg)
335
+ variable = rec_menber_class.name
336
+ type = @cast_type || self.class.instance_variable_get(:@bt_type)
337
+ arg_variables << GeneratedArg.new(type, variable)
338
+ variable
339
+ else
340
+ arg_variables.shift
341
+ end
342
+ end
343
+
344
+ def get_getter(field:, arg_variables:)
345
+ bt_func_get = self.class.instance_variable_get(:@bt_func) % 'get'
346
+ variable = bt_get_variable(field, arg_variables)
347
+ cast_func = @cast_type ? "(#{@cast_type})" : ''
348
+ pr "#{variable} = #{cast_func}#{bt_func_get}(#{field});"
349
+ end
350
+
351
+ def get_setter(field:, arg_variables:)
352
+ bt_func_get = self.class.instance_variable_get(:@bt_func) % 'set'
353
+ variable = bt_get_variable(field, arg_variables)
354
+ cast_func = @cast_type ? "(#{self.class.instance_variable_get(:@bt_type)})" : ''
355
+ pr "#{bt_func_get}(#{field}, #{variable});"
356
+ end
357
+ end
358
+
359
+ class BTFieldClass::Bool < BTFieldClass
360
+ extend BTFromH
361
+
362
+ @bt_type = 'bt_bool'
363
+ @bt_func = 'bt_field_bool_%s_value'
364
+
365
+ def get_declarator(trace_class:, variable:)
366
+ pr "#{variable} = bt_field_class_bool_create(#{trace_class});"
367
+ end
368
+ end
369
+
370
+ class BTFieldClass::BitArray < BTFieldClass
371
+ extend BTFromH
372
+ attr_reader :length
373
+
374
+ @bt_type = 'uint64_t'
375
+ @bt_func = 'bt_field_bit_array_%s_value_as_integer'
376
+
377
+ def initialize(parent:, length:)
378
+ @parent = parent
379
+ @length = length
380
+ end
381
+
382
+ def get_declarator(trace_class:, variable:)
383
+ pr "#{variable} = bt_field_class_bit_array_create(#{trace_class}, #{@length});"
384
+ end
385
+ end
386
+
387
+ class BTFieldClass::Integer < BTFieldClass
388
+ attr_reader :field_value_range, :preferred_display_base
389
+
390
+ def initialize(parent:, field_value_range: nil, preferred_display_base: nil)
391
+ @parent = parent
392
+ @field_value_range = field_value_range
393
+ @preferred_display_base = preferred_display_base
394
+ end
395
+
396
+ def get_declarator(variable:)
397
+ pr "bt_field_class_integer_set_field_value_range(#{variable}, #{@field_value_range});" if @field_value_range
398
+ if @preferred_display_base
399
+ pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
400
+ end
401
+ end
402
+ end
403
+
404
+ class BTFieldClass::Integer::Unsigned < BTFieldClass::Integer
405
+ extend BTFromH
406
+
407
+ @bt_type = 'uint64_t'
408
+ @bt_func = 'bt_field_integer_unsigned_%s_value'
409
+
410
+ def get_declarator(trace_class:, variable:)
411
+ pr "#{variable} = bt_field_class_integer_unsigned_create(#{trace_class});"
412
+ super(variable: variable)
413
+ end
414
+ end
415
+
416
+ class BTFieldClass::Integer::Signed < BTFieldClass::Integer
417
+ extend BTFromH
418
+
419
+ @bt_type = 'int64_t'
420
+ @bt_func = 'bt_field_integer_signed_%s_value'
421
+
422
+ def get_declarator(trace_class:, variable:)
423
+ pr "#{variable} = bt_field_class_integer_signed_create(#{trace_class});"
424
+ super(variable: variable)
425
+ end
426
+ end
427
+
428
+ class BTFieldClass::Real < BTFieldClass
429
+ end
430
+
431
+ class BTFieldClass::Real::SinglePrecision < BTFieldClass::Real
432
+ extend BTFromH
433
+
434
+ @bt_type = 'float'
435
+ @bt_func = 'bt_field_real_single_precision_%s_value'
436
+
437
+ def get_declarator(trace_class:, variable:)
438
+ pr "#{variable} = bt_field_class_real_single_precision_create(#{trace_class});"
439
+ end
440
+ end
441
+
442
+ class BTFieldClass::Real::DoublePrecision < BTFieldClass::Real
443
+ extend BTFromH
444
+
445
+ @bt_type = 'double'
446
+ @bt_func = 'bt_field_real_double_precision_%s_value'
447
+
448
+ def get_declarator(trace_class:, variable:)
449
+ pr "#{variable} = bt_field_class_real_double_precision_create(#{trace_class});"
450
+ end
451
+ end
452
+
453
+ module BTFieldClass::Enumeration
454
+ attr_reader :mappings
455
+
456
+ class Mapping
457
+ end
458
+ end
459
+
460
+ class BTFieldClass::Enumeration::Unsigned < BTFieldClass::Integer::Unsigned
461
+ include BTFieldClass::Enumeration
462
+ class Mapping < BTFieldClass::Enumeration::Mapping
463
+ end
464
+
465
+ def initialize(parent:, field_value_range:, mappings:, preferred_display_base: 10)
466
+ @mappings = mappings # TODO: init Mapping
467
+ super(parent: parent, field_value_range: field_value_range, preferred_display_base: preferred_display_base)
468
+ end
469
+ end
470
+
471
+ class BTFieldClass::Enumeration::Signed < BTFieldClass::Integer::Signed
472
+ include BTFieldClass::Enumeration
473
+ class Mapping < BTFieldClass::Enumeration::Mapping
474
+ end
475
+
476
+ def initialize(parent:, field_value_range:, mappings:, preferred_display_base: 10)
477
+ @mappings = mappings # TODO: init Mapping
478
+ super(parent: parent, field_value_range: field_value_range, preferred_display_base: preferred_display_base)
479
+ end
480
+ end
481
+
482
+ class BTFieldClass::String < BTFieldClass
483
+ extend BTFromH
484
+
485
+ @bt_type = 'const char*'
486
+ @bt_func = 'bt_field_string_%s_value'
487
+
488
+ def get_declarator(trace_class:, variable:)
489
+ pr "#{variable} = bt_field_class_string_create(#{trace_class});"
490
+ end
491
+ end
492
+
493
+ class BTFieldClass::Array < BTFieldClass
494
+ attr_reader :element_field_class
495
+
496
+ def initialize(parent:, element_field_class:)
497
+ @parent = parent
498
+ @element_field_class = BTFieldClass.from_h(self, element_field_class)
499
+ end
500
+ end
501
+
502
+ class BTFieldClass::Array::Static < BTFieldClass::Array
503
+ extend BTFromH
504
+ attr_reader :length
505
+
506
+ def initialize(parent:, element_field_class:, length:)
507
+ @length = length
508
+ super(parent: parent, element_field_class: element_field_class)
509
+ end
510
+
511
+ def get_declarator(trace_class:, variable:)
512
+ element_field_class_variable = "#{variable}_field_class"
513
+ scope do
514
+ pr "bt_field_class *#{element_field_class_variable};"
515
+ @element_field_class.get_declarator(trace_class: trace_class, variable: element_field_class_variable)
516
+ pr "#{variable} = bt_field_class_array_static_create(#{trace_class}, #{element_field_class_variable}, #{@length});"
517
+ end
518
+ end
519
+ end
520
+
521
+ class BTFieldClass::Array::Dynamic < BTFieldClass::Array
522
+ extend BTFromH
523
+ module WithLengthField
524
+ attr_reader :length_field_path
525
+ end
526
+
527
+ def initialize(parent:, element_field_class:, length_field_path: nil)
528
+ super(parent: parent, element_field_class: element_field_class)
529
+ if length_field_path
530
+ extend(WithLengthField)
531
+ @length_field_path = length_field_path
532
+ end
533
+ end
534
+
535
+ def get_declarator(trace_class:, variable:)
536
+ element_field_class_variable = "#{variable}_field_class"
537
+ scope do
538
+ pr "bt_field_class *#{element_field_class_variable};"
539
+ @element_field_class.get_declarator(trace_class: trace_class, variable: element_field_class_variable)
540
+ if @length_field_path
541
+ element_field_class_variable_length = "#{element_field_class_variable}_length"
542
+ pr "bt_field_class *#{element_field_class_variable_length};"
543
+ find_field_class(@length_field_path, element_field_class_variable_length)
544
+ pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, #{element_field_class_variable_length});"
545
+ else
546
+ pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, NULL);"
547
+ end
548
+ end
549
+ end
550
+ end
551
+
552
+ class BTMemberClass
553
+ include BTLocator
554
+ attr_reader :parent, :name, :field_class
555
+
556
+ def initialize(parent:, name:, field_class:)
557
+ @parent = parent
558
+ @name = name
559
+ @field_class = BTFieldClass.from_h(self, field_class)
560
+ end
561
+ end
562
+
563
+ class BTFieldClass::Structure < BTFieldClass
564
+ extend BTFromH
565
+
566
+ attr_reader :members
567
+
568
+ def initialize(parent:, members: [])
569
+ @parent = parent
570
+ @members = members.collect { |m| BTMemberClass.new(parent: self, **m) }
571
+ end
572
+
573
+ def [](index)
574
+ case index
575
+ when Integer
576
+ @members[index]
577
+ when String
578
+ @members.find { |m| m.name == index }
579
+ end
580
+ end
581
+
582
+ def get_declarator(trace_class:, variable:)
583
+ @variable = variable
584
+ pr "#{variable} = bt_field_class_structure_create(#{trace_class});"
585
+ @members.each_with_index do |m, i|
586
+ var_name = "#{variable}_m_#{i}"
587
+ scope do
588
+ pr "bt_field_class *#{var_name};"
589
+ m.field_class.get_declarator(trace_class: trace_class, variable: var_name)
590
+ pr "bt_field_class_structure_append_member(#{variable}, \"#{m.name}\", #{var_name});"
591
+ end
592
+ end
593
+ end
594
+
595
+ def get_setter(variable:, arg_variables:)
596
+ @members.each_with_index do |m, i|
597
+ field = "#{variable}_m_#{i}"
598
+ scope do
599
+ pr "bt_field *#{field} = bt_field_structure_borrow_member_field_by_index(#{variable}, #{i});"
600
+ m.field_class.get_setter(field: field, arg_variables: arg_variables)
601
+ end
602
+ end
603
+ end
604
+
605
+ def get_getter(variable:, arg_variables:)
606
+ @members.each_with_index do |m, i|
607
+ field = "#{variable}_m_#{i}"
608
+ scope do
609
+ pr "const bt_field *#{field} = bt_field_structure_borrow_member_field_by_index_const(#{variable}, #{i});"
610
+ m.field_class.get_getter(field: field, arg_variables: arg_variables)
611
+ end
612
+ end
613
+ end
614
+ end
615
+
616
+ class BTFieldClass::Option < BTFieldClass
617
+ attr_reader :field_class
618
+
619
+ def initialize(parent:, field_class:)
620
+ @parent = parent
621
+ @field_class = BTFieldClass.from_h(self, field_class)
622
+ end
623
+ end
624
+ BTFieldClassOption = BTFieldClass::Option
625
+
626
+ class BTFieldClass::Option::WithoutSelectorField < BTFieldClass::Option
627
+ extend BTFromH
628
+ end
629
+
630
+ class BTFieldClass::Option::WithSelectorField < BTFieldClass::Option
631
+ attr_reader :selector_field_path
632
+
633
+ def initialize(parent:, field_class:, selector_field_path:)
634
+ @selector_field_path = selector_field_path
635
+ super(parent: parent, field_class: field_class)
636
+ end
637
+ end
638
+
639
+ class BTFieldClass::Option::WithSelectorField::Bool < BTFieldClass::Option::WithSelectorField
640
+ extend BTFromH
641
+ attr_reader :selector_is_reversed
642
+
643
+ def initialize(parent:, field_class:, selector_field_path:, selector_is_reversed: nil)
644
+ @selector_is_reversed = selector_is_reversed
645
+ super(parent: parent, field_class: field_class, selector_field_path: selector_field_path)
646
+ end
647
+ end
648
+
649
+ class BTFieldClass::Option::WithSelectorField::IntegerUnsigned < BTFieldClass::Option::WithSelectorField
650
+ extend BTFromH
651
+ attr_reader :selector_ranges
652
+
653
+ def initialize(parent:, field_class:, selector_field_path:, selector_ranges:)
654
+ @selector_ranges = selector_ranges
655
+ super(parent: parent, field_class: field_class, selector_field_path: selector_field_path)
656
+ end
657
+ end
658
+
659
+ class BTFieldClass::Option::WithSelectorField::IntegerSigned < BTFieldClass::Option::WithSelectorField
660
+ extend BTFromH
661
+ attr_reader :selector_ranges
662
+
663
+ def initialize(parent:, field_class:, selector_field_path:, selector_ranges:)
664
+ @selector_ranges = selector_ranges
665
+ super(parent: parent, field_class: field_class, selector_field_path: selector_field_path)
666
+ end
667
+ end
668
+
669
+ class BTFieldClass::Variant < BTFieldClass
670
+ extend BTFromH
671
+ attr_reader :options
672
+
673
+ class Option
674
+ attr_reader :name, :field_class
675
+
676
+ def initialize(parent:, name:, field_class:)
677
+ @parent = parent
678
+ @name = name
679
+ @field_class = BTFieldClass.from_h(self, field_class)
680
+ end
681
+ end
682
+
683
+ module WithoutSelectorField
684
+ end
685
+
686
+ module WithSelectorField
687
+ attr_reader :selector_field_class
688
+
689
+ class Option < BTFieldClass::Variant::Option
690
+ attr_reader :ranges
691
+
692
+ def initialize(parent:, name:, field_class:, ranges:)
693
+ @ranges = ranges
694
+ super(parent: parent, name: name, field_class: field_class)
695
+ end
696
+ end
697
+ end
698
+
699
+ def initialize(parent:, options:, selector_field_class: nil)
700
+ @parent = parent
701
+ if selector_field_class
702
+ extend(WithSelectorField)
703
+ @selector_field_class = selector_field_class
704
+ @options = options.collect do |o|
705
+ BTFieldClass::Variant::WithSelectorField::Option.new(name: o[:name], field_class: o[:field_class],
706
+ range: o[:range])
707
+ end
708
+ else
709
+ extend(WithoutSelectorField)
710
+ @options = options.collect do |o|
711
+ BTFieldClass::Variant::Option.new(name: o[:name], field_class: o[:field_class])
712
+ end
713
+ end
714
+ end
715
+ end
716
+ end