### Home Classes Methods

### In Files

- lib/ffi/tools/types_generator.rb

### Parent

Object

### Methods

- ::generate

### Files

- Makefile
- ChangeLog
- LICENSE
- README
- compile
- configure
- depcomp
- stamp-vti
- install-sh
- libtool-version
- mdate-sh
- missing

### Class/Module Index

Quicksearch

- FFI
- FFI::AutoPointer
- FFI::AutoPointer::CallableReleaser
- FFI::AutoPointer::DefaultReleaser
- FFI::AutoPointer::Releaser
- FFI::ConstGenerator
- FFI::ConstGenerator::Constant
- FFI::Enum
- FFI::Enums
- FFI::FunctionType
- FFI::Generator
- FFI::Generator::Task
- FFI::IO
- FFI::Library
- FFI::ManagedStruct
- FFI::NotFoundError
- FFI::Platform
- FFI::PlatformError
- FFI::Pointer
- FFI::StrPtrConverter
- FFI::Struct
- FFI::Struct::ManagedStructConverter
- FFI::StructGenerator
- FFI::StructGenerator::Field
- FFI::StructLayout
- FFI::StructLayout::Array
- FFI::StructLayout::Enum
- FFI::StructLayout::Field
- FFI::StructLayout::Function
- FFI::StructLayout::InnerStruct
- FFI::StructLayout::Mapped
- FFI::StructLayout::Number
- FFI::StructLayout::Pointer
- FFI::StructLayout::String
- FFI::StructLayoutBuilder
- FFI::TypesGenerator
- FFI::Union
- FFI::VariadicInvoker

No matching classes.

# FFI::TypesGenerator

@private

### 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 46
    def self.generate(options = {})
      typedefs = nil
      Tempfile.open 'ffi_types_generator' do |io|
        io.puts #include <sys/types.h>#if !(defined(WIN32))#include <sys/socket.h>#include <sys/resource.h>#endif

        io.close
        cc = ENV['CC'] || 'gcc'
        cmd = "#{cc} -E -x c #{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c"
        if options[:input]
          typedefs = File.read(options[:input])
        elsif options[:remote]
          typedefs = `ssh #{options[:remote]} #{cmd} - < #{io.path}`
        else
          typedefs = `#{cmd} #{io.path}`
        end
      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

[Validate]

Generated with the Darkfish Rdoc Generator 2.