rbx-trepanning 0.0.4-universal-rubinius-1.2 → 0.0.6-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/ChangeLog +682 -0
  2. data/NEWS +19 -0
  3. data/README.textile +8 -9
  4. data/Rakefile +8 -8
  5. data/app/complete.rb +52 -0
  6. data/app/complete.rbc +1288 -0
  7. data/app/irb.rb +1 -2
  8. data/app/irb.rbc +55 -72
  9. data/app/llvm.rbc +780 -878
  10. data/app/method.rb +1 -1
  11. data/app/method.rbc +31 -35
  12. data/app/method_name.rbc +2467 -0
  13. data/app/options.rb +7 -24
  14. data/app/options.rbc +238 -132
  15. data/app/rbx-llvm.rbc +2478 -0
  16. data/app/util.rb +3 -3
  17. data/app/util.rbc +23 -27
  18. data/bin/trepanx +4 -3
  19. data/bin/trepanx.compiled.rbc +42 -32
  20. data/data/irbrc +41 -0
  21. data/data/irbrc.compiled.rbc +640 -0
  22. data/interface/base_intf.rb +9 -5
  23. data/interface/base_intf.rbc +200 -146
  24. data/interface/comcodes.rb +10 -8
  25. data/interface/comcodes.rbc +68 -26
  26. data/interface/script.rbc +21 -9
  27. data/interface/user.rb +74 -8
  28. data/interface/user.rbc +1702 -156
  29. data/io/input.rb +37 -14
  30. data/io/input.rbc +869 -320
  31. data/io/tcpclient.rb +7 -1
  32. data/io/tcpclient.rbc +205 -113
  33. data/io/tcpfns.rb +5 -3
  34. data/io/tcpfns.rbc +82 -40
  35. data/io/tcpserver.rb +13 -10
  36. data/io/tcpserver.rbc +236 -183
  37. data/lib/trepanning.rb +62 -21
  38. data/lib/trepanning.rbc +1304 -874
  39. data/lib/{trepanning.rb.orig → trepanning2.rb} +12 -4
  40. data/processor/breakpoint.rb +4 -1
  41. data/processor/command/base/cmd.rb +48 -3
  42. data/processor/command/base/subcmd.rb +2 -1
  43. data/processor/command/base/submgr.rb +23 -20
  44. data/processor/command/base/subsubmgr.rb +13 -2
  45. data/processor/command/complete.rb +7 -17
  46. data/processor/command/continue.rb +19 -11
  47. data/processor/command/disassemble.rb +39 -12
  48. data/processor/command/eval.rb +23 -5
  49. data/processor/command/help.rb +60 -6
  50. data/processor/command/info_subcmd/{file.rb → files.rb} +76 -18
  51. data/processor/command/info_subcmd/line.rb +86 -0
  52. data/processor/command/info_subcmd/program.rb +2 -11
  53. data/processor/command/info_subcmd/ruby.rb +62 -0
  54. data/processor/command/info_subcmd/variables.rb +7 -0
  55. data/processor/command/irb.rb +39 -7
  56. data/processor/command/macro.rb +76 -0
  57. data/processor/command/set_subcmd/confirm.rb +24 -0
  58. data/processor/command/set_subcmd/max.rb +4 -5
  59. data/processor/command/show.rb +11 -0
  60. data/processor/command/show_subcmd/auto.rb +1 -0
  61. data/processor/command/show_subcmd/basename.rb +1 -2
  62. data/processor/command/show_subcmd/confirm.rb +18 -0
  63. data/processor/command/show_subcmd/max.rb +0 -2
  64. data/processor/command/source.rb +0 -1
  65. data/processor/default.rb +2 -0
  66. data/processor/disassemble.rb +1 -0
  67. data/processor/load_cmds.rb +104 -20
  68. data/processor/location.rb +11 -12
  69. data/processor/main.rb +10 -6
  70. data/processor/mock.rb +6 -2
  71. data/processor/stepping.rb +1 -4
  72. data/processor/subcmd.rb +3 -2
  73. data/processor/validate.rb +3 -3
  74. data/sample/list-terminal-colors.rbc +158 -4
  75. data/sample/rocky-trepanx-colors.rb +15 -7
  76. data/sample/rocky-trepanx-colors.rbc +530 -0
  77. data/test/data/quit2.cmd +6 -0
  78. data/test/data/quit2.right +3 -0
  79. data/test/data/step-bug.cmd +11 -0
  80. data/test/data/step-bug.right +3 -0
  81. data/test/example/step-bug.rb +14 -0
  82. data/test/integration/helper.rb +1 -1
  83. data/test/integration/skip-test-step-bug.rb +17 -0
  84. data/test/integration/test-quit.rb +11 -0
  85. data/test/unit/test-app-util.rb +0 -1
  86. data/test/unit/test-base-cmd.rb +47 -0
  87. data/test/unit/test-base-subcmd.rb +2 -2
  88. data/test/unit/test-base-submgr.rb +24 -0
  89. data/test/unit/test-cmd-help.rb +4 -0
  90. data/test/unit/test-completion.rb +38 -0
  91. data/test/unit/test-intf-user.rb +2 -2
  92. data/test/unit/test-io-tcpclient.rb +3 -2
  93. data/test/unit/test-proc-eval.rb +1 -1
  94. data/test/unit/test-proc-load_cmds.rb +9 -0
  95. data/test/unit/test-subcmd-help.rb +1 -5
  96. metadata +182 -167
  97. data/app/options.rb.orig +0 -154
  98. data/bin/trepan.orig +0 -0
  99. data/bin/trepan.rej +0 -11
  100. data/lib/trepanning.rb.rej +0 -11
  101. data/sample/rocky-dot-trepanrc.orig +0 -0
  102. data/sample/rocky-dot-trepanrc.rej +0 -11
