In Files

  • fiddle/lib/fiddle/cparser.rb

Fiddle::CParser

A mixin that provides methods for parsing C struct and prototype signatures.

Example

require 'fiddle/import'

include Fiddle::CParser
  #=> Object

parse_ctype('int increment(int)')
  #=> ["increment", Fiddle::TYPE_INT, [Fiddle::TYPE_INT]]

Public Instance Methods

parse_ctype(ty, tymap=nil) click to toggle source

Given a String of C type ty, returns the corresponding Fiddle constant.

ty can also accept an Array of C type Strings, and will be returned in a corresponding Array.

If Hash tymap is provided, ty is expected to be the key, and the value will be the C type to be looked up.

Example:

include Fiddle::CParser
  #=> Object

parse_ctype('int')
  #=> Fiddle::TYPE_INT

parse_ctype('double')
  #=> Fiddle::TYPE_DOUBLE

parse_ctype('unsigned char')
  #=> -Fiddle::TYPE_CHAR
 
               # File fiddle/lib/fiddle/cparser.rb, line 116
def parse_ctype(ty, tymap=nil)
  tymap ||= {}
  case ty
  when Array
    return [parse_ctype(ty[0], tymap), ty[1]]
  when "void"
    return TYPE_VOID
  when "char"
    return TYPE_CHAR
  when "unsigned char"
    return  -TYPE_CHAR
  when "short"
    return TYPE_SHORT
  when "unsigned short"
    return -TYPE_SHORT
  when "int"
    return TYPE_INT
  when "unsigned int", 'uint'
    return -TYPE_INT
  when "long"
    return TYPE_LONG
  when "unsigned long"
    return -TYPE_LONG
  when "long long"
    if( defined?(TYPE_LONG_LONG) )
      return TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "unsigned long long"
    if( defined?(TYPE_LONG_LONG) )
      return -TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when "float"
    return TYPE_FLOAT
  when "double"
    return TYPE_DOUBLE
  when "size_t"
    return TYPE_SIZE_T
  when "ssize_t"
    return TYPE_SSIZE_T
  when "ptrdiff_t"
    return TYPE_PTRDIFF_T
  when "intptr_t"
    return TYPE_INTPTR_T
  when "uintptr_t"
    return TYPE_UINTPTR_T
  when /\*/, /\[\s*\]/
    return TYPE_VOIDP
  else
    if( tymap[ty] )
      return parse_ctype(tymap[ty], tymap)
    else
      raise(DLError, "unknown type: #{ty}")
    end
  end
end
            
parse_signature(signature, tymap=nil) click to toggle source

Parses a C prototype signature

If Hash tymap is provided, the return value and the arguments from the signature are expected to be keys, and the value will be the C type to be looked up.

Example:

include Fiddle::CParser
  #=> Object

parse_signature('double sum(double, double)')
  #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]]
 
               # File fiddle/lib/fiddle/cparser.rb, line 73
def parse_signature(signature, tymap=nil)
  tymap ||= {}
  signature = signature.gsub(/\s+/, " ").strip
  case signature
  when /^([\w@\*\s]+)\(([\w\*\s\,\[\]]*)\)$/
    ret = $1
    (args = $2).strip!
    ret = ret.split(/\s+/)
    args = args.split(/\s*,\s*/)
    func = ret.pop
    if( func =~ /^\*/ )
      func.gsub!(/^\*+/,"")
      ret.push("*")
    end
    ret  = ret.join(" ")
    return [func, parse_ctype(ret, tymap), args.collect{|arg| parse_ctype(arg, tymap)}]
  else
    raise(RuntimeError,"can't parse the function prototype: #{signature}")
  end
end
            
parse_struct_signature(signature, tymap=nil) click to toggle source

Parses a C struct’s members

Example:

include Fiddle::CParser
  #=> Object

parse_struct_signature(['int i', 'char c'])
  #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]
 
               # File fiddle/lib/fiddle/cparser.rb, line 24
def parse_struct_signature(signature, tymap=nil)
  if( signature.is_a?(String) )
    signature = signature.split(/\s*,\s*/)
  end
  mems = []
  tys  = []
  signature.each{|msig|
    tks = msig.split(/\s+(\*)?/)
    ty = tks[0..-2].join(" ")
    member = tks[-1]

    case ty
    when /\[(\d+)\]/
      n = $1.to_i
      ty.gsub!(/\s*\[\d+\]/,"")
      ty = [ty, n]
    when /\[\]/
      ty.gsub!(/\s*\[\]/, "*")
    end

    case member
    when /\[(\d+)\]/
      ty = [ty, $1.to_i]
      member.gsub!(/\s*\[\d+\]/,"")
    when /\[\]/
      ty = ty + "*"
      member.gsub!(/\s*\[\]/, "")
    end

    mems.push(member)
    tys.push(parse_ctype(ty,tymap))
  }
  return tys, mems
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus