linecache2 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/COPYING +340 -0
- data/ChangeLog +793 -0
- data/NEWS +63 -0
- data/README.md +28 -0
- data/Rakefile +93 -0
- data/lib/linecache2.rb +566 -0
- data/lib/linecache2/colors.rb +77 -0
- data/lib/linecache2/version.rb +7 -0
- data/lib/tracelines.rb +68 -0
- data/test/data/begin1.rb +3 -0
- data/test/data/begin2.rb +3 -0
- data/test/data/begin3.rb +5 -0
- data/test/data/block1.rb +7 -0
- data/test/data/block2.rb +4 -0
- data/test/data/case1.rb +6 -0
- data/test/data/case2.rb +5 -0
- data/test/data/case3.rb +5 -0
- data/test/data/case4.rb +4 -0
- data/test/data/case5.rb +9 -0
- data/test/data/class1.rb +5 -0
- data/test/data/comments1.rb +3 -0
- data/test/data/def1.rb +9 -0
- data/test/data/each1.rb +3 -0
- data/test/data/end.rb +3 -0
- data/test/data/for1.rb +4 -0
- data/test/data/if1.rb +4 -0
- data/test/data/if2.rb +4 -0
- data/test/data/if3.rb +9 -0
- data/test/data/if4.rb +12 -0
- data/test/data/if5.rb +6 -0
- data/test/data/if6.rb +4 -0
- data/test/data/if7.rb +6 -0
- data/test/data/match.rb +3 -0
- data/test/data/match3.rb +5 -0
- data/test/data/match3a.rb +6 -0
- data/test/data/not-lit.rb +6 -0
- data/test/lnum-diag.rb +130 -0
- data/test/parse-show.rb +14 -0
- data/test/rcov-bug.rb +10 -0
- data/test/short-file +2 -0
- data/test/test-linecache.rb +174 -0
- data/test/test-lnum.rb +35 -0
- data/test/test-tracelines.rb +36 -0
- metadata +112 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'term/ansicolor'
|
2
|
+
require 'coderay'
|
3
|
+
module LineCache
|
4
|
+
ColorScheme = {
|
5
|
+
light: CodeRay::Encoders::Terminal::TOKEN_COLORS.clone,
|
6
|
+
# Adapted from the above
|
7
|
+
dark: {:debug=>"\e[1;37;44m",
|
8
|
+
:annotation=>"\e[33m",
|
9
|
+
:attribute_name=>"\e[35m",
|
10
|
+
:attribute_value=>"\e[31m",
|
11
|
+
:binary=>{:self=>"\e[31m", :char=>"\e[1;31m", :delimiter=>"\e[1;31m"},
|
12
|
+
:char=>{:self=>"\e[35m", :delimiter=>"\e[1;35m"},
|
13
|
+
:class=> '', # "\e[1;36m",
|
14
|
+
:class_variable=> '', # "\e[0;33m",
|
15
|
+
:color=> '', # "\e[32m",
|
16
|
+
:comment=>{:self=>"\e[3;31m", :char=>"\e[0;36m", :delimiter=>"\e[0;36m"},
|
17
|
+
:constant=>"\e[0;36;4m",
|
18
|
+
:decorator=>"\e[35m",
|
19
|
+
:definition=>"\e[1;33m",
|
20
|
+
:directive=>"\e[33m",
|
21
|
+
:docstring=>"\e[31m",
|
22
|
+
:doctype=>"\e[1;33m",
|
23
|
+
:done=>"\e[1;30;2m",
|
24
|
+
:entity=>"\e[31m",
|
25
|
+
:error=>"\e[1;37;41m",
|
26
|
+
:exception=>"\e[1;31m",
|
27
|
+
:float=>"\e[1;35m",
|
28
|
+
:function=>"\e[1;33m",
|
29
|
+
:global_variable=>"\e[1;32m",
|
30
|
+
:hex=>"\e[1;36m",
|
31
|
+
:id=>"\e[1;33m",
|
32
|
+
:include=>"\e[31m",
|
33
|
+
:integer=>"\e[1;34m",
|
34
|
+
:imaginary=>"\e[1;34m",
|
35
|
+
:important=>"\e[1;31m",
|
36
|
+
:key=>{:self=>"\e[35m", :char=>"\e[1;35m", :delimiter=>"\e[1;35m"},
|
37
|
+
:keyword=>"\e[32m",
|
38
|
+
:label=>"\e[1;33m",
|
39
|
+
:local_variable=>"\e[33m",
|
40
|
+
:namespace=>"\e[1;35m",
|
41
|
+
:octal=>"\e[1;33m",
|
42
|
+
:predefined=>"\e[36m",
|
43
|
+
:predefined_constant=>"\e[1;36m",
|
44
|
+
:predefined_type=>"\e[1;32m",
|
45
|
+
:preprocessor=>"\e[1;36m",
|
46
|
+
:pseudo_class=>"\e[1;33m",
|
47
|
+
:regexp=>
|
48
|
+
{:self=>"\e[35m",
|
49
|
+
:delimiter=>"\e[1;35m",
|
50
|
+
:modifier=>"\e[35m",
|
51
|
+
:char=>"\e[1;35m"},
|
52
|
+
:reserved=>"\e[32m",
|
53
|
+
:shell=>
|
54
|
+
{:self=>"\e[33m",
|
55
|
+
:char=>"\e[1;33m",
|
56
|
+
:delimiter=>"\e[1;33m",
|
57
|
+
:escape=>"\e[1;33m"},
|
58
|
+
:string=>
|
59
|
+
{:self=>"\e[33m",
|
60
|
+
:modifier=>"\e[1;31m",
|
61
|
+
:char=>"\e[1;35m",
|
62
|
+
:delimiter=>"\e[1;36m",
|
63
|
+
:escape=>"\e[1;31m"},
|
64
|
+
:symbol=>{:self=>"\e[33m", :delimiter=>"\e[1;33m"},
|
65
|
+
:tag=>"\e[32m",
|
66
|
+
:type=>"\e[1;33m",
|
67
|
+
:value=>"\e[36m",
|
68
|
+
:variable=>"\e[33m",
|
69
|
+
:insert=>{:self=>"\e[42m", :insert=>"\e[1;32;42m", :eyecatcher=>"\e[102m"},
|
70
|
+
:delete=>{:self=>"\e[41m", :delete=>"\e[1;31;41m", :eyecatcher=>"\e[101m"},
|
71
|
+
:change=>{:self=>"\e[44m", :change=>"\e[37;44m"},
|
72
|
+
:head=>{:self=>"\e[45m", :filename=>"\e[37;45m"},
|
73
|
+
:method=>"\e[3;33m",
|
74
|
+
:escape=>nil}
|
75
|
+
# Extend by adding keys for your own style
|
76
|
+
}
|
77
|
+
end
|
data/lib/tracelines.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2007, 2008, 2009, 2010, 2014
|
3
|
+
# Rocky Bernstein <rockyb@rubyforge.net>
|
4
|
+
#
|
5
|
+
# This program is free software; you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation; either version 2 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
18
|
+
# 02110-1301 USA.
|
19
|
+
|
20
|
+
module TraceLineNumbers
|
21
|
+
|
22
|
+
def self.lnums_for_str src
|
23
|
+
name = "#{Time.new.to_i}_#{rand(2**31)}"
|
24
|
+
iseq = RubyVM::InstructionSequence.compile(src, name)
|
25
|
+
lines = {}
|
26
|
+
iseq.disasm.each_line{|line|
|
27
|
+
if /^\d+ (\w+)\s+.+\(\s*(\d+)\)$/ =~ line
|
28
|
+
insn = $1
|
29
|
+
lineno = $2.to_i
|
30
|
+
next unless insn == 'trace'
|
31
|
+
lines[lineno] = true
|
32
|
+
# p [lineno, line]
|
33
|
+
end
|
34
|
+
}
|
35
|
+
lines.keys
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return an array of lines numbers that could be
|
39
|
+
# stopped at given a file name of a Ruby program.
|
40
|
+
def lnums_for_file(file)
|
41
|
+
lnums_for_str(File.read(file))
|
42
|
+
end
|
43
|
+
module_function :lnums_for_file
|
44
|
+
|
45
|
+
# Return an array of lines numbers that could be
|
46
|
+
# stopped at given a string array.
|
47
|
+
def lnums_for_str_array(string_array, newline='', uniq=true)
|
48
|
+
lnums_for_str(string_array.join(newline))
|
49
|
+
end
|
50
|
+
module_function :lnums_for_str_array
|
51
|
+
end
|
52
|
+
|
53
|
+
if __FILE__ == $0
|
54
|
+
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
55
|
+
# test_file = '../test/rcov-bug.rb'
|
56
|
+
test_file = '../test/lnum-data/begin1.rb'
|
57
|
+
if File.exists?(test_file)
|
58
|
+
puts TraceLineNumbers.lnums_for_file(test_file).inspect
|
59
|
+
load(test_file, 0) # for later
|
60
|
+
end
|
61
|
+
puts TraceLineNumbers.lnums_for_file(__FILE__).inspect
|
62
|
+
unless SCRIPT_LINES__.empty?
|
63
|
+
key = SCRIPT_LINES__.keys.first
|
64
|
+
puts key
|
65
|
+
puts SCRIPT_LINES__[key]
|
66
|
+
puts TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[key]).inspect
|
67
|
+
end
|
68
|
+
end
|
data/test/data/begin1.rb
ADDED
data/test/data/begin2.rb
ADDED
data/test/data/block1.rb
ADDED
data/test/data/block2.rb
ADDED
data/test/data/case1.rb
ADDED
data/test/data/case2.rb
ADDED
data/test/data/case3.rb
ADDED
data/test/data/case4.rb
ADDED
data/test/data/case5.rb
ADDED
data/test/data/class1.rb
ADDED
data/test/data/def1.rb
ADDED
data/test/data/each1.rb
ADDED
data/test/data/end.rb
ADDED
data/test/data/for1.rb
ADDED
data/test/data/if1.rb
ADDED
data/test/data/if2.rb
ADDED
data/test/data/if3.rb
ADDED
data/test/data/if4.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# [ 6, 7, 8, 10, 12 ]
|
2
|
+
|
3
|
+
# Running through Tracer will not give the line numbers in the same
|
4
|
+
# order. Also note 9 before 7. This is because in the parse tree
|
5
|
+
# != has been turned into == with the branches switched.
|
6
|
+
[true, false].each do |t|
|
7
|
+
if t != true
|
8
|
+
8
|
9
|
+
else
|
10
|
+
10
|
11
|
+
end
|
12
|
+
end
|
data/test/data/if5.rb
ADDED
data/test/data/if6.rb
ADDED
data/test/data/if7.rb
ADDED
data/test/data/match.rb
ADDED
data/test/lnum-diag.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# begin require 'rubygems' rescue LoadError end
|
4
|
+
# require 'ruby-debug' ; Debugger.start
|
5
|
+
|
6
|
+
TEST_DIR = File.expand_path(File.dirname(__FILE__))
|
7
|
+
TOP_SRC_DIR = File.join(TEST_DIR, '..')
|
8
|
+
require File.join(TOP_SRC_DIR, 'lib', 'tracelines.rb')
|
9
|
+
|
10
|
+
def dump_file(file, opts)
|
11
|
+
puts file
|
12
|
+
begin
|
13
|
+
fp = File.open(file, 'r')
|
14
|
+
rescue Errno::ENOENT
|
15
|
+
puts "File #{file} is not readable."
|
16
|
+
return
|
17
|
+
end
|
18
|
+
lines = fp.read
|
19
|
+
if opts[:print_source]
|
20
|
+
puts '=' * 80
|
21
|
+
puts lines
|
22
|
+
end
|
23
|
+
if opts[:print_parse]
|
24
|
+
puts '=' * 80
|
25
|
+
cmd = "#{File.join(TEST_DIR, 'parse-show.rb')} #{file}"
|
26
|
+
system(cmd)
|
27
|
+
end
|
28
|
+
if opts[:print_trace]
|
29
|
+
require 'tracer'
|
30
|
+
puts '=' * 80
|
31
|
+
tracer = Tracer.new
|
32
|
+
tracer.add_filter lambda {|event, f, line, id, binding, klass|
|
33
|
+
__FILE__ != f && event == 'line'
|
34
|
+
}
|
35
|
+
tracer.on{load(file)}
|
36
|
+
end
|
37
|
+
expected_lnums = nil
|
38
|
+
if opts[:expect_line]
|
39
|
+
fp.rewind
|
40
|
+
first_line = fp.readline.chomp
|
41
|
+
expected_str = first_line[1..-1]
|
42
|
+
begin
|
43
|
+
expected_lnums = eval(expected_str, binding, __FILE__, __LINE__)
|
44
|
+
rescue SyntaxError
|
45
|
+
puts '=' * 80
|
46
|
+
puts "Failed reading expected values from #{file}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
fp.close()
|
50
|
+
got_lnums = TraceLineNumbers.lnums_for_str(lines)
|
51
|
+
if expected_lnums
|
52
|
+
puts "expecting: #{expected_lnums.inspect}"
|
53
|
+
puts '-' * 80
|
54
|
+
if expected_lnums
|
55
|
+
if got_lnums != expected_lnums
|
56
|
+
puts "mismatch: #{got_lnums.inspect}"
|
57
|
+
else
|
58
|
+
puts 'Got what was expected.'
|
59
|
+
end
|
60
|
+
else
|
61
|
+
puts got_lnums.inspect
|
62
|
+
end
|
63
|
+
else
|
64
|
+
puts got_lnums.inspect
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
require 'getoptlong'
|
69
|
+
program = File.basename($0)
|
70
|
+
opts = {
|
71
|
+
:print_source => true, # Print source file?
|
72
|
+
:print_trace => true, # Run Tracer over file?
|
73
|
+
:expect_line => true, # Source file has expected (correct) list of lines?
|
74
|
+
:print_parse => true, # Show ParseTree output?
|
75
|
+
}
|
76
|
+
|
77
|
+
getopts = GetoptLong.new(
|
78
|
+
[ '--expect', '-e', GetoptLong::NO_ARGUMENT ],
|
79
|
+
[ '--no-expect', '-E', GetoptLong::NO_ARGUMENT ],
|
80
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
81
|
+
[ '--parse', '-p', GetoptLong::NO_ARGUMENT ],
|
82
|
+
[ '--no-parse', '-P', GetoptLong::NO_ARGUMENT ],
|
83
|
+
[ '--source', '-s', GetoptLong::NO_ARGUMENT ],
|
84
|
+
[ '--no-source', '-S', GetoptLong::NO_ARGUMENT ],
|
85
|
+
[ '--trace', '-t', GetoptLong::NO_ARGUMENT ],
|
86
|
+
[ '--no-trace', '-T', GetoptLong::NO_ARGUMENT ])
|
87
|
+
|
88
|
+
getopts.each do |opt, arg|
|
89
|
+
case opt
|
90
|
+
when '--help'
|
91
|
+
puts "usage
|
92
|
+
Usage: #{$program} [options] file1 file2 ...
|
93
|
+
|
94
|
+
Diagnostic program to make see what TraceLineNumbers does and compare
|
95
|
+
against other output.
|
96
|
+
|
97
|
+
options:
|
98
|
+
-e --expect Read source file expected comment (default)
|
99
|
+
-E --no-expect Don't look for source file expected comment
|
100
|
+
-p --parse Show ParseTree Output (default)
|
101
|
+
-P --no-parse Don't show ParseTree output
|
102
|
+
-s --source Show source file (default)
|
103
|
+
-S --no-source Don't print source
|
104
|
+
-t --trace Show Tracer output (default)
|
105
|
+
-T --no-trace Don't show Tracer output
|
106
|
+
"
|
107
|
+
when '--expect'
|
108
|
+
opts[:expect_line] = true
|
109
|
+
when '--no-expect'
|
110
|
+
opts[:expect_line] = false
|
111
|
+
when '--parse'
|
112
|
+
opts[:print_parse] = true
|
113
|
+
when '--no-parse'
|
114
|
+
opts[:print_parse] = false
|
115
|
+
when '--source'
|
116
|
+
opts[:print_source] = true
|
117
|
+
when '--no-source'
|
118
|
+
opts[:print_source] = false
|
119
|
+
when '--trace'
|
120
|
+
opts[:print_trace] = true
|
121
|
+
when '--no-trace'
|
122
|
+
opts[:print_trace] = false
|
123
|
+
else
|
124
|
+
puts "Unknown and ignored option #{opt}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
ARGV.each do |file|
|
129
|
+
dump_file(file, opts)
|
130
|
+
end
|