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,518 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/searcher.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/methoddatabase'
|
|
11
|
+
require 'bitclust/functiondatabase'
|
|
12
|
+
require 'bitclust/nameutils'
|
|
13
|
+
require 'bitclust/methodid'
|
|
14
|
+
require 'bitclust/exception'
|
|
15
|
+
require 'uri'
|
|
16
|
+
require 'rbconfig'
|
|
17
|
+
require 'optparse'
|
|
18
|
+
require 'nkf'
|
|
19
|
+
|
|
20
|
+
module BitClust
|
|
21
|
+
|
|
22
|
+
class Searcher
|
|
23
|
+
|
|
24
|
+
include NameUtils
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
cmd = File.basename($0, '.*')
|
|
28
|
+
@dblocation = nil
|
|
29
|
+
@name = (/\Abitclust/ =~ cmd ? 'bitclust search' : 'refe')
|
|
30
|
+
@describe_all = false
|
|
31
|
+
@linep = false
|
|
32
|
+
@encoding = nil
|
|
33
|
+
@target_type = nil
|
|
34
|
+
@listen_url = nil
|
|
35
|
+
@foreground = false
|
|
36
|
+
@parser = OptionParser.new {|opt|
|
|
37
|
+
opt.banner = "Usage: #{@name} <pattern>"
|
|
38
|
+
unless cmd == 'bitclust'
|
|
39
|
+
opt.on('-d', '--database=URL', "Database location (default: #{dblocation_name()})") {|loc|
|
|
40
|
+
url = (/:/ =~ loc) ? loc : "file://#{File.expand_path(loc)}"
|
|
41
|
+
@dblocation = URI.parse(url)
|
|
42
|
+
}
|
|
43
|
+
opt.on('--server=URL', 'Spawns BitClust database server and listen URL. Requires --database option with local path.') {|url|
|
|
44
|
+
require 'bitclust/server' # require here for speed
|
|
45
|
+
@listen_url = url
|
|
46
|
+
}
|
|
47
|
+
opt.on('--foreground', 'Do not become daemon (for debug)') {
|
|
48
|
+
@foreground = true
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
opt.on('-a', '--all', 'Prints descriptions for all matched entries.') {
|
|
52
|
+
@describe_all = true
|
|
53
|
+
}
|
|
54
|
+
opt.on('-l', '--line', 'Prints one entry in one line.') {
|
|
55
|
+
@linep = true
|
|
56
|
+
}
|
|
57
|
+
opt.on('-e', '--encoding=ENCODING', 'Select encoding.') {|enc|
|
|
58
|
+
@encoding = enc
|
|
59
|
+
}
|
|
60
|
+
opt.on('--class', 'Search class or module.') {
|
|
61
|
+
@target_type = :class
|
|
62
|
+
}
|
|
63
|
+
opt.on('--version', 'Prints version and quit.') {
|
|
64
|
+
if cmd == 'bitclust'
|
|
65
|
+
puts "BitClust -- Next generation reference manual interface"
|
|
66
|
+
exit 1
|
|
67
|
+
else
|
|
68
|
+
puts "ReFe version 2"
|
|
69
|
+
exit 1
|
|
70
|
+
end
|
|
71
|
+
}
|
|
72
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
73
|
+
puts opt.help
|
|
74
|
+
exit 0
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
attr_reader :parser
|
|
80
|
+
|
|
81
|
+
def parse(argv)
|
|
82
|
+
@parser.parse! argv
|
|
83
|
+
if @listen_url # server mode
|
|
84
|
+
server_mode_check argv
|
|
85
|
+
else
|
|
86
|
+
refe_mode_check argv
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def exec(db, argv)
|
|
91
|
+
if @listen_url
|
|
92
|
+
spawn_server db
|
|
93
|
+
else
|
|
94
|
+
search_pattern db, argv
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
def server_mode_check(argv)
|
|
101
|
+
if @dblocation
|
|
102
|
+
unless @dblocation.scheme == 'file'
|
|
103
|
+
$stderr.puts "Give local path to --database option on server mode"
|
|
104
|
+
exit 1
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
unless dbpath()
|
|
108
|
+
$stderr.puts "no local database given; use --database option with local database path"
|
|
109
|
+
exit 1
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
unless argv.empty?
|
|
113
|
+
$stderr.puts "too many arguments"
|
|
114
|
+
exit 1
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def refe_mode_check(argv)
|
|
119
|
+
case @target_type
|
|
120
|
+
when :class
|
|
121
|
+
unless argv.size == 1
|
|
122
|
+
$stderr.puts "--class option requires only 1 argument"
|
|
123
|
+
exit 1
|
|
124
|
+
end
|
|
125
|
+
else
|
|
126
|
+
if argv.size > 3
|
|
127
|
+
$stderr.puts "too many arguments (#{argv.size} for 2)"
|
|
128
|
+
exit 1
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
# FIXME
|
|
132
|
+
#compiler = RDCompiler::Text.new
|
|
133
|
+
compiler = Plain.new
|
|
134
|
+
@view = TerminalView.new(compiler,
|
|
135
|
+
{:describe_all => @describe_all,
|
|
136
|
+
:line => @linep,
|
|
137
|
+
:encoding => @encoding})
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def spawn_server(db)
|
|
141
|
+
Server.new(new_local_database(db)).listen @listen_url, @foreground
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def new_local_database(db)
|
|
145
|
+
return db if db
|
|
146
|
+
path = @dblocation ? @dblocation.path : dbpath()
|
|
147
|
+
MethodDatabase.new(path)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def new_database
|
|
151
|
+
db = MethodDatabase.connect(@dblocation || dblocation())
|
|
152
|
+
@view.database = db if @view
|
|
153
|
+
db
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def dblocation_name
|
|
157
|
+
find_dblocation() or 'NONE'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def dblocation
|
|
161
|
+
find_dblocation() or
|
|
162
|
+
raise InvalidDatabase, "database not exist or invalid database"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def find_dblocation
|
|
166
|
+
%w( REFE2_SERVER BITCLUST_SERVER ).each do |key|
|
|
167
|
+
return URI.parse(ENV[key]) if ENV[key]
|
|
168
|
+
end
|
|
169
|
+
if path = dbpath()
|
|
170
|
+
URI.parse("file://#{path}")
|
|
171
|
+
else
|
|
172
|
+
nil
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def dbpath
|
|
177
|
+
env_dbpath() || default_dbpath()
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def env_dbpath
|
|
181
|
+
[ 'REFE2_DATADIR', 'BITCLUST_DATADIR' ].each do |key|
|
|
182
|
+
if ENV.key?(key)
|
|
183
|
+
unless MethodDatabase.datadir?(ENV[key])
|
|
184
|
+
raise InvalidDatabase, "environment variable #{key} given but #{ENV[key]} is not a valid BitClust database"
|
|
185
|
+
end
|
|
186
|
+
return ENV[key]
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
nil
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def default_dbpath
|
|
193
|
+
datadir = ::RbConfig::CONFIG['datadir']
|
|
194
|
+
[ "#{datadir}/refe2", "#{datadir}/bitclust" ].each do |path|
|
|
195
|
+
return path if MethodDatabase.datadir?(path)
|
|
196
|
+
end
|
|
197
|
+
nil
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def search_pattern(db, argv)
|
|
201
|
+
db ||= new_database()
|
|
202
|
+
@view.database ||= db if @view
|
|
203
|
+
case @target_type || db
|
|
204
|
+
when :class
|
|
205
|
+
find_class db, argv[0]
|
|
206
|
+
when FunctionDatabase
|
|
207
|
+
case argv.size
|
|
208
|
+
when 0
|
|
209
|
+
show_all_functions db
|
|
210
|
+
when 1
|
|
211
|
+
find_function db, argv[0]
|
|
212
|
+
else
|
|
213
|
+
raise "must not happen: #{argv.size}"
|
|
214
|
+
end
|
|
215
|
+
else
|
|
216
|
+
case argv.size
|
|
217
|
+
when 0
|
|
218
|
+
show_all_classes db
|
|
219
|
+
when 1
|
|
220
|
+
find_class_or_method db, argv[0]
|
|
221
|
+
when 2
|
|
222
|
+
c, m = *argv
|
|
223
|
+
find_method db, c, nil, m
|
|
224
|
+
when 3
|
|
225
|
+
c, t, m = *argv
|
|
226
|
+
check_method_type t
|
|
227
|
+
find_method db, c, t, m
|
|
228
|
+
else
|
|
229
|
+
raise "must not happen: #{argv.size}"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def show_all_classes(db)
|
|
235
|
+
@view.show_class db.classes
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def show_all_functions(db)
|
|
239
|
+
@view.show_function db.functions
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def find_class(db, c)
|
|
243
|
+
@view.show_class db.search_classes(c)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def find_method(db, c, t, m)
|
|
247
|
+
@view.show_method db.search_methods(MethodNamePattern.new(c, t, m))
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def find_function(db, f)
|
|
251
|
+
@view.show_function db.search_functions(f)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def check_method_type(t)
|
|
255
|
+
if t == '$'
|
|
256
|
+
raise InvalidKey, "'$' cannot be used as method type"
|
|
257
|
+
end
|
|
258
|
+
unless typemark?(t)
|
|
259
|
+
raise InvalidKey, "unknown method type: #{t.inspect}"
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def find_class_or_method(db, pattern)
|
|
264
|
+
case pattern
|
|
265
|
+
when /\A\$/ # Special variable.
|
|
266
|
+
find_method db, 'Kernel', '$', pattern.sub(/\A\$/, '')
|
|
267
|
+
when /[\#,]\.|\.[\#,]|[\#\.\,]/ # method spec
|
|
268
|
+
find_method db, *parse_method_spec_pattern(pattern)
|
|
269
|
+
when /::/ # Class name or constant name.
|
|
270
|
+
find_constant db, pattern
|
|
271
|
+
when /\A[A-Z]/ # Method name or class name, but class name is better.
|
|
272
|
+
begin
|
|
273
|
+
find_class db, pattern
|
|
274
|
+
rescue ClassNotFound
|
|
275
|
+
find_method db, nil, nil, pattern
|
|
276
|
+
end
|
|
277
|
+
else # No hint. Method name or class name.
|
|
278
|
+
begin
|
|
279
|
+
find_method db, nil, nil, pattern
|
|
280
|
+
rescue MethodNotFound
|
|
281
|
+
find_class db, pattern
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def find_constant(db, pattern)
|
|
287
|
+
# class lookup is faster
|
|
288
|
+
find_class db, pattern
|
|
289
|
+
rescue ClassNotFound
|
|
290
|
+
cnames = pattern.split(/::/)
|
|
291
|
+
name = cnames.pop
|
|
292
|
+
find_method db, cnames.join('::'), '::', name
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def parse_method_spec_pattern(pat)
|
|
296
|
+
_m, _t, _c = pat.reverse.split(/([\#,]\.|\.[\#,]|[\#\.\,])/, 2)
|
|
297
|
+
c = _c.reverse
|
|
298
|
+
t = _t.tr(',', '#').sub(/\#\./, '.#')
|
|
299
|
+
m = _m.reverse
|
|
300
|
+
return c, t, m
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class Plain
|
|
307
|
+
def compile(src)
|
|
308
|
+
src
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class TerminalView
|
|
314
|
+
|
|
315
|
+
def initialize(compiler, opts)
|
|
316
|
+
@compiler = compiler
|
|
317
|
+
@describe_all = opts[:describe_all]
|
|
318
|
+
@line = opts[:line]
|
|
319
|
+
@encoding = opts[:encoding]
|
|
320
|
+
@database = nil
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
attr_accessor :database
|
|
324
|
+
|
|
325
|
+
def show_class(cs)
|
|
326
|
+
if cs.size == 1
|
|
327
|
+
if @line
|
|
328
|
+
print_names [cs.first.label]
|
|
329
|
+
else
|
|
330
|
+
describe_class cs.first
|
|
331
|
+
end
|
|
332
|
+
else
|
|
333
|
+
if @describe_all
|
|
334
|
+
cs.sort.each do |c|
|
|
335
|
+
describe_class c
|
|
336
|
+
end
|
|
337
|
+
else
|
|
338
|
+
print_names cs.map {|c| c.labels }.flatten
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def show_method(result)
|
|
344
|
+
if result.determined?
|
|
345
|
+
if @line
|
|
346
|
+
print_names result.names
|
|
347
|
+
else
|
|
348
|
+
describe_method result.record
|
|
349
|
+
end
|
|
350
|
+
else
|
|
351
|
+
if @describe_all
|
|
352
|
+
result.each_record do |rec|
|
|
353
|
+
describe_method rec
|
|
354
|
+
end
|
|
355
|
+
else
|
|
356
|
+
print_names result.names
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def show_function(fs)
|
|
362
|
+
if fs.size == 1
|
|
363
|
+
if @line
|
|
364
|
+
print_names [fs.first.label]
|
|
365
|
+
else
|
|
366
|
+
describe_function fs.first
|
|
367
|
+
end
|
|
368
|
+
else
|
|
369
|
+
if @describe_all
|
|
370
|
+
fs.sort.each do |f|
|
|
371
|
+
describe_function f
|
|
372
|
+
end
|
|
373
|
+
else
|
|
374
|
+
print_names fs.map {|f| f.label }
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
private
|
|
380
|
+
|
|
381
|
+
def print_names(names)
|
|
382
|
+
if @line
|
|
383
|
+
names.sort.each do |n|
|
|
384
|
+
puts n
|
|
385
|
+
end
|
|
386
|
+
else
|
|
387
|
+
print_packed_names names.sort
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def print_packed_names(names)
|
|
392
|
+
max = terminal_column()
|
|
393
|
+
buf = ''
|
|
394
|
+
names.each do |name|
|
|
395
|
+
if buf.size + name.size + 1 > max
|
|
396
|
+
if buf.empty?
|
|
397
|
+
puts name
|
|
398
|
+
next
|
|
399
|
+
end
|
|
400
|
+
puts buf
|
|
401
|
+
buf = ''
|
|
402
|
+
end
|
|
403
|
+
buf << name << ' '
|
|
404
|
+
end
|
|
405
|
+
puts buf unless buf.empty?
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def terminal_column
|
|
409
|
+
(ENV['COLUMNS'] || 70).to_i
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def describe_class(c)
|
|
413
|
+
if c.alias?
|
|
414
|
+
describe_class(c.aliasof)
|
|
415
|
+
return
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
unless c.library.name == '_builtin'
|
|
419
|
+
puts "require '#{c.library.name}'"
|
|
420
|
+
puts
|
|
421
|
+
end
|
|
422
|
+
puts "#{c.type} #{c.name}#{c.superclass ? " < #{c.superclass.name}" : ''}"
|
|
423
|
+
unless c.included.empty?
|
|
424
|
+
puts
|
|
425
|
+
c.included.each do |mod|
|
|
426
|
+
puts "include #{mod.name}"
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
unless c.aliases.empty?
|
|
430
|
+
puts
|
|
431
|
+
c.aliases.each do |al|
|
|
432
|
+
puts "alias #{al.name}"
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
unless c.source.strip.empty?
|
|
436
|
+
puts
|
|
437
|
+
puts @compiler.compile(c.source.strip)
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def describe_method(rec)
|
|
442
|
+
unless rec.entry.library.name == '_builtin'
|
|
443
|
+
puts "require '#{rec.entry.library.name}'"
|
|
444
|
+
end
|
|
445
|
+
# FIXME: replace method signature by method spec
|
|
446
|
+
if rec.method_of_alias_class?
|
|
447
|
+
rec.specs.each do |spec|
|
|
448
|
+
puts "#{rec.origin.klass}#{rec.origin.type}#{spec.method} (#{spec.klass} is an alias of #{rec.origin.klass})"
|
|
449
|
+
end
|
|
450
|
+
elsif rec.inherited_method?
|
|
451
|
+
rec.specs.each do |spec|
|
|
452
|
+
puts "#{spec.klass}\t< #{rec.origin.klass}#{rec.origin.type}#{spec.method}"
|
|
453
|
+
end
|
|
454
|
+
else
|
|
455
|
+
rec.names.each do |name|
|
|
456
|
+
puts name
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
puts @compiler.compile(rec.entry.source.strip)
|
|
461
|
+
puts
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def describe_function(f)
|
|
465
|
+
puts "#{f.type_label} #{f.name}"
|
|
466
|
+
puts f.header
|
|
467
|
+
puts @compiler.compile(f.source.strip)
|
|
468
|
+
puts
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def puts(*args)
|
|
472
|
+
super(*args.collect {|arg| convert(arg)})
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def convert(string)
|
|
476
|
+
return string if @database.nil?
|
|
477
|
+
_output_encoding = output_encoding
|
|
478
|
+
return string if _output_encoding.nil?
|
|
479
|
+
input_nkf_option = encoding_to_nkf_option(@database.encoding)
|
|
480
|
+
output_nkf_option = encoding_to_nkf_option(_output_encoding)
|
|
481
|
+
if input_nkf_option and output_nkf_option
|
|
482
|
+
NKF.nkf("-#{input_nkf_option.upcase}#{output_nkf_option}", string)
|
|
483
|
+
else
|
|
484
|
+
string
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def output_encoding
|
|
489
|
+
return @encoding if @encoding
|
|
490
|
+
|
|
491
|
+
locale = ENV["LC_ALL"] || ENV["LC_MESSAGE"] || ENV["LANG"]
|
|
492
|
+
case locale
|
|
493
|
+
when /\.([a-z\d\-]+)\z/i
|
|
494
|
+
$1
|
|
495
|
+
else
|
|
496
|
+
nil
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def encoding_to_nkf_option(encoding)
|
|
501
|
+
return nil if encoding.nil?
|
|
502
|
+
case encoding
|
|
503
|
+
when /\A(?:euc[-_]?jp|ujis)\z/i
|
|
504
|
+
"e"
|
|
505
|
+
when /\Autf[-_]?8\z/i
|
|
506
|
+
"w"
|
|
507
|
+
when /\As(?:hift[-_]?)?jis\z/i
|
|
508
|
+
"s"
|
|
509
|
+
when /\Aiso-2022-jp\z/i
|
|
510
|
+
"j"
|
|
511
|
+
else
|
|
512
|
+
nil
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
end
|