Class: FFI::FileProcessor

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi2/generators/file_processor.rb

Overview

Processes a file containing Ruby code with blocks of FFI definitions delimited by @@@. The blocks are replaced with Ruby code produced by running the FFI generators contained in the blocks. For example:

module Something
  @@@
  constants do |c|
    c.include 'somefile.h'

    c.const 'MAX'
    c.const 'MIN'
  end
  @@@
end

would be converted to:

module Something
  MAX = 1
  MIN = 2
end

assuming that

#define MAX 1
#define MIN 2

was contained in the file ‘something.h’.

Instance Method Summary collapse

Constructor Details

#initialize(ffi_name, rb_name) ⇒ FileProcessor

Returns a new instance of FileProcessor.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ffi2/generators/file_processor.rb', line 34

def initialize(ffi_name, rb_name)
  @name = File.basename rb_name, '.rb'

  definitions = File.read ffi_name

  replacement = definitions.gsub(/^( *)@@@(.*?)@@@/m) do
    @constants = []
    @structs = []

    indent = $1
    line_count = $2.count("\n") + 1

    instance_eval $2

    lines = []
    @constants.each { |c| lines << c.to_ruby }
    @structs.each { |s| lines << s.generate_layout }

    # expand multiline blocks
    lines = lines.join("\n").split "\n"
    lines = lines.map { |line| indent + line }

    # preserve source line numbers in output
    padding = line_count - lines.length
    lines += [nil] * padding if padding >= 0

    lines.join "\n"
  end

  File.open rb_name, 'wb' do |f|
    f.puts "# This file is generated #{self.class} from #{ffi_name}."
    f.puts
    f.puts replacement
  end
end

Instance Method Details

#constants(options = {}, &block) ⇒ Object



70
71
72
# File 'lib/ffi2/generators/file_processor.rb', line 70

def constants(options={}, &block)
  @constants << FFI::ConstGenerator.new(@name, options, &block)
end

#struct(&block) ⇒ Object



74
75
76
# File 'lib/ffi2/generators/file_processor.rb', line 74

def struct(&block)
  @structs << FFI::StructGenerator.new(@name, &block)
end

#to_sObject

Utility converter for constants



81
82
83
# File 'lib/ffi2/generators/file_processor.rb', line 81

def to_s
  proc { |obj| obj.to_s.inspect }
end