rbx-trepanning 0.0.8-universal-rubinius-1.2 → 0.1.0-universal-rubinius-1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/ChangeLog +762 -238
  2. data/NEWS +44 -0
  3. data/Rakefile +61 -32
  4. data/app/breakpoint.rb +2 -0
  5. data/app/brkptmgr.rb +9 -11
  6. data/app/client.rb +0 -1
  7. data/app/cmd_parse.kpeg +21 -4
  8. data/app/cmd_parse.rb +10 -10
  9. data/app/cmd_parser.rb +1029 -840
  10. data/app/complete.rb +1 -1
  11. data/app/display.rb +38 -0
  12. data/app/file.rb +24 -0
  13. data/app/frame.rb +11 -4
  14. data/app/irb.rb +41 -39
  15. data/app/iseq.rb +71 -0
  16. data/app/options.rb +55 -30
  17. data/app/rbx-llvm.rb +0 -2
  18. data/app/run.rb +13 -9
  19. data/app/util.rb +55 -5
  20. data/bin/trepanx +3 -3
  21. data/data/irbrc +13 -13
  22. data/{interface/base_intf.rb → interface.rb} +5 -1
  23. data/interface/client.rb +4 -0
  24. data/interface/script.rb +13 -5
  25. data/interface/server.rb +5 -1
  26. data/interface/user.rb +8 -1
  27. data/{io/base_io.rb → io.rb} +0 -0
  28. data/io/input.rb +1 -1
  29. data/io/null_output.rb +28 -24
  30. data/io/string_array.rb +2 -3
  31. data/io/tcpclient.rb +1 -1
  32. data/io/tcpserver.rb +1 -1
  33. data/lib/trepanning.rb +11 -13
  34. data/{processor/main.rb → processor.rb} +50 -54
  35. data/processor/breakpoint.rb +150 -137
  36. data/processor/{command/base/cmd.rb → command.rb} +1 -1
  37. data/processor/command/alias.rb +14 -3
  38. data/processor/command/backtrace.rb +2 -1
  39. data/processor/command/base/subcmd.rb +1 -5
  40. data/processor/command/base/submgr.rb +5 -2
  41. data/processor/command/base/subsubcmd.rb +1 -1
  42. data/processor/command/base/subsubmgr.rb +4 -4
  43. data/processor/command/break.rb +1 -1
  44. data/processor/command/complete.rb +2 -1
  45. data/processor/command/condition.rb +2 -2
  46. data/processor/command/continue.rb +4 -4
  47. data/processor/command/delete.rb +34 -20
  48. data/processor/command/directory.rb +4 -4
  49. data/processor/command/disable.rb +71 -0
  50. data/processor/command/disassemble.rb +55 -22
  51. data/processor/command/display.rb +3 -1
  52. data/processor/command/down.rb +8 -8
  53. data/processor/command/edit.rb +74 -0
  54. data/processor/command/enable.rb +43 -0
  55. data/processor/command/eval.rb +37 -15
  56. data/processor/command/exit.rb +25 -6
  57. data/processor/command/finish.rb +5 -5
  58. data/processor/command/frame.rb +2 -2
  59. data/processor/command/help.rb +7 -9
  60. data/processor/command/help/README +10 -0
  61. data/processor/command/help/command.txt +37 -27
  62. data/processor/command/help/examples.txt +16 -0
  63. data/processor/command/help/filename.txt +1 -1
  64. data/processor/command/help/suffixes.txt +17 -0
  65. data/processor/command/info.rb +3 -1
  66. data/processor/command/info_subcmd/files.rb +3 -2
  67. data/processor/command/info_subcmd/frame.rb +2 -1
  68. data/processor/command/info_subcmd/line.rb +17 -28
  69. data/processor/command/info_subcmd/locals.rb +22 -0
  70. data/processor/command/{show_subcmd → info_subcmd}/macro.rb +4 -4
  71. data/processor/command/info_subcmd/program.rb +2 -0
  72. data/processor/command/info_subcmd/ruby.rb +2 -0
  73. data/processor/command/info_subcmd/source.rb +75 -0
  74. data/processor/command/info_subcmd/stack.rb +25 -0
  75. data/processor/command/info_subcmd/variables.rb +23 -36
  76. data/processor/command/info_subcmd/variables_subcmd/.gitignore +2 -0
  77. data/processor/command/info_subcmd/variables_subcmd/class.rb +42 -0
  78. data/processor/command/info_subcmd/variables_subcmd/constant.rb +42 -0
  79. data/processor/command/info_subcmd/variables_subcmd/globals.rb +69 -0
  80. data/processor/command/info_subcmd/variables_subcmd/instance.rb +42 -0
  81. data/processor/command/info_subcmd/variables_subcmd/locals.rb +80 -0
  82. data/processor/command/kill.rb +8 -9
  83. data/processor/command/list.rb +101 -167
  84. data/processor/command/macro.rb +28 -10
  85. data/processor/command/next.rb +2 -1
  86. data/processor/command/nexti.rb +1 -1
  87. data/processor/command/parsetree.rb +51 -0
  88. data/processor/command/pr.rb +1 -2
  89. data/processor/command/ps.rb +1 -1
  90. data/processor/command/restart.rb +2 -2
  91. data/processor/command/save.rb +1 -1
  92. data/processor/command/server.rb +1 -1
  93. data/processor/command/set_subcmd/abbrev.rb +25 -0
  94. data/processor/command/set_subcmd/auto.rb +7 -1
  95. data/processor/command/set_subcmd/auto_subcmd/eval.rb +1 -2
  96. data/processor/command/set_subcmd/auto_subcmd/irb.rb +2 -3
  97. data/processor/command/set_subcmd/auto_subcmd/list.rb +2 -3
  98. data/processor/command/set_subcmd/different.rb +1 -1
  99. data/processor/command/set_subcmd/highlight.rb +7 -1
  100. data/processor/command/set_subcmd/reload.rb +42 -0
  101. data/processor/command/set_subcmd/timer.rb +58 -0
  102. data/processor/command/set_subcmd/trace.rb +4 -3
  103. data/processor/command/{irb.rb → shell.rb} +22 -19
  104. data/processor/command/show_subcmd/abbrev.rb +20 -0
  105. data/processor/command/show_subcmd/{alias.rb → aliases.rb} +2 -2
  106. data/processor/command/show_subcmd/auto_subcmd/eval.rb +2 -6
  107. data/processor/command/show_subcmd/directories.rb +22 -0
  108. data/processor/command/show_subcmd/hidelevel.rb +1 -1
  109. data/processor/command/show_subcmd/highlight.rb +2 -1
  110. data/processor/command/show_subcmd/reload.rb +18 -0
  111. data/processor/command/show_subcmd/timer.rb +18 -0
  112. data/processor/command/source.rb +9 -9
  113. data/processor/command/step.rb +1 -1
  114. data/processor/command/tbreak.rb +3 -2
  115. data/processor/command/unalias.rb +11 -6
  116. data/processor/command/undisplay.rb +13 -9
  117. data/processor/command/up.rb +13 -14
  118. data/processor/default.rb +47 -44
  119. data/processor/disassemble.rb +48 -35
  120. data/processor/display.rb +38 -3
  121. data/processor/eval.rb +54 -53
  122. data/processor/eventbuf.rb +69 -69
  123. data/processor/frame.rb +186 -187
  124. data/processor/help.rb +6 -4
  125. data/processor/hook.rb +103 -102
  126. data/processor/list.rb +123 -0
  127. data/processor/load_cmds.rb +9 -1
  128. data/processor/location.rb +193 -188
  129. data/processor/mock.rb +1 -7
  130. data/processor/msg.rb +56 -42
  131. data/processor/running.rb +26 -15
  132. data/processor/stepping.rb +2 -1
  133. data/processor/subcmd.rb +18 -43
  134. data/processor/validate.rb +41 -30
  135. data/processor/virtual.rb +33 -0
  136. data/rbx-trepanning.gemspec +7 -8
  137. data/sample/rocky-trepanx-colors.rb +0 -1
  138. data/test/data/fname-with-blank.right +2 -0
  139. data/test/data/inline-call.right +11 -10
  140. data/test/data/quit.right +1 -0
  141. data/test/example/debugger-stop.rb +1 -1
  142. data/test/example/goto2goto.rb +11 -0
  143. data/test/functional/fn_helper.rb +2 -2
  144. data/test/functional/test-list.rb +7 -6
  145. data/test/integration/helper.rb +5 -5
  146. data/test/unit/cmd-helper.rb +2 -6
  147. data/test/unit/test-app-cmd_parser.rb +3 -2
  148. data/test/unit/test-app-display.rb +22 -0
  149. data/test/unit/test-app-options.rb +14 -10
  150. data/test/unit/test-app-run.rb +0 -2
  151. data/test/unit/test-app-util.rb +21 -4
  152. data/test/unit/test-base-cmd.rb +5 -7
  153. data/test/unit/test-base-subcmd.rb +1 -5
  154. data/test/unit/test-base-submgr.rb +1 -1
  155. data/test/unit/test-base-subsubcmd.rb +0 -4
  156. data/test/unit/test-bin-trepanx.rb +2 -2
  157. data/test/unit/test-cmd-break.rb +2 -0
  158. data/test/unit/test-cmd-edit.rb +34 -0
  159. data/test/unit/test-cmd-kill.rb +11 -4
  160. data/test/unit/test-cmd-parse_list_cmd.rb +36 -0
  161. data/test/unit/test-command.rb +45 -0
  162. data/test/unit/test-completion.rb +1 -1
  163. data/test/unit/test-proc-eval.rb +1 -2
  164. data/test/unit/test-proc-frame.rb +5 -3
  165. data/test/unit/test-proc-list.rb +55 -0
  166. data/test/unit/test-proc-load_cmds.rb +4 -3
  167. data/test/unit/test-proc-location.rb +32 -29
  168. data/test/unit/test-proc-main.rb +1 -5
  169. data/test/unit/test-proc-validate.rb +14 -4
  170. data/test/unit/test-subcmd-help.rb +1 -5
  171. metadata +73 -107
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'locals'
5
+
6
+ class Trepan::Subcommand::InfoVariablesConstant <
7
+ Trepan::Subcommand::InfoVariablesLocals
8
+ Trepan::Util.suppress_warnings {
9
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
10
+ HELP = <<-EOH
11
+ #{CMD}
12
+ #{CMD} [names]
13
+
14
+ Show class constants 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 class constants via the current stack frame'
19
+ MIN_ABBREV = 'co'.size
20
+ MIN_ARGS = 0
21
+ MAX_ARGS = 1
22
+ NEED_STACK = true
23
+ }
24
+
25
+ def get_names
26
+ @proc.debug_eval_no_errmsg('self.class.constants.sort') || []
27
+ end
28
+
29
+ def run(args)
30
+ run_for_type(args, 'constant', @proc.debug_eval('self'))
31
+ end
32
+ end
33
+
34
+ if __FILE__ == $0
35
+ # Demo it.
36
+ require_relative '../../mock'
37
+ cmd =
38
+ MockDebugger::subsub_setup(Trepan::Subcommand::InfoVariables,
39
+ Trepan::Subcommand::InfoVariablesConstant)
40
+ cmd.run(cmd.prefix)
41
+ cmd.run(cmd.prefix + ['name'])
42
+ end
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'locals'
5
+
6
+ class Trepan::SubSubcommand::InfoVariablesGlobals < Trepan::SubSubcommand
7
+ Trepan::Util.suppress_warnings {
8
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
9
+ HELP = <<-EOH
10
+ #{CMD}
11
+ #{CMD} [names]
12
+
13
+ Show global variables.
14
+ Normally for each which show both the name and value. If you just
15
+ want a list of names add parameter 'names'.
16
+ EOH
17
+ SHORT_HELP = 'Show global variables'
18
+ MIN_ARGS = 0
19
+ MAX_ARGS = 1
20
+ NEED_STACK = true
21
+ }
22
+
23
+ def get_names
24
+ global_variables.sort
25
+ end
26
+
27
+ def run(args)
28
+ if args.size == 2
29
+ if 0 == 'names'.index(args[-1].downcase)
30
+ names = get_names()
31
+ if names.empty?
32
+ msg "No global variables defined."
33
+ else
34
+ section "Global variable names:"
35
+ width = settings[:maxwidth]
36
+ mess = Columnize::columnize(names,
37
+ @proc.settings[:maxwidth], ' ',
38
+ false, true, ' ' * 2).chomp
39
+ msg mess
40
+ end
41
+ else
42
+ errmsg("unrecognized argument: #{args[-1]}")
43
+ end
44
+ elsif args.size == 1
45
+ names = get_names
46
+ if names.empty?
47
+ msg "No global variables defined."
48
+ else
49
+ section "Global variables:"
50
+ names.each do |var_name|
51
+ s = @proc.debug_eval(var_name.to_s)
52
+ msg("#{var_name} = #{s.inspect}", :code=>true)
53
+ end
54
+ end
55
+ else
56
+ errmsg("Wrong number of arguments #{args.size}")
57
+ end
58
+ end
59
+ end
60
+
61
+ if __FILE__ == $0
62
+ # Demo it.
63
+ require_relative '../../../mock'
64
+ require_relative '../variables'
65
+ cmd = MockDebugger::subsub_setup(Trepan::Subcommand::InfoVariables,
66
+ Trepan::SubSubcommand::InfoVariablesGlobals)
67
+ cmd.run(cmd.prefix)
68
+ cmd.run(cmd.prefix + ['name'])
69
+ end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require_relative 'locals'
5
+
6
+ class Trepan::Subcommand::InfoVariablesInstance <
7
+ Trepan::Subcommand::InfoVariablesLocals
8
+ Trepan::Util.suppress_warnings {
9
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
10
+ HELP = <<-EOH
11
+ #{CMD}
12
+ #{CMD} [names]
13
+
14
+ Show instance variables 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 instance variables of the current stack frame'
19
+ MIN_ARGS = 0
20
+ MAX_ARGS = 1
21
+ MIN_ABBREV = 'iv'.size
22
+ NEED_STACK = true
23
+ }
24
+
25
+ def get_names
26
+ @proc.debug_eval('self.instance_variables')
27
+ end
28
+
29
+ def run(args)
30
+ run_for_type(args, 'instance', @proc.debug_eval('self'))
31
+ end
32
+ end
33
+
34
+ if __FILE__ == $0
35
+ # Demo it.
36
+ require_relative '../../mock'
37
+ cmd =
38
+ MockDebugger::subsub_setup(Trepan::Subcommand::InfoVariables,
39
+ Trepan::Subcommand::InfoVariablesInstance)
40
+ cmd.run(cmd.prefix)
41
+ cmd.run(cmd.prefix + ['name'])
42
+ end
@@ -0,0 +1,80 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
3
+ require 'rubygems'; require 'require_relative'
4
+ require 'columnize'
5
+ require_relative '../../base/subsubcmd'
6
+ require_relative '../../../../app/frame'
7
+ require_relative '../../../../app/util'
8
+
9
+ class Trepan::Subcommand::InfoVariablesLocals < Trepan::SubSubcommand
10
+ Trepan::Util.suppress_warnings {
11
+ Trepanning::Subcommand.set_name_prefix(__FILE__, self)
12
+ HELP = <<-EOH
13
+ #{CMD}
14
+ #{CMD} [names]
15
+
16
+ Show local variables including parameters of the current stack frame.
17
+ Normally for each which show both the name and value. If you just
18
+ want a list of names add parameter 'names'.
19
+ EOH
20
+ SHORT_HELP = 'Show local variables of the current stack frame'
21
+ MIN_ARGS = 0
22
+ MAX_ARGS = 1
23
+ MIN_ABBREV = 'lo'.size
24
+ NEED_STACK = true
25
+ }
26
+
27
+ def get_names
28
+ @proc.frame.local_variables
29
+ end
30
+
31
+ def run_for_type(args, type, klass=nil)
32
+ suffix = klass ? " for #{klass.to_s}" : '' rescue ''
33
+ names = get_names()
34
+ if args.size == 2
35
+ if 0 == 'names'.index(args[-1].downcase)
36
+ names = get_names()
37
+ if names.empty?
38
+ msg "No #{type} variables defined."
39
+ else
40
+ section "#{type.capitalize} variable names#{suffix}:"
41
+
42
+ width = settings[:maxwidth]
43
+ mess = Columnize::columnize(names,
44
+ @proc.settings[:maxwidth], ' ',
45
+ false, true, ' ' * 2).chomp
46
+ msg mess
47
+ end
48
+ else
49
+ errmsg("unrecognized argument: #{args[-1]}")
50
+ end
51
+ elsif args.size == 1
52
+ if names.empty?
53
+ msg "No #{type} variables defined#{suffix}."
54
+ else
55
+ section "#{type.capitalize} variables#{suffix}:"
56
+ names.each do |var_name|
57
+ var_value =
58
+ @proc.safe_rep(@proc.debug_eval_no_errmsg(var_name).inspect)
59
+ msg("#{var_name} = #{var_value}", :code =>true)
60
+ end
61
+ end
62
+ else
63
+ errmsg("Wrong number of arguments #{args.size}")
64
+ end
65
+ end
66
+ def run(args)
67
+ run_for_type(args, 'local', @proc.debug_eval('self'))
68
+ end
69
+ end
70
+
71
+ if __FILE__ == $0
72
+ # Demo it.
73
+ require_relative '../../../mock'
74
+ require_relative '../variables'
75
+ cmd = MockDebugger::subsub_setup(Trepan::SubSubcommand::InfoVariables,
76
+ Trepan::SubSubcommand::InfoVariablesLocals
77
+ )
78
+ cmd.run([])
79
+ cmd.run(['name'])
80
+ end
@@ -1,6 +1,6 @@
1
1
  # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require 'rubygems'; require 'require_relative'
