bitclust-core 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +2907 -0
- data/Gemfile +7 -0
- data/README +21 -0
- data/Rakefile +20 -0
- data/bin/bitclust +14 -0
- data/bin/refe +36 -0
- data/bitclust-dev.gemspec +33 -0
- data/bitclust.gemspec +30 -0
- data/config.in +23 -0
- data/config.ru +48 -0
- data/config.ru.sample +31 -0
- data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
- data/data/bitclust/template.lillia/class +98 -0
- data/data/bitclust/template.lillia/class-index +28 -0
- data/data/bitclust/template.lillia/doc +48 -0
- data/data/bitclust/template.lillia/layout +19 -0
- data/data/bitclust/template.lillia/library +129 -0
- data/data/bitclust/template.lillia/library-index +32 -0
- data/data/bitclust/template.lillia/method +20 -0
- data/data/bitclust/template.lillia/rd_file +6 -0
- data/data/bitclust/template.offline/class +67 -0
- data/data/bitclust/template.offline/class-index +28 -0
- data/data/bitclust/template.offline/doc +13 -0
- data/data/bitclust/template.offline/function +22 -0
- data/data/bitclust/template.offline/function-index +24 -0
- data/data/bitclust/template.offline/layout +18 -0
- data/data/bitclust/template.offline/library +87 -0
- data/data/bitclust/template.offline/library-index +32 -0
- data/data/bitclust/template.offline/method +21 -0
- data/data/bitclust/template.offline/rd_file +6 -0
- data/data/bitclust/template/class +133 -0
- data/data/bitclust/template/class-index +30 -0
- data/data/bitclust/template/doc +14 -0
- data/data/bitclust/template/function +21 -0
- data/data/bitclust/template/function-index +25 -0
- data/data/bitclust/template/layout +19 -0
- data/data/bitclust/template/library +89 -0
- data/data/bitclust/template/library-index +35 -0
- data/data/bitclust/template/method +24 -0
- data/data/bitclust/template/opensearchdescription +10 -0
- data/data/bitclust/template/search +57 -0
- data/lib/bitclust.rb +9 -0
- data/lib/bitclust/app.rb +129 -0
- data/lib/bitclust/classentry.rb +425 -0
- data/lib/bitclust/compat.rb +39 -0
- data/lib/bitclust/completion.rb +531 -0
- data/lib/bitclust/crossrubyutils.rb +91 -0
- data/lib/bitclust/database.rb +181 -0
- data/lib/bitclust/docentry.rb +83 -0
- data/lib/bitclust/entry.rb +223 -0
- data/lib/bitclust/exception.rb +38 -0
- data/lib/bitclust/functiondatabase.rb +115 -0
- data/lib/bitclust/functionentry.rb +81 -0
- data/lib/bitclust/functionreferenceparser.rb +76 -0
- data/lib/bitclust/htmlutils.rb +80 -0
- data/lib/bitclust/interface.rb +87 -0
- data/lib/bitclust/libraryentry.rb +211 -0
- data/lib/bitclust/lineinput.rb +165 -0
- data/lib/bitclust/messagecatalog.rb +95 -0
- data/lib/bitclust/methoddatabase.rb +401 -0
- data/lib/bitclust/methodentry.rb +202 -0
- data/lib/bitclust/methodid.rb +209 -0
- data/lib/bitclust/methodsignature.rb +82 -0
- data/lib/bitclust/nameutils.rb +236 -0
- data/lib/bitclust/parseutils.rb +60 -0
- data/lib/bitclust/preprocessor.rb +273 -0
- data/lib/bitclust/rdcompiler.rb +507 -0
- data/lib/bitclust/refsdatabase.rb +66 -0
- data/lib/bitclust/requesthandler.rb +330 -0
- data/lib/bitclust/ridatabase.rb +349 -0
- data/lib/bitclust/rrdparser.rb +522 -0
- data/lib/bitclust/runner.rb +143 -0
- data/lib/bitclust/screen.rb +554 -0
- data/lib/bitclust/searcher.rb +518 -0
- data/lib/bitclust/server.rb +59 -0
- data/lib/bitclust/simplesearcher.rb +84 -0
- data/lib/bitclust/subcommand.rb +746 -0
- data/lib/bitclust/textutils.rb +51 -0
- data/lib/bitclust/version.rb +3 -0
- data/packer.rb +224 -0
- data/refe2.gemspec +29 -0
- data/server.exe +0 -0
- data/server.exy +159 -0
- data/server.rb +10 -0
- data/setup.rb +1596 -0
- data/standalone.rb +193 -0
- data/test/run_test.rb +15 -0
- data/test/test_bitclust.rb +81 -0
- data/test/test_entry.rb +39 -0
- data/test/test_functiondatabase.rb +55 -0
- data/test/test_libraryentry.rb +31 -0
- data/test/test_methoddatabase.rb +81 -0
- data/test/test_methodsignature.rb +14 -0
- data/test/test_nameutils.rb +324 -0
- data/test/test_preprocessor.rb +84 -0
- data/test/test_rdcompiler.rb +534 -0
- data/test/test_refsdatabase.rb +76 -0
- data/test/test_rrdparser.rb +26 -0
- data/test/test_runner.rb +102 -0
- data/test/test_simplesearcher.rb +48 -0
- data/theme/default/images/external.png +0 -0
- data/theme/default/rurema.png +0 -0
- data/theme/default/style.css +288 -0
- data/theme/default/test.css +254 -0
- data/theme/lillia/rurema.png +0 -0
- data/theme/lillia/style.css +331 -0
- data/theme/lillia/test.css +254 -0
- data/tools/bc-ancestors.rb +153 -0
- data/tools/bc-checkparams.rb +246 -0
- data/tools/bc-classes.rb +80 -0
- data/tools/bc-convert.rb +165 -0
- data/tools/bc-list.rb +63 -0
- data/tools/bc-methods.rb +171 -0
- data/tools/bc-preproc.rb +42 -0
- data/tools/bc-rdoc.rb +343 -0
- data/tools/bc-tochm.rb +301 -0
- data/tools/bc-tohtml.rb +125 -0
- data/tools/bc-tohtmlpackage.rb +241 -0
- data/tools/check-signature.rb +19 -0
- data/tools/forall-ruby.rb +20 -0
- data/tools/gencatalog.rb +69 -0
- data/tools/statrefm.rb +98 -0
- data/tools/stattodo.rb +150 -0
- data/tools/update-database.rb +146 -0
- data/view.cgi +6 -0
- metadata +222 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/methodid.rb
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006-2007 Minero Aoki
|
|
5
|
+
#
|
|
6
|
+
# This program is free software.
|
|
7
|
+
# You can distribute/modify this program under the Ruby License.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'bitclust/compat'
|
|
11
|
+
require 'bitclust/nameutils'
|
|
12
|
+
require 'bitclust/exception'
|
|
13
|
+
|
|
14
|
+
module BitClust
|
|
15
|
+
|
|
16
|
+
# A MethodID has #library, #klass, #typename, and method name.
|
|
17
|
+
# #library, #klass, #typename must be an object.
|
|
18
|
+
class MethodID
|
|
19
|
+
include NameUtils
|
|
20
|
+
|
|
21
|
+
def initialize(library = nil, klass = nil, type = nil, name = nil)
|
|
22
|
+
@library = library
|
|
23
|
+
@klass = klass
|
|
24
|
+
@type = type
|
|
25
|
+
@name = name
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
attr_accessor :library
|
|
29
|
+
attr_accessor :klass
|
|
30
|
+
attr_accessor :type
|
|
31
|
+
attr_accessor :name
|
|
32
|
+
|
|
33
|
+
def inspect
|
|
34
|
+
"#<methodid #{@library.name}.#{@klass.name}#{typemark()}#{@name}>"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def match?(m)
|
|
38
|
+
m.name == @name and
|
|
39
|
+
m.type == @type and
|
|
40
|
+
m.library == @library
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
alias typename type
|
|
44
|
+
|
|
45
|
+
def typechar
|
|
46
|
+
typename2char(@type)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def typemark
|
|
50
|
+
typename2mark(@type)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def idstring
|
|
54
|
+
build_method_id(@library.id, @klass.id, @type, @name)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# A MethodSpec has #klass, #type, #method and #library.
|
|
60
|
+
# All attributes are string.
|
|
61
|
+
# #library is optional.
|
|
62
|
+
class MethodSpec
|
|
63
|
+
|
|
64
|
+
def MethodSpec.parse(str)
|
|
65
|
+
new(*NameUtils.split_method_spec(str))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def initialize(c, t, m, library = nil)
|
|
69
|
+
@klass = c
|
|
70
|
+
@type = t
|
|
71
|
+
@method = m
|
|
72
|
+
@library = library
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
attr_reader :klass
|
|
76
|
+
attr_reader :type
|
|
77
|
+
attr_reader :method
|
|
78
|
+
attr_reader :library
|
|
79
|
+
|
|
80
|
+
def inspect
|
|
81
|
+
"#<spec #{@klass}#{@type}#{@method}>"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def to_s
|
|
85
|
+
"#{@klass}#{@type}#{@method}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def display_name
|
|
89
|
+
@type == '$' ? "$#{@method}" : to_s()
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def ==(other)
|
|
93
|
+
@klass == other.klass and
|
|
94
|
+
@type == other.type and
|
|
95
|
+
@method == other.method
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
alias eql? ==
|
|
99
|
+
|
|
100
|
+
def hash
|
|
101
|
+
to_s().hash
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def <=>(other)
|
|
105
|
+
[@klass, @type, @method] <=> [other.klass, other.type, other.method]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def match?(m)
|
|
109
|
+
(not @type or @type == m.typemark) and
|
|
110
|
+
(not @method or m.name?(@method))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def singleton_method?
|
|
114
|
+
@type == '.' or @type == '.#'
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def instance_method?
|
|
118
|
+
@type == '#' or @type == '.#'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def module_function?
|
|
122
|
+
@type == '.#'
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def method?
|
|
126
|
+
singleton_method? or instance_method?
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def constant?
|
|
130
|
+
@type == '::'
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def special_variable?
|
|
134
|
+
@type == '$'
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# A MethodNamePattern has #klass, #type, #method and #library.
|
|
141
|
+
# All attributes are string.
|
|
142
|
+
# All attributes are optional.
|
|
143
|
+
class MethodNamePattern
|
|
144
|
+
|
|
145
|
+
def initialize(c = nil, t = nil, m = nil, lib = nil)
|
|
146
|
+
@klass = c
|
|
147
|
+
if c and c.empty?
|
|
148
|
+
@klass = nil
|
|
149
|
+
end
|
|
150
|
+
@type = t
|
|
151
|
+
@method = m
|
|
152
|
+
if m and m.empty?
|
|
153
|
+
@method = nil
|
|
154
|
+
end
|
|
155
|
+
@library = library
|
|
156
|
+
@crecache = []
|
|
157
|
+
@mrecache = []
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
attr_reader :klass
|
|
161
|
+
attr_reader :type
|
|
162
|
+
attr_reader :method
|
|
163
|
+
attr_reader :library
|
|
164
|
+
|
|
165
|
+
def inspect
|
|
166
|
+
"#<pattern #{esc(@library)}.#{esc(@klass)}#{tesc(@type)}#{esc(@method)}>"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def esc(s)
|
|
170
|
+
s || '_'
|
|
171
|
+
end
|
|
172
|
+
private :esc
|
|
173
|
+
|
|
174
|
+
def tesc(s)
|
|
175
|
+
s || ' _ '
|
|
176
|
+
end
|
|
177
|
+
private :tesc
|
|
178
|
+
|
|
179
|
+
def match?(m)
|
|
180
|
+
(not @library or m.library.name?(@library)) and
|
|
181
|
+
(not @klass or m.klass.name?(@klass)) and
|
|
182
|
+
(not @type or m.typemark == @type) and
|
|
183
|
+
(not @method or m.name?(@method))
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def select_classes(cs)
|
|
187
|
+
return cs unless @klass
|
|
188
|
+
expand_ic(cs, @klass, @crecache)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def empty?
|
|
192
|
+
not @klass and not @type and not @method
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def class?
|
|
196
|
+
@klass and (not @type and not @method)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def method?
|
|
200
|
+
@method or (@type and @type != '$')
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def special_variable?
|
|
204
|
+
@type == '$'
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/methodsignature.rb
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006-2008 Minero Aoki
|
|
5
|
+
#
|
|
6
|
+
# This program is free software.
|
|
7
|
+
# You can distribute/modify this program under the Ruby License.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'bitclust/nameutils'
|
|
11
|
+
require 'bitclust/exception'
|
|
12
|
+
|
|
13
|
+
module BitClust
|
|
14
|
+
|
|
15
|
+
class MethodSignature
|
|
16
|
+
|
|
17
|
+
include NameUtils
|
|
18
|
+
|
|
19
|
+
METHOD_SIGNATURE_RE = /\A
|
|
20
|
+
--- \s*
|
|
21
|
+
(?: (?:#{CLASS_PATH_RE} #{TYPEMARK_RE})? (#{METHOD_NAME_RE})
|
|
22
|
+
| (#{GVAR_RE})
|
|
23
|
+
) \s* # method name ($1) or gvar name ($2)
|
|
24
|
+
(?: \( (.*?) \) \s* )? # parameters (optional); $3=parameter_list
|
|
25
|
+
(?: (\{ .* \}) \s* )? # block (optional); $4=block
|
|
26
|
+
(?: -> \s* (\S.*) \s* )? # type declaration (optional); $5=return_type
|
|
27
|
+
\z/x
|
|
28
|
+
|
|
29
|
+
def MethodSignature.parse(line)
|
|
30
|
+
m = METHOD_SIGNATURE_RE.match(line) or
|
|
31
|
+
raise ParseError, %Q(unknown signature format: "#{line.strip}")
|
|
32
|
+
method, gvar, params, block, type = m.captures
|
|
33
|
+
new(method || gvar, params && params.strip, block && block.strip, type && type.strip)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def initialize(name, params, block, type)
|
|
37
|
+
@name = name
|
|
38
|
+
@params = params
|
|
39
|
+
@block = block
|
|
40
|
+
@type = type
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
attr_reader :name
|
|
44
|
+
attr_reader :params
|
|
45
|
+
attr_reader :block
|
|
46
|
+
attr_reader :type
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
@name +
|
|
50
|
+
(@params ? "(#{@params})" : "") +
|
|
51
|
+
(@block ? " #{@block}" : "") +
|
|
52
|
+
(@type ? " -> #{@type}" : "")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def friendly_string
|
|
56
|
+
case @name
|
|
57
|
+
when /\A\$/ # gvar
|
|
58
|
+
@name + (@type ? " -> #{@type}" : "")
|
|
59
|
+
when "+@", "-@", "~", "!", "!@" # unary operator
|
|
60
|
+
"#{@name.sub(/@/, '')}#{@params}" + (@type ? " -> #{@type}" : "")
|
|
61
|
+
when "[]" # aref
|
|
62
|
+
"self[#{@params}]" + (@type ? " -> #{@type}" : "")
|
|
63
|
+
when "[]=" # aset
|
|
64
|
+
params = @params.split(',')
|
|
65
|
+
val = params.pop
|
|
66
|
+
"self[#{params.join(',').strip}] = #{val.strip}"
|
|
67
|
+
when "`" # `command`
|
|
68
|
+
"`#{@params}`" + (@type ? " -> #{@type}" : "")
|
|
69
|
+
when /\A\W/ # binary operator
|
|
70
|
+
"self #{@name} #{@params}" + (@type ? " -> #{@type}" : "")
|
|
71
|
+
else
|
|
72
|
+
to_s()
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def inspect
|
|
77
|
+
"\#<#{self.class} name=#{@name.inspect} params=#{@params.inspect} block=#{@block.inspect} type=#{@type.inspect}>"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/nameutils.rb
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006-2007 Minero Aoki
|
|
5
|
+
#
|
|
6
|
+
# This program is free software.
|
|
7
|
+
# You can distribute/modify this program under the Ruby License.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'bitclust/compat'
|
|
11
|
+
|
|
12
|
+
module BitClust
|
|
13
|
+
|
|
14
|
+
module NameUtils
|
|
15
|
+
|
|
16
|
+
module_function
|
|
17
|
+
|
|
18
|
+
LIBNAME_RE = %r<[\w\-]+(/[\w\-]+)*>
|
|
19
|
+
CONST_RE = /[A-Z]\w*/
|
|
20
|
+
CONST_PATH_RE = /#{CONST_RE}(?:::#{CONST_RE})*/
|
|
21
|
+
CLASS_NAME_RE = /(?:#{CONST_RE}|fatal)/
|
|
22
|
+
CLASS_PATH_RE = /(?:#{CONST_PATH_RE}|fatal)/
|
|
23
|
+
METHOD_NAME_RE = /\w+[?!=]?|===|==|=~|<=>|<=|>=|!=|!|!@|\[\]=|\[\]|\*\*|>>|<<|\+@|\-@|[~+\-*\/%&|^<>`]/
|
|
24
|
+
TYPEMARK_RE = /(?:\.|\#|\.\#|::|\$)/
|
|
25
|
+
METHOD_SPEC_RE = /#{CLASS_PATH_RE}#{TYPEMARK_RE}#{METHOD_NAME_RE}/
|
|
26
|
+
GVAR_RE = /\$(?:\w+|-.|\S)/
|
|
27
|
+
|
|
28
|
+
def libname?(str)
|
|
29
|
+
(/\A#{LIBNAME_RE}\z/o =~ str) ? true : false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def libname2id(name)
|
|
33
|
+
name.split('/').map {|ent| encodename_url(ent) }.join('.')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def libid2name(id)
|
|
37
|
+
id.split('.').map {|ent| decodename_url(ent) }.join('/')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def classname?(str)
|
|
41
|
+
(/\A#{CLASS_PATH_RE}\z/o =~ str) ? true : false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def classname2id(name)
|
|
45
|
+
name.gsub(/::/, '=')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def classid2name(id)
|
|
49
|
+
id.gsub(/=/, '::')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def method_spec?(str)
|
|
53
|
+
(/\A#{METHOD_SPEC_RE}\z/o =~ str) ? true : false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def split_method_spec(spec)
|
|
57
|
+
case spec
|
|
58
|
+
when /\AKernel\$/
|
|
59
|
+
return 'Kernel', '$', $'
|
|
60
|
+
else
|
|
61
|
+
m = /\A(#{CLASS_PATH_RE})(#{TYPEMARK_RE})(#{METHOD_NAME_RE})\z/o.match(spec) or
|
|
62
|
+
raise ArgumentError, "wrong method spec: #{spec.inspect}"
|
|
63
|
+
return *m.captures
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def methodid2specstring(id)
|
|
68
|
+
c, t, m, lib = *split_method_id(id)
|
|
69
|
+
classid2name(c) + typechar2mark(t) + decodename_url(m)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def methodid2specparts(id)
|
|
73
|
+
c, t, m, lib = *split_method_id(id)
|
|
74
|
+
return classid2name(c), typechar2mark(t), decodename_url(m), libid2name(lib)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def methodid2libid(id)
|
|
78
|
+
c, t, m, lib = *split_method_id(id)
|
|
79
|
+
lib
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def methodid2classid(id)
|
|
83
|
+
c, t, m, lib = *split_method_id(id)
|
|
84
|
+
c
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def methodid2typechar(id)
|
|
88
|
+
c, t, m, lib = *split_method_id(id)
|
|
89
|
+
t
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def methodid2typename(id)
|
|
93
|
+
c, t, m, lib = *split_method_id(id)
|
|
94
|
+
typechar2name(t)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def methodid2typemark(id)
|
|
98
|
+
c, t, m, lib = *split_method_id(id)
|
|
99
|
+
typechar2mark(t)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def methodid2mname(id)
|
|
103
|
+
c, t, m, lib = *split_method_id(id)
|
|
104
|
+
decodename_url(m)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def gvarname?(str)
|
|
108
|
+
GVAR_RE =~ str ? true : false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
MID = /\A#{METHOD_NAME_RE}\z/
|
|
112
|
+
|
|
113
|
+
def methodname?(str)
|
|
114
|
+
(MID =~ str) ? true : false
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def build_method_id(libid, cid, t, name)
|
|
118
|
+
"#{cid}/#{typename2char(t)}.#{encodename_url(name)}.#{libid}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# private module function
|
|
122
|
+
def split_method_id(id)
|
|
123
|
+
return *id.split(%r<[/\.]>, 4)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
NAME_TO_MARK = {
|
|
127
|
+
:singleton_method => '.',
|
|
128
|
+
:instance_method => '#',
|
|
129
|
+
:module_function => '.#',
|
|
130
|
+
:constant => '::',
|
|
131
|
+
:special_variable => '$'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
MARK_TO_NAME = NAME_TO_MARK.invert
|
|
135
|
+
|
|
136
|
+
def typename?(n)
|
|
137
|
+
NAME_TO_MARK.key?(n)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def typename2mark(name)
|
|
141
|
+
NAME_TO_MARK[name] or
|
|
142
|
+
raise "must not happen: #{name.inspect}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def typemark2name(mark)
|
|
146
|
+
MARK_TO_NAME[mark] or
|
|
147
|
+
raise "must not happen: #{mark.inspect}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
NAME_TO_CHAR = {
|
|
151
|
+
:singleton_method => 's',
|
|
152
|
+
:instance_method => 'i',
|
|
153
|
+
:module_function => 'm',
|
|
154
|
+
:constant => 'c',
|
|
155
|
+
:special_variable => 'v'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
CHAR_TO_NAME = NAME_TO_CHAR.invert
|
|
159
|
+
|
|
160
|
+
def typechar?(c)
|
|
161
|
+
CHAR_TO_NAME.key?(c)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def typename2char(name)
|
|
165
|
+
NAME_TO_CHAR[name] or
|
|
166
|
+
raise "must not happen: #{name.inspect}"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def typechar2name(char)
|
|
170
|
+
CHAR_TO_NAME[char] or
|
|
171
|
+
raise "must not happen: #{char.inspect}"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
MARK_TO_CHAR = {
|
|
175
|
+
'.' => 's',
|
|
176
|
+
'#' => 'i',
|
|
177
|
+
'.#' => 'm',
|
|
178
|
+
'::' => 'c',
|
|
179
|
+
'$' => 'v'
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
CHAR_TO_MARK = MARK_TO_CHAR.invert
|
|
183
|
+
|
|
184
|
+
def typemark?(m)
|
|
185
|
+
MARK_TO_CHAR.key?(m)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def typechar2mark(char)
|
|
189
|
+
CHAR_TO_MARK[char] or
|
|
190
|
+
raise "must not happen: #{char.inspect}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def typemark2char(mark)
|
|
194
|
+
MARK_TO_CHAR[mark] or
|
|
195
|
+
raise "must not happen: #{mark.inspect}"
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def functionname?(n)
|
|
199
|
+
/\A\w+\z/ =~ n ? true : false
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# string -> case-sensitive ID
|
|
203
|
+
def encodename_url(str)
|
|
204
|
+
str.gsub(/[^A-Za-z0-9_]/n) {|ch| sprintf('=%02x', ch[0].ord) }
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# case-sensitive ID -> string
|
|
208
|
+
def decodename_url(str)
|
|
209
|
+
str.gsub(/=[\da-h]{2}/ni) {|s| s[1,2].hex.chr }
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# case-sensitive ID -> encoded string (encode only [A-Z])
|
|
213
|
+
def encodeid(str)
|
|
214
|
+
str.gsub(/[A-Z]/n) {|ch| "-#{ch}" }.downcase
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# encoded string -> case-sensitive ID (decode only [A-Z])
|
|
218
|
+
def decodeid(str)
|
|
219
|
+
str.gsub(/-[a-z]/ni) {|s| s[1,1].upcase }
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def encodename_fs(str)
|
|
223
|
+
str.gsub(/[^a-z0-9_]/n) {|ch|
|
|
224
|
+
(/[A-Z]/n =~ ch) ? "-#{ch}" : sprintf('=%02x', ch[0].ord)
|
|
225
|
+
}.downcase
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def decodename_fs(str)
|
|
229
|
+
str.gsub(/=[\da-h]{2}|-[a-z]/ni) {|s|
|
|
230
|
+
(/\A-/ =~ s) ? s[1,1].upcase : s[1,2].hex.chr
|
|
231
|
+
}
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|