trepanning 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/ChangeLog +354 -0
  2. data/NEWS +21 -0
  3. data/Rakefile +27 -20
  4. data/app/cmd_parse.kpeg +20 -4
  5. data/app/cmd_parse.rb +11 -10
  6. data/app/cmd_parser.rb +119 -55
  7. data/app/complete.rb +1 -0
  8. data/app/core.rb +3 -3
  9. data/app/disassemble.rb +13 -3
  10. data/app/file.rb +2 -1
  11. data/app/frame.rb +3 -1
  12. data/app/mock.rb +3 -0
  13. data/app/options.rb +48 -31
  14. data/app/util.rb +50 -0
  15. data/interface/base_intf.rb +4 -0
  16. data/interface/client.rb +4 -0
  17. data/interface/script.rb +1 -1
  18. data/interface/server.rb +4 -0
  19. data/interface/user.rb +5 -0
  20. data/io/input.rb +3 -2
  21. data/io/null_output.rb +7 -1
  22. data/processor/breakpoint.rb +3 -2
  23. data/processor/command/base/subcmd.rb +1 -1
  24. data/processor/command/base/submgr.rb +4 -1
  25. data/processor/command/base/subsubcmd.rb +2 -2
  26. data/processor/command/base/subsubmgr.rb +1 -1
  27. data/processor/command/break.rb +7 -3
  28. data/processor/command/complete.rb +1 -0
  29. data/processor/command/continue.rb +1 -1
  30. data/processor/command/disassemble.rb +1 -1
  31. data/processor/command/edit.rb +35 -14
  32. data/processor/command/enable.rb +5 -3
  33. data/processor/command/eval.rb +35 -14
  34. data/processor/command/exit.rb +2 -0
  35. data/processor/command/help.rb +0 -9
  36. data/processor/command/help/command.txt +37 -27
  37. data/processor/command/help/examples.txt +16 -0
  38. data/processor/command/help/suffixes.txt +17 -0
  39. data/processor/command/info.rb +1 -1
  40. data/processor/command/info_subcmd/args.rb +7 -13
  41. data/processor/command/info_subcmd/breakpoints.rb +8 -2
  42. data/processor/command/info_subcmd/frame.rb +2 -0
  43. data/processor/command/info_subcmd/globals.rb +63 -0
  44. data/processor/command/info_subcmd/iseq.rb +3 -1
  45. data/processor/command/info_subcmd/locals.rb +16 -15
  46. data/processor/command/{show_subcmd → info_subcmd}/macro.rb +7 -7
  47. data/processor/command/info_subcmd/program.rb +2 -0
  48. data/processor/command/info_subcmd/registers.rb +5 -1
  49. data/processor/command/info_subcmd/registers_subcmd/dfp.rb +2 -3
  50. data/processor/command/info_subcmd/registers_subcmd/helper.rb +8 -9
  51. data/processor/command/info_subcmd/registers_subcmd/lfp.rb +10 -5
  52. data/processor/command/info_subcmd/registers_subcmd/pc.rb +9 -4
  53. data/processor/command/info_subcmd/registers_subcmd/sp.rb +4 -5
  54. data/processor/command/info_subcmd/ruby.rb +3 -1
  55. data/processor/command/info_subcmd/source.rb +78 -0
  56. data/processor/command/info_subcmd/stack.rb +23 -0
  57. data/processor/command/kill.rb +4 -6
  58. data/processor/command/list.rb +118 -120
  59. data/processor/command/macro.rb +1 -1
  60. data/processor/command/parsetree.rb +56 -0
  61. data/processor/command/pp.rb +40 -0
  62. data/processor/command/pr.rb +1 -2
  63. data/processor/command/quit.rb +2 -1
  64. data/processor/command/set_subcmd/abbrev.rb +24 -0
  65. data/processor/command/set_subcmd/auto_subcmd/eval.rb +1 -2
  66. data/processor/command/set_subcmd/auto_subcmd/irb.rb +2 -3
  67. data/processor/command/set_subcmd/auto_subcmd/list.rb +2 -3
  68. data/processor/command/set_subcmd/highlight.rb +8 -2
  69. data/processor/command/set_subcmd/reload.rb +41 -0
  70. data/processor/command/set_subcmd/timer.rb +8 -18
  71. data/processor/command/set_subcmd/trace.rb +2 -2
  72. data/processor/command/set_subcmd/trace_subcmd/buffer.rb +2 -2
  73. data/processor/command/set_subcmd/trace_subcmd/print.rb +3 -3
  74. data/processor/command/{irb.rb → shell.rb} +9 -6
  75. data/processor/command/show_subcmd/abbrev.rb +19 -0
  76. data/processor/command/show_subcmd/directories.rb +21 -0
  77. data/processor/command/show_subcmd/hidelevel.rb +1 -1
  78. data/processor/command/show_subcmd/highlight.rb +2 -1
  79. data/processor/command/show_subcmd/reload.rb +17 -0
  80. data/processor/command/show_subcmd/timer.rb +17 -0
  81. data/processor/command/show_subcmd/trace_subcmd/buffer.rb +1 -1
  82. data/processor/command/source.rb +15 -14
  83. data/processor/command/tbreak.rb +20 -0
  84. data/processor/command/watchg.rb +114 -0
  85. data/processor/default.rb +43 -41
  86. data/processor/display.rb +3 -2
  87. data/processor/eval.rb +5 -3
  88. data/processor/eventbuf.rb +3 -2
  89. data/processor/frame.rb +12 -3
  90. data/processor/hook.rb +3 -2
  91. data/processor/load_cmds.rb +186 -179
  92. data/processor/location.rb +154 -159
  93. data/processor/main.rb +44 -16
  94. data/processor/mock.rb +0 -11
  95. data/processor/msg.rb +3 -1
  96. data/processor/running.rb +3 -2
  97. data/processor/validate.rb +25 -4
  98. data/processor/virtual.rb +32 -0
  99. data/test/data/debugger-stop.right +1 -0
  100. data/test/data/fname-with-blank.right +1 -0
  101. data/test/example/gcd.rb +1 -0
  102. data/test/functional/{test-trace-var.rb → test-watchg.rb} +15 -4
  103. data/test/unit/cmd-helper.rb +0 -3
  104. data/test/unit/test-app-cmd_parser.rb +2 -2
  105. data/test/unit/test-app-file.rb +1 -0
  106. data/test/unit/test-app-frame.rb +1 -1
  107. data/test/unit/test-app-util.rb +21 -0
  108. data/test/unit/test-base-cmd.rb +4 -6
  109. data/test/unit/test-base-subcmd.rb +1 -4
  110. data/test/unit/test-base-submgr.rb +1 -2
  111. data/test/unit/test-base-subsubcmd.rb +0 -4
  112. data/test/unit/test-cmd-edit.rb +33 -0
  113. data/test/unit/test-cmd-parse_list_cmd.rb +33 -0
  114. data/test/unit/test-completion.rb +1 -1
  115. data/test/unit/test-proc-frame.rb +4 -1
  116. data/test/unit/test-proc-load_cmds.rb +2 -1
  117. data/test/unit/test-proc-location.rb +9 -26
  118. data/test/unit/test-proc-main.rb +1 -4
  119. data/test/unit/test-proc-validate.rb +28 -18
  120. data/test/unit/test-subcmd-help.rb +0 -4
  121. data/trepanning.gemspec +1 -1
  122. metadata +27 -10
  123. data/processor/command/set_subcmd/trace_subcmd/var.rb +0 -57
@@ -12,10 +12,12 @@ class Trepan::Command::EnableCommand < Trepan::Command::DisableCommand
12
12
  $VERBOSE = nil
13
13
  NAME = File.basename(__FILE__, '.rb')
14
14
  HELP = <<-HELP
15
- #{NAME} [display] bpnumber [bpnumber ...]
15
+ #{NAME} [display] BPNUM1 [BPNUM2 ...]
16
16
 
17
- Enables the breakpoints given as a space separated list of breakpoint
18
- numbers. See also "info break" to get a list.
17
+ Enables breakpoints BPNUM1. Breakpoints numbers are given as a space-
18
+ separated list numbers.
19
+
20
+ See also "info break" to get a list of breakpoints.
19
21
  HELP
20
22
 
21
23
  ALIASES = %w(en)
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require_relative './base/cmd'
4
+ require_relative '../../app/util'
4
5
 
5
6
  class Trepan::Command::EvalCommand < Trepan::Command
6
7
 
@@ -16,10 +17,22 @@ The value of the expression is stored into a global variable so it
16
17
  may be used again easily. The name of the global variable is printed
17
18
  next to the inspect output of the value.
18
19
 
19
- If no string is given we run the string from the current source code
20
+ If no string is given, we run the string from the current source code
20
21
  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.
