/usr/lib/ruby/vendor_ruby/ffi/tools/types_generator.rb is in ruby-ffi 1.0.11debian-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | require 'tempfile'
module FFI
class TypesGenerator
##
# Maps different C types to the C type representations we use
TYPE_MAP = {
"char" => :char,
"signed char" => :char,
"__signed char" => :char,
"unsigned char" => :uchar,
"short" => :short,
"signed short" => :short,
"signed short int" => :short,
"unsigned short" => :ushort,
"unsigned short int" => :ushort,
"int" => :int,
"signed int" => :int,
"unsigned int" => :uint,
"long" => :long,
"long int" => :long,
"signed long" => :long,
"signed long int" => :long,
"unsigned long" => :ulong,
"unsigned long int" => :ulong,
"long unsigned int" => :ulong,
"long long" => :long_long,
"long long int" => :long_long,
"signed long long" => :long_long,
"signed long long int" => :long_long,
"unsigned long long" => :ulong_long,
"unsigned long long int" => :ulong_long,
"char *" => :string,
"void *" => :pointer,
}
def self.generate(options = {})
typedefs = nil
Tempfile.open 'ffi_types_generator' do |io|
io.puts <<-C
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
C
io.close
typedefs = `gcc -E -x c #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c #{io.path}`
end
code = ""
typedefs.each_line do |type|
# We only care about single line typedef
next unless type =~ /typedef/
# Ignore unions or structs
next if type =~ /union|struct/
# strip off the starting typedef and ending ;
type.gsub!(/^(.*typedef\s*)/, "")
type.gsub!(/\s*;\s*$/, "")
parts = type.split(/\s+/)
def_type = parts.join(" ")
# GCC does mapping with __attribute__ stuf, also see
# http://hal.cs.berkeley.edu/cil/cil016.html section 16.2.7. Problem
# with this is that the __attribute__ stuff can either occur before or
# after the new type that is defined...
if type =~ /__attribute__/
if parts.last =~ /__QI__|__HI__|__SI__|__DI__|__word__/
# In this case, the new type is BEFORE __attribute__ we need to
# find the final_type as the type before the part that starts with
# __attribute__
final_type = ""
parts.each do |p|
break if p =~ /__attribute__/
final_type = p
end
else
final_type = parts.pop
end
def_type = case type
when /__QI__/ then "char"
when /__HI__/ then "short"
when /__SI__/ then "int"
when /__DI__/ then "long long"
when /__word__/ then "long"
else "int"
end
def_type = "unsigned #{def_type}" if type =~ /unsigned/
else
final_type = parts.pop
def_type = parts.join(" ")
end
if type = TYPE_MAP[def_type]
code << "rbx.platform.typedef.#{final_type} = #{type}\n"
TYPE_MAP[final_type] = TYPE_MAP[def_type]
else
# Fallback to an ordinary pointer if we don't know the type
if def_type =~ /\*/
code << "rbx.platform.typedef.#{final_type} = pointer\n"
TYPE_MAP[final_type] = :pointer
end
end
end
code
end
end
end
|