c2ffi4rb 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|