bitclust-dev 0.5.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.
@@ -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