@@ -48,10 +48,15 @@ class Trepan
48
48
  @input = @settings[:input] || STDIN
49
49
  @output = @settings[:output] || STDOUT
50
50
 
51
- cmdproc_settings = {:terminal => @settings[:terminal]}
51
+ cmdproc_settings = {:highlight => @settings[:highlight]}
52
52
 
53
53
  @processor = CmdProcessor.new(self, cmdproc_settings)
54
-
54
+ completion_proc = Proc.new do |str|
55
+ completed_ary = @processor.complete(Readline.line_buffer, true)
56
+ Readline.line_buffer = '' unless completed_ary.empty?
57
+ completed_ary
58
+ end
59
+
55
60
  @intf =
56
61
  if @settings[:server]
57
62
  opts = Trepan::ServerInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
@@ -64,9 +69,11 @@ class Trepan
64
69
  opts = Trepan::ClientInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
65
70
  opts[:port] = @settings[:port] if @settings[:port]
66
71
  opts[:host] = @settings[:host] if @settings[:host]
72
+ opts[:complete] = completion_proc
67
73
  [Trepan::ClientInterface.new(nil, nil, nil, nil, opts)]
68
74
  else
69
- [Trepan::UserInterface.new(@input, @output)]
75
+ opts = {:complete => completion_proc}
76
+ [Trepan::UserInterface.new(@input, @output, opts)]
70
77
  end
71
78
 
72
79
  process_cmdfile_setting(@settings)
@@ -86,7 +93,8 @@ class Trepan
86
93
  @history_path = File.expand_path("~/.trepanx")
87
94
 
88
95
  if File.exists?(@history_path)
89
- File.readlines(@history_path).each do |line|
96
+ File.readlines(@history_path).each_with_index do |line, i|
97
+ break if i > 50 # FIXME: remove constant 50
90
98
  Readline::HISTORY << line.strip
91
99
  end
92
100
  @history_io = File.new(@history_path, "a")
@@ -58,7 +58,7 @@ class Trepan
58
58
  if line
59
59
  ip = cm.first_ip_on_line(line)
60
60
 
61
- if ip == -1
61
+ unless ip
62
62
  errmsg "Unknown line '#{line}' in method '#{cm.name}'"
63
63
  return nil
64
64
  end
@@ -67,6 +67,9 @@ class Trepan
67
67
  ip = 0
68
68
  end
69
69
 
