class FFIDB::Exporter
Attributes
options[R]
Public Class Methods
for(format)
click to toggle source
# File lib/ffidb/exporter.rb, line 9 def self.for(format) # TODO require_relative 'exporters' case format&.to_sym when :c, :c99, :c11, :c18 then Exporters::C when :'c++', :'c++11', :'c++14', :'c++17', :'c++20', :cpp, :cxx then Exporters::Cpp when :csv then Exporters::CSV when :dart, :flutter then Exporters::Dart when :go, :cgo then Exporters::Go when :java, :jna then Exporters::Java when :json then Exporters::JSON when :lisp, :'common-lisp' then Exporters::Lisp when :python, :py then Exporters::Python when :ruby, :rb then Exporters::Ruby # TODO: csharp, haskell, julia, luajit, nim, nodejs, ocaml, php, racket, rust, zig when :yaml then Exporters::YAML else raise "unknown output format: #{format}" end end
new(stream = $stdout, **kwargs)
click to toggle source
# File lib/ffidb/exporter.rb, line 30 def initialize(stream = $stdout, **kwargs) @stream = stream @options = kwargs.transform_keys(&:to_sym).freeze end
Public Instance Methods
begin()
click to toggle source
# File lib/ffidb/exporter.rb, line 65 def begin() end
begin_library(library)
click to toggle source
# File lib/ffidb/exporter.rb, line 67 def begin_library(library) @library = library @libraries ||= [] @libraries << library @typedefs ||= {} @enums ||= {} @structs ||= {} @unions ||= {} @functions ||= {} end
close()
click to toggle source
# File lib/ffidb/exporter.rb, line 117 def close() end
debug?()
click to toggle source
# File lib/ffidb/exporter.rb, line 35 def debug? self.options[:debug] end
dlopen_paths_for(library)
click to toggle source
# File lib/ffidb/exporter.rb, line 57 def dlopen_paths_for(library) if library_path = self.options[:library_path] library.objects.map { |lib| library_path.delete_suffix('/') << "/" << lib } else library.objects + library.dlopen end end
emit() { |self| ... }
click to toggle source
# File lib/ffidb/exporter.rb, line 47 def emit(&block) begin self.begin yield self self.finish ensure self.close end end
export_enum(enum, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 95 def export_enum(enum, disabled: nil) (@enums[@library] ||= []) << enum end
export_function(function, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 107 def export_function(function, disabled: nil) (@functions[@library] ||= []) << self.resolve_function(function) end
export_header(header)
click to toggle source
# File lib/ffidb/exporter.rb, line 78 def export_header(header) header.typedefs.sort.each { |typedef| self.export_typedef(typedef) } header.enums.sort.each { |enum| self.export_enum(enum) } header.structs.sort.each { |struct| self.export_struct(struct) } header.unions.sort.each { |union| self.export_union(union) } header.functions.sort.each { |function| self.export_function(function) } end
export_struct(struct, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 99 def export_struct(struct, disabled: nil) (@structs[@library] ||= []) << self.resolve_struct(struct) end
export_symbol(symbol, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 86 def export_symbol(symbol, disabled: nil) self.__send__("export_#{symbol.kind}", symbol, disabled: disabled) end
export_typedef(typedef, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 90 def export_typedef(typedef, disabled: nil) @typedefs[@library] ||= {} @typedefs[@library][typedef.name] = typedef end
export_union(union, disabled: nil)
click to toggle source
# File lib/ffidb/exporter.rb, line 103 def export_union(union, disabled: nil) (@unions[@library] ||= []) << self.resolve_union(union) end
finish()
click to toggle source
# File lib/ffidb/exporter.rb, line 115 def finish() end
finish_library()
click to toggle source
# File lib/ffidb/exporter.rb, line 111 def finish_library @library = nil end
header?()
click to toggle source
# File lib/ffidb/exporter.rb, line 43 def header? self.options[:header] end
verbose?()
click to toggle source
# File lib/ffidb/exporter.rb, line 39 def verbose? self.options[:verbose] || self.debug? end
Protected Instance Methods
format_comment(comment, prefix)
click to toggle source
@param [String] comment @param [String] prefix @return [String]
# File lib/ffidb/exporter.rb, line 133 def format_comment(comment, prefix) prefix = prefix + ' ' comment.each_line.map(&:strip).map { |s| s.prepend(prefix) }.join("\n") end
load_template(template_name)
click to toggle source
# File lib/ffidb/exporter.rb, line 242 def load_template(template_name) File.read(self.path_to_template(template_name)).freeze end
load_typemap(typemap_name)
click to toggle source
# File lib/ffidb/exporter.rb, line 229 def load_typemap(typemap_name) ::YAML.load(File.read(self.path_to_typemap(typemap_name))).freeze end
lookup_symbol(type)
click to toggle source
@param [Type] type @return [Symbolic]
# File lib/ffidb/exporter.rb, line 190 def lookup_symbol(type) self.lookup_typedef(type.name) end
lookup_typedef(type_name)
click to toggle source
@param [Symbol] type_name @return [Typedef]
# File lib/ffidb/exporter.rb, line 197 def lookup_typedef(type_name) @typedefs && @typedefs[@library] && @typedefs[@library][type_name] end
param_type(c_type)
click to toggle source
@param [Symbol, Type] c_type @return [#to_s]
# File lib/ffidb/exporter.rb, line 212 def param_type(c_type) return c_type if c_type.is_a?(Symbol) # a resolved typedef case when type = typemap[c_type.to_s] then type when c_type.enum? then typemap['int'] when c_type.pointer? then typemap['void *'] when c_type.array? then typemap['void *'] else warn "#{$0}: unknown C type #{c_type}, mapping to enum (int)" if debug? typemap['int'] # TODO: typedef or enum end end
path_to_template(template_name)
click to toggle source
# File lib/ffidb/exporter.rb, line 246 def path_to_template(template_name) File.expand_path("../../etc/templates/#{template_name}", __dir__) end
path_to_typemap(typemap_name)
click to toggle source
# File lib/ffidb/exporter.rb, line 233 def path_to_typemap(typemap_name) File.expand_path("../../etc/mappings/#{typemap_name}", __dir__) end
print(*args)
click to toggle source
# File lib/ffidb/exporter.rb, line 125 def print(*args) @stream.print *args end
puts(*args)
click to toggle source
# File lib/ffidb/exporter.rb, line 121 def puts(*args) @stream.puts *args end
render_template(template_name)
click to toggle source
# File lib/ffidb/exporter.rb, line 237 def render_template(template_name) #ERB.new(self.load_template(template_name)).result(binding) Tilt.new(self.path_to_template(template_name)).render(self) end
resolve_function(function)
click to toggle source
@param [Function] function @feturn [Function]
# File lib/ffidb/exporter.rb, line 141 def resolve_function(function) function.type = self.resolve_type(function.type) function.parameters.transform_values! do |param| param.type = self.resolve_type(param.type) param end function end
resolve_struct(struct)
click to toggle source
@param [Struct] struct @feturn [Struct]
# File lib/ffidb/exporter.rb, line 153 def resolve_struct(struct) struct.fields.each do |field_name, field_type| struct.fields[field_name] = self.resolve_type(field_type) end struct end
resolve_type(type)
click to toggle source
@param [Type] type @return [Type, Symbol]
# File lib/ffidb/exporter.rb, line 170 def resolve_type(type) case when type.struct_pointer? name = type.spec.gsub(/^const /, '').gsub(/^struct /, '').gsub(/\s*\*+$/, '') name.to_sym when type.struct? || type.union? type when typedef = lookup_typedef(type.name) case typedef.type.tag when :enum then type.name.to_sym when :struct then (type.pointer? ? type.name : "#{type.name}.by_value").to_sym # FIXME else typedef.type end else type end end
resolve_union(union)
click to toggle source
@param [Union] union @feturn [Union]
# File lib/ffidb/exporter.rb, line 163 def resolve_union(union) self.resolve_struct(union) end
struct_type(c_type)
click to toggle source
@param [Symbol, Type] c_type @return [#to_s]
# File lib/ffidb/exporter.rb, line 204 def struct_type(c_type) return c_type if c_type.is_a?(Symbol) # a resolved typedef self.param_type(c_type) end
typemap()
click to toggle source
# File lib/ffidb/exporter.rb, line 225 def typemap @typemap ||= self.load_typemap(self.class.const_get(:TYPE_MAP)) end