Skip to content

Commit

Permalink
Reworked FFI generators.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen authored and Brian Ford committed Feb 27, 2011
1 parent 11d8e4b commit 0db919c
Show file tree
Hide file tree
Showing 12 changed files with 767 additions and 583 deletions.
172 changes: 0 additions & 172 deletions lib/ffi/const_generator.rb

This file was deleted.

87 changes: 87 additions & 0 deletions lib/ffi/file_processor.rb
@@ -0,0 +1,87 @@
require File.expand_path('../generators', __FILE__)

module FFI

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

class FileProcessor

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

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

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

##
# Utility converter for constants

def to_s
proc { |obj| obj.to_s.inspect }
end
end
end
56 changes: 5 additions & 51 deletions lib/ffi/generator.rb
@@ -1,58 +1,12 @@
require File.expand_path('../file_processor', __FILE__)

module FFI
class Generator

def initialize(ffi_name, rb_name)
@ffi_name = ffi_name
@rb_name = rb_name

@name = File.basename rb_name, '.rb'

file = File.read @ffi_name

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

indent = $1
original_lines = $2.count "\n"

instance_eval $2

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

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

padding = original_lines - new_lines.length
new_lines += [nil] * padding if padding >= 0
STDERR.puts "FFI::Generator is deprecated. Use FFI::FileProcessor"
STDERR.puts "Called from: #{caller(1).first}"

new_lines.join "\n"
end

open @rb_name, 'w' do |f|
f.puts "# This file is generated by rake. Do not edit."
f.puts
f.puts new_file
end
end

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

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

##
# Utility converter for constants

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

end
end

0 comments on commit 0db919c

Please sign in to comment.