utils 0.0.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.
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/chroot-exec +12 -0
- data/bin/chroot-libs +18 -0
- data/bin/classify +37 -0
- data/bin/discover +137 -0
- data/bin/edit +74 -0
- data/bin/errf +32 -0
- data/bin/git-empty +8 -0
- data/bin/myex +90 -0
- data/bin/number_files +26 -0
- data/bin/same_files +37 -0
- data/bin/search +205 -0
- data/bin/sedit +3 -0
- data/bin/sshscreen +68 -0
- data/bin/term +21 -0
- data/bin/unquarantine_apps +8 -0
- data/bin/untest +17 -0
- data/bin/utils-install-config +10 -0
- data/bin/vacuum_firefox_sqlite +22 -0
- data/bin/xmp +74 -0
- data/lib/utils.rb +8 -0
- data/lib/utils/config.rb +23 -0
- data/lib/utils/config/gdb/asm +179 -0
- data/lib/utils/config/gdb/ruby +528 -0
- data/lib/utils/config/gdbinit +8 -0
- data/lib/utils/config/irbrc +455 -0
- data/lib/utils/config/rdebugrc +2 -0
- data/lib/utils/config/screenrc +143 -0
- data/lib/utils/config/vim/autoload/Align.vim +1029 -0
- data/lib/utils/config/vim/autoload/AlignMaps.vim +330 -0
- data/lib/utils/config/vim/autoload/rails.vim +4744 -0
- data/lib/utils/config/vim/autoload/rubycomplete.vim +801 -0
- data/lib/utils/config/vim/autoload/sqlcomplete.vim +741 -0
- data/lib/utils/config/vim/autoload/vimball.vim +750 -0
- data/lib/utils/config/vim/colors/flori.vim +113 -0
- data/lib/utils/config/vim/compiler/eruby.vim +40 -0
- data/lib/utils/config/vim/compiler/ruby.vim +67 -0
- data/lib/utils/config/vim/compiler/rubyunit.vim +34 -0
- data/lib/utils/config/vim/ftdetect/ragel.vim +2 -0
- data/lib/utils/config/vim/ftdetect/ruby.vim +17 -0
- data/lib/utils/config/vim/ftplugin/eruby.vim +100 -0
- data/lib/utils/config/vim/ftplugin/ruby.vim +260 -0
- data/lib/utils/config/vim/ftplugin/xml.vim +941 -0
- data/lib/utils/config/vim/indent/IndentAnything_html.vim +35 -0
- data/lib/utils/config/vim/indent/eruby.vim +77 -0
- data/lib/utils/config/vim/indent/javascript.vim +116 -0
- data/lib/utils/config/vim/indent/ruby.vim +377 -0
- data/lib/utils/config/vim/plugin/AlignMapsPlugin.vim +242 -0
- data/lib/utils/config/vim/plugin/AlignPlugin.vim +41 -0
- data/lib/utils/config/vim/plugin/Decho.vim +592 -0
- data/lib/utils/config/vim/plugin/IndentAnything.vim +675 -0
- data/lib/utils/config/vim/plugin/bufexplorer.vim +1144 -0
- data/lib/utils/config/vim/plugin/cecutil.vim +482 -0
- data/lib/utils/config/vim/plugin/fugitive.vim +1703 -0
- data/lib/utils/config/vim/plugin/lusty-explorer.vim +1509 -0
- data/lib/utils/config/vim/plugin/rails.vim +340 -0
- data/lib/utils/config/vim/plugin/rubyextra.vim +193 -0
- data/lib/utils/config/vim/plugin/surround.vim +628 -0
- data/lib/utils/config/vim/plugin/taglist.vim +4546 -0
- data/lib/utils/config/vim/plugin/test/IndentAnything/test.js +131 -0
- data/lib/utils/config/vim/plugin/vimballPlugin.vim +40 -0
- data/lib/utils/config/vim/syntax/Decho.vim +101 -0
- data/lib/utils/config/vim/syntax/eruby.vim +73 -0
- data/lib/utils/config/vim/syntax/javascript.vim +246 -0
- data/lib/utils/config/vim/syntax/ragel.vim +165 -0
- data/lib/utils/config/vim/syntax/ruby.vim +367 -0
- data/lib/utils/config/vimrc +461 -0
- data/lib/utils/file.rb +49 -0
- data/lib/utils/find.rb +54 -0
- data/lib/utils/md5.rb +23 -0
- data/lib/utils/patterns.rb +34 -0
- data/lib/utils/version.rb +8 -0
- data/utils.gemspec +33 -0
- metadata +183 -0
data/bin/number_files
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils::Verbose
|
5
|
+
|
6
|
+
def usage
|
7
|
+
STDERR.puts "Usage: #$0 prefix"
|
8
|
+
end
|
9
|
+
|
10
|
+
ARGV.empty? and usage
|
11
|
+
prefix = ARGV.shift
|
12
|
+
files = ARGV.sort_by do |x|
|
13
|
+
if m = /(\d+)/.match(x)
|
14
|
+
[ m.pre_match == prefix ? -1 : 0, m[1].to_i ]
|
15
|
+
else
|
16
|
+
[ -1, 0 ]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
for f in files
|
20
|
+
mv f, f + '.tmp'
|
21
|
+
end
|
22
|
+
i = 1
|
23
|
+
for f in files
|
24
|
+
mv f + '.tmp', sprintf("%s%03u", prefix, i)
|
25
|
+
i += 1
|
26
|
+
end
|
data/bin/same_files
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'utils'
|
4
|
+
include Utils::MD5
|
5
|
+
|
6
|
+
def find_same(*pathes)
|
7
|
+
files = Hash.new { |h,k| h[k] = {} }
|
8
|
+
Utils::Find.find(*pathes) do |filename|
|
9
|
+
file_stat = File.stat(filename)
|
10
|
+
if file_stat.file?
|
11
|
+
size = file_stat.size
|
12
|
+
$DEBUG and warn "Encountered '#{filename}' (#{size} bytes)."
|
13
|
+
files[size][filename] = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
files = files.inject({}) do |h, (_,fs)|
|
18
|
+
keys = fs.keys
|
19
|
+
if keys.size >= 2
|
20
|
+
keys.each { |k| h[k] = true }
|
21
|
+
end
|
22
|
+
h
|
23
|
+
end.keys
|
24
|
+
|
25
|
+
md5s = Hash.new { |h,k| h[k] = [] }
|
26
|
+
for filename in files
|
27
|
+
md5sum = md5 filename
|
28
|
+
md5s[md5sum] << filename
|
29
|
+
end
|
30
|
+
files = md5s.values
|
31
|
+
files.reject! { |fs| fs.size < 2 }
|
32
|
+
files
|
33
|
+
end
|
34
|
+
|
35
|
+
puts find_same(*ARGV).map { |fs| [ fs.size, fs ] }.sort.map { |c, fs|
|
36
|
+
"#{c}\t#{fs.sort.map { |f| "'#{f}'" } * "\t"}"
|
37
|
+
}
|
data/bin/search
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require 'utils'
|
5
|
+
include Utils::Patterns
|
6
|
+
require 'term/ansicolor'
|
7
|
+
require 'spruz/xt'
|
8
|
+
|
9
|
+
class ::String
|
10
|
+
include Term::ANSIColor
|
11
|
+
end
|
12
|
+
|
13
|
+
class ::File
|
14
|
+
include Utils::FileXt
|
15
|
+
end
|
16
|
+
|
17
|
+
class Grepper
|
18
|
+
PRUNE = /\A(\.svn|\.git|CVS|tmp)\Z/
|
19
|
+
SKIP = /(\A\.|\.sw[pon]\Z|~\Z)/
|
20
|
+
|
21
|
+
class Queue
|
22
|
+
def initialize(max_size)
|
23
|
+
@max_size, @data = max_size, []
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :max_size
|
27
|
+
|
28
|
+
def data
|
29
|
+
@data.dup
|
30
|
+
end
|
31
|
+
|
32
|
+
def push(x)
|
33
|
+
@data.shift if @data.size > @max_size
|
34
|
+
@data << x
|
35
|
+
self
|
36
|
+
end
|
37
|
+
alias << push
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(opts = {})
|
41
|
+
@args = opts[:args] || {}
|
42
|
+
@roots = opts[:roots] || []
|
43
|
+
if n = @args.values_at(*%w[A B C]).compact.first
|
44
|
+
if n.to_s =~ /\A\d+\Z/ and (n = n.to_i) >= 1
|
45
|
+
@queue = Queue.new n
|
46
|
+
else
|
47
|
+
raise ArgumentError, "needs to be an integer number >= 1"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
@pathes = []
|
51
|
+
pattern_opts = opts.subhash(:pattern) | {
|
52
|
+
:cset => @args['a'],
|
53
|
+
:icase => @args['i'],
|
54
|
+
}
|
55
|
+
@pattern = @args['R'] ?
|
56
|
+
FuzzyPattern.new(pattern_opts) :
|
57
|
+
RegexpPattern.new(pattern_opts)
|
58
|
+
@name_pattern =
|
59
|
+
if name_pattern = @args['N']
|
60
|
+
RegexpPattern.new(:pattern => name_pattern)
|
61
|
+
elsif name_pattern = @args['n']
|
62
|
+
FuzzyPattern.new(:pattern => name_pattern)
|
63
|
+
end
|
64
|
+
@skip_pattern =
|
65
|
+
if skip_pattern = @args['S']
|
66
|
+
RegexpPattern.new(:pattern => skip_pattern)
|
67
|
+
elsif skip_pattern = @args['s']
|
68
|
+
FuzzyPattern.new(:pattern => skip_pattern)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
attr_reader :pathes
|
73
|
+
|
74
|
+
def match(filename)
|
75
|
+
@filename = filename
|
76
|
+
bn = File.basename(filename)
|
77
|
+
@output = []
|
78
|
+
s = File.stat(filename)
|
79
|
+
if s.directory? && bn =~ PRUNE
|
80
|
+
$DEBUG and warn "Pruning '#{filename}'."
|
81
|
+
Utils::Find.prune
|
82
|
+
end
|
83
|
+
if s.file? && bn !~ SKIP && (!@name_pattern || @name_pattern.match(bn))
|
84
|
+
File.open(filename, 'rb') do |file|
|
85
|
+
if file.binary? != true
|
86
|
+
$DEBUG and warn "Matching '#{filename}'."
|
87
|
+
match_lines file
|
88
|
+
else
|
89
|
+
$DEBUG and warn "Skipping binary file '#{filename}'."
|
90
|
+
end
|
91
|
+
end
|
92
|
+
else
|
93
|
+
$DEBUG and warn "Skipping '#{filename}'."
|
94
|
+
end
|
95
|
+
unless @output.empty?
|
96
|
+
case
|
97
|
+
when @args['l'], @args['e']
|
98
|
+
@output.uniq!
|
99
|
+
@pathes.concat @output
|
100
|
+
else
|
101
|
+
STDOUT.puts @output
|
102
|
+
end
|
103
|
+
@output.clear
|
104
|
+
end
|
105
|
+
self
|
106
|
+
rescue SystemCallError => e
|
107
|
+
warn "Caught #{e.class}: #{e}"
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def match_lines(file)
|
112
|
+
for line in file
|
113
|
+
if m = @pattern.match(line)
|
114
|
+
@skip_pattern and @skip_pattern =~ line and next
|
115
|
+
line[m.begin(0)...m.end(0)] = m[0].on_yellow
|
116
|
+
@queue and @queue << line
|
117
|
+
if @args['l'] or @args['e']
|
118
|
+
@output << @filename
|
119
|
+
elsif @args['L']
|
120
|
+
@output << "#{@filename}:#{file.lineno}"
|
121
|
+
else
|
122
|
+
@output << "#{@filename}:#{file.lineno}".red
|
123
|
+
if @args['B'] or @args['C']
|
124
|
+
@output.concat @queue.data
|
125
|
+
else
|
126
|
+
@output << line
|
127
|
+
end
|
128
|
+
if @args['A'] or @args['C']
|
129
|
+
where = file.tell
|
130
|
+
@queue.max_size.times do
|
131
|
+
file.eof? and break
|
132
|
+
line = file.readline
|
133
|
+
@queue << line
|
134
|
+
@output << line
|
135
|
+
end
|
136
|
+
file.seek where
|
137
|
+
end
|
138
|
+
end
|
139
|
+
else
|
140
|
+
@queue and @queue << line
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def search
|
146
|
+
for dir in @roots
|
147
|
+
Utils::Find.find(dir) { |filename| match(filename) }
|
148
|
+
end
|
149
|
+
@pathes.sort!
|
150
|
+
self
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
include Spruz::GO
|
155
|
+
|
156
|
+
def edit_files(pathes)
|
157
|
+
system "edit #{pathes.map { |x| "'#{x}'" } * ' '}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def usage
|
161
|
+
puts <<-EOT
|
162
|
+
Usage: #{File.basename($0)} [OPTS] PATTERN [PATHES]
|
163
|
+
|
164
|
+
PATTERN is a pattern expression which is used to match against the content of
|
165
|
+
the files. PATHES are the directory and file pathes that are searched.
|
166
|
+
|
167
|
+
Options are
|
168
|
+
|
169
|
+
-n PATTERN only search files whose names match fuzzy PATTERN
|
170
|
+
-N PATTERN only search files whose names match regex PATTERN
|
171
|
+
-s PATTERN skip lines that match fuzzy PATTERN
|
172
|
+
-S PATTERN skip lines that match regex PATTERN
|
173
|
+
-A NUMBER displays NUMBER lines of context after the match
|
174
|
+
-B NUMBER displays NUMBER lines of context before the match
|
175
|
+
-C NUMBER displays NUMBER lines of context around the match
|
176
|
+
-l just list the pathes of the files with matches
|
177
|
+
-L list only the path:linenumber of the files with matches
|
178
|
+
-R interpret PATTERN argument as fuzzy not regex
|
179
|
+
-c disable color output
|
180
|
+
-i use case insensitive matches
|
181
|
+
-e open the matching files with edit command
|
182
|
+
-a CSET use only character set CSET from PATTERN
|
183
|
+
-h display this help
|
184
|
+
|
185
|
+
EOT
|
186
|
+
exit 1
|
187
|
+
end
|
188
|
+
|
189
|
+
args = go 'A:B:C:s:S:n:N:a:RcilLeh'
|
190
|
+
args['h'] and usage
|
191
|
+
pattern = ARGV.shift or usage
|
192
|
+
roots = (ARGV.empty? ? [ Dir.pwd ] : ARGV).map { |f| File.expand_path(f) }
|
193
|
+
|
194
|
+
Term::ANSIColor.coloring = (STDIN.tty? && ENV['TERM'] !~ /dumb/) && !args['c']
|
195
|
+
STDOUT.sync = true
|
196
|
+
|
197
|
+
grepper = Grepper.new(
|
198
|
+
:pattern => pattern,
|
199
|
+
:args => args,
|
200
|
+
:roots => roots
|
201
|
+
).search
|
202
|
+
case
|
203
|
+
when args['e'] then edit_files grepper.pathes
|
204
|
+
when args['l'] then puts grepper.pathes
|
205
|
+
end
|
data/bin/sedit
ADDED
data/bin/sshscreen
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils::Verbose
|
5
|
+
require 'spruz/go'
|
6
|
+
include Spruz::GO
|
7
|
+
|
8
|
+
=begin
|
9
|
+
~/.ssh/config:
|
10
|
+
|
11
|
+
Host *
|
12
|
+
ForwardX11 = yes
|
13
|
+
ControlMaster auto
|
14
|
+
ControlPath ~/.ssh/%r@%h:%p.sock
|
15
|
+
=end
|
16
|
+
|
17
|
+
def usage
|
18
|
+
puts <<EOT
|
19
|
+
Usage: #{File.basename($0)} [OPTS] [user@]remote[:port]"
|
20
|
+
|
21
|
+
OPTS is one of
|
22
|
+
-N list all session names on the specified remote
|
23
|
+
-n NAME name of the screen session to attach to
|
24
|
+
-t [HOST[:PORT]] host:port to tunnel if different from LOCALPORT
|
25
|
+
-l LOCALPORT the localport to forward to
|
26
|
+
-h to display this help
|
27
|
+
|
28
|
+
EOT
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
arguments = ARGV.dup
|
33
|
+
opts = go 'l:t:n:hN', arguments
|
34
|
+
usage if opts['h'] or arguments.size != 1
|
35
|
+
user_remote = arguments.shift
|
36
|
+
user, remote, rport =
|
37
|
+
case user_remote
|
38
|
+
when /\A(?:([^@:]+)@)?([^@:]+)(?::(\d+))?\Z/
|
39
|
+
user = $1 || ENV['USER']
|
40
|
+
user.to_s.empty? and fail "user required to login"
|
41
|
+
[ user, $2, $3 || '22' ]
|
42
|
+
else
|
43
|
+
usage
|
44
|
+
end
|
45
|
+
lport = opts['l']
|
46
|
+
tunnel, tport = if tunnel_port = opts['t']
|
47
|
+
case tunnel_port
|
48
|
+
when /\A([^:]+)(?::(\d+))?\Z/
|
49
|
+
[ $1, $2 || '22' ]
|
50
|
+
else
|
51
|
+
usage
|
52
|
+
end
|
53
|
+
else
|
54
|
+
[ 'localhost', lport ]
|
55
|
+
end
|
56
|
+
ssh_dir = File.expand_path('~/.ssh')
|
57
|
+
mkdir_p ssh_dir
|
58
|
+
sock_file = "#{ssh_dir}/#{user}@#{remote}:#{rport}.sock"
|
59
|
+
if opts['N']
|
60
|
+
exec "ssh -p #{rport} -S #{sock_file} #{user}@#{remote} screen -ls"
|
61
|
+
elsif lport
|
62
|
+
File.exist? sock_file and rm_f sock_file
|
63
|
+
exec "ssh -p #{rport} -Mt -L localhost:#{lport}:#{tunnel}:#{tport}"\
|
64
|
+
" -S #{sock_file} #{user}@#{remote} screen -DUR #{opts['n']}"
|
65
|
+
else
|
66
|
+
File.exist? sock_file and rm_f sock_file
|
67
|
+
exec "ssh -p #{rport} -Mt -S #{sock_file} #{user}@#{remote} screen -DUR #{opts['n']}"
|
68
|
+
end
|
data/bin/term
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
if [ "x-x" = x"$1" ]; then
|
4
|
+
EXIT="; exit"; shift;
|
5
|
+
fi
|
6
|
+
|
7
|
+
if [[ -d "$1" ]]; then
|
8
|
+
WD=`cd "$1"; pwd`; shift;
|
9
|
+
else
|
10
|
+
WD="'`pwd`'";
|
11
|
+
fi
|
12
|
+
|
13
|
+
COMMAND="cd $WD; $@"
|
14
|
+
echo "$COMMAND $EXIT"
|
15
|
+
|
16
|
+
osascript 2>/dev/null <<EOF
|
17
|
+
tell application "Terminal"
|
18
|
+
activate
|
19
|
+
do script with command "$COMMAND $EXIT"
|
20
|
+
end tell
|
21
|
+
EOF
|
data/bin/untest
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spruz/xt/write'
|
4
|
+
|
5
|
+
for filename in ARGV
|
6
|
+
File.open(filename) do |input|
|
7
|
+
write(filename) do |output|
|
8
|
+
until input.eof?
|
9
|
+
line = input.readline
|
10
|
+
line.sub!(/^(\s*)test "(.+)" do\s*$/) do
|
11
|
+
"#$1def test_" << $2.downcase.gsub(/\A[^a-z]/, '').gsub(/[ -]/, '_').delete('^0-9a-z_')
|
12
|
+
end
|
13
|
+
output.puts line
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
case `uname -s` in
|
4
|
+
Darwin)
|
5
|
+
profiles="$HOME/Library/Application Support/Firefox/Profiles/"
|
6
|
+
;;
|
7
|
+
*)
|
8
|
+
profiles="$HOME/.mozilla/firefox/"
|
9
|
+
;;
|
10
|
+
esac
|
11
|
+
|
12
|
+
cd "$profiles"
|
13
|
+
for p in *.default
|
14
|
+
do
|
15
|
+
cd $p
|
16
|
+
for db in *.sqlite
|
17
|
+
do
|
18
|
+
echo "Vacuuming $db..."
|
19
|
+
sqlite3 $db VACUUM
|
20
|
+
done
|
21
|
+
cd -
|
22
|
+
done
|
data/bin/xmp
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
class String
|
5
|
+
unless method_defined?(:lines)
|
6
|
+
def lines
|
7
|
+
self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
MARKER = "!XMP#{Time.new.to_i}_#{rand(1000000)}!"
|
13
|
+
XMPRE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] => (.*)')
|
14
|
+
VAR = "_xmp_#{Time.new.to_i}_#{rand(1000000)}"
|
15
|
+
WARNING_RE = /-:([0-9]+): warning: (.*)/
|
16
|
+
interpreter = ARGV
|
17
|
+
interpreter << 'ruby' << '-w' if interpreter.empty?
|
18
|
+
|
19
|
+
IO.popen(interpreter.first, 'w') do |script|
|
20
|
+
script.write <<-TEST
|
21
|
+
begin
|
22
|
+
require 'rubygems'
|
23
|
+
rescue LoadError
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
exit 0
|
27
|
+
TEST
|
28
|
+
end
|
29
|
+
if $?.exitstatus == 1
|
30
|
+
ENV['RUBYOPT'] = ENV['RUBYOPT'].gsub(/-rr?ubygems/i, '')
|
31
|
+
end
|
32
|
+
code = STDIN.read
|
33
|
+
|
34
|
+
idx = 0
|
35
|
+
newcode = code.gsub(/^(.*) # =>.*/) do |l|
|
36
|
+
expr = $1
|
37
|
+
(/^\s*#/ =~ l) ? l :
|
38
|
+
%!((#{VAR} = (#{expr}); $stderr.puts("#{MARKER}[#{idx+=1}] => " + #{VAR}.inspect) || #{VAR}))!
|
39
|
+
end
|
40
|
+
stdin, stdout, stderr = Open3::popen3(*interpreter)
|
41
|
+
stdin.puts newcode
|
42
|
+
stdin.close
|
43
|
+
output = stderr.readlines
|
44
|
+
|
45
|
+
results = Hash.new{|h,k| h[k] = []}
|
46
|
+
output.grep(XMPRE).each do |line|
|
47
|
+
result_id, result = XMPRE.match(line).captures
|
48
|
+
results[result_id.to_i] << result
|
49
|
+
end
|
50
|
+
|
51
|
+
idx = 0
|
52
|
+
annotated = code.gsub(/^(.*) # =>.*/) do |l|
|
53
|
+
expr = $1
|
54
|
+
(/^\s*#/ =~ l) ? l : "#{expr} # => " + (results[idx+=1] || []).join(", ")
|
55
|
+
end.gsub(/ # !>.*/, '').gsub(/# (>>|~>)[^\n]*\n/m, "");
|
56
|
+
|
57
|
+
warnings = {}
|
58
|
+
output.join.lines.grep(WARNING_RE).map do |x|
|
59
|
+
md = WARNING_RE.match(x)
|
60
|
+
warnings[md[1].to_i] = md[2]
|
61
|
+
end
|
62
|
+
idx = 0
|
63
|
+
annotated = annotated.lines.map do |line|
|
64
|
+
w = warnings[idx+=1]
|
65
|
+
w ? (line.chomp + " # !> #{w}") : line
|
66
|
+
end
|
67
|
+
puts annotated
|
68
|
+
output.reject!{|x| /^-:[0-9]+: warning/.match(x)}
|
69
|
+
if exception = /^-:[0-9]+:.*/m.match(output.join)
|
70
|
+
puts exception[0].map{|line| "# ~> " + line }
|
71
|
+
end
|
72
|
+
if (s = stdout.read) != ""
|
73
|
+
puts "# >> #{s.inspect}"
|
74
|
+
end
|