trepanning 0.1.6 → 1.93.32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/COPYING +57 -0
  2. data/ChangeLog +585 -736
  3. data/NEWS +26 -12
  4. data/README.md +62 -0
  5. data/Rakefile +15 -9
  6. data/app/breakpoint.rb +11 -12
  7. data/app/complete.rb +14 -14
  8. data/app/core.rb +34 -30
  9. data/app/default.rb +8 -7
  10. data/app/markdown.rb +191 -0
  11. data/app/options.rb +104 -99
  12. data/app/run.rb +9 -1
  13. data/app/util.rb +7 -7
  14. data/bin/trepan +7 -7
  15. data/interface.rb +0 -4
  16. data/interface/user.rb +11 -11
  17. data/io/input.rb +13 -13
  18. data/lib/trepanning.rb +30 -29
  19. data/processor.rb +40 -40
  20. data/processor/command.rb +13 -9
  21. data/processor/command/alias.rb +21 -15
  22. data/processor/command/backtrace.rb +27 -19
  23. data/processor/command/break.rb +24 -21
  24. data/processor/command/complete.rb +5 -2
  25. data/processor/command/condition.rb +14 -9
  26. data/processor/command/debug.rb +8 -8
  27. data/processor/command/down.rb +6 -6
  28. data/processor/command/edit.rb +4 -0
  29. data/processor/command/eval.rb +2 -2
  30. data/processor/command/exit.rb +12 -9
  31. data/processor/command/finish.rb +25 -23
  32. data/processor/command/frame.rb +30 -26
  33. data/processor/command/help.rb +203 -185
  34. data/processor/command/help/{command.txt → command.md} +21 -18
  35. data/processor/command/help/examples.md +20 -0
  36. data/processor/command/help/filename.md +46 -0
  37. data/processor/command/help/location.md +34 -0
  38. data/processor/command/help/suffixes.md +19 -0
  39. data/processor/command/info.rb +6 -4
  40. data/processor/command/info_subcmd/breakpoints.rb +13 -13
  41. data/processor/command/info_subcmd/files.rb +35 -31
  42. data/processor/command/info_subcmd/frame.rb +82 -33
  43. data/processor/command/info_subcmd/macro.rb +1 -1
  44. data/processor/command/info_subcmd/program.rb +8 -5
  45. data/processor/command/info_subcmd/registers.rb +15 -13
  46. data/processor/command/kill.rb +23 -17
  47. data/processor/command/list.rb +63 -56
  48. data/processor/command/macro.rb +45 -28
  49. data/processor/command/next.rb +29 -23
  50. data/processor/command/pp.rb +11 -9
  51. data/processor/command/pr.rb +10 -8
  52. data/processor/command/ps.rb +5 -5
  53. data/processor/command/quit.rb +24 -17
  54. data/processor/command/raise.rb +6 -6
  55. data/processor/command/reload.rb +9 -2
  56. data/processor/command/reload_subcmd/command.rb +4 -4
  57. data/processor/command/restart.rb +9 -4
  58. data/processor/command/save.rb +9 -9
  59. data/processor/command/server.rb +18 -17
  60. data/processor/command/set.rb +8 -6
  61. data/processor/command/set_subcmd/confirm.rb +15 -2
  62. data/processor/command/set_subcmd/different.rb +7 -5
  63. data/processor/command/set_subcmd/highlight.rb +14 -3
  64. data/processor/command/set_subcmd/pc.rb +62 -0
  65. data/processor/command/set_subcmd/sp.rb +8 -2
  66. data/processor/command/shell.rb +25 -23
  67. data/processor/command/show.rb +9 -7
  68. data/processor/command/show_subcmd/confirm.rb +12 -1
  69. data/processor/command/show_subcmd/highlight.rb +13 -3
  70. data/processor/command/source.rb +27 -26
  71. data/processor/command/step.rb +52 -43
  72. data/processor/command/tbreak.rb +9 -4
  73. data/processor/command/unalias.rb +9 -7
  74. data/processor/command/undisplay.rb +11 -7
  75. data/processor/command/up.rb +18 -13
  76. data/processor/command/watchg.rb +20 -17
  77. data/processor/complete.rb +120 -0
  78. data/processor/default.rb +47 -43
  79. data/processor/list.rb +23 -6
  80. data/processor/load_cmds.rb +25 -105
  81. data/processor/location.rb +104 -96
  82. data/processor/mock.rb +12 -12
  83. data/processor/msg.rb +61 -52
  84. data/processor/validate.rb +36 -27
  85. data/test/data/fname-with-blank.right +0 -1
  86. data/test/data/trace-mingw.right +28 -0
  87. data/test/data/trace.right +0 -2
  88. data/test/functional/test-raise.rb +3 -0
  89. data/test/integration/helper.rb +16 -16
  90. data/test/integration/test-debugger-stop.rb +8 -2
  91. data/test/integration/test-quit.rb +16 -15
  92. data/test/integration/test-trace.rb +19 -10
  93. data/test/unit/cmd-helper.rb +4 -1
  94. data/test/unit/test-app-complete.rb +3 -1
  95. data/test/unit/test-app-options.rb +7 -1
  96. data/test/unit/test-app-run.rb +9 -1
  97. data/test/unit/test-cmd-alias.rb +1 -1
  98. data/test/unit/test-cmd-edit.rb +2 -0
  99. data/test/unit/test-cmd-help.rb +10 -5
  100. data/test/unit/test-cmd-parse_list_cmd.rb +3 -3
  101. data/test/unit/test-completion.rb +2 -2
  102. data/test/unit/test-proc-default.rb +34 -0
  103. data/trepanning.gemspec +15 -14
  104. metadata +70 -44
  105. data/README.textile +0 -50
  106. data/processor/command/help/examples.txt +0 -16
  107. data/processor/command/help/filename.txt +0 -40
  108. data/processor/command/help/location.txt +0 -37
  109. data/processor/command/help/suffixes.txt +0 -17
  110. data/processor/command/info_subcmd/registers_subcmd/dfp.rb +0 -28
  111. data/processor/command/info_subcmd/registers_subcmd/lfp.rb +0 -47
  112. data/processor/command/nocache.rb +0 -32
  113. data/processor/command/parsetree.rb +0 -56