3
- require_relative 'base/cmd'
3
+ require_relative '../command'
4
4
  class Trepan::Command::KillCommand < Trepan::Command
5
5
 
6
6
  unless defined?(HELP)
@@ -35,9 +35,10 @@ Examples:
35
35
  end
36
36
 
37
37
  def complete(prefix)
38
- completions = Signal.list.keys +
38
+ completions = Signal.list.keys + Signal.list.keys.map{|k| k.downcase} +
39
39
  Signal.list.values.map{|i| i.to_s} +
40
- Signal.list.values.map{|i| (-i).to_s}
40
+ Signal.list.values.map{|i| (-i).to_s} +
41
+ ['unconditionally']
41
42
  Trepan::Complete.complete_token(completions, prefix)
42
43
  end
43
44
 
@@ -50,9 +51,6 @@ Examples:
50
51
  errmsg("Signal name '#{sig}' is not a signal I know about.\n")
51
52
  return false
52
53
  end
53
- if 'KILL' == sig || Signal['KILL'] == sig
54
- @proc.intf.finalize
55
- end
56
54
  else
57
55
  if not (unconditional || confirm('Really quit?', false))
58
56
  msg('Kill not confirmed.')
@@ -62,9 +60,10 @@ Examples:
62
60
  end
63
61
  end