70
+ # def lines without code will have value -1.
71
+ ip = 0 if -1 == ip
72
+
70
73
  bp = @brkpts.add(descriptor, cm, ip, line, @brkpts.max+1, opts)
71
74
  bp.activate
72
75
  msg("Set %sbreakpoint #{bp.id}: #{meth.name}() at #{bp.location}" %
@@ -3,8 +3,9 @@
3
3
  # Base class of all commands. Code common to all commands is here.
4
4
  # Note: don't end classname with Command (capital C) since main
5
5
  # will think this a command name like QuitCommand
6
- require 'rubygems'
6
+ require 'rubygems'; require 'require_relative'
7
7
  require 'columnize'
8
+ require_relative '../../../app/complete'
8
9
 
9
10
  class Trepan
10
11
  class Command
@@ -60,8 +61,8 @@ class Trepan
60
61
  end
61
62
 
62
63
  # Convenience short-hand for @dbgr.intf[-1].msg_nocr
63
- def msg_nocr(msg)
64
- @proc.msg_nocr(msg, opts={})
64
+ def msg_nocr(msg, opts={})
65
+ @proc.msg_nocr(msg, opts)
65
66
  end
66
67
 
67
68
  def my_const(name)
@@ -103,6 +104,14 @@ class Trepan
103
104
  my_const(help_constant_sym)
104
105
  end
105
106
 
107
+ # Define a method called 'complete' on the singleton class.
108
+ def self.completion(ary)
109
+ self.send(:define_method,
110
+ :complete,
111
+ Proc.new {|prefix|
112
+ Trepan::Complete.complete_token(ary, prefix) })
113
+ end
114
+
106
115
  # From reference debugger
107
116
  def run_code(str)
108
117
  @proc.dbgr.current_frame.run(str)
@@ -126,3 +135,39 @@ class Trepan
126
135
 
127
136
  end
128
137
  end
138
+ if __FILE__ == $0
139
+ class Trepan
140
+ class CmdProcessor
141
+ def initialize(dbgr)
142
+ end
143
+ def confirm(message, default)
144
+ p ['confirm: ', message, default]
145
+ end
146
+ def errmsg(message, opts)
147
+ p ['err:', message, opts]
148
+ end
149
+ def msg(message, opts)
150
+ p [message, opts]
151
+ end
152
+ def msg_nocr(message, opts)
153
+ p ['nocr: ', message, opts]
154
+ end
155
+ def section(message, opts)
156
+ p ['section: ', message, opts]
157
+ end
158
+ end
159
+ class Command::Test < Trepan::Command
160
+ NAME = 'test'
161
+ CATEGORY = 'testcategory'
162
+ completion %w(a aa ab ba aac)
163
+ end
164
+ end
165
+ proc = Trepan::CmdProcessor.new(nil)
166
+ cmd = Trepan::Command::Test.new(proc)
167
+ %w(confirm errmsg msg msg_nocr section).each do |meth|
168
+ cmd.send(meth, 'test', nil)
169
+ end
170
+ p cmd.complete('aa')
171
+ cmd.instance_variable_set('@completions', %w(aardvark apple))
172
+ p cmd.complete('aa')
173
+ end
@@ -160,10 +160,11 @@ class Trepan
160
160
  def summary_help(subcmd_name)
161
161
  msg_nocr("%-12s: %s" % [subcmd_name, my_const(:SHORT_HELP)])
162
162
  end
163
-
164
163
  end
165
164
 
166
165
  class SetBoolSubcommand < Subcommand
166
+ completion %w(on off)
167
+
167
168
  def run(args)
168
169
  run_set_bool(args)
169
170
  end
@@ -1,9 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require 'rubygems'; require 'require_relative'
4
4
  require_relative 'cmd'
5
5
  require_relative '../../subcmd'
6
6
  require_relative '../../help'
7
+ require_relative '../../../app/complete'
7
8
 
8
9
  class Trepan::SubcommandMgr < Trepan::Command
9
10
 
@@ -18,7 +19,7 @@ class Trepan::SubcommandMgr < Trepan::Command
18
19
  NEED_STACK = false
19
20
  end
20
21
 
21
- attr_accessor :subcmds # Array of instaniated Trepan::Subcommand objects
22
+ attr_accessor :subcmds # Trepan::Subcmd
22
23
  attr_reader :name # Name of command
23
24
  attr_reader :last_args # Last arguments seen
24
25
 
@@ -60,20 +61,18 @@ class Trepan::SubcommandMgr < Trepan::Command
60
61
  subcommands = {}
61
62
  cmd_names.each do |name|
62
63
  next unless Trepan::Subcommand.constants.member?(name)
63
- subcmd_class = "Trepan::Subcommand::#{name}.new(self)"
64
- cmd = self.instance_eval(subcmd_class)
65
- cmd_name = cmd.name
64
+ klass = Trepan::Subcommand.const_get(name)
65
+ cmd = klass.send(:new, self)
66
66
  @subcmds.add(cmd)
67
67
  end
68
68
  subcmd_names.each do |name|
69
69
  next unless Trepan::SubSubcommand.constants.member?(name)
70
- subcmd_class = "Trepan::SubSubcommand::#{name}.new(self, parent)"
70
+ subcmd_class = Trepan::SubSubcommand.const_get(name)
71
71
  begin
72
- cmd = self.instance_eval(subcmd_class)
72
+ cmd = subcmd_class.send(:new, self, parent)
73
73
  rescue
74
74
  puts "Subcmd #{name} is bad"
75
75
  end
76
- cmd_name = cmd.name
77
76
  @subcmds.add(cmd)
78
77
  end
79
78
  end
@@ -143,7 +142,18 @@ class Trepan::SubcommandMgr < Trepan::Command
143
142
  end
144
143
  end
145
144
 
146
- def run(args)
145
+ # Return an Array of subcommands that can start with +arg+. If none
146
+ # found we just return +arg+.
147
+ # FIXME: Not used any more?
148
+ def complete(prefix)
149
+ Trepan::Complete.complete_token(@subcmds.subcmds.keys, prefix)
150
+ end
151
+
152
+ def complete_token_with_next(prefix)
153
+ Trepan::Complete.complete_token_with_next(@subcmds.subcmds, prefix)
154
+ end
155
+
156
+ def run(args) # nodoc
147
157
  @last_args = args
148
158
  if args.size < 2 || args.size == 2 && args[-1] == '*'
149
159
  summary_list(obj_const(self, :NAME), @subcmds)
@@ -165,15 +175,8 @@ end
165
175
  if __FILE__ == $0
166
176
  # Demo it.
167
177
  require_relative '../../mock'
168
- dbgr = MockDebugger::MockDebugger.new
169
- # cmds = dbgr.core.processor.commands
170
- # cmd = cmds['set']
171
- # Trepan::SubcommandMgr.new(dbgr.core.processor)
172
- # puts cmd.help(%w(help set))
173
- # puts '=' * 40
174
- # # require_relative '../../../lib/trepanning)
175
- # # Trepan.debug(:set_restart => true)
176
- # puts cmd.help(%w(help set *))
177
- # puts '=' * 40
178
- # puts cmd.help(%w(help set d.*))
178
+ dbgr, cmd = MockDebugger::setup('show')
179
+ p cmd.complete('d')
180
+ p cmd.subcmds.lookup('ar').prefix
181
+ p cmd.subcmds.lookup('a')
179
182
  end
@@ -5,7 +5,6 @@ require_relative 'subcmd'
5
5
  require_relative '../../subcmd'
6
6
  require_relative '../../help'
7
7
 
8
- require 'rubygems'; require 'require_relative'
9
8
  class Trepan::SubSubcommandMgr < Trepan::Subcommand
10
9
 
11
10
  include Trepan::Help
@@ -146,6 +145,18 @@ class Trepan::SubSubcommandMgr < Trepan::Subcommand
146
145
  end
147
146
  end
148
147
 
148
+ # Return an Array of subcommands that can start with +arg+. If none
149
+ # found we just return +arg+.
150
+ def complete(prefix)
151
+ prior = self.prefix.join('').size
152
+ last_args = @subcmds.list.map{|str| str[prior..-1]}
153
+ Trepan::Complete.complete_token(last_args, prefix)
154
+ end
155
+
156
+ def complete_token_with_next(prefix)
157
+ Trepan::Complete.complete_token_with_next(@subcmds.subcmds, prefix)
158
+ end
159
+
149
160
  def run(args)
150
161
  args = @parent.last_args if args.size == 0
151
162
  if args.size < 3 || args.size == 3 && args[-1] == '*'
@@ -179,6 +190,6 @@ if __FILE__ == $0
179
190
  # puts '=' * 40
180
191
  # FIXME
181
192
  # require_relative '../../lib/trepanning'
182
- # Trepan.debug(:set_restart => true)
193
+ # Trepan.debugger
183
194
  # puts cmd.help(%w(help info registers p.*))
184
195
  end
@@ -1,35 +1,25 @@
1
1
  # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require 'rubygems'; require 'require_relative'
3
3
  require_relative 'base/cmd'
4
+ require_relative '../load_cmds'
4
5
  class Trepan::Command::CompleteCommand < Trepan::Command
5
6
 
6
7
  unless defined?(HELP)
7
- HELP =
8
- "complete COMMAND-PREFIX
8
+ NAME = File.basename(__FILE__, '.rb')
9
+ HELP = <<-HELP
10
+ #{NAME} COMMAND-PREFIX
9
11
 
10
12
  List the completions for the rest of the line as a command.
11
-
12
- NOTE: For now we just handle completion of the first token.
13
- "
13
+ HELP
14
14
  CATEGORY = 'support'
15
- NAME = File.basename(__FILE__, '.rb')
16
15
  NEED_STACK = false
17
16
  SHORT_HELP = 'List the completions for the rest of the line as a command'
18
17
  end
19
18
 
20
19
  # This method runs the command
21
20
  def run(args) # :nodoc
22
- if args.size == 2
23
- cmd_matches = @proc.commands.keys.select do |cmd|
24
- cmd.start_with?(args[1])
25
- end
26
- alias_matches = @proc.aliases.keys.select do |cmd|
27
- cmd.start_with?(args[1]) && !cmd_matches.member?(@proc.aliases[cmd])
28
- end
29
- (cmd_matches+alias_matches).sort.each do |match|
30
- msg match
31
- end
32
- else # FIXME: handle more complex completions
21
+ @proc.complete(args[1..-1]).each do |match|
22
+ msg match
33
23
  end
34
24
  end
35
25
  end
@@ -1,31 +1,38 @@
1
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
2
  require 'rubygems'; require 'require_relative'
2
3
  require_relative 'base/cmd'
3
4
  require_relative '../stepping'
4
5
 
5
6
  class Trepan::Command::ContinueCommand < Trepan::Command
6
- NAME = File.basename(__FILE__, '.rb')
7
- HELP = <<-HELP
7
+ unless defined?(HELP)
8
+ NAME = File.basename(__FILE__, '.rb')
9
+ HELP = <<-HELP
8
10
  #{NAME} [breakpoint-position]
9
11
 
10
12
  Leave the debugger loop and continue execution. Subsequent entry to
11
13
  the debugger however may occur via breakpoints or explicit calls, or
12
14
  exceptions.
13
15
 
14
- If a parameter is given, a one-time breakpoint is set at that position
15
- before continuing.
16
+ If a parameter is given, a temporary breakpoint is set at that position
17
+ before continuing. Offset are numbers prefixed with an "O" otherwise
18
+ the parameter is taken as a line number.
16
19
 
17
20
  Examples:
18
21
  #{NAME}
19
22
  #{NAME} 10 # continue to line 10
20
- #{NAME} Array#map # beginning of next Array#map call
23
+ #{NAME} o20 # continue to VM Instruction Sequence offset 20
24
+ #{NAME} gcd # continue to first instruction of method gcd
25
+ #{NAME} IRB.start o7 # continue to IRB.start offset 7
21
26
 
22
27
  See also 'step', 'next', 'finish', and 'nexti' commands.
23
- HELP
24
- ALIASES = %w(c cont)
25
- CATEGORY = 'running'
26
- MAX_ARGS = 1
27
- NEED_RUNNING = true
28
- SHORT_HELP = 'Continue execution of the debugged program'
28
+ HELP
29
+
30
+ ALIASES = %w(c cont)
31
+ CATEGORY = 'running'
32
+ MAX_ARGS = 2 # Need at most this many
33
+ NEED_RUNNING = true
34
+ SHORT_HELP = 'Continue execution of the debugged program'
35
+ end
29
36
 
30
37
  # This is the method that runs the command
31
38
  def run(args)
@@ -80,4 +87,5 @@ end
80
87
  if __FILE__ == $0
81
88
  require_relative '../mock'
82
89
  dbgr, cmd = MockDebugger::setup
90
+ p cmd.run([cmd.name])
83
91
  end
@@ -2,20 +2,31 @@
2
2
  # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require 'rubygems'; require 'require_relative'
4
4
  require_relative './base/cmd'
5
+ require_relative '../../app/method'
5
6
  require_relative '../../app/iseq'
6
7
 
7
8
  class Trepan::Command::DisassembleCommand < Trepan::Command
9
+
10
+ include Trepanning::Method
11
+
8
12
  NAME = File.basename(__FILE__, '.rb')
9
- ALIASES = %w(dis)
13
+ ALIASES = %w(disas disassem) # Note we (will) have disable
10
14
  CATEGORY = 'data'
11
15
  HELP = <<-HELP
12
- #{NAME} [all|method]
16
+ #{NAME} [all]
17
+ #{NAME} [method|LINE-NUM]...
13
18
 
14
19
  Disassembles Rubinius VM instructions. By default, the bytecode for the
15
20
  current line is disassembled only.
16
21
 
17
- If a method name is given, disassemble just that method. If the
18
- argument is 'all', the entire method is shown as bytecode.
22
+ If a method name is given, disassemble just that method.
23
+
24
+ If a line number given, then disassemble just that line number if it
25
+ has bytecode assocated with that line. Note that if a line has
26
+ discontinuous regions we will show just the first region associated
27
+ with that line.
28
+
29
+ If the argument is 'all', the entire method is shown as bytecode.
19
30
 
20
31
  Examples:
21
32
  #{NAME} # dissasemble VM for current line
@@ -23,7 +34,8 @@ Examples:
23
34
  #{NAME} [1,2].max # disassemble max method of Array
24
35
  #{NAME} Object.is_a? # disassemble Object.is_a?
25
36
  #{NAME} is_a? # same as above (probably)
26
-
37
+ #{NAME} 6 # Disassemble line 6 if there is bytecode for it
38
+ #{NAME} 6 is_a? # The above two commands combined into one
27
39
  HELP
28
40
 
29
41
  NEED_STACK = true
@@ -66,7 +78,7 @@ Examples:
66
78
  # FIXME DRY with ../disassemble.rb
67
79
  if settings[:highlight]
68
80
  require_relative '../../app/rbx-llvm'
69
- @llvm_highlighter = CodeRay::Duo[:llvm, :term]
81
+ @llvm_highlighter ||= CodeRay::Duo[:llvm, :term]
70
82
  # llvm_scanner = CodeRay.scanner :llvm
71
83
  # p llvm_scanner.tokenize(disasm)
72
84
  disasm = @llvm_highlighter.encode(disasm)
@@ -85,12 +97,25 @@ Examples:
85
97
  section "Bytecode for #{@proc.frame.vm_location.describe}"
86
98
  disassemble_method(current_method)
87
99
  else
88
- cm = @proc.parse_method(args[1])
89
- if cm
90
- section "Bytecode for method #{args[1]}"
91
- disassemble_method(cm.executable)
92
- else
93
- errmsg "Method #{args[1]} not found"
100
+ args[1..-1].each do |arg|
101
+ cm = @proc.parse_method(arg)
102
+ if cm
103
+ section "Bytecode for method #{arg}"
104
+ disassemble_method(cm.executable)
105
+ else
106
+ opts = {:msg_on_error => false }
107
+ line_num = @proc.get_an_int(arg, opts)
108
+ if line_num
109
+ cm = find_method_with_line(current_method, line_num)
110
+ if cm
111
+ @proc.show_bytecode(line_num)
112
+ else
113
+ errmsg "Can't find that bytecode for line #{line_num}"
114
+ end
115
+ else
116
+ errmsg "Method #{arg} not found"
117
+ end
118
+ end
94
119
  end
95
120
  end
96
121
  end
@@ -113,6 +138,8 @@ if __FILE__ == $0
113
138
  # require_relative '../../lib/trepanning'
114
139
  # debugger
115
140
  cmd.run([cmd.name, 'self.setup'])
141
+ puts '=' * 40
142
+ cmd.run([cmd.name, __LINE__.to_s])
116
143
  end
117
144
  foo(cmd)
118
145
  end
@@ -5,20 +5,40 @@ require_relative './base/cmd'
5
5
 
6
6
  class Trepan::Command::EvalCommand < Trepan::Command
7
7
 
8
+ NAME = File.basename(__FILE__, '.rb')
8
9
  CATEGORY = 'data'
9
10
  HELP = <<-HELP
11
+ #{NAME} [STRING]
12
+
10
13
  Run code in the context of the current frame.
11
14
 
12
15
  The value of the expression is stored into a global variable so it
13
16
  may be used again easily. The name of the global variable is printed
14
17
  next to the inspect output of the value.
18
+
19
+ If no string is given we run the string from the current source code
20
+ about to be run
21
+
22
+ #{NAME} 1+2 # 3
23
+ #{NAME} @v
24
+ #{NAME} # Run current source-code line
25
+
26
+ See also 'set autoeval'
15
27
  HELP
16
28
 
17
29
  NAME = File.basename(__FILE__, '.rb')
18
30
  NEED_STACK = true
19
31
  SHORT_HELP = 'Run code in the current context'
20
32
  def run(args)
21
- @proc.debug_eval(@proc.cmd_argstr, settings[:maxstring])
33
+ if args.size == 1
34
+ loc = @proc.source_location_info
35
+ opts = {:reload_on_change => @proc.reload_on_change}
36
+ loc, junk, text = @proc.loc_and_text(loc, opts)
37
+ msg "eval: #{text}"
38
+ else
39
+ text = @proc.cmd_argstr
40
+ end
41
+ @proc.eval_code(text, settings[:maxstring])
22
42
  end
23
43
  end
24
44
 
@@ -26,8 +46,6 @@ if __FILE__ == $0
26
46
  require_relative '../mock'
27
47
  dbgr, cmd = MockDebugger::setup
28
48
  arg_str = '1 + 2'
29
- ## cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
30
- dbgr.instance_variable_set('@cmd_argstr', arg_str)
31
-
32
- ## cmd.run([cmd.name, arg_str])
49
+ cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
50
+ puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
33
51
  end
@@ -1,6 +1,7 @@
1
1
  # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require 'rubygems'; require 'require_relative'
3
3
  require_relative 'base/cmd'
4
+ require_relative '../../app/complete'
4
5
  class Trepan::Command::HelpCommand < Trepan::Command
5
6
 
6
7
  unless defined?(HELP)
@@ -40,6 +41,30 @@ See also 'examine' and 'whatis'.
40
41
  SHORT_HELP = 'Print commands or give help for command(s)'
41
42
  end
42
43
 
44
+ def complete(prefix)
45
+ matches = Trepan::Complete.complete_token(CATEGORIES.keys +
46
+ %w(* syntax all) +
47
+ @proc.commands.keys, prefix)
48
+ aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
49
+ matches)
50
+ (matches + aliases).sort
51
+ end
52
+
53
+ def complete(prefix)
54
+ matches = Trepan::Complete.complete_token(CATEGORIES.keys +
55
+ %w(* syntax all) +
56
+ @proc.commands.keys, prefix)
57
+ aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
58
+ matches)
59
+ (matches + aliases).sort
60
+ end
61
+
62
+ def complete_token_with_next(prefix)
63
+ complete(prefix).map do |cmd|
64
+ [cmd, @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil]
65
+ end
66
+ end
67
+
43
68
  # List the command categories and a short description of each.