@@ -14,7 +14,7 @@ class Trepan::Subcommand::InfoMacro < Trepan::Subcommand
14
14
  In the first form a list of the existing macro names are shown
15
15
  in column format.
16
16
 
17
- In the second form, all macro names and their definitions are show.
17
+ In the second form, all macro names and their definitions are shown.
18
18
 
19
19
  In the last form the only definitions of the given macro names is shown.
20
20
  HELP
@@ -15,18 +15,21 @@ class Trepan::Subcommand::InfoProgram < Trepan::Subcommand
15
15
  def run(args)
16
16
  frame = @proc.frame
17
17
  m = 'Program stop event: %s' % @proc.event
18
- m +=
18
+ m +=
19
19
  if frame.iseq
20
- '; PC offset %d of instruction sequence: %s' %
20
+ '; PC offset %d of instruction sequence: %s' %
21
21
  [frame.pc_offset, frame.iseq.name]
22
22
  else
23
23
  '.'
24
24
  end
25
25
  msg m
26
- if 'return' == @proc.event
27
- msg 'R=> %s' % @proc.frame.sp(1).inspect
26
+ if 'return' == @proc.event
27
+ msg 'R=> %s' % @proc.frame.sp(1).inspect
28
28
  elsif 'raise' == @proc.event
29
- msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
29
+ msg @proc.core.hook_arg.inspect if @proc.core.hook_arg
30
+ if @proc.frame.iseq.catch_table_size == 0
31
+ msg "Warning: exception raised is non-local!"
32
+ end
30
33
  end
31
34
 
32
35
  if @proc.brkpt
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require_relative '../base/subsubcmd'
4
4
  require_relative '../base/subsubmgr'
5
5
 
@@ -7,18 +7,20 @@ class Trepan::SubSubcommand::InfoRegisters < Trepan::SubSubcommandMgr
7
7
  unless defined?(HELP)
8
8
  Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
9
  HELP = <<-EOH
10
- #{CMD} [lfp|pc|sp]
10
+ **#{CMD}** [**lfp**|**pc**|**sp**]
11
11
 
