Parent

Methods

FFI::TypesGenerator

Constants

TYPE_MAP

Maps different C types to the C type representations we use

Public Class Methods

generate(options = {}) click to toggle source
     # File lib/ffi/tools/types_generator.rb, line 44
 44:     def self.generate(options = {})
 45:       typedefs = nil
 46:       Tempfile.open 'ffi_types_generator' do |io|
 47:         io.puts #include <sys/types.h>#include <sys/socket.h>#include <sys/resource.h>
 48: 
 49:         io.close
 50:         typedefs = `gcc -E -x c #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c #{io.path}`
 51:       end
 52:       
 53:       code = ""
 54: 
 55:       typedefs.each_line do |type|
 56:         # We only care about single line typedef
 57:         next unless type =~ /typedef/
 58:         # Ignore unions or structs
 59:         next if type =~ /union|struct/
 60:         
 61:         # strip off the starting typedef and ending ;
 62:         type.gsub!(/^(.*typedef\s*)/, "")
 63:         type.gsub!(/\s*;\s*$/, "")
 64:     
 65:         parts = type.split(/\s+/)
 66:         def_type   = parts.join(" ")
 67: 
 68:         # GCC does mapping with __attribute__ stuf, also see
 69:         # http://hal.cs.berkeley.edu/cil/cil016.html section 16.2.7.  Problem
 70:         # with this is that the __attribute__ stuff can either occur before or
 71:         # after the new type that is defined...
 72:         if type =~ /__attribute__/
 73:           if parts.last =~ /__QI__|__HI__|__SI__|__DI__|__word__/
 74: 
 75:             # In this case, the new type is BEFORE __attribute__ we need to
 76:             # find the final_type as the type before the part that starts with
 77:             # __attribute__
 78:             final_type = ""
 79:             parts.each do |p|
 80:               break if p =~ /__attribute__/
 81:               final_type = p
 82:             end
 83:           else
 84:             final_type = parts.pop
 85:           end
 86:           
 87:           def_type = case type
 88:                      when /__QI__/   then "char"
 89:                      when /__HI__/   then "short"
 90:                      when /__SI__/   then "int"
 91:                      when /__DI__/   then "long long"
 92:                      when /__word__/ then "long"
 93:                      else                 "int"
 94:                      end
 95: 
 96:           def_type = "unsigned #{def_type}" if type =~ /unsigned/
 97:         else
 98:           final_type = parts.pop
 99:           def_type   = parts.join(" ")
100:         end
101:         
102:         if type = TYPE_MAP[def_type]
103:           code << "rbx.platform.typedef.#{final_type} = #{type}\n"
104:           TYPE_MAP[final_type] = TYPE_MAP[def_type]
105:         else
106:           # Fallback to an ordinary pointer if we don't know the type
107:           if def_type =~ /\*/
108:             code << "rbx.platform.typedef.#{final_type} = pointer\n"
109:             TYPE_MAP[final_type] = :pointer
110:           end
111:         end
112:       end
113: 
114:       code
115:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.