bitclust-dev 1.7.0 → 1.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2b70c22f437c01d0972d9cc39ed011f26af88ce04a295909ad02dc3177822c7
4
- data.tar.gz: 3a86cd213fb1cb1be92d1d1f71c8cf3da91ece0cbd9e24ac05f11639f7a47aee
3
+ metadata.gz: d2759bd606017d5361386015b8fa44b404272bd23445c74f98f6e6e571fc0c0d
4
+ data.tar.gz: f370ab5fbe22cad11dfe65c9b7fed3eb75086428352947b778bb58336783861a
5
5
  SHA512:
6
- metadata.gz: 7b6750fd7bf351610c039432aa220ce67bb95602002d281c8bb52e79667207b8156adf230193c7115ef6d13025642bfaecacd3f5ee5048beaefe5a1d960c7c36
7
- data.tar.gz: fe4fa1117faa16fd0f4b6cf7f0aa4c09e8cbb8f244b1ba7eb3e20be9be62f4c5e91a79f6adaddc783f5f0c227a34a006c9b6cdc1c691044185f0331db7658504
6
+ metadata.gz: 4a9caaab23e117be4018664057f2df0765ee8874a22da2d31003892edce97ada3524dc0475c866aebab775559d9862c770c93cd12e9e8735d8a01837d7d9bf97
7
+ data.tar.gz: e68dc2a8cb51eeb48a86cbab2e335faaec7e0297cc6c444662782e6b2fe70ce1facae7ab283a3b2f5c16bf99e4c1d581a3da1a6052066c0801b525d4e9afc5c5
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitclust-dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/rurema
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 1.7.0
18
+ version: 1.8.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 1.7.0
25
+ version: 1.8.0
26
26
  description: |
27
27
  Rurema is a Japanese ruby documentation project, and
28
28
  bitclust is a rurema document processor.
@@ -30,40 +30,25 @@ description: |
30
30
  email:
31
31
  - ''
32
32
  executables:
33
- - bc-checkparams.rb
34
- - bc-convert.rb
35
- - bc-rdoc.rb
36
33
  - forall-ruby.rb
37
34
  - gencatalog.rb
38
- - insert-canonical.rb
39
35
  - md-bridge-check.rb
40
36
  - md-compile-check.rb
41
37
  - md-db-check.rb
42
38
  - md-parse-check.rb
43
39
  - md-roundtrip-check.rb
44
40
  - md-tree-check.rb
45
- - statrefm.rb
46
- - stattodo.rb
47
- - update-database.rb
48
41
  extensions: []
49
42
  extra_rdoc_files: []
50
43
  files:
51
- - tools/bc-checkparams.rb
52
- - tools/bc-convert.rb
53
- - tools/bc-rdoc.rb
54
- - tools/check-signature.rb
55
44
  - tools/forall-ruby.rb
56
45
  - tools/gencatalog.rb
57
- - tools/insert-canonical.rb
58
46
  - tools/md-bridge-check.rb
59
47
  - tools/md-compile-check.rb
60
48
  - tools/md-db-check.rb
61
49
  - tools/md-parse-check.rb
62
50
  - tools/md-roundtrip-check.rb
63
51
  - tools/md-tree-check.rb
64
- - tools/statrefm.rb
65
- - tools/stattodo.rb
66
- - tools/update-database.rb
67
52
  homepage: https://docs.ruby-lang.org/ja/
68
53
  licenses: []
69
54
  metadata:
@@ -1,274 +0,0 @@
1
- #! /usr/bin/ruby
2
-
3
- require 'optparse'
4
- require 'pathname'
5
- require 'set'
6
-
7
- bindir = Pathname.new(__FILE__).realpath.dirname
8
- $LOAD_PATH.unshift((bindir + '../lib').realpath)
9
-
10
- require 'bitclust/preprocessor'
11
- require 'bitclust/lineinput'
12
- require 'bitclust/parseutils'
13
- require 'bitclust/methodsignature'
14
-
15
- def main
16
- option = OptionParser.new
17
- version = '1.9.1'
18
- option.banner = "Usage: #{File.basename($0, '.*')} <filename>"
19
- option.on('--ruby=[VER]', "The version of Ruby interpreter"){|ver|
20
- version = ver
21
- }
22
- option.on('--help', 'Prints this message and quit.') {
23
- puts option.help
24
- exit 0
25
- }
26
- begin
27
- option.parse!(ARGV)
28
- rescue OptionParser::ParseError => err
29
- $stderr.puts err.message
30
- exit 1
31
- end
32
- unless ARGV.size == 1
33
- $stderr.puts "wrong number of arguments"
34
- $stderr.puts option.help
35
- exit 1
36
- end
37
- filename = ARGV[0]
38
- path = Pathname.new(filename)
39
-
40
- params = { "version" => version }
41
- parser = BitClust::RDParser.new(BitClust::Preprocessor.read(path, params))
42
- parser.parse
43
- end
44
-
45
- module BitClust
46
- class RDParser
47
- def initialize(src)
48
- @f = LineInput.new(StringIO.new(src))
49
- @option = { :force => true }
50
- end
51
-
52
- def parse
53
- while @f.next?
54
- case @f.peek
55
- when /\A---/
56
- method_entry_chunk
57
- else
58
- @f.gets
59
- end
60
- end
61
- end
62
-
63
- def method_entry_chunk
64
- method_signatures = []
65
- @f.while_match(/\A---/) do |line|
66
- method_signatures << method_signature(line)
67
- end
68
- props = {}
69
- @f.while_match(/\A:/) do |line|
70
- k, v = line.sub(/\A:/, '').split(':', 2)
71
- props[k.strip] = v.strip
72
- end
73
- params = Set.new
74
- while @f.next?
75
- case @f.peek
76
- when /\A===+/
77
- @f.gets
78
- when /\A==?/
79
- if @option[:force]
80
- break
81
- else
82
- raise "method entry includes headline: #{@f.peek.inspect}"
83
- end
84
- when /\A---/
85
- break
86
- when /\A\s+\*\s/
87
- ulist
88
- when /\A\s+\(\d+\)\s/
89
- olist
90
- when /\A:\s/
91
- dlist
92
- when %r<\A//emlist\{>
93
- emlist
94
- when /\A\s+\S/
95
- list
96
- when /@see/
97
- see
98
- when /\A@[a-z]/
99
- method_info.each do |param|
100
- params << param
101
- end
102
- else
103
- if @f.peek.strip.empty?
104
- @f.gets
105
- else
106
- method_entry_paragraph
107
- end
108
- end
109
- end
110
- check_parameters(method_signatures, params)
111
- end
112
-
113
- def headline(line)
114
- # nop
115
- end
116
-
117
- def ulist
118
- @f.while_match(/\A\s+\*\s/) do |line|
119
- @f.while_match(/\A\s+[^\*\s]/) do |cont|
120
- # nop
121
- end
122
- end
123
- end
124
-
125
- def olist
126
- @f.while_match(/\A\s+\(\d+\)/) do |line|
127
- @f.while_match(/\A\s+(?!\(\d+\))\S/) do |cont|
128
- # nop
129
- end
130
- end
131
- end
132
-
133
- def dlist
134
- while @f.next? and /\A:/ =~ @f.peek
135
- @f.while_match(/\A:/) do |line|
136
- # nop
137
- end
138
- dd_with_p
139
- end
140
- end
141
-
142
- # empty lines separate paragraphs.
143
- def dd_with_p
144
- while /\A(?:\s|\z)/ =~ @f.peek or %r!\A//emlist\{! =~ @f.peek
145
- case @f.peek
146
- when /\A$/
147
- @f.gets
148
- when /\A[ \t]/
149
- @f.while_match(/\A[ \t]/) do |line|
150
- # nop
151
- end
152
- when %r!\A//emlist\{!
153
- emlist
154
- else
155
- raise 'must not happen'
156
- end
157
- end
158
- end
159
-
160
- # empty lines do not separate paragraphs.
161
- def dd_without_p
162
- while /\A[ \t]/ =~ @f.peek or %r!\A//emlist\{! =~ @f.peek
163
- case @f.peek
164
- when /\A[ \t]/
165
- @f.while_match(/\A[ \t]/) do |line|
166
- # nop
167
- end
168
- when %r!\A//emlist\{!
169
- emlist
170
- end
171
- end
172
- end
173
-
174
- def emlist
175
- @f.gets # discard "//emlist{"
176
- @f.until_terminator(%r<\A//\}>) do |line|
177
- # nop
178
- end
179
- end
180
-
181
- def list
182
- @f.break(/\A\S/)
183
- end
184
-
185
- def see
186
- @f.gets
187
- @f.span(/\A\s+\S/)
188
- end
189
-
190
- def paragraph
191
- read_paragraph(@f).each do |line|
192
- # nop
193
- end
194
- end
195
-
196
- def read_paragraph(f)
197
- f.span(%r<\A(?!---|=|//emlist\{)\S>)
198
- end
199
-
200
- def method_info
201
- params = []
202
- while @f.next? and /\A\@(?!see)\w+|\A$/ =~ @f.peek
203
- header = @f.gets
204
- next if /\A$/ =~ header
205
- cmd = header.slice!(/\A\@\w+/)
206
- @f.ungets(header)
207
- case cmd
208
- when '@param', '@arg'
209
- name = header.slice!(/\A\s*\w+/) || '?'
210
- params << name.strip
211
- when '@raise'
212
- # nop
213
- when '@return'
214
- # nop
215
- when '@todo'
216
- # nop
217
- when '@undef'
218
- # nop
219
- else
220
- $stderr.puts "[UNKNOWN_META_INFO] #{cmd}"
221
- end
222
- dd_without_p
223
- end
224
- params
225
- rescue
226
- $stderr.puts "#{@f.lineno}: #{@sig.friendly_string}"
227
- $stderr.puts params.inspect
228
- $stderr.puts @sig.params.inspect
229
- end
230
-
231
- def method_entry_paragraph
232
- read_method_entry_paragraph(@f).each do |line|
233
- # nop
234
- end
235
- end
236
-
237
- def read_method_entry_paragraph(f)
238
- f.span(%r<\A(?!---|=|//emlist\{|@[a-z])\S>)
239
- end
240
-
241
- def method_signature(sig_line)
242
- @sig = MethodSignature.parse(sig_line)
243
- end
244
-
245
- private
246
-
247
- def check_parameters(method_signatures, params)
248
- params_in_signature = extract_params(method_signatures)
249
- unless params_in_signature == params
250
- puts "#{@f.lineno}:"
251
- method_signatures.each do |signature|
252
- puts signature.friendly_string
253
- puts "signature: #{signature.params}"
254
- end
255
- puts "@params: #{params.to_a.join(", ")}"
256
- puts "-" * 72
257
- end
258
- end
259
-
260
- def extract_params(method_signatures)
261
- method_signatures.map do |signature|
262
- next unless signature.params
263
- signature.params.split(",").map do |param|
264
- param = param.tr("*&", "")
265
- param = param.gsub(/\=.*/, "")
266
- param = param.gsub(/.*:/, "")
267
- param.strip
268
- end
269
- end.compact.flatten.to_set
270
- end
271
- end
272
- end
273
-
274
- main
data/tools/bc-convert.rb DELETED
@@ -1,165 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
-
4
- $KCODE = 'UTF-8' unless Object.const_defined?(:Encoding)
5
-
6
- require 'stringio'
7
- require 'fileutils'
8
- require 'tmpdir'
9
- require 'optparse'
10
-
11
- def main
12
- mode = :output
13
- parser = OptionParser.new
14
- parser.banner = "Usage: #{File.basename($0, '.*')} [--diff] [file...]"
15
- parser.on('--diff', 'Show the diff between original file and output') {
16
- mode = :diff
17
- }
18
- parser.on('--inplace', 'edit input files in-place (make backup)') {
19
- mode = :inplace
20
- }
21
- parser.on('--help') {
22
- puts parser.help
23
- exit
24
- }
25
- begin
26
- parser.parse!
27
- rescue OptionParser::ParseError => err
28
- $stderr.puts err.message
29
- exit 1
30
- end
31
- case mode
32
- when :output
33
- do_convert ARGF
34
- when :diff
35
- ARGV.each do |path|
36
- diff_output path
37
- end
38
- when :inplace
39
- ARGV.each do |path|
40
- inplace_edit path
41
- end
42
- else
43
- raise "must not happen: mode=#{mode.inspect}"
44
- end
45
- end
46
-
47
- def inplace_edit(path)
48
- str = convert_file(path)
49
- File.rename path, path + '.bak'
50
- File.open(path, 'w') {|f|
51
- f.write str
52
- }
53
- end
54
-
55
- def diff_output(path)
56
- tmppath = "#{Dir.tmpdir}/bc-convert-diff"
57
- File.open(tmppath, 'w') {|f|
58
- f.write convert_file(path)
59
- }
60
- system 'diff', '-u', path, tmppath
61
- ensure
62
- FileUtils.rm_f tmppath
63
- end
64
-
65
- def convert_file(path)
66
- File.open(path) {|f| convert(f) }
67
- end
68
-
69
- def convert(f)
70
- buf = StringIO.new
71
- do_convert f, buf
72
- buf.string
73
- end
74
-
75
- def do_convert(f, out = $stdout)
76
- f.each do |line|
77
- case line
78
- when /\A\#@/
79
- out.puts line
80
- when /\A\#/
81
- out.puts '#@' + line
82
- when /\A---\s/
83
- sig = convert_signature(line.sub(/\A---/, '').sub(/\(\(<.*?>\)\)/i, '').strip)
84
- out.puts "--- #{sig}"
85
- if meta = line.slice(/\(\(<.*?>\)\)/i)
86
- out.puts
87
- out.puts meta
88
- out.puts
89
- end
90
- else
91
- out.puts convert_link(line.rstrip)
92
- end
93
- end
94
- end
95
-
96
- def convert_signature(sig)
97
- case sig
98
- when /\A([\w:\.\#]+[?!]?)\s*(?:[\(\{]|--|->|\z)/
99
- # name(arg), name{}, name,
100
- # name() -- obsolete
101
- # name() -> return value type
102
- sig
103
- when /\A[\w:]+[\.\#]([+\-<>=~*^&|%\/]+)/ # Complex#+
104
- sig
105
- when /\Aself\s*(==|===|=~)\s*(\w+)/ # self == other
106
- "#{$1}(#{$2})"
107
- when /\A([\w:\.\#]+)\s*\=(\(|\s*\w+)?/ # name=
108
- "#{remove_class_spec($1)}=(#{remove_paren($2.to_s.strip)})"
109
- when /\A\w+\[(.*)\]=(.*)/ # self[key]=
110
- "[]=(#{$1}, #{$2.strip})"
111
- when /\A[\w\:]+\[(.*)\]/ # self[key]
112
- "[](#{$1})"
113
- when /\Aself\s*([+\-<>=~*^&|%\/]+)\s*(\w+)/ # self + other
114
- "#{$1}(#{$2})"
115
- when /\A([+\-~`])\s*\w+/ # ~ self
116
- case op = $1
117
- when '+', '-' then op + '@'
118
- else op
119
- end
120
- when /\A(?:[\w:]+[\.\#])?(\[\]=?)/ # Matrix.[](i)
121
- sig
122
- when /\A([+\-<>=~*^&|%]+)/ # +(m)
123
- sig
124
- when /\A([A-Z]\w+\*)/ # HKEY_*
125
- sig
126
- when /\Aself([+\-<>=~*^&|%\/\[\]]+)\(\w/ # self+(other)
127
- sig.sub(/\Aself/, '')
128
- else
129
- $stderr.puts "warning: unknown method signature: #{sig.inspect}"
130
- sig
131
- end
132
- end
133
-
134
- def remove_class_spec(str)
135
- str.sub(/\A[A-Z]\w*(?:::[A-Z]\w*)*[\.\#]/, '')
136
- end
137
-
138
- def remove_paren(str)
139
- str.sub(/\A\(/, '').sub(/\)\z/, '')
140
- end
141
-
142
- def convert_link(line)
143
- line.gsub(/\(\(\{(.*?)\}\)\)/) { $1 }\
144
- .gsub(/\(\(\|(.*?)\|\)\)/) { $1 }\
145
- .gsub(/\(\(<(.*?)>\)\)/) { convert_href($1) }
146
- end
147
-
148
- def convert_href(link)
149
- case link
150
- when /\Atrap::(.*)/ then "[[trap:#{$1}]]"
151
- when /\Aruby 1\.\S+ feature/ then "((<#{link}>))"
152
- when /\Aobsolete/ then "((<obsolete>))"
153
- when /\A組み込み変数\/(.*)/u then "[[m:#{$1}]]"
154
- when /\A組み込み定数\/(.*)/u then "[[m:Kernel::#{$1}]]"
155
- when /\A組み込み関数\/(.*)/u then "[[m:Kernel\##{$1}]]"
156
- when /\A([\w:]+[\#\.][^|]+)\|/ then "[[m:#{$1}]]"
157
- when /\A(.*?)\|manual page\z/ then "[[man:#{$1}]]"
158
- when /\A([\w:]+)\/(.*)\z/n then "[[m:#{$1}\##{$2}]]"
159
- when /\A([A-Z][\w:]*)\z/ then "[[c:#{$1}]]"
160
- else
161
- "[[unknown:#{link}]]"
162
- end
163
- end
164
-
165
- main
data/tools/bc-rdoc.rb DELETED
@@ -1,343 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # bc-rdoc.rb -- handle rdoc (ri) database.
4
- #
5
- # "bc-rdoc history" code is derived from bc-history.rb, posted in
6
- # [ruby-reference-manual:150] by moriq.
7
- #
8
-
9
- require 'pathname'
10
-
11
- srcdir_root = Pathname.new(__FILE__).realpath.dirname.parent.cleanpath
12
- $LOAD_PATH.unshift srcdir_root + 'lib'
13
-
14
- require 'bitclust'
15
- require 'bitclust/ridatabase'
16
- require 'rdoc/ri/ri_reader'
17
- require 'rdoc/ri/ri_cache'
18
- require 'rdoc/ri/ri_paths'
19
- require 'rdoc/markup/simple_markup/fragments'
20
- require 'stringio'
21
- require 'pp'
22
- require 'optparse'
23
-
24
- class ApplicationError < StandardError; end
25
- class RiClassNotFound < ApplicationError; end
26
-
27
- def main
28
- Signal.trap(:PIPE) { exit 1 } rescue nil # Win32 does not have SIGPIPE
29
- Signal.trap(:INT) { exit 1 }
30
-
31
- parser = OptionParser.new
32
- parser.banner = <<-EndUsage
33
- Usage: #{File.basename($0)} (list|diff|history) [options]
34
-
35
- Subcommands:
36
- list List methods stored in ri database.
37
- diff Compare between BitClust and ri database.
38
- history Show class/method history stored in ri database.
39
-
40
- Global Options:
41
- EndUsage
42
- parser.on('--help', 'Prints this message and quit.') {
43
- puts parser.help
44
- exit 0
45
- }
46
- begin
47
- parser.order!
48
- rescue OptionParser::ParseError => err
49
- $stderr.puts err.message
50
- $stderr.puts parser.help
51
- exit 1
52
- end
53
-
54
- subcommands = {
55
- 'list' => ListCommand.new,
56
- 'diff' => DiffCommand.new,
57
- 'history' => HistoryCommand.new
58
- }
59
- subcommands['hist'] = subcommands['history']
60
- unless ARGV[0]
61
- $stderr.puts 'no subcommand given'
62
- $stderr.puts parser.help
63
- exit 1
64
- end
65
- unless subcommands.key?(ARGV[0])
66
- $stderr.puts "unknown subcommand: #{ARGV[0].inspect}"
67
- $stderr.puts parser.help
68
- exit 1
69
- end
70
- sub = subcommands[ARGV.shift]
71
- begin
72
- sub.parse ARGV
73
- rescue OptionParser::ParseError => err
74
- $stderr.puts err.message
75
- $stderr.puts sub.parser.help
76
- exit 1
77
- end
78
- sub.exec
79
- rescue Errno::EPIPE
80
- exit 1
81
- rescue ApplicationError, BitClust::UserError => err
82
- $stderr.puts err.message
83
- exit 1
84
- end
85
-
86
-
87
- class Subcommand
88
-
89
- def open_ri_database(prefix)
90
- if prefix
91
- RiDatabase.open(prefix, nil)
92
- else
93
- RiDatabase.open_system_db
94
- end
95
- end
96
-
97
- end
98
-
99
-
100
- class ListCommand < Subcommand
101
-
102
- def initialize
103
- @prefix = nil
104
- @type = :name
105
- @parser = OptionParser.new
106
- @parser.banner = "Usage: #{File.basename($0, '.*')} list"
107
- @parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
108
- @prefix = path
109
- }
110
- @parser.on('-c', '--content', 'Prints method description') {
111
- @type = :content
112
- }
113
- @parser.on('--help', 'Prints this message and quit.') {
114
- puts @parser.help
115
- exit 0
116
- }
117
- end
118
-
119
- attr_reader :parser
120
-
121
- def parse(argv)
122
- @parser.parse! argv
123
- unless argv.size == 1
124
- $stderr.puts "class name not given"
125
- exit 1
126
- end
127
- @classname = argv[0]
128
- @ri = open_ri_database(@prefix)
129
- end
130
-
131
- def exec
132
- c = @ri.lookup_class(@classname)
133
- case @type
134
- when :name
135
- c.method_entries.each do |m|
136
- puts m.fullname
137
- end
138
- when :content
139
- fmt = Formatter.new
140
- c.method_entries.each do |m|
141
- puts fmt.method_info(@ri.get_method(m))
142
- end
143
- end
144
- end
145
-
146
- end
147
-
148
-
149
- class DiffCommand < Subcommand
150
-
151
- def initialize
152
- @bcprefix = nil
153
- @riprefix = nil
154
- @type = :name
155
- @parser = OptionParser.new
156
- @parser.banner = "Usage: #{File.basename($0, '.*')} diff --bc=PATH --ri=PATH <classname>"
157
- @parser.on('--bc-database=PREFIX', 'BitClust database prefix') {|path|
158
- @bcprefix = path
159
- }
160
- @parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
161
- @riprefix = path
162
- }
163
- @parser.on('-c', '--content', 'Prints method description') {
164
- @type = :content
165
- }
166
- @parser.on('--help', 'Prints this message and quit.') {
167
- puts @parser.help
168
- exit 0
169
- }
170
- end
171
-
172
- attr_reader :parser
173
-
174
- def parse(argv)
175
- @parser.parse! argv
176
- unless @bcprefix
177
- $stderr.puts 'missing BitClust database prefix. Use --bc option'
178
- exit 1
179
- end
180
- @bc = BitClust::MethodDatabase.new(@bcprefix)
181
- @ri = open_ri_database(@riprefix)
182
- unless argv.size == 1
183
- $stderr.puts "wrong number of arguments (#{argv.size} for 1)"
184
- $stderr.puts @parser.help
185
- exit 1
186
- end
187
- @classname = argv[0]
188
- end
189
-
190
- def exec
191
- @ri.current_class = @classname
192
- win, lose = *diff_class(bc_lookup_class(@classname), @ri)
193
- case @type
194
- when :name
195
- win.each do |m|
196
- puts "+ #{m.id}"
197
- end
198
- lose.each do |m|
199
- puts "- #{m.fullname}"
200
- end
201
- when :content
202
- fmt = Formatter.new
203
- lose.each do |m|
204
- # puts "\#@\# bc-rdoc: detected missing name: #{m.name}"
205
- puts fmt.method_info(m.entry)
206
- end
207
- end
208
- end
209
-
210
- def bc_lookup_class(classname)
211
- @bc.fetch_class(classname)
212
- rescue BitClust::ClassNotFound
213
- $stderr.puts "warning: class #{classname} not exist in BitClust database"
214
- @bc.get_class(classname)
215
- end
216
-
217
- def diff_class(bc, ri)
218
- unzip(diff_entries(bc, bc_wrap(bc.singleton_methods), ri.singleton_methods),
219
- diff_entries(bc, bc_wrap(bc.instance_methods), ri.instance_methods))\
220
- .map {|list| list.flatten }
221
- end
222
-
223
- def bc_wrap(ents)
224
- ents.map {|m|
225
- m.names.map {|name| BCMethodEntry.new(name, m) }
226
- }.flatten.uniq
227
- end
228
-
229
- def unzip(*tuples)
230
- [tuples.map {|s, i| s }, tuples.map {|s, i| i }]
231
- end
232
-
233
- def diff_entries(bc_class, bc, ri)
234
- bc = bc.sort
235
- ri = ri.sort
236
- [bc - ri, (ri - bc).reject {|m| true_exist?(bc_class, m) }]
237
- end
238
-
239
- def true_exist?(c, m)
240
- if m.singleton_method?
241
- c.singleton_method?(m.name, true)
242
- else
243
- c.instance_method?(m.name, true)
244
- end
245
- end
246
-
247
- end
248
-
249
-
250
- class HistoryCommand < Subcommand
251
-
252
- def initialize
253
- @riprefix = nil
254
- @parser = OptionParser.new
255
- @parser.banner = "Usage: #{File.basename($0, '.*')} history --ri=PATH <classname>"
256
- @parser.on('--ri-database=PREFIX', 'Ri database prefix') {|path|
257
- @riprefix = path
258
- }
259
- @parser.on('--help', 'Prints this message and quit.') {
260
- puts @parser.help
261
- exit 0
262
- }
263
- end
264
-
265
- attr_reader :parser
266
-
267
- def parse(argv)
268
- @parser.parse! argv
269
- unless @riprefix
270
- $stderr.puts 'ri database not given; use --ri option'
271
- exit 1
272
- end
273
- @ris = Dir.glob("#{@riprefix}/1.*").map {|dir|
274
- RiDatabase.open(dir, File.basename(dir))
275
- }
276
- if @ris.empty?
277
- $stderr.puts 'wrong ri database directory; directories like <path>/1.8.3/, <path>/1.8.4/, ... must exist'
278
- exit 1
279
- end
280
- unless argv.size == 1
281
- $stderr.puts "wrong number of arguments (#{argv.size} for 1)"
282
- $stderr.puts @parser.help
283
- exit 1
284
- end
285
- @classname = argv[0]
286
- end
287
-
288
- def exec
289
- @ris.each do |ri|
290
- ri.current_class = @classname
291
- end
292
- s = {}
293
- i = {}
294
- @ris.each do |ri|
295
- ri.singleton_methods.each do |m|
296
- (s[m] ||= []).push ri.version
297
- end
298
- ri.instance_methods.each do |m|
299
- (i[m] ||= []).push ri.version
300
- end
301
- end
302
- namecols = calculate_n_namecols(s.keys + i.keys)
303
- versions = @ris.map {|ri| ri.version }
304
- print_header namecols, versions
305
- print_records namecols, versions, (s.to_a + i.to_a)
306
- end
307
-
308
- def calculate_n_namecols(ms)
309
- tabstop = 8
310
- maxnamelen = ms.map {|m| m.fullname.size }.max
311
- (maxnamelen / tabstop + 1) * tabstop
312
- end
313
-
314
- def print_header(namecols, versions)
315
- print ' ' * namecols
316
- versions.each do |ver|
317
- printf '%4s', ver.tr('.', '')
318
- end
319
- puts
320
- end
321
-
322
- def print_records(namecols, versions, records)
323
- veridx = {}
324
- versions.each_with_index do |ver, idx|
325
- veridx[ver] = idx
326
- end
327
- records.sort_by {|m, vers| m.fullname }.each do |m, vers|
328
- printf "%-#{namecols}s", m.fullname
329
-
330
- fmt = '%4s' * versions.size
331
- cols = ['-'] * versions.size
332
- vers.each do |ver|
333
- cols[veridx[ver]] = 'o'
334
- end
335
- printf fmt, *cols
336
- puts
337
- end
338
- end
339
-
340
- end
341
-
342
-
343
- main
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'pathname'
4
- $LOAD_PATH.unshift Pathname($0).realpath.dirname.dirname + 'lib'
5
-
6
- require 'bitclust/methodsignature'
7
-
8
- st = 0
9
- ARGF.each do |line|
10
- if /\A---/ =~ line
11
- begin
12
- BitClust::MethodSignature.parse(line)
13
- rescue => _err
14
- $stderr.puts "#{ARGF.filename}:#{ARGF.file.lineno}: #{line.strip.inspect}"
15
- st = 1
16
- end
17
- end
18
- end
19
- exit st
@@ -1,60 +0,0 @@
1
- require "optparse"
2
- require "uri"
3
- require "fileutils"
4
- require "tempfile"
5
- require "strscan"
6
-
7
- canonical_base_url = "https://docs.ruby-lang.org/ja/latest/"
8
- base_dir = nil
9
-
10
- parser = OptionParser.new
11
- parser.on("--canonical-base-url=URL", "Canonical base URL") do |url|
12
- canonical_base_url = URI(url)
13
- end
14
- parser.on("--base-dir=DIR", "Base directory") do |dir|
15
- base_dir = dir
16
- end
17
-
18
- begin
19
- parser.parse!
20
- rescue OptionParser::ParseError => ex
21
- $stderr.puts ex.message
22
- $stderr.push parser.help
23
- exit(false)
24
- end
25
-
26
- def insert_canonical_url(canonical_base_url, entry)
27
- canonical_link = %Q(<link rel="canonical" href="#{canonical_base_url + entry}">\n)
28
- scanner = StringScanner.new(File.read(entry))
29
- Tempfile.create(File.basename(entry)) do |file|
30
- loop do
31
- if scanner.scan(%r!( +)<link rel="icon" type="image/png" href=".+">\n!)
32
- matched = scanner.matched
33
- file.write(matched)
34
- file.write(scanner[1])
35
- file.write(canonical_link)
36
- end
37
- ch = scanner.getch
38
- if ch
39
- file.write(ch)
40
- else
41
- break
42
- end
43
- end
44
- mode = File.stat(entry).mode
45
- file.flush
46
- FileUtils.cp(file.path, entry)
47
- File.chmod(mode, entry)
48
- end
49
- end
50
-
51
- Dir.chdir(base_dir) do
52
- Dir.glob("**/*.html") do |entry|
53
- print entry
54
- insert_canonical_url(canonical_base_url, entry)
55
- print "\r"
56
- print " " * entry.bytesize
57
- print "\r"
58
- end
59
- puts "done"
60
- end
data/tools/statrefm.rb DELETED
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- class Error < StandardError; end
4
-
5
- def main
6
- entries = parse(find_basedir(ARGV[0]))
7
- puts '--- Status'
8
- done = entries.select {|ent| ent.done? }.size
9
- puts "#{done}/#{entries.size} files done (#{percent_str(done, entries.size)})"
10
- puts
11
- puts '--- Ranking by number of files'
12
- ranking_table(entries) {|ent| 1 }.each_with_index do |(owner, n), idx|
13
- printf "%2d %4d %-s\n", idx + 1, n, (owner || '(not yet)')
14
- end
15
- puts
16
- puts '--- Ranking by Kbytes'
17
- ranking_table(entries) {|ent| ent.size }.each_with_index do |(owner,n), idx|
18
- printf "%2d %4d %-s\n", idx + 1, kb(n), (owner || '(not yet)')
19
- end
20
- rescue Error => err
21
- $stderr.puts err.message
22
- exit 1
23
- end
24
-
25
- def find_basedir(dir)
26
- [ dir, "#{dir}/api", "#{dir}/refm/api", "#{dir}/.." ].each do |basedir|
27
- if File.file?("#{basedir}/ASSIGN")
28
- return basedir
29
- end
30
- end
31
- raise Error, "error: wrong directory: #{dir}"
32
- end
33
-
34
- def percent_str(n, base)
35
- sprintf('%0.2f%%', percent(n, base))
36
- end
37
-
38
- def percent(n, base)
39
- n * 100 / base.to_f
40
- end
41
-
42
- def kb(bytes)
43
- if bytes % 1024 == 0
44
- bytes / 1024
45
- else
46
- (bytes / 1024) + 1
47
- end
48
- end
49
-
50
- def ranking_table(entries)
51
- h = Hash.new(0)
52
- entries.each do |ent|
53
- h[ent.done? ? ent.owner : nil] += yield(ent)
54
- end
55
- h.to_a.sort_by {|owner, n| -n }
56
- end
57
-
58
- def parse(basedir)
59
- File.open("#{basedir}/ASSIGN") {|f|
60
- f.map {|line|
61
- next if line.strip.empty?
62
- next if /\A\#/ =~ line
63
- Entry.new(basedir, *line.split)
64
- }.compact
65
- }
66
- end
67
-
68
- class Entry
69
- def initialize(basedir, name, owner = nil, status = nil)
70
- @basedir = basedir
71
- @name = name
72
- @owner = owner
73
- @status = status
74
- @path = nil
75
- end
76
-
77
- attr_reader :name
78
- attr_reader :owner
79
- attr_reader :status
80
-
81
- def done?
82
- @status == 'done'
83
- end
84
-
85
- def size
86
- File.size(path())
87
- rescue Error
88
- 0
89
- end
90
-
91
- def path
92
- @path ||= ["#{@basedir}/src/#{@name}.rd",
93
- "#{@basedir}/src/#{@name}"].detect {|path| File.file?(path) } or
94
- raise Error, "file not found: library #{@name}"
95
- end
96
- end
97
-
98
- main
data/tools/stattodo.rb DELETED
@@ -1,150 +0,0 @@
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/preprocessor'
9
- require 'find'
10
-
11
- #ALL = 14349
12
-
13
- def main
14
- cmd, hist, prefix = ARGV[0], ARGV[1], ARGV[2]
15
- case cmd
16
- when 'count'
17
- count hist, prefix
18
- when 'update'
19
- update hist, prefix
20
- else
21
- $stderr.puts "unknown command: #{cmd}"
22
- exit 1
23
- end
24
- end
25
-
26
- def count(hist, prefix)
27
- total = 0
28
- curr = 0
29
- Table.parse_file(hist).each do |ent|
30
- n = count_todo_in_file(File.join(prefix, ent.name))
31
- curr += n
32
- total += ent.total
33
- report_count ent.name, n, ent.total
34
- end
35
- report_count 'TOTAL', curr, total
36
- end
37
-
38
- def report_count(label, curr, all)
39
- done = all - curr
40
- printf "%-24s %5d/%5d (%6.2f%%)\n", label, done, all, percent(done, all)
41
- end
42
-
43
- def percent(done, all)
44
- return 0 if all == 0
45
- done * 100 / all.to_f
46
- end
47
-
48
- def update(hist, prefix)
49
- table = Table.parse_file(hist)
50
- table.each do |ent|
51
- ent.push count_todo(File.join(prefix, ent.name))
52
- end
53
- File.open("#{hist}.tmp", 'w') {|f|
54
- f.puts table.header
55
- table.each do |ent|
56
- f.puts ent.serialize
57
- end
58
- }
59
- File.rename "#{hist}.tmp", hist
60
- end
61
-
62
- def count_todo(path)
63
- if File.directory?(path)
64
- count_todo_in_dir(path)
65
- else
66
- count_todo_in_file(path)
67
- end
68
- end
69
-
70
- def count_todo_in_dir(dir)
71
- n = 0
72
- Dir.entries(dir).each do |ent|
73
- next if /\A\./ =~ ent
74
- path = File.join(dir, ent)
75
- if File.extname(ent) == '.rd' and File.file?(path)
76
- n += count_todo_in_file(path)
77
- elsif File.directory?(path)
78
- n += count_todo_in_dir(path)
79
- end
80
- end
81
- n
82
- end
83
-
84
- def count_todo_in_file(path)
85
- n = 0
86
- File.open(path) {|f|
87
- pp = BitClust::LineCollector.wrap(f)
88
- pp.grep(/\A\#[@%]todo/) { n += 1 }
89
- }
90
- n
91
- end
92
-
93
- class Table
94
- def Table.parse_file(path)
95
- File.open(path) {|f|
96
- _, *dates = f.gets.split
97
- ents = f.map {|line|
98
- name, *ns = line.split
99
- Entry.new(name, ns.map {|n| n.to_i })
100
- }
101
- return new(dates, ents)
102
- }
103
- end
104
-
105
- include Enumerable
106
-
107
- def initialize(dates, ents)
108
- @dates = dates
109
- @entries = ents
110
- end
111
-
112
- attr_reader :dates
113
- attr_reader :entries
114
-
115
- def header
116
- (["-"] + @dates).join(' ')
117
- end
118
-
119
- def each(&block)
120
- @entries.each(&block)
121
- end
122
- end
123
-
124
- class Entry
125
- def initialize(name, ns)
126
- @name = name
127
- @counts = ns
128
- end
129
-
130
- attr_reader :name
131
- attr_reader :counts
132
-
133
- def total
134
- @counts.first
135
- end
136
-
137
- def count
138
- @counts.last
139
- end
140
-
141
- def push(n)
142
- @counts.push n
143
- end
144
-
145
- def serialize
146
- @name + "\t" + @counts.join("\t")
147
- end
148
- end
149
-
150
- main
@@ -1,146 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'pathname'
4
-
5
- def srcdir_root
6
- (Pathname.new(__FILE__).realpath.dirname + '..').cleanpath
7
- end
8
-
9
- $LOAD_PATH.unshift srcdir_root() + 'lib'
10
-
11
- require 'bitclust'
12
- require 'fileutils'
13
- require 'net/smtp'
14
- require 'socket'
15
- require 'time'
16
- require 'optparse'
17
-
18
- include FileUtils
19
-
20
- def main
21
- version = '1.9.0'
22
- host = nil
23
- port = Net::SMTP.default_port
24
- from = nil
25
- to = nil
26
-
27
- parser = OptionParser.new
28
- parser.banner = "Usage: #{File.basename($0, '.*')} --from=ADDR --to=ADDR --smtp-host=NAME [--smtp-port-NUM] <refm-api-dir>"
29
- parser.on('--from=ADDR', 'From: address of error report.') {|addr|
30
- from = addr
31
- }
32
- parser.on('--to=ADDR', 'To: address of error report.') {|addr|
33
- to = addr
34
- }
35
- parser.on('--smtp-host=NAME', 'SMTP host to send mail.') {|name|
36
- host = name
37
- }
38
- parser.on('--smtp-port=NUM', 'SMTP port to send mail.') {|num|
39
- port = num.to_i
40
- }
41
- parser.on('--help', 'Prints this message and quit.') {
42
- puts parser.help
43
- exit 0
44
- }
45
- begin
46
- parser.parse!
47
- rescue OptionParser::ParseError => err
48
- $stderr.puts err.message
49
- $stderr.puts parser.help
50
- exit 1
51
- end
52
- unless ARGV.size == 1
53
- $stderr.puts "wrong number of argument (expected 1)"
54
- exit 1
55
- end
56
- reporter = SMTPReporter.new(:host => host, :port => port,
57
- :from => from, :to => to)
58
- cwd = ARGV[0]
59
- Dir.chdir cwd
60
- begin
61
- update_database "#{cwd}/var/#{version}", "#{cwd}/src", version
62
- clear_error
63
- rescue BitClust::Error, Errno::ENOENT => err
64
- reporter.report_error err if new_error?(err)
65
- save_error err
66
- end
67
- end
68
-
69
- def update_database(dbdir, doctree, version)
70
- tmpdir = 'db.tmp'
71
- build_database tmpdir, doctree, version
72
- begin
73
- File.rename dbdir, 'db.old'
74
- rescue Errno::ENOENT
75
- end
76
- mkdir_p File.dirname(dbdir)
77
- File.rename tmpdir, dbdir
78
- ensure
79
- rm_rf 'db.old'
80
- rm_rf tmpdir
81
- end
82
-
83
- def build_database(prefix, doctree, version)
84
- db = BitClust::MethodDatabase.new(prefix)
85
- db.init
86
- db.transaction {
87
- db.propset 'version', version
88
- db.propset 'encoding', 'utf-8'
89
- }
90
- db.transaction {
91
- db.update_by_stdlibtree doctree
92
- }
93
- end
94
-
95
- LASTLOG_FILE = 'lasterror.log'
96
-
97
- def new_error?(err)
98
- return true unless File.exist?(LASTLOG_FILE)
99
- serialize_error(err) != File.read(LASTLOG_FILE)
100
- end
101
-
102
- def save_error(err)
103
- File.open(LASTLOG_FILE, 'w') {|f|
104
- f.write serialize_error(err)
105
- }
106
- end
107
-
108
- def clear_error
109
- rm_f LASTLOG_FILE
110
- end
111
-
112
- def serialize_error(err)
113
- msgline = "#{err.message} (#{err.class})"
114
- backtraces = err.backtrace.map {|s| "\t#{s}" }
115
- ([msgline] + backtraces).join("\n")
116
- end
117
-
118
- class SMTPReporter
119
- def initialize(h)
120
- @host = h[:host]
121
- @port = h[:port]
122
- @from = h[:from]
123
- @to = h[:to]
124
- end
125
-
126
- def report_error(err)
127
- send_message "[build error] #{err.message}", serialize_error(err)
128
- end
129
-
130
- private
131
-
132
- def send_message(subject, body)
133
- Net::SMTP.start(@host, @port, Socket.gethostname) {|smtp|
134
- smtp.send_mail(<<-End, @from, @to)
135
- Date: #{Time.now.rfc2822}
136
- From: #{@from}
137
- To: #{@to}
138
- Subject: #{subject}
139
-
140
- #{body}
141
- End
142
- }
143
- end
144
- end
145
-
146
- main