44
69
  def list_categories
45
70
  section 'Classes of commands:'
@@ -49,7 +74,9 @@ See also 'examine' and 'whatis'.
49
74
  final_msg = '
50
75
  Type "help" followed by a class name for a list of commands in that class.
51
76
  Type "help syntax" for information on debugger command syntax.
52
- Type "help *" for the list of all commands.
77
+ Type "help aliases" for a list of current aliases
78
+ Type "help macros" for a list of current macros
79
+ Type "help *" for the list of all commands, macros and aliases.
53
80
  Type "help all" for the list of all commands.
54
81
  Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
55
82
  Type "help CLASS *" for the list of all commands in class CLASS.
@@ -65,6 +92,12 @@ Type "help" followed by command name for full documentation.
65
92
  if cmd_name == '*'
66
93
  section 'All command names:'
67
94
  msg columnize_commands(@proc.commands.keys.sort)
95
+ show_aliases unless @proc.aliases.empty?
96
+ show_macros unless @proc.macros.empty?
97
+ elsif cmd_name =~ /^aliases$/i
98
+ show_aliases
99
+ elsif cmd_name =~ /^macros$/i
100
+ show_macros
68
101
  elsif cmd_name =~ /^syntax$/i
69
102
  show_command_syntax
70
103
  elsif cmd_name =~ /^all$/i
