bitclust-core 0.6.0 → 0.7.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 (34) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +7 -0
  3. data/Gemfile +1 -0
  4. data/bitclust.gemspec +1 -0
  5. data/data/bitclust/template.offline/class +1 -1
  6. data/lib/bitclust/crossrubyutils.rb +2 -2
  7. data/lib/bitclust/methodentry.rb +1 -2
  8. data/lib/bitclust/progress_bar.rb +7 -0
  9. data/lib/bitclust/rdcompiler.rb +1 -1
  10. data/lib/bitclust/runner.rb +46 -32
  11. data/lib/bitclust/searcher.rb +14 -13
  12. data/lib/bitclust/silent_progress_bar.rb +17 -0
  13. data/lib/bitclust/subcommand.rb +27 -0
  14. data/lib/bitclust/subcommands/ancestors_command.rb +145 -0
  15. data/lib/bitclust/subcommands/chm_command.rb +268 -0
  16. data/lib/bitclust/subcommands/classes_command.rb +73 -0
  17. data/lib/bitclust/subcommands/extract_command.rb +55 -0
  18. data/lib/bitclust/subcommands/htmlfile_command.rb +105 -0
  19. data/lib/bitclust/subcommands/init_command.rb +29 -30
  20. data/lib/bitclust/subcommands/list_command.rb +39 -41
  21. data/lib/bitclust/subcommands/lookup_command.rb +71 -73
  22. data/lib/bitclust/subcommands/methods_command.rb +159 -0
  23. data/lib/bitclust/subcommands/preproc_command.rb +35 -0
  24. data/lib/bitclust/subcommands/property_command.rb +47 -48
  25. data/lib/bitclust/subcommands/query_command.rb +12 -18
  26. data/lib/bitclust/subcommands/server_command.rb +180 -182
  27. data/lib/bitclust/subcommands/setup_command.rb +85 -89
  28. data/lib/bitclust/subcommands/statichtml_command.rb +276 -0
  29. data/lib/bitclust/subcommands/update_command.rb +39 -41
  30. data/lib/bitclust/version.rb +1 -1
  31. data/test/test_bitclust.rb +1 -1
  32. data/test/test_rdcompiler.rb +1 -1
  33. data/test/test_runner.rb +7 -14
  34. metadata +120 -114
@@ -8,39 +8,38 @@ require 'yaml'
8
8
  require 'bitclust'
9
9
  require 'bitclust/subcommand'
10
10
 
11
- module BitClust::Subcommands
12
- class InitCommand < BitClust::Subcommand
13
- def initialize
14
- @parser = OptionParser.new {|opt|
15
- opt.banner = "Usage: #{File.basename($0, '.*')} init [KEY=VALUE ...]"
16
- opt.on('--help', 'Prints this message and quit.') {
17
- puts opt.help
18
- exit 0
19
- }
20
- }
21
- end
11
+ module BitClust
12
+ module Subcommands
13
+ class InitCommand < Subcommand
14
+ def initialize
15
+ super
16
+ @parser.banner = "Usage: #{File.basename($0, '.*')} init [KEY=VALUE ...]"
17
+ end
22
18
 
23
- STANDARD_PROPERTIES = %w( encoding version )
19
+ STANDARD_PROPERTIES = %w( encoding version )
24
20
 
25
- def exec(db, argv)
26
- db.init
27
- db.transaction {
28
- argv.each do |kv|
29
- k, v = kv.split('=', 2)
30
- db.propset k, v
31
- end
32
- }
33
- fail = false
34
- STANDARD_PROPERTIES.each do |key|
35
- unless db.propget(key)
36
- $stderr.puts "#{File.basename($0, '.*')}: warning: standard property `#{key}' not given"
37
- fail = true
21
+ def exec(argv, options)
22
+ prefix = options[:prefix]
23
+ db = MethodDatabase.new(prefix)
24
+ db.init
25
+ db.transaction {
26
+ argv.each do |kv|
27
+ k, v = kv.split('=', 2)
28
+ db.propset k, v
29
+ end
30
+ }
31
+ fail = false
32
+ STANDARD_PROPERTIES.each do |key|
33
+ unless db.propget(key)
34
+ $stderr.puts "#{File.basename($0, '.*')}: warning: standard property `#{key}' not given"
35
+ fail = true
36
+ end
38
37
  end
