bitclust-dev 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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