12
12
  List of contents for the registers of the current stack frame.
13
13
  If a register name given, only only that register is show.
14
14
 
15
15
  Examples:
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)
16
+ ---------
17
+
18
+ #{CMD} # show all registers
19
+ #{CMD} pc # show only the pc register
20
+ info reg sp # show all stack pointer registers
21
+ info reg sp 1 3 # show sp(1) and sp(3)
22
+ info reg sp size # show sp size
23
+ info reg lfp # show lfp(0)
22
24
  EOH
23
25
  MIN_ABBREV = 'reg'.size # Note we have "info return"
24
26
  NEED_STACK = true
@@ -28,14 +30,14 @@ info reg lfp # show lfp(0)
28
30
  def run(args)
29
31
 
30
32
  args = @parent.last_args
31
- unavailable_regs =
33
+ unavailable_regs =
32
34
  if 'CFUNC' == @proc.frame.type
33
- %w(inforegisterslfp inforegisterspc)
35
+ %w(inforegisterslfp inforegisterspc)
34
36
  else
35
37
  []
36
38
  end
37
39
  all_regs = @subcmds.subcmds.keys.sort - unavailable_regs
38
-
40
+
39
41
  if args.size == 2
40
42
  # Form is: "info registers"
41
43
  all_regs.sort.each do |subcmd_name|
@@ -49,10 +51,10 @@ info reg lfp # show lfp(0)
49
51
  subcmd = @subcmds.subcmds[key_name]
50
52
  if @proc.ok_for_running(subcmd, subcmd.class.const_get('CMD'),
51
53
  remain_args.size)
52
- @subcmds.subcmds[key_name].run(remain_args)
54
+ @subcmds.subcmds[key_name].run(remain_args)
53
55
  end
54
56
  elsif unavailable_regs.member?(key_name)
