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,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
|