module 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 ext/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 ext/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 ext/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