22
+ given we will the following translations occur:
23
+
24
+ {if|elsif|unless} expr [then] => expr
25
+ {until|while} expr [do] => expr
26
+ return expr => expr
27
+ case expr => expr
28
+ def fn(params) => [params]
29
+ var = expr => expr
30
+
31
+ The above is done via regular expression. No fancy parsing is done, say,
32
+ to look to see if expr is split across a line or whether var an assigment
33
+ might have multiple variables on the left-hand side.
34
+
35
+ Examples:
23
36
 
24
37
  #{NAME} 1+2 # 3
25
38
  #{NAME} @v
@@ -37,21 +50,23 @@ See 'set buffer trace' for showing what may have already been run.
37
50
  SHORT_HELP = 'Run code in the current context'
38
51
  $VERBOSE = old_verbose
39
52
 
53
+ def complete(prefix)
54
+ if prefix.empty?
55
+ if @proc.leading_str.start_with?('eval?')
56
+ Trepan::Util.extract_expression @proc.current_source_text
57
+ else
58
+ @proc.current_source_text
59
+ end
60
+ else
61
+ prefix
62
+ end
63
+ end
64
+
40
65
  def run(args)
41
66
  if args.size == 1
42
67
  text = @proc.current_source_text
43
68
  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
69
+ text = Trepan::Util::extract_expression(text)
55
70
  msg "eval: #{text}"
56
71
  end
57
72
  else
@@ -67,4 +82,10 @@ if __FILE__ == $0
67
82
  arg_str = '1 + 2'
68
83
  cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
69
84
  puts "eval #{arg_str} is: #{cmd.run([cmd.name, arg_str])}"
85
+ arg_str = 'return "foo"'
86
+ # def cmd.proc.current_source_text
87
+ # 'return "foo"'
88
+ # end
89
+ # cmd.proc.instance_variable_set('@cmd_argstr', arg_str)
90
+ # puts "eval? #{arg_str} is: #{cmd.run([cmd.name + '?'])}"
70
91
  end
@@ -53,6 +53,8 @@ end
53
53
  if __FILE__ == $0
54
54
  require_relative '../mock'
55
55
  dbgr, cmd = MockDebugger::setup
56
+ puts "before #{cmd.name}"
56
57
  fork { cmd.run([cmd.name]) }
58
+ puts "before #{cmd.name} 10"
57
59
  cmd.run([cmd.name, '10'])
58
60
  end
@@ -44,15 +44,6 @@ See also 'examine' and 'whatis'.
44
44
  HELP_DIR = File.join(ROOT_DIR, 'help')
45
45
  end
46
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
47
  def complete(prefix)
57
48
  matches = Trepan::Complete.complete_token(CATEGORIES.keys + %w(* all) +
58
49
  @proc.commands.keys, prefix)
@@ -1,11 +1,11 @@
1
- overall debugger command syntax
1
+ Overall Debugger Command Syntax
2
2
 
3
- Command tokenization syntax is very simple-minded.
3
+ If the first non-blank character of a line starts with #,
4
+ the command is ignored.
4
5
 
5
- If a line starts with #, the command is ignored.
6
- If a line starts with !, the line is eval'd.
6
+ If a line starts with ! in column one, the line is eval'd.
7
7
 
8
- If the command you want eval'd uses the Ruby ! initially, add that
8
+ If the command you want Ruby to eval uses ! initially, add that
9
9
  after the first ! or start the line with a space.
10
10
 
11
11
  Commands are split at whereever ;; appears. This process disregards
@@ -18,31 +18,41 @@ Some commands like 'eval', 'macro', and 'break' have access to the
18
18
  untokenized string entered and make use of that rather than the
19
19
  tokenized list.
20
20
 
21
- The leading token is first looked up in the macro table. If it is in
22
- the table, the expansion is replaces the current command and possibly
23
- other commands pushed onto a command queue. Next, the leading token is
24
- looked up in the debugger alias table and the name may be substituted
25
- there. Finally, the leading token is looked up in the debugger alias
26
- table. If a match is found, the command name and arguments are
27
- dispatched to the command object that process the command.
21
+ Resolving a command name involves possibly 4 steps. Some steps may be
22
+ omitted depending on early success or some debugger settings:
28
23
 
