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,59 @@
|
|
|
1
|
+
#
|
|
2
|
+
# bitclust/server.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/methoddatabase'
|
|
11
|
+
require 'bitclust/functiondatabase'
|
|
12
|
+
require 'bitclust/libraryentry'
|
|
13
|
+
require 'bitclust/classentry'
|
|
14
|
+
require 'bitclust/methodentry'
|
|
15
|
+
require 'bitclust/docentry'
|
|
16
|
+
require 'drb'
|
|
17
|
+
require 'webrick/server'
|
|
18
|
+
|
|
19
|
+
module BitClust
|
|
20
|
+
|
|
21
|
+
class Server
|
|
22
|
+
|
|
23
|
+
def initialize(db)
|
|
24
|
+
@db = db
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def listen(url, foreground = false)
|
|
28
|
+
WEBrick::Daemon.start unless foreground
|
|
29
|
+
DRb.start_service url, @db
|
|
30
|
+
DRb.thread.join
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Database # reopen
|
|
36
|
+
include DRb::DRbUndumped
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class Entry # reopen
|
|
40
|
+
include DRb::DRbUndumped
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class SearchResult # reopen
|
|
44
|
+
include DRb::DRbUndumped
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class Object
|
|
50
|
+
def _remote_object?
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class DRb::DRbObject
|
|
56
|
+
def _remote_object?
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'bitclust/nameutils'
|
|
2
|
+
require 'bitclust/methodid'
|
|
3
|
+
|
|
4
|
+
module BitClust
|
|
5
|
+
module SimpleSearcher
|
|
6
|
+
include NameUtils
|
|
7
|
+
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def search_pattern(db, pat)
|
|
11
|
+
pat = to_pattern(pat)
|
|
12
|
+
return [] if pat.empty? or /\A\s+\z/ =~ pat
|
|
13
|
+
cname, type, mname = parse_method_spec_pattern(pat)
|
|
14
|
+
ret = cs = ms = []
|
|
15
|
+
if cname and not cname.empty?
|
|
16
|
+
if mname
|
|
17
|
+
ms = find_class_method(db, cname, type, mname)
|
|
18
|
+
cs += find_class(db, cname + '::' + mname) if /\A[A-Z]/ =~ mname
|
|
19
|
+
else
|
|
20
|
+
cs = find_class(db, cname)
|
|
21
|
+
end
|
|
22
|
+
elsif type == '$'
|
|
23
|
+
ms = find_special_vars(db, mname)
|
|
24
|
+
else
|
|
25
|
+
ms = find_methods(db, mname)
|
|
26
|
+
end
|
|
27
|
+
ms = ms.sort_by{|e| [e.library.name, e.klass.name] }
|
|
28
|
+
cs = cs.sort_by{|e| [e.library.name] }
|
|
29
|
+
cs + ms
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def find_class(db, cname)
|
|
33
|
+
db.classes.find_all{|c| /\b#{Regexp.escape(cname)}\w*\z/ =~ c.name }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def find_class_method(db, cname, type, mname)
|
|
37
|
+
ret = []
|
|
38
|
+
db.classes.each{|c|
|
|
39
|
+
if /\b#{Regexp.escape(cname)}/ =~ c.name
|
|
40
|
+
ret += c.methods.find_all{|m|
|
|
41
|
+
m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
}
|
|
45
|
+
ret
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def find_methods(db, mname)
|
|
49
|
+
db.methods.find_all{|m|
|
|
50
|
+
m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def find_special_vars(db, mname)
|
|
55
|
+
db.get_class('Kernel').special_variables.find_all{|m|
|
|
56
|
+
m.names.any?{|n| /\A#{Regexp.escape(mname)}/ =~ n }
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def to_pattern(pat)
|
|
61
|
+
pat = pat.to_str
|
|
62
|
+
pat = pat[/\A\s*(.*?)\s*\z/, 1]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def parse_method_spec_pattern(pat)
|
|
66
|
+
if /\s/ =~ pat
|
|
67
|
+
return parse_method_spec_pattern0(pat)
|
|
68
|
+
end
|
|
69
|
+
return pat, nil, nil if /\A[A-Z]\w*\z/ =~ pat
|
|
70
|
+
return nil, '$', $1 if /\$(\S*)/ =~ pat
|
|
71
|
+
_m, _t, _c = pat.reverse.split(/(::|[\#,]\.|\.[\#,]|[\#\.\,])/, 2)
|
|
72
|
+
c = _c.reverse if _c
|
|
73
|
+
t = _t.tr(',', '#').sub(/\#\./, '.#') if _t
|
|
74
|
+
m = _m.reverse
|
|
75
|
+
return c, t, m
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def parse_method_spec_pattern0(q)
|
|
79
|
+
q = q.scan(/\S+/)[0..1]
|
|
80
|
+
q = q.reverse unless /\A[A-Z]/ =~ q[0]
|
|
81
|
+
return q[0], nil, q[1]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
require 'bitclust'
|
|
4
|
+
require 'erb'
|
|
5
|
+
require 'find'
|
|
6
|
+
require 'pp'
|
|
7
|
+
require 'optparse'
|
|
8
|
+
require 'yaml'
|
|
9
|
+
|
|
10
|
+
module BitClust
|
|
11
|
+
|
|
12
|
+
class Subcommand
|
|
13
|
+
def parse(argv)
|
|
14
|
+
@parser.parse! argv
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def help
|
|
18
|
+
@parser.help
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# TODO refactor
|
|
22
|
+
def error(message)
|
|
23
|
+
$stderr.puts "#{File.basename($0, '.*')}: error: #{message}"
|
|
24
|
+
exit 1
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InitCommand < Subcommand
|
|
30
|
+
|
|
31
|
+
def initialize
|
|
32
|
+
@parser = OptionParser.new {|opt|
|
|
33
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} init [KEY=VALUE ...]"
|
|
34
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
35
|
+
puts opt.help
|
|
36
|
+
exit 0
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
STANDARD_PROPERTIES = %w( encoding version )
|
|
42
|
+
|
|
43
|
+
def exec(db, argv)
|
|
44
|
+
db.init
|
|
45
|
+
db.transaction {
|
|
46
|
+
argv.each do |kv|
|
|
47
|
+
k, v = kv.split('=', 2)
|
|
48
|
+
db.propset k, v
|
|
49
|
+
end
|
|
50
|
+
}
|
|
51
|
+
fail = false
|
|
52
|
+
STANDARD_PROPERTIES.each do |key|
|
|
53
|
+
unless db.propget(key)
|
|
54
|
+
$stderr.puts "#{File.basename($0, '.*')}: warning: standard property `#{key}' not given"
|
|
55
|
+
fail = true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
if fail
|
|
59
|
+
$stderr.puts "---- Current Properties ----"
|
|
60
|
+
db.properties.each do |key, value|
|
|
61
|
+
$stderr.puts "#{key}=#{value}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class UpdateCommand < Subcommand
|
|
70
|
+
|
|
71
|
+
def initialize
|
|
72
|
+
@root = nil
|
|
73
|
+
@library = nil
|
|
74
|
+
@parser = OptionParser.new {|opt|
|
|
75
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} update [<file>...]"
|
|
76
|
+
opt.on('--stdlibtree=ROOT', 'Process stdlib source directory tree.') {|path|
|
|
77
|
+
@root = path
|
|
78
|
+
}
|
|
79
|
+
opt.on('--library-name=NAME', 'Use NAME for library name in file mode.') {|name|
|
|
80
|
+
@library = name
|
|
81
|
+
}
|
|
82
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
83
|
+
puts opt.help
|
|
84
|
+
exit 0
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def parse(argv)
|
|
90
|
+
super
|
|
91
|
+
if not @root and argv.empty?
|
|
92
|
+
error "no input file given"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def exec(db, argv)
|
|
97
|
+
db.transaction {
|
|
98
|
+
if @root
|
|
99
|
+
db.update_by_stdlibtree @root
|
|
100
|
+
end
|
|
101
|
+
argv.each do |path|
|
|
102
|
+
db.update_by_file path, @library || guess_library_name(path)
|
|
103
|
+
end
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def guess_library_name(path)
|
|
110
|
+
if %r<(\A|/)src/> =~ path
|
|
111
|
+
path.sub(%r<.*(\A|/)src/>, '').sub(/\.rd\z/, '')
|
|
112
|
+
else
|
|
113
|
+
path
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def get_c_filename(path)
|
|
118
|
+
File.basename(path, '.rd')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ListCommand < Subcommand
|
|
125
|
+
|
|
126
|
+
def initialize
|
|
127
|
+
@mode = nil
|
|
128
|
+
@parser = OptionParser.new {|opt|
|
|
129
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} list (--library|--class|--method|--function)"
|
|
130
|
+
opt.on('--library', 'List libraries.') {
|
|
131
|
+
@mode = :library
|
|
132
|
+
}
|
|
133
|
+
opt.on('--class', 'List classes.') {
|
|
134
|
+
@mode = :class
|
|
135
|
+
}
|
|
136
|
+
opt.on('--method', 'List methods.') {
|
|
137
|
+
@mode = :method
|
|
138
|
+
}
|
|
139
|
+
opt.on('--function', 'List functions.') {
|
|
140
|
+
@mode = :function
|
|
141
|
+
}
|
|
142
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
143
|
+
puts opt.help
|
|
144
|
+
exit 0
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def parse(argv)
|
|
150
|
+
super
|
|
151
|
+
unless @mode
|
|
152
|
+
error 'one of (--library|--class|--method|--function) is required'
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def exec(db, argv)
|
|
157
|
+
case @mode
|
|
158
|
+
when :library
|
|
159
|
+
db.libraries.map {|lib| lib.name }.sort.each do |name|
|
|
160
|
+
puts name
|
|
161
|
+
end
|
|
162
|
+
when :class
|
|
163
|
+
db.classes.map {|c| c.name }.sort.each do |name|
|
|
164
|
+
puts name
|
|
165
|
+
end
|
|
166
|
+
when :method
|
|
167
|
+
db.classes.sort_by {|c| c.name }.each do |c|
|
|
168
|
+
c.entries.sort_by {|m| m.id }.each do |m|
|
|
169
|
+
puts m.label
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
when :function
|
|
173
|
+
db.functions.sort_by {|f| f.name }.each do |f|
|
|
174
|
+
puts f.name
|
|
175
|
+
end
|
|
176
|
+
else
|
|
177
|
+
raise "must not happen: @mode=#{@mode.inspect}"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class LookupCommand < Subcommand
|
|
185
|
+
|
|
186
|
+
def initialize
|
|
187
|
+
@format = :text
|
|
188
|
+
@type = nil
|
|
189
|
+
@key = nil
|
|
190
|
+
@parser = OptionParser.new {|opt|
|
|
191
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} lookup (--library|--class|--method|--function) [--html] <key>"
|
|
192
|
+
opt.on('--library=NAME', 'Lookup library.') {|name|
|
|
193
|
+
@type = :library
|
|
194
|
+
@key = name
|
|
195
|
+
}
|
|
196
|
+
opt.on('--class=NAME', 'Lookup class.') {|name|
|
|
197
|
+
@type = :class
|
|
198
|
+
@key = name
|
|
199
|
+
}
|
|
200
|
+
opt.on('--method=NAME', 'Lookup method.') {|name|
|
|
201
|
+
@type = :method
|
|
202
|
+
@key = name
|
|
203
|
+
}
|
|
204
|
+
opt.on('--function=NAME', 'Lookup function.') {|name|
|
|
205
|
+
@type = :function
|
|
206
|
+
@key = name
|
|
207
|
+
}
|
|
208
|
+
opt.on('--html', 'Show result in HTML.') {
|
|
209
|
+
@format = :html
|
|
210
|
+
}
|
|
211
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
212
|
+
puts opt.help
|
|
213
|
+
exit 0
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def parse(argv)
|
|
219
|
+
super
|
|
220
|
+
unless @type
|
|
221
|
+
error "one of --library/--class/--method/--function is required"
|
|
222
|
+
end
|
|
223
|
+
unless argv.empty?
|
|
224
|
+
error "too many arguments"
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def exec(db, argv)
|
|
229
|
+
entry = fetch_entry(db, @type, @key)
|
|
230
|
+
puts fill_template(get_template(@type, @format), entry)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def fetch_entry(db, type, key)
|
|
234
|
+
case type
|
|
235
|
+
when :library
|
|
236
|
+
db.fetch_library(key)
|
|
237
|
+
when :class
|
|
238
|
+
db.fetch_class(key)
|
|
239
|
+
when :method
|
|
240
|
+
db.fetch_method(BitClust::MethodSpec.parse(key))
|
|
241
|
+
when :function
|
|
242
|
+
db.fetch_function(key)
|
|
243
|
+
else
|
|
244
|
+
raise "must not happen: #{type.inspect}"
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def fill_template(template, entry)
|
|
249
|
+
ERB.new(template).result(binding())
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def get_template(type, format)
|
|
253
|
+
template = TEMPLATE[type][format]
|
|
254
|
+
BitClust::TextUtils.unindent_block(template.lines).join('')
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
TEMPLATE = {
|
|
258
|
+
:library => {
|
|
259
|
+
:text => <<-End,
|
|
260
|
+
type: library
|
|
261
|
+
name: <%= entry.name %>
|
|
262
|
+
classes: <%= entry.classes.map {|c| c.name }.sort.join(', ') %>
|
|
263
|
+
methods: <%= entry.methods.map {|m| m.name }.sort.join(', ') %>
|
|
264
|
+
|
|
265
|
+
<%= entry.source %>
|
|
266
|
+
End
|
|
267
|
+
:html => <<-End
|
|
268
|
+
<dl>
|
|
269
|
+
<dt>type</dt><dd>library</dd>
|
|
270
|
+
<dt>name</dt><dd><%= entry.name %></dd>
|
|
271
|
+
<dt>classes</dt><dd><%= entry.classes.map {|c| c.name }.sort.join(', ') %></dd>
|
|
272
|
+
<dt>methods</dt><dd><%= entry.methods.map {|m| m.name }.sort.join(', ') %></dd>
|
|
273
|
+
</dl>
|
|
274
|
+
<%= compile_rd(entry.source) %>
|
|
275
|
+
End
|
|
276
|
+
},
|
|
277
|
+
:class => {
|
|
278
|
+
:text => <<-End,
|
|
279
|
+
type: class
|
|
280
|
+
name: <%= entry.name %>
|
|
281
|
+
library: <%= entry.library.name %>
|
|
282
|
+
singleton_methods: <%= entry.singleton_methods.map {|m| m.name }.sort.join(', ') %>
|
|
283
|
+
instance_methods: <%= entry.instance_methods.map {|m| m.name }.sort.join(', ') %>
|
|
284
|
+
constants: <%= entry.constants.map {|m| m.name }.sort.join(', ') %>
|
|
285
|
+
special_variables: <%= entry.special_variables.map {|m| '$' + m.name }.sort.join(', ') %>
|
|
286
|
+
|
|
287
|
+
<%= entry.source %>
|
|
288
|
+
End
|
|
289
|
+
:html => <<-End
|
|
290
|
+
<dl>
|
|
291
|
+
<dt>type</dt><dd>class</dd>
|
|
292
|
+
<dt>name</dt><dd><%= entry.name %></dd>
|
|
293
|
+
<dt>library</dt><dd><%= entry.library.name %></dd>
|
|
294
|
+
<dt>singleton_methods</dt><dd><%= entry.singleton_methods.map {|m| m.name }.sort.join(', ') %></dd>
|
|
295
|
+
<dt>instance_methods</dt><dd><%= entry.instance_methods.map {|m| m.name }.sort.join(', ') %></dd>
|
|
296
|
+
</dl>
|
|
297
|
+
<%= compile_rd(entry.source) %>
|
|
298
|
+
End
|
|
299
|
+
},
|
|
300
|
+
:method => {
|
|
301
|
+
:text => <<-End,
|
|
302
|
+
type: <%= entry.type %>
|
|
303
|
+
name: <%= entry.name %>
|
|
304
|
+
names: <%= entry.names.sort.join(', ') %>
|
|
305
|
+
visibility: <%= entry.visibility %>
|
|
306
|
+
kind: <%= entry.kind %>
|
|
307
|
+
library: <%= entry.library.name %>
|
|
308
|
+
|
|
309
|
+
<%= entry.source %>
|
|
310
|
+
End
|
|
311
|
+
:html => <<-End
|
|
312
|
+
<dl>
|
|
313
|
+
<dt>type</dt><dd><%= entry.type %></dd>
|
|
314
|
+
<dt>name</dt><dd><%= entry.name %></dd>
|
|
315
|
+
<dt>names</dt><dd><%= entry.names.sort.join(', ') %></dd>
|
|
316
|
+
<dt>visibility</dt><dd><%= entry.visibility %></dd>
|
|
317
|
+
<dt>kind</dt><dd><%= entry.kind %></dd>
|
|
318
|
+
<dt>library</dt><dd><%= entry.library.name %></dd>
|
|
319
|
+
</dl>
|
|
320
|
+
<%= compile_rd(entry.source) %>
|
|
321
|
+
End
|
|
322
|
+
},
|
|
323
|
+
:function => {
|
|
324
|
+
:text => <<-End,
|
|
325
|
+
kind: <%= entry.kind %>
|
|
326
|
+
header: <%= entry.header %>
|
|
327
|
+
filename: <%= entry.filename %>
|
|
328
|
+
|
|
329
|
+
<%= entry.source %>
|
|
330
|
+
End
|
|
331
|
+
:html => <<-End
|
|
332
|
+
<dl>
|
|
333
|
+
<dt>kind</dt><dd><%= entry.kind %></dd>
|
|
334
|
+
<dt>header</dt><dd><%= entry.header %></dd>
|
|
335
|
+
<dt>filename</dt><dd><%= entry.filename %></dd>
|
|
336
|
+
</dl>
|
|
337
|
+
<%= compile_rd(entry.source) %>
|
|
338
|
+
End
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
def compile_rd(src)
|
|
343
|
+
umap = BitClust::URLMapper.new(:base_url => 'http://example.com',
|
|
344
|
+
:cgi_url => 'http://example.com/view')
|
|
345
|
+
compiler = BitClust::RDCompiler.new(umap, 2)
|
|
346
|
+
compiler.compile(src)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
class QueryCommand < Subcommand
|
|
353
|
+
|
|
354
|
+
def initialize
|
|
355
|
+
@parser = OptionParser.new {|opt|
|
|
356
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} query <ruby-script>"
|
|
357
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
358
|
+
puts opt.help
|
|
359
|
+
exit 0
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def parse(argv)
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def exec(db, argv)
|
|
368
|
+
argv.each do |query|
|
|
369
|
+
#pp eval(query) # FIXME: causes ArgumentError
|
|
370
|
+
p eval(query)
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
class PropertyCommand < Subcommand
|
|
377
|
+
|
|
378
|
+
def initialize
|
|
379
|
+
@mode = nil
|
|
380
|
+
@parser = OptionParser.new {|opt|
|
|
381
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} property [options]"
|
|
382
|
+
opt.on('--list', 'List all properties.') {
|
|
383
|
+
@mode = :list
|
|
384
|
+
}
|
|
385
|
+
opt.on('--get', 'Get property value.') {
|
|
386
|
+
@mode = :get
|
|
387
|
+
}
|
|
388
|
+
opt.on('--set', 'Set property value.') {
|
|
389
|
+
@mode = :set
|
|
390
|
+
}
|
|
391
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
392
|
+
puts opt.help
|
|
393
|
+
exit 0
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
def parse(argv)
|
|
399
|
+
super
|
|
400
|
+
unless @mode
|
|
401
|
+
error "one of (--list|--get|--set) is required"
|
|
402
|
+
end
|
|
403
|
+
case @mode
|
|
404
|
+
when :list
|
|
405
|
+
unless argv.empty?
|
|
406
|
+
error "--list requires no argument"
|
|
407
|
+
end
|
|
408
|
+
when :get
|
|
409
|
+
;
|
|
410
|
+
when :set
|
|
411
|
+
unless argv.size == 2
|
|
412
|
+
error "--set requires just 2 arguments"
|
|
413
|
+
end
|
|
414
|
+
else
|
|
415
|
+
raise "must not happen: #{@mode}"
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def exec(db, argv)
|
|
420
|
+
case @mode
|
|
421
|
+
when :list
|
|
422
|
+
db.properties.each do |key, val|
|
|
423
|
+
puts "#{key}=#{val}"
|
|
424
|
+
end
|
|
425
|
+
when :get
|
|
426
|
+
argv.each do |key|
|
|
427
|
+
puts db.propget(key)
|
|
428
|
+
end
|
|
429
|
+
when :set
|
|
430
|
+
key, val = *argv
|
|
431
|
+
db.transaction {
|
|
432
|
+
db.propset key, val
|
|
433
|
+
}
|
|
434
|
+
else
|
|
435
|
+
raise "must not happen: #{@mode}"
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
class SetupCommand < Subcommand
|
|
442
|
+
|
|
443
|
+
REPOSITORY_PATH = "http://jp.rubyist.net/svn/rurema/doctree/trunk"
|
|
444
|
+
|
|
445
|
+
def initialize
|
|
446
|
+
@prepare = nil
|
|
447
|
+
@cleanup = nil
|
|
448
|
+
@versions = ["1.8.7", "1.9.2", "1.9.3"]
|
|
449
|
+
@parser = OptionParser.new {|opt|
|
|
450
|
+
opt.banner = "Usage: #{File.basename($0, '.*')} setup [options]"
|
|
451
|
+
opt.on('--prepare', 'Prepare config file and checkout repository. Do not create database.') {
|
|
452
|
+
@prepare = true
|
|
453
|
+
}
|
|
454
|
+
opt.on('--cleanup', 'Cleanup datebase before create database.') {
|
|
455
|
+
@cleanup = true
|
|
456
|
+
}
|
|
457
|
+
opt.on('--versions=V1,V2,...', "Specify versions. [#{@versions.join(',')}]") {|versions|
|
|
458
|
+
@versions = versions.split(",")
|
|
459
|
+
}
|
|
460
|
+
opt.on('--help', 'Prints this message and quit.') {
|
|
461
|
+
puts opt.help
|
|
462
|
+
exit 0
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def exec(db, argv)
|
|
468
|
+
prepare
|
|
469
|
+
return if @prepare
|
|
470
|
+
@config[:versions].each do |version|
|
|
471
|
+
puts "Generating database for Ruby#{version}..."
|
|
472
|
+
prefix = "#{@config[:database_prefix]}-#{version}"
|
|
473
|
+
FileUtils.rm_ rf(prefix) if @cleanup
|
|
474
|
+
init_argv = ["version=#{version}", "encoding=#{@config[:encoding]}"]
|
|
475
|
+
db = BitClust::MethodDatabase.new(prefix)
|
|
476
|
+
InitCommand.new.exec(db, init_argv)
|
|
477
|
+
update_method_database(prefix, ["--stdlibtree=#{@config[:stdlibtree]}"])
|
|
478
|
+
argv = Pathname(@config[:capi_src]).children.select(&:file?).map{|v| v.realpath.to_s }
|
|
479
|
+
update_function_database(prefix, argv)
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
private
|
|
484
|
+
|
|
485
|
+
def prepare
|
|
486
|
+
home_directory = Pathname(ENV["HOME"])
|
|
487
|
+
config_dir = home_directory + ".bitclust"
|
|
488
|
+
config_dir.mkpath
|
|
489
|
+
config_path = config_dir + "config"
|
|
490
|
+
rubydoc_dir = config_dir + "rubydoc"
|
|
491
|
+
@config = {
|
|
492
|
+
:database_prefix => (config_dir + "db").to_s,
|
|
493
|
+
:encoding => "utf-8",
|
|
494
|
+
:versions => @versions,
|
|
495
|
+
:default_version => @versions.max,
|
|
496
|
+
:stdlibtree => (rubydoc_dir + "refm/api/src").to_s,
|
|
497
|
+
:capi_src => (rubydoc_dir + "refm/capi/src/").to_s,
|
|
498
|
+
:beseurl => "http://localhost:10080",
|
|
499
|
+
:port => "10080",
|
|
500
|
+
:pid_file => "/tmp/bitclust.pid",
|
|
501
|
+
}
|
|
502
|
+
if config_path.exist?
|
|
503
|
+
@config = YAML.load_file(config_path)
|
|
504
|
+
unless @config[:versions] == @versions
|
|
505
|
+
@config[:versions] = @versions
|
|
506
|
+
@config[:default_version] = @versions.max
|
|
507
|
+
end
|
|
508
|
+
generate_config(config_path, @config)
|
|
509
|
+
else
|
|
510
|
+
generate_config(config_path, @config)
|
|
511
|
+
end
|
|
512
|
+
checkout(rubydoc_dir)
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
def generate_config(path, config)
|
|
516
|
+
path.open("w+", 0644) do |file|
|
|
517
|
+
file.puts config.to_yaml
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def checkout(rubydoc_dir)
|
|
522
|
+
system("svn", "co", REPOSITORY_PATH, rubydoc_dir.to_s)
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def update_method_database(prefix, argv)
|
|
526
|
+
db = BitClust::MethodDatabase.new(prefix)
|
|
527
|
+
cmd = UpdateCommand.new
|
|
528
|
+
cmd.parse(argv)
|
|
529
|
+
cmd.exec(db, argv)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
def update_function_database(prefix, argv)
|
|
533
|
+
db = BitClust::FunctionDatabase.new(prefix)
|
|
534
|
+
cmd = UpdateCommand.new
|
|
535
|
+
cmd.parse(argv)
|
|
536
|
+
cmd.exec(db, argv)
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
class ServerCommand < Subcommand
|
|
542
|
+
|
|
543
|
+
def initialize
|
|
544
|
+
require 'webrick'
|
|
545
|
+
require 'uri'
|
|
546
|
+
|
|
547
|
+
@params = {
|
|
548
|
+
:Port => 10080
|
|
549
|
+
}
|
|
550
|
+
@baseurl = nil
|
|
551
|
+
@dbpath = nil
|
|
552
|
+
@srcdir = @datadir = @themedir = @theme = @templatedir = nil
|
|
553
|
+
@encoding = 'utf-8' # encoding of view
|
|
554
|
+
if Object.const_defined?(:Encoding)
|
|
555
|
+
Encoding.default_external = @encoding
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
@debugp = false
|
|
559
|
+
@autop = false
|
|
560
|
+
@browser = nil
|
|
561
|
+
@pid_file = nil
|
|
562
|
+
@capi = false
|
|
563
|
+
|
|
564
|
+
@parser = OptionParser.new
|
|
565
|
+
@parser.banner = "#{$0} [--bind-address=ADDR] [--port=NUM] --baseurl=URL --database=PATH [--srcdir=PATH] [--datadir=PATH] [--themedir=PATH] [--debug] [--auto] [--browser=BROWSER] [--pid-file=PATH] [--capi]"
|
|
566
|
+
@parser.on('--bind-address=ADDR', 'Bind address') {|addr|
|
|
567
|
+
@params[:BindAddress] = addr
|
|
568
|
+
}
|
|
569
|
+
@parser.on('--port=NUM', 'Listening port number') {|num|
|
|
570
|
+
@params[:Port] = num.to_i
|
|
571
|
+
}
|
|
572
|
+
@parser.on('--baseurl=URL', 'The base URL to host.') {|url|
|
|
573
|
+
@baseurl = url
|
|
574
|
+
}
|
|
575
|
+
@parser.on('--database=PATH', 'MethodDatabase root directory.') {|path|
|
|
576
|
+
@dbpath = path
|
|
577
|
+
}
|
|
578
|
+
@parser.on('--srcdir=PATH', 'BitClust source directory.') {|path|
|
|
579
|
+
@set_srcdir.call path
|
|
580
|
+
}
|
|
581
|
+
@parser.on('--datadir=PATH', 'BitClust data directory.') {|path|
|
|
582
|
+
@datadir = path
|
|
583
|
+
}
|
|
584
|
+
@parser.on('--templatedir=PATH', 'Template directory.') {|path|
|
|
585
|
+
@templatedir = path
|
|
586
|
+
}
|
|
587
|
+
@parser.on('--themedir=PATH', 'BitClust theme directory.') {|path|
|
|
588
|
+
@themedir = path
|
|
589
|
+
}
|
|
590
|
+
@parser.on('--theme=THEME', 'BitClust theme.') {|th|
|
|
591
|
+
@theme = th
|
|
592
|
+
}
|
|
593
|
+
@parser.on('--[no-]debug', 'Debug mode.') {|flag|
|
|
594
|
+
@debugp = flag
|
|
595
|
+
}
|
|
596
|
+
@parser.on('--[no-]auto', 'Auto mode.') {|flag|
|
|
597
|
+
@autop = flag
|
|
598
|
+
}
|
|
599
|
+
@parser.on('--browser=BROWSER', 'Open with the browser.') {|path|
|
|
600
|
+
@browser = path
|
|
601
|
+
}
|
|
602
|
+
@parser.on('--pid-file=PATH', 'Write pid of the daemon to the specified file.') {|path|
|
|
603
|
+
@pid_file = path
|
|
604
|
+
}
|
|
605
|
+
@parser.on('--help', 'Prints this message and quit.') {
|
|
606
|
+
puts @parser.help
|
|
607
|
+
exit 0
|
|
608
|
+
}
|
|
609
|
+
@parser.on('--capi', 'see also FunctionDatabase.') {|path|
|
|
610
|
+
@capi = true
|
|
611
|
+
}
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
def parse(argv)
|
|
615
|
+
super
|
|
616
|
+
load_config_file
|
|
617
|
+
set_srcdir(srcdir_root) unless @srcdir
|
|
618
|
+
|
|
619
|
+
unless @baseurl
|
|
620
|
+
$stderr.puts "missing base URL. Use --baseurl or check ~/.bitclust/config"
|
|
621
|
+
exit 1
|
|
622
|
+
end
|
|
623
|
+
unless @dbpath || @autop
|
|
624
|
+
$stderr.puts "missing database path. Use --database"
|
|
625
|
+
exit 1
|
|
626
|
+
end
|
|
627
|
+
unless @datadir
|
|
628
|
+
$stderr.puts "missing datadir. Use --datadir"
|
|
629
|
+
exit 1
|
|
630
|
+
end
|
|
631
|
+
unless @themedir
|
|
632
|
+
$stderr.puts "missing themedir. Use --themedir"
|
|
633
|
+
exit 1
|
|
634
|
+
end
|
|
635
|
+
if @pid_file
|
|
636
|
+
if File.exist?(@pid_file)
|
|
637
|
+
$stderr.puts "There is still #{pid_file}. Is another process running?"
|
|
638
|
+
exit 1
|
|
639
|
+
end
|
|
640
|
+
@pid_file = File.expand_path(@pid_file)
|
|
641
|
+
end
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
def exec(db, argv)
|
|
645
|
+
require 'bitclust/app'
|
|
646
|
+
if @debugp
|
|
647
|
+
@params[:Logger] = WEBrick::Log.new($stderr, WEBrick::Log::DEBUG)
|
|
648
|
+
@params[:AccessLog] = [
|
|
649
|
+
[ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
|
|
650
|
+
[ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
|
|
651
|
+
[ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT ],
|
|
652
|
+
]
|
|
653
|
+
else
|
|
654
|
+
@params[:Logger] = WEBrick::Log.new($stderr, WEBrick::Log::INFO)
|
|
655
|
+
@params[:AccessLog] = []
|
|
656
|
+
end
|
|
657
|
+
basepath = URI.parse(@baseurl).path
|
|
658
|
+
server = WEBrick::HTTPServer.new(@params)
|
|
659
|
+
|
|
660
|
+
if @autop
|
|
661
|
+
app = BitClust::App.new(
|
|
662
|
+
:dbpath => Dir.glob("db-*"),
|
|
663
|
+
:baseurl => @baseurl,
|
|
664
|
+
:datadir => @datadir,
|
|
665
|
+
:templatedir => @templatedir,
|
|
666
|
+
:theme => @theme,
|
|
667
|
+
:encoding => @encoding,
|
|
668
|
+
:capi => @capi
|
|
669
|
+
)
|
|
670
|
+
app.interfaces.each do |version, interface|
|
|
671
|
+
server.mount File.join(basepath, version), interface
|
|
672
|
+
end
|
|
673
|
+
server.mount(File.join(basepath, '/'), app)
|
|
674
|
+
else
|
|
675
|
+
viewpath = File.join(basepath, 'view')
|
|
676
|
+
app = BitClust::App.new(
|
|
677
|
+
:viewpath => viewpath,
|
|
678
|
+
:dbpath => @dbpath,
|
|
679
|
+
:baseurl => @baseurl,
|
|
680
|
+
:datadir => @datadir,
|
|
681
|
+
:templatedir => @templatedir,
|
|
682
|
+
:theme => @theme,
|
|
683
|
+
:encoding => @encoding,
|
|
684
|
+
:capi => @capi
|
|
685
|
+
)
|
|
686
|
+
app.interfaces.each do |viewpath, interface|
|
|
687
|
+
server.mount viewpath, interface
|
|
688
|
+
end
|
|
689
|
+
# Redirect from '/' to "#{viewpath}/"
|
|
690
|
+
server.mount('/', app)
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
server.mount File.join(basepath, 'theme/'), WEBrick::HTTPServlet::FileHandler, @themedir
|
|
694
|
+
|
|
695
|
+
if @debugp
|
|
696
|
+
trap(:INT) { server.shutdown }
|
|
697
|
+
else
|
|
698
|
+
WEBrick::Daemon.start do
|
|
699
|
+
trap(:TERM) {
|
|
700
|
+
server.shutdown
|
|
701
|
+
begin
|
|
702
|
+
File.unlink @pid_file if @pid_file
|
|
703
|
+
rescue Errno::ENOENT
|
|
704
|
+
end
|
|
705
|
+
}
|
|
706
|
+
File.open(@pid_file, 'w') {|f| f.write Process.pid } if @pid_file
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
exit if $".include?("exerb/mkexy.rb")
|
|
710
|
+
if @autop && !@browser
|
|
711
|
+
case RUBY_PLATFORM
|
|
712
|
+
when /mswin/
|
|
713
|
+
@browser = "start"
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
system("#{browser} http://localhost:#{params[:Port]}/") if @browser
|
|
717
|
+
server.start
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
private
|
|
721
|
+
|
|
722
|
+
def srcdir_root
|
|
723
|
+
Pathname.new(__FILE__).realpath.dirname.parent.parent.cleanpath
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
def set_srcdir(dir)
|
|
727
|
+
@srcdir ||= dir
|
|
728
|
+
@datadir ||= "#{@srcdir}/data/bitclust"
|
|
729
|
+
@themedir ||= "#{@srcdir}/theme"
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
def load_config_file
|
|
733
|
+
home_directory = Pathname(ENV['HOME'])
|
|
734
|
+
config_path = home_directory + ".bitclust/config"
|
|
735
|
+
if config_path.exist?
|
|
736
|
+
config = YAML.load_file(config_path)
|
|
737
|
+
@baseurl ||= config[:baseurl]
|
|
738
|
+
@dbpath ||= "#{config[:database_prefix]}-#{config[:default_version]}"
|
|
739
|
+
@port ||= config[:port]
|
|
740
|
+
@pid_file ||= config[:pid_file]
|
|
741
|
+
end
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
end
|