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