ffidb 0.12.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.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/CHANGES.md +7 -0
- data/CREDITS.md +2 -0
- data/README.md +201 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/bin/ffidb +387 -0
- data/etc/mappings/dart.yaml +35 -0
- data/etc/mappings/java.yaml +36 -0
- data/etc/mappings/lisp.yaml +35 -0
- data/etc/mappings/python.yaml +35 -0
- data/etc/mappings/ruby.yaml +35 -0
- data/etc/templates/c.erb +46 -0
- data/etc/templates/cpp.erb +45 -0
- data/etc/templates/dart.erb +64 -0
- data/etc/templates/go.erb +50 -0
- data/etc/templates/java.erb +56 -0
- data/etc/templates/lisp.erb +49 -0
- data/etc/templates/python.erb +59 -0
- data/etc/templates/ruby.erb +48 -0
- data/lib/ffidb.rb +34 -0
- data/lib/ffidb/enum.rb +37 -0
- data/lib/ffidb/errors.rb +64 -0
- data/lib/ffidb/exporter.rb +141 -0
- data/lib/ffidb/exporters.rb +28 -0
- data/lib/ffidb/exporters/c.rb +52 -0
- data/lib/ffidb/exporters/cpp.rb +13 -0
- data/lib/ffidb/exporters/csharp.rb +6 -0
- data/lib/ffidb/exporters/csv.rb +24 -0
- data/lib/ffidb/exporters/dart.rb +60 -0
- data/lib/ffidb/exporters/go.rb +16 -0
- data/lib/ffidb/exporters/haskell.rb +3 -0
- data/lib/ffidb/exporters/java.rb +39 -0
- data/lib/ffidb/exporters/json.rb +38 -0
- data/lib/ffidb/exporters/julia.rb +3 -0
- data/lib/ffidb/exporters/lisp.rb +41 -0
- data/lib/ffidb/exporters/luajit.rb +3 -0
- data/lib/ffidb/exporters/nim.rb +4 -0
- data/lib/ffidb/exporters/nodejs.rb +4 -0
- data/lib/ffidb/exporters/ocaml.rb +4 -0
- data/lib/ffidb/exporters/php.rb +4 -0
- data/lib/ffidb/exporters/python.rb +35 -0
- data/lib/ffidb/exporters/racket.rb +3 -0
- data/lib/ffidb/exporters/ruby.rb +33 -0
- data/lib/ffidb/exporters/rust.rb +5 -0
- data/lib/ffidb/exporters/yaml.rb +31 -0
- data/lib/ffidb/exporters/zig.rb +3 -0
- data/lib/ffidb/function.rb +70 -0
- data/lib/ffidb/glob.rb +28 -0
- data/lib/ffidb/header.rb +19 -0
- data/lib/ffidb/header_parser.rb +339 -0
- data/lib/ffidb/library.rb +120 -0
- data/lib/ffidb/library_parser.rb +132 -0
- data/lib/ffidb/location.rb +17 -0
- data/lib/ffidb/parameter.rb +35 -0
- data/lib/ffidb/registry.rb +87 -0
- data/lib/ffidb/release.rb +14 -0
- data/lib/ffidb/struct.rb +41 -0
- data/lib/ffidb/symbol_table.rb +90 -0
- data/lib/ffidb/symbolic.rb +67 -0
- data/lib/ffidb/sysexits.rb +21 -0
- data/lib/ffidb/type.rb +214 -0
- data/lib/ffidb/typedef.rb +38 -0
- data/lib/ffidb/union.rb +37 -0
- data/lib/ffidb/version.rb +21 -0
- metadata +197 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative 'symbolic'
|
4
|
+
|
5
|
+
module FFIDB
|
6
|
+
module SymbolTable
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
##
|
10
|
+
# @return [Array<Type>]
|
11
|
+
def types
|
12
|
+
self.each_type.to_a
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# @yield [type]
|
17
|
+
# @yieldparam [type] Type
|
18
|
+
# @return [Enumerator]
|
19
|
+
def each_type(&block)
|
20
|
+
return self.to_enum(:each_type) unless block_given?
|
21
|
+
types = {}
|
22
|
+
self.each_function do |function| # TODO: each_symbol
|
23
|
+
types[function.type.to_s] ||= function.type
|
24
|
+
function.parameters.each_value do |parameter|
|
25
|
+
types[parameter.type.to_s] ||= parameter.type
|
26
|
+
end
|
27
|
+
end
|
28
|
+
types.values.sort.each(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# @yield [symbol]
|
33
|
+
# @yieldparam [symbol] Symbolic
|
34
|
+
# @return [Enumerator]
|
35
|
+
def each_symbol(&block)
|
36
|
+
return self.to_enum(:each_symbol) unless block_given?
|
37
|
+
self.each_typedef(&block)
|
38
|
+
self.each_enum(&block)
|
39
|
+
self.each_struct(&block)
|
40
|
+
self.each_union(&block)
|
41
|
+
self.each_function(&block)
|
42
|
+
end
|
43
|
+
alias_method :each, :each_symbol
|
44
|
+
|
45
|
+
##
|
46
|
+
# @yield [typedef]
|
47
|
+
# @yieldparam [symbol] Symbolic
|
48
|
+
# @return [Enumerator]
|
49
|
+
def each_typedef(&block)
|
50
|
+
return self.to_enum(:each_typedef) unless block_given?
|
51
|
+
self.typedefs.each(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @yield [enum]
|
56
|
+
# @yieldparam [enum] Enum
|
57
|
+
# @return [Enumerator]
|
58
|
+
def each_enum(&block)
|
59
|
+
return self.to_enum(:each_enum) unless block_given?
|
60
|
+
self.enums.each(&block)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# @yield [struct]
|
65
|
+
# @yieldparam [struct] Struct
|
66
|
+
# @return [Enumerator]
|
67
|
+
def each_struct(&block)
|
68
|
+
return self.to_enum(:each_struct) unless block_given?
|
69
|
+
self.structs.each(&block)
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# @yield [union]
|
74
|
+
# @yieldparam [union] Union
|
75
|
+
# @return [Enumerator]
|
76
|
+
def each_union(&block)
|
77
|
+
return self.to_enum(:each_union) unless block_given?
|
78
|
+
self.unions.each(&block)
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# @yield [function]
|
83
|
+
# @yieldparam [function] Function
|
84
|
+
# @return [Enumerator]
|
85
|
+
def each_function(&block)
|
86
|
+
return self.to_enum(:each_function) unless block_given?
|
87
|
+
self.functions.each(&block)
|
88
|
+
end
|
89
|
+
end # SymbolTable
|
90
|
+
end # FFIDB
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
module FFIDB
|
4
|
+
module Symbolic
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
##
|
8
|
+
# @param [Symbolic] other
|
9
|
+
# @return [Integer]
|
10
|
+
def <=>(other)
|
11
|
+
self.name <=> other.name
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# @return [Symbol]
|
16
|
+
def kind
|
17
|
+
case
|
18
|
+
when self.typedef? then :typedef
|
19
|
+
when self.enum? then :enum
|
20
|
+
when self.struct? then :struct
|
21
|
+
when self.union? then :union
|
22
|
+
when self.function? then :function
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [Integer]
|
28
|
+
def kind_weight
|
29
|
+
case
|
30
|
+
when self.typedef? then 1
|
31
|
+
when self.enum? then 2
|
32
|
+
when self.struct? then 3
|
33
|
+
when self.union? then 4
|
34
|
+
when self.function? then 5
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @return [Boolean]
|
40
|
+
def typedef?() return false end
|
41
|
+
|
42
|
+
##
|
43
|
+
# @return [Boolean]
|
44
|
+
def enum?() return false end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @return [Boolean]
|
48
|
+
def struct?() return false end
|
49
|
+
|
50
|
+
##
|
51
|
+
# @return [Boolean]
|
52
|
+
def union?() return false end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @return [Boolean]
|
56
|
+
def function?() return false end
|
57
|
+
|
58
|
+
##
|
59
|
+
# @return [String]
|
60
|
+
def to_yaml
|
61
|
+
h = self.to_h
|
62
|
+
h.transform_keys!(&:to_s)
|
63
|
+
h.transform_values! { |v| v.is_a?(Hash) ? v.transform_keys!(&:to_s) : v }
|
64
|
+
YAML.dump(h).gsub!("---\n", "--- !#{self.kind}\n")
|
65
|
+
end
|
66
|
+
end # Symbolic
|
67
|
+
end # FFIDB
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
module FFIDB
|
4
|
+
module Sysexits
|
5
|
+
EX_USAGE = 64
|
6
|
+
EX_DATAERR = 65
|
7
|
+
EX_NOINPUT = 66
|
8
|
+
EX_NOUSER = 67
|
9
|
+
EX_NOHOST = 68
|
10
|
+
EX_UNAVAILABLE = 69
|
11
|
+
EX_SOFTWARE = 70
|
12
|
+
EX_OSERR = 71
|
13
|
+
EX_OSFILE = 72
|
14
|
+
EX_CANTCREAT = 73
|
15
|
+
EX_IOERR = 74
|
16
|
+
EX_TEMPFAIL = 75
|
17
|
+
EX_PROTOCOL = 76
|
18
|
+
EX_NOPERM = 77
|
19
|
+
EX_CONFIG = 78
|
20
|
+
end # Sysexits
|
21
|
+
end # FFIDB
|
data/lib/ffidb/type.rb
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
module FFIDB
|
4
|
+
class Type < ::Struct.new(:spec)
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
##
|
8
|
+
# @param [String, #to_s] spec
|
9
|
+
# @return [Type]
|
10
|
+
def self.for(type_spec)
|
11
|
+
return type_spec if type_spec.is_a?(Type)
|
12
|
+
self.new(type_spec)
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [String, #to_s] spec
|
17
|
+
def initialize(spec)
|
18
|
+
super(spec.to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param [Type] other
|
23
|
+
# @return [Integer]
|
24
|
+
def <=>(other) self.spec <=> other.spec end
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [Boolean]
|
28
|
+
def const_qualified?
|
29
|
+
self.spec.start_with?('const ')
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# @return [Boolean]
|
34
|
+
def atomic?
|
35
|
+
self.bool? || self.integer? || self.floating_point? || self.pointer? || nil # TODO
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @return [Boolean]
|
40
|
+
def void?
|
41
|
+
self.spec == 'void'
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# @return [Boolean]
|
46
|
+
def bool?
|
47
|
+
self.spec == '_Bool'
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# @return [Boolean]
|
52
|
+
def enum?
|
53
|
+
!(self.pointer?) && self.spec.start_with?('enum ')
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# @return [Boolean]
|
58
|
+
def struct?
|
59
|
+
!(self.pointer?) && (self.spec.start_with?('struct ') || self.spec.start_with?('const struct '))
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# @return [Boolean]
|
64
|
+
def union?
|
65
|
+
!(self.pointer?) && (self.spec.start_with?('union ') || self.spec.start_with?('const union '))
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# @return [Boolean]
|
70
|
+
def integer?
|
71
|
+
case self.spec
|
72
|
+
when 'char', 'short', 'int', 'long', 'long long' then true
|
73
|
+
when 'unsigned char', 'unsigned short', 'unsigned int', 'unsigned long', 'unsigned long long' then true
|
74
|
+
when 'size_t', 'wchar_t' then true # <stddef.h>
|
75
|
+
when 'ssize_t', 'off_t' then true # <sys/types.h>
|
76
|
+
when /^u?int\d+_t$/ then true
|
77
|
+
else false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# @return [Boolean]
|
83
|
+
def signed_integer?
|
84
|
+
return false unless self.integer?
|
85
|
+
case self.spec
|
86
|
+
when 'char', 'short', 'int', 'long', 'long long' then true
|
87
|
+
when 'wchar_t' then nil # <stddef.h>
|
88
|
+
when 'ssize_t' then true # <sys/types.h>
|
89
|
+
when /^int\d+_t$/ then true
|
90
|
+
else false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# @return [Boolean]
|
96
|
+
def unsigned_integer?
|
97
|
+
return false unless self.integer?
|
98
|
+
return true if self.spec.start_with?('u')
|
99
|
+
case self.spec
|
100
|
+
when 'unsigned char', 'unsigned short', 'unsigned int', 'unsigned long', 'unsigned long long' then true
|
101
|
+
when 'size_t' then true # <stddef.h>
|
102
|
+
when 'wchar_t' then nil # <stddef.h>
|
103
|
+
when 'off_t' then true # <sys/types.h>
|
104
|
+
when /^uint\d+_t$/ then true
|
105
|
+
else false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# @return [Boolean]
|
111
|
+
def floating_point?
|
112
|
+
case self.spec
|
113
|
+
when 'float', 'double', 'long double' then true
|
114
|
+
else false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# @return [Boolean]
|
120
|
+
def array?
|
121
|
+
self.spec.include?('[')
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# @return [Type]
|
126
|
+
def array_type
|
127
|
+
if self.array?
|
128
|
+
self.class.for(self.spec.gsub(/\s+(\[[^\]]+\])/, ''))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# @return [Integer]
|
134
|
+
def array_size
|
135
|
+
if self.array?
|
136
|
+
(/\[([^\]]+)\]/ =~ self.spec) && $1.to_i
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# @return [Boolean]
|
142
|
+
def pointer?
|
143
|
+
self.spec.end_with?('*') ||
|
144
|
+
self.array_pointer? ||
|
145
|
+
self.function_pointer? ||
|
146
|
+
case self.spec
|
147
|
+
when 'intptr_t', 'uintptr_t' then true
|
148
|
+
when 'va_list' then true
|
149
|
+
else false
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# @return [Boolean]
|
155
|
+
def array_pointer?
|
156
|
+
self.spec.end_with?('[]')
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# @return [Boolean]
|
161
|
+
def enum_pointer?
|
162
|
+
self.pointer? && self.spec.start_with?('enum ')
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# @return [Boolean]
|
167
|
+
def struct_pointer?
|
168
|
+
self.pointer? && (self.spec.start_with?('struct ') || self.spec.start_with?('const struct '))
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# @return [Boolean]
|
173
|
+
def union_pointer?
|
174
|
+
self.pointer? && (self.spec.start_with?('union ') || self.spec.start_with?('const union '))
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# @return [Boolean]
|
179
|
+
def function_pointer?
|
180
|
+
self.spec.include?('(*)')
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# @return [Integer, Range, nil]
|
185
|
+
def sizeof
|
186
|
+
nil # TODO
|
187
|
+
end
|
188
|
+
alias_method :size, :sizeof
|
189
|
+
|
190
|
+
##
|
191
|
+
# @return [Integer, Range, nil]
|
192
|
+
def alignof
|
193
|
+
nil # TODO
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# @return [String]
|
198
|
+
def to_s
|
199
|
+
self.spec
|
200
|
+
end
|
201
|
+
|
202
|
+
##
|
203
|
+
# @return [Hash<Symbol, Object>]
|
204
|
+
def to_h
|
205
|
+
{spec: self.spec}
|
206
|
+
end
|
207
|
+
|
208
|
+
##
|
209
|
+
# @return [String]
|
210
|
+
def inspect
|
211
|
+
"#{self.class}(#{self.spec.inspect})"
|
212
|
+
end
|
213
|
+
end # Type
|
214
|
+
end # FFIDB
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative 'symbolic'
|
4
|
+
require_relative 'type'
|
5
|
+
|
6
|
+
module FFIDB
|
7
|
+
class Typedef < ::Struct.new(:name, :type, :comment)
|
8
|
+
include Symbolic
|
9
|
+
|
10
|
+
##
|
11
|
+
# @param [Symbol, #to_sym] name
|
12
|
+
# @param [Type] type
|
13
|
+
# @param [String, #to_s] comment
|
14
|
+
def initialize(name, type, comment = nil)
|
15
|
+
super(name.to_sym, Type.for(type), comment&.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# @return [Boolean]
|
20
|
+
def typedef?() return true end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [String]
|
24
|
+
def to_s
|
25
|
+
"typedef #{self.type} #{self.name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [Hash<Symbol, Type>]
|
30
|
+
def to_h
|
31
|
+
{
|
32
|
+
name: self.name.to_s,
|
33
|
+
type: self.type.to_s,
|
34
|
+
comment: self.comment,
|
35
|
+
}.delete_if { |k, v| v.nil? }
|
36
|
+
end
|
37
|
+
end # Typedef
|
38
|
+
end # FFIDB
|
data/lib/ffidb/union.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative 'symbolic'
|
4
|
+
|
5
|
+
module FFIDB
|
6
|
+
class Union < ::Struct.new(:name, :fields, :comment)
|
7
|
+
include Symbolic
|
8
|
+
|
9
|
+
##
|
10
|
+
# @param [Symbol, #to_sym] name
|
11
|
+
# @param [Map<Symbol, Type>] fields
|
12
|
+
# @param [String, #to_s] comment
|
13
|
+
def initialize(name, fields = {}, comment = nil)
|
14
|
+
super(name.to_sym, fields || {}, comment&.to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# @return [Boolean]
|
19
|
+
def union?() return true end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @return [String]
|
23
|
+
def to_s
|
24
|
+
"union #{self.name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# @return [Hash<Symbol, Type>]
|
29
|
+
def to_h
|
30
|
+
{
|
31
|
+
name: self.name.to_s,
|
32
|
+
comment: self.comment,
|
33
|
+
fields: self.fields,
|
34
|
+
}.delete_if { |k, v| v.nil? }
|
35
|
+
end
|
36
|
+
end # Union
|
37
|
+
end # FFIDB
|