ffidb 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,52 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the C programming language.
|
8
|
+
class C < FFIDB::Exporter
|
9
|
+
SYMBOL_INDENT = 0
|
10
|
+
EXTERN_QUALIFIER = 'extern'
|
11
|
+
|
12
|
+
def finish
|
13
|
+
puts self.render_template('c.erb')
|
14
|
+
end
|
15
|
+
|
16
|
+
def _export_function(function, **kwargs)
|
17
|
+
parameters = function.parameters.each_value.map do |p|
|
18
|
+
p_type = case
|
19
|
+
when p.type.function_pointer?
|
20
|
+
p.type.to_s.sub('(*)', "(*#{p.name})")
|
21
|
+
when self.options[:parameter_names] == false
|
22
|
+
p.type.to_s.gsub(' *', '*')
|
23
|
+
else "#{p.type.to_s.gsub(' *', '*')} #{p.name}"
|
24
|
+
end
|
25
|
+
p_type.gsub('const char *const[]', 'const char* const*') # FIXME
|
26
|
+
end
|
27
|
+
print ' '*self.symbol_indent if self.symbol_indent.nonzero?
|
28
|
+
print self.extern_qualifier, ' ' if self.extern_qualifier
|
29
|
+
if function.type.function_pointer?
|
30
|
+
print function.type.to_s.sub('(*)', "(*#{function.name}(#{parameters.join(', ')}))")
|
31
|
+
else
|
32
|
+
print function.type, ' ', function.name, '('
|
33
|
+
parameters.each_with_index do |p, i|
|
34
|
+
print ', ' if i.nonzero?
|
35
|
+
print p
|
36
|
+
end
|
37
|
+
print ')'
|
38
|
+
end
|
39
|
+
puts (self.options[:semicolon] == false ? '' : ';')
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def symbol_indent
|
45
|
+
self.class.const_get(:SYMBOL_INDENT)
|
46
|
+
end
|
47
|
+
|
48
|
+
def extern_qualifier
|
49
|
+
self.class.const_get(:EXTERN_QUALIFIER)
|
50
|
+
end
|
51
|
+
end # C
|
52
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative 'c'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the C++ programming language.
|
8
|
+
class Cpp < C
|
9
|
+
def finish
|
10
|
+
puts self.render_template('cpp.erb')
|
11
|
+
end
|
12
|
+
end # Cpp
|
13
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
# TODO: https://docs.microsoft.com/en-us/dotnet/framework/interop/platform-invoke-examples
|
4
|
+
# TODO: https://docs.microsoft.com/en-us/dotnet/framework/interop/
|
5
|
+
# TODO: https://docs.microsoft.com/en-us/dotnet/framework/interop/consuming-unmanaged-dll-functions
|
6
|
+
# TODO: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the CSV file format.
|
8
|
+
class CSV < FFIDB::Exporter
|
9
|
+
DELIMITER = ','
|
10
|
+
|
11
|
+
def begin
|
12
|
+
puts [:library, :kind, :name].join(DELIMITER) # TODO: definition
|
13
|
+
end
|
14
|
+
|
15
|
+
def export_symbol(symbol, **kwargs)
|
16
|
+
puts [@library&.name, symbol.kind, symbol.name].join(DELIMITER)
|
17
|
+
end
|
18
|
+
alias_method :export_typedef, :export_symbol
|
19
|
+
alias_method :export_enum, :export_symbol
|
20
|
+
alias_method :export_struct, :export_symbol
|
21
|
+
alias_method :export_union, :export_symbol
|
22
|
+
alias_method :export_function, :export_symbol
|
23
|
+
end # CSV
|
24
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Dart programming language.
|
8
|
+
#
|
9
|
+
# @see https://dart.dev/guides/libraries/c-interop
|
10
|
+
# @see https://flutter.dev/docs/development/platform-integration/c-interop
|
11
|
+
# @see https://api.dart.dev/dev/dart-ffi/dart-ffi-library.html
|
12
|
+
class Dart < FFIDB::Exporter
|
13
|
+
TYPE_MAP_FFI = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/dart.yaml", __dir__)))
|
14
|
+
.freeze
|
15
|
+
|
16
|
+
# @see https://dart.dev/guides/language/language-tour
|
17
|
+
TYPE_MAP_DART = {
|
18
|
+
:Void => :void,
|
19
|
+
:Int8 => :int,
|
20
|
+
:Int16 => :int,
|
21
|
+
:Int32 => :int,
|
22
|
+
:Int64 => :int,
|
23
|
+
:Uint8 => :int,
|
24
|
+
:Uint16 => :int,
|
25
|
+
:Uint32 => :int,
|
26
|
+
:Uint64 => :int,
|
27
|
+
:Float => :double,
|
28
|
+
:Double => :double,
|
29
|
+
:IntPtr => :int,
|
30
|
+
'Pointer<Int8>' => 'Pointer<Int8>',
|
31
|
+
nil => 'Pointer<Void>',
|
32
|
+
}
|
33
|
+
|
34
|
+
def finish
|
35
|
+
puts self.render_template('dart.erb')
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
##
|
41
|
+
# @param [FFIDB::Type] c_type
|
42
|
+
# @return [#to_s]
|
43
|
+
def dart_param_type(c_type)
|
44
|
+
TYPE_MAP_DART[self.ffi_param_type(c_type)] || TYPE_MAP_DART[nil]
|
45
|
+
end
|
46
|
+
alias_method :dart_struct_type, :dart_param_type
|
47
|
+
|
48
|
+
##
|
49
|
+
# @param [FFIDB::Type] c_type
|
50
|
+
# @return [#to_s]
|
51
|
+
def ffi_param_type(c_type)
|
52
|
+
case
|
53
|
+
#when c_type.array? then # TODO: https://github.com/dart-lang/sdk/issues/35763
|
54
|
+
when c_type.enum? then :Int32
|
55
|
+
else TYPE_MAP_FFI[c_type.to_s] || TYPE_MAP_FFI['void *']
|
56
|
+
end
|
57
|
+
end
|
58
|
+
alias_method :ffi_struct_type, :ffi_param_type
|
59
|
+
end # Dart
|
60
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative 'c'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Go programming language (using Cgo).
|
8
|
+
#
|
9
|
+
# @see https://golang.org/cmd/cgo/
|
10
|
+
# @see https://github.com/golang/go/wiki/cgo
|
11
|
+
class Go < C
|
12
|
+
def finish
|
13
|
+
puts self.render_template('go.erb')
|
14
|
+
end
|
15
|
+
end # Go
|
16
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Java programming language (using JNA).
|
8
|
+
#
|
9
|
+
# @see https://github.com/java-native-access/jna/blob/master/www/GettingStarted.md
|
10
|
+
class Java < FFIDB::Exporter
|
11
|
+
TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/java.yaml", __dir__)))
|
12
|
+
.freeze
|
13
|
+
|
14
|
+
def begin_library(library)
|
15
|
+
if library
|
16
|
+
interface_name = self.options[:module] || library.name.capitalize
|
17
|
+
library.define_singleton_method(:interface_name) { interface_name }
|
18
|
+
end
|
19
|
+
super(library)
|
20
|
+
end
|
21
|
+
|
22
|
+
def finish
|
23
|
+
puts self.render_template('java.erb')
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param [FFIDB::Type] c_type
|
30
|
+
# @return [#to_s]
|
31
|
+
def param_type(c_type)
|
32
|
+
case
|
33
|
+
when c_type.enum? then :int
|
34
|
+
else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
alias_method :struct_type, :param_type
|
38
|
+
end # Java
|
39
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module FFIDB::Exporters
|
8
|
+
##
|
9
|
+
# Code generator for the JSON data interchange language.
|
10
|
+
class JSON < FFIDB::Exporter
|
11
|
+
def begin
|
12
|
+
# No header, because JSON doesn't support comments
|
13
|
+
@json = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def begin_library(library)
|
17
|
+
@library = library
|
18
|
+
@json[@library&.name] ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def export_symbol(symbol, **kwargs)
|
22
|
+
@json[@library&.name][symbol.name] = {kind: symbol.kind.to_s}.merge!(symbol.to_h)
|
23
|
+
end
|
24
|
+
alias_method :export_typedef, :export_symbol
|
25
|
+
alias_method :export_enum, :export_symbol
|
26
|
+
alias_method :export_struct, :export_symbol
|
27
|
+
alias_method :export_union, :export_symbol
|
28
|
+
alias_method :export_function, :export_symbol
|
29
|
+
|
30
|
+
def finish_library
|
31
|
+
@library = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def finish
|
35
|
+
puts ::JSON.pretty_generate(@json)
|
36
|
+
end
|
37
|
+
end # JSON
|
38
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Common Lisp programming language (using CFFI).
|
8
|
+
#
|
9
|
+
# @see https://common-lisp.net/project/cffi/
|
10
|
+
class Lisp < FFIDB::Exporter
|
11
|
+
TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/lisp.yaml", __dir__)))
|
12
|
+
.transform_values(&:to_sym)
|
13
|
+
.freeze
|
14
|
+
|
15
|
+
def finish
|
16
|
+
puts self.render_template('lisp.erb')
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param [FFIDB::Type] c_type
|
23
|
+
# @return [#inspect]
|
24
|
+
def struct_type(c_type)
|
25
|
+
case
|
26
|
+
when c_type.array? then [c_type.array_type.to_s.to_sym, :count, c_type.array_size]
|
27
|
+
else [self.param_type(c_type)]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# @param [FFIDB::Type] c_type
|
33
|
+
# @return [#inspect]
|
34
|
+
def param_type(c_type)
|
35
|
+
case
|
36
|
+
when c_type.enum? then :int
|
37
|
+
else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end # Lisp
|
41
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Python programming language (using ctypes).
|
8
|
+
#
|
9
|
+
# @see https://docs.python.org/3/library/ctypes.html
|
10
|
+
class Python < FFIDB::Exporter
|
11
|
+
TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/python.yaml", __dir__)))
|
12
|
+
.freeze
|
13
|
+
|
14
|
+
def finish
|
15
|
+
puts self.render_template('python.erb')
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
##
|
21
|
+
# @param [FFIDB::Type] c_type
|
22
|
+
# @return [#to_s]
|
23
|
+
def param_type(c_type)
|
24
|
+
case
|
25
|
+
when c_type.enum? then 'ctypes.c_int'
|
26
|
+
when c_type.array? then [self.param_type(c_type.array_type), '*', c_type.array_size].join(' ')
|
27
|
+
else case py_type = TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
|
28
|
+
when 'None' then py_type
|
29
|
+
else "ctypes.#{py_type}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
alias_method :struct_type, :param_type
|
34
|
+
end # Python
|
35
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the Ruby programming language (using FFI).
|
8
|
+
#
|
9
|
+
# @see https://github.com/ffi/ffi/wiki
|
10
|
+
class Ruby < FFIDB::Exporter
|
11
|
+
TYPE_MAP = ::YAML.load(File.read(File.expand_path("../../../etc/mappings/ruby.yaml", __dir__)))
|
12
|
+
.transform_values(&:to_sym)
|
13
|
+
.freeze
|
14
|
+
|
15
|
+
def finish
|
16
|
+
puts self.render_template('ruby.erb')
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param [FFIDB::Type] c_type
|
23
|
+
# @return [#inspect]
|
24
|
+
def param_type(c_type)
|
25
|
+
case
|
26
|
+
when c_type.enum? then :int
|
27
|
+
when c_type.array? then [self.param_type(c_type.array_type), c_type.array_size]
|
28
|
+
else TYPE_MAP[c_type.to_s] || TYPE_MAP['void *']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias_method :struct_type, :param_type
|
32
|
+
end # Ruby
|
33
|
+
end # FFIDB::Exporters
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
require_relative '../exporter'
|
4
|
+
|
5
|
+
module FFIDB::Exporters
|
6
|
+
##
|
7
|
+
# Code generator for the YAML markup language.
|
8
|
+
class YAML < FFIDB::Exporter
|
9
|
+
def begin
|
10
|
+
puts "# #{FFIDB.header}" if self.header?
|
11
|
+
puts if self.header?
|
12
|
+
end
|
13
|
+
|
14
|
+
def begin_library(library) end
|
15
|
+
|
16
|
+
def export_symbol(symbol, **kwargs)
|
17
|
+
@counter ||= 0
|
18
|
+
puts unless @counter.zero?
|
19
|
+
puts "# #{symbol.instance_variable_get(:@debug)}" if self.debug? && symbol.instance_variable_get(:@debug)
|
20
|
+
puts symbol.to_yaml
|
21
|
+
@counter += 1
|
22
|
+
end
|
23
|
+
alias_method :export_typedef, :export_symbol
|
24
|
+
alias_method :export_enum, :export_symbol
|
25
|
+
alias_method :export_struct, :export_symbol
|
26
|
+
alias_method :export_union, :export_symbol
|
27
|
+
alias_method :export_function, :export_symbol
|
28
|
+
|
29
|
+
def finish_library() end
|
30
|
+
end # YAML
|
31
|
+
end # FFIDB::Exporters
|