29
- If the command is not found and "auto eval" is set on, then the
30
- command is eval'd in the context that the program is currently stopped
31
- at. If "auto eval" is not set on, then we display an error message
32
- that the entered string is "undefined".
24
+ 1. The leading token is first looked up in the macro table. If it is in
25
+ the table, the expansion is replaces the current command and possibly
26
+ other commands pushed onto a command queue. See the "help macros" for
27
+ help on how to define macros, and "info macro" for current macro
28
+ definitions.
29
+
30
+ 2. The leading token is next looked up in the debugger alias table and
31
+ the name may be substituted there. See "help alias" for how to define
32
+ aliases, and "show alias" for the current list of aliases.
33
+
34
+ 3. After the above, The leading token is looked up a table of debugger
35
+ commands. If an exact match is found, the command name and arguments
36
+ are dispatched to that command. Otherwise, we may check to see the the
37
+ token is a unique prefix of a valid command. For example, "dis" is not
38
+ a unique prefix because there are both "display" and "disable"
39
+ commands, but "disp" is a unique prefix. You can allow or disallow
40
+ abbreviations for commands using "set abbrev". The default is
41
+ abbreviations are on.
42
+
43
+ 4. If after all of the above, we still don't find a command, the line
44
+ may be evaluated as a Ruby statement in the current context of the
45
+ program at the point it is stoppped. However this is done only if
46
+ "autoeval" is on. (It is on by default.)
47
+
48
+ If "auto eval" is not set on, or if running the Ruby statement
49
+ produces an error, we display an error message that the entered string
50
+ is "undefined".
33
51
 
34
52
  If you want irb-like command-processing, it's possible to go into an
35
53
  irb shell with the "irb" command. It is also possible to arrange going
36
54
  into an irb shell every time you enter the debugger.
37
55
 
38
- Examples:
39
-
40
- # This line does nothing. It is a comment
41
- s # by default, this is an alias for the "step" command
42
- !s # shows the value of variable step.
43
- !!s # Evaluates !s (or "not s"). The first ! is indicates evaluate.
44
- info program;; list # Runs two commands "info program" and "list"
45
- pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
46
- !puts "hi ;;-)" # One way to do the above.
47
-
48
- See also "alias", "irb", "set auto eval", and "set auto irb".
56
+ See also:
57
+ "help syntax examples"
58
+ "help syntax suffix"
@@ -0,0 +1,16 @@
1
+ Command examples
2
+
3
+ # This line does nothing. It is a comment. Useful in debugger command files.
4
+ # This line also does nothing.
5
+ s # by default, this is an alias for the "step" command
6
+ !s # shows the value of variable "s".
7
+ !!s # Evaluates "!s" (or "not s"). The first ! is indicates evaluate.
8
+ !s # Same as above, since there is a space in column one.
9
+
10
+ info program;; list # Runs two commands "info program" and "list"
11
+ pr "hi ;;-)" # Syntax error since ;; splits the line and " is not closed.
12
+ !puts "hi ;;-)" # One way to do the above.
13
+
14
+ See also "macro" "alias", "irb", "set auto eval", "set auto irb", "set
15
+ abbrev", "info macro", and "show" variants of the above "set"
16
+ commands.
@@ -0,0 +1,17 @@
1
+ Command suffixes which have special meaning
2
+
3
+ Some commands like "step", or "list" do different things when an
4
+ alias to the command ends in a particular suffix like ">".
5
+
6
+ Here are a list of commands and the special suffixes:
7
+
8
+ command suffix
9
+ ------- ------
10
+ list >
11
+ step +,-,<,>
12
+ next +,-,<,>
13
+ quit !
14
+ kill !
15
+ eval ?
16
+
17
+ See help on the commands listed above for the specific meaning of the suffix.
@@ -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/submgr'
4
4
 
5
5
  class Trepan::Command::InfoCommand < Trepan::SubcommandMgr
@@ -8,10 +8,11 @@ class Trepan::Subcommand::InfoArgs < Trepan::Subcommand
8
8
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
9
  HELP = 'Show argument variables of the current stack frame'
10
10
  MIN_ABBREV = 'ar'.size
11
+ MIN_ARGS = 0
12
+ MAX_ARGS = 0
11
13
  NEED_STACK = true
12
14
  end
13
15
 
14
- include Trepan::Frame
15
16
  def run(args)
16
17
  if 'CFUNC' == @proc.frame.type
17
18
  argc = @proc.frame.argc
@@ -23,12 +24,13 @@ class Trepan::Subcommand::InfoArgs < Trepan::Subcommand
23
24
  msg("No parameters in C call.")
24
25
  end
25
26
  else
26
- param_names = all_param_names(@proc.frame.iseq, false)
27
+ param_names = Trepan::Frame::all_param_names(@proc.frame.iseq, false)
27
28
  if param_names.empty?
28
29
  msg("No parameters in call.")
29
30
  else
30
31
  param_names.each_with_index do |var_name, i|
31
- var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
32
+ var_value =
33
+ @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
32
34
  msg("#{var_name} = #{var_value}")
33
35
  end
34
36
  unless 'call' == @proc.event and 0 == @proc.frame_index
@@ -42,14 +44,6 @@ end
42
44
  if __FILE__ == $0
43
45
  # Demo it.
44
46
  require_relative '../../mock'
45
- require_relative '../../subcmd'
46
- name = File.basename(__FILE__, '.rb')
47
-
48
- # FIXME: DRY the below code
49
- dbgr, cmd = MockDebugger::setup('info')
50
- subcommand = Trepan::Subcommand::InfoArgs.new(cmd)
51
- testcmdMgr = Trepan::Subcmd.new(subcommand)
52
-
53
- name = File.basename(__FILE__, '.rb')
54
- subcommand.summary_help(name)
47
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoArgs, false)
48
+ cmd.run(cmd.prefix)
55
49
  end
@@ -6,7 +6,7 @@ class Trepan::Subcommand::InfoBreakpoints < Trepan::Subcommand
6
6
  unless defined?(HELP)
7
7
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
8
8
  HELP = <<-EOH
9
- #{PREFIX.join(' ')} [num1 ...] [verbose]
9
+ #{CMD} [num1 ...] [verbose]
10
10
 
11
11
  Show status of user-settable breakpoints. If no breakpoint numbers are
12
12
  given, the show all breakpoints. Otherwise only those breakpoints
@@ -90,7 +90,7 @@ EOH
90
90
  if args.size > 2
91
91
  opts = {
92
92
  :msg_on_error =>
93
- "An '#{PREFIX.join(' ')}' argument must eval to a breakpoint between 1..#{@proc.brkpts.max}.",
93
+ "An '#{CMD}' argument must eval to a breakpoint between 1..#{@proc.brkpts.max}.",
94
94
  :min_value => 1,
95
95
  :max_value => @proc.brkpts.max
96
96
  }
@@ -124,6 +124,12 @@ EOH
124
124
  notfound.empty?
125
125
  end
126
126
  end
127
+ if @proc.traced_vars.empty?
128
+ msg('No traced variables.')
129
+ else
130
+ section 'Traced Variables'
131
+ msg columnize_commands(@proc.traced_vars.keys.sort)
132
+ end
127
133
  end
128
134
 
129
135
  end
@@ -34,6 +34,8 @@ Frame basename
34
34
  See also: backtrace
35
35
  EOH
36
36
  MIN_ABBREV = 'fr'.size # Note we have "info file"
37
+ MIN_ARGS = 0
38
+ MAX_ARGS = 0
37
39
  NEED_STACK = true
38
40
  SHORT_HELP = 'Show information about the selected frame'
39
41
  end
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'columnize'
4
+ require_relative '../base/subcmd'
5
+ require_relative '../../../app/frame'
6
+
7
+ class Trepan::Subcommand::InfoGlobals < Trepan::Subcommand
8
+ unless defined?(HELP)
9
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
10
+ HELP = <<-EOH
11
+ #{CMD}
12
+ #{CMD} [names]
13
+
14
+ Show global variables.
15
+ Normally for each which show both the name and value. If you just
16
+ want a list of names add parameter 'names'.
17
+ EOH
18
+ SHORT_HELP = 'Show global variables'
19
+ MIN_ARGS = 0
20
+ MAX_ARGS = 1
21
+ MIN_ABBREV = 'gl'.size
22
+ NEED_STACK = true
23
+ end
24
+
25
+ def run(args)
26
+ if args.size == 3
27
+ if 0 == 'names'.index(args[-1].downcase)
28
+ if global_variables.empty?
29
+ msg "No global variables defined."
30
+ else
31
+ section "Global variable names:"
32
+ width = settings[:maxwidth]
33
+ mess = Columnize::columnize(global_variables.sort,
34
+ @proc.settings[:maxwidth], ' ',
35
+ false, true, ' ' * 2).chomp
36
+ msg mess
37
+ end
38
+ else
39
+ errmsg("unrecognized argument #{args[2]}")
40
+ end
41
+ elsif args.size == 2
42
+ if global_variables.empty?
43
+ msg "No global variables defined."
44
+ else
45
+ section "Global variables:"
46
+ global_variables.sort.each do |var_name|
47
+ s = @proc.debug_eval(var_name)
48
+ msg("#{var_name} = #{s.inspect}")
49
+ end
50
+ end
51
+ else
52
+ errmsg("Wrong number of arguments #{args.size}")
53
+ end
54
+ end
55
+ end
56
+
57
+ if __FILE__ == $0
58
+ # Demo it.
59
+ require_relative '../../mock'
60
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoGlobals, false)
61
+ cmd.run(cmd.prefix)
62
+ cmd.run(cmd.prefix + ['name'])
63
+ end
@@ -9,7 +9,7 @@ class Trepan::Subcommand::InfoIseq < Trepan::Subcommand
9
9
  unless defined?(HELP)
