rb8-trepanning 0.1.3-universal-ruby-1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGES +34 -0
- data/ChangeLog +875 -0
- data/README.textile +59 -0
- data/Rakefile +215 -0
- data/app/.gitignore +1 -0
- data/app/cmd_parse.kpeg +241 -0
- data/app/cmd_parse.rb +212 -0
- data/app/cmd_parser.rb +1948 -0
- data/app/complete.rb +79 -0
- data/app/default.rb +90 -0
- data/app/display.rb +148 -0
- data/app/eventbuffer.rb +147 -0
- data/app/frame.rb +166 -0
- data/app/irb.rb +114 -0
- data/app/options.rb +200 -0
- data/app/run.rb +74 -0
- data/app/util.rb +65 -0
- data/bin/.gitignore +1 -0
- data/bin/trepan8 +115 -0
- data/data/.gitignore +1 -0
- data/data/irbrc +41 -0
- data/interface/.gitignore +1 -0
- data/interface/base_intf.rb +109 -0
- data/interface/client.rb +82 -0
- data/interface/comcodes.rb +20 -0
- data/interface/script.rb +110 -0
- data/interface/server.rb +147 -0
- data/interface/user.rb +165 -0
- data/io/base_io.rb +148 -0
- data/io/input.rb +158 -0
- data/io/null_output.rb +46 -0
- data/io/string_array.rb +156 -0
- data/io/tcpclient.rb +129 -0
- data/io/tcpfns.rb +33 -0
- data/io/tcpserver.rb +141 -0
- data/lib/debugger.rb +8 -0
- data/lib/trepanning.rb +283 -0
- data/processor/.gitignore +1 -0
- data/processor/command-ruby-debug/breakpoints.rb +155 -0
- data/processor/command-ruby-debug/catchpoint.rb +55 -0
- data/processor/command-ruby-debug/condition.rb +49 -0
- data/processor/command-ruby-debug/control.rb +31 -0
- data/processor/command-ruby-debug/display.rb +120 -0
- data/processor/command-ruby-debug/enable.rb +202 -0
- data/processor/command-ruby-debug/frame.rb +199 -0
- data/processor/command-ruby-debug/help.rb +63 -0
- data/processor/command-ruby-debug/info.rb +359 -0
- data/processor/command-ruby-debug/method.rb +84 -0
- data/processor/command-ruby-debug/reload.rb +40 -0
- data/processor/command-ruby-debug/save.rb +90 -0
- data/processor/command-ruby-debug/set.rb +237 -0
- data/processor/command-ruby-debug/show.rb +251 -0
- data/processor/command-ruby-debug/source.rb +36 -0
- data/processor/command-ruby-debug/threads.rb +189 -0
- data/processor/command-ruby-debug/trace.rb +57 -0
- data/processor/command-ruby-debug/variables.rb +199 -0
- data/processor/command.rb +270 -0
- data/processor/command/.gitignore +1 -0
- data/processor/command/alias.rb +54 -0
- data/processor/command/backtrace.rb +123 -0
- data/processor/command/base/cmd.rb +177 -0
- data/processor/command/base/subcmd.rb +230 -0
- data/processor/command/base/submgr.rb +188 -0
- data/processor/command/base/subsubcmd.rb +128 -0
- data/processor/command/base/subsubmgr.rb +199 -0
- data/processor/command/break.rb +114 -0
- data/processor/command/catch.rb +71 -0
- data/processor/command/complete.rb +39 -0
- data/processor/command/continue.rb +57 -0
- data/processor/command/directory.rb +50 -0
- data/processor/command/disable.rb +85 -0
- data/processor/command/display.rb +78 -0
- data/processor/command/down.rb +54 -0
- data/processor/command/edit.rb +79 -0
- data/processor/command/enable.rb +48 -0
- data/processor/command/eval.rb +90 -0
- data/processor/command/exit.rb +66 -0
- data/processor/command/finish.rb +59 -0
- data/processor/command/frame.rb +97 -0
- data/processor/command/help.rb +230 -0
- data/processor/command/help/.gitignore +1 -0
- data/processor/command/help/README +10 -0
- data/processor/command/help/command.txt +58 -0
- data/processor/command/help/examples.txt +16 -0
- data/processor/command/help/filename.txt +40 -0
- data/processor/command/help/location.txt +37 -0
- data/processor/command/help/suffixes.txt +17 -0
- data/processor/command/info.rb +28 -0
- data/processor/command/info_subcmd/.gitignore +1 -0
- data/processor/command/info_subcmd/args.rb +39 -0
- data/processor/command/info_subcmd/breakpoints.rb +80 -0
- data/processor/command/info_subcmd/catch.rb +36 -0
- data/processor/command/info_subcmd/files.rb +39 -0
- data/processor/command/info_subcmd/globals.rb +64 -0
- data/processor/command/info_subcmd/line.rb +30 -0
- data/processor/command/info_subcmd/locals.rb +69 -0
- data/processor/command/info_subcmd/macro.rb +62 -0
- data/processor/command/info_subcmd/program.rb +51 -0
- data/processor/command/info_subcmd/ruby.rb +57 -0
- data/processor/command/info_subcmd/source.rb +74 -0
- data/processor/command/info_subcmd/stack.rb +25 -0
- data/processor/command/info_subcmd/threads.rb +75 -0
- data/processor/command/kill.rb +78 -0
- data/processor/command/list.rb +117 -0
- data/processor/command/macro.rb +68 -0
- data/processor/command/next.rb +79 -0
- data/processor/command/parsetree.rb +56 -0
- data/processor/command/pp.rb +40 -0
- data/processor/command/pr.rb +37 -0
- data/processor/command/ps.rb +40 -0
- data/processor/command/restart.rb +86 -0
- data/processor/command/save.rb +58 -0
- data/processor/command/set.rb +47 -0
- data/processor/command/set_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/abbrev.rb +25 -0
- data/processor/command/set_subcmd/auto.rb +27 -0
- data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
- data/processor/command/set_subcmd/auto_subcmd/eval.rb +53 -0
- data/processor/command/set_subcmd/auto_subcmd/irb.rb +33 -0
- data/processor/command/set_subcmd/auto_subcmd/list.rb +33 -0
- data/processor/command/set_subcmd/basename.rb +25 -0
- data/processor/command/set_subcmd/callstyle.rb +46 -0
- data/processor/command/set_subcmd/confirm.rb +24 -0
- data/processor/command/set_subcmd/debug.rb +47 -0
- data/processor/command/set_subcmd/different.rb +61 -0
- data/processor/command/set_subcmd/highlight.rb +43 -0
- data/processor/command/set_subcmd/max.rb +26 -0
- data/processor/command/set_subcmd/max_subcmd/list.rb +49 -0
- data/processor/command/set_subcmd/max_subcmd/stack.rb +50 -0
- data/processor/command/set_subcmd/max_subcmd/string.rb +76 -0
- data/processor/command/set_subcmd/max_subcmd/width.rb +49 -0
- data/processor/command/set_subcmd/reload.rb +42 -0
- data/processor/command/set_subcmd/timer.rb +58 -0
- data/processor/command/set_subcmd/trace.rb +37 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +42 -0
- data/processor/command/set_subcmd/trace_subcmd/print.rb +41 -0
- data/processor/command/shell.rb +139 -0
- data/processor/command/show.rb +39 -0
- data/processor/command/show_subcmd/.gitignore +1 -0
- data/processor/command/show_subcmd/abbrev.rb +20 -0
- data/processor/command/show_subcmd/alias.rb +46 -0
- data/processor/command/show_subcmd/args.rb +34 -0
- data/processor/command/show_subcmd/auto.rb +28 -0
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +27 -0
- data/processor/command/show_subcmd/auto_subcmd/irb.rb +23 -0
- data/processor/command/show_subcmd/auto_subcmd/list.rb +22 -0
- data/processor/command/show_subcmd/basename.rb +20 -0
- data/processor/command/show_subcmd/callstyle.rb +22 -0
- data/processor/command/show_subcmd/confirm.rb +18 -0
- data/processor/command/show_subcmd/debug.rb +26 -0
- data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +21 -0
- data/processor/command/show_subcmd/debug_subcmd/skip.rb +22 -0
- data/processor/command/show_subcmd/debug_subcmd/step.rb +22 -0
- data/processor/command/show_subcmd/different.rb +26 -0
- data/processor/command/show_subcmd/directories.rb +22 -0
- data/processor/command/show_subcmd/highlight.rb +24 -0
- data/processor/command/show_subcmd/max.rb +27 -0
- data/processor/command/show_subcmd/max_subcmd/list.rb +38 -0
- data/processor/command/show_subcmd/max_subcmd/stack.rb +36 -0
- data/processor/command/show_subcmd/max_subcmd/string.rb +42 -0
- data/processor/command/show_subcmd/max_subcmd/width.rb +37 -0
- data/processor/command/show_subcmd/reload.rb +18 -0
- data/processor/command/show_subcmd/timer.rb +18 -0
- data/processor/command/show_subcmd/trace.rb +29 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +65 -0
- data/processor/command/show_subcmd/trace_subcmd/print.rb +23 -0
- data/processor/command/show_subcmd/version.rb +23 -0
- data/processor/command/source.rb +134 -0
- data/processor/command/step.rb +81 -0
- data/processor/command/tbreak.rb +19 -0
- data/processor/command/unalias.rb +44 -0
- data/processor/command/undisplay.rb +59 -0
- data/processor/command/up.rb +72 -0
- data/processor/default.rb +56 -0
- data/processor/display.rb +17 -0
- data/processor/eval.rb +113 -0
- data/processor/eventbuf.rb +105 -0
- data/processor/frame.rb +172 -0
- data/processor/help.rb +92 -0
- data/processor/helper.rb +76 -0
- data/processor/hook.rb +134 -0
- data/processor/load_cmds.rb +258 -0
- data/processor/location.rb +174 -0
- data/processor/main.rb +455 -0
- data/processor/mock.rb +136 -0
- data/processor/msg.rb +61 -0
- data/processor/processor.rb +674 -0
- data/processor/running.rb +168 -0
- data/processor/stepping.rb +18 -0
- data/processor/subcmd.rb +161 -0
- data/processor/validate.rb +355 -0
- data/processor/virtual.rb +34 -0
- data/test/data/.gitignore +1 -0
- data/test/data/break_bad.cmd +19 -0
- data/test/data/break_bad.right +29 -0
- data/test/data/break_loop_bug.cmd +5 -0
- data/test/data/break_loop_bug.right +15 -0
- data/test/data/dollar-0.right +2 -0
- data/test/data/dollar-0a.right +2 -0
- data/test/data/dollar-0b.right +2 -0
- data/test/data/edit.cmd +14 -0
- data/test/data/edit.right +24 -0
- data/test/data/file-with-space.cmd +6 -0
- data/test/data/file-with-space.right +4 -0
- data/test/data/printvar.cmd +17 -0
- data/test/data/printvar.right +31 -0
- data/test/data/raise.cmd +11 -0
- data/test/data/raise.right +19 -0
- data/test/data/source.cmd +5 -0
- data/test/data/source.right +18 -0
- data/test/data/stepping-1.9.right +50 -0
- data/test/data/stepping.cmd +21 -0
- data/test/data/stepping.right +48 -0
- data/test/data/trepan8-save.1 +6 -0
- data/test/example/bp_loop_issue.rb +3 -0
- data/test/example/break-bug.rb +7 -0
- data/test/example/brkpt-class-bug.rb +8 -0
- data/test/example/classes.rb +11 -0
- data/test/example/dollar-0.rb +5 -0
- data/test/example/except-bug1.rb +4 -0
- data/test/example/except-bug2.rb +7 -0
- data/test/example/file with space.rb +1 -0
- data/test/example/gcd.rb +18 -0
- data/test/example/info-var-bug.rb +47 -0
- data/test/example/info-var-bug2.rb +2 -0
- data/test/example/null.rb +1 -0
- data/test/example/pm-bug.rb +3 -0
- data/test/example/pm.rb +11 -0
- data/test/example/raise.rb +3 -0
- data/test/integration/.gitignore +4 -0
- data/test/integration/config.yaml +8 -0
- data/test/integration/helper.rb +154 -0
- data/test/integration/test-break_bad.rb +26 -0
- data/test/integration/test-dollar-0.rb +31 -0
- data/test/integration/test-edit.rb +17 -0
- data/test/integration/test-file-with-space.rb +26 -0
- data/test/integration/test-printvar.rb +17 -0
- data/test/integration/test-raise.rb +21 -0
- data/test/integration/test-source.rb +16 -0
- data/test/integration/test-stepping.rb +24 -0
- data/test/unit/.gitignore +1 -0
- data/test/unit/cmd-helper.rb +52 -0
- data/test/unit/mock-helper.rb +12 -0
- data/test/unit/test-app-cmd_parse.rb +97 -0
- data/test/unit/test-app-cmd_parser.rb +23 -0
- data/test/unit/test-app-complete.rb +39 -0
- data/test/unit/test-app-frame.rb +32 -0
- data/test/unit/test-app-options.rb +92 -0
- data/test/unit/test-app-run.rb +14 -0
- data/test/unit/test-app-util.rb +44 -0
- data/test/unit/test-base-cmd.rb +45 -0
- data/test/unit/test-base-subcmd.rb +57 -0
- data/test/unit/test-base-submgr.rb +23 -0
- data/test/unit/test-base-subsubcmd.rb +17 -0
- data/test/unit/test-cmd-alias.rb +48 -0
- data/test/unit/test-cmd-exit.rb +27 -0
- data/test/unit/test-cmd-help.rb +104 -0
- data/test/unit/test-cmd-kill.rb +46 -0
- data/test/unit/test-cmd-source.rb +34 -0
- data/test/unit/test-completion.rb +42 -0
- data/test/unit/test-intf-user.rb +46 -0
- data/test/unit/test-io-input.rb +27 -0
- data/test/unit/test-io-tcp.rb +33 -0
- data/test/unit/test-io-tcpclient.rb +54 -0
- data/test/unit/test-io-tcpfns.rb +17 -0
- data/test/unit/test-io-tcpserver.rb +50 -0
- data/test/unit/test-proc-eval.rb +36 -0
- data/test/unit/test-proc-hook.rb +30 -0
- data/test/unit/test-proc-load_cmds.rb +50 -0
- data/test/unit/test-proc-location.rb +79 -0
- data/test/unit/test-subcmd-help.rb +44 -0
- data/trepan8.gemspec +58 -0
- metadata +388 -0
data/README.textile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
h1. rb8-trepanning a Ruby MRI 1.8 and 1.9 debugger using _ruby-debug-base_.
|
2
|
+
|
3
|
+
This is a rewrite of _ruby-debug_, but still using _ruby-debug base_.
|
4
|
+
|
5
|
+
Right now, I've mostly tested on MRI 1.8, it sort of works on MRI 1.9.2 Ruby. Since the code is pure Ruby, it probably will work on other Rubies that have _ruby-debug-base_ installed to some degree.
|
6
|
+
|
7
|
+
h2. Features
|
8
|
+
|
9
|
+
* Syntax highlighting (if "coderay":http://coderay.rubychan.de/ and term-ansicolor are installed)
|
10
|
+
* tab completion of commands
|
11
|
+
* expanded on-line help
|
12
|
+
* easy evaluation of the statement or expression in a statement about to be run (eval and eval? with no arguments)
|
13
|
+
* cleaner, more modular and more testable code
|
14
|
+
|
15
|
+
I realize the last item may not be of importance to many, but it's _very_ important as a developer of the code.
|
16
|
+
|
17
|
+
There is a "google group mailing list":http://groups.google.com/group/ruby-debugger for Ruby debuggers.
|
18
|
+
|
19
|
+
h2. Installing (from git)
|
20
|
+
|
21
|
+
bq. $ git://github.com/rocky/rb8-trepanning.git
|
22
|
+
$ cd rb8-trepanning
|
23
|
+
$ rake test
|
24
|
+
$ rake install
|
25
|
+
|
26
|
+
h2. Background
|
27
|
+
|
28
|
+
_ruby-debug_ is cool, but it became getting harder to work on and to extend it while keeping compatibility. The code never started out from a test-driven development standpoint--tests were bolted on afterwards.
|
29
|
+
|
30
|
+
Over time, I gained a better understanding of what was important (to me), and I learned how to do things better. So I decided to rewrite
|
31
|
+
the code. This code base is a backport of the "trepanning debugger for
|
32
|
+
Rubinius":https://github.com/rocky/rbx-trepanning/wiki which in turn
|
33
|
+
is a port of the "trepanning debugger for a patched MRI YARV
|
34
|
+
1.9.2":https://github.com/rocky/rb-trepanning/wiki which is a port of "a debugger for Python":http://code.google.com/p/pydbgr/ which is a port of ruby-debug)
|
35
|
+
|
36
|
+
h2. Compatibility with ruby-debug
|
37
|
+
|
38
|
+
Compatiblity between _ruby-debug_ and _trepanning_ is like compatibility between Ruby 1.8 and Ruby 1.9.
|
39
|
+
|
40
|
+
Here are some incompatibilities. Depending on your point of view, I hope you will find as I do that these are improvements:
|
41
|
+
|
42
|
+
* "set autoeval" is on by default
|
43
|
+
* ";;" rather than ";" separates debugger commands. This way, ";" can be used in a Ruby statement to evaluate.
|
44
|
+
* Command names can be abbreviated if they are unique. For example "st" and "ste" are abbreviations of "step". To turn this off, "set abbrev off".
|
45
|
+
|
46
|
+
|
47
|
+
h2. Dependencies
|
48
|
+
|
49
|
+
The debugger needs to work in more limited environments, so there are a number packages which are _optional_ but not required. They are:
|
50
|
+
|
51
|
+
* _coderay_ and _term-ansicolor_ for syntax and terminal highlighting
|
52
|
+
* _rb-readline_ (>= 0.4.0) on MRI 1.8 for better tab completion.
|
53
|
+
* _ParseTree_ (>= 3.0.7) and its dependencies for showing method S-expressions
|
54
|
+
* _linecache_ (>= 0.45dev) for syntax highlighting
|
55
|
+
|
56
|
+
Required dependencies are the same as ruby-debug:
|
57
|
+
* _ruby-debug-base_ -- for run-time debugging support
|
58
|
+
* _linecache_ or _linecache19_ -- for caching source-code lines and figuring out breakpoint lines)
|
59
|
+
* _columnize_ -- for showing commands in columns
|
data/Rakefile
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# -*- Ruby -*-
|
3
|
+
require 'rubygems'; require 'require_relative'
|
4
|
+
|
5
|
+
ROOT_DIR = File.dirname(__FILE__)
|
6
|
+
Gemspec_filename='trepan8.gemspec'
|
7
|
+
require_relative './app/options'
|
8
|
+
|
9
|
+
def gemspec
|
10
|
+
@gemspec ||= eval(File.read(Gemspec_filename), binding, Gemspec_filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake/gempackagetask'
|
14
|
+
desc 'Build the gem'
|
15
|
+
task :package=>:gem
|
16
|
+
task :gem=>:gemspec do
|
17
|
+
Dir.chdir(ROOT_DIR) do
|
18
|
+
sh "gem build #{Gemspec_filename}"
|
19
|
+
FileUtils.mkdir_p 'pkg'
|
20
|
+
FileUtils.mv gemspec.file_name, 'pkg'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Install the gem locally'
|
25
|
+
task :install => :gem do
|
26
|
+
Dir.chdir(ROOT_DIR) do
|
27
|
+
sh %{gem install --local pkg/#{gemspec.file_name}}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'rake/testtask'
|
32
|
+
require 'rbconfig'
|
33
|
+
|
34
|
+
def RbConfig.ruby
|
35
|
+
File.join(RbConfig::CONFIG['bindir'],
|
36
|
+
RbConfig::CONFIG['RUBY_INSTALL_NAME'] +
|
37
|
+
RbConfig::CONFIG['EXEEXT'])
|
38
|
+
end unless defined? RbConfig.ruby
|
39
|
+
|
40
|
+
def run_standalone_ruby_files(list, opts={})
|
41
|
+
puts '*' * 40
|
42
|
+
list.each do |ruby_file|
|
43
|
+
system(RbConfig.ruby, ruby_file)
|
44
|
+
p $?.exitstatus
|
45
|
+
break if $?.exitstatus != 0 && !opts[:continue]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_standalone_ruby_file(directory, opts={})
|
50
|
+
puts(('*' * 10) + ' ' + directory + ' ' + ('*' * 10))
|
51
|
+
Dir.chdir(directory) do
|
52
|
+
Dir.glob('*.rb').each do |ruby_file|
|
53
|
+
puts(('-' * 20) + ' ' + ruby_file + ' ' + ('-' * 20))
|
54
|
+
system(RbConfig.ruby, ruby_file)
|
55
|
+
break if $?.exitstatus != 0 && !opts[:continue]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
desc 'Create a GNU-style ChangeLog via git2cl'
|
61
|
+
task :ChangeLog do
|
62
|
+
system('git log --pretty --numstat --summary | git2cl > ChangeLog')
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'Test units - the smaller tests'
|
66
|
+
Rake::TestTask.new(:'test:unit') do |t|
|
67
|
+
t.test_files = FileList['test/unit/**/test-*.rb']
|
68
|
+
# t.pattern = 'test/**/*test-*.rb' # instead of above
|
69
|
+
t.options = '--verbose' if $VERBOSE
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Test functional - the medium-sized tests'
|
73
|
+
Rake::TestTask.new(:'test:functional') do |t|
|
74
|
+
t.test_files = FileList['test/functional/**/test-*.rb']
|
75
|
+
t.options = '--verbose' if $VERBOSE
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'Test integration - end-to-end blackbox tests'
|
79
|
+
Rake::TestTask.new(:'test:integration') do |t|
|
80
|
+
t.test_files = FileList['test/integration/**/test-*.rb']
|
81
|
+
t.options = '--verbose' if $VERBOSE
|
82
|
+
end
|
83
|
+
|
84
|
+
desc 'Test everything - unit tests for now.'
|
85
|
+
task :test do
|
86
|
+
exceptions = %w(test:unit test:integration).collect do |task|
|
87
|
+
begin
|
88
|
+
Rake::Task[task].invoke
|
89
|
+
nil
|
90
|
+
rescue => e
|
91
|
+
e
|
92
|
+
end
|
93
|
+
end.compact
|
94
|
+
|
95
|
+
exceptions.each {|e| puts e;puts e.backtrace }
|
96
|
+
raise 'Test failures' unless exceptions.empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
desc 'Run each Ruby app file in standalone mode.'
|
100
|
+
task :'check:app' do
|
101
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} app)))
|
102
|
+
end
|
103
|
+
|
104
|
+
desc 'Run each command in standalone mode.'
|
105
|
+
task :'check:commands' do
|
106
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} processor command)))
|
107
|
+
end
|
108
|
+
|
109
|
+
desc 'Run each of the sub-sub commands in standalone mode.'
|
110
|
+
task :'check:sub:commands' do
|
111
|
+
p "#{ROOT_DIR}/processor/command/*_subcmd/*_subcmd/*.rb"
|
112
|
+
Dir.glob("#{ROOT_DIR}/processor/command/*_subcmd").each do |sub_dir|
|
113
|
+
run_standalone_ruby_file(sub_dir)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
desc 'Run each of the sub-sub commands in standalone mode.'
|
118
|
+
task :'check:subsub:commands' do
|
119
|
+
subsub_files = FileList["#{ROOT_DIR}/processor/command/*_subcmd/*_subcmd/*.rb"]
|
120
|
+
run_standalone_ruby_files(subsub_files)
|
121
|
+
end
|
122
|
+
|
123
|
+
desc 'Run each processor Ruby file in standalone mode.'
|
124
|
+
task :'check:lib' do
|
125
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} lib)))
|
126
|
+
end
|
127
|
+
|
128
|
+
desc 'Run each processor Ruby file in standalone mode.'
|
129
|
+
task :'check:processor' do
|
130
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} processor)))
|
131
|
+
end
|
132
|
+
|
133
|
+
desc 'Run each processor Ruby file in standalone mode.'
|
134
|
+
task :'check:unit' do
|
135
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test unit)))
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Run functional tests in standalone mode.'
|
139
|
+
task :'check:functional' do
|
140
|
+
run_standalone_ruby_file(File.join(%W(#{ROOT_DIR} test functional)))
|
141
|
+
end
|
142
|
+
|
143
|
+
desc 'Run command parser grammar.'
|
144
|
+
task :'check:cmd_parse' do
|
145
|
+
sh "kpeg --test --debug #{File.join(ROOT_DIR, %w(app cmd_parse.kpeg))}"
|
146
|
+
end
|
147
|
+
|
148
|
+
desc 'Generate command parser.'
|
149
|
+
task :'cmd_parse' do
|
150
|
+
require 'tmpdir'
|
151
|
+
temp_file =
|
152
|
+
File.join(Dir.tmpdir,
|
153
|
+
Dir::Tmpname.make_tmpname(['cmd_parser_', '.rb'], nil))
|
154
|
+
|
155
|
+
sh('kpeg --name CmdParse --verbose --stand-alone ' +
|
156
|
+
"#{File.join(ROOT_DIR, %w(app cmd_parse.kpeg))} " +
|
157
|
+
"--output #{temp_file}")
|
158
|
+
end
|
159
|
+
|
160
|
+
task :'check:integration' do
|
161
|
+
run_standalone_ruby_files(FileList['test/integration/**/test-*.rb'])
|
162
|
+
end
|
163
|
+
|
164
|
+
task :check => %w(check:lib check:processor check:commands).map{|c| c.to_sym}
|
165
|
+
|
166
|
+
desc "Default action is same as 'test'."
|
167
|
+
task :default => :test
|
168
|
+
|
169
|
+
desc 'Generate the gemspec'
|
170
|
+
task :generate do
|
171
|
+
puts gemspec.to_ruby
|
172
|
+
end
|
173
|
+
|
174
|
+
desc 'Validate the gemspec'
|
175
|
+
task :gemspec do
|
176
|
+
gemspec.validate
|
177
|
+
end
|
178
|
+
|
179
|
+
# --------- RDoc Documentation ------
|
180
|
+
require 'rake/rdoctask'
|
181
|
+
desc 'Generate rdoc documentation'
|
182
|
+
Rake::RDocTask.new('rdoc') do |rdoc|
|
183
|
+
rdoc.rdoc_dir = 'doc'
|
184
|
+
rdoc.title = "Trepanning #{Trepan::VERSION} Documentation"
|
185
|
+
|
186
|
+
rdoc.rdoc_files.include(%w(lib/*.rb
|
187
|
+
app/*.rb intf/*.rb io/*.rb
|
188
|
+
bin/trepan8
|
189
|
+
))
|
190
|
+
end
|
191
|
+
|
192
|
+
desc 'Same as rdoc'
|
193
|
+
task :doc => :rdoc
|
194
|
+
|
195
|
+
task :clobber_package do
|
196
|
+
FileUtils.rm_rf File.join(ROOT_DIR, 'pkg')
|
197
|
+
end
|
198
|
+
|
199
|
+
task :clobber_rdoc do
|
200
|
+
FileUtils.rm_rf File.join(ROOT_DIR, 'doc')
|
201
|
+
end
|
202
|
+
|
203
|
+
desc 'Remove residue from running patch'
|
204
|
+
task :rm_patch_residue do
|
205
|
+
FileUtils.rm_rf FileList['**/*.{rej,orig}'].to_a, :verbose => true
|
206
|
+
end
|
207
|
+
|
208
|
+
desc 'Remove ~ backup files'
|
209
|
+
task :rm_tilde_backups do
|
210
|
+
FileUtils.rm_rf Dir.glob('**/*~'), :verbose => true
|
211
|
+
FileUtils.rm_rf Dir.glob('**/*.rbc'), :verbose => true
|
212
|
+
end
|
213
|
+
|
214
|
+
desc 'Remove built files'
|
215
|
+
task :clean => [:clobber_package, :clobber_rdoc, :rm_patch_residue, :rm_tilde_backups]
|
data/app/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/*~
|
data/app/cmd_parse.kpeg
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
# -*- Ruby -*-
|
2
|
+
|
3
|
+
%% {
|
4
|
+
#####################################################
|
5
|
+
# Structure to hold composite method names
|
6
|
+
SymbolEntry = Struct.new(:type, :name, :chain)
|
7
|
+
|
8
|
+
|
9
|
+
# Structure to hold position information
|
10
|
+
Position = Struct.new(:container_type, :container,
|
11
|
+
:position_type, :position)
|
12
|
+
|
13
|
+
# Structure to hold breakpoint information
|
14
|
+
Breakpoint = Struct.new(:position, :negate, :condition)
|
15
|
+
|
16
|
+
# Structure to hold list information
|
17
|
+
List = Struct.new(:position, :num)
|
18
|
+
|
19
|
+
DEFAULT_OPTS = {
|
20
|
+
:debug=>false,
|
21
|
+
:file_exists_proc => Proc.new{|filename|
|
22
|
+
File.readable?(filename) && !File.directory?(filename)
|
23
|
+
}
|
24
|
+
}
|
25
|
+
def initialize(str, opts={})
|
26
|
+
@opts = DEFAULT_OPTS.merge(opts)
|
27
|
+
setup_parser(str, opts[:debug])
|
28
|
+
@file_exists_proc = @opts[:file_exists_proc]
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
}
|
33
|
+
#####################################################
|
34
|
+
|
35
|
+
upcase_letter = /[A-Z]/
|
36
|
+
downcase_letter = /[a-z]/
|
37
|
+
suffix_letter = /[=!?]/
|
38
|
+
letter = upcase_letter
|
39
|
+
| downcase_letter
|
40
|
+
id_symbol = letter | "_" | [0-9]
|
41
|
+
|
42
|
+
|
43
|
+
# An variable or a method identifier
|
44
|
+
# Examples:
|
45
|
+
# var1
|
46
|
+
# my_var?
|
47
|
+
# But not: Variable or @var
|
48
|
+
vm_identifier = < (downcase_letter | "_") id_symbol* suffix_letter? >
|
49
|
+
{
|
50
|
+
SymbolEntry.new(:variable, text)
|
51
|
+
}
|
52
|
+
|
53
|
+
# Examples:
|
54
|
+
# var1
|
55
|
+
# But not: my_var?, my_var!
|
56
|
+
variable_identifier = < (downcase_letter | "_") id_symbol* >
|
57
|
+
{
|
58
|
+
SymbolEntry.new(:variable, text)
|
59
|
+
}
|
60
|
+
|
61
|
+
# Examples:
|
62
|
+
# MY_CONSTANT
|
63
|
+
# MyConstant_01
|
64
|
+
# But not:
|
65
|
+
# MyConstant_01?
|
66
|
+
constant_identifier = < upcase_letter id_symbol* >
|
67
|
+
{
|
68
|
+
SymbolEntry.new(:constant, text)
|
69
|
+
}
|
70
|
+
|
71
|
+
# Examples:
|
72
|
+
# $global_variable
|
73
|
+
# We won't try for funny global names like $$, $? $:, $', etc
|
74
|
+
global_identifier = < "$" (constant_identifier | variable_identifier) >
|
75
|
+
{
|
76
|
+
SymbolEntry.new(:global, text)
|
77
|
+
}
|
78
|
+
|
79
|
+
# Examples:
|
80
|
+
# Foo
|
81
|
+
# foo
|
82
|
+
# But not:
|
83
|
+
# foo!, @foo, Class.foo
|
84
|
+
local_internal_identifier = constant_identifier | variable_identifier
|
85
|
+
|
86
|
+
# Examples:
|
87
|
+
# Foo, foo, foo!
|
88
|
+
# foo
|
89
|
+
# But not:
|
90
|
+
# @foo, Class.foo
|
91
|
+
local_identifier = constant_identifier | vm_identifier
|
92
|
+
|
93
|
+
# Example: @foo
|
94
|
+
instance_identifier = < '@' local_identifier >
|
95
|
+
{
|
96
|
+
SymbolEntry.new(:instance, text)
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
# Example: @@foo
|
101
|
+
classvar_identifier = ('@@' local_identifier:id )
|
102
|
+
{
|
103
|
+
SymbolEntry.new(:classvar, id)
|
104
|
+
}
|
105
|
+
|
106
|
+
identifier = global_identifier
|
107
|
+
| instance_identifier
|
108
|
+
| classvar_identifier
|
109
|
+
| local_identifier
|
110
|
+
|
111
|
+
id_separator = < '::'|'.' > { text }
|
112
|
+
|
113
|
+
# Like of class_module_chain *after* the first name. So we don't
|
114
|
+
# allow sigils in the initial id. That is we don't allow:
|
115
|
+
# Class.@name1.@@name2.$name3
|
116
|
+
# But we do allow final sigils:
|
117
|
+
# class.name!, class.name=
|
118
|
+
internal_class_module_chain =
|
119
|
+
< local_internal_identifier:parent id_separator:sep
|
120
|
+
internal_class_module_chain:child >
|
121
|
+
{
|
122
|
+
SymbolEntry.new(parent.type, text, [parent, child, sep])
|
123
|
+
}
|
124
|
+
| local_identifier
|
125
|
+
|
126
|
+
|
127
|
+
# I think strict Ruby rules are that once one goes from :: to .
|
128
|
+
# There is no going back. That is, A.B::C is invalid.
|
129
|
+
#
|
130
|
+
# Also I think method names can't be constants. But such
|
131
|
+
# subtleties we'll handle when we process the final structure.
|
132
|
+
# Examples:
|
133
|
+
# Object, A::B, A.b @@foo.bar, $foo.bar.baz?
|
134
|
+
|
135
|
+
class_module_chain =
|
136
|
+
< identifier:parent id_separator:sep internal_class_module_chain:child >
|
137
|
+
{
|
138
|
+
SymbolEntry.new(parent.type, text, [parent, child, sep])
|
139
|
+
}
|
140
|
+
| identifier
|
141
|
+
|
142
|
+
##############################################################
|
143
|
+
# Location-specific things. This is used in conjunction with
|
144
|
+
# method-like things above.
|
145
|
+
sp = /[ \t]/
|
146
|
+
- = sp+
|
147
|
+
dbl_escapes = "\\\"" { '"' }
|
148
|
+
| "\\n" { "\n" }
|
149
|
+
| "\\t" { "\t" }
|
150
|
+
| "\\\\" { "\\" }
|
151
|
+
escapes = "\\\"" { '"' }
|
152
|
+
| "\\n" { "\n" }
|
153
|
+
| "\\t" { "\t" }
|
154
|
+
| "\\ " { " " }
|
155
|
+
| "\\:" { ":" }
|
156
|
+
| "\\\\" { "\\" }
|
157
|
+
dbl_seq = < /[^\\"]+/ > { text }
|
158
|
+
dbl_not_quote = (dbl_escapes | dbl_seq)+:ary { ary }
|
159
|
+
dbl_string = "\"" dbl_not_quote:ary "\"" { ary.join }
|
160
|
+
not_space_colon = escapes
|
161
|
+
| < /[^ \t\n:]/ > { text }
|
162
|
+
not_space_colons = ( not_space_colon )+:ary { ary.join }
|
163
|
+
filename = dbl_string | not_space_colons
|
164
|
+
file_pos_sep = sp+ | ':'
|
165
|
+
integer = </[0-9]+/> { text.to_i }
|
166
|
+
line_number = integer
|
167
|
+
|
168
|
+
vm_offset = '@' integer:int
|
169
|
+
{
|
170
|
+
Position.new(nil, nil, :offset, int)
|
171
|
+
}
|
172
|
+
|
173
|
+
# Examples:
|
174
|
+
# @43
|
175
|
+
# 5
|
176
|
+
position =
|
177
|
+
vm_offset
|
178
|
+
| line_number:l {
|
179
|
+
Position.new(nil, nil, :line, l)
|
180
|
+
}
|
181
|
+
|
182
|
+
file_colon_line = file_no_colon:file &{ File.exist?(file) } ':' position:pos {
|
183
|
+
Position.new(:file, file, pos.position_type, pos.position)
|
184
|
+
}
|
185
|
+
|
186
|
+
# Examples:
|
187
|
+
# Myclass.fn @5 # bytecode offset 5 of fn
|
188
|
+
# Myclass.fn:@5 # same as above
|
189
|
+
# Myclass.fn 5 # line number 5 of fn
|
190
|
+
# Note: Myclass.fn could be either a filename or a method name
|
191
|
+
|
192
|
+
# The below ordering is important.
|
193
|
+
# 1. Numbers can't be method names they are first. If there's a
|
194
|
+
# file with that name, later we'll allow quoting to indicate filename.
|
195
|
+
# 2. filename:position can't also be a method so that's next
|
196
|
+
# 3. It is possible a filename can be a method name, but we
|
197
|
+
# test using File.exist? so we want to put this first.
|
198
|
+
# Later "quoting" will skip the File.exist?
|
199
|
+
# 4. Class module *with* a position is next and has to be before
|
200
|
+
# without a position, else we would stop early before handling
|
201
|
+
# the position.
|
202
|
+
|
203
|
+
location =
|
204
|
+
position
|
205
|
+
| <filename>:file &{ @file_exists_proc.call(file) } file_pos_sep position:pos {
|
206
|
+
Position.new(:file, file, pos.position_type, pos.position)
|
207
|
+
}
|
208
|
+
| <filename>:file &{ @file_exists_proc.call(file) } {
|
209
|
+
Position.new(:file, file, nil, nil)
|
210
|
+
}
|
211
|
+
| class_module_chain?:fn file_pos_sep position:pos {
|
212
|
+
Position.new(:fn, fn, pos.position_type, pos.position)
|
213
|
+
}
|
214
|
+
| class_module_chain?:fn {
|
215
|
+
Position.new(:fn, fn, nil, nil)
|
216
|
+
}
|
217
|
+
|
218
|
+
if_unless = <"if" | "unless"> { text }
|
219
|
+
condition = </.+/> { text}
|
220
|
+
|
221
|
+
breakpoint_stmt_no_condition = location:loc {
|
222
|
+
Breakpoint.new(loc, false, 'true')
|
223
|
+
}
|
224
|
+
|
225
|
+
# Note that the first word "break" is handled in the command.
|
226
|
+
# Also, "break" with nothing else is handled there as well
|
227
|
+
breakpoint_stmt = location:loc - if_unless:iu - condition:cond {
|
228
|
+
Breakpoint.new(loc, iu == 'unless', cond)
|
229
|
+
}
|
230
|
+
| breakpoint_stmt_no_condition
|
231
|
+
|
232
|
+
# Note that the first word "list", "list>" or handled in
|
233
|
+
# the command. Also, "list" with nothing else is
|
234
|
+
# handled there as well
|
235
|
+
list_special_targets = <'.' | '-'> { text }
|
236
|
+
list_stmt = (list_special_targets | location):loc - (integer:int)? {
|
237
|
+
List.new(loc, int)
|
238
|
+
}
|
239
|
+
| (list_special_targets | location):loc {
|
240
|
+
List.new(loc, nil)
|
241
|
+
}
|