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.
Files changed (127) hide show
  1. data/ChangeLog +2907 -0
  2. data/Gemfile +7 -0
  3. data/README +21 -0
  4. data/Rakefile +20 -0
  5. data/bin/bitclust +14 -0
  6. data/bin/refe +36 -0
  7. data/bitclust-dev.gemspec +33 -0
  8. data/bitclust.gemspec +30 -0
  9. data/config.in +23 -0
  10. data/config.ru +48 -0
  11. data/config.ru.sample +31 -0
  12. data/data/bitclust/catalog/ja_JP.EUC-JP +78 -0
  13. data/data/bitclust/catalog/ja_JP.UTF-8 +78 -0
  14. data/data/bitclust/template.lillia/class +98 -0
  15. data/data/bitclust/template.lillia/class-index +28 -0
  16. data/data/bitclust/template.lillia/doc +48 -0
  17. data/data/bitclust/template.lillia/layout +19 -0
  18. data/data/bitclust/template.lillia/library +129 -0
  19. data/data/bitclust/template.lillia/library-index +32 -0
  20. data/data/bitclust/template.lillia/method +20 -0
  21. data/data/bitclust/template.lillia/rd_file +6 -0
  22. data/data/bitclust/template.offline/class +67 -0
  23. data/data/bitclust/template.offline/class-index +28 -0
  24. data/data/bitclust/template.offline/doc +13 -0
  25. data/data/bitclust/template.offline/function +22 -0
  26. data/data/bitclust/template.offline/function-index +24 -0
  27. data/data/bitclust/template.offline/layout +18 -0
  28. data/data/bitclust/template.offline/library +87 -0
  29. data/data/bitclust/template.offline/library-index +32 -0
  30. data/data/bitclust/template.offline/method +21 -0
  31. data/data/bitclust/template.offline/rd_file +6 -0
  32. data/data/bitclust/template/class +133 -0
  33. data/data/bitclust/template/class-index +30 -0
  34. data/data/bitclust/template/doc +14 -0
  35. data/data/bitclust/template/function +21 -0
  36. data/data/bitclust/template/function-index +25 -0
  37. data/data/bitclust/template/layout +19 -0
  38. data/data/bitclust/template/library +89 -0
  39. data/data/bitclust/template/library-index +35 -0
  40. data/data/bitclust/template/method +24 -0
  41. data/data/bitclust/template/opensearchdescription +10 -0
  42. data/data/bitclust/template/search +57 -0
  43. data/lib/bitclust.rb +9 -0
  44. data/lib/bitclust/app.rb +129 -0
  45. data/lib/bitclust/classentry.rb +425 -0
  46. data/lib/bitclust/compat.rb +39 -0
  47. data/lib/bitclust/completion.rb +531 -0
  48. data/lib/bitclust/crossrubyutils.rb +91 -0
  49. data/lib/bitclust/database.rb +181 -0
  50. data/lib/bitclust/docentry.rb +83 -0
  51. data/lib/bitclust/entry.rb +223 -0
  52. data/lib/bitclust/exception.rb +38 -0
  53. data/lib/bitclust/functiondatabase.rb +115 -0
  54. data/lib/bitclust/functionentry.rb +81 -0
  55. data/lib/bitclust/functionreferenceparser.rb +76 -0
  56. data/lib/bitclust/htmlutils.rb +80 -0
  57. data/lib/bitclust/interface.rb +87 -0
  58. data/lib/bitclust/libraryentry.rb +211 -0
  59. data/lib/bitclust/lineinput.rb +165 -0
  60. data/lib/bitclust/messagecatalog.rb +95 -0
  61. data/lib/bitclust/methoddatabase.rb +401 -0
  62. data/lib/bitclust/methodentry.rb +202 -0
  63. data/lib/bitclust/methodid.rb +209 -0
  64. data/lib/bitclust/methodsignature.rb +82 -0
  65. data/lib/bitclust/nameutils.rb +236 -0
  66. data/lib/bitclust/parseutils.rb +60 -0
  67. data/lib/bitclust/preprocessor.rb +273 -0
  68. data/lib/bitclust/rdcompiler.rb +507 -0
  69. data/lib/bitclust/refsdatabase.rb +66 -0
  70. data/lib/bitclust/requesthandler.rb +330 -0
  71. data/lib/bitclust/ridatabase.rb +349 -0
  72. data/lib/bitclust/rrdparser.rb +522 -0
  73. data/lib/bitclust/runner.rb +143 -0
  74. data/lib/bitclust/screen.rb +554 -0
  75. data/lib/bitclust/searcher.rb +518 -0
  76. data/lib/bitclust/server.rb +59 -0
  77. data/lib/bitclust/simplesearcher.rb +84 -0
  78. data/lib/bitclust/subcommand.rb +746 -0
  79. data/lib/bitclust/textutils.rb +51 -0
  80. data/lib/bitclust/version.rb +3 -0
  81. data/packer.rb +224 -0
  82. data/refe2.gemspec +29 -0
  83. data/server.exe +0 -0
  84. data/server.exy +159 -0
  85. data/server.rb +10 -0
  86. data/setup.rb +1596 -0
  87. data/standalone.rb +193 -0
  88. data/test/run_test.rb +15 -0
  89. data/test/test_bitclust.rb +81 -0
  90. data/test/test_entry.rb +39 -0
  91. data/test/test_functiondatabase.rb +55 -0
  92. data/test/test_libraryentry.rb +31 -0
  93. data/test/test_methoddatabase.rb +81 -0
  94. data/test/test_methodsignature.rb +14 -0
  95. data/test/test_nameutils.rb +324 -0
  96. data/test/test_preprocessor.rb +84 -0
  97. data/test/test_rdcompiler.rb +534 -0
  98. data/test/test_refsdatabase.rb +76 -0
  99. data/test/test_rrdparser.rb +26 -0
  100. data/test/test_runner.rb +102 -0
  101. data/test/test_simplesearcher.rb +48 -0
  102. data/theme/default/images/external.png +0 -0
  103. data/theme/default/rurema.png +0 -0
  104. data/theme/default/style.css +288 -0
  105. data/theme/default/test.css +254 -0
  106. data/theme/lillia/rurema.png +0 -0
  107. data/theme/lillia/style.css +331 -0
  108. data/theme/lillia/test.css +254 -0
  109. data/tools/bc-ancestors.rb +153 -0
  110. data/tools/bc-checkparams.rb +246 -0
  111. data/tools/bc-classes.rb +80 -0
  112. data/tools/bc-convert.rb +165 -0
  113. data/tools/bc-list.rb +63 -0
  114. data/tools/bc-methods.rb +171 -0
  115. data/tools/bc-preproc.rb +42 -0
  116. data/tools/bc-rdoc.rb +343 -0
  117. data/tools/bc-tochm.rb +301 -0
  118. data/tools/bc-tohtml.rb +125 -0
  119. data/tools/bc-tohtmlpackage.rb +241 -0
  120. data/tools/check-signature.rb +19 -0
  121. data/tools/forall-ruby.rb +20 -0
  122. data/tools/gencatalog.rb +69 -0
  123. data/tools/statrefm.rb +98 -0
  124. data/tools/stattodo.rb +150 -0
  125. data/tools/update-database.rb +146 -0
  126. data/view.cgi +6 -0
  127. metadata +222 -0
