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
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