64
62
  begin
63
+ @proc.intf.finalize if 'KILL' == sig || Signal.list['KILL'] == sig
65
64
  Process.kill(sig, Process.pid)
66
- rescue Errno::ESRCH
67
- errmsg "Unable to send kill #{sig} to process #{Process.pid}"
65
+ rescue Errno::ESRCH, Errno::EINVAL, Errno::EPERM, RangeError
66
+ errmsg "Unable to send kill #{sig} to process #{Process.pid}: #{$!}"
68
67
  end
69
68
  end
70
69
  end
@@ -72,7 +71,7 @@ end
72
71
  if __FILE__ == $0
73
72
  require_relative '../mock'
74
73
  dbgr, cmd = MockDebugger::setup
75
- %w(fooo 1 -1 HUP -9).each do |arg|
74
+ %w(fooo 100 1 -1 HUP -9).each do |arg|
76
75
  puts "#{cmd.name} #{arg}"
77
76
  cmd.run([cmd.name, arg])
78
77
  puts '=' * 40
@@ -3,13 +3,14 @@
3
3
  require 'rubygems'
4
4
  require 'require_relative'
5
5
  require 'linecache'
6
- require_relative 'base/cmd'
6
+ require_relative '../command'
7
+ require_relative '../list'
7
8
 
8
9
  class Trepan::Command::ListCommand < Trepan::Command
9
10
  unless defined?(HELP)
10
11
  NAME = File.basename(__FILE__, '.rb')
11
12
  HELP = <<-HELP
12
- #{NAME}[>] [FIRST [NUM]]
13
+ #{NAME}[>] [MODULE] [FIRST [NUM]]
13
14
  #{NAME}[>] LOCATION [NUM]
14
15
 
15
16
  #{NAME} source code.
@@ -24,7 +25,7 @@ previously shown.
24
25
  If the command has a '>' suffix, then line centering is disabled and
25
26
  listing begins at the specificed location.
26
27
 
27
- The number of lines to show is controlled by the debugger "list size"
28
+ The number of lines to show is controlled by the debugger "listsize"
28
29
  setting. Use 'set max list' or 'show max list' to see or set the
29
30
  value.
30
31
 
@@ -42,8 +43,9 @@ A LOCATION is a either
42
43
  If the location form is used with a subsequent parameter, the
43
44
  parameter is the starting line number. When there two numbers are
44
45
  given, the last number value is treated as a stopping line unless it
45
- is less than the start line, in which case it is taken to mean the
46
- number of lines to list instead.
46
+ is positive and less than the start line. In this case, it is taken to
47
+ mean the number of lines to list instead. If last is negative, we start
48
+ that many lines back from first and list to first.
47
49
 
48
50
  Wherever a number is expected, it does not need to be a constant --
49
51
  just something that evaluates to a positive integer.
@@ -51,131 +53,49 @@ just something that evaluates to a positive integer.
51
53
  Some examples:
52
54
 
53
55
  #{NAME} 5 # List centered around line 5
54
- #{NAME} 4+1 # Same as above.
56
+ #{NAME} @5 # List lines centered around bytecode offset 5.
55
57
  #{NAME} 5> # List starting at line 5
56
58
  #{NAME} foo.rb:5 # List centered around line 5 of foo.rb
57
59
  #{NAME} foo.rb 5 # Same as above.
58
- #{NAME} foo.rb:5> # List starting around line 5 of foo.rb
60
+ #{NAME}> foo.rb:5 # List starting around line 5 of foo.rb
59
61
  #{NAME} foo.rb 5 6 # list lines 5 and 6 of foo.rb
60
62
  #{NAME} foo.rb 5 2 # Same as above, since 2 < 5.
61
63
  #{NAME} foo.rb:5 2 # Same as above
64
+ #{NAME} foo.rb 15 -5 # List lines 10..15 of foo
62
65
  #{NAME} FileUtils.cp # List lines around the FileUtils.cp function.
63
66
  #{NAME} . # List lines centered from where we currently are stopped
64
67
  #{NAME} . 3 # List 3 lines starting from where we currently are stopped
65
68
  # if . > 3. Otherwise we list from . to 3.
66
69
  #{NAME} - # List lines previous to those just shown
67
70
 
71
+ The output of the #{NAME} command gives a line number, and some status
72
+ information about the line and the text of the line. Here is some
73
+ hypothetical #{NAME} output modeled roughly around line 251 of one
74
+ version of this code:
75
+
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
81
+
82
+ Line 251 has nothing special about it. Line 252 is where we are
83
+ currently stopped. On line 253 there is a breakpoint 1 which is
84
+ enabled, while at line 255 there is an breakpoint 2 which is
85
+ disabled.
68
86
  HELP
69
87
 
70
- ALIASES = %W(l #{NAME}> l>)
88
+ ALIASES = %W(l #{NAME}> l> cat)
71
89
  CATEGORY = 'files'
72
90
  MAX_ARGS = 3
73
91
  SHORT_HELP = 'List source code'
74
92
  end
75
93
 
76
- # If last is less than first, assume last is a count rather than an
77
- # end line number.
78
- def adjust_last(first, last)
79
- last < first ? first + last - 1 : last
80
- end
81
-
82
- # What a f*cking mess. Necessitated I suppose because we want to
83
- # allow somewhat flexible parsing with either module names, files or none
84
- # and optional line counts or end-line numbers.
85
-
86
- # Parses arguments for the "list" command and returns the tuple:
87
- # filename, start, last
88
- # or sets these to nil if there was some problem.
89
- def parse_list_cmd(args, listsize, center_correction)
90
-
91
- last = nil
92
-
93
- if args.size > 0
94
- if args[0] == '-'
95
- return no_frame_msg unless @proc.line_no
96
- first = [1, @proc.line_no - 2*listsize - 1].max
97
- file = @proc.frame.file
98
- elsif args[0] == '.'
99
- return no_frame_msg unless @proc.line_no
100
- if args.size == 2
101
- opts = {
102
- :msg_on_error =>
103
- "#{NAME} command last or count parameter expected, " +
104
- 'got: %s.' % args[2]
105
- }
106
- second = @proc.get_an_int(args[1], opts)
107
- return nil, nil, nil unless second
108
- first = @proc.frame.line
109
- last = adjust_last(first, second)
110
- else
111
- first = [1, @proc.frame.line - center_correction].max
112
- end
113
-
114
- file = @proc.frame.file
115
- else
116
- modfunc, file, first = @proc.parse_position(args[0])
117
- if first == nil and modfunc == nil
118
- # error should have been shown previously
119
- return nil, nil, nil
120
- end
121
- if args.size == 1
122
- first = 1 if !first and modfunc
123
- first = [1, first - center_correction].max
124
- elsif args.size == 2 or (args.size == 3 and modfunc)
125
- opts = {
126
- :msg_on_error =>
127
- "#{NAME} command starting line expected, got %s." % args[-1]
128
- }
129
- last = @proc.get_an_int(args[1], opts)
130
- return nil, nil, nil unless last
131
- if modfunc
132
- if first
133
- first = last
134
- if args.size == 3 and modfunc
135
- opts[:msg_on_error] =
136
- ("#{NAME} command last or count parameter expected, " +
137
- 'got: %s.' % args[2])
138
- last = @proc.get_an_int(args[2], opts)
139
- return nil, nil, nil unless last
140
- end
141
- end
142
- end
143
- last = adjust_last(first, last)
144
- elsif not modfunc
145
- errmsg('At most 2 parameters allowed when no module' +
146
- ' name is found/given. Saw: %d parameters' % args.size)
147
- return nil, nil, nil
148
- else
149
- errmsg(('At most 3 parameters allowed when a module' +
150
- ' name is given. Saw: %d parameters') % args.size)
151
- return nil, nil, nil
152
- end
153
- end
154
- elsif !@proc.line_no and @proc.frame
155
- first = [1, @proc.frame.line - center_correction].max
156
- file = @proc.frame.file
157
- else
158
- first = [1, @proc.line_no - center_correction].max
159
- file = @proc.frame.file
160
- end
161
- last = first + listsize - 1 unless last
162
-
163
- if @proc.frame.eval?
164
- script = @proc.frame.vm_location.static_scope.script
165
- LineCache::cache(script)
166
- else
167
- LineCache::cache(file)
168
- script = nil
169
- end
170
- return file, script, first, last
171
- end
172
-
173
- def no_frame_msg
174
- errmsg("No Ruby program loaded.")
175
- return nil, nil, nil
176
- end
177
-
178
94
  def run(args)
95
+ if args.empty? and not frame
96
+ errmsg("No Ruby program loaded.")
97
+ return
98
+ end
179
99
  listsize = settings[:maxlist]
180
100
  center_correction =
181
101
  if args[0][-1..-1] == '>'
@@ -184,36 +104,21 @@ Some examples:
184
104
  (listsize-1) / 2
185
105
  end
186
106
 
187
- file, script, first, last =
188
- parse_list_cmd(args[1..-1], listsize, center_correction)
189
- frame = @proc.frame
190
- return unless file
191
-
192
- cached_item = script || file
107
+ cm, filename, first, last =
108
+ @proc.parse_list_cmd(@proc.cmd_argstr, listsize, center_correction)
109
+ return unless filename
110
+ breaklist = @proc.brkpts.line_breaks(cm)
193
111
 
194
112
  # We now have range information. Do the listing.
195
- max_line = LineCache::size(cached_item)
196
-
197
- # FIXME: join with line_at of location.rb
198
- unless max_line && file
199
- # Try using search directories (set with command "directory")
200
- if file[0..0] != File::SEPARATOR
201
- try_filename = @proc.resolve_file_with_dir(file)
202
- if try_filename &&
203
- max_line = LineCache::size(try_filename)
204
- LineCache::remap_file(file, try_filename)
205
- end
206
- end
207
- end
208
-
113
+ max_line = LineCache::size(filename)
209
114
  unless max_line
210
- errmsg('File "%s" not found.' % file)
115
+ errmsg('File "%s" not found.' % filename)
211
116
  return
212
117
  end
213
118
 
214
119
  if first > max_line
215
120
  errmsg('Bad line range [%d...%d]; file "%s" has only %d lines' %
216
- [first, last, file, max_line])
121
+ [first, last, filename, max_line])
217
122
  return
218
123
  end
219
124
 
@@ -224,11 +129,12 @@ Some examples:
224
129
 
225
130
  begin
226
131
  opts = {
227
- :reload_on_change => @proc.reload_on_change,
132
+ :reload_on_change => settings[:reload],
228
133
  :output => settings[:highlight]
229
134
  }
135
+ frame = @proc.frame
230
136
  first.upto(last).each do |lineno|
231
- line = LineCache::getline(cached_item, lineno, opts)
137
+ line = LineCache::getline(filename, lineno, opts)
232
138
  unless line
233
139
  msg('[EOF]')
234
140
  break
@@ -236,8 +142,16 @@ Some examples:
236
142
  line.chomp!
237
143
  s = '%3d' % lineno
238
144
  s = s + ' ' if s.size < 4
239
- s += (@proc.frame && lineno == @proc.frame.vm_location.line) ? '->' : ' '
240
- # && container == frame.source_container)
145
+ s += if breaklist.member?(lineno)
146
+ bp = breaklist[lineno]
147
+ a_pad = '%02d' % bp.id
148
+ bp.icon_char
149
+ else
150
+ a_pad = ' '
151
+ ' '
152
+ end
153
+ s += (frame && lineno == @proc.frame.line &&
154
+ filename == @proc.frame.file) ? '->' : a_pad
241
155
  msg(s + "\t" + line, {:unlimited => true})
242
156
  @proc.line_no = lineno
243
157
  end
@@ -248,53 +162,73 @@ Some examples:
248
162
  end
249
163
 
250
164
  if __FILE__ == $0
165
+ # require_relative '../../lib/trepanning'; debugger
251
166
  require_relative '../location'
252
167
  require_relative '../mock'
253
168
  require_relative '../frame'
254
169
  dbgr, cmd = MockDebugger::setup
255
170
  cmd.proc.send('frame_initialize')
256
- LineCache::cache(__FILE__)
257
- require 'trepanning'
258
- cmd.run([cmd.name])
259
- cmd.run([cmd.name, __FILE__ + ':10'])
260
171
 
261
172
  def run_cmd(cmd, args)
262
- seps = '--' * 10
263
- puts "%s %s %s" % [seps, args.join(' '), seps]
173
+ cmd.proc.instance_variable_set('@cmd_argstr', args[1..-1].join(' '))
264
174
  cmd.run(args)
265
175
  end
266
176
 
267
-
268
- load 'tmpdir.rb'
269
- run_cmd(cmd, %W(#{cmd.name} tmpdir.rb 10))
270
- run_cmd(cmd, %W(#{cmd.name} tmpdir.rb))
271
-
272
- run_cmd(cmd, %W(cmd.name .))
273
- run_cmd(cmd, %W(cmd.name 30))
274
-
275
- # cmd.run(['list', '9+1'])
276
-
277
- run_cmd(cmd, %W(cmd.name> 10))
278
- run_cmd(cmd, %W(cmd.name 3000))
279
- run_cmd(cmd, %W(cmd.name run_cmd))
280
-
177
+ LineCache::cache(__FILE__)
178
+ run_cmd(cmd, [cmd.name])
179
+ run_cmd(cmd, [cmd.name, __FILE__ + ':10'])
180
+
181
+ def run_cmd2(cmd, args)
182
+ seps = '--' * 10
183
+ puts "%s %s %s" % [seps, args.join(' '), seps]
184
+ run_cmd(cmd,args)
185
+ end
186
+
187
+ require 'tmpdir.rb'
188
+ run_cmd2(cmd, %w(list tmpdir.rb 10))
189
+ run_cmd2(cmd, %w(list tmpdir.rb))
190
+
191
+ # cmd.proc.frame = sys._getframe()
192
+ # cmd.proc.setup()
193
+ # run_cmd2(['list'])
194
+
195
+ run_cmd2(cmd, %w(list .))
196
+ run_cmd2(cmd, %w(list 30))
197
+
198
+ # run_cmd2(['list', '9+1'])
199
+
200
+ run_cmd2(cmd, %w(list> 10))
201
+ run_cmd2(cmd, %w(list 3000))
202
+ run_cmd2(cmd, %w(list run_cmd2))
203
+
281
204
  p = Proc.new do
282
205
  |x,y| x + y
283
206
  end
284
- run_cmd(cmd, %W(#{cmd.name} p))
285
-
207
+ run_cmd2(cmd, %w(list p))
208
+
286
209
  # Function from a file found via an instruction sequence
287
- run_cmd(cmd, %W(#{cmd.name} Columnize.columnize))
288
-
210
+ run_cmd2(cmd, %w(list Columnize.columnize))
211
+
289
212
  # Use Class/method name. 15 isn't in the function - should this be okay?
290
- run_cmd(cmd, %W(#{cmd.name} Columnize.columnize 15))
291
-
213
+ run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 15))
214
+
292
215
  # Start line and count, since 3 < 30
293
- run_cmd(cmd, %W(#{cmd.name} Columnize.columnize 30 3))
294
-
216
+ run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 30 3))
217
+
295
218
  # Start line finish line
296
- run_cmd(cmd, %W(#{cmd.name} Columnize.columnize 40 50))
219
+ run_cmd2(cmd, %W(#{cmd.name} Columnize.columnize 40 50))
220
+
221
+ line = __LINE__
222
+ brkpt_cmd = cmd.proc.instance_variable_get('@commands')['break']
223
+ cmd.proc.instance_variable_set('@cmd_argstr', "#{__FILE__} #{line}")
224
+ brkpt_cmd.run(['break', __FILE__, line.to_s])
225
+ run_cmd2(cmd, [cmd.name, line.to_s])
226
+
227
+ # disable_cmd = cmd.proc.instance_variable_get('@commands')['disable']
228
+ # disable_cmd.run(['disable', '1'])
297
229
 
298
- # Method name
299
- run_cmd(cmd, %W(#{cmd.name} cmd.run))
230
+ # run_cmd2(cmd, [cmd.name, line.to_s])
231
+ run_cmd2(cmd, %W(#{cmd.name} run_cmd2))
232
+ run_cmd2(cmd, %W(#{cmd.name} run_cmd2))
233
+ run_cmd2(cmd, %W(#{cmd.name} @713))
300
234
  end