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
data/processor/help.rb CHANGED
@@ -1,4 +1,5 @@
1
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+
2
3
  class Trepan
3
4
  # class SubHelp
4
5
  # def initialize(name, dir)
@@ -48,7 +49,7 @@ class Trepan
48
49
  # like "show", "info" or "set". Generally this means list
49
50
  # all of the subcommands.
50
51
  def summary_list(name, subcmds)
51
- msg "List of #{name} commands (with minimum abbreviation in parenthesis):"
52
+ section "List of #{name} commands (with minimum abbreviation in parenthesis):"
52
53
  subcmds.list.each do |subcmd_name|
53
54
  # Some commands have lots of output.
54
55
  # they are excluded here because 'in_list' is false.
@@ -59,8 +60,9 @@ class Trepan
59
60
 
60
61
  # Error message when subcommand asked for but doesn't exist
61
62
  def undefined_subcmd(cmd, subcmd)
62
- errmsg(('Undefined "%s" subcommand: "%s". ' +
63
- 'Try "help %s *".') % [cmd, subcmd, cmd])
63
+ ambig = settings[:abbrev] ? 'or ambiguous ' : ''
64
+ errmsg(['Undefined %s"%s" subcommand: "%s". ' % [ambig, cmd, subcmd],
65
+ 'Try "help %s *".' % cmd])
64
66
  end
65
67
 
66
68
  end
data/processor/hook.rb CHANGED
@@ -1,113 +1,114 @@
1
- # Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
2
- class Trepan
3
- class CmdProcessor
4
- # Command processor hooks.
5
- attr_reader :autodis_hook
6
- attr_reader :autoirb_hook
7
- attr_reader :autolist_hook
8
- attr_reader :debug_dbgr_hook
9
- attr_reader :display_hook
10
- attr_reader :timer_hook
11
- attr_reader :trace_hook
12
- attr_reader :tracebuf_hook
13
- attr_reader :unconditional_prehooks
14
- attr_reader :cmdloop_posthooks
15
- attr_reader :cmdloop_prehooks
1
+ # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+ require 'rubygems'; require 'require_relative'
3
+ require_relative 'virtual'
16
4
 
17
- # Used to time how long a debugger action takes
18
- attr_accessor :time_last
19
-
20
- class Hook
21
- attr_accessor :list
22
-
23
- def initialize(list=[])
24
- @list = list
25
- end
26
-
27
- def delete_by_name(delete_name)
28
- @list.delete_if {|hook_name, priority, hook| hook_name == delete_name}
29
- end
30
-
31
- def empty?
32
- @list.empty?
33
- end
34
-
35
- def insert(priority, name, hook)
36
- insert_loc = @list.size # at end
37
- @list.each_with_index do |entry, index|
38
- n, p, h = entry
39
- if priority > p
40
- insert_loc = index
41
- break
42
- end
43
- end
44
- @list.insert(insert_loc, [name, priority, hook])
45
- end
46
-
47
- def insert_if_new(priority, name, hook)
48
- insert(priority, name, hook) unless
49
- @list.find {|try_name, try_priority, try_hook| try_name == name}
50
- end
51
-
52
- # Run each function in `hooks' with args
53
- def run(*args)
54
- @list.each do |name, priority, hook|
55
- hook.call(name, *args)
5
+ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
6
+ # Command processor hooks.
7
+ attr_reader :autodis_hook
8
+ attr_reader :autoirb_hook
9
+ attr_reader :autolist_hook
10
+ attr_reader :debug_dbgr_hook
11
+ attr_reader :display_hook
12
+ attr_reader :timer_hook
13
+ attr_reader :trace_hook
14
+ attr_reader :tracebuf_hook
15
+ attr_reader :unconditional_prehooks
16
+ attr_reader :cmdloop_posthooks
17
+ attr_reader :cmdloop_prehooks
18
+
19
+ # Used to time how long a debugger action takes
20
+ attr_accessor :time_last
21
+
22
+ class Hook
23
+ attr_accessor :list
24
+
25
+ def initialize(list=[])
26
+ @list = list
27
+ end
28
+
29
+ def delete_by_name(delete_name)
30
+ @list.delete_if {|hook_name, priority, hook| hook_name == delete_name}
31
+ end
32
+
33
+ def empty?
34
+ @list.empty?
35
+ end
36
+
37
+ def insert(priority, name, hook)
38
+ insert_loc = @list.size # at end
39
+ @list.each_with_index do |entry, index|
40
+ n, p, h = entry
41
+ if priority > p
42
+ insert_loc = index
43
+ break
56
44
  end
