### Home Classes Methods

### In Files

- lib/ffi/tools/types_generator.rb

### Parent

Object

### Methods

- ::generate

### Files

- History.txt
- README.rdoc

### 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::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::Enum
- FFI::StructLayout::InnerStruct
- FFI::StructLayout::Mapped
- FFI::StructLayoutBuilder
- FFI::TypesGenerator
- FFI::Union
- FFI::VariadicInvoker

No matching classes.

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

        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

[Validate]

Generated with the Darkfish Rdoc Generator 2.