linecache19-patched 0.5.13

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/README ADDED
@@ -0,0 +1,50 @@
1
+ = LineCache - A module to read and cache file information of a Ruby program.
2
+
3
+ == SYNOPSIS
4
+
5
+ The LineCache module allows one to get any line from any file, caching
6
+ the lines and file information on first access to the file. Although
7
+ the file may be any file, the common use is when the file is a Ruby
8
+ script since parsing of the file is done to figure out where the
9
+ statement boundaries are.
10
+
11
+ The routines here may be is useful when a small random sets of lines
12
+ are read from a single file, in particular in a debugger to show
13
+ source lines.
14
+
15
+ == Summary
16
+
17
+ require 'linecache'
18
+ lines = LineCache::getlines('/tmp/myruby.rb')
19
+ # The following lines have same effect as the above.
20
+ $: << '/tmp'
21
+ Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb')
22
+
23
+ line = LineCache::getline('/tmp/myruby.rb', 6)
24
+ # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)
25
+
26
+ LineCache::clear_file_cache
27
+ LineCache::clear_file_cache('/tmp/myruby.rb')
28
+ LineCache::update_cache # Check for modifications of all cached files.
29
+
30
+ == Credits
31
+
32
+ This is a port of the module of the same name from the Python distribution.
33
+
34
+ The idea for how TraceLineNumbers works, and some code was taken
35
+ from ParseTree by Ryan Davis.
36
+
37
+ == Other stuff
38
+
39
+ Author:: Rocky Bernstein <rockyb@rubyforge.net>
40
+ License:: Copyright (c) 2007, 2008 Rocky Bernstein
41
+ Released under the GNU GPL 2 license
42
+
43
+ == Warranty
44
+
45
+ This program is distributed in the hope that it will be useful,
46
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ GNU General Public License for more details.
49
+
50
+ $Id$
@@ -0,0 +1,409 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id$
3
+ #
4
+ # Copyright (C) 2007, 2008 Rocky Bernstein <rockyb@rubyforge.net>
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
+ # 02110-1301 USA.
20
+ #
21
+
22
+ # Author:: Rocky Bernstein (mailto:rockyb@rubyforge.net)
23
+ #
24
+ # = linecache
25
+ # A module to read and cache lines of a Ruby program.
26
+ # == Version
27
+ # :include:VERSION
28
+
29
+ # == SYNOPSIS
30
+ #
31
+ # The LineCache module allows one to get any line from any file,
32
+ # caching lines of the file on first access to the file. Although the
33
+ # file may be any file, the common use is when the file is a Ruby
34
+ # script since parsing of the file is done to figure out where the
35
+ # statement boundaries are.
36
+ #
37
+ # The routines here may be is useful when a small random sets of lines
38
+ # are read from a single file, in particular in a debugger to show
39
+ # source lines.
40
+ #
41
+ #
42
+ # require 'linecache19'
43
+ # lines = LineCache::getlines('/tmp/myruby.rb')
44
+ # # The following lines have same effect as the above.
45
+ # $: << '/tmp'
46
+ # Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb')
47
+ #
48
+ # line = LineCache::getline('/tmp/myruby.rb', 6)
49
+ # # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)
50
+ #
51
+ # LineCache::clear_file_cache
52
+ # LineCache::clear_file_cache('/tmp/myruby.rb')
53
+ # LineCache::update_cache # Check for modifications of all cached files.
54
+ #
55
+ # Some parts of the interface is derived from the Python module of the
56
+ # same name.
57
+ #
58
+
59
+ # Defining SCRIPT_LINES__ causes Ruby to cache the lines of files
60
+ # it reads. The key the setting of __FILE__ at the time when Ruby does
61
+ # its read. LineCache keeps a separate copy of the lines elsewhere
62
+ # and never destroys SCRIPT_LINES__
63
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
64
+
65
+ require 'digest/sha1'
66
+ require 'set'
67
+
68
+ begin require 'rubygems' rescue LoadError end
69
+ require 'tracelines19'
70
+ # require 'ruby-debug' ; Debugger.start
71
+
72
+ # = module LineCache
73
+ # A module to read and cache lines of a Ruby program.
74
+ module LineCache
75
+ LineCacheInfo = Struct.new(:stat, :line_numbers, :lines, :path, :sha1) unless
76
+ defined?(LineCacheInfo)
77
+
78
+ # The file cache. The key is a name as would be given by Ruby for
79
+ # __FILE__. The value is a LineCacheInfo object.
80
+ @@file_cache = {}
81
+
82
+ # Maps a string filename (a String) to a key in @@file_cache (a
83
+ # String).
84
+ #
85
+ # One important use of @@file2file_remap is mapping the a full path
86
+ # of a file into the name stored in @@file_cache or given by Ruby's
87
+ # __FILE__. Applications such as those that get input from users,
88
+ # may want canonicalize a file name before looking it up. This map
89
+ # gives a way to do that.
90
+ #
91
+ # Another related use is when a template system is used. Here we'll
92
+ # probably want to remap not only the file name but also line
93
+ # ranges. Will probably use this for that, but I'm not sure.
94
+ @@file2file_remap = {}
95
+ @@file2file_remap_lines = {}
96
+
97
+ # Clear the file cache entirely.
98
+ def clear_file_cache()
99
+ @@file_cache = {}
100
+ @@file2file_remap = {}
101
+ @@file2file_remap_lines = {}
102
+ end
103
+ module_function :clear_file_cache
104
+
105
+ # Return an array of cached file names
106
+ def cached_files()
107
+ @@file_cache.keys
108
+ end
109
+ module_function :cached_files
110
+
111
+ # Discard cache entries that are out of date. If +filename+ is +nil+
112
+ # all entries in the file cache +@@file_cache+ are checked.
113
+ # If we don't have stat information about a file, which can happen
114
+ # if the file was read from SCRIPT_LINES__ but no corresponding file
115
+ # is found, it will be kept. Return a list of invalidated filenames.
116
+ # nil is returned if a filename was given but not found cached.
117
+ def checkcache(filename=nil, use_script_lines=false)
118
+
119
+ if !filename
120
+ filenames = @@file_cache.keys()
121
+ elsif @@file_cache.member?(filename)
122
+ filenames = [filename]
123
+ else
124
+ return nil
125
+ end
126
+
127
+ result = []
128
+ for filename in filenames
129
+ next unless @@file_cache.member?(filename)
130
+ path = @@file_cache[filename].path
131
+ if File.exist?(path)
132
+ cache_info = @@file_cache[filename].stat
133
+ stat = File.stat(path)
134
+ if stat &&
135
+ (cache_info.size != stat.size or cache_info.mtime != stat.mtime)
136
+ result << filename
137
+ update_cache(filename, use_script_lines)
138
+ end
139
+ end
140
+ end
141
+ return result
142
+ end
143
+ module_function :checkcache
144
+
145
+ # Cache filename if it's not already cached.
146
+ # Return the expanded filename for it in the cache
147
+ # or nil if we can't find the file.
148
+ def cache(filename, reload_on_change=false)
149
+ if @@file_cache.member?(filename)
150
+ checkcache(filename) if reload_on_change
151
+ else
152
+ update_cache(filename, true)
153
+ end
154
+ if @@file_cache.member?(filename)
155
+ @@file_cache[filename].path
156
+ else
157
+ nil
158
+ end
159
+ end
160
+ module_function :cache
161
+
162
+ # Return true if filename is cached
163
+ def cached?(filename)
164
+ @@file_cache.member?(unmap_file(filename))
165
+ end
166
+ module_function :cached?
167
+
168
+ def cached_script?(filename)
169
+ # In 1.8.6, the SCRIPT_LINES__ filename key can be unqualified
170
+ # In 1.9.1 it's the fully qualified name
171
+ if RUBY_VERSION < "1.9"
172
+ SCRIPT_LINES__.member?(unmap_file(filename))
173
+ else
174
+ SCRIPT_LINES__.member?(File.expand_path(unmap_file(filename)))
175
+ end
176
+ end
177
+ module_function :cached_script?
178
+
179
+ def empty?(filename)
180
+ filename=unmap_file(filename)
181
+ @@file_cache[filename].lines.empty?
182
+ end
183
+ module_function :empty?
184
+
185
+ # Get line +line_number+ from file named +filename+. Return nil if
186
+ # there was a problem. If a file named filename is not found, the
187
+ # function will look for it in the $: array.
188
+ #
189
+ # Examples:
190
+ #
191
+ # lines = LineCache::getline('/tmp/myfile.rb')
192
+ # # Same as above
193
+ # $: << '/tmp'
194
+ # lines = LineCache.getlines('myfile.rb')
195
+ #
196
+ def getline(filename, line_number, reload_on_change=true)
197
+ filename = unmap_file(filename)
198
+ filename, line_number = unmap_file_line(filename, line_number)
199
+ lines = getlines(filename, reload_on_change)
200
+ if lines and (1..lines.size) === line_number
201
+ return lines[line_number-1]
202
+ else
203
+ return nil
204
+ end
205
+ end
206
+ module_function :getline
207
+
208
+ # Read lines of +filename+ and cache the results. However +filename+ was
209
+ # previously cached use the results from the cache. Return nil
210
+ # if we can't get lines
211
+ def getlines(filename, reload_on_change=false)
212
+ filename = unmap_file(filename)
213
+ checkcache(filename) if reload_on_change
214
+ if @@file_cache.member?(filename)
215
+ return @@file_cache[filename].lines
216
+ else
217
+ update_cache(filename, true)
218
+ return @@file_cache[filename].lines if @@file_cache.member?(filename)
219
+ end
220
+ end
221
+ module_function :getlines
222
+
223
+ # Return full filename path for filename
224
+ def path(filename)
225
+ filename = unmap_file(filename)
226
+ return nil unless @@file_cache.member?(filename)
227
+ @@file_cache[filename].path
228
+ end
229
+ module_function :path
230
+
231
+ def remap_file(from_file, to_file)
232
+ @@file2file_remap[to_file] = from_file
233
+ end
234
+ module_function :remap_file
235
+
236
+ def remap_file_lines(from_file, to_file, range, start)
237
+ range = (range..range) if range.is_a?(Fixnum)
238
+ to_file = from_file unless to_file
239
+ if @@file2file_remap_lines[to_file]
240
+ # FIXME: need to check for overwriting ranges: whether
241
+ # they intersect or one encompasses another.
242
+ @@file2file_remap_lines[to_file] << [from_file, range, start]
243
+ else
244
+ @@file2file_remap_lines[to_file] = [[from_file, range, start]]
245
+ end
246
+ end
247
+ module_function :remap_file_lines
248
+
249
+ # Return SHA1 of filename.
250
+ def sha1(filename)
251
+ filename = unmap_file(filename)
252
+ return nil unless @@file_cache.member?(filename)
253
+ return @@file_cache[filename].sha1.hexdigest if
254
+ @@file_cache[filename].sha1
255
+ sha1 = Digest::SHA1.new
256
+ @@file_cache[filename].lines.each do |line|
257
+ sha1 << line
258
+ end
259
+ @@file_cache[filename].sha1 = sha1
260
+ sha1.hexdigest
261
+ end
262
+ module_function :sha1
263
+
264
+ # Return the number of lines in filename
265
+ def size(filename)
266
+ filename = unmap_file(filename)
267
+ return nil unless @@file_cache.member?(filename)
268
+ @@file_cache[filename].lines.length
269
+ end
270
+ module_function :size
271
+
272
+ # Return File.stat in the cache for filename.
273
+ def stat(filename)
274
+ return nil unless @@file_cache.member?(filename)
275
+ @@file_cache[filename].stat
276
+ end
277
+ module_function :stat
278
+
279
+ # Return an Array of breakpoints in filename.
280
+ # The list will contain an entry for each distinct line event call
281
+ # so it is possible (and possibly useful) for a line number appear more
282
+ # than once.
283
+ def trace_line_numbers(filename, reload_on_change=false)
284
+ fullname = cache(filename, reload_on_change)
285
+ return nil unless fullname
286
+ e = @@file_cache[filename]
287
+ unless e.line_numbers
288
+ e.line_numbers =
289
+ TraceLineNumbers.lnums_for_str_array(e.lines)
290
+ e.line_numbers = false unless e.line_numbers
291
+ end
292
+ e.line_numbers
293
+ end
294
+ module_function :trace_line_numbers
295
+
296
+ def unmap_file(file)
297
+ @@file2file_remap[file] ? @@file2file_remap[file] : file
298
+ end
299
+ module_function :unmap_file
300
+
301
+ def unmap_file_line(file, line)
302
+ if @@file2file_remap_lines[file]
303
+ @@file2file_remap_lines[file].each do |from_file, range, start|
304
+ if range === line
305
+ from_file = from_file || file
306
+ return [from_file, start+line-range.begin]
307
+ end
308
+ end
309
+ end
310
+ return [file, line]
311
+ end
312
+ module_function :unmap_file_line
313
+
314
+ # Update a cache entry. If something's
315
+ # wrong, return nil. Return true if the cache was updated and false
316
+ # if not. If use_script_lines is true, use that as the source for the
317
+ # lines of the file
318
+ def update_cache(filename, use_script_lines=false)
319
+
320
+ return nil unless filename
321
+
322
+ @@file_cache.delete(filename)
323
+ path = File.expand_path(filename)
324
+
325
+ if use_script_lines
326
+ list = [filename]
327
+ list << @@file2file_remap[path] if @@file2file_remap[path]
328
+ list.each do |name|
329
+ if !SCRIPT_LINES__[name].nil? && SCRIPT_LINES__[name] != true
330
+ begin
331
+ stat = File.stat(name)
332
+ rescue
333
+ stat = nil
334
+ end
335
+ lines = SCRIPT_LINES__[name]
336
+ @@file_cache[filename] = LineCacheInfo.new(stat, nil, lines, path, nil)
337
+ @@file2file_remap[path] = filename
338
+ return true
339
+ end
340
+ end
341
+ end
342
+
343
+ if File.exist?(path)
344
+ stat = File.stat(path)
345
+ elsif File.basename(filename) == filename
346
+ # try looking through the search path.
347
+ stat = nil
348
+ for dirname in $:
349
+ path = File.join(dirname, filename)
350
+ if File.exist?(path)
351
+ stat = File.stat(path)
352
+ break
353
+ end
354
+ end
355
+ return false unless stat
356
+ end
357
+ begin
358
+ fp = File.open(path, 'r')
359
+ lines = fp.readlines()
360
+ fp.close()
361
+ rescue
362
+ ## print '*** cannot open', path, ':', msg
363
+ return nil
364
+ end
365
+ @@file_cache[filename] = LineCacheInfo.new(File.stat(path), nil, lines,
366
+ path, nil)
367
+ @@file2file_remap[path] = filename
368
+ return true
369
+ end
370
+
371
+ module_function :update_cache
372
+
373
+ end
374
+
375
+ # example usage
376
+ if __FILE__ == $0
377
+ def yes_no(var)
378
+ return var ? "" : "not "
379
+ end
380
+
381
+ lines = LineCache::getlines(__FILE__)
382
+ puts "#{__FILE__} has #{LineCache.size(__FILE__)} lines"
383
+ line = LineCache::getline(__FILE__, 6)
384
+ puts "The 6th line is\n#{line}"
385
+ line = LineCache::remap_file(__FILE__, 'another_name')
386
+ puts LineCache::getline('another_name', 7)
387
+
388
+ puts("Files cached: #{LineCache::cached_files.inspect}")
389
+ LineCache::update_cache(__FILE__)
390
+ LineCache::checkcache(__FILE__)
391
+ puts "#{__FILE__} has #{LineCache::size(__FILE__)} lines"
392
+ puts "#{__FILE__} trace line numbers:\n" +
393
+ "#{LineCache::trace_line_numbers(__FILE__).to_a.sort.inspect}"
394
+ puts("#{__FILE__} is %scached." %
395
+ yes_no(LineCache::cached?(__FILE__)))
396
+ puts LineCache::stat(__FILE__).inspect
397
+ puts "Full path: #{LineCache::path(__FILE__)}"
398
+ LineCache::checkcache # Check all files in the cache
399
+ LineCache::clear_file_cache
400
+ puts("#{__FILE__} is now %scached." %
401
+ yes_no(LineCache::cached?(__FILE__)))
402
+ digest = SCRIPT_LINES__.select{|k,v| k =~ /digest.rb$/}
403
+ puts digest.first[0] if digest
404
+ line = LineCache::getline(__FILE__, 7)
405
+ puts "The 7th line is\n#{line}"
406
+ LineCache::remap_file_lines(__FILE__, 'test2', (10..20), 6)
407
+ puts LineCache::getline('test2', 10)
408
+ puts "Remapped 10th line of test2 is\n#{line}"
409
+ end
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id$
3
+ begin require 'rubygems' rescue LoadError end
4
+ # require 'ruby-debug' ; Debugger.start(:post-mortem => true)
5
+
6
+ module TraceLineNumbers
7
+ @@SRC_DIR = File.expand_path(File.dirname(__FILE__))
8
+ begin
9
+ require File.join(@@SRC_DIR, '..', 'ext\trace_nums', 'trace_nums19')
10
+ rescue LoadError
11
+ # MSWindows seems to put this in lib rather than ext.
12
+ require File.join(@@SRC_DIR, '..', 'lib', 'trace_nums19')
13
+ end
14
+
15
+ # Return an array of lines numbers that could be
16
+ # stopped at given a file name of a Ruby program.
17
+ def lnums_for_file(file)
18
+ lnums_for_str(File.read(file))
19
+ end
20
+ module_function :lnums_for_file
21
+
22
+ # Return an array of lines numbers that could be
23
+ # stopped at given a file name of a Ruby program.
24
+ # We assume the each line has \n at the end. If not
25
+ # set the newline parameters to \n.
26
+ def lnums_for_str_array(string_array, newline='')
27
+ lnums_for_str(string_array.join(newline))
28
+ end
29
+ module_function :lnums_for_str_array
30
+ end
31
+
32
+ if __FILE__ == $0
33
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
34
+ # test_file = '../test/rcov-bug.rb'
35
+ test_file = '../test/lnum-data/begin1.rb'
36
+ if File.exists?(test_file)
37
+ puts TraceLineNumbers.lnums_for_file(test_file).inspect
38
+ load(test_file, 0) # for later
39
+ end
40
+ puts TraceLineNumbers.lnums_for_file(__FILE__).inspect
41
+ unless SCRIPT_LINES__.empty?
42
+ key = SCRIPT_LINES__.keys.first
43
+ puts key
44
+ puts SCRIPT_LINES__[key]
45
+ puts TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[key]).inspect
46
+ end
47
+ end
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', 'tracelines19.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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ begin require 'rubygems' rescue LoadError end
5
+ require 'parse_tree'
6
+
7
+ ARGV.push "-" if ARGV.empty?
8
+
9
+ parse_tree = ParseTree.new(true)
10
+
11
+ ARGV.each do |file|
12
+ ruby = file == "-" ? $stdin.read : File.read(file)
13
+ pp parse_tree.parse_tree_for_string(ruby, file).first
14
+ end
data/test/rcov-bug.rb ADDED
@@ -0,0 +1,10 @@
1
+ # [3, 10]
2
+ # Some rcov bugs.
3
+ z = "
4
+ Now is the time
5
+ "
6
+
7
+ z =~
8
+ /
9
+ 5
10
+ /ix
data/test/short-file ADDED
@@ -0,0 +1,2 @@
1
+ # This is a small test file.
2
+
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'fileutils'
4
+ require 'tempfile'
5
+ require 'set'
6
+
7
+ # require 'rubygems'
8
+ # require 'ruby-debug'; Debugger.start
9
+
10
+ # Test LineCache module
11
+ class TestLineCache < Test::Unit::TestCase
12
+ @@TEST_DIR = File.expand_path(File.dirname(__FILE__))
13
+ @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib')
14
+ require File.join(@@TOP_SRC_DIR, 'linecache19.rb')
15
+
16
+ def setup
17
+ LineCache::clear_file_cache
18
+ end
19
+
20
+ def test_basic
21
+ fp = File.open(__FILE__, 'r')
22
+ compare_lines = fp.readlines()
23
+ fp.close
24
+
25
+ # Test getlines to read this file.
26
+ lines = LineCache::getlines(__FILE__)
27
+ assert_equal(compare_lines, lines,
28
+ 'We should get exactly the same lines as reading this file.')
29
+
30
+ # Test getline to read this file. The file should now be cached,
31
+ # so internally a different set of routines are used.
32
+ test_line = 1
33
+ line = LineCache::getline(__FILE__, test_line)
34
+ assert_equal(compare_lines[test_line-1], line,
35
+ 'We should get exactly the same line as reading this file.')
36
+
37
+ # Test getting the line via a relative file name
38
+ Dir.chdir(File.dirname(__FILE__)) do
39
+ short_file = File.basename(__FILE__)
40
+ test_line = 10
41
+ line = LineCache::getline(short_file, test_line)
42
+ assert_equal(compare_lines[test_line-1], line,
43
+ 'Short filename lookup should work')
44
+ end
45
+
46
+ # Write a temporary file; read contents, rewrite it and check that
47
+ # we get a change when calling getline.
48
+ tf = Tempfile.new("testing")
49
+ test_string = "Now is the time.\n"
50
+ tf.puts(test_string)
51
+ tf.close
52
+ line = LineCache::getline(tf.path, 1)
53
+ assert_equal(test_string, line,
54
+ "C'mon - a simple line test like this worked before.")
55
+ tf.open
56
+ test_string = "Now is another time.\n"
57
+ tf.puts(test_string)
58
+ tf.close
59
+ LineCache::checkcache
60
+ line = LineCache::getline(tf.path, 1)
61
+ assert_equal(test_string, line,
62
+ "checkcache should have reread the temporary file.")
63
+ FileUtils.rm tf.path
64
+
65
+ LineCache::update_cache(__FILE__)
66
+ LineCache::clear_file_cache
67
+ end
68
+
69
+ def test_cached
70
+ assert_equal(false, LineCache::cached?(__FILE__),
71
+ "file #{__FILE__} shouldn't be cached - just cleared cache.")
72
+ line = LineCache::getline(__FILE__, 1)
73
+ assert line
74
+ assert_equal(true, LineCache::cached?(__FILE__),
75
+ "file #{__FILE__} should now be cached")
76
+ assert_equal(false, LineCache::cached_script?('./short-file'),
77
+ "Should not find './short-file' in SCRIPT_LINES__")
78
+ assert_equal(true, 78 < LineCache.size(__FILE__))
79
+ Dir.chdir(File.dirname(__FILE__)) do
80
+ load('./short-file', 0)
81
+ assert_equal(true, LineCache::cached_script?('./short-file'),
82
+ "Should be able to find './short-file' in SCRIPT_LINES__")
83
+ end
84
+ end
85
+
86
+ def test_remap
87
+ LineCache::remap_file(__FILE__, 'another-name')
88
+ line1 = LineCache::getline('another-name', 1)
89
+ line2 = LineCache::getline(__FILE__, 1)
90
+ assert_equal(line1, line2, 'Both lines should be the same via remap_file')
91
+ end
92
+
93
+ def test_remap_lines
94
+ LineCache::remap_file_lines(__FILE__, 'test2', (10..11), 6)
95
+
96
+ line5 = LineCache::getline(__FILE__, 5)
97
+ LineCache::remap_file_lines(__FILE__, 'test2', 9, 5)
98
+ rline9 = LineCache::getline('test2', 9)
99
+ assert_equal(line5, rline9,
100
+ 'lines should be the same via remap_file_line - remap integer')
101
+
102
+ line6 = LineCache::getline(__FILE__, 6)
103
+ rline10 = LineCache::getline('test2', 10)
104
+ assert_equal(line6, rline10,
105
+ 'lines should be the same via remap_file_line - range')
106
+
107
+ line7 = LineCache::getline(__FILE__, 7)
108
+ rline11 = LineCache::getline('test2', 11)
109
+ assert_equal(line7, rline11,
110
+ 'lines should be the same via remap_file_line - range')
111
+
112
+ line8 = LineCache::getline(__FILE__, 8)
113
+ LineCache::remap_file_lines(__FILE__, nil, 20, 8)
114
+ rline20 = LineCache::getline(__FILE__, 20)
115
+ assert_equal(line8, rline20,
116
+ 'lines should be the same via remap_file_line - nil file')
117
+ end
118
+
119
+ def test_stat
120
+ assert_equal(nil, LineCache::stat(__FILE__),
121
+ "stat for #{__FILE__} shouldn't be nil - just cleared cache.")
122
+ line = LineCache::getline(__FILE__, 1)
123
+ assert line
124
+ assert(LineCache::stat(__FILE__),
125
+ "file #{__FILE__} should now have a stat")
126
+ end
127
+
128
+ def test_path
129
+ assert_equal(nil, LineCache::path(__FILE__),
130
+ "path for #{__FILE__} should be nil - just cleared cache.")
131
+ path = LineCache::cache(__FILE__)
132
+ assert path
133
+ assert_equal(path, LineCache::path(__FILE__),
134
+ "path of #{__FILE__} should be the same as we got before")
135
+ end
136
+
137
+ def test_trace_line_numbers
138
+ test_file = File.join(@@TEST_DIR, 'short-file')
139
+ assert_equal([], LineCache::trace_line_numbers(test_file))
140
+ test_file = File.join(@@TEST_DIR, 'rcov-bug.rb')
141
+ assert_equal([3, 10], LineCache::trace_line_numbers(test_file))
142
+ end
143
+
144
+ def test_sha1
145
+ test_file = File.join(@@TEST_DIR, 'short-file')
146
+ LineCache::cache(test_file)
147
+ assert_equal('1134f95ea84a3dcc67d7d1bf41390ee1a03af6d2',
148
+ LineCache::sha1(test_file))
149
+ end
150
+
151
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id$
3
+ require 'test/unit'
4
+ require 'fileutils'
5
+ require 'tempfile'
6
+
7
+ # require 'rubygems'
8
+ # require 'ruby-debug'; Debugger.init
9
+
10
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
11
+ # Test TestLineNumbers module
12
+ class TestLineNumbers1 < Test::Unit::TestCase
13
+
14
+ @@TEST_DIR = File.expand_path(File.dirname(__FILE__))
15
+ @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib')
16
+ require File.join(@@TOP_SRC_DIR, 'tracelines19.rb')
17
+
18
+ @@rcov_file = File.join(@@TEST_DIR, 'rcov-bug.rb')
19
+ File.open(@@rcov_file, 'r') {|fp|
20
+ first_line = fp.readline[1..-2]
21
+ @@rcov_lnums = eval(first_line, binding, __FILE__, __LINE__)
22
+ }
23
+
24
+ def test_for_file
25
+ rcov_lines = TraceLineNumbers.lnums_for_file(@@rcov_file)
26
+ assert_equal(@@rcov_lnums, rcov_lines)
27
+ end
28
+
29
+ def test_for_string
30
+ string = "# Some rcov bugs.\nz = \"\nNow is the time\n\"\n\nz =~ \n /\n 5\n /ix\n"
31
+ rcov_lines = TraceLineNumbers.lnums_for_str(string)
32
+ assert_equal([2, 9], rcov_lines)
33
+ end
34
+
35
+ def test_for_string_array
36
+ load(@@rcov_file, 0)
37
+ rcov_lines =
38
+ TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[@@rcov_file])
39
+ assert_equal(@@rcov_lnums, rcov_lines)
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linecache19-patched
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.13
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Do Not Use
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-11-13 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Do not use
15
+ email: noreply@noemail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README
21
+ - lib/linecache19.rb
22
+ - lib/tracelines19.rb
23
+ - test/lnum-diag.rb
24
+ - test/parse-show.rb
25
+ - test/rcov-bug.rb
26
+ - test/short-file
27
+ - test/test-linecache.rb
28
+ - test/test-tracelines.rb
29
+ homepage: http://github.com/robmathews/linecache19-0.5.13
30
+ licenses: []
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.9.3
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.23.2
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: Do no use
53
+ test_files: []