10
10
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
11
11
  HELP = <<-EOH
12
- #{CMD} iseq [METHOD|.]
12
+ #{CMD} [METHOD|.]
13
13
 
14
14
  Show information about an instruction sequence.
15
15
 
@@ -20,6 +20,8 @@ Examples:
20
20
  #{CMD} require_relative
21
21
  EOH
22
22
  MIN_ABBREV = 'is'.size
23
+ MIN_ARGS = 0
24
+ MAX_ARGS = 1
23
25
  NEED_STACK = true
24
26
  SHORT_HELP = 'Information about an instruction sequence'
25
27
  end
@@ -7,13 +7,21 @@ require_relative '../../../app/frame'
7
7
  class Trepan::Subcommand::InfoLocals < Trepan::Subcommand
8
8
  unless defined?(HELP)
9
9
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
10
- HELP = 'Show local variables of the current stack frame'
10
+ HELP = <<-EOH
11
+ #{CMD}
12
+ #{CMD} [names]
13
+
14
+ Show local variables including parameters of the current stack frame.
15
+ Normally for each which show both the name and value. If you just
16
+ want a list of names add parameter 'names'.
17
+ EOH
18
+ SHORT_HELP = 'Show local variables of the current stack frame'
19
+ MIN_ARGS = 0
11
20
  MAX_ARGS = 1
12
21
  MIN_ABBREV = 'lo'.size
13
22
  NEED_STACK = true
14
23
  end
15
24
 
16
- include Trepan::Frame
17
25
  def get_local_names
18
26
  iseq = @proc.frame.iseq
19
27
  0.upto(iseq.local_size-2).map do
@@ -32,10 +40,10 @@ class Trepan::Subcommand::InfoLocals < Trepan::Subcommand
32
40
  if local_names.empty?
33
41
  msg "No local variables defined."
34
42
  else
35
- msg "Local variable names:"
43
+ section "Local variable names:"
36
44
  width = settings[:maxwidth]
37
45
  mess = Columnize::columnize(local_names,
38
- @proc.settings[:maxwidth], ', ',
46
+ @proc.settings[:maxwidth], ' ',
39
47
  false, true, ' ' * 2).chomp
40
48
  msg mess
41
49
  end
@@ -58,7 +66,7 @@ class Trepan::Subcommand::InfoLocals < Trepan::Subcommand
58
66
  if local_names.empty?
59
67
  msg "No local variables defined."
60
68
  else
61
- msg "Local variables:"
69
+ section "Local variables:"
62
70
  get_local_names.each_with_index do |var_name, i|
63
71
  var_value = @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
64
72
  msg("#{var_name} = #{var_value}")
@@ -74,14 +82,7 @@ end
74
82
  if __FILE__ == $0
75
83
  # Demo it.
76
84
  require_relative '../../mock'
77
- require_relative '../../subcmd'
78
- name = File.basename(__FILE__, '.rb')
79
-
80
- # FIXME: DRY the below code
81
- dbgr, cmd = MockDebugger::setup('info')
82
- subcommand = Trepan::Subcommand::InfoLocals.new(cmd)
83
- testcmdMgr = Trepan::Subcmd.new(subcommand)
84
-
85
- name = File.basename(__FILE__, '.rb')
86
- subcommand.summary_help(name)
85
+ cmd = MockDebugger::sub_setup(Trepan::Subcommand::InfoLocals, false)
86
+ cmd.run(cmd.prefix)
87
+ cmd.run(cmd.prefix + ['name'])
87
88
  end