Class: FFI::EnumGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/enum_generator.rb

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ EnumGenerator

Creates a new enum generator.

You probably don’t want to instantiate one of these directly. Take a look at Library.generate_enum instead.

Yields:

  • (_self)

Yield Parameters:



61
62
63
64
65
66
# File 'lib/ffi/enum_generator.rb', line 61

def initialize
  @includes = ["stdio.h"]
  @enum_symbols = {}

  yield self if block_given?
end

Instance Method Details

#generateArray

Generate an array of enum symbols and values.

You probably don’t ever want to call this yourself. We use it to feed the enum creation code.

Returns:

  • (Array)

    Alternating symbols and values for the new enum.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/ffi/enum_generator.rb', line 103

def generate
  binary = File.join Dir.tmpdir, "rb_ffi_enum_gen_bin_#{Process.pid}"

  Tempfile.open("#{@name}.enum_generator") do |f|
    @includes.each do |inc|
      f.puts "#include <#{inc}>"
    end
    f.puts "\nint main(void)\n{"

    @enum_symbols.each do |name, ruby_name|
      f.puts "        printf(\"\#{ruby_name} %d\\\\n\", \#{name});\n      EOF\n    end\n\n    f.puts \"\\n\\treturn 0;\\n}\"\n    f.flush\n\n    output = `gcc -x c -Wall -Werror \#{f.path} -o \#{binary} 2>&1`\n\n    unless $?.success? then\n      output = output.split(\"\\n\").map { |l| \"\\t\#{l}\" }.join \"\\n\"\n      raise \"Compilation error generating constants \#{@prefix}:\\n\#{output}\"\n    end\n  end\n\n  output = `\#{binary}`\n  File.unlink(binary + (FFI::Platform.windows? ? \".exe\" : \"\"))\n  output.split(\"\\n\").inject([]) do |a, l|\n    l =~ /^(\\S+)\\s(.*)$/\n    a += [$1.to_sym, Integer($2)]\n  end\nend\n".gsub(/^\t{6}/, '')

#include(*i) ⇒ Array<String>

Add additional C include file(s) to use to lookup the enum values.

You should use this method to add the .h files needed to fully define the enum(s) you wish to extract values from.

Parameters:

  • i (List<String>, Array<String>)

    The additional file(s) to include.

Returns:

  • (Array<String>)

    The complete array of included files.



92
93
94
# File 'lib/ffi/enum_generator.rb', line 92

def include(*i)
  @includes += i.flatten
end

#symbol(name, ruby_name = nil) ⇒ Object

Add a symbolic value to the enum.

Parameters:

  • name (#to_s)

    The name of the enum value to lookup.

  • ruby_name (#to_sym) (defaults to: nil)

    The name that the enum value will have inside the Ruby enum. This is useful to remove namespacing prefixes that are unnecessary in Ruby, or to make the symbols more pleasing to the eye (camel-casing, for instance).



77
78
79
80
# File 'lib/ffi/enum_generator.rb', line 77

def symbol(name, ruby_name = nil)
  ruby_name ||= name
  @enum_symbols[name] = ruby_name
end