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,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
|