модуль Fiddle::CParser
Mixin, предоставляющий методы для разбора сигнатур C-структур и прототипов.
Пример
require 'fiddle/import'
include Fiddle::CParser
#=> Object
parse_ctype('int increment(int)')
#=> ["increment", Fiddle::TYPE_INT, [Fiddle::TYPE_INT]]
Открытые методы экземпляров
# 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 Принимая строку C-типа ty, возвращает соответствующую константу Fiddle.
ty также может принимать массив строк C-типов и вернёт соответствующий массив.
Если предоставлен Хэш tymap, ty ожидается в качестве ключа, а значением будет C-тип для поиска.
Пример:
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 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 Разбирает C-сигнатуру прототипа.
Если предоставлен Хэш tymap, возвращаемое значение и аргументы из signature ожидаются в качестве ключей, а значением будет C-тип для поиска.
Пример:
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 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 Разбирает члены C-структуры.
Пример:
include Fiddle::CParser #=> Object parse_struct_signature(['int i', 'char c']) #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.