39
- end
40
- if fail
41
- $stderr.puts "---- Current Properties ----"
42
- db.properties.each do |key, value|
43
- $stderr.puts "#{key}=#{value}"
38
+ if fail
39
+ $stderr.puts "---- Current Properties ----"
40
+ db.properties.each do |key, value|
41
+ $stderr.puts "#{key}=#{value}"
42
+ end
44
43
  end
45
44
  end
46
45
  end
@@ -8,60 +8,58 @@ require 'yaml'
8
8
  require 'bitclust'
9
9
  require 'bitclust/subcommand'
10
10
 
11
- module BitClust::Subcommands
12
- class ListCommand < BitClust::Subcommand
13
- def initialize
14
- @mode = nil
15
- @parser = OptionParser.new {|opt|
16
- opt.banner = "Usage: #{File.basename($0, '.*')} list (--library|--class|--method|--function)"
17
- opt.on('--library', 'List libraries.') {
11
+ module BitClust
12
+ module Subcommands
13
+ class ListCommand < Subcommand
14
+ def initialize
15
+ super
16
+ @mode = nil
17
+ @parser.banner = "Usage: #{File.basename($0, '.*')} list (--library|--class|--method|--function)"
18
+ @parser.on('--library', 'List libraries.') {
18
19
  @mode = :library
19
20
  }
20
- opt.on('--class', 'List classes.') {
21
+ @parser.on('--class', 'List classes.') {
21
22
  @mode = :class
22
23
  }
23
- opt.on('--method', 'List methods.') {
24
+ @parser.on('--method', 'List methods.') {
24
25
  @mode = :method
25
26
  }
26
- opt.on('--function', 'List functions.') {
27
+ @parser.on('--function', 'List functions (C API).') {
27
28
  @mode = :function
28
29
  }
29
- opt.on('--help', 'Prints this message and quit.') {
30
- puts opt.help
31
- exit 0
32
- }
33
- }
34
- end
35
-
36
- def parse(argv)
37
- super
38
- unless @mode
39
- error 'one of (--library|--class|--method|--function) is required'
40
30
  end
41
- end
42
31
 
43
- def exec(db, argv)
44
- case @mode
45
- when :library
46
- db.libraries.map {|lib| lib.name }.sort.each do |name|
47
- puts name
48
- end
49
- when :class
50
- db.classes.map {|c| c.name }.sort.each do |name|
51
- puts name
32
+ def parse(argv)
33
+ super
34
+ unless @mode
35
+ error 'one of (--library|--class|--method|--function) is required'
52
36
  end
53
- when :method
54
- db.classes.sort_by {|c| c.name }.each do |c|
55
- c.entries.sort_by {|m| m.id }.each do |m|
56
- puts m.label
37
+ end
38
+
39
+ def exec(argv, options)
40
+ super
41
+ case @mode
42
+ when :library
43
+ @db.libraries.map {|lib| lib.name }.sort.each do |name|
44
+ puts name
57
45
  end
46
+ when :class
47
+ @db.classes.map {|c| c.name }.sort.each do |name|
48
+ puts name
49
+ end
50
+ when :method
51
+ @db.classes.sort_by {|c| c.name }.each do |c|
52
+ c.entries.sort_by {|m| m.id }.each do |m|
53
+ puts m.label
54
+ end
55
+ end
56
+ when :function
57
+ @db.functions.sort_by {|f| f.name }.each do |f|
58
+ puts f.name
59
+ end
60
+ else
61
+ raise "must not happen: @mode=#{@mode.inspect}"
58
62
  end
59
- when :function
60
- db.functions.sort_by {|f| f.name }.each do |f|
61
- puts f.name
62
- end
63
- else
64
- raise "must not happen: @mode=#{@mode.inspect}"
65
63
  end
66
64
  end
67
65
  end
@@ -8,82 +8,79 @@ require 'yaml'
8
8
  require 'bitclust'
9
9
  require 'bitclust/subcommand'
10
10
 
11
- module BitClust::Subcommands
12
- class LookupCommand < BitClust::Subcommand
13
- def initialize
14
- @format = :text
15
- @type = nil
16
- @key = nil
17
- @parser = OptionParser.new {|opt|
18
- opt.banner = "Usage: #{File.basename($0, '.*')} lookup (--library|--class|--method|--function) [--html] <key>"
19
- opt.on('--library=NAME', 'Lookup library.') {|name|
11
+ module BitClust
12
+ module Subcommands
13
+ class LookupCommand < Subcommand
14
+ def initialize
15
+ super
16
+ @format = :text
17
+ @type = nil
18
+ @key = nil
19
+ @parser.banner = "Usage: #{File.basename($0, '.*')} lookup (--library|--class|--method|--function) [--html] <key>"
20
+ @parser.on('--library=NAME', 'Lookup library.') {|name|
20
21
  @type = :library
21
22
  @key = name
22
23
  }
23
- opt.on('--class=NAME', 'Lookup class.') {|name|
24
+ @parser.on('--class=NAME', 'Lookup class.') {|name|
24
25
  @type = :class
25
26
  @key = name
26
27
  }
27
- opt.on('--method=NAME', 'Lookup method.') {|name|
28
+ @parser.on('--method=NAME', 'Lookup method.') {|name|
28
29
  @type = :method
29
30
  @key = name
30
31
  }
31
- opt.on('--function=NAME', 'Lookup function.') {|name|
32
+ @parser.on('--function=NAME', 'Lookup function. (C API)') {|name|
32
33
  @type = :function
33
34
  @key = name
34
35
  }
35
- opt.on('--html', 'Show result in HTML.') {
36
+ @parser.on('--html', 'Show result in HTML.') {
36
37
  @format = :html
37
38
  }
38
- opt.on('--help', 'Prints this message and quit.') {
39
- puts opt.help
40
- exit 0
41
- }
42
- }
43
- end
44
-
45
- def parse(argv)
46
- super
47
- unless @type
48
- error "one of --library/--class/--method/--function is required"
49
39
  end
50
- unless argv.empty?
51
- error "too many arguments"
40
+
41
+ def parse(argv)
42
+ super
43
+ unless @type
44
+ error "one of --library/--class/--method/--function is required"
45
+ end
46
+ unless argv.empty?
47
+ error "too many arguments"
48
+ end
52
49
  end
53
- end
54
50
 
55
- def exec(db, argv)
56
- entry = fetch_entry(db, @type, @key)
57
- puts fill_template(get_template(@type, @format), entry)
58
- end
51
+ def exec(argv, options)
52
+ super
53
+ entry = fetch_entry(@db, @type, @key)
54
+ puts fill_template(get_template(@type, @format), entry)
55
+ end
59
56
 
60
- def fetch_entry(db, type, key)
61
- case type
62
- when :library
63
- db.fetch_library(key)
64
- when :class
65
- db.fetch_class(key)
66
- when :method
67
- db.fetch_method(BitClust::MethodSpec.parse(key))
68
- when :function
69
- db.fetch_function(key)
70
- else
71
- raise "must not happen: #{type.inspect}"
57
+ def fetch_entry(db, type, key)
58
+ case type
59
+ when :library
60
+ db.fetch_library(key)
61
+ when :class
62
+ db.fetch_class(key)
63
+ when :method
64
+ db.fetch_method(MethodSpec.parse(key))
65
+ when :function
66
+ db.fetch_function(key)
67
+ else
68
+ raise "must not happen: #{type.inspect}"
69
+ end
72
70
  end
73
- end
74
71
 
75
- def fill_template(template, entry)
76
- ERB.new(template).result(binding())
77
- end
72
+ def fill_template(template, entry)
73
+ ERB.new(template).result(binding())
74
+ end
78
75
 
79
- def get_template(type, format)
80
- template = TEMPLATE[type][format]
81
- BitClust::TextUtils.unindent_block(template.lines).join('')
82
- end
76
+ def get_template(type, format)
77
+ template = TEMPLATE[type][format]
78
+ TextUtils.unindent_block(template.lines).join('')
79
+ end
83
80
 
84
- TEMPLATE = {
85
- :library => {
86
- :text => <<-End,
81
+ TEMPLATE = {
82
+ :library => {
83
+ :text => <<-End,
87
84
  type: library
88
85
  name: <%= entry.name %>
89
86
  classes: <%= entry.classes.map {|c| c.name }.sort.join(', ') %>
@@ -91,7 +88,7 @@ module BitClust::Subcommands
91
88
 
92
89
  <%= entry.source %>
93
90
  End
94
- :html => <<-End
91
+ :html => <<-End
95
92
  <dl>
96
93
  <dt>type</dt><dd>library</dd>
97
94
  <dt>name</dt><dd><%= entry.name %></dd>
@@ -100,9 +97,9 @@ module BitClust::Subcommands
100
97
  </dl>
101
98
  <%= compile_rd(entry.source) %>
102
99
  End
103
- },
104
- :class => {
105
- :text => <<-End,
100
+ },
101
+ :class => {
102
+ :text => <<-End,
106
103
  type: class
107
104
  name: <%= entry.name %>
108
105
  library: <%= entry.library.name %>
@@ -113,7 +110,7 @@ module BitClust::Subcommands
113
110
 
114
111
  <%= entry.source %>
115
112
  End
116
- :html => <<-End
113
+ :html => <<-End
117
114
  <dl>
118
115
  <dt>type</dt><dd>class</dd>
119
116
  <dt>name</dt><dd><%= entry.name %></dd>
@@ -123,9 +120,9 @@ module BitClust::Subcommands
123
120
  </dl>
124
121
  <%= compile_rd(entry.source) %>
125
122
  End
126
- },
127
- :method => {
128
- :text => <<-End,
123
+ },
124
+ :method => {
125
+ :text => <<-End,
129
126
  type: <%= entry.type %>
130
127
  name: <%= entry.name %>
131
128
  names: <%= entry.names.sort.join(', ') %>
@@ -135,7 +132,7 @@ module BitClust::Subcommands
135
132
 
136
133
  <%= entry.source %>
137
134
  End
138
- :html => <<-End
135
+ :html => <<-End
139
136
  <dl>
140
137
  <dt>type</dt><dd><%= entry.type %></dd>
141
138
  <dt>name</dt><dd><%= entry.name %></dd>
@@ -146,16 +143,16 @@ module BitClust::Subcommands
146
143
  </dl>
147
144
  <%= compile_rd(entry.source) %>
148
145
  End
149
- },
150
- :function => {
151
- :text => <<-End,
146
+ },
147
+ :function => {
148
+ :text => <<-End,
152
149
  kind: <%= entry.kind %>
153
150
  header: <%= entry.header %>
154
151
  filename: <%= entry.filename %>
155
152
 
156
153
  <%= entry.source %>
157
154
  End
158
- :html => <<-End
155
+ :html => <<-End
159
156
  <dl>
160
157
  <dt>kind</dt><dd><%= entry.kind %></dd>
161
158
  <dt>header</dt><dd><%= entry.header %></dd>
@@ -163,14 +160,15 @@ module BitClust::Subcommands
163
160
  </dl>
164
161
  <%= compile_rd(entry.source) %>
165
162
  End
163
+ }
166
164
  }
167
- }
168
165
 
169
- def compile_rd(src)
170
- umap = BitClust::URLMapper.new(:base_url => 'http://example.com',
171
- :cgi_url => 'http://example.com/view')
172
- compiler = BitClust::RDCompiler.new(umap, 2)
173
- compiler.compile(src)
166
+ def compile_rd(src)
167
+ umap = URLMapper.new(:base_url => 'http://example.com',
168
+ :cgi_url => 'http://example.com/view')
169
+ compiler = RDCompiler.new(umap, 2)
170
+ compiler.compile(src)
171
+ end
174
172
  end
175
173
  end
176
174
  end
@@ -0,0 +1,159 @@
1
+ require 'pathname'
2
+ require 'optparse'
3
+
4
+ require 'bitclust'
5
+ require 'bitclust/crossrubyutils'
6
+ require 'bitclust/subcommand'
7
+
8
+ module BitClust
9
+ module Subcommands
10
+ class MethodsCommand < Subcommand
11
+ include CrossRubyUtils
12
+
13
+ def initialize
14
+ super
15
+ @requires = []
16
+ @verbose = false
17
+ @version = RUBY_VERSION
18
+ @mode = :list
19
+ @target = nil
20
+ @parser.banner = "Usage: #{File.basename($0, '.*')} [-r<lib>] <classname>"
21
+ @parser.on('-r LIB', 'Requires library LIB') {|lib|
22
+ @requires.push lib
23
+ }
24
+ @parser.on('-v', '--verbose', "Prints each ruby's version") {
25
+ @verbose = true
26
+ }
27
+ @parser.on('--diff=RDFILE', 'RD file name') {|path|
28
+ @mode = :diff
29
+ @target = path
30
+ }
31
+ @parser.on('-c', '') {
32
+ @content = true
33
+ require 'bitclust/ridatabase'
34
+ }
35
+ @parser.on('--ruby=[VER]', "The version of Ruby interpreter"){|version|
36
+ @version = version
37
+ }
38
+ @parser.on('--ri-database', 'The path of ri database'){|path|
39
+ @ri_path = path
40
+ }
41
+ end
42
+
43
+ def parse(argv)
44
+ super
45
+ option_error("wrong number of arguments") unless argv.size == 1
46
+ end
47
+
48
+ def exec(argv, options)
49
+ classname = argv[0]
50
+ case @mode
51
+ when :list
52
+ print_crossruby_table {|ruby| defined_methods(ruby, classname) }
53
+ when :diff
54
+ unless ruby = get_ruby(@version)
55
+ raise "Not found Ruby interpreter of the given version"
56
+ end
57
+ keys = defined_methods(ruby, classname)
58
+ lib = RRDParser.parse_stdlib_file(@target, { 'version' => @version })
59
+ c = lib.fetch_class(classname)
60
+ list0 = lib.classes.find_all{|c0| /\A#{classname}\b/o =~ c0.name }
61
+ list0 = c.entries + list0
62
+ list = list0.map {|ent| ent.labels.map {|n| expand_mf(n) } }.flatten
63
+ if @content
64
+ ri = @ri_path ? RiDatabase.open(@ri_path, nil) : RiDatabase.open_system_db
65
+ ri.current_class = c.name
66
+ mthds = ( ri.singleton_methods + ri.instance_methods )
67
+ fmt = Formatter.new
68
+ (keys - list).sort.each do |name|
69
+ mthd = mthds.find{|m| name == m.fullname }
70
+ if mthd
71
+ puts fmt.method_info(mthd.entry)
72
+ else
73
+ name = name.sub(/\A\w+#/, '')
74
+ puts "--- #{name}\n\#@todo\n\n"
75
+ end
76
+ end
77
+ else
78
+ (keys - list).sort.each do |name|
79
+ puts "-#{name}"
80
+ end
81
+ (list - keys).sort.each do |name|
82
+ puts "+#{name}"
83
+ end
84
+ end
85
+ else
86
+ raise "must not happen: #{mode.inspect}"
87
+ end
88
+ end
89
+
90
+ def expand_mf(n)
91
+ if /\.\#/ =~ n
92
+ [n.sub(/\.\#/, '.'), n.sub(/\.\#/, '#')]
93
+ else
94
+ n
95
+ end
96
+ end
97
+
98
+ def crossrubyutils_sort_entries(ents)
99
+ ents.sort_by {|m| m_order(m) }
100
+ end
101
+
102
+ ORDER = { '.' => 1, '#' => 2, '::' => 3 }
103
+
104
+ def m_order(m)
105
+ m, t, c = *m.reverse.split(/(\#|\.|::)/, 2)
106
+ [ORDER[t] || 0, m.reverse]
107
+ end
108
+
109
+ def defined_methods(ruby, classname)
110
+ req = @requires.map {|lib| "-r#{lib}" }.join(' ')
111
+ avoid_tracer = ""
112
+ avoid_tracer = "Tracer.off" if @requires.include?("tracer")
113
+ case classname
114
+ when 'Object'
115
+ script = <<-SCRIPT
116
+ c = #{classname}
117
+ c.singleton_methods(false).each do |m|
118
+ puts "#{classname}.\#{m}"
119
+ end
120
+ c.instance_methods(true).each do |m|
121
+ puts "#{classname}\\#\#{m}"
122
+ end
123
+ SCRIPT
124
+ when 'Kernel'
125
+ script = <<-SCRIPT
126
+ c = #{classname}
127
+ c.singleton_methods(true).each do |m|
128
+ puts "#{classname}.\#{m}"
129
+ end
130
+ ( c.private_instance_methods(false) && c.methods(false) ).each do |m|
131
+ puts "#{classname}\\#\#{m}"
132
+ end
133
+ Object::constants.delete_if{|c| cl = Object.const_get(c).class; cl == Class or cl == Module }.each do |m|
134
+ puts "#{classname}::\#{m}"
135
+ end
136
+ global_variables.each do |m|
137
+ puts "#{classname}\#{m}"
138
+ end
139
+ SCRIPT
140
+ else
141
+ script = <<-SCRIPT
142
+ #{avoid_tracer}
143
+ c = #{classname}
144
+ c.singleton_methods(false).each do |m|
145
+ puts "#{classname}.\#{m}"
146
+ end
147
+ c.instance_methods(false).each do |m|
148
+ puts "#{classname}\\#\#{m}"
149
+ end
150
+ c.ancestors.map {|mod| mod.constants }.inject {|r,n| r-n }.each do |m|
151
+ puts "#{classname}::\#{m}"
152
+ end
153
+ SCRIPT
154
+ end
155
+ `#{ruby} #{req} -e '#{script}'`.split
156
+ end
157
+ end
158
+ end
159
+ end