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 +9 -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
- metadata +118 -0
@@ -0,0 +1,19 @@
|
|
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
|
@@ -0,0 +1,20 @@
|
|
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
|
+
|
10
|
+
include BitClust::CrossRubyUtils
|
11
|
+
|
12
|
+
def main
|
13
|
+
ENV.delete('GEM_HOME')
|
14
|
+
forall_ruby(ENV['PATH']) do |ruby, ver|
|
15
|
+
puts ver
|
16
|
+
system ruby, *ARGV
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
main
|
data/tools/gencatalog.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# gencatalog.rb
|
4
|
+
#
|
5
|
+
# Copyright (c) 2008 Minero Aoki
|
6
|
+
#
|
7
|
+
# This program is free software.
|
8
|
+
# You can distribute/modify this program under the Ruby License.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'optparse'
|
12
|
+
|
13
|
+
def main
|
14
|
+
catalog_path = nil
|
15
|
+
parser = OptionParser.new
|
16
|
+
parser.banner = "Usage: #{File.basename($0)} --merge=PATH [<file>...]"
|
17
|
+
parser.on('--merge=PATH', 'Current catalog file.') {|path|
|
18
|
+
catalog_path = path
|
19
|
+
}
|
20
|
+
parser.on('--help', 'Prints this message and quit.') {
|
21
|
+
puts parser.help
|
22
|
+
exit 0
|
23
|
+
}
|
24
|
+
begin
|
25
|
+
parser.parse!
|
26
|
+
rescue OptionParser::ParseError => err
|
27
|
+
$stderr.puts err
|
28
|
+
$stderr.puts parser.help
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
h = collect_messages(ARGF)
|
33
|
+
h.update load_catalog(catalog_path) if catalog_path
|
34
|
+
print_catalog h
|
35
|
+
end
|
36
|
+
|
37
|
+
def print_catalog(h)
|
38
|
+
h.keys.sort.each do |key|
|
39
|
+
puts key
|
40
|
+
puts h[key]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def collect_messages(f)
|
45
|
+
h = {}
|
46
|
+
f.each do |line|
|
47
|
+
line.scan(/_\(
|
48
|
+
(?: "( (?:[^"]+|\\.)* )"
|
49
|
+
| '( (?:[^']+|\\.)* )'
|
50
|
+
)
|
51
|
+
/x) do
|
52
|
+
text = ($1 || $2).strip
|
53
|
+
h[text] = text unless text.empty?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
h
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_catalog(path)
|
60
|
+
h = {}
|
61
|
+
File.open(path) {|f|
|
62
|
+
f.each do |line|
|
63
|
+
h[line.chomp] = f.gets.chomp
|
64
|
+
end
|
65
|
+
}
|
66
|
+
h
|
67
|
+
end
|
68
|
+
|
69
|
+
main
|
data/tools/statrefm.rb
ADDED
@@ -0,0 +1,98 @@
|
|
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
ADDED
@@ -0,0 +1,150 @@
|
|
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
|
@@ -0,0 +1,146 @@
|
|
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
|