Module: BitClust::NameUtils

Overview

Utilities for conversion among names, ids and URL fragments.

Constant Summary collapse

LIBNAME_RE =
%r<[\w\-]+(/[\w\-]+)*>
CONST_RE =
/[A-Z]\w*/
CONST_PATH_RE =
/#{CONST_RE}(?:::#{CONST_RE})*/
CLASS_NAME_RE =
/(?:#{CONST_RE}(?:::compatible)?|fatal|ARGF\.class|main)/
CLASS_PATH_RE =
/(?:#{CONST_PATH_RE}(?:::compatible)?|fatal|ARGF\.class|main)/
METHOD_NAME_RE =
/\w+[?!=]?|===|==|=~|<=>|<=|>=|!=|!~|!@|!|\[\]=|\[\]|\*\*|>>|<<|\+@|\-@|[~+\-*\/%&|^<>`]/
TYPEMARK_RE =
/(?:\.|\#|\.\#|::|\$)/
METHOD_SPEC_RE =
/#{CLASS_PATH_RE}#{TYPEMARK_RE}#{METHOD_NAME_RE}/
GVAR_RE =
/\$(?:\w+|-.|\S)/
MID =
/\A#{METHOD_NAME_RE}\z/
NAME_TO_MARK =
{
  :singleton_method => '.',
  :instance_method  => '#',
  :module_function  => '.#',
  :constant         => '::',
  :special_variable => '$'
}
MARK_TO_NAME =
NAME_TO_MARK.invert
NAME_TO_CHAR =
{
  :singleton_method => 's',
  :instance_method  => 'i',
  :module_function  => 'm',
  :constant         => 'c',
  :special_variable => 'v'
}
CHAR_TO_NAME =
NAME_TO_CHAR.invert
MARK_TO_CHAR =
{
  '.'  => 's',
  '#'  => 'i',
  '.#' => 'm',
  '::' => 'c',
  '$'  => 'v'
}
CHAR_TO_MARK =
MARK_TO_CHAR.invert
@@split_method_id =
{}

Class Method Summary collapse

Class Method Details

.build_method_id(libid, cid, t, name) ⇒ Object

[View source]

120
121
122
# File 'lib/bitclust/nameutils.rb', line 120

def build_method_id(libid, cid, t, name)
  "#{cid}/#{typename2char(t)}.#{encodename_url(name)}.#{libid}"
end

.classid2name(id) ⇒ Object

[View source]

50
51
52
# File 'lib/bitclust/nameutils.rb', line 50

def classid2name(id)
  id.gsub(/=/, '::')
end

.classname2id(name) ⇒ Object

[View source]

46
47
48
# File 'lib/bitclust/nameutils.rb', line 46

def classname2id(name)
  name.gsub(/::/, '=')
end

.classname?(str) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

42
43
44
# File 'lib/bitclust/nameutils.rb', line 42

def classname?(str)
  (/\A#{CLASS_PATH_RE}\z/o =~ str) ? true : false
end

.decodeid(str) ⇒ Object

encoded string -> case-sensitive ID (decode only [A-Z])

[View source]

234
235
236
# File 'lib/bitclust/nameutils.rb', line 234

def decodeid(str)
  str.gsub(/-[a-z]/ni) {|s| s[1,1].upcase }
end

.decodename_fs(str) ⇒ Object

[View source]

244
245
246
247
248
# File 'lib/bitclust/nameutils.rb', line 244

def decodename_fs(str)
  str.gsub(/=[\da-h]{2}|-[a-z]/ni) {|s|
    (/\A-/ =~ s) ? s[1,1].upcase : s[1,2].hex.chr
  }
end

.decodename_url(str) ⇒ Object

case-sensitive ID -> string

[View source]

216
217
218
# File 'lib/bitclust/nameutils.rb', line 216

def decodename_url(str)
  str.gsub(/=[\da-h]{2}/ni) {|s| s[1,2].hex.chr }
end

.encodeid(str) ⇒ Object

case-sensitive ID -> encoded string (encode only [A-Z])

[View source]

229
230
231
# File 'lib/bitclust/nameutils.rb', line 229

def encodeid(str)
  str.gsub(/[A-Z]/n) {|ch| "-#{ch}" }.downcase
end

.encodename_fs(str) ⇒ Object

[View source]

238
239
240
241
242
# File 'lib/bitclust/nameutils.rb', line 238

def encodename_fs(str)
  str.gsub(/[^a-z0-9_]/n) {|ch|
    (/[A-Z]/n =~ ch) ? "-#{ch}" : sprintf('=%02x', ch[0].ord)
  }.downcase
end

.encodename_rdocurl(str) ⇒ Object

string -> encoded string in a rdoc way

[View source]

221
222
223
224
225
226
# File 'lib/bitclust/nameutils.rb', line 221

def encodename_rdocurl(str)
  str = str.gsub(/[^A-Za-z0-9_.]/n) {|ch|
    sprintf('-%02X', ch[0].ord)
  }
  str.sub(/\A-/, '')
end

.encodename_url(str) ⇒ Object

string -> case-sensitive ID

[View source]

211
212
213
# File 'lib/bitclust/nameutils.rb', line 211

def encodename_url(str)
  str.gsub(/[^A-Za-z0-9_]/n) {|ch| sprintf('=%02x', ch[0].ord) }
end

.functionname?(n) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

206
207
208
# File 'lib/bitclust/nameutils.rb', line 206

def functionname?(n)
  /\A\w+\z/ =~ n ? true : false
end

.gvarname?(str) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

110
111
112
# File 'lib/bitclust/nameutils.rb', line 110

def gvarname?(str)
  GVAR_RE =~ str ? true : false
end

.html_filename(basename, suffix) ⇒ Object

[View source]

250
251
252
# File 'lib/bitclust/nameutils.rb', line 250

def html_filename(basename, suffix)
  "#{basename}#{suffix}"
end

.libid2name(id) ⇒ Object

[View source]

38
39
40
# File 'lib/bitclust/nameutils.rb', line 38

def libid2name(id)
  id.split('.').map {|ent| decodename_url(ent) }.join('/')
end

.libname2id(name) ⇒ Object

[View source]

34
35
36
# File 'lib/bitclust/nameutils.rb', line 34

def libname2id(name)
  name.split('/').map {|ent| encodename_url(ent) }.join('.')
end

.libname?(str) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

30
31
32
# File 'lib/bitclust/nameutils.rb', line 30

def libname?(str)
  (/\A#{LIBNAME_RE}\z/o =~ str) ? true : false
end

.method_spec?(str) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

54
55
56
57
# File 'lib/bitclust/nameutils.rb', line 54

def method_spec?(str)
  return false if str == "ARGF.class"
  (/\A#{METHOD_SPEC_RE}\z/o =~ str) ? true : false
end

.methodid2classid(id) ⇒ Object

[View source]

85
86
87
88
# File 'lib/bitclust/nameutils.rb', line 85

def methodid2classid(id)
  c, _t, _m, _lib = *split_method_id(id)
  c
end

.methodid2libid(id) ⇒ Object

[View source]

80
81
82
83
# File 'lib/bitclust/nameutils.rb', line 80

def methodid2libid(id)
  _c, _t, _m, lib = *split_method_id(id)
  lib
end

.methodid2mname(id) ⇒ Object

[View source]

105
106
107
108
# File 'lib/bitclust/nameutils.rb', line 105

def methodid2mname(id)
  _c, _t, m, _lib = *split_method_id(id)
  decodename_url(m)
end

.methodid2specparts(id) ⇒ Object

[View source]

75
76
77
78
# File 'lib/bitclust/nameutils.rb', line 75

def methodid2specparts(id)
  c, t, m, lib = *split_method_id(id)
  return classid2name(c), typechar2mark(t), decodename_url(m), libid2name(lib)
end

.methodid2specstring(id) ⇒ Object

[View source]

70
71
72
73
# File 'lib/bitclust/nameutils.rb', line 70

def methodid2specstring(id)
  c, t, m, _lib = *split_method_id(id)
  classid2name(c) + typechar2mark(t) + decodename_url(m)
end

.methodid2typechar(id) ⇒ Object

[View source]

90
91
92
93
# File 'lib/bitclust/nameutils.rb', line 90

def methodid2typechar(id)
  _c, t, _m, _lib = *split_method_id(id)
  t
end

.methodid2typemark(id) ⇒ Object

[View source]

100
101
102
103
# File 'lib/bitclust/nameutils.rb', line 100

def methodid2typemark(id)
  _c, t, _m, _lib = *split_method_id(id)
  typechar2mark(t)
end

.methodid2typename(id) ⇒ Object

[View source]

95
96
97
98
# File 'lib/bitclust/nameutils.rb', line 95

def methodid2typename(id)
  _c, t, _m, _lib = *split_method_id(id)
  typechar2name(t)
end

.methodname?(str) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

116
117
118
# File 'lib/bitclust/nameutils.rb', line 116

def methodname?(str)
  (MID =~ str) ? true : false
end

.split_method_id(id) ⇒ Object

private module function

[View source]

127
128
129
130
131
132
# File 'lib/bitclust/nameutils.rb', line 127

def split_method_id(id)
  @@split_method_id[id] ||= begin
    c, rest = id.split("/")
    [c, *rest.split(%r<[/\.]>, 3)]
  end
end

.split_method_spec(spec) ⇒ Object

[View source]

59
60
61
62
63
64
65
66
67
68
# File 'lib/bitclust/nameutils.rb', line 59

def split_method_spec(spec)
  case spec
  when /\AKernel\$/
    return 'Kernel', '$', $'
  else
    m = /\A(#{CLASS_PATH_RE})(#{TYPEMARK_RE})(#{METHOD_NAME_RE})\z/o.match(spec) or
        raise ArgumentError, "wrong method spec: #{spec.inspect}"
    return *m.captures
  end
end

.typechar2mark(char) ⇒ Object

[View source]

196
197
198
199
# File 'lib/bitclust/nameutils.rb', line 196

def typechar2mark(char)
  CHAR_TO_MARK[char] or
      raise "must not happen: #{char.inspect}"
end

.typechar2name(char) ⇒ Object

[View source]

177
178
179
180
# File 'lib/bitclust/nameutils.rb', line 177

def typechar2name(char)
  CHAR_TO_NAME[char] or
      raise "must not happen: #{char.inspect}"
end

.typechar?(c) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

168
169
170
# File 'lib/bitclust/nameutils.rb', line 168

def typechar?(c)
  CHAR_TO_NAME.key?(c)
end

.typemark2char(mark) ⇒ Object

[View source]

201
202
203
204
# File 'lib/bitclust/nameutils.rb', line 201

def typemark2char(mark)
  MARK_TO_CHAR[mark] or
      raise "must not happen: #{mark.inspect}"
end

.typemark2name(mark) ⇒ Object

[View source]

153
154
155
156
# File 'lib/bitclust/nameutils.rb', line 153

def typemark2name(mark)
  MARK_TO_NAME[mark] or
      raise "must not happen: #{mark.inspect}"
end

.typemark?(m) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

192
193
194
# File 'lib/bitclust/nameutils.rb', line 192

def typemark?(m)
  MARK_TO_CHAR.key?(m)
end

.typename2char(name) ⇒ Object

[View source]

172
173
174
175
# File 'lib/bitclust/nameutils.rb', line 172

def typename2char(name)
  NAME_TO_CHAR[name] or
      raise "must not happen: #{name.inspect}"
end

.typename2mark(name) ⇒ Object

[View source]

148
149
150
151
# File 'lib/bitclust/nameutils.rb', line 148

def typename2mark(name)
  NAME_TO_MARK[name] or
      raise "must not happen: #{name.inspect}"
end

.typename?(n) ⇒ Boolean

Returns:

  • (Boolean)
[View source]

144
145
146
# File 'lib/bitclust/nameutils.rb', line 144

def typename?(n)
  NAME_TO_MARK.key?(n)
end