bitclust-dev 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bitclust.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'bitclust/requesthandler'
2
+ require 'bitclust/screen'
3
+ require 'bitclust/server'
4
+ require 'bitclust/searcher'
5
+ require 'bitclust/methoddatabase'
6
+ require 'bitclust/functiondatabase'
7
+ require 'bitclust/rrdparser'
8
+ require 'bitclust/exception'
9
+ require 'bitclust/version'
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ bindir = Pathname.new(__FILE__).realpath.dirname
6
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
7
+
8
+ require 'bitclust'
9
+ require 'bitclust/crossrubyutils'
10
+ require 'optparse'
11
+ require 'set'
12
+
13
+ include BitClust::CrossRubyUtils
14
+
15
+ def main
16
+ prefix = nil
17
+ requires = []
18
+ ver = RUBY_VERSION
19
+ @verbose = false
20
+ all = false
21
+ parser = OptionParser.new
22
+ parser.banner =<<BANNER
23
+ Usage: #{File.basename($0, '.*')} [-r<lib>] [--ruby=<VER>] --db=PATH <classname>
24
+ #{File.basename($0, '.*')} [-r<lib>] [--ruby=<VER>] --db=PATH --all
25
+ NG Sample:
26
+ $ #{File.basename($0, '.*')} -rfoo --ruby=1.9.1 --db=./db Foo
27
+ NG : Foo
28
+ + FooModule (The Ruby have this class/module in ancestors of the class)
29
+ - BarModule (The Database have this class/module in ancestors of the class)
30
+ Options:
31
+ BANNER
32
+ parser.on('-d', '--database=PATH', 'Database prefix.') {|path|
33
+ prefix = path
34
+ }
35
+ parser.on('-r LIB', 'Requires library LIB') {|lib|
36
+ requires.push lib
37
+ }
38
+ parser.on('--ruby=[VER]', "The version of Ruby interpreter"){|ver|
39
+ ver = ver
40
+ }
41
+ parser.on('-v', '--verbose', 'Show differences'){
42
+ @verbose = true
43
+ }
44
+ parser.on('--all', 'Check anccestors for all classes'){
45
+ all = true
46
+ }
47
+ parser.on('--help', 'Prints this message and quit.') {
48
+ puts parser.help
49
+ exit 0
50
+ }
51
+ begin
52
+ parser.parse!
53
+ rescue OptionParser::ParseError => err
54
+ $stderr.puts err.message
55
+ $stderr.puts parser.help
56
+ exit 1
57
+ end
58
+ unless ARGV.size == 1 || all
59
+ $stderr.puts "wrong number of arguments"
60
+ $stderr.puts parser.help
61
+ exit 1
62
+ end
63
+ classname = ARGV[0]
64
+ db = BitClust::MethodDatabase.new(prefix)
65
+ ruby = get_ruby(ver)
66
+ if classname && !all
67
+ check_ancestors(db, ruby, requires, classname)
68
+ else
69
+ $stderr.puts 'check all...'
70
+ check_all_ancestors(db, ruby, requires)
71
+ end
72
+ end
73
+
74
+ def ancestors(ruby, requires, classname)
75
+ req = requires.map{|lib|
76
+ unless '_builtin' == lib
77
+ "-r#{lib}"
78
+ else
79
+ ''
80
+ end
81
+ }.join(" ")
82
+ script =<<-SRC
83
+ c = #{classname}
84
+ puts c.ancestors.join("\n")
85
+ SRC
86
+ `#{ruby} #{req} -e '#{script}'`.split
87
+ end
88
+
89
+ def check_ancestors(db, ruby, requires, classname)
90
+ a = ancestors(ruby, requires, classname)
91
+ begin
92
+ b = db.fetch_class(classname).ancestors.map(&:name)
93
+ rescue BitClust::ClassNotFound => ex
94
+ $stderr.puts "class not found in database : #{classname}"
95
+ b = []
96
+ end
97
+ unless a.to_set == b.to_set
98
+ puts "NG : #{classname}"
99
+ puts (a-b).map{|c| "+ #{c}" }.join("\n")
100
+ puts (b-a).map{|c| "- #{c}" }.join("\n")
101
+ else
102
+ puts "OK : #{classname}" if @verbose
103
+ end
104
+ end
105
+
106
+ def check_all_ancestors(db, ruby, requires)
107
+ classnames = []
108
+ requires.each do |lib|
109
+ classnames.push(*defined_classes(ruby, lib, []))
110
+ end
111
+ classnames.each do |classname|
112
+ check_ancestors(db, ruby, requires, classname)
113
+ end
114
+ end
115
+
116
+ def defined_classes(ruby, lib, rejects)
117
+ output = `#{ruby} -e '
118
+ def class_extent
119
+ result = []
120
+ ObjectSpace.each_object(Module) do |c|
121
+ result.push c
122
+ end
123
+ result
124
+ end
125
+
126
+ %w(#{rejects.join(" ")}).each do |lib|
127
+ begin
128
+ require lib
129
+ rescue LoadError
130
+ end
131
+ end
132
+ if "#{lib}" == "_builtin"
133
+ class_extent().each do |c|
134
+ puts c
135
+ end
136
+ else
137
+ before = class_extent()
138
+ begin
139
+ require "#{lib}"
140
+ rescue LoadError
141
+ $stderr.puts "\#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}): library not exist: #{lib}"
142
+ exit
143
+ end
144
+ after = class_extent()
145
+ (after - before).each do |c|
146
+ puts c
147
+ end
148
+ end
149
+ '`
150
+ output.split
151
+ end
152
+
153
+ main
@@ -0,0 +1,246 @@
1
+ #! /usr/bin/ruby
2
+
3
+ require 'optparse'
4
+ require 'pathname'
5
+
6
+ bindir = Pathname.new(__FILE__).realpath.dirname
7
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
8
+
9
+ require 'bitclust/preprocessor'
10
+ require 'bitclust/lineinput'
11
+ require 'bitclust/parseutils'
12
+ require 'bitclust/methodsignature'
13
+
14
+ def main
15
+ option = OptionParser.new
16
+ version = '1.9.1'
17
+ option.banner = "Usage: #{File.basename($0, '.*')} <filename>"
18
+ option.on('--ruby=[VER]', "The version of Ruby interpreter"){|ver|
19
+ version = ver
20
+ }
21
+ option.on('--help', 'Prints this message and quit.') {
22
+ puts option.help
23
+ exit 0
24
+ }
25
+ begin
26
+ option.parse!(ARGV)
27
+ rescue OptionParser::ParseError => ex
28
+ $stderr.puts err.message
29
+ exit 1
30
+ end
31
+ unless ARGV.size == 1
32
+ $stderr.puts "wrong number of arguments"
33
+ $stderr.puts option.help
34
+ exit 1
35
+ end
36
+ filename = ARGV[0]
37
+ path = Pathname.new(filename)
38
+
39
+ params = { "version" => version }
40
+ parser = BitClust::RDParser.new(BitClust::Preprocessor.read(path, params))
41
+ parser.parse
42
+ end
43
+
44
+ module BitClust
45
+ class RDParser
46
+ def initialize(src)
47
+ @f = LineInput.new(StringIO.new(src))
48
+ @option = { :force => true }
49
+ end
50
+
51
+ def parse
52
+ while @f.next?
53
+ case @f.peek
54
+ when /\A---/
55
+ method_entry_chunk
56
+ else
57
+ @f.gets
58
+ end
59
+ end
60
+ end
61
+
62
+ def method_entry_chunk
63
+ @f.while_match(/\A---/) do |line|
64
+ method_signature line
65
+ end
66
+ props = {}
67
+ @f.while_match(/\A:/) do |line|
68
+ k, v = line.sub(/\A:/, '').split(':', 2)
69
+ props[k.strip] = v.strip
70
+ end
71
+ while @f.next?
72
+ case @f.peek
73
+ when /\A===+/
74
+ @f.gets
75
+ when /\A==?/
76
+ if @option[:force]
77
+ break
78
+ else
79
+ raise "method entry includes headline: #{@f.peek.inspect}"
80
+ end
81
+ when /\A---/
82
+ break
83
+ when /\A\s+\*\s/
84
+ ulist
85
+ when /\A\s+\(\d+\)\s/
86
+ olist
87
+ when /\A:\s/
88
+ dlist
89
+ when %r<\A//emlist\{>
90
+ emlist
91
+ when /\A\s+\S/
92
+ list
93
+ when /@see/
94
+ see
95
+ when /\A@[a-z]/
96
+ method_info
97
+ else
98
+ if @f.peek.strip.empty?
99
+ @f.gets
100
+ else
101
+ method_entry_paragraph
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def headline(line)
108
+ # nop
109
+ end
110
+
111
+ def ulist
112
+ @f.while_match(/\A\s+\*\s/) do |line|
113
+ @f.while_match(/\A\s+[^\*\s]/) do |cont|
114
+ # nop
115
+ end
116
+ end
117
+ end
118
+
119
+ def olist
120
+ @f.while_match(/\A\s+\(\d+\)/) do |line|
121
+ @f.while_match(/\A\s+(?!\(\d+\))\S/) do |cont|
122
+ # nop
123
+ end
124
+ end
125
+ end
126
+
127
+ def dlist
128
+ while @f.next? and /\A:/ =~ @f.peek
129
+ @f.while_match(/\A:/) do |line|
130
+ # nop
131
+ end
132
+ dd_with_p
133
+ end
134
+ end
135
+
136
+ # empty lines separate paragraphs.
137
+ def dd_with_p
138
+ while /\A(?:\s|\z)/ =~ @f.peek or %r!\A//emlist\{! =~ @f.peek
139
+ case @f.peek
140
+ when /\A$/
141
+ @f.gets
142
+ when /\A[ \t\z]/
143
+ @f.while_match(/\A[ \t\z]/) do |line|
144
+ # nop
145
+ end
146
+ when %r!\A//emlist\{!
147
+ emlist
148
+ else
149
+ raise 'must not happen'
150
+ end
151
+ end
152
+ end
153
+
154
+ # empty lines do not separate paragraphs.
155
+ def dd_without_p
156
+ while /\A[ \t]/ =~ @f.peek or %r!\A//emlist\{! =~ @f.peek
157
+ case @f.peek
158
+ when /\A[ \t\z]/
159
+ @f.while_match(/\A[ \t\z]/) do |line|
160
+ # nop
161
+ end
162
+ when %r!\A//emlist\{!
163
+ emlist
164
+ end
165
+ end
166
+ end
167
+
168
+ def emlist
169
+ @f.gets # discard "//emlist{"
170
+ @f.until_terminator(%r<\A//\}>) do |line|
171
+ # nop
172
+ end
173
+ end
174
+
175
+ def list
176
+ @f.break(/\A\S/)
177
+ end
178
+
179
+ def see
180
+ @f.gets
181
+ @f.span(/\A\s+\S/)
182
+ end
183
+
184
+ def paragraph
185
+ read_paragraph(@f).each do |line|
186
+ # nop
187
+ end
188
+ end
189
+
190
+ def read_paragraph(f)
191
+ f.span(%r<\A(?!---|=|//emlist\{)\S>)
192
+ end
193
+
194
+ def method_info
195
+ params = []
196
+ while @f.next? and /\A\@(?!see)\w+|\A$/ =~ @f.peek
197
+ header = @f.gets
198
+ next if /\A$/ =~ header
199
+ cmd = header.slice!(/\A\@\w+/)
200
+ @f.ungets(header)
201
+ case cmd
202
+ when '@param', '@arg'
203
+ name = header.slice!(/\A\s*\w+/n) || '?'
204
+ params << name
205
+ when '@raise'
206
+ # nop
207
+ when '@return'
208
+ # nop
209
+ else
210
+ $stderr.puts "[UNKNOWN_META_INFO] #{cmd}"
211
+ end
212
+ dd_without_p
213
+ end
214
+ # check parameters
215
+ params.map(&:strip).each{|param|
216
+ unless @sig.params.split(',').map(&:strip).any?{|v|
217
+ param == v.tr('*', '').gsub(/\s*=\s*.+/, '')
218
+ }
219
+ $stderr.puts "#{@f.lineno}: #{@sig.friendly_string}"
220
+ $stderr.puts params.inspect
221
+ $stderr.puts @sig.params.inspect
222
+ end
223
+ }
224
+ rescue
225
+ $stderr.puts "#{@f.lineno}: #{@sig.friendly_string}"
226
+ $stderr.puts params.inspect
227
+ $stderr.puts @sig.params.inspect
228
+ end
229
+
230
+ def method_entry_paragraph
231
+ read_method_entry_paragraph(@f).each do |line|
232
+ # nop
233
+ end
234
+ end
235
+
236
+ def read_method_entry_paragraph(f)
237
+ f.span(%r<\A(?!---|=|//emlist\{|@[a-z])\S>)
238
+ end
239
+
240
+ def method_signature(sig_line)
241
+ @sig = MethodSignature.parse(sig_line)
242
+ end
243
+ end
244
+ end
245
+
246
+ main
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ bindir = Pathname.new(__FILE__).realpath.dirname
6
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
7
+
8
+ require 'bitclust/crossrubyutils'
9
+ require 'optparse'
10
+
11
+ include BitClust::CrossRubyUtils
12
+
13
+ def main
14
+ rejects = []
15
+ @verbose = false
16
+ opts = OptionParser.new
17
+ opts.banner = "Usage: #{File.basename($0, '.*')} [-r<lib>] <lib>"
18
+ opts.on('-r', '--reject=LIB', 'Reject library LIB') {|lib|
19
+ rejects.concat lib.split(',')
20
+ }
21
+ opts.on('-v', '--verbose', 'Show all ruby version.') {
22
+ @verbose = true
23
+ }
24
+ opts.on('--help', 'Prints this message and quit.') {
25
+ puts opts.help
26
+ exit 0
27
+ }
28
+ begin
29
+ opts.parse!(ARGV)
30
+ rescue OptionParser::ParseError => err
31
+ $stderr.puts err.message
32
+ exit 1
33
+ end
34
+ unless ARGV.size == 1
35
+ $stderr.puts 'wrong number of arguments'
36
+ $stderr.puts opts.help
37
+ exit 1
38
+ end
39
+ lib = ARGV[0]
40
+ print_crossruby_table {|ruby| defined_classes(ruby, lib, rejects) }
41
+ end
42
+
43
+ def defined_classes(ruby, lib, rejects)
44
+ output = `#{ruby} -e '
45
+ def class_extent
46
+ result = []
47
+ ObjectSpace.each_object(Module) do |c|
48
+ result.push c
49
+ end
50
+ result
51
+ end
52
+
53
+ %w(#{rejects.join(" ")}).each do |lib|
54
+ begin
55
+ require lib
56
+ rescue LoadError
57
+ end
58
+ end
59
+ if "#{lib}" == "_builtin"
60
+ class_extent().each do |c|
61
+ puts c
62
+ end
63
+ else
64
+ before = class_extent()
65
+ begin
66
+ require "#{lib}"
67
+ rescue LoadError
68
+ $stderr.puts "\#{RUBY_VERSION} (\#{RUBY_RELEASE_DATE}): library not exist: #{lib}"
69
+ exit
70
+ end
71
+ after = class_extent()
72
+ (after - before).each do |c|
73
+ puts c
74
+ end
75
+ end
76
+ '`
77
+ output.split
78
+ end
79
+
80
+ main