@@ -91,6 +124,9 @@ Type "help" followed by command name for full documentation.
91
124
  msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
92
125
  end
93
126
  end
127
+ elsif @proc.macros.member?(cmd_name)
128
+ msg "#{cmd_name} is a macro which expands to:"
129
+ msg " #{@proc.macros[cmd_name]}", {:unlimited => true}
94
130
  else
95
131
  matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
96
132
  if matches.empty?
@@ -105,6 +141,11 @@ Type "help" followed by command name for full documentation.
105
141
  end
106
142
  end
107
143
 
144
+ def show_aliases
145
+ section 'All alias names:'
146
+ msg columnize_commands(@proc.aliases.keys.sort)
147
+ end
148
+
108
149
  # Show short help for all commands in `category'.
109
150
  def show_category(category, args)
110
151
 
@@ -130,7 +171,7 @@ Type "help" followed by command name for full documentation.
130
171
  def show_command_syntax
131
172
  section "Debugger command syntax"
132
173
  msg <<-EOS
133
- Command command syntax is very simple-minded.
174
+ Command tokenization syntax is very simple-minded.
134
175
 
135
176
  If a line starts with #, the command is ignored.
136
177
  If a line starts with !, the line is eval'd.
@@ -144,11 +185,16 @@ after the leading command string are put back on a command queue.
144
185
 
