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 +4 -4
- data/exe/c2ffi4rb +13 -1
- data/lib/c2ffi4rb/bind_gen.rb +31 -15
- data/lib/c2ffi4rb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06ea739a36f2f4a6485ba3e65b6e91724eafed7f7440df1d26e7dfb5d5290897
|
4
|
+
data.tar.gz: 2eaf74991d02fd8b6e5beae79150cc1b40f5178c4bb27cf1277bf1bae0c744f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/lib/c2ffi4rb/bind_gen.rb
CHANGED
@@ -4,21 +4,28 @@ require 'json'
|
|
4
4
|
|
5
5
|
module C2FFI4RB
|
6
6
|
class BindGen
|
7
|
-
|
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
|
-
}
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
data/lib/c2ffi4rb/version.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2024-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|