@@ -0,0 +1,91 @@
1
+ #
2
+ # bitclust/crossrubyutils.rb
3
+ #
4
+ # Copyright (c) 2006 Minero Aoki
5
+ #
6
+
7
+ module BitClust
8
+
9
+ module CrossRubyUtils
10
+
11
+ private
12
+
13
+ def print_crossruby_table(&block)
14
+ print_table(*build_crossruby_table(&block))
15
+ end
16
+
17
+ def print_table(vers, table)
18
+ thcols = ([20] + table.keys.map {|s| s.size }).max
19
+ versions = vers.map {|ver| version_id(ver) }
20
+ width_list = versions.map{|v| v.size + 1 }
21
+ print_record thcols, '', versions, width_list
22
+ crossrubyutils_sort_entries(table.keys).each do |c|
23
+ print_record thcols, c, vers.map {|ver| table[c][ver] ? 'o' : '-' }, width_list
24
+ end
25
+ end
26
+
27
+ def crossrubyutils_sort_entries(ents)
28
+ ents.sort
29
+ end
30
+
31
+ def print_record(thcols, th, tds, width_list = nil)
32
+ unless width_list
33
+ width_list = Array.new(tds.size){ 4 }
34
+ end
35
+ printf "%-#{thcols}s ", th
36
+ puts tds.zip(width_list).map {|td, width| "%#{width}s" % td }.join('')
37
+ end
38
+
39
+ def version_id(ver)
40
+ ver.split[1].tr('.', '')
41
+ end
42
+
43
+ def get_ruby(version)
44
+ forall_ruby(ENV['PATH']) do |ruby, |
45
+ v = `#{ruby} -e 'print RUBY_VERSION'`
46
+ patch = `#{ruby} -e 'print RUBY_PATCHLEVEL if defined? RUBY_PATCHLEVEL'`
47
+ if version == v or ( version == v.succ and patch == '5000')
48
+ return ruby
49
+ end
50
+ end
51
+ return nil
52
+ end
53
+
54
+ def build_crossruby_table
55
+ ENV.delete 'RUBYOPT'
56
+ ENV.delete 'RUBYLIB'
57
+ ENV.delete 'GEM_HOME'
58
+ vers = []
59
+ table = {}
60
+ forall_ruby(ENV['PATH']) do |ruby, ver|
61
+ puts "#{version_id(ver)}: #{ver}" if @verbose
62
+ vers.push ver
63
+ yield(ruby).each do |c|
64
+ (table[c] ||= {})[ver] = true
65
+ end
66
+ end
67
+ return vers, table
68
+ end
69
+
70
+ def forall_ruby(path, &block)
71
+ rubys(path)\
72
+ .map {|ruby| [ruby, `#{ruby} --version`] }\
73
+ .reject {|ruby, verstr| `which #{ruby}`.include?('@') }\
74
+ .sort_by {|ruby, verstr| verstr }\
75
+ .each(&block)
76
+ end
77
+
78
+ def rubys(path)
79
+ parse_PATH(path).map {|bindir|
80
+ Dir.glob("#{bindir}/ruby-[12t]*").map {|path| File.basename(path) }
81
+ }\
82
+ .flatten.uniq + ['ruby']
83
+ end
84
+
85
+ def parse_PATH(str)
86
+ str.split(':').map {|path| path.empty? ? '.' : path }
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,181 @@
1
+ #
2
+ # bitclust/database.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 Database
16
+
17
+ include NameUtils
18
+
19
+ def Database.datadir?(dir)
20
+ File.file?("#{dir}/properties")
21
+ end
22
+
23
+ def Database.connect(uri)
24
+ case uri.scheme
25
+ when 'file'
26
+ new(uri.path)
27
+ when 'druby'
28
+ DRbObject.new_with_uri(uri.to_s)
29
+ else
30
+ raise InvalidScheme, "unknown database scheme: #{uri.scheme}"
31
+ end
32
+ end
33
+
34
+ def Database.dummy(params = {})
35
+ db = new(nil)
36
+ db.properties['version'] = params['version']
37
+ db
38
+ end
39
+
40
+ def initialize(prefix)
41
+ @prefix = prefix
42
+ @properties = nil
43
+ @in_transaction = false
44
+ @properties_dirty = false
45
+ end
46
+
47
+ def dummy?
48
+ not @prefix
49
+ end
50
+
51
+ #
52
+ # Transaction
53
+ #
54
+
55
+ def transaction
56
+ @in_transaction = true
57
+ yield
58
+ return if dummy?
59
+ if @properties_dirty
60
+ save_properties 'properties', @properties
61
+ @properties_dirty = false
62
+ end
63
+ commit if dirty?
64
+ ensure
65
+ @in_transaction = false
66
+ end
67
+
68
+ # abstract dirty?
69
+ # abstract clear_dirty
70
+ # abstract commit
71
+
72
+ def check_transaction
73
+ return if dummy?
74
+ unless @in_transaction
75
+ raise NotInTransaction, "database changed without transaction"
76
+ end
77
+ end
78
+ private :check_transaction
79
+
80
+ #
81
+ # Properties
82
+ #
83
+
84
+ def properties
85
+ @properties ||=
86
+ begin
87
+ h = load_properties('properties')
88
+ h.delete 'source' if h['source'] and h['source'].strip.empty?
89
+ h
90
+ end
91
+ end
92
+
93
+ def propkeys
94
+ properties().keys
95
+ end
96
+
97
+ def propget(key)
98
+ properties()[key]
99
+ end
100
+
101
+ def propset(key, value)
102
+ check_transaction
103
+ properties()[key] = value
104
+ @properties_dirty = true
105
+ end
106
+
107
+ def encoding
108
+ propget('encoding')
109
+ end
110
+
111
+ #
112
+ # Direct File Access Layer: BitClust internal use only
113
+ #
114
+
115
+ def exist?(rel)
116
+ return false unless @prefix
117
+ File.exist?(realpath(rel))
118
+ end
119
+
120
+ def entries(rel)
121
+ Dir.entries(realpath(rel))\
122
+ .reject {|ent| /\A[\.=]/ =~ ent }\
123
+ .map {|ent| decodeid(ent) }
124
+ rescue Errno::ENOENT
125
+ return []
126
+ end
127
+
128
+ def makepath(rel)
129
+ FileUtils.mkdir_p realpath(rel)
130
+ end
131
+
132
+ def load_properties(rel)
133
+ h = {}
134
+ fopen(realpath(rel), 'r:UTF-8') {|f|
135
+ while line = f.gets
136
+ k, v = line.strip.split('=', 2)
137
+ break unless k
138
+ h[k] = v
139
+ end
140
+ h['source'] = f.read
141
+ }
142
+ h
143
+ rescue Errno::ENOENT
144
+ return {}
145
+ end
146
+
147
+ def save_properties(rel, h)
148
+ source = h.delete('source')
149
+ atomic_write_open(rel) {|f|
150
+ h.each do |key, val|
151
+ f.puts "#{key}=#{val}"
152
+ end
153
+ f.puts
154
+ f.puts source
155
+ }
156
+ end
157
+
158
+ def read(rel)
159
+ File.read(realpath(rel))
160
+ end
161
+
162
+ def foreach_line(rel, &block)
163
+ File.foreach(realpath(rel), &block)
164
+ end
165
+
166
+ def atomic_write_open(rel, &block)
167
+ tmppath = realpath(rel) + '.writing'
168
+ fopen(tmppath, 'wb', &block)
169
+ File.rename tmppath, realpath(rel)
170
+ ensure
171
+ File.unlink tmppath rescue nil
172
+ end
173
+
174
+ def realpath(rel)
175
+ "#{@prefix}/#{encodeid(rel)}"
176
+ end
177
+ private :realpath
178
+
179
+ end
180
+
181
+ end
@@ -0,0 +1,83 @@
1
+ #
2
+ # bitclust/docentry.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/entry'
11
+ require 'bitclust/exception'
12
+
13
+ module BitClust
14
+
15
+ class DocEntry < Entry
16
+
17
+ def self.type_id
18
+ :doc
19
+ end
20
+
21
+ def initialize(db, id)
22
+ super db
23
+ @id = id
24
+ init_properties
25
+ end
26
+
27
+ attr_reader :id
28
+
29
+ def ==(other)
30
+ @id == other.id
31
+ end
32
+
33
+ alias eql? ==
34
+
35
+ def hash
36
+ @id.hash
37
+ end
38
+
39
+ def <=>(other)
40
+ @id.casecmp(other.id)
41
+ end
42
+
43
+ def name
44
+ libid2name(@id)
45
+ end
46
+
47
+ alias label name
48
+
49
+ def labels
50
+ [label()]
51
+ end
52
+
53
+ def name?(n)
54
+ name() == n
55
+ end
56
+
57
+ persistent_properties {
58
+ property :title, 'String'
59
+ property :source, 'String'
60
+ }
61
+
62
+ def inspect
63
+ "#<doc #{@id}>"
64
+ end
65
+
66
+ def classes
67
+ @db.classes
68
+ end
69
+
70
+ def error_classes
71
+ classes.select{|c| c.ancestors.any?{|k| k.name == 'Exception' }}
72
+ end
73
+
74
+ def methods
75
+ @db.methods
76
+ end
77
+
78
+ def libraries
79
+ @db.libraries
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,223 @@
1
+ #
2
+ # bitclust/entry.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/compat'
11
+ require 'bitclust/nameutils'
12
+ require 'bitclust/exception'
13
+
14
+ module BitClust
15
+
16
+ class Entry
17
+
18
+ include NameUtils
19
+
20
+ def self.persistent_properties
21
+ @slots = []
22
+ yield
23
+ sep = ";"
24
+ module_eval(src = <<-End, __FILE__, __LINE__ + 1)
25
+ def init_properties
26
+ if saved?
27
+ #{@slots.map {|s| "@#{s.name} = nil" }.join(sep)}
28
+ @loaded = false
29
+ else
30
+ clear
31
+ end
32
+ end
33
+
34
+ def clear
35
+ #{@slots.map {|s| "@#{s.name} = #{s.initial_value}" }.join(sep)}
36
+ @loaded = true
37
+ end
38
+
39
+ def _set_properties(h)
40
+ #{@slots.map {|s| "@#{s.name} = #{s.deserializer}" }.join(sep)}
41
+ end
42
+
43
+ def _get_properties
44
+ h = {}
45
+ #{@slots.map {|s| "h['#{s.name}'] = #{s.serializer}" }.join(sep)}
46
+ h
47
+ end
48
+
49
+ def unload
50
+ clear
51
+ @loaded = false
52
+ end
53
+ End
54
+ @slots.each do |slot|
55
+ module_eval(<<-End, __FILE__, __LINE__ + 1)
56
+ def #{slot.name}
57
+ load unless @loaded
58
+ @#{slot.name}
59
+ end
60
+
61
+ def #{slot.name}=(value)
62
+ load unless @loaded
63
+ @#{slot.name} = value
64
+ end
65
+ End
66
+ end
67
+ end
68
+
69
+ def self.property(name, type)
70
+ @slots.push Property.new(name, type)
71
+ end
72
+
73
+ class Property
74
+ def initialize(name, type)
75
+ @name = name
76
+ @type = type
77
+ end
78
+
79
+ attr_reader :name
80
+
81
+ def initial_value
82
+ case @type
83
+ when 'String' then "'(uninitialized)'"
84
+ when 'Symbol' then "nil"
85
+ when 'bool' then "false"
86
+ when 'LibraryEntry' then "nil"
87
+ when 'ClassEntry' then "nil"
88
+ when 'MethodEntry' then "nil"
89
+ when '[String]' then "[]"
90
+ when '[LibraryEntry]' then "[]"
91
+ when '[ClassEntry]' then "[]"
92
+ when '[MethodEntry]' then "[]"
93
+ else
94
+ raise "must not happen: @type=#{@type.inspect}"
95
+ end
96
+ end
97
+
98
+ def deserializer
99
+ case @type
100
+ when 'String' then "h['#{@name}']"
101
+ when 'Symbol' then "h['#{@name}'].intern"
102
+ when 'bool' then "h['#{@name}'] == 'true' ? true : false"
103
+ when 'LibraryEntry' then "restore_library(h['#{@name}'])"
104
+ when 'ClassEntry' then "restore_class(h['#{@name}'])"
105
+ when 'MethodEntry' then "restore_method(h['#{@name}'])"
106
+ when '[String]' then "h['#{@name}'].split(/,(?=.)/)"
107
+ when '[LibraryEntry]' then "restore_libraries(h['#{@name}'])"
108
+ when '[ClassEntry]' then "restore_classes(h['#{@name}'])"
109
+ when '[MethodEntry]' then "restore_methods(h['#{@name}'])"
110
+ else
111
+ raise "must not happen: @type=#{@type.inspect}"
112
+ end
113
+ end
114
+
115
+ def serializer
116
+ case @type
117
+ when 'String' then "@#{@name}"
118
+ when 'Symbol' then "@#{@name}.to_s"
119
+ when 'bool' then "@#{@name}.to_s"
120
+ when 'LibraryEntry' then "serialize_entry(@#{@name})"
121
+ when 'ClassEntry' then "serialize_entry(@#{@name})"
122
+ when 'MethodEntry' then "serialize_entry(@#{@name})"
123
+ when '[String]' then "@#{@name}.join(',')"
124
+ when '[LibraryEntry]' then "serialize_entries(@#{@name})"
125
+ when '[ClassEntry]' then "serialize_entries(@#{@name})"
126
+ when '[MethodEntry]' then "serialize_entries(@#{@name})"
127
+ else
128
+ raise "must not happen: @type=#{@type.inspect}"
129
+ end
130
+ end
131
+ end
132
+
133
+ class << self
134
+ alias load new
135
+ end
136
+
137
+ def initialize(db)
138
+ @db = db
139
+ end
140
+
141
+ def type_id
142
+ self.class.type_id
143
+ end
144
+
145
+ def loaded?
146
+ @loaded
147
+ end
148
+
149
+ def encoding
150
+ @db.encoding
151
+ end
152
+
153
+ def synopsis_source
154
+ source().split(/\n\n/, 2).first || ''
155
+ end
156
+
157
+ def detail_source
158
+ source().split(/\n\n/, 2)[1] || ''
159
+ end
160
+
161
+ def save
162
+ @db.save_properties objpath(), _get_properties()
163
+ rescue Errno::ENOENT
164
+ @db.makepath File.dirname(objpath())
165
+ retry
166
+ end
167
+
168
+ private
169
+
170
+ def load
171
+ _set_properties @db.load_properties(objpath())
172
+ @loaded = true
173
+ end
174
+
175
+ def saved?
176
+ @db.exist?(objpath())
177
+ end
178
+
179
+ def restore_library(id)
180
+ LibraryEntry.load(@db, id)
181
+ end
182
+
183
+ def restore_class(id)
184
+ id.empty? ? nil : ClassEntry.load(@db, id)
185
+ end
186
+
187
+ def restore_libraries(str)
188
+ restore_entries(str, LibraryEntry)
189
+ end
190
+
191
+ def restore_classes(str)
192
+ restore_entries(str, ClassEntry)
193
+ end
194
+
195
+ def restore_methods(str)
196
+ restore_entries(str, MethodEntry)
197
+ end
198
+
199
+ def restore_entries(str, klass)
200
+ str.split(',').map {|id| klass.load(@db, id) }
201
+ end
202
+
203
+ def serialize_entry(x)
204
+ x ? x.id : ''
205
+ end
206
+
207
+ def serialize_entries(xs)
208
+ xs.map {|x| x.id }.join(',')
209
+ end
210
+
211
+ def objpath
212
+ "#{type_id()}/#{id()}"
213
+ end
214
+
215
+ def path_string(path)
216
+ i = path.index(name())
217
+ (path[i..-1] + [name()]).join(' -> ')
218
+ end
219
+ private :path_string
220
+
221
+ end
222
+
223
+ end