trepanning 0.1.2 → 0.1.3

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 (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
data/app/options.rb CHANGED
@@ -8,8 +8,8 @@ require 'optparse'
8
8
  class Trepan
9
9
  require_relative 'default'
10
10
 
11
- Trepan::VERSION = '0.1.2'
12
- Trepan::PROGRAM = 'trepan'
11
+ VERSION = '0.1.3'
12
+ PROGRAM = 'trepan'
13
13
 
14
14
  def self.show_version
15
15
  "#{PROGRAM}, version #{VERSION}"
@@ -31,18 +31,20 @@ class Trepan
31
31
  OptionParser.new do |opts|
32
32
  opts.banner = <<EOB
33
33
  #{show_version}
34
- Usage: #{PROGRAM} [options] <script.rb> -- <script.rb parameters>
34
+ Usage: #{PROGRAM} [options] [[--] <script.rb> <script.rb parameters>]
35
35
  EOB
36
+ opts.separator ''
37
+ opts.separator 'Options:'
36
38
  opts.on('--client',
37
- "Connect to out-of-process program") do
39
+ 'Connect to out-of-process program') do
38
40
  if options[:server]
39
- stderr.puts "--server option previously given. --client option ignored."
41
+ stderr.puts '--server option previously given. --client option ignored.'
40
42
  else
41
43
  options[:client] = true
42
44
  end
43
45
  end
44
46
  opts.on('-c', '--command FILE', String,
45
- "Execute debugger commands from FILE") do |cmdfile|
47
+ 'Execute debugger commands from FILE') do |cmdfile|
46
48
  if File.readable?(cmdfile)
47
49
  options[:cmdfiles] << cmdfile
48
50
  elsif File.exists?(cmdfile)
@@ -51,14 +53,7 @@ EOB
51
53
  stderr.puts "Command file '#{cmdfile}' does not exist."
52
54
  end
53
55
  end
54
- opts.on('--nx',
55
- "Do not run debugger initialization file #{CMD_INITFILE}") do
56
- options[:nx] = true
57
- end
58
- # opts.on('--output FILE', String, "Name of file to record output") do |outfile|
59
- # options[:outfile] = outfile
60
- # end
61
- opts.on("--cd DIR", String, "Change current directory to DIR") do |dir|
56
+ opts.on('--cd DIR', String, 'Change current directory to DIR') do |dir|
62
57
  if File.directory?(dir)
63
58
  if File.executable?(dir)
64
59
  options[:chdir] = dir
@@ -69,40 +64,62 @@ EOB
69
64
  stderr.puts "\"#{dir}\" is not a directory. Option --cd ignored."
70
65
  end
71
66
  end
72
- opts.on("-h", "--host NAME", String,
73
- "Host or IP used in TCP connections for --server or --client. " +
67
+ opts.on('-d', '--debug', "Set $DEBUG=true") {$DEBUG = true}
68
+ opts.on('--[no-]highlight',
69
+ 'Use [no] syntax highlight output') do |v|
70
+ options[:highlight] = ((v) ? :term : nil)
71
+ end
72
+ opts.on('-h', '--host NAME', String,
73
+ 'Host or IP used in TCP connections for --server or --client. ' +
74
74
  "Default is #{DEFAULT_SETTINGS[:host].inspect}.") do
75
75
  |name_or_ip|
76
76
  options[:host] = name_or_ip
77
77
  end
78
- opts.on("-p", "--port NUMBER", Integer,
79
- "Port number used in TCP connections for --server or --client. " +
78
+ opts.on('-I', '--include PATH', String, 'Add PATH to $LOAD_PATH') do
79
+ |path|
80
+ $LOAD_PATH.unshift(path)
81
+ end
82
+ opts.on('--nx',
83
+ "Do not run debugger initialization file #{CMD_INITFILE}") do
84
+ options[:nx] = true
85
+ end
86
+ opts.on('-p', '--port NUMBER', Integer,
87
+ 'Port number used in TCP connections for --server or --client. ' +
80
88
  "Default is #{DEFAULT_SETTINGS[:port]}.") do
81
89
  |num|
82
90
  options[:port] = num
83
91
  end
84
- opts.on('--server',
85
- "Set up for out-of-process debugging") do
92
+ opts.on('--[no-]readline',
93
+ 'Try [not] GNU Readline') do |v|
94
+ options[:readline] = v
95
+ end
96
+ opts.on('-r', '--require SCRIPT', String,
97
+ 'Require the library, before executing your script') do |name|
98
+ if name == 'debug'
99
+ stderr.puts "ruby-debug is not compatible with Ruby's 'debug' library. This option is ignored."
100
+ else
101
+ require name
102
+ end
103
+ end
104
+ opts.on('-s', '--server',
105
+ 'Set up for out-of-process debugging') do
86
106
  if options[:client]
87
- stderr.puts "--client option previously given. --server option ignored."
107
+ stderr.puts '--client option previously given. --server option ignored.'
88
108
  else
89
109
  options[:server] = true
90
110
  end
91
111
  end
92
- opts.on('--[no-]highlight',
93
- "Use [no] syntax highlight output") do |v|
94
- options[:highlight] = ((v) ? :term : nil)
95
- end
96
- opts.on('--[no-]readline',
97
- "Try [not] GNU Readline") do |v|
98
- options[:readline] = v
112
+ opts.on('-x', '--trace', 'Turn on line tracing') do
113
+ options[:tracing] = true
99
114
  end
100
- opts.on_tail("-?", "--help", "Show this message") do
115
+ opts.separator ''
116
+ opts.on_tail('-?', '--help', 'Show this message') do
101
117
  options[:help] = true
102
118
  stdout.puts opts
119
+ exit
103
120
  end
104
- opts.on_tail("-v", "--version",
105
- "print the version") do
121
+ opts.on_tail('-v', '--version',
122
+ 'print the version') do
106
123
  options[:version] = true
107
124
  stdout.puts show_version
108
125
  end
data/app/util.rb CHANGED
@@ -11,14 +11,64 @@ class Trepan
11
11
  str
12
12
  end
13
13
  end
14
+
15
+ # name is String and list is an Array of String.
16
+ # If name is a unique leading prefix of one of the entries of list,
17
+ # then return that. Otherwise return name.
18
+ def uniq_abbrev(list, name)
19
+ candidates = list.select do |try_name|
20
+ try_name.start_with?(name)
21
+ end
22
+ candidates.size == 1 ? candidates.first : name
23
+ end
24
+
25
+ # extract the "expression" part of a line of source code.
26
+ #
27
+ def extract_expression(text)
28
+ if text =~ /^\s*(?:if|elsif|unless)\s+/
29
+ text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
30
+ text.gsub!(/\s+then\s*$/, '')
31
+ elsif text =~ /^\s*(?:until|while)\s+/
32
+ text.gsub!(/^\s*(?:until|while)\s+/,'')
33
+ text.gsub!(/\s+do\s*$/, '')
34
+ elsif text =~ /^\s*return\s+/
35
+ # EXPRESION in: return EXPRESSION
36
+ text.gsub!(/^\s*return\s+/,'')
37
+ elsif text =~ /^\s*case\s+/
38
+ # EXPRESSION in: case EXPESSION
39
+ text.gsub!(/^\s*case\s*/,'')
40
+ elsif text =~ /^\s*def\s*.*\(.+\)/
41
+ text.gsub!(/^\s*def\s*.*\((.*)\)/,'[\1]')
42
+ elsif text =~ /^\s*[A-Za-z_][A-Za-z0-9_\[\]]*\s*=[^=>]/
43
+ # RHS of an assignment statement.
44
+ text.gsub!(/^\s*[A-Za-z_][A-Za-z0-9_\[\]]*\s*=/,'')
45
+ end
46
+ return text
47
+ end
14
48
  end
15
49
  end
16
50
 
17
51
  if __FILE__ == $0
18
52
  include Trepan::Util
53
+ # save repr
19
54
  string = 'The time has come to talk of many things.'
20
55
  puts safe_repr(string, 50)
21
56
  puts safe_repr(string, 17)
22
57
  puts safe_repr(string.inspect, 17)
23
58
  puts safe_repr(string.inspect, 17, '')
59
+ # ------------------------------------
60
+ # extract_expression
61
+ ['if condition("if")',
62
+ 'until until_termination',
63
+ 'return return_value',
64
+ 'nothing_to_be.done'
65
+ ].each do |stmt|
66
+ puts extract_expression stmt
67
+ end
68
+
69
+ list = %w(disassemble disable distance up)
70
+ p list
71
+ %w(dis disa u upper foo).each do |name|
72
+ puts "uniq_abbrev of #{name} is #{uniq_abbrev(list, name)}"
73
+ end
24
74
  end
@@ -59,6 +59,10 @@ class Trepan
59
59
  end
60
60
 
61
61
  def finalize(last_wishes=nil)
62
+ if @output && !@output.closed?
63
+ msg "%sThat's all, folks..." %
64
+ (defined?(Trepan::PROGRAM) ? "#{Trepan::PROGRAM}: " : '')
65
+ end
62
66
  close
63
67
  end
64
68
 
data/interface/client.rb CHANGED
@@ -45,6 +45,10 @@ class Trepan::ClientInterface < Trepan::Interface
45
45
  end
46
46
  end
47
47
 
48
+ def closed?
49
+ @inout.closed?
50
+ end
51
+
48
52
  def confirm(prompt, default)
49
53
  @user.confirm(prompt, default)
50
54
  end
data/interface/script.rb CHANGED
@@ -27,7 +27,7 @@ class Trepan::ScriptInterface < Trepan::Interface
27
27
  @input = opts[:input] ||
28
28
  Trepan::UserInput.open(script_name, :line_edit => false)
29
29
  @buffer_output = []
30
- unless opts[:verbose] or out
30
+ unless @opts[:verbose] or out
31
31
  out = Trepan::StringArrayOutput.open(@buffer_output)
32
32
  end
33
33
  super(@input, out, @opts)
data/interface/server.rb CHANGED
@@ -51,6 +51,10 @@ class Trepan::ServerInterface < Trepan::Interface
51
51
  end
52
52
  end
53
53
 
54
+ def closed?
55
+ @inout.closed?
56
+ end
57
+
54
58
  # Called when a dangerous action is about to be done to make sure
55
59
  # it's okay. `prompt' is printed; user response is returned.
56
60
  # FIXME: make common routine for this and user.rb
data/interface/user.rb CHANGED
@@ -37,6 +37,10 @@ class Trepan::UserInterface < Trepan::Interface
37
37
  at_exit { finalize }
38
38
  end
39
39
 
40
+ def closed?
41
+ @input.closed? && @output.closed?
42
+ end
43
+
40
44
  # Called when a dangerous action is about to be done, to make
41
45
  # sure it's okay. Expect a yes/no answer to `prompt' which is printed,
42
46
  # suffixed with a question mark and the default value. The user
@@ -146,4 +150,5 @@ if __FILE__ == $0
146
150
  puts "EOF is now: %s" % intf.input.eof?.inspect
147
151
  end
148
152
  end
153
+ puts "User interface closed?: #{intf.closed?}"
149
154
  end
data/io/input.rb CHANGED
@@ -37,7 +37,7 @@ class Trepan
37
37
  line = Readline.readline(prompt, true)
38
38
  else
39
39
  line = @input.gets
40
- end
40
+ end
41
41
  rescue Interrupt
42
42
  return ''
43
43
  rescue EOFError
@@ -76,13 +76,14 @@ class Trepan
76
76
  rescue
77
77
  end
78
78
  @@readline_finalized = true
79
- end
79
+ end
80
80
  end
81
81
  end
82
82
  end
83
83
  end
84
84
 
85
85
  def Trepan::GNU_readline?
86
+ @have_readline ||= nil
86
87
  begin
87
88
  return @have_readline unless @have_readline.nil?
88
89
  @have_readline = require 'readline'
data/io/null_output.rb CHANGED
@@ -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
 
4
4
  # Nukes output. Used for example in sourcing where you don't want
5
5
  # to see output.
@@ -10,10 +10,16 @@ require_relative 'base_io'
10
10
  class Trepan
11
11
  class OutputNull < Trepan::OutputBase
12
12
  def initialize(out, opts={})
13
+ @closed = false
13
14
  super
14
15
  end
15
16
 
16
17
  def close
18
+ @closed = true
19
+ end
20
+
21
+ def closed?
22
+ !!@closed
17
23
  end
18
24
 
19
25
  def flush
@@ -1,7 +1,8 @@
1
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require_relative 'virtual'
2
3
  class Trepan
3
4
 
4
- class CmdProcessor
5
+ class CmdProcessor < VirtualCmdProcessor
5
6
 
6
7
  attr_reader :brkpts # BreakpointManager.
7
8
 
@@ -201,7 +201,7 @@ module Trepanning
201
201
  dirname = File.basename(File.dirname(File.expand_path(__file__)))
202
202
  name = File.basename(__file__, '.rb')
203
203
  klass.const_set('NAME', name)
204
- prefix = klass.const_set('PREFIX', %W(#{dirname[0...-'_subcmd'.size]} #{name}))
204
+ prefix = klass.const_set(:PREFIX, %W(#{dirname[0...-'_subcmd'.size]} #{name}))
205
205
  klass.const_set('CMD', prefix.join(' '))
206
206
  end
207
207
  end
@@ -174,7 +174,10 @@ class Trepan::SubcommandMgr < Trepan::Command
174
174
  # Run that.
175
175
  subcmd = @subcmds.lookup(subcmd_prefix)
176
176
  if subcmd
177
- subcmd.run(args)
177
+ if @proc.ok_for_running(subcmd, subcmd.class.const_get('CMD'),
178
+ args.size-2)
179
+ subcmd.run(args)
180
+ end
178
181
  else
179
182
  undefined_subcmd(@name, subcmd_prefix)
180
183
  end
@@ -99,9 +99,9 @@ module Trepanning
99
99
 
100
100
  short_dirname = dirname[0...-'_subcmd'.size]
101
101
  short_parent_dirname = parent_dirname[0...-'_subcmd'.size]
102
- prefix = klass.const_set('PREFIX', %W(#{short_parent_dirname}
102
+ prefix = klass.const_set(:PREFIX, %W(#{short_parent_dirname}
103
103
  #{short_dirname} #{name}))
104
- klass.const_set('CMD', prefix.join(' '))
104
+ klass.const_set(:CMD, prefix.join(' '))
105
105
  end
106
106
  end
107
107
  end
@@ -38,7 +38,7 @@ class Trepan::SubSubcommandMgr < Trepan::Subcommand
38
38
  # we are the super class but want to set the subclass's constant.
39
39
  # defined? didn't seem to work here.
40
40
  c = self.class.constants
41
- self.class.const_set('SHORT_HELP',
41
+ self.class.const_set(:SHORT_HELP,
42
42
  self.class.const_get('HELP')) if
43
43
  c.member?(:HELP) and !c.member?(:SHORT_HELP)
44
44
 
@@ -33,7 +33,7 @@ See also condition, continue and "help location".
33
33
  end
34
34
 
35
35
  # This method runs the command
36
- def run(args)
36
+ def run(args, temp=false)
37
37
  # FIXME: handle more conditions
38
38
  # a line number
39
39
  if args.size == 1
@@ -45,12 +45,16 @@ See also condition, continue and "help location".
45
45
  iseq, line_number, vm_offset, condition, negate =
46
46
  @proc.breakpoint_position(@proc.cmd_argstr, true)
47
47
  return false unless iseq && vm_offset
48
- bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate)
48
+ bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate, temp)
49
49
  end
50
50
  if bp
51
51
  bp.condition = condition
52
52
 
53
- mess = "Breakpoint %d set at " % bp.id
53
+ if temp
54
+ mess = "Temporary breakpoint %d set at " % bp.id
55
+ else
56
+ mess = "Breakpoint %d set at " % bp.id
57
+ end
54
58
 
55
59
  line_loc = "line %s in %s" %
56
60
  [bp.source_location.join(', '),
@@ -29,6 +29,7 @@ if __FILE__ == $0
29
29
  require_relative '../mock'
30
30
  dbgr, cmd = MockDebugger::setup
31
31
  %w(d b bt).each do |prefix|
32
+ cmd.proc.instance_variable_set('@cmd_argstr', prefix)
32
33
  cmd.run [cmd.name, prefix]
33
34
  puts '=' * 40
34
35
  end
@@ -43,7 +43,7 @@ See also 'step', 'next', 'finish', 'nexti' commands and "help location".
43
43
  iseq, line_number, vm_offset, condition, negate =
44
44
  @proc.breakpoint_position(@proc.cmd_argstr, false)
45
45
  return false unless iseq && vm_offset
46
- bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate)
46
+ bp = @proc.breakpoint_offset(vm_offset, iseq, condition, negate, true)
47
47
  return unless bp
48
48
  @proc.continue
49
49
  end
@@ -10,7 +10,7 @@ class Trepan::Command::DisassembleCommand < Trepan::Command
10
10
 
11
11
  unless defined?(HELP)
12
12
  NAME = File.basename(__FILE__, '.rb')
13
- ALIASES = %w(disas disassem) # Note we have disable
13
+ ALIASES = %w(disasm) # Note we have disable
14
14
  CATEGORY = 'data'
15
15
  HELP = <<-HELP
16
16
  #{NAME} [thing] [full]
@@ -8,38 +8,57 @@ class Trepan::Command::EditCommand < Trepan::Command
8
8
  $VERBOSE = nil
9
9
  NAME = File.basename(__FILE__, '.rb')
10
10
  HELP = <<-HELP
11
- #{NAME} [LOCATION]
11
+ #{NAME} [[FILE] [LINE]]
12
12
 
13
13
  With no argument, edits file containing most recent line listed.
14
+ The value of the environment variable EDITOR is used for the
15
+ editor to run. If no EDITOR environment variable is set /bin/ex
16
+ is used. The editor should support line and file positioning via
17
+ editor-name +line file-name
18
+ (Most editors do.)
14
19
 
15
- Editing targets can also be specified.
20
+ Examples:
21
+ #{NAME} # Edit current location
22
+ #{NAME} 7 # Edit current file at line 7
23
+ #{NAME} test.rb # Edit test.rb, line 1
24
+ #{NAME} test.rb 10 # Edit test.rb line 10
16
25
  HELP
17
26
 
18
27
  ALIASES = %w(e)
19
28
  CATEGORY = 'files'
20
29
  NEED_STACK = false
21
- SHORT_HELP = 'Edit specified file or function'
30
+ SHORT_HELP = 'Invoke an editor on some source code'
31
+ MAX_ARGS = 2
22
32
  $VERBOSE = old_verbose
23
33
 
34
+ # FIXME: redo with locations and kparse.
24
35
  def run(args)
25
- if args.size == 1
26
-
27
- unless true # @state.context
28
- errmsg "We are not in a state that has an associated file.\n"
29
- return
36
+ case args.size
37
+ when 1
38
+ file = @proc.frame.source_container[1]
39
+ line = @proc.frame.source_location[0]
40
+ when 2
41
+ line = Integer(args[1]) rescue nil
42
+ if line
43
+ file = @proc.frame.source_container[1]
44
+ else
45
+ file = args[1]
46
+ line = 1
30
47
  end
48
+ when 3
49
+ line, file = args[2], args[1]
31
50
  else
32
- text = @proc.cmd_argstr
51
+ errmsg "edit needs at most 2 args."
33
52
  end
34
53
  editor = ENV['EDITOR'] || '/bin/ex'
35
- file = @proc.frame.file
36
54
  if File.readable?(file)
37
- edit_cmd = "#{editor} +#{@proc.frame.line} \"#{file}\""
55
+ file = File.basename(file) if settings[:basename]
56
+ edit_cmd = "#{editor} +#{line} \"#{file}\""
38
57
  msg "Running #{edit_cmd}..."
39
58
  system(edit_cmd)
40
59
  msg "Warning: return code was #{$?.exitstatus}" if $?.exitstatus != 0
41
60
  else
42
- errmsg "File \"#{file}\" is not readable.\n"
61
+ errmsg "File \"#{file}\" is not readable."
43
62
  end
44
63
  end
45
64
  end
@@ -47,6 +66,8 @@ end
47
66
  if __FILE__ == $0
48
67
  require_relative '../mock'
49
68
  dbgr, cmd = MockDebugger::setup
50
- dbgr, cmd = MockDebugger::setup
51
- cmd.run [cmd.name] if ARGV.size > 0
69
+ ENV['EDITOR'] = 'echo FAKE-EDITOR'
70
+ cmd.run [cmd.name]
71
+ cmd.run [cmd.name, '7']
72
+ cmd.run [cmd.name, __FILE__, '10']
52
73
  end