c2ffi4rb 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9471bfff4cabf71daa4a888c294218eb8b74200168b35584cb166771a062fe4a
4
- data.tar.gz: f84570b4abbae4fd1eba8e1ee76554da81aa621a92be31014748ac5e5aa5e20e
3
+ metadata.gz: 06ea739a36f2f4a6485ba3e65b6e91724eafed7f7440df1d26e7dfb5d5290897
4
+ data.tar.gz: 2eaf74991d02fd8b6e5beae79150cc1b40f5178c4bb27cf1277bf1bae0c744f2
5
5
  SHA512:
6
- metadata.gz: a2443c99c551de4a8c42a977604c4654e75a0f9f9c754395fb894bdcf488d388e1523aac2a0862126baf17b7cda86966e902f71bbf0ecd2db54f8a68df1e2da8
7
- data.tar.gz: ce7450668d888f8fc575e56a8a9be650ea2862044feac2e49e0a94f5f50834576cb3a3a46c4f6ac05ea056942e6b9924401342b87876941ebfe97dddd45c5e02
6
+ metadata.gz: cdc2f8439c2722a83b3a82aac50821d4bf4f9be35efa52e30202e44417ab29b3a203896ddc955e0046637667d50751a354902955df92560c22a4b74a9939fc61
7
+ data.tar.gz: 5bb0f1ba5929c3ba8dbc4ca176701fddc05a3fb836ac218a1606b935335af035972354cfb4ba0950f5a19daf04457486801fca9ea868685070c1134b90e6938b
data/exe/c2ffi4rb CHANGED
@@ -8,8 +8,20 @@
8
8
  require 'optparse'
9
9
  require 'c2ffi4rb'
10
10
 
11
+ type_table = {}
12
+
11
13
  opts = OptionParser.new
12
14
  opts.banner = 'Usage: c2ffi4rb [options] [file1, file2, ...]'
15
+ opts.on('-t FILE', '--table FILE', 'Type conversion table TSV') do |file|
16
+ File.open(file) do |io|
17
+ io.each_line do |line|
18
+ next if line =~ /^#/
19
+
20
+ from, to = line.chomp.split("\t")
21
+ type_table[from] = to
22
+ end
23
+ end
24
+ end
13
25
  opts.on('-h', '--help', 'Show this message') do
14
26
  puts opts
15
27
  exit
@@ -32,4 +44,4 @@ ARGV.each do |file|
32
44
  end
33
45
  end
34
46
 
35
- C2FFI4RB::BindGen.generate_bindings(spec)
47
+ C2FFI4RB::BindGen.new(type_table).generate_bindings(spec)
@@ -4,21 +4,28 @@ require 'json'
4
4
 
5
5
  module C2FFI4RB
6
6
  class BindGen
7
- TYPE_TABLE = {
7
+ DEFAULT_TYPE_TABLE = {
8
+ ':signed-int' => ':int',
8
9
  ':unsigned-int' => ':uint',
10
+ ':signed-char' => ':char',
9
11
  ':unsigned-char' => ':uchar',
12
+ ':signed-short' => ':short',
10
13
  ':unsigned-short' => ':ushort',
11
14
  ':long-long' => ':long_long',
15
+ ':ulong-long' => ':ulong_long',
16
+ ':long-double' => ':long_double',
17
+ ':signed-long' => ':long',
12
18
  ':unsigned-long' => ':ulong',
13
19
  ':unsigned-long-long' => ':ulong_long',
14
20
  ':function-pointer' => ':pointer'
15
- }.freeze
21
+ }
16
22
 
17
23
  def self.generate_bindings(arr)
18
24
  new.generate_bindings(arr)
19
25
  end
20
26
 
21
- def initialize
27
+ def initialize(type_table = {})
28
+ @type_table = DEFAULT_TYPE_TABLE.merge(type_table)
22
29
  @struct_type = []
23
30
  @toplevels = []
24
31
  @anon_counter = 0
@@ -55,7 +62,11 @@ module C2FFI4RB
55
62
  type = resolve_type(form[:type])
56
63
  if @struct_type.include?(type)
57
64
  name = define_struct(form[:name])
58
- "#{name} = #{type}"
65
+ if name == type
66
+ "# #{name} = #{type}"
67
+ else
68
+ "#{name} = #{type}"
69
+ end
59
70
  elsif type == ":{#{form[:name]}}"
