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
@@ -20,6 +20,8 @@ made unconditional.
20
20
  Examples:
21
21
  #{NAME} 5 x > 10 # Breakpoint 5 now has condition x > 10
22
22
  #{NAME} 5 # Remove above condition
23
+
24
+ See also "break", "enable" and "disable".
23
25
  HELP
24
26
 
25
27
  ALIASES = %w(cond)
@@ -1,13 +1,13 @@
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
3
  require_relative '../running'
4
4
  require_relative '../../app/breakpoint' # FIXME: possibly temporary
5
- class Trepan::Command::ContinueCommand < Trepan::Command
6
5
 
6
+ class Trepan::Command::ContinueCommand < Trepan::Command
7
7
  unless defined?(HELP)
8
- NAME = File.basename(__FILE__, '.rb')
8
+ NAME = File.basename(__FILE__, '.rb')
9
9
  HELP = <<-HELP
10
- #{NAME} [offset|line number]
10
+ #{NAME} [LOCATION]
11
11
 
12
12
  Leave the debugger loop and continue execution. Subsequent entry to
13
13
  the debugger however may occur via breakpoints or explicit calls, or
@@ -21,32 +21,29 @@ Examples:
21
21
  #{NAME}
22
22
  #{NAME} 10 # continue to line 10
23
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
26
+
27
+ See also 'step', 'next', 'finish', 'nexti' commands and "help location".
24
28
  HELP
25
29
 
26
30
  ALIASES = %w(c cont)
27
31
  CATEGORY = 'running'
28
- MAX_ARGS = 1 # Need at most this many
32
+ MAX_ARGS = 2 # Need at most this many
29
33
  NEED_RUNNING = true
30
- SHORT_HELP = 'Continue execution of debugged program'
34
+ SHORT_HELP = 'Continue execution of the debugged program'
31
35
  end
32
36
 
33
- # This method runs the command
37
+ # This is the method that runs the command
34
38
  def run(args)
35
39
  if args.size == 1
36
40
  # Form is: "continue"
37
41
  @proc.continue
38
42
  else
39
- # FIXME: handle more general condition parameter rather than just
40
- # a line number
41
- position, iseq, use_offset, condition =
42
- @proc.breakpoint_position(args[1..-1])
43
- return false unless position && iseq
44
- bp =
45
- if use_offset
46
- @proc.breakpoint_offset(position, iseq, true)
47
- else
48
- @proc.breakpoint_line(position, iseq, true)
49
- end
43
+ iseq, line_number, vm_offset, condition, negate =
44
+ @proc.breakpoint_position(@proc.cmd_argstr, false)
45
+ return false unless iseq && vm_offset
46
+ bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate)
50
47
  return unless bp
51
48
  @proc.continue
52
49
  end
@@ -35,6 +35,8 @@ Examples:
35
35
  SHORT_HELP = 'Disassemble Ruby VM instructions'
36
36
  end
37
37
 
38
+ completion %w(. full)
39
+
38
40
  # FIXME: put in processor/data.rb?
39
41
 
40
42
  def marked_disassemble(iseq_param, include_children)
@@ -99,4 +101,7 @@ if __FILE__ == $0
99
101
  end
100
102
  cmd.proc.frame_setup(RubyVM::ThreadFrame::current)
101
103
  cmd.run([cmd.name, 'p'])
104
+ puts cmd.complete('f')
105
+ require 'irb'
106
+ cmd.run([cmd.name, 'IRB.start'])
102
107
  end
@@ -1,5 +1,5 @@
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 'up'
4
4
 
5
5
  # Debugger "down" command. Is the same as the "up" command with the
@@ -0,0 +1,70 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require_relative './base/cmd'
4
+
5
+ class Trepan::Command::EvalCommand < Trepan::Command
6
+
7
+ old_verbose = $VERBOSE
8
+ $VERBOSE = nil
9
+ NAME = File.basename(__FILE__, '.rb')
10
+ HELP = <<-HELP
11
+ #{NAME} [STRING]
12
+
13
+ Run code in the context of the current frame.
14
+
15
+ The value of the expression is stored into a global variable so it
16
+ may be used again easily. The name of the global variable is printed
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. If the command ends ? (via an alias) and no string is
21
+ given we will also strip off any leading 'if', 'while', 'elseif',
22
+ 'return', 'case', 'unless', or 'until' in the string.
23
+
24
+ #{NAME} 1+2 # 3
25
+ #{NAME} @v
26
+ #{NAME} # Run current source-code line
27
+ #{NAME}? # but strips off leading 'if', 'while', ..
28
+ # from command
29
+
30
+ See also 'set autoeval'. The command helps one predict future execution.
31
+ See 'set buffer trace' for showing what may have already been run.
32
+ HELP
33
+
34
+ ALIASES = %w(eval? ev? ev)
35
+ CATEGORY = 'data'
36
+ NEED_STACK = true
37
+ SHORT_HELP = 'Run code in the current context'
38
+ $VERBOSE = old_verbose
39
+
40
+ def run(args)
41
+ if args.size == 1
42
+ text = @proc.current_source_text
43
+ if '?' == args[0][-1..-1]
44
+ if text =~ /^\s*(?:if|elsif|unless)\s+/
45
+ text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
46
+ text.gsub!(/\s+then\s*$/, '')
47
+ elsif text =~ /^\s*(?:until|while)\s+/
48
+ text.gsub!(/^\s*(?:until|while)\s+/,'')
49
+ text.gsub!(/\s+do\s*$/, '')
50
+ elsif text =~ /^\s*return\s+/
51
+ text.gsub!(/^\s*return\s+/,'')
52
+ elsif text =~ /^\s*case\s+/
53
+ text.gsub!(/^\s*case\s*/,'')
54
+ end
55
+ msg "eval: #{text}"
56
+ end
57
+ else
58
+ text = @proc.cmd_argstr
59
+ end
60
+ @proc.eval_code(text, settings[:maxstring])
61
+ end
62
+ end
63
+
64
+ if __FILE__ == $0
65
+ require_relative '../mock'
66
+ dbgr, cmd = MockDebugger::setup
67
+ arg_str = '1 + 2'
68
+ cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
69
+ puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
70
+ end
@@ -1,4 +1,4 @@
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
3
  class Trepan::Command::ExitCommand < Trepan::Command
4
4
 
@@ -43,6 +43,9 @@ See also the commands "quit" and "kill".
43
43
  exitrc = (args.size > 1) ? exitrc = Integer(args[1]) rescue 0 : 0
44
44
  # No graceful way to stop threads...
45
45
  # A little harsh, but for now let's go with this.
46
+ # FIXME: Is this the best/most general way?
47
+ @proc.finalize
48
+ @proc.dbgr.intf[-1].finalize
46
49
  exit! exitrc
47
50
  end
48
51
  end
@@ -1,5 +1,5 @@
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
 
5
5
  class Trepan::Command::FinishCommand < Trepan::Command
@@ -9,8 +9,9 @@ class Trepan::Command::FinishCommand < Trepan::Command
9
9
  HELP = <<-HELP
10
10
  #{NAME} [levels]
11
11
 
12
- Continue execution until leaving the current function.
13
- Sometimes this is called 'step out'.
12
+ Continue execution until the program is about to leaving the current
13
+ function or switch context via yielding or ending a block which was
14
+ yield to. Sometimes this is called 'step out'.
14
15
 
15
16
  When `levels' is specified, that many frame levels need to be
16
17
  popped. The default is 1. Note that 'yield' and exceptions raised my
@@ -24,6 +25,7 @@ one.
24
25
  See the break command if you want to stop at a particular point in a
25
26
  program. In general, '#{NAME}', 'step' and 'next' may slow a program down
26
27
  while 'break' will have less overhead.
28
+
27
29
  HELP
28
30
  ALIASES = %w(fin)
29
31
  CATEGORY = 'running'
@@ -54,7 +56,7 @@ while 'break' will have less overhead.
54
56
  # step 1 is core.level_count = 0 or "stop next event"
55
57
  level_count = count - 1
56
58
  end
57
- if 0 == level_count and %w(return c-return).member?(@proc.event)
59
+ if 0 == level_count and %w(return c-return yield leave).member?(@proc.event)
58
60
  errmsg "You are already at the requested return event."
59
61
  else
60
62
  @proc.finish(level_count, opts)
@@ -46,15 +46,18 @@ See also 'up', 'down' 'where' and 'info thread'.
46
46
  SHORT_HELP = 'Select and print a stack frame'
47
47
  end
48
48
 
49
+ def complete(prefix)
50
+ @proc.frame_complete(prefix, nil)
51
+ end
52
+
49
53
  # The simple case: thread frame switching has been done or is
50
54
  # not needed and we have an explicit position number as a string
51
55
  def one_arg_run(position_str)
52
- stack_size = @proc.top_frame.stack_size - @proc.hide_level
56
+ low, high = @proc.frame_low_high(nil)
53
57
  opts={
54
58
  :msg_on_error =>
55
59
  "The '#{NAME}' command requires a frame number. Got: #{position_str}",
56
- :min_value => -stack_size,
57
- :max_value => stack_size-1
60
+ :min_value => low, :max_value => high
58
61
  }
59
62
  frame_num = @proc.get_an_int(position_str, opts)
60
63
  return false unless frame_num
@@ -1,7 +1,7 @@
1
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::HelpCommand < Trepan::Command
4
-
5
5
  unless defined?(HELP)
6
6
  NAME = File.basename(__FILE__, '.rb')
7
7
  HELP = <<-HELP
@@ -32,25 +32,61 @@ See also 'examine' and 'whatis'.
32
32
  'running' => 'Running the program',
33
33
  'status' => 'Status inquiries',
34
34
  'support' => 'Support facilities',
35
- 'stack' => 'Examining the call stack'
35
+ 'stack' => 'Examining the call stack',
36
+ 'syntax' => 'Debugger command syntax'
36
37
  }
37
38
  CATEGORY = 'support'
38
39
  NEED_STACK = false
39
40
  SHORT_HELP = 'Print commands or give help for command(s)'
41
+
42
+ require 'thread_frame'
43
+ ROOT_DIR = File.dirname(RubyVM::ThreadFrame.current.source_container[1])
44
+ HELP_DIR = File.join(ROOT_DIR, 'help')
45
+ end
46
+
47
+ def complete(prefix)
48
+ matches = Trepan::Complete.complete_token(CATEGORIES.keys +
49
+ %w(* syntax all) +
50
+ @proc.commands.keys, prefix)
51
+ aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
52
+ matches)
53
+ (matches + aliases).sort
54
+ end
55
+
56
+ def complete(prefix)
57
+ matches = Trepan::Complete.complete_token(CATEGORIES.keys + %w(* all) +
58
+ @proc.commands.keys, prefix)
59
+ aliases = Trepan::Complete.complete_token_filtered(@proc.aliases, prefix,
60
+ matches)
61
+ (matches + aliases).sort
62
+ end
63
+
64
+ def complete_token_with_next(prefix)
65
+ complete(prefix).map do |cmd|
66
+ [cmd, @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil]
67
+ # complete_method =
68
+ # if 'syntax' == cmd
69
+ # Syntax.new(syntax_files)
70
+ # else
71
+ # @proc.commands.member?(cmd) ? @proc.commands[cmd] : nil
72
+ # end
73
+ # [cmd, complete_method]
74
+ end
40
75
  end
41
76
 
42
77
  # List the command categories and a short description of each.
43
78
  def list_categories
44
- section 'Classes of commands:'
79
+ section 'Help classes:'
45
80
  CATEGORIES.keys.sort.each do |cat|
46
81
  msg("%-13s -- %s" % [cat, CATEGORIES[cat]])
47
82
  end
48
83
  final_msg = '
49
- Type "help" followed by a class name for a list of commands in that class.
50
- Type "help syntax" for information on debugger command syntax.
51
- Type "help *" for the list of all commands.
84
+ Type "help" followed by a class name for a list of help items in that class.
85
+ Type "help aliases" for a list of current aliases.
86
+ Type "help macros" for a list of current macros.
87
+ Type "help *" for the list of all commands, macros and aliases.
52
88
  Type "help all" for the list of all commands.
53
- Type "help REGEXP" for the list of commands matching /^#{REGEXP}/
89
+ Type "help REGEXP" for the list of commands matching /^#{REGEXP}/.
54
90
  Type "help CLASS *" for the list of all commands in class CLASS.
55
91
  Type "help" followed by command name for full documentation.
56
92
  '
@@ -64,8 +100,14 @@ Type "help" followed by command name for full documentation.
64
100
  if cmd_name == '*'
65
101
  section 'All command names:'
66
102
  msg columnize_commands(@proc.commands.keys.sort)
103
+ show_aliases unless @proc.aliases.empty?
104
+ show_macros unless @proc.macros.empty?
105
+ elsif cmd_name =~ /^aliases$/i
106
+ show_aliases
107
+ elsif cmd_name =~ /^macros$/i
108
+ show_macros
67
109
  elsif cmd_name =~ /^syntax$/i
68
- show_command_syntax
110
+ show_command_syntax(args)
69
111
  elsif cmd_name =~ /^all$/i
70
112
  CATEGORIES.sort.each do |category|
71
113
  show_category(category[0], [])
@@ -90,6 +132,9 @@ Type "help" followed by command name for full documentation.
90
132
  msg "Aliases: #{cmd_obj.class.const_get(:ALIASES).join(', ')}"
91
133
  end
92
134
  end
135
+ elsif @proc.macros.member?(cmd_name)
136
+ msg "#{cmd_name} is a macro which expands to:"
137
+ msg " #{@proc.macros[cmd_name]}", {:unlimited => true}
93
138
  else
94
139
  matches = @proc.commands.keys.grep(/^#{cmd_name}/).sort rescue []
95
140
  if matches.empty?
@@ -104,9 +149,14 @@ Type "help" followed by command name for full documentation.
104
149
  end
105
150
  end
106
151
 
152
+ def show_aliases
153
+ section 'All alias names:'
154
+ msg columnize_commands(@proc.aliases.keys.sort)
155
+ end
156
+
107
157
  # Show short help for all commands in `category'.
108
158
  def show_category(category, args)
109
-
159
+
110
160
  if args.size == 1 && args[0] == '*'
111
161
  section "Commands in class %s:" % category
112
162
 
@@ -116,7 +166,7 @@ Type "help" followed by command name for full documentation.
116
166
  width = settings[:maxwidth]
117
167
  return columnize_commands(cmds)
118
168
  end
119
-
169
+
120
170
  msg('')
121
171
  section "Command class: %s" % category
122
172
  msg('')
@@ -125,52 +175,42 @@ Type "help" followed by command name for full documentation.
125
175
  msg("%-13s -- %s" % [name, @proc.commands[name].short_help])
126
176
  end
127
177
  end
178
+
179
+ def syntax_files
180
+ @syntax_files ||= Dir.glob(File.join(HELP_DIR, '*.txt')).map do |txt|
181
+ basename = File.basename(txt, '.txt')
182
+ end
183
+ end
184
+
185
+ def show_command_syntax(args)
186
+ if args.size == 2
187
+ @syntax_summary_help ||= {}
188
+ section "List of syntax help"
189
+ syntax_files.each do |name|
190
+ @syntax_summary_help[name] ||=
191
+ File.open(File.join(HELP_DIR, "#{name}.txt")).readline.chomp
192
+ msg " %-8s -- %s" % [name, @syntax_summary_help[name]]
193
+ end
194
+ else
195
+ args[2..-1].each do |name|
196
+ if syntax_files.member?(name)
197
+ @syntax_help ||= {}
198
+ @syntax_help[name] =
199
+ File.open(File.join(HELP_DIR, "#{name}.txt")).readlines[2..-1].join
200
+ section "Debugger syntax for a #{name}:"
201
+ msg @syntax_help[name]
202
+ else
203
+ errmsg "No syntax help for #{name}"
204
+ end
205
+ end
206
+ end
207
+ end
128
208
 
129
- def show_command_syntax
130
- section "Debugger command syntax"
131
- msg <<-EOS
132
- Command command syntax is very simple-minded.
133
-
134
- If a line starts with #, the command is ignored.
135
- If a line starts with !, the line is eval'd.
136
-
137
- If the command you want eval'd uses the Ruby ! initally, add that
138
- after the first !.
139
-
140
- Commands are split at whereever ;; appears. This process disregards
141
- any quotes or other symbols that have meaning in Ruby. The strings
142
- after the leading command string are put back on a command queue.
143
-
144
- Within a single command, tokens are then white-space split. Again,
145
- this process disregards quotes or symbols that have meaning in Ruby.
146
-
147
- The first token is then looked up in the debugger command table and
148
- then the debugger alias table. If a match is found the command name
149
- and arguments are dispatched to the command object that process the
150
- command.
151
-
152
- If the command is not found and "auto eval" is set on, then the
153
- command is eval'd in the context that the program is currently stopped
154
- at. If "auto eval" is not set on, then we display an error message
155
- that the entered string is "undefined".
156
-
157
- If you want irb-like command-processing, it's possible to go into an
158
- irb shell with the "irb" command. It is also possible to arrange going
159
- into an irb shell every time you enter the debugger.
160
-
161
- Examples:
162
-
163
- # This line does nothing. It is a comment
164
- s # by default, this is an alias for the "step" command
165
- !s # shows the value of variable step.
166
- !!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
167
- info program;; list # Runs two commands "info program" and "list"
168
- pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
169
- !puts "hi ;;-)" # One way to do the above.
170
-
171
- See also "alias", "irb", "set auto eval", and "set auto irb".
172
- EOS
209
+ def show_macros
210
+ section 'All macro names:'
211
+ msg columnize_commands(@proc.macros.keys.sort)
173
212
  end
213
+
174
214
  end
175
215
 
176
216
  if __FILE__ == $0
@@ -193,4 +233,7 @@ if __FILE__ == $0
193
233
  cmd.run %W(#{cmd.name} s.*)
194
234
  puts '=' * 40
195
235
  cmd.run %W(#{cmd.name} s<>)
236
+ puts '=' * 40
237
+ p cmd.complete('br')
238
+ p cmd.complete('un')
196
239
  end