145
186
  Within a single command, tokens are then white-space split. Again,
146
187
  this process disregards quotes or symbols that have meaning in Ruby.
188
+ Some commands like 'eval' and 'macro' have access to the untokenized
189
+ string entered and make use of that rather than the tokenized list.
147
190
 
148
- The first token is then looked up in the debugger command table and
149
- then the debugger alias table. If a match is found the command name
150
- and arguments are dispatched to the command object that process the
151
- command.
191
+ The leading token is first looked up in the macro table. If it
192
+ found there, the expansion is replaces the current command and possibly
193
+ other commands pushed onto a command queue. Next the leading token is
194
+ looked up in the debugger alias table and the name may be substituted
195
+ there. Finally, the leading token is looked up in the debugger alias
196
+ table. If a match is found, the command name and arguments are
197
+ dispatched to the command object that process the command.
152
198
 
153
199
  If the command is not found and "auto eval" is set on, then the
154
200
  command is eval'd in the context that the program is currently stopped
@@ -172,6 +218,12 @@ pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
172
218
  See also "alias", "irb", "set auto eval", and "set auto irb".
173
219
  EOS
174
220
  end
221
+
222
+ def show_macros
223
+ section 'All macro names:'
224
+ msg columnize_commands(@proc.macros.keys.sort)
225
+ end
226
+
175
227
  end
176
228
 
177
229
  if __FILE__ == $0
@@ -194,4 +246,6 @@ if __FILE__ == $0
194
246
  cmd.run %W(#{cmd.name} s.*)
195
247
  puts '=' * 40
196
248
  cmd.run %W(#{cmd.name} s<>)
249
+ puts '=' * 40
250
+ p cmd.complete('br')
197
251
  end