57
45
  end
58
-
59
- # Could add delete_at and delete if necessary.
46
+ @list.insert(insert_loc, [name, priority, hook])
60
47
  end
61
48
 
62
- def hook_initialize(commands)
63
- @cmdloop_posthooks = Hook.new
64
- @cmdloop_prehooks = Hook.new
65
- @unconditional_prehooks = Hook.new
66
-
67
- irb_cmd = commands['irb']
68
- @autoirb_hook = ['autoirb',
69
- Proc.new{|*args| irb_cmd.run(['irb']) if irb_cmd}]
70
-
71
- @debug_dbgr_hook = ['dbgdbgr',
72
- Proc.new{|*args|
73
- if settings[:debugdbgr]
74
- $trepan_cmdproc = self
75
- $trepan_frame = @frame
76
- else
77
- $trepan_cmdproc = nil
78
- $trepan_frame = nil
79
- end}]
80
-
81
- display_cmd = commands['display']
82
- @display_hook = ['display',
83
- Proc.new{|*args| display_cmd.run(['display']) if display_cmd}]
84
-
85
- # FIXME: generalize for any command run
86
- dis_cmd = commands['disassemble']
87
- @autodis_hook = ['autodis',
88
- Proc.new{|*args| dis_cmd.run(['disassemble']) if dis_cmd}]
89
-
90
- list_cmd = commands['list']
91
- @autolist_hook = ['autolist',
92
- Proc.new{|*args| list_cmd.run(['list']) if list_cmd}]
93
-
94
- @timer_hook = ['timer',
95
- Proc.new{|*args|
96
- now = Time.now
97
- msg("%g seconds" %
98
- (now - @time_last)) if @time_last
99
- @time_last = now
100
- }]
101
- @timer_posthook = ['timer', Proc.new{|*args| @time_last = Time.now}]
102
- @trace_hook = ['trace',
103
- Proc.new{|*args| print_location}]
104
- @tracebuf_hook = ['tracebuffer',
105
- Proc.new{|*args| @eventbuf.append(@event, @frame,
106
- nil)}]
49
+ def insert_if_new(priority, name, hook)
50
+ insert(priority, name, hook) unless
51
+ @list.find {|try_name, try_priority, try_hook| try_name == name}
107
52
  end
108
-
53
+
54
+ # Run each function in `hooks' with args
55
+ def run(*args)
56
+ @list.each do |name, priority, hook|
57
+ hook.call(name, *args)
58
+ end
59
+ end
60
+
61
+ # Could add delete_at and delete if necessary.
62
+ end
63
+
64
+ def hook_initialize(commands)
65
+ @cmdloop_posthooks = Hook.new
66
+ @cmdloop_prehooks = Hook.new
67
+ @unconditional_prehooks = Hook.new
68
+
69
+ irb_cmd = commands['shell']
70
+ @autoirb_hook = ['autoirb',
71
+ Proc.new{|*args| irb_cmd.run(['shell']) if irb_cmd}]
72
+
73
+ @debug_dbgr_hook = ['dbgdbgr',
74
+ Proc.new{|*args|
75
+ if settings[:debugdbgr]
76
+ $trepan_cmdproc = self
77
+ $trepan_frame = @frame
78
+ else
79
+ $trepan_cmdproc = nil
80
+ $trepan_frame = nil
81
+ end}]
82
+
83
+ display_cmd = commands['display']
84
+ @display_hook = ['display',
85
+ Proc.new{|*args| display_cmd.run(['display']) if display_cmd}]
86
+
87
+ # FIXME: generalize for any command run
88
+ dis_cmd = commands['disassemble']
89
+ @autodis_hook = ['autodis',
90
+ Proc.new{|*args| dis_cmd.run(['disassemble']) if dis_cmd}]
91
+
92
+ list_cmd = commands['list']
93
+ @autolist_hook = ['autolist',
94
+ Proc.new{|*args| list_cmd.run(['list']) if list_cmd}]
95
+
96
+ @timer_hook = ['timer',
97
+ Proc.new{|*args|
98
+ now = Time.now
99
+ msg("%g seconds" %
100
+ (now - @time_last)) if @time_last
101
+ @time_last = now
102
+ }]
103
+ @timer_posthook = ['timer', Proc.new{|*args| @time_last = Time.now}]
104
+ @trace_hook = ['trace',
105
+ Proc.new{|*args| print_location}]
106
+ @tracebuf_hook = ['tracebuffer',
107
+ Proc.new{|*args| @eventbuf.append(@event, @frame,
108
+ nil)}]
109
109
  end
110
110
  end
111
+
111
112
  if __FILE__ == $0
112
113
  # Demo it.
113
114
  hooks = Trepan::CmdProcessor::Hook.new
data/processor/list.rb ADDED
@@ -0,0 +1,123 @@
1
+ # Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
+
3
+ # Trepan command list validation routines. A String type is
4
+ # usually passed in as the argument to validation routines.
5
+
6
+ require 'rubygems'
7
+ require 'require_relative'
8
+
9
+ require_relative './validate'
10
+
11
+ class Trepan
12
+ class CmdProcessor < VirtualCmdProcessor
13
+
14
+ # If last is less than first, assume last is a count rather than an
15
+ # end line number. If last is negative, range is [first+last..first].
16
+ def adjust_last(first, last)
17
+ last < first ? first + last - 1 : last
18
+ end
19
+
20
+ # Parse a list command. On success return:
21
+ # - compiled method
22
+ # - the line number - a Fixnum
23
+ # - file name
24
+ # - last line
25
+ def parse_list_cmd(position_str, listsize, center_correction=0)
26
+ cm = nil
27
+ if position_str.empty?
28
+ filename = frame.file
29
+ first = [1, frame.line - center_correction].max
30
+ else
31
+ list_cmd_parse = parse_list(position_str,
32
+ :file_exists_proc => file_exists_proc)
33
+ return [nil] * 4 unless list_cmd_parse
34
+ last = list_cmd_parse.num
35
+ position = list_cmd_parse.position
36
+
37
+ if position.is_a?(String)
38
+ if position == '-'
39
+ return no_frame_msg_for_list unless frame.line
40
+ first = [1, frame.line - 2*listsize - 1].max
41
+ elsif position == '.'
42
+ return no_frame_msg_for_list unless frame.line
43
+ if (second = list_cmd_parse.num)
44
+ first = frame.line
45
+ last = adjust_last(first, second)
46
+ else
47
+ first = [1, frame.line - center_correction].max
48
+ last = first + listsize - 1
49
+ end
50
+ end
51
+ filename = frame.file
52
+ cm = frame.method
53
+ else
54
+ cm, filename, offset, offset_type =
55
+ parse_position(position)
56
+
57
+ return [nil] * 4 unless filename
58
+ if offset_type == :line
59
+ first = offset
60
+ elsif cm
61
+ first, vm_offset =
62
+ position_to_line_and_offset(cm, filename, position,
63
+ offset_type)
64
+ unless first
65
+ errmsg("Unable to get location in #{meth_or_frame}")
66
+ return [nil] * 4
67
+ end
68
+ elsif !offset
69
+ first = 1
70
+ else
71
+ errmsg("Unable to parse list position #{position_str}")
72
+ return [nil] * 4
73
+ end
74
+ end
75
+ end
76
+ if last
77
+ first, last = [first + last, first] if last < 0
78
+ last = adjust_last(first, last)
79
+ else
80
+ first = [1, first - center_correction].max
81
+ last = first + listsize - 1 unless last
82
+ end
83
+ LineCache::cache(filename) unless LineCache::cached?(filename)
84
+ return [cm, filename, first, last]
85
+ end
86
+
87
+ def no_frame_msg_for_list
88
+ errmsg("No Ruby program loaded.")
89
+ return [nil] * 4
90
+ end
91
+
92
+ end
93
+ end
94
+
95
+ if __FILE__ == $0
96
+ # Demo it.
97
+ require_relative 'mock'
98
+ require_relative 'frame'
99
+ dbgr, cmd = MockDebugger::setup('exit', false)
100
+ cmdproc = cmd.proc
101
+ cmdproc.frame_initialize
102
+ cmdproc.instance_variable_set('@settings',
103
+ Trepan::CmdProcessor::DEFAULT_SETTINGS)
104
+ def foo; 5 end
105
+ def cmdproc.errmsg(msg)
106
+ puts msg
107
+ end
108
+ puts '-' * 20
109
+ p cmdproc.parse_list_cmd('.', 10)
110
+ p cmdproc.parse_list_cmd('-', 10)
111
+ p cmdproc.parse_list_cmd('foo', 10)
112
+ p cmdproc.parse_list_cmd('@0', 10)
113
+ p cmdproc.parse_list_cmd("#{__LINE__}", 10)
114
+ p cmdproc.parse_list_cmd("#{__FILE__} @0", 10)
115
+ p '-' * 40
116
+ # require_relative '../lib/trepanning'; debugger
117
+ p cmdproc.parse_list_cmd("#{__FILE__}:#{__LINE__}", 10)
118
+ p cmdproc.parse_list_cmd("#{__FILE__} #{__LINE__}", 10)
119
+ p '-' * 40
120
+ p cmdproc.parse_list_cmd("cmdproc.errmsg", 10)
121
+ p cmdproc.parse_list_cmd("cmdproc.errmsg:@0", 10)
122
+ p cmdproc.parse_list_cmd("cmdproc.errmsg:@0", -10)
123
+ end
@@ -7,8 +7,9 @@ require 'tmpdir'
7
7
  # Sets @commands, @aliases, @macros
8
8
  require 'rubygems'; require 'require_relative'
9
9
  require_relative '../app/complete'
10
+ require_relative 'virtual'
10
11
  class Trepan
11
- class CmdProcessor
12
+ class CmdProcessor < VirtualCmdProcessor
12
13
 
13
14
  attr_reader :aliases # Hash[String] of command names
14
15
  # indexed by alias name
@@ -16,6 +17,8 @@ class Trepan
16
17
  # indexed by name
17
18
  attr_reader :macros # Hash[String] of Proc objects
18
19
  # indexed by macro name.
20
+ attr_reader :leading_str # leading part of string. Used in
21
+ # command completion
19
22
 
20
23
  # "initialize" for multi-file class. Called from main.rb's "initialize".
21
24
  def load_cmds_initialize
@@ -37,10 +40,14 @@ class Trepan
37
40
  def load_debugger_commands(file_or_dir)
38
41
  if File.directory?(file_or_dir)
39
42
  dir = File.expand_path(file_or_dir)
43
+ # change $0 so it doesn't get in the way of __FILE__ = $0
44
+ old_dollar0 = $0
45
+ $0 = ''
40
46
  Dir.glob(File.join(dir, '*.rb')).each do |rb|
41
47
  # We use require so that multiple calls have no effect.
42
48
  require rb
43
49
  end
50
+ $0 = old_dollar0
44
51
  elsif File.readable?(file_or_dir)
45
52
  # We use load in case we are reloading.
46
53
  # 'require' would not be effective here
@@ -138,6 +145,7 @@ class Trepan
138
145
  # and macros for completion. However we won't include aliases which
139
146
  # are prefixes of other commands.
140
147
  def complete(str, last_token)
148
+ @leading_str = str
141
149
  next_blank_pos, token = Trepan::Complete.next_token(str, 0)
142
150
  return [''] if token.empty? && !last_token.empty?
143
151
  match_pairs = Trepan::Complete.complete_token_with_next(@commands,
@@ -1,223 +1,228 @@
1
1
  # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
2
- require 'pathname' # For cleanpath
3
2
  require 'rubygems';
3
+ require 'pathname' # For cleanpath
4
4
  require 'linecache'
5
5
  require 'require_relative'
6
6
  require_relative 'disassemble'
7
7
  require_relative 'msg'
8
8
  require_relative 'frame'
9
- class Trepan
10
- class CmdProcessor
11
- attr_accessor :reload_on_change
12
-
13
- def location_initialize
14
- @reload_on_change = nil
9
+ require_relative '../app/file'
10
+ require_relative 'virtual'
11
+ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
12
+
13
+ unless defined?(EVENT2ICON)
14
+ # Event icons used in printing locations.
15
+ EVENT2ICON = {
16
+ 'brkpt' => 'xx',
17
+ 'tbrkpt' => 'x1',
18
+ 'c-call' => 'C>',
19
+ 'c-return' => '<C',
20
+ 'step-call' => '->',
21
+ 'call' => '->',
22
+ 'class' => '::',
23
+ 'coverage' => '[]',
24
+ 'debugger-call' => ':o',
25
+ 'end' => '-|',
26
+ 'line' => '--',
27
+ 'raise' => '!!',
28
+ 'return' => '<-',
29
+ 'start' => '>>',
30
+ 'switch' => 'sw',
31
+ 'trace-var' => '$V',
32
+ 'unknown' => '?!',
33
+ 'vm' => 'VM',
34
+ 'vm-insn' => '..',
35
+ }
15
36
  end
16
37
 
17
- def canonic_file(filename)
18
- # For now we want resolved filenames
19
- @settings[:basename] ? File.basename(filename) :
20
- # Cache this?
21
- File.expand_path(Pathname.new(filename).cleanpath.to_s)
38
+ def canonic_file(filename, resolve=true)
39
+ # For now we want resolved filenames
40
+ if @settings[:basename]
41
+ return File.basename(filename)
22
42
  end
23
-
24
- # Return the text to the current source line.
25
- # FIXME: loc_and_text should call this rather than the other
26
- # way around.
27
- def current_source_text
28
- opts = {:reload_on_change => @reload_on_change}
29
- loc, junk, text = loc_and_text(source_location_info, opts)
30
- text
31
- end
32
-
33
- def resolve_file_with_dir(path_suffix)
34
- settings[:directory].split(/:/).each do |dir|
35
- dir =
36
- if '$cwd' == dir
37
- Dir.pwd
38
- elsif '$cdir' == dir
39
- Rubinius::OS_STARTUP_DIR
40
- else
41
- dir
42
- end
43
- next unless dir && File.directory?(dir)
44
- try_file = File.join(dir, path_suffix)
45
- return try_file if File.readable?(try_file)
43
+ if resolve
44
+ try_filename = LineCache::map_file(filename)
45
+ filename = try_filename || filename
46
+ if !File.exist?(filename)
47
+ if (try_filename = find_load_path(filename))
48
+ return try_filename
49
+ elsif (try_filename = resolve_file_with_dir(filename))
50
+ return try_filename
51
+ else
52
+ return File.expand_path(Pathname.new(filename).cleanpath.to_s).
53
+ gsub(/\.rbc$/, '.rb')
54
+ end
46
55
  end
47
- nil
48
56
  end
57
+ return filename.gsub(/\.rbc$/, '.rb')
58
+ end
49
59
 
50
- # Get line +line_number+ from file named +filename+. Return "\n"
51
- # there was a problem. Leading blanks are stripped off.
52
- def line_at(filename, line_number,
53
- opts = {
54
- :reload_on_change => @reload_on_change,
55
- :output => @settings[:highlight]
56
- })
57
- # We use linecache first to give precidence to user-remapped
58
- # file names
59
- line = LineCache::getline(filename, line_number, opts)
60
- unless line
61
- # Try using search directories (set with command "directory")
62
- if filename[0..0] != File::SEPARATOR
63
- try_filename = resolve_file_with_dir(filename)
64
- if try_filename &&
65
- line = LineCache::getline(try_filename, line_number, opts)
66
- LineCache::remap_file(filename, try_filename)
60
+ # Return the text to the current source line.
61
+ # FIXME: loc_and_text should call this rather than the other
62
+ # way around.
63
+ def current_source_text
64
+ opts = {:reload_on_change => settings[:reload]}
65
+ loc, junk, text = loc_and_text(source_location_info, opts)
66
+ text
67
+ end
68
+
69
+ def resolve_file_with_dir(path_suffix)
70
+ settings[:directory].split(/:/).each do |dir|
71
+ dir =
72
+ if '$cwd' == dir
73
+ Dir.pwd
74
+ elsif '$cdir' == dir
75
+ Rubinius::OS_STARTUP_DIR
76
+ elsif '$rbx' == dir
77
+ compiler_file = '/lib/compiler/compiler.rb'
78
+ compiler_rb_path =
79
+ $LOADED_FEATURES.find{|f| f.end_with?(compiler_file)}
80
+ if compiler_rb_path
81
+ compiler_rb_path[0...-(compiler_file.size)]
82
+ else
83
+ nil
67
84
  end
85
+ else
86
+ dir
68
87
  end
69
- end
70
- return nil unless line
71
- return line.lstrip.chomp
88
+ next unless dir && File.directory?(dir)
89
+ try_file = File.join(dir, path_suffix)
90
+ return try_file if File.readable?(try_file)
72
91
  end
73
-
74
- def loc_and_text(loc, opts=
75
- {:reload_on_change => @reload_on_change,
76
- :output => @settings[:highlight]
77
- })
78
-
79
- vm_location = @frame.vm_location
80
- filename = vm_location.method.active_path
81
- line_no = vm_location.line
82
- static = vm_location.static_scope
83
- opts[:compiled_method] = top_scope(@frame.method)
84
-
85
- if @frame.eval?
86
- file = LineCache::map_script(static.script)
87
- text = LineCache::getline(static.script, line_no, opts)
88
- loc += " remapped #{canonic_file(file)}:#{line_no}"
89
- else
90
- text = line_at(filename, line_no, opts)
91
- map_file, map_line = LineCache::map_file_line(filename, line_no)
92
- if [filename, line_no] != [map_file, map_line]
93
- loc += " remapped #{canonic_file(map_file)}:#{map_line}"
92
+ nil
93
+ end
94
+
95
+ # Get line +line_number+ from file named +filename+. Return "\n"
96
+ # there was a problem. Leading blanks are stripped off.
97
+ def line_at(filename, line_number,
98
+ opts = {
99
+ :reload_on_change => @settings[:reload],
100
+ :output => @settings[:highlight]
101
+ })
102
+ # We use linecache first to give precidence to user-remapped
103
+ # file names
104
+ line = LineCache::getline(filename, line_number, opts)
105
+ unless line
106
+ # Try using search directories (set with command "directory")
107
+ if filename[0..0] != File::SEPARATOR
108
+ try_filename = resolve_file_with_dir(filename)
109
+ if try_filename &&
110
+ line = LineCache::getline(try_filename, line_number, opts)
111
+ LineCache::remap_file(filename, try_filename)
94
112
  end
95
113
  end
96
-
97
- [loc, line_no, text]
98
- end
99
-
100
- def format_location(event=@event, frame=@frame, frame_index=@frame_index)
101
- text = nil
102
- ev = if event.nil? || 0 != frame_index
103
- ' '
104
- else
105
- (EVENT2ICON[event] || event)
106
- end
107
-
108
- @line_no = frame.vm_location.line
109
-
110
- loc = source_location_info
111
- loc, @line_no, text = loc_and_text(loc)
112
- ip_str = frame.method ? " @#{frame.next_ip}" : ''
113
-
114
- "#{ev} (#{loc}#{ip_str})"
115
114
  end
116
-
117
- # FIXME: Use above format_location routine
118
- def print_location
119
- # if %w(c-call call).member?(@event)
120
- # # FIXME: Fix Ruby so we don't need this workaround?
121
- # # See also where.rb
122
- # opts = {}
123
- # opts[:class] = @core.hook_arg if
124
- # 'CFUNC' == @frame.type && @core.hook_arg && 0 == @frame_index
125
- # msg format_stack_call(@frame, opts)
126
- # elsif 'raise' == @core.event
127
- # msg @core.hook_arg.inspect if @core.hook_arg # Exception object
128
- # end
129
-
130
- text = nil
131
- # source_container = frame_container(@frame, false)
132
- ev = if @event.nil? || 0 != @frame_index
133
- ' '
134
- else
135
- (EVENT2ICON[@event] || @event)
136
- end
137
-
138
- @line_no = @frame.vm_location.line
139
-
140
- loc = source_location_info
141
- loc, @line_no, text = loc_and_text(loc)
142
- ip_str = frame.method ? " @#{frame.next_ip}" : ''
143
-
144
- msg "#{ev} (#{loc}#{ip_str})"
145
-
146
- # if %w(return c-return).member?(@core.event)
147
- # retval = Trepan::Frame.value_returned(@frame, @core.event)
148
- # msg 'R=> %s' % retval.inspect
149
- # end
150
-
151
- if text && !text.strip.empty?
152
- old_maxstring = @settings[:maxstring]
153
- @settings[:maxstring] = -1
154
- msg text
155
- @settings[:maxstring] = old_maxstring
156
- @line_no -= 1
157
- else
158
- show_bytecode
115
+ return nil unless line
116
+ return line.lstrip.chomp
117
+ end
118
+
119
+ def loc_and_text(loc, opts=
120
+ {:reload_on_change => @settings[:reload],
121
+ :output => @settings[:highlight]
122
+ })
123
+
124
+ vm_location = @frame.vm_location
125
+ filename = vm_location.method.active_path
126
+ line_no = @frame.line
127
+ static = vm_location.static_scope
128
+ opts[:compiled_method] = top_scope(@frame.method)
129
+
130
+ if @frame.eval?
131
+ file = LineCache::map_script(static.script)
132
+ text = LineCache::getline(static.script, line_no, opts)
133
+ loc += " remapped #{canonic_file(file)}:#{line_no}"
134
+ else
135
+ text = line_at(filename, line_no, opts)
136
+ map_file, map_line = LineCache::map_file_line(filename, line_no)
137
+ if [filename, line_no] != [map_file, map_line]
138
+ loc += " remapped #{canonic_file(map_file)}:#{map_line}"
159
139
  end
160
140
  end
161
-
162
- # def print_location(event=@event, frame=@frame)
163
- # text = format_location(event, frame)
164
- # if text && !text.strip.empty?
165
- # old_maxstring = @settings[:maxstring]
166
- # @settings[:maxstring] = -1
167
- # msg text
168
- # @settings[:maxstring] = old_maxstring
169
- # @line_no -= 1
170
- # else
171
- # show_bytecode
172
- # end
141
+ [loc, line_no, text]
142
+ end
143
+
144
+ def format_location(event=@event, frame=@frame, frame_index=@frame_index)
145
+ text = nil
146
+ ev = if event.nil? || 0 != frame_index
147
+ ' '
148
+ else
149
+ (EVENT2ICON[event] || event)
150
+ end
151
+
152
+ @line_no = frame.line
153
+
154
+ loc = source_location_info
155
+ loc, @line_no, text = loc_and_text(loc)
156
+ ip_str = frame.method ? " @#{frame.next_ip}" : ''
157
+
158
+ "#{ev} (#{loc}#{ip_str})"
159
+ end
160
+
161
+ # FIXME: Use above format_location routine
162
+ def print_location
163
+ text = nil
164
+ ev = if @event.nil? || 0 != @frame_index
165
+ ' '
166
+ else
167
+ (EVENT2ICON[@event] || @event)
168
+ end
169
+
170
+ @line_no = @frame.line
171
+
172
+ loc = source_location_info
173
+ loc, @line_no, text = loc_and_text(loc)
174
+ ip_str = frame.method ? " @#{frame.next_ip}" : ''
175
+
176
+ msg "#{ev} (#{loc}#{ip_str})"
177
+
178
+ # if %w(return c-return).member?(@core.event)
179
+ # retval = Trepan::Frame.value_returned(@frame, @core.event)
180
+ # msg 'R=> %s' % retval.inspect
173
181
  # end
174
-
175
- def source_location_info
176
- filename = @frame.vm_location.method.active_path
177
- canonic_filename =
178
- if @frame.eval?
179
- 'eval ' + safe_repr(@frame.eval_string.gsub("\n", ';').inspect, 20)
180
- else
181
- canonic_file(filename)
182
- end
183
- loc = "#{canonic_filename}:#{@frame.vm_location.line}"
184
- return loc
185
- end
186
-
182
+
183
+ if text && !text.strip.empty?
184
+ old_maxstring = @settings[:maxstring]
185
+ @settings[:maxstring] = -1
186
+ msg text
187
+ @settings[:maxstring] = old_maxstring
188
+ @line_no -= 1
189
+ else
190
+ show_bytecode
191
+ end
187
192
  end
193
+
194
+ def source_location_info
195
+ filename = @frame.vm_location.method.active_path
196
+ canonic_filename =
197
+ if @frame.eval?
198
+ 'eval ' + safe_repr(@frame.eval_string.gsub("\n", ';').inspect, 20)
199
+ else
200
+ canonic_file(filename, false)
201
+ end
202
+ loc = "#{canonic_filename}:#{@frame.line}"
203
+ return loc
204
+ end
188
205
  end
189
206
 
190
- if __FILE__ == $0 && caller.size == 0 && ARGV.size > 0
207
+ if __FILE__ == $0 && caller.size == 0
191
208
  # Demo it.
192
- require 'thread_frame'
193
- require_relative 'frame'
194
- require_relative '../app/mock'
195
- require_relative 'main' # Have to include before defining CmdProcessor!
196
- # FIXME
197
- class Trepan::CmdProcessor
198
- def errmsg(msg)
199
- puts msg
200
- end
201
- def print_location
202
- puts "#{@frame.source_container} #{frame.source_location[0]}"
203
- end
204
- end
205
-
206
- proc = Trepan::CmdProcessor.new(Trepan::MockCore.new())
207
- proc.instance_variable_set('@settings', {})
208
- proc.frame_initialize
209
- #proc.frame_setup(RubyVM::ThreadFrame.current)
209
+ require_relative './mock'
210
+ dbgr = MockDebugger::MockDebugger.new
211
+ proc = Trepan::CmdProcessor.new(dbgr)
212
+ proc.settings = {:directory => '$rbx:$cdir:$cwd'}
210
213
  proc.frame_initialize
214
+ frame = Trepan::Frame.new(self, 1, Rubinius::VM.backtrace(0)[0])
215
+ proc.instance_variable_set('@frame', frame)
211
216
 
212
- proc.location_initialize
213
217
  puts proc.canonic_file(__FILE__)
214
- proc.instance_variable_set('@settings', {:basename => true})
218
+ puts proc.canonic_file('lib/compiler/ast.rb')
219
+ proc.settings[:basename] = true
215
220
  puts proc.canonic_file(__FILE__)
216
221
  puts proc.current_source_text
217
222
  xx = eval <<-END
218
223
  proc.frame_initialize
219
- ##proc.frame_setup(RubyVM::ThreadFrame.current)
220
- proc.location_initialize
221
- proc.current_source_text
224
+ frame = Trepan::Frame.new(self, 1, Rubinius::VM.backtrace(0)[0])
225
+ proc.instance_variable_set('@frame', frame)
226
+ puts proc.current_source_text
222
227
  END
223
228
  end