bitclust-core 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|