Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 1f16933ab8
Fetching contributors…

Cannot retrieve contributors at this time

118 lines (99 sloc) 3.596 kb
require 'ffi'
require 'ffi/tools/const_generator'
require 'ffi/tools/struct_generator'
require 'set'
desc 'Regenerate ffi_autogen.rb'
task :ffi_header do
XDo::Tasks.generate_ffi_header
end
# :nodoc: namespace
module XDo
module Tasks
def self.resolve_constants(pattern, format)
if FFI::Platform.mac?
header_path = '/System/Library/Frameworks/PCSC.framework/Headers/'
else
header_path = '/usr/include/'
end
headers = Dir.glob(header_path + 'xdo*.h').map { |f| File.basename f }
consts = Set.new
headers.each do |header|
contents = File.read("#{header_path}#{header}")
contents.each_line do |line|
tokens = line.split
next unless tokens[0] == '#define'
next if tokens[1].index '('
consts << tokens[1] if pattern =~ tokens[1]
end
contents.scan /enum\s*\{([^}]*)\}/ do |match|
match[0].split(',').each do |enum_item|
enum_name = enum_item.split('=').first.strip
consts << enum_name if pattern =~ enum_name
end
end
end
const_gen = FFI::ConstGenerator.new(nil,
:cppflags => "-w -I#{header_path}") do |g|
headers.each { |header| g.include header }
consts.each { |const| g.const const, format }
end
const_gen.constants
end
def self.output_constants(constants, f)
constants.each do |name, const|
value = const.to_ruby
value += 'nil' if value.strip[-1] == ?=
f.write " #{value}\n"
end
end
def self.output_enum(enum_name, constants, name_regexp, f)
f.write " #{enum_name} = enum [\n"
re = Regexp.new('^' + name_regexp + '$')
constants.each do |name, const|
ruby_name = re.match(name)[1]
f.write " :#{ruby_name.downcase}, Consts::#{name},\n"
end
f.write " ]\n"
end
def self.generate_ffi_header
File.open('lib/x_do/ffi_autogen.rb', 'wb') do |f|
f.write "# Automatically generated by tasks/ffi_codegen.rb\n\n"
# Return codes.
stat_consts = resolve_constants(/^XDO_.*$/, '%d')
# Search flags.
search_consts = resolve_constants(/^SEARCH_/, '0x%04X')
# Window sizing flags.
sizing_consts = resolve_constants(/^SIZE_/, '%d')
# Search direction.
direction_consts = resolve_constants(/^XDO_FIND_/, '%d')
stat_consts.delete_if { |k, v| direction_consts[k] }
# Features.
feature_consts = resolve_constants(/^XDO_FEATURE_/, '%d')
stat_consts.delete_if { |k, v| feature_consts[k] }
f.write "# :nodoc: namespace\n"
f.write "class XDo\n\n"
f.write "# :nodoc: namespace\n"
f.write "module FFILib\n"
f.write " # Constant values extracted from headers.\n"
f.write " module Consts\n"
output_constants stat_consts, f
output_constants search_consts, f
output_constants sizing_consts, f
output_constants direction_consts, f
output_constants feature_consts, f
f.write " end # module XDo::FFILib::Consts\n\n"
f.write " # Status returned by libxdo functions.\n"
output_enum 'Status', stat_consts, 'XDO_(.*)', f
f.write "\n"
f.write " # Search directions.\n"
output_enum 'Direction', direction_consts, 'XDO_FIND_(.*)', f
f.write "\n"
f.write " # Optional features.\n"
output_enum 'Feature', feature_consts, 'XDO_FEATURE_(.*)', f
f.write "\n"
f.write "end # namespace XDo::FFILib\n"
f.write "end # namespace XDo\n"
end
end
end # namespace XDo::Tasks
end # namespace XDo
Jump to Line
Something went wrong with that request. Please try again.