60
71
  warn "Ignoring self-referential typedef #{form[:name]}"
61
72
  else
@@ -65,6 +76,7 @@ module C2FFI4RB
65
76
  warn "# Redefinition of #{form[:name]} from #{@typedefs[form[:name]]} to #{type}"
66
77
 
67
78
  end
79
+ "typedef :pointer, :#{form[:name]} # #{type}" if form[:type][:tag] == ':array'
68
80
  @typedefs[form[:name]] = type
69
81
  "typedef #{type}, :#{form[:name]}"
70
82
  end
@@ -81,7 +93,9 @@ module C2FFI4RB
81
93
  end
82
94
 
83
95
  def generate_function(form)
84
- params = form[:parameters].map { |f| " #{resolve_type(f[:type])}," }.join("\n")
96
+ params = form[:parameters].map do |f|
97
+ f[:type][:tag] == ':array' ? " :pointer, # #{resolve_type(f[:type])}" : " #{resolve_type(f[:type])},"
98
+ end.join("\n")
85
99
  <<~FUNCTION
86
100
  attach_function '#{form[:name]}', [
87
101
  #{params}
@@ -100,7 +114,7 @@ module C2FFI4RB
100
114
 
101
115
  @anon_enum_ids << id
102
116
  end
103
- name = normalize_enum_name(form[:name])
117
+ name = normalize_enum_name(form[:name], form[:id])
104
118
  fields = form[:fields].map { |f| " :#{f[:name]}, #{f[:value]}," }.join("\n")
105
119
  <<~ENUM
106
120
  enum #{name}, [
@@ -136,12 +150,9 @@ module C2FFI4RB
136
150
  end
137
151
  end
138
152
 
139
- def normalize_enum_name(name)
153
+ def normalize_enum_name(name, id)
140
154
  # Anonymous enums are given a name
141
- if name.empty?
142
- @anon_counter += 1
143
- name = "anon_type_#{@anon_counter}"
144
- end
155
+ name = "anon_enum_#{id}" if name.empty?
145
156
 
146
157
  # All enums are prefixed with a colon
147
158
  name = ":#{name}" unless name.start_with?(':')
@@ -161,7 +172,8 @@ module C2FFI4RB
161
172
 
162
173
  register_struct(name)
163
174
 
164
- type = form[:tag] == 'struct' ? 'FFI::Struct' : 'FFI::Union'
175
+ # FIXME: :FFI::Struct or FFI::Struct
176
+ type = form[:tag] == 'struct' ? '::FFI::Struct' : '::FFI::Union'
165
177
 
166
178
  lines = ["class #{name} < #{type}"]
167
179
 
@@ -183,12 +195,12 @@ module C2FFI4RB
183
195
  end
184
196
 
185
197
  def resolve_type(form)
186
- TYPE_TABLE.fetch(form[:tag]) do
198
+ @type_table.fetch(form[:tag]) do
187
199
  case form[:tag]
188
200
  when ':pointer' then resolve_pointer_type(form)
189
201
  when ':array' then resolve_array_type(form)
190
202
  when ':struct', ':union' then define_struct(form[:name])
191
- when ':enum' then normalize_enum_name(form[:name])
203
+ when ':enum' then normalize_enum_name(form[:name], form[:id])
192
204
  when 'struct', 'union' then define_struct_or_union_type(form)
193
205
  when 'enum' then normalize_enum_name_type(form)
194
206
  else resolve_default_type(form)
@@ -212,7 +224,7 @@ module C2FFI4RB
212
224
  end
213
225
 
214
226
  def normalize_enum_name_type(form)
215
- form[:name] = normalize_enum_name(form[:name])
227
+ form[:name] = normalize_enum_name(form[:name], form[:id])
216
228
  process_toplevel(form)
217
229
  form[:name]
218
230
  end
@@ -224,6 +236,10 @@ module C2FFI4RB
224
236
  end
225
237
 
226
238
  def resolve_default_type(form)
239
+ ## FIXME
240
+ st_name = normalize_struct_name(form[:tag])
241
+ return st_name if @struct_type.include?(st_name)
242
+
227
243
  form[:tag].start_with?(':') ? form[:tag] : ":#{form[:tag]}"
228
244
  end
229
245
  end
@@ -1,3 +1,3 @@
1
1
  module C2FFI4RB
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c2ffi4rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-09-05 00:00:00.000000000 Z
12
+ date: 2024-09-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler