### Home Classes Methods

### In Files

- lib/ffi/tools/const_generator.rb

### Parent

Object

### Namespace

- CLASS FFI::ConstGenerator::Constant

### Methods

- ::new
- ::options
- ::options=
- #[]
- #calculate
- #const
- #dump_constants
- #include
- #to_ruby

### Files

- History.txt
- README.rdoc

### Class/Module Index

Quicksearch

- FFI
- FFI::AutoPointer
- FFI::AutoPointer::CallableReleaser
- FFI::AutoPointer::DefaultReleaser
- FFI::AutoPointer::Releaser
- FFI::ConstGenerator
- FFI::ConstGenerator::Constant
- FFI::Enum
- FFI::Enums
- FFI::Generator
- FFI::Generator::Task
- FFI::IO
- FFI::Library
- FFI::ManagedStruct
- FFI::NotFoundError
- FFI::Platform
- FFI::PlatformError
- FFI::Pointer
- FFI::StrPtrConverter
- FFI::Struct
- FFI::Struct::ManagedStructConverter
- FFI::StructGenerator
- FFI::StructGenerator::Field
- FFI::StructLayout
- FFI::StructLayout::Enum
- FFI::StructLayout::InnerStruct
- FFI::StructLayout::Mapped
- FFI::StructLayoutBuilder
- FFI::TypesGenerator
- FFI::Union
- FFI::VariadicInvoker

No matching classes.

# FFI::ConstGenerator

ConstGenerator turns C constants into ruby values.

@example a simple example for stdio

    cg = FFI::ConstGenerator.new('stdio') do |gen|
      gen.const(:SEEK_SET)
      gen.const('SEEK_CUR')
      gen.const('seek_end')   # this constant does not exist
    end            # #calculate called automatically at the end of the block

    cg['SEEK_SET'] # => 0
    cg['SEEK_CUR'] # => 1
    cg['seek_end'] # => nil
    cg.to_ruby     # => "SEEK_SET = 0\nSEEK_CUR = 1\n# seek_end not available"

### 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.

@param [to_s] prefix @param [Hash] options @return @option options [Boolean] :required @overload initialize(prefix, options) @overload initialize(prefix, options) { |gen| … }

    @yieldparam [ConstGenerator] gen new generator is passed to the block
    When passed a block, {#calculate} is automatically called at the end of
    the block, otherwise you must call it yourself.

    # File lib/ffi/tools/const_generator.rb, line 38
    def initialize(prefix = nil, options = {})
      @includes = ['stdio.h', 'stddef.h']
      @constants = {}
      @prefix = prefix

      @required = options[:required]
      @options = options

      if block_given? then
        yield self
        calculate self.class.options.merge(options)
      end
    end

options() click to toggle source

Get class options. @return [Hash] class options

    # File lib/ffi/tools/const_generator.rb, line 60
    def self.options
      @options
    end

options=(options) click to toggle source

Set class options These options are merged with {initialize} options when it is called with a block. @param [Hash] options @return [Hash] class options

    # File lib/ffi/tools/const_generator.rb, line 55
    def self.options=(options)
      @options = options
    end

### Public Instance Methods

[](name) click to toggle source

@param [String] name @return constant value (converted if a `converter` was defined). Access a constant by name.

    # File lib/ffi/tools/const_generator.rb, line 66
    def [](name)
      @constants[name].converted_value
    end

calculate(options = {}) click to toggle source

Calculate constants values. @param [Hash] options @option options [String] :cppflags flags for C compiler @return [nil] @raise if a constant is missing and `:required` was set to `true` (see {initialize})

    # File lib/ffi/tools/const_generator.rb, line 106
    def calculate(options = {})
      binary = File.join Dir.tmpdir, "rb_const_gen_bin_#{Process.pid}"

      Tempfile.open("#{@prefix}.const_generator") do |f|
        @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   #ifdef #{const.name}  printf("#{const.name} #{const.format}\\n", #{const.cast}#{const.name});  #endif
        end

        f.puts "\n\treturn 0;\n}"
        f.flush

        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`

        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}`
      File.unlink(binary + (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, &converter_proc) click to toggle source

Request the value for C constant `name`.

@param [to_s] name C constant name @param [String] format a printf format string to print the value out @param [String] cast a C cast for the value @param ruby_name alternate ruby name for {to_ruby}

@overload const(name, format=nil, cast=”, ruby_name=nil, converter=nil)

    +converter+ is a Method or a Proc.
    @param [#call] converter convert the value from a string to the appropriate
     type for {#to_ruby}.

@overload const(name, format=nil, cast=”, ruby_name=nil) { |value| … }

    Use a converter block. This block convert the value from a string to the
    appropriate type for {#to_ruby}.
    @yieldparam value constant value

    # File lib/ffi/tools/const_generator.rb, line 85
    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) click to toggle source

Dump constants to `io`. @param [puts] io @return [nil]

    # File lib/ffi/tools/const_generator.rb, line 154
    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) click to toggle source

Add additional C include file(s) to calculate constants from. @note `stdio.h` and `stddef.h` automatically included @param [List<String>, Array<String>] i include file(s) @return [Array<String>] array of include files

    # File lib/ffi/tools/const_generator.rb, line 178
    def include(*i)
      @includes |= i.flatten
    end

to_ruby() click to toggle source

Outputs values for discovered constants. If the constant’s value was not discovered it is not omitted. @return [String]

    # File lib/ffi/tools/const_generator.rb, line 164
    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

[Validate]

Generated with the Darkfish Rdoc Generator 2.