Class: FFI::ConstGenerator
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | lib/ffi/tools/const_generator.rb |
Overview
ConstGenerator
turns C constants into ruby values.
Class Attribute Summary
-
.options ⇒ Hash
rw
Get class options.
-
.options=(options) ⇒ Hash
rw
Set class options These options are merged with
#initialize
options when it is called with a block.
Class Method Summary
-
.new(prefix, options) ⇒ Object
constructor
Creates a new constant generator that uses
prefix
as a name, and an options hash.
Instance Attribute Summary
- #constants readonly
Instance Method Summary
-
#[](name) ⇒ Object
Access a constant by name.
-
#calculate(options = {}) ⇒ nil
Calculate constants values.
-
#const(name, format = nil, cast = '', ruby_name = nil, converter = nil)
Request the value for C constant
name
. -
#dump_constants(io) ⇒ nil
Dump constants to
io
. -
#include(*i) ⇒ Array<String>
Add additional C include file(s) to calculate constants from.
-
#to_ruby ⇒ String
Outputs values for discovered constants.
Constructor Details
Creates a new constant generator that uses prefix
as a name, and an options hash.
The only option is :required
, which if set to true
raises an error if a constant you have requested was not found.
# File 'lib/ffi/tools/const_generator.rb', line 39
def initialize(prefix = nil, = {}) @includes = ['stdio.h', 'stddef.h'] @constants = {} @prefix = prefix @required = [:required] @options = if block_given? then yield self calculate self.class. .merge( ) end end
Class Attribute Details
.options ⇒ Hash
(rw)
Get class options.
# File 'lib/ffi/tools/const_generator.rb', line 61
def self. @options end
.options=(options) ⇒ Hash
(rw)
Set class options These options are merged with #initialize
options when it is called with a block.
# File 'lib/ffi/tools/const_generator.rb', line 56
def self. ( ) @options = end
Instance Attribute Details
#constants (readonly)
[ GitHub ]# File 'lib/ffi/tools/const_generator.rb', line 22
attr_reader :constants
Instance Method Details
#[](name) ⇒ Object
Access a constant by name.
# File 'lib/ffi/tools/const_generator.rb', line 67
def [](name) @constants[name].converted_value end
#calculate(options = {}) ⇒ nil
Calculate constants values.
# File 'lib/ffi/tools/const_generator.rb', line 107
def calculate( = {}) binary_path = nil Tempfile.open("#{@prefix}.const_generator") do |f| binary_path = f.path + ".bin" @includes.each do |inc| f.puts "#include <#{inc}>" end f.puts "\nint main(int argc, char **argv)\n{" @constants.each_value do |const| f.puts <<-EOF #ifdef #{const.name} printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name}); #endif EOF end f.puts "\n\treturn 0;\n}" f.flush cc = ENV['CC'] || 'gcc' output = `#{cc} #{ [:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary_path} 2>&1` unless $?.success? then output = output.split("\n").map { |l| "\t#{l}" }.join "\n" raise "Compilation error generating constants #{@prefix}:\n#{output}" end end output = `#{binary_path}` File.unlink(binary_path + (FFI::Platform.windows? ? ".exe" : "")) output.each_line do |line| line =~ /^(\S+)\s(.*)$/ const = @constants[$1] const.value = $2 end missing_constants = @constants.select do |name, constant| constant.value.nil? end.map { |name,| name } if @required and not missing_constants.empty? then raise "Missing required constants for #{@prefix}: #{missing_constants.join ', '}" end end
#const(name, format = nil, cast = '', ruby_name = nil, converter = nil)
#const(name, format=nil, cast='', ruby_name=nil) { |value| ... }) {|value| ... }
Request the value for C constant name
.
# File 'lib/ffi/tools/const_generator.rb', line 86
def const(name, format = nil, cast = '', ruby_name = nil, converter = nil, &converter_proc) format ||= '%d' cast ||= '' if converter_proc and converter then raise ArgumentError, "Supply only converter or converter block" end converter = converter_proc if converter.nil? const = Constant.new name, format, cast, ruby_name, converter @constants[name.to_s] = const return const end
#dump_constants(io) ⇒ nil
Dump constants to io
.
# File 'lib/ffi/tools/const_generator.rb', line 157
def dump_constants(io) @constants.each do |name, constant| name = [@prefix, name].join '.' if @prefix io.puts "#{name} = #{constant.converted_value}" end end
#include(*i) ⇒ Array
<String
>
stdio.h
and stddef.h
automatically included
Add additional C include file(s) to calculate constants from.
# File 'lib/ffi/tools/const_generator.rb', line 181
def include(*i) @includes |= i.flatten end
#to_ruby ⇒ String
Outputs values for discovered constants. If the constant’s value was not discovered it is not omitted.
# File 'lib/ffi/tools/const_generator.rb', line 167
def to_ruby @constants.sort_by { |name,| name }.map do |name, constant| if constant.value.nil? then "# #{name} not available" else constant.to_ruby end end.join "\n" end