55
- msg("info registers: %s can not be displayed for frame type %s." %
57
+ msg("info registers: %s can not be displayed for frame type %s." %
56
58
  [subcmd_name, @proc.frame.type])
57
59
  else
58
60
  errmsg("info registers: %s is not a valid register name" % subcmd_name)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require_relative '../command'
3
3
  require_relative '../../app/complete'
4
4
  class Trepan::Command::KillCommand < Trepan::Command
@@ -6,26 +6,32 @@ class Trepan::Command::KillCommand < Trepan::Command
6
6
  unless defined?(HELP)
7
7
  NAME = File.basename(__FILE__, '.rb')
8
8
  HELP = <<-HELP
9
- #{NAME} [signal-number|signal-name]
9
+ **#{NAME}** [signal-number|signal-name]
10
10
 
11
11
  Kill execution of program being debugged.
12
12
 
13
- Equivalent of Process.kill('KILL', Process.pid). This is an unmaskable
13
+ Equivalent of `Process.kill('KILL', Process.pid)`. This is an unmaskable
14
14
  signal. When all else fails, e.g. in thread code, use this.
15
15
 
16
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
17
+ However when this command is aliased from a command ending in "!", no
18
18
  questions are asked.
19
19
 
20
20
  Examples:
21
+ ---------
21
22
 
22
- #{NAME}
23
- #{NAME} unconditionally
24
- #{NAME} KILL # same as above
25
- #{NAME} kill # same as above
26
- #{NAME} -9 # same as above
27
- #{NAME} 9 # same as above
28
- #{NAME}! 9 # above, but unconditional
23
+ #{NAME}
24
+ #{NAME} unconditionally
25
+ #{NAME} KILL # same as above
26
+ #{NAME} kill # same as above
27
+ #{NAME} -9 # same as above
28
+ #{NAME} 9 # same as above
29
+ #{NAME}! 9 # above, but unconditional
30
+
31
+ See also:
32
+ ---------
33
+
34
+ `quit`, `exit`
29
35
  HELP
30
36
 
31
37
  ALIASES = %w(kill!)
@@ -33,15 +39,15 @@ Examples:
33
39
  MAX_ARGS = 1 # Need at most this many
34
40
  SHORT_HELP = 'Send this process a POSIX signal (default "9" is "kill -9")'
35
41
  end
36
-
42
+
37
43
  def complete(prefix)
38
44
  completions = Signal.list.keys + Signal.list.keys.map{|k| k.downcase} +
39
- Signal.list.values.map{|i| i.to_s} +
40
- Signal.list.values.map{|i| (-i).to_s} +
45
+ Signal.list.values.map{|i| i.to_s} +
46
+ Signal.list.values.map{|i| (-i).to_s} +
41
47
  ['unconditionally']
42
48
  Trepan::Complete.complete_token(completions, prefix)
43
49
  end
44
-
50
+
45
51
  # This method runs the command
46
52
  def run(args) # :nodoc
47
53
  unconditional = ('!' == args[0][-1..-1])
@@ -54,7 +60,7 @@ Examples:
54
60
  else
55
61
  if unconditional || confirm('Really quit?', false)
56
62
  sig = 'KILL'
57
- else
63
+ else
58
64
  msg('Kill not confirmed.')
59
65
  return
60
66
  end
@@ -71,7 +77,7 @@ end
71
77
  if __FILE__ == $0
72
78
  require_relative '../mock'
73
79
  dbgr, cmd = MockDebugger::setup
74
- %w(fooo 100 1 -1 HUP -9).each do |arg|
80
+ %w(fooo 100 1 -1 HUP -9).each do |arg|
75
81
  puts "#{cmd.name} #{arg}"
76
82
  cmd.run([cmd.name, arg])
77
83
  puts '=' * 40
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  # -*- coding: utf-8 -*-
3
3
  require 'linecache'
4
4
  require_relative '../command'
@@ -8,79 +8,86 @@ class Trepan::Command::ListCommand < Trepan::Command
8
8
  unless defined?(HELP)
9
9
  NAME = File.basename(__FILE__, '.rb')
10
10
  HELP = <<-HELP
11
- #{NAME}[>] [MODULE] [FIRST [NUM]]
12
- #{NAME}[>] LOCATION [NUM]
11
+ **#{NAME}[>]** [*module*] [*first* [*num*]]
12
+ **#{NAME}[>]** *location [*num*]
13
13
 
14
- #{NAME} source code.
14
+ List source code.
15
15
 
16
- Without arguments, prints lines centered around the current
17
- line. If this is the first #{NAME} command issued since the debugger
18
- command loop was entered, then the current line is the current
19
- frame. If a subsequent #{NAME} command was issued with no intervening
20
- frame changing, then that is start the line after we last one
21
- previously shown.
16
+ Without arguments, prints lines centered around the current line. If
17
+ this is the first #{NAME} command issued since the debugger command
18
+ loop was entered, then the current line is the current frame. If a
19
+ subsequent #{NAME} command was issued with no intervening frame
20
+ changing, then that is start the line after we last one previously
21
+ shown.
22
22
 
23
- If the command has a '>' suffix, then line centering is disabled and
23
+ If the command has a ">" suffix, then line centering is disabled and
24
24
  listing begins at the specificed location.
25
25
 
26
26
  The number of lines to show is controlled by the debugger "listsize"
27
27
  setting. Use 'set max list' or 'show max list' to see or set the
28
28
  value.
29
29
 
30
- \"#{NAME} -\" shows lines before a previous listing.
30
+ \"#{NAME} -\" shows lines before a previous listing.
31
31
 
32
- A LOCATION is a either
33
- - number, e.g. 5,
34
- - a function, e.g. join or os.path.join
35
- - a module, e.g. os or os.path
36
- - a filename, colon, and a number, e.g. foo.rb:5,
37
- - or a module name and a number, e.g,. os.path:5.
38
- - a '.' for the current line number
39
- - a '-' for the lines before the current line number
32
+ A *location* is a either:
33
+
34
+ * number, e.g. 5,
35
+ * a function, e.g. *join* or *os.path.join*
36
+ * a module, e.g. *os* or *os.path*
37
+ * a filename, colon, and a number, e.g. *foo.rb:5*,
38
+ * or a module name and a number, e.g,. *os.path:5*.
39
+ * a "." for the current line number
40
+ * a "-" for the lines before the current line number
40
41
 
41
42
  If the location form is used with a subsequent parameter, the
42
43
  parameter is the starting line number. When there two numbers are
43
44
  given, the last number value is treated as a stopping line unless it
44
45
  is positive and less than the start line. In this case, it is taken to
45
- mean the number of lines to list instead. If last is negative, we start
46
- that many lines back from first and list to first.
46
+ mean the number of lines to list instead. If last is negative, we
47
+ start that many lines back from first and list to first.
47
48
 
48
- Wherever a number is expected, it does not need to be a constant --
49
+ Wherever a number is expected, it does not need to be a constant,
49
50
  just something that evaluates to a positive integer.
50
51
 
51
- Some examples:
52
-
53
- #{NAME} 5 # List centered around line 5
54
- #{NAME} @5 # List lines centered around bytecode offset 5.
55
- #{NAME} 5> # List starting at line 5
56
- #{NAME} foo.rb:5 # List centered around line 5 of foo.rb
57
- #{NAME} foo.rb 5 # Same as above.
58
- #{NAME}> foo.rb:5 # List starting around line 5 of foo.rb
59
- #{NAME} foo.rb 5 6 # list lines 5 and 6 of foo.rb
60
- #{NAME} foo.rb 5 2 # Same as above, since 2 < 5.
61
- #{NAME} foo.rb:5 2 # Same as above
62
- #{NAME} foo.rb 15 -5 # List lines 10..15 of foo
63
- #{NAME} FileUtils.cp # List lines around the FileUtils.cp function.
64
- #{NAME} . # List lines centered from where we currently are stopped
65
- #{NAME} . 3 # List 3 lines starting from where we currently are stopped
66
- # if . > 3. Otherwise we list from . to 3.
67
- #{NAME} - # List lines previous to those just shown
52
+ Examples:
53
+ ---------
54
+
55
+ #{NAME} 5 # List centered around line 5
56
+ #{NAME} @5 # List lines centered around bytecode offset 5.
57
+ #{NAME} 5> # List starting at line 5
58
+ #{NAME} foo.rb:5 # List centered around line 5 of foo.rb
59
+ #{NAME} foo.rb 5 # Same as above.
60
+ #{NAME}> foo.rb:5 # List starting around line 5 of foo.rb
61
+ #{NAME} foo.rb 5 6 # list lines 5 and 6 of foo.rb
62
+ #{NAME} foo.rb 5 2 # Same as above, since 2 < 5.
63
+ #{NAME} foo.rb:5 2 # Same as above
64
+ #{NAME} foo.rb 15 -5 # List lines 10..15 of foo
65
+ #{NAME} FileUtils.cp # List lines around the FileUtils.cp function.
66
+ #{NAME} . # List lines centered from where we currently are stopped
67
+ #{NAME} . 3 # List 3 lines starting from where we currently are stopped
68
+ # if . > 3. Otherwise we list from . to 3.
69
+ #{NAME} - # List lines previous to those just shown
68
70
 
69
71
  The output of the #{NAME} command gives a line number, and some status
70
- information about the line and the text of the line. Here is some
72
+ information about the line and the text of the line. Here is some
71
73
  hypothetical #{NAME} output modeled roughly around line 251 of one
72
74
  version of this code:
73
75
 
74
- 251 cmd.proc.frame_setup(tf)
75
- 252 -> brkpt_cmd.run(['break'])
76
- 253 B01 line = __LINE__
77
- 254 b02 cmd.run(['list', __LINE__.to_s])
78
- 255 t03 puts '--' * 10
76
+ 251 cmd.proc.frame_setup(tf)
77
+ 252 -> brkpt_cmd.run(['break'])
78
+ 253 B01 line = __LINE__
79
+ 254 b02 cmd.run(['list', __LINE__.to_s])
80
+ 255 t03 puts '--' * 10
79
81
 
80
82
  Line 251 has nothing special about it. Line 252 is where we are
81
83
  currently stopped. On line 253 there is a breakpoint 1 which is
82
84
  enabled, while at line 255 there is an breakpoint 2 which is
83
85
  disabled.
86
+
87
+ See also:
88
+ ---------
89
+
90
+ `set max list`, `show max list`, `disassemble`, `help syntax location`
84
91
  HELP
85
92
 
86
93
  ALIASES = %W(l #{NAME}> l> cat)
@@ -95,14 +102,14 @@ disabled.
95
102
  return
96
103
  end
97
104
  listsize = settings[:maxlist]
98
- center_correction =
105
+ center_correction =
99
106
  if args[0][-1..-1] == '>'
100
107
  0
101
108
  else
102
109
  (listsize-1) / 2
103
110
  end
104
111
 
105
- iseq, filename, first, last =
112
+ iseq, filename, first, last =
106
113
  @proc.parse_list_cmd(@proc.cmd_argstr, listsize, center_correction)
107
114
  return unless filename
108
115
  container = iseq ? iseq.source_container : ['file', filename]
@@ -110,7 +117,7 @@ disabled.
110
117
 
111
118
  # We now have range information. Do the listing.
112
119
  max_line = LineCache::size(filename)
113
- unless max_line
120
+ unless max_line
114
121
  errmsg('File "%s" not found.' % filename)
115
122
  return
116
123
  end
@@ -140,14 +147,14 @@ disabled.
140
147
  end
141
148
  line.chomp!
142
149
  s = '%3d' % lineno
143
- s = s + ' ' if s.size < 4
150
+ s = s + ' ' if s.size < 4
144
151
  s += if breaklist.member?(lineno)
145
152
  bp = breaklist[lineno]
146
153
  a_pad = '%02d' % bp.id
147
154
  bp.icon_char
148
- else
155
+ else
149
156
  a_pad = ' '
150
- ' '
157
+ ' '
151
158
  end
152
159
  s += (frame && lineno == @proc.frame_line &&
153
160
  filename == frame.source_container[1]) ? '->' : a_pad
@@ -164,7 +171,7 @@ if __FILE__ == $0
164
171
  if !(ARGV.size == 1 && ARGV[0] == 'noload')
165
172
  ARGV[0..-1] = ['noload']
166
173
  load(__FILE__)
167
- else
174
+ else
168
175
  require_relative '../location'
169
176
  require_relative '../mock'
170
177
  require_relative '../frame'
@@ -185,7 +192,7 @@ if __FILE__ == $0
185
192
  puts "%s %s %s" % [seps, args.join(' '), seps]
186
193
  run_cmd(cmd,args)
187
194
  end
188
-
195
+
189
196
 
190
197
  load 'tmpdir.rb'
191
198
  run_cmd2(cmd, %w(list tmpdir.rb 10))
@@ -204,7 +211,7 @@ if __FILE__ == $0
204
211
  run_cmd2(cmd, %w(list 3000))
205
212
  run_cmd2(cmd, %w(list run_cmd2))
206
213
 
207
- p = Proc.new do
214
+ p = Proc.new do
208
215
  |x,y| x + y
209
216
  end
210
217
  require 'thread_frame'
@@ -221,7 +228,7 @@ if __FILE__ == $0
221
228
  # Start line and count, since 3 < 30
222
229
  run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 30 3))
223
230
 
224
- # Start line finish line
231
+ # Start line finish line
225
232
  run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 40 50))
226
233
 
227
234
  # puts '--' * 10
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ # Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
3
3
  require_relative '../command'
4
4
  require_relative '../eval'
5
5
  class Trepan::Command::MacroCommand < Trepan::Command
@@ -7,65 +7,82 @@ class Trepan::Command::MacroCommand < Trepan::Command
7
7
  unless defined?(HELP)
8
8
  NAME = File.basename(__FILE__, '.rb')
9
9
  HELP = <<-HELP
10
- #{NAME} MACRO-NAME PROC-OBJECT
10
+ **#{NAME}** *macro-name* *Proc-object*
11
11
 
12
- Define MACRO-NAME as a debugger macro. Debugger macros get a list of
13
- arguments. Debugger macros get a list of arguments which you supply
14
- without parenthesis or commas. See below for an example.
12
+ Define *macro-name* as a debugger macro. Debugger macros get a list of
13
+ arguments which you supply without parenthesis or commas. See below
14
+ for an example.
15
15
 
16
- The macro (really a Ruby Proc) should return either a String or an
17
- Array of Strings. The string in both cases are strings of debugger
18
- commands. If the return is a String, that gets tokenized by a simple
19
- String#split . Note that macro processing is done right after
20
- splitting on ;; so if the macro returns a string containing ;; this
21
- will not be handled on the string returned.
16
+ The macro (really a Ruby *Proc()*) should return either a *String* or
17
+ an *Array* of *Strings*. Each component string in either case
18
+ refers to a debugger command.
22
19
 
23
- If instead, Array of Strings is returned, then the first string is
20
+ If the return is a *String*, that gets tokenized by a simple
21
+ *String#split*. Note that macro processing is done right after
22
+ splitting on `;;` so if the macro returns a string containing `;;`
23
+ this will not be handled on the string returned.
24
+
25
+ Here is a simple macro using a string:
26
+
27
+ macro resize Proc.new{"set max width"}
28
+
29
+ We have to use a macro here rather than an *alias*, because the
30
+ expansion is more than to a command name, but contains the 3 tokens,
31
+ "set", "max", and "width".
32
+
33
+ If an Array of Strings is returned instead, then the first string is
24
34
  shifted from the array and executed. The remaining strings are pushed
25
35
  onto the command queue. In contrast to the first string, subsequent
26
36
  strings can contain other macros, and ;; in those strings will be
27
37
  split into separate commands.
28
38
 
29
- Here is an example. The below creates a macro called fin+ which
30
- issues two commands 'finish' followed by 'step':
39
+ Here is an example using na Array of Strings. The below creates a
40
+ macro called fin+ which issues two commands 'finish' followed by
41
+ 'step':
31
42
 
32
- macro fin+ Proc.new{|*args| %w(finish step)}
43
+ macro fin+ Proc.new{|*args| %w(finish step)}
33
44
 
34
45
  If you wanted to parameterize the argument of the 'finish' command
35
46
  you could do that this way:
36
47
 
37
- macro fin+ Proc.new{|*args| ['finish \#{args[0]}' 'step']}
48
+ macro fin+ Proc.new{|*args| ["finish \#{args[0]}" 'step']}
49
+
50
+ Invoking with:
38
51
 
39
- Invoking with
40
- fin+ 3
52
+ fin+ 3
41
53
 
42
54
  would expand to ["finish 3", "step"]
43
55
 
44
- If you were to add another parameter for 'step', the note that the
45
- invocation might be
46
- fin+ 3 2
56
+ If you were to add another parameter for 'step', the note that the
57
+ invocation might be:
58
+
59
+ fin+ 3 2
47
60
 
48
61
  rather than 'fin+(3,2)' or 'fin+ 3, 2'.
49
62
 
50
63
  Here is another example using arguments. I use the following to debug
51
64
  a debugger command:
52
65
 
53
- macro dbgcmd Proc.new{|*args| ["set debug dbgr", "debug $trepan_cmdproc.commands['\#{args[0]}'].run(\#{args.inspect})"]}
66
+ macro dbgcmd Proc.new{|*args| ["set debug dbgr", "debug $trepan_cmdproc.commands['\#{args[0]}'].run(\#{args.inspect})"]}
67
+
68
+ With the above, 'dbgcmd list 5' will ultimately expand to:
54
69
 
55
- With the above, 'dbgcmd list 5' will ultimately expand to:
56
- set debug dbgr
57
- debug $trepan_cmdproc.commands['list'].run(['5'])
70
+ set debug dbgr
71
+ debug $trepan_cmdproc.commands['list'].run(['5'])
58
72
 
59
73
  and will debug the debugger's 'list' command on the command 'list 5'.
60
74
 
61
- See also 'info macro'.
75
+ See also:
76
+ ---------
77
+
78
+ `alias` and `info macro`.
62
79
  HELP
63
80
 
64
81
  CATEGORY = 'support'
65
82
  MIN_ARGS = 2 # Need at least this many
66
83
  SHORT_HELP = 'Define a macro'
67
84
  end
68
-
85
+
69
86
  def run(args)
70
87
  cmd_name = args[1]
71
88
  cmd_argstr = @proc.cmd_argstr[cmd_name.size..-1].lstrip
@@ -80,7 +97,7 @@ See also 'info macro'.
80
97
  end
81
98
  end
82
99
  end
83
-
100
+
84
101
  if __FILE__ == $0
85
102
  require_relative '../mock'
86
103
  dbgr, cmd = MockDebugger::setup