非常教程

Ruby 2.4参考手册

Fiddle

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')
  #=> Fiddle::TYPE_INT

parse_struct_signature(['int i', 'char c'])
  #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]]

parse_signature('double sum(double, double)')
  #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]]

Public Instance Methods

parse_ctype(ty, tymap=nil) Show 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 diff')
  #=> Fiddle::TYPE_DOUBLE

parse_ctype('unsigned char byte')
  #=> -Fiddle::TYPE_CHAR

parse_ctype('const char* const argv[]')
  #=> -Fiddle::TYPE_VOIDP
# File ext/fiddle/lib/fiddle/cparser.rb, line 120
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 /^(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?$/
    if( defined?(TYPE_LONG_LONG) )
      return TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when /^(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?$/
    if( defined?(TYPE_LONG_LONG) )
      return -TYPE_LONG_LONG
    else
      raise(RuntimeError, "unsupported type: #{ty}")
    end
  when /^(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?$/
    return TYPE_LONG
  when /^unsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?$/
    return -TYPE_LONG
  when /^(?:signed\s+)?int(?:\s+\w+)?$/
    return TYPE_INT
  when /^(?:unsigned\s+int|uint)(?:\s+\w+)?$/
    return -TYPE_INT
  when /^(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?$/
    return TYPE_SHORT
  when /^unsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?$/
    return -TYPE_SHORT
  when /^(?:signed\s+)?char(?:\s+\w+)?$/
    return TYPE_CHAR
  when /^unsigned\s+char(?:\s+\w+)?$/
    return  -TYPE_CHAR
  when /^float(?:\s+\w+)?$/
    return TYPE_FLOAT
  when /^double(?:\s+\w+)?$/
    return TYPE_DOUBLE
  when /^size_t(?:\s+\w+)?$/
    return TYPE_SIZE_T
  when /^ssize_t(?:\s+\w+)?$/
    return TYPE_SSIZE_T
  when /^ptrdiff_t(?:\s+\w+)?$/
    return TYPE_PTRDIFF_T
  when /^intptr_t(?:\s+\w+)?$/
    return TYPE_INTPTR_T
  when /^uintptr_t(?:\s+\w+)?$/
    return TYPE_UINTPTR_T
  when /\*/, /\[[\s\d]*\]/
    return TYPE_VOIDP
  else
    ty = ty.split(' ', 2)[0]
    if( tymap[ty] )
      return parse_ctype(tymap[ty], tymap)
    else
      raise(DLError, "unknown type: #{ty}")
    end
  end
end

parse_signature(signature, tymap=nil) Show 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]]

parse_signature('void update(void (*cb)(int code))')
  #=> ["update", Fiddle::TYPE_VOID, [Fiddle::TYPE_VOIDP]]

parse_signature('char (*getbuffer(void))[80]')
  #=> ["getbuffer", Fiddle::TYPE_VOIDP, []]
# File ext/fiddle/lib/fiddle/cparser.rb, line 81
def parse_signature(signature, tymap=nil)
  tymap ||= {}
  case compact(signature)
  when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/
    func, args = $1, $2
    return [func, TYPE_VOIDP, split_arguments(args).collect {|arg| parse_ctype(arg, tymap)}]
  when /^([\w\*\s]+[\*\s])(\w+)\((.*?)\);?$/
    ret, func, args = $1.strip, $2, $3
    return [func, parse_ctype(ret, tymap), split_arguments(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) Show 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"]]

parse_struct_signature(['char buffer[80]'])
  #=> [[[Fiddle::TYPE_CHAR, 80]], ["buffer"]]
# File ext/fiddle/lib/fiddle/cparser.rb, line 33
def parse_struct_signature(signature, tymap=nil)
  if signature.is_a?(String)
    signature = split_arguments(signature, /[,;]/)
  end
  mems = []
  tys  = []
  signature.each{|msig|
    msig = compact(msig)
    case msig
    when /^[\w\*\s]+[\*\s](\w+)$/
      mems.push($1)
      tys.push(parse_ctype(msig, tymap))
    when /^[\w\*\s]+\(\*(\w+)\)\(.*?\)$/
      mems.push($1)
      tys.push(parse_ctype(msig, tymap))
    when /^([\w\*\s]+[\*\s])(\w+)\[(\d+)\]$/
      mems.push($2)
      tys.push([parse_ctype($1.strip, tymap), $3.to_i])
    when /^([\w\*\s]+)\[(\d+)\](\w+)$/
      mems.push($3)
      tys.push([parse_ctype($1.strip, tymap), $2.to_i])
    else
      raise(RuntimeError,"can't parse the struct member: #{msig}")
    end
  }
  return tys, mems
end

Private Instance Methods

compact(signature) Show source

# File ext/fiddle/lib/fiddle/cparser.rb, line 188
def compact(signature)
  signature.gsub(/\s+/, ' ').gsub(/\s*([\(\)\[\]\*,;])\s*/, '\1').strip
end

split_arguments(arguments, sep=',') Show source

# File ext/fiddle/lib/fiddle/cparser.rb, line 183
def split_arguments(arguments, sep=',')
  return [] if arguments.strip == 'void'
  arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+)(?:#{sep}\s*|$)/).collect {|m| m[0]}
end
Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct