trepanning 0.1.0 → 0.1.1

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.
Files changed (181) hide show
  1. data/.gitignore +4 -0
  2. data/ChangeLog +1279 -235
  3. data/Makefile +13 -0
  4. data/NEWS +30 -0
  5. data/Rakefile +50 -14
  6. data/app/.gitignore +1 -0
  7. data/app/breakpoint.rb +7 -2
  8. data/app/brkptmgr.rb +12 -0
  9. data/app/cmd_parse.citrus +167 -0
  10. data/app/cmd_parse.kpeg +221 -0
  11. data/app/cmd_parse.rb +201 -0
  12. data/app/cmd_parser.rb +1914 -0
  13. data/app/complete.rb +79 -0
  14. data/app/condition.rb +1 -1
  15. data/app/core.rb +7 -11
  16. data/app/default.rb +1 -1
  17. data/app/disassemble.rb +3 -2
  18. data/app/file.rb +12 -36
  19. data/app/frame.rb +3 -2
  20. data/app/irb.rb +9 -5
  21. data/app/iseq.rb +46 -0
  22. data/app/options.rb +6 -30
  23. data/app/run.rb +5 -2
  24. data/app/util.rb +1 -2
  25. data/app/yarv.rb +11 -1
  26. data/bin/.gitignore +1 -0
  27. data/bin/trepan +6 -6
  28. data/data/.gitignore +1 -0
  29. data/interface/.gitignore +1 -0
  30. data/interface/base_intf.rb +9 -5
  31. data/interface/comcodes.rb +10 -8
  32. data/interface/user.rb +76 -17
  33. data/io/.gitignore +1 -0
  34. data/io/input.rb +39 -15
  35. data/io/tcpclient.rb +7 -1
  36. data/io/tcpfns.rb +5 -3
  37. data/io/tcpserver.rb +13 -10
  38. data/lib/.gitignore +1 -0
  39. data/lib/trepanning.rb +50 -13
  40. data/processor/.gitignore +1 -0
  41. data/processor/Makefile +7 -0
  42. data/processor/breakpoint.rb +7 -2
  43. data/processor/command/.gitignore +1 -0
  44. data/processor/command/Makefile +7 -0
  45. data/processor/command/alias.rb +2 -2
  46. data/processor/command/backtrace.rb +4 -0
  47. data/processor/command/base/cmd.rb +45 -2
  48. data/processor/command/base/subcmd.rb +4 -2
  49. data/processor/command/base/submgr.rb +23 -19
  50. data/processor/command/base/subsubcmd.rb +23 -1
  51. data/processor/command/base/subsubmgr.rb +13 -0
  52. data/processor/command/break.rb +34 -29
  53. data/processor/command/complete.rb +37 -0
  54. data/processor/command/condition.rb +2 -0
  55. data/processor/command/continue.rb +15 -18
  56. data/processor/command/disassemble.rb +5 -0
  57. data/processor/command/down.rb +1 -1
  58. data/processor/command/eval.rb +70 -0
  59. data/processor/command/exit.rb +4 -1
  60. data/processor/command/finish.rb +6 -4
  61. data/processor/command/frame.rb +6 -3
  62. data/processor/command/help.rb +97 -54
  63. data/processor/command/help/.gitignore +1 -0
  64. data/processor/command/help/README +10 -0
  65. data/processor/command/help/command.txt +48 -0
  66. data/processor/command/help/filename.txt +40 -0
  67. data/processor/command/help/location.txt +37 -0
  68. data/processor/command/info_subcmd/.gitignore +1 -0
  69. data/processor/command/info_subcmd/breakpoints.rb +9 -9
  70. data/processor/command/info_subcmd/{file.rb → files.rb} +92 -27
  71. data/processor/command/info_subcmd/frame.rb +41 -15
  72. data/processor/command/info_subcmd/iseq.rb +39 -17
  73. data/processor/command/info_subcmd/program.rb +2 -8
  74. data/processor/command/info_subcmd/registers.rb +12 -10
  75. data/processor/command/info_subcmd/registers_subcmd/.gitignore +1 -0
  76. data/processor/command/info_subcmd/ruby.rb +60 -0
  77. data/processor/command/irb.rb +26 -3
  78. data/processor/command/kill.rb +21 -10
  79. data/processor/command/list.rb +1 -1
  80. data/processor/command/macro.rb +37 -23
  81. data/processor/command/pr.rb +1 -1
  82. data/processor/command/reload.rb +4 -0
  83. data/processor/command/reload_subcmd/.gitignore +1 -0
  84. data/processor/command/restart.rb +9 -9
  85. data/processor/command/save.rb +29 -36
  86. data/processor/command/set_subcmd/.gitignore +1 -0
  87. data/processor/command/set_subcmd/auto_subcmd/.gitignore +1 -0
  88. data/processor/command/set_subcmd/confirm.rb +23 -0
  89. data/processor/command/set_subcmd/debug_subcmd/.gitignore +1 -0
  90. data/processor/command/set_subcmd/different.rb +2 -0
  91. data/processor/command/set_subcmd/events.rb +2 -0
  92. data/processor/command/set_subcmd/max.rb +9 -12
  93. data/processor/command/set_subcmd/max_subcmd/.gitignore +1 -0
  94. data/processor/command/set_subcmd/substitute_subcmd/.gitignore +1 -0
  95. data/processor/command/set_subcmd/trace.rb +7 -13
  96. data/processor/command/set_subcmd/trace_subcmd/.gitignore +1 -0
  97. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +12 -27
  98. data/processor/command/set_subcmd/trace_subcmd/print.rb +10 -8
  99. data/processor/command/set_subcmd/trace_subcmd/var.rb +6 -10
  100. data/processor/command/show.rb +12 -1
  101. data/processor/command/show_subcmd/.gitignore +1 -0
  102. data/processor/command/show_subcmd/alias.rb +11 -15
  103. data/processor/command/show_subcmd/auto_subcmd/.gitignore +1 -0
  104. data/processor/command/show_subcmd/basename.rb +1 -9
  105. data/processor/command/show_subcmd/confirm.rb +25 -0
  106. data/processor/command/show_subcmd/debug_subcmd/.gitignore +1 -0
  107. data/processor/command/show_subcmd/macro.rb +32 -14
  108. data/processor/command/show_subcmd/max_subcmd/.gitignore +1 -0
  109. data/processor/command/show_subcmd/trace_subcmd/.gitignore +1 -0
  110. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +11 -31
  111. data/processor/command/show_subcmd/trace_subcmd/print.rb +4 -20
  112. data/processor/command/source.rb +7 -1
  113. data/processor/command/up.rb +7 -4
  114. data/processor/default.rb +3 -1
  115. data/processor/eval.rb +13 -0
  116. data/processor/eventbuf.rb +3 -2
  117. data/processor/frame.rb +19 -0
  118. data/processor/help.rb +20 -0
  119. data/processor/load_cmds.rb +143 -24
  120. data/processor/location.rb +61 -10
  121. data/processor/main.rb +30 -11
  122. data/processor/mock.rb +5 -3
  123. data/processor/msg.rb +17 -0
  124. data/processor/running.rb +1 -1
  125. data/processor/subcmd.rb +3 -2
  126. data/processor/validate.rb +173 -185
  127. data/sample/.gitignore +1 -0
  128. data/sample/list-terminal-colors.rb +139 -0
  129. data/sample/rocky-dot-trepanrc +14 -0
  130. data/sample/rocky-trepan-colors.rb +47 -0
  131. data/test/Makefile +7 -0
  132. data/test/data/.gitignore +1 -0
  133. data/test/data/debugger-stop.cmd +3 -0
  134. data/test/data/debugger-stop.right +5 -0
  135. data/test/data/fname-with-blank.right +0 -3
  136. data/test/data/quit.right +0 -1
  137. data/test/data/quit2.cmd +6 -0
  138. data/test/data/quit2.right +3 -0
  139. data/test/data/testing.cmd +1 -0
  140. data/test/example/.gitignore +1 -0
  141. data/test/example/debugger-stop.rb +14 -0
  142. data/test/functional/.gitignore +2 -0
  143. data/test/functional/fn_helper.rb +7 -9
  144. data/test/functional/test-break-long.rb +7 -7
  145. data/test/functional/test-break.rb +7 -7
  146. data/test/functional/test-condition.rb +4 -4
  147. data/test/functional/test-delete.rb +6 -5
  148. data/test/functional/test-eval.rb +115 -0
  149. data/test/functional/test-raise.rb +1 -1
  150. data/test/functional/test-return.rb +1 -1
  151. data/test/integration/.gitignore +2 -0
  152. data/test/integration/helper.rb +6 -3
  153. data/test/integration/test-debugger-stop.rb +22 -0
  154. data/test/integration/test-quit.rb +8 -0
  155. data/test/unit/.gitignore +1 -0
  156. data/test/unit/Makefile +7 -0
  157. data/test/unit/test-app-brkpt.rb +0 -1
  158. data/test/unit/test-app-cmd_parse.rb +107 -0
  159. data/test/unit/test-app-cmd_parser.rb +22 -0
  160. data/test/unit/test-app-complete.rb +38 -0
  161. data/test/unit/test-app-condition.rb +20 -0
  162. data/test/unit/test-app-iseq.rb +31 -0
  163. data/test/unit/test-app-options.rb +9 -1
  164. data/test/unit/test-app-util.rb +0 -1
  165. data/test/unit/test-base-cmd.rb +46 -0
  166. data/test/unit/test-base-subcmd.rb +11 -2
  167. data/test/unit/test-base-submgr.rb +23 -0
  168. data/test/unit/test-base-subsubcmd.rb +20 -0
  169. data/test/unit/test-cmd-break.rb +22 -23
  170. data/test/unit/test-cmd-help.rb +4 -0
  171. data/test/unit/test-completion.rb +43 -0
  172. data/test/unit/test-io-tcpclient.rb +3 -2
  173. data/test/unit/test-proc-load_cmds.rb +10 -1
  174. data/test/unit/test-proc-location.rb +39 -0
  175. data/test/unit/test-proc-main.rb +1 -1
  176. data/test/unit/test-proc-validate.rb +47 -31
  177. data/trepanning.gemspec +45 -0
  178. metadata +247 -179
  179. data/app/core.rb-consider +0 -198
  180. data/test/functional/tmp/b3.rb +0 -5
  181. data/test/functional/tmp/immediate-bug1.rb +0 -9
@@ -1,33 +1,49 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
- require_relative '../base/subcmd'
3
+ require 'columnize'
4
4
  require 'pp'
5
+ require_relative '../base/subcmd'
6
+ require_relative '../../../app/file'
5
7
 
6
8
  class Trepan::Subcommand::InfoIseq < Trepan::Subcommand
7
9
  unless defined?(HELP)
8
10
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
- HELP =
10
- 'info iseq [METHOD|.]
11
+ HELP = <<-EOH
12
+ #{CMD} iseq [METHOD|.]
11
13
 
12
14
  Show information about an instruction sequence.
13
15
 
14
16
  Examples:
15
- info iseq
16
- info iseq .
17
- info iseq require_relative
18
- '
17
+ #{CMD}
18
+ #{CMD} .
19
+ #{CMD} *
20
+ #{CMD} require_relative
21
+ EOH
19
22
  MIN_ABBREV = 'is'.size
20
23
  NEED_STACK = true
21
24
  SHORT_HELP = 'Information about an instruction sequence'
22
25
  end
23
26
 
27
+ def iseq_list
28
+ ISEQS__.keys
29
+ end
30
+ def complete(prefix)
31
+ completions = ['.'] + iseq_list
32
+ Trepan::Complete.complete_token(completions, prefix)
33
+ end
34
+
35
+ include Trepanning
36
+
24
37
  def run(args)
25
- if 2 == args.size
26
- iseq_name = '.'
27
- else
28
- iseq_name = args[2]
29
- end
30
- if '.' == iseq_name
38
+ args << '.' if 2 == args.size
39
+ iseq_name = args[2]
40
+ if '*' == iseq_name
41
+ section 'Instruction Sequences:'
42
+ iseq_list.sort.each do |iseq|
43
+ msg "\t #{iseq}"
44
+ end
45
+ return
46
+ elsif '.' == iseq_name
31
47
  iseq = frame = @proc.frame.iseq
32
48
  elsif !(matches = find_iseqs(ISEQS__, iseq_name)).empty?
33
49
  # FIXME: do something if there is more than one
@@ -78,14 +94,20 @@ if __FILE__ == $0
78
94
 
79
95
  require_relative '../../mock'
80
96
  require_relative '../../subcmd'
81
- name = File.basename(__FILE__, '.rb')
82
97
 
83
98
  # FIXME: DRY the below code
84
99
  dbgr, cmd = MockDebugger::setup('info')
85
100
  subcommand = Trepan::Subcommand::InfoIseq.new(cmd)
86
101
  testcmdMgr = Trepan::Subcmd.new(subcommand)
87
102
 
88
- subcommand.run_show_bool
89
- name = File.basename(__FILE__, '.rb')
90
- subcommand.summary_help(name)
103
+ def five; 5; end
104
+
105
+ [%w(info iseq nothere),
106
+ %w(info file .),
107
+ %w(info file *),
108
+ ].each do |args|
109
+ subcommand.run(args)
110
+ puts '-' * 40
111
+ end
112
+ p subcommand.complete('')
91
113
  end
@@ -42,12 +42,6 @@ if __FILE__ == $0
42
42
  name = File.basename(__FILE__, '.rb')
43
43
 
44
44
  # FIXME: DRY the below code
45
- dbgr, cmd = MockDebugger::setup('info')
46
- subcommand = Trepan::Subcommand::InfoProgram.new(cmd)
47
- testcmdMgr = Trepan::Subcmd.new(subcommand)
48
-
49
- name = File.basename(__FILE__, '.rb')
50
- subcommand.run([name])
51
- subcommand.summary_help(name)
52
- puts
45
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoProgram, false)
46
+ cmd.run(cmd.prefix)
53
47
  end
@@ -6,21 +6,23 @@ require_relative '../base/subsubmgr'
6
6
  class Trepan::SubSubcommand::InfoRegisters < Trepan::SubSubcommandMgr
7
7
  unless defined?(HELP)
8
8
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
- HELP =
10
- 'List of contents for the registers of the current stack frame.
9
+ HELP = <<-EOH
10
+ #{CMD} [lfp|pc|sp]
11
+
12
+ List of contents for the registers of the current stack frame.
11
13
  If a register name given, only only that register is show.
12
14
 
13
15
  Examples:
14
- info registers # show all registers
15
- info register pc # show only the pc register
16
- info reg sp # show all stack pointer registers
17
- info reg sp 1 3 # show sp(1) and sp(3)
18
- info reg sp size # show sp size
19
- info reg lfp # show lfp(0)
20
- '
21
-
16
+ #{CMD} # show all registers
17
+ #{CMD} pc # show only the pc register
18
+ info reg sp # show all stack pointer registers
19
+ info reg sp 1 3 # show sp(1) and sp(3)
20
+ info reg sp size # show sp size
21
+ info reg lfp # show lfp(0)
22
+ EOH
22
23
  MIN_ABBREV = 'reg'.size # Note we have "info return"
23
24
  NEED_STACK = true
25
+ SHORT_HELP = 'List of register values of the current stack frame'
24
26
  end
25
27
 
26
28
  def run(args)
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative '../base/subcmd'
4
+
5
+ class Trepan::Subcommand::InfoRuby < Trepan::Subcommand
6
+ unless defined?(HELP)
7
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
8
+ HELP = <<-EOH
9
+ #{CMD}
10
+
11
+ Show Ruby version information such as you'd get from "ruby -v", which
12
+ is really just the value of RUBY_RELEASE_DATE.
13
+
14
+ See also constants: RUBY_DESCRIPTION, RUBY_VERSION, and RUBY_RELEASE_DATE."
15
+ EOH
16
+ MIN_ABBREV = 'ru'.size
17
+ NEED_STACK = false
18
+ SHORT_HELP = 'Ruby version information'
19
+ end
20
+
21
+ # def parse_options(args) # :nodoc
22
+ # options = {}
23
+ # parser = OptionParser.new do |opts|
24
+ # opts.on("-v",
25
+ # "--[no-]verbose", "show additional version information") do
26
+ # |v|
27
+ # options[:verbose] = v
28
+ # end
29
+ # end
30
+ # parser.parse(args)
31
+ # return options
32
+ # end
33
+
34
+ def run(args)
35
+ # options = parse_options(args[2..-1])
36
+ msg RUBY_DESCRIPTION
37
+ # if options[:verbose]
38
+ # msg "Options:"
39
+ # msg " Interpreter type: #{Rubinius::INTERPRETER}"
40
+ # if jit = Rubinius::JIT
41
+ # msg " JIT enabled: #{jit.join(', ')}"
42
+ # else
43
+ # msg " JIT disabled"
44
+ # end
45
+ # end
46
+ end
47
+
48
+ end
49
+
50
+ if __FILE__ == $0
51
+ # Demo it.
52
+ $0 = __FILE__ + 'notagain' # So we don't run this again
53
+ require_relative '../../mock'
54
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoRuby, false)
55
+ cmd.run(cmd.prefix)
56
+ %w(-v --verbose --no-verbose).each do |opt|
57
+ puts '-' * 10 + " #{opt}"
58
+ cmd.run(cmd.prefix + [opt])
59
+ end
60
+ end
@@ -7,7 +7,7 @@ class Trepan::Command::IRBCommand < Trepan::Command
7
7
  unless defined?(HELP)
8
8
  NAME = File.basename(__FILE__, '.rb')
9
9
  HELP = <<-HELP
10
- #{NAME} [-d]\tstarts an Interactive Ruby (IRB) session.
10
+ #{NAME} [-d]\tstarts an Interactive Ruby (IRB) session.
11
11
 
12
12
  If -d is added you can get access to debugger frame the global variables
13
13
  $trepan_frame and $trepan_cmdproc.
@@ -64,10 +64,33 @@ Here then is a loop to query VM stack values:
64
64
  $trepan_irb_statements = nil
65
65
  $trepan_command = nil
66
66
 
67
- conf = {:BACK_TRACE_LIMIT => settings[:maxstack]}
67
+ conf = {:BACK_TRACE_LIMIT => settings[:maxstack],
68
+ :RC => true}
69
+
70
+ # ?? Should we set GNU readline to what we have,
71
+ # or let IRB make its own determination?
72
+
73
+ # Save the Readline history and set the Readline completion function
74
+ # to be IRB's function
75
+ if Trepan::GNU_readline?
76
+ @proc.intf.save_history if @proc.intf.respond_to?(:save_history)
77
+ require 'irb/completion'
78
+ Readline.completion_proc = IRB::InputCompletor::CompletionProc
79
+ end
80
+
81
+ # And just when you thought, we'd never get around to
82
+ # actually running irb...
68
83
  cont = IRB.start_session(@proc.frame.binding, @proc, conf)
69
- trap('SIGINT', save_trap) # Restore old trap
84
+ trap('SIGINT', save_trap) # Restore our old interrupt function.
85
+
86
+ # Restore the debuggers' Readline history and the Readline completion
87
+ # function
88
+ if Trepan::GNU_readline? && @proc.dbgr.completion_proc
89
+ @proc.intf.read_history if @proc.intf.respond_to?(:read_history)
90
+ Readline.completion_proc = @proc.dbgr.completion_proc
91
+ end
70
92
 
93
+ # Respect any backtrace limit set in irb.
71
94
  back_trace_limit = IRB.CurrentContext.back_trace_limit
72
95
  if settings[:maxstack] != back_trace_limit
73
96
  msg("\nSetting debugger's BACK_TRACE_LIMIT (%d) to match irb's last setting (%d)" %
@@ -1,19 +1,21 @@
1
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require_relative 'base/cmd'
3
+ require_relative '../../app/complete'
3
4
  class Trepan::Command::KillCommand < Trepan::Command
4
5
 
5
6
  unless defined?(HELP)
6
7
  NAME = File.basename(__FILE__, '.rb')
7
8
  HELP = <<-HELP
8
- #{NAME} [signal-number|signal-name|unconditionally]
9
+ #{NAME} [signal-number|signal-name]
9
10
 
10
11
  Kill execution of program being debugged.
11
12
 
12
13
  Equivalent of Process.kill('KILL', Process.pid). This is an unmaskable
13
14
  signal. When all else fails, e.g. in thread code, use this.
14
15
 
15
- If 'unconditionally' is given, no questions are asked. Otherwise, if
16
- we are in interactive mode, we'll prompt to make sure.
16
+ If you are in interactive mode, you are prompted to confirm killing.
17
+ However when this command is aliased from a command ending in !, no
18
+ questions are asked.
17
19
 
18
20
  Examples:
19
21
 
@@ -22,28 +24,37 @@ Examples:
22
24
  #{NAME} KILL # same as above
23
25
  #{NAME} kill # same as above
24
26
  #{NAME} -9 # same as above
25
- #{NAME} 9 # same as above
27
+ #{NAME} 9 # same as above
28
+ #{NAME}! 9 # same as above
26
29
  HELP
27
30
 
31
+ ALIASES = %w(kill!)
28
32
  CATEGORY = 'running'
29
33
  MAX_ARGS = 1 # Need at most this many
30
34
  SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
31
35
  end
36
+
37
+ def complete(prefix)
38
+ completions = Signal.list.keys +
39
+ Signal.list.values.map{|i| i.to_s} +
40
+ Signal.list.values.map{|i| (-i).to_s}
41
+ Trepan::Complete.complete_token(completions, prefix)
42
+ end
32
43
 
33
44
  # This method runs the command
34
45
  def run(args) # :nodoc
46
+ unconditional = ('!' == args[0][-1..-1])
35
47
  if args.size > 1
36
48
  sig = Integer(args[1]) rescue args[1]
37
49
  unless sig.is_a?(Integer) || Signal.list.member?(sig.upcase)
38
50
  errmsg("Signal name '#{sig}' is not a signal I know about.\n")
39
51
  return false
40
52
  end
41
- # FIXME: reinstate
42
- # if 'KILL' == sig || Signal['KILL'] == sig
43
- # @proc.intf.finalize
44
- # end
53
+ if 'KILL' == sig || Signal['KILL'] == sig
54
+ @proc.intf.finalize
55
+ end
45
56
  else
46
- if not confirm('Really kill?', false)
57
+ if not (unconditional || confirm('Really quit?', false))
47
58
  msg('Kill not confirmed.')
48
59
  return
49
60
  else
@@ -146,7 +146,7 @@ disabled.
146
146
 
147
147
  else
148
148
  modfunc, container, first = @proc.parse_position(args[0])
149
- if first == nil and modfunc == nil
149
+ if first == nil and container == nil
150
150
  # error should have been shown previously
151
151
  return nil, nil, nil
152
152
  end
@@ -1,48 +1,63 @@
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_relative 'base/cmd'
4
4
  require_relative '../eval'
5
5
  class Trepan::Command::MacroCommand < Trepan::Command
6
6
 
7
7
  unless defined?(HELP)
8
- HELP =
9
- "macro NAME PROC-OBJECT
8
+ NAME = File.basename(__FILE__, '.rb')
9
+ HELP = <<-HELP
10
+ #{NAME} MACRO-NAME PROC-OBJECT
11
+
12
+ Define MACRO-NAME as a debugger macro. Debugger macros get a list of
13
+ arguments.
14
+
15
+ The macro should return either a String or an Array of Strings which
16
+ is substituted for the command. If the return is a String, that gets
17
+ tokenized by a simple String#split . Note that macro processing is
18
+ done right after splitting on ;; so if the macro returns a string
19
+ containing ;; this will not be handled on the string returned.
10
20
 
11
- Define NAME as a debugger macro. Debugger macros get a list of arguments
12
- and should return a command string to use in its place.
21
+ If instead, Array of Strings is returned, then the first string is
22
+ unshifted from the array and executed. The remaning strings are pushed
23
+ onto the command queue. In contrast to the first string, subsequent
24
+ strings can contain other macros, and ;; in those strings will be
25
+ split into separate commands.
13
26
 
14
- Here is a contrived example that shows how to issue 'finish' if we are in
15
- method 'gcd' and 'step' otherwise:
27
+ Here is an example. The below creates a macro called finish+ which
28
+ issues two commands 'finish' followed by 'step':
16
29
 
17
- macro step_unless_gcd Proc.new{|*args| \"$trepan_frame.method == 'gcd' ? 'finish' : 'step'\"}
30
+ macro fin+ Proc.new{|*args| %w(finish step)}
18
31
 
19
- Here is another real example. I use the following to debug a
20
- debugger command, assuming 'set debug dbgr' is set:
32
+ Here is another example using arguments. I use the following to debug
33
+ a debugger command:
21
34
 
22
- macro dbgcmd Proc.new{|*args| \"debug $trepan_cmdproc.commands['\#{args[0]}'].run(\#{args.inspect})\"}
35
+ macro dbgcmd Proc.new{|*args| ["set debug dbgr", "debug $trepan_cmdproc.commands['\#{args[0]}'].run(\#{args.inspect})"]}
23
36
 
24
- With the above, 'dbgcmd list 5' will debug the debugger 'list' command
25
- on the command 'list 5'.
37
+ With the above, 'dbgcmd list 5' will ultimately expand to:
38
+ set debug dbgr
39
+ debug $trepan_cmdproc.commands['list'].run(['5'])
40
+
41
+ and will debug the debugger's 'list' command on the command 'list 5'.
26
42
 
27
43
  See also 'show macro'.
28
- "
44
+ HELP
29
45
 
30
46
  CATEGORY = 'support'
31
47
  MIN_ARGS = 2 # Need at least this many
32
- NAME = File.basename(__FILE__, '.rb')
33
48
  SHORT_HELP = 'Define a macro'
34
49
  end
35
50
 
36
51
  def run(args)
37
- macro_name = args[1]
38
- proc_argstr = @proc.cmd_argstr[macro_name.size..-1].lstrip
39
- proc_obj = @proc.debug_eval(proc_argstr, @proc.settings[:maxstring])
52
+ cmd_name = args[1]
53
+ cmd_argstr = @proc.cmd_argstr[cmd_name.size..-1].lstrip
54
+ proc_obj = @proc.debug_eval(cmd_argstr, @proc.settings[:maxstring])
40
55
  if proc_obj
41
56
  if proc_obj.is_a?(Proc)
42
- @proc.macros[macro_name] = proc_obj
43
- msg "Macro \"#{macro_name}\" defined."
57
+ @proc.macros[cmd_name] = [proc_obj, cmd_argstr]
58
+ msg "Macro \"#{cmd_name}\" defined."
44
59
  else
45
- errmsg "Expecting a Proc object; got: #{proc_argstr}"
60
+ errmsg "Expecting a Proc object; got: #{cmd_argstr}"
46
61
  end
47
62
  end
48
63
  end
@@ -52,8 +67,7 @@ if __FILE__ == $0
52
67
  require_relative '../mock'
53
68
  dbgr, cmd = MockDebugger::setup
54
69
  cmdproc = dbgr.core.processor
55
- ["#{cmd.name} foo Proc.new{|x, y| x+y}",
56
- "#{cmd.name} bad x+1",
70
+ ["#{cmd.name} foo Proc.new{|x, y| 'x+y'}",
57
71
  "#{cmd.name} bad2 1+2"].each do |cmdline|
58
72
  args = cmdline.split
59
73
  cmd_argstr = cmdline[args[0].size..-1].lstrip
@@ -24,7 +24,7 @@ See 'set max string' to change the string truncation limit.
24
24
  end
25
25
 
26
26
  def run(args)
27
- msg @proc.debug_eval(@proc.cmd_argstr, @proc.settings[:maxstring])
27
+ @proc.eval_code(@proc.cmd_argstr, @proc.settings[:maxstring])
28
28
  end
29
29
  end
30
30
 
@@ -3,12 +3,16 @@
3
3
  require_relative 'base/submgr'
4
4
 
5
5
  class Trepan::Command::ReloadCommand < Trepan::SubcommandMgr
6
+ # Silence already initialized constant .. warnings
7
+ old_verbose = $VERBOSE
8
+ $VERBOSE = nil
6
9
  NAME = File.basename(__FILE__, '.rb')
7
10
  ALIASES = %w(rel)
8
11
  HELP = 'Reload information'
9
12
  CATEGORY = 'data'
10
13
  NEED_STACK = false
11
14
  SHORT_HELP = 'Reload information'
15
+ $VERBOSE = old_verbose
12
16
  def initialize(proc)
13
17
  super
14
18
  end