Parent

FFI::ConstGenerator

ConstGenerator turns C constants into ruby values.

Attributes

constants[R]

Public Class Methods

new(prefix = nil, options = {}) click to toggle source

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.

When passed a block, # is automatically called at the end of the block, otherwise you must call it yourself.

    # File lib/ffi/tools/const_generator.rb, line 23
23:     def initialize(prefix = nil, options = {})
24:       @includes = []
25:       @constants = {}
26:       @prefix = prefix
27: 
28:       @required = options[:required]
29:       @options = options
30: 
31:       if block_given? then
32:         yield self
33:         calculate self.class.options.merge(options)
34:       end
35:     end
options() click to toggle source
    # File lib/ffi/tools/const_generator.rb, line 39
39:     def self.options
40:       @options
41:     end
options=(options) click to toggle source
    # File lib/ffi/tools/const_generator.rb, line 36
36:     def self.options=(options)
37:       @options = options
38:     end

Public Instance Methods

[](name) click to toggle source
    # File lib/ffi/tools/const_generator.rb, line 42
42:     def [](name)
43:       @constants[name].value
44:     end
calculate(options = {}) click to toggle source
     # File lib/ffi/tools/const_generator.rb, line 69
 69:     def calculate(options = {})
 70:       binary = File.join Dir.tmpdir, "rb_const_gen_bin_#{Process.pid}"
 71: 
 72:       Tempfile.open("#{@prefix}.const_generator") do |f|
 73:         f.puts "#include <stdio.h>"
 74: 
 75:         @includes.each do |inc|
 76:           f.puts "#include <#{inc}>"
 77:         end
 78: 
 79:         f.puts "#include <stddef.h>\n\n"
 80:         f.puts "int main(int argc, char **argv)\n{"
 81: 
 82:         @constants.each_value do |const|
 83:           f.puts   #ifdef #{const.name}  printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name});  #endif
 84:         end
 85: 
 86:         f.puts "\n\treturn 0;\n}"
 87:         f.flush
 88: 
 89:         output = `gcc #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -x c -Wall -Werror #{f.path} -o #{binary} 2>&1`
 90: 
 91:         unless $?.success? then
 92:           output = output.split("\n").map { |l| "\t#{l}" }.join "\n"
 93:           raise "Compilation error generating constants #{@prefix}:\n#{output}"
 94:         end
 95:       end
 96: 
 97:       output = `#{binary}`
 98:       File.unlink(binary + (FFI::Platform.windows? ? ".exe" : ""))
 99:       output.each_line do |line|
100:         line =~ /^(\S+)\s(.*)$/
101:         const = @constants[$1]
102:         const.value = $2
103:       end
104: 
105:       missing_constants = @constants.select do |name, constant|
106:         constant.value.nil?
107:       end.map { |name,| name }
108: 
109:       if @required and not missing_constants.empty? then
110:         raise "Missing required constants for #{@prefix}: #{missing_constants.join ', '}"
111:       end
112:     end
const(name, format = nil, cast = '', ruby_name = nil, converter = nil, &converter_proc) click to toggle source

Request the value for C constant name. format is a printf format string to print the value out, and cast is a C cast for the value. ruby_name allows you to give the constant an alternate ruby name for #. converter or converter_proc allow you to convert the value from a string to the appropriate type for #.

    # File lib/ffi/tools/const_generator.rb, line 53
53:     def const(name, format = nil, cast = '', ruby_name = nil, converter = nil,
54:               &converter_proc)
55:       format ||= '%d'
56:       cast ||= ''
57: 
58:       if converter_proc and converter then
59:         raise ArgumentError, "Supply only converter or converter block"
60:       end
61: 
62:       converter = converter_proc if converter.nil?
63: 
64:       const = Constant.new name, format, cast, ruby_name, converter
65:       @constants[name.to_s] = const
66:       return const
67:     end
dump_constants(io) click to toggle source
     # File lib/ffi/tools/const_generator.rb, line 118
118:     def dump_constants(io)
119:       @constants.each do |name, constant|
120:         name = [@prefix, name].join '.'
121:         io.puts "#{name} = #{constant.converted_value}"
122:       end
123:     end
include(i) click to toggle source
     # File lib/ffi/tools/const_generator.rb, line 139
139:     def include(i)
140:       @includes << i
141:     end
to_ruby() click to toggle source

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 129
129:     def to_ruby
130:       @constants.sort_by { |name,| name }.map do |name, constant|
131:         if constant.value.nil? then
132:           "# #{name} not available"
133:         else
134:           constant.to_ruby
135:         end
136:       end.join "\n"
137:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.