trepanning 1.93.35 → 2.15.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +491 -55
  3. data/LICENSE +1 -1
  4. data/NEWS +18 -14
  5. data/README.md +5 -22
  6. data/Rakefile +22 -1
  7. data/app/breakpoint.rb +5 -3
  8. data/app/core.rb +147 -179
  9. data/app/default.rb +47 -46
  10. data/app/file.rb +6 -7
  11. data/app/frame.rb +183 -176
  12. data/app/markdown.rb +2 -9
  13. data/app/options.rb +1 -1
  14. data/app/run.rb +71 -37
  15. data/interface/script.rb +8 -8
  16. data/io.rb +19 -20
  17. data/lib/trepanning.rb +292 -297
  18. data/processor.rb +332 -344
  19. data/processor/breakpoint.rb +98 -96
  20. data/processor/command/base/submgr.rb +9 -9
  21. data/processor/command/break.rb +40 -38
  22. data/processor/command/continue.rb +15 -10
  23. data/processor/command/debug.rb +6 -25
  24. data/processor/command/delete.rb +21 -12
  25. data/processor/command/directory.rb +15 -13
  26. data/processor/command/disable.rb +12 -9
  27. data/processor/command/disassemble.rb +80 -74
  28. data/processor/command/display.rb +15 -12
  29. data/processor/command/down.rb +8 -3
  30. data/processor/command/edit.rb +37 -23
  31. data/processor/command/enable.rb +11 -8
  32. data/processor/command/eval.rb +24 -22
  33. data/processor/command/finish.rb +50 -48
  34. data/processor/command/help.rb +1 -1
  35. data/processor/command/info_subcmd/breakpoints.rb +7 -7
  36. data/processor/command/info_subcmd/files.rb +195 -196
  37. data/processor/command/info_subcmd/frame.rb +7 -4
  38. data/processor/command/info_subcmd/locals.rb +29 -12
  39. data/processor/command/info_subcmd/program.rb +48 -39
  40. data/processor/command/info_subcmd/registers_subcmd/ep.rb +46 -0
  41. data/processor/command/info_subcmd/registers_subcmd/helper.rb +32 -35
  42. data/processor/command/info_subcmd/registers_subcmd/sp.rb +29 -23
  43. data/processor/command/info_subcmd/return.rb +28 -10
  44. data/processor/command/info_subcmd/variables_subcmd/class.rb +3 -3
  45. data/processor/command/info_subcmd/variables_subcmd/constants.rb +77 -0
  46. data/processor/command/info_subcmd/variables_subcmd/globals.rb +7 -7
  47. data/processor/command/info_subcmd/variables_subcmd/instance.rb +68 -22
  48. data/processor/command/info_subcmd/variables_subcmd/locals.rb +148 -67
  49. data/processor/command/list.rb +14 -8
  50. data/processor/command/macro.rb +1 -1
  51. data/processor/command/next.rb +1 -0
  52. data/processor/command/set_subcmd/auto.rb +3 -3
  53. data/processor/command/set_subcmd/different.rb +30 -29
  54. data/processor/command/set_subcmd/events.rb +74 -48
  55. data/processor/command/set_subcmd/max_subcmd/list.rb +12 -5
  56. data/processor/command/set_subcmd/max_subcmd/width.rb +28 -19
  57. data/processor/command/set_subcmd/register.rb +37 -0
  58. data/processor/command/set_subcmd/register_subcmd/pc.rb +67 -0
  59. data/processor/command/set_subcmd/register_subcmd/sp.rb +75 -0
  60. data/processor/command/set_subcmd/reload.rb +12 -10
  61. data/processor/command/set_subcmd/return.rb +68 -44
  62. data/processor/command/shell.rb +3 -2
  63. data/processor/command/show_subcmd/different.rb +17 -14
  64. data/processor/command/show_subcmd/events.rb +25 -25
  65. data/processor/default.rb +1 -1
  66. data/processor/eval.rb +14 -15
  67. data/processor/frame.rb +43 -36
  68. data/processor/help.rb +5 -5
  69. data/processor/hook.rb +26 -29
  70. data/processor/location.rb +54 -51
  71. data/processor/mock.rb +4 -3
  72. data/processor/running.rb +113 -103
  73. data/processor/validate.rb +401 -373
  74. data/test/data/debug.cmd +8 -0
  75. data/test/data/debug.right +13 -0
  76. data/test/data/debugger-stop.right +6 -4
  77. data/test/data/fname-with-blank.cmd +1 -1
  78. data/test/data/fname-with-blank.right +5 -0
  79. data/test/data/pc.cmd +8 -0
  80. data/test/data/pc.right +10 -0
  81. data/test/data/quit.right +3 -1
  82. data/test/data/trace.cmd +2 -2
  83. data/test/data/trace.right +41 -20
  84. data/test/example/assign.rb +6 -0
  85. data/test/functional/fn_helper.rb +11 -17
  86. data/test/functional/test-break-long.rb +15 -16
  87. data/test/functional/test-break.rb +6 -8
  88. data/test/functional/test-condition.rb +8 -10
  89. data/test/functional/test-debugger-call-bug.rb +21 -22
  90. data/test/functional/test-delete.rb +57 -59
  91. data/test/functional/test-eval.rb +101 -103
  92. data/test/functional/test-finish.rb +24 -33
  93. data/test/functional/test-immediate-step-bug.rb +6 -10
  94. data/test/functional/test-next.rb +64 -65
  95. data/test/functional/test-raise.rb +63 -64
  96. data/test/functional/test-recursive-bt.rb +81 -76
  97. data/test/functional/test-remap.rb +6 -7
  98. data/test/functional/test-return.rb +44 -38
  99. data/test/functional/test-step.rb +55 -53
  100. data/test/functional/test-stepbug.rb +6 -9
  101. data/test/functional/test-watchg.rb +40 -39
  102. data/test/integration/test-debug.rb +12 -0
  103. data/test/integration/test-debugger-stop.rb +7 -7
  104. data/test/integration/test-pc.rb +24 -0
  105. data/test/integration/test-trace.rb +1 -1
  106. data/test/unit/cmd-helper.rb +0 -1
  107. data/test/unit/test-app-brkpt.rb +21 -21
  108. data/test/unit/test-app-brkptmgr.rb +7 -8
  109. data/test/unit/test-app-display.rb +3 -4
  110. data/test/unit/test-app-frame.rb +4 -5
  111. data/test/unit/test-base-subsubcmd.rb +2 -2
  112. data/test/unit/test-cmd-break.rb +6 -6
  113. data/test/unit/test-cmd-endisable.rb +7 -6
  114. data/test/unit/test-cmd-parse_list_cmd.rb +24 -24
  115. data/test/unit/test-io-tcpserver.rb +39 -35
  116. data/test/unit/test-proc-default.rb +23 -22
  117. data/test/unit/test-proc-eval.rb +1 -2
  118. data/test/unit/test-proc-frame.rb +8 -9
  119. data/test/unit/test-proc-list.rb +1 -1
  120. data/test/unit/test-proc-location.rb +2 -2
  121. data/test/unit/test-proc-main.rb +10 -10
  122. data/test/unit/test-proc-validate.rb +11 -13
  123. data/test/unit/test-subcmd-help.rb +1 -2
  124. data/trepanning.gemspec +8 -13
  125. metadata +44 -95
  126. data/COPYING +0 -57
  127. data/data/custom_require.rb +0 -44
  128. data/data/perldb.bindings +0 -17
  129. data/data/prelude.rb +0 -38
  130. data/processor/command/info_subcmd/variables_subcmd/constant.rb +0 -41
  131. data/processor/command/raise.rb +0 -48
  132. data/processor/command/set_subcmd/pc.rb +0 -62
  133. data/processor/command/set_subcmd/sp.rb +0 -67
  134. data/processor/eventbuf.rb +0 -133
@@ -40,6 +40,7 @@ module MockDebugger
40
40
 
41
41
  # Don't allow user commands in mocks.
42
42
  @core.processor.settings[:user_cmd_dir] = nil
43
+ @core.processor.hidelevels = {}
43
44
 
44
45
  end
45
46
 
@@ -51,7 +52,7 @@ module MockDebugger
51
52
  # Common Mock debugger setup
52
53
  def setup(name=nil, show_constants=true)
53
54
  unless name
54
- tf = RubyVM::Frame.current.prev
55
+ tf = RubyVM::Frame.get(1)
55
56
  name = File.basename(tf.source_container[1], '.rb')
56
57
  end
57
58
  if ARGV.size > 0 && ARGV[0] == 'debug'
@@ -64,7 +65,7 @@ module MockDebugger
64
65
 
65
66
  cmds = dbgr.core.processor.commands
66
67
  cmd = cmds[name]
67
- cmd.proc.frame_setup(RubyVM::Frame::current.prev)
68
+ cmd.proc.frame_setup(RubyVM::Frame::get(1))
68
69
  show_special_class_constants(cmd) if show_constants
69
70
 
70
71
  def cmd.confirm(prompt, default)
@@ -90,7 +91,7 @@ module MockDebugger
90
91
  def sub_setup(sub_class, run=true)
91
92
  sub_name = sub_class.const_get('PREFIX')
92
93
  dbgr, cmd = setup(sub_name[0], false)
93
- cmd.proc.frame_setup(RubyVM::Frame::current.prev)
94
+ cmd.proc.frame_setup(RubyVM::Frame::get)
94
95
  cmd.proc.event = 'debugger-call'
95
96
  sub_cmd = sub_class.new(cmd)
96
97
  sub_cmd.summary_help(sub_cmd)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2015 Rocky Bernstein <rockyb@rubyforge.net>
2
2
  require_relative 'virtual'
3
3
  class Trepan
4
4
  class CmdProcessor < VirtualCmdProcessor
@@ -16,57 +16,65 @@ class Trepan
16
16
  # be more temporarily changed via
17
17
  # "step>" or "step!" commands.
18
18
  attr_accessor :to_method
19
-
19
+
20
20
  # Does whatever needs to be done to set to continue program
21
21
  # execution.
22
22
  # FIXME: turn line_number into a condition.
23
23
  def continue
24
- @next_level = 32000 # I'm guessing the stack size can't
25
- # ever reach this
26
- @next_thread = nil
27
- if @settings[:traceprint]
28
- @core.step_count = 1 # traceprint will avoid stopping
29
- else
30
- @core.step_count = -1 # No more event stepping
31
- end
32
- @leave_cmd_loop = true # Break out of the processor command loop.
24
+
25
+ # FIXME: with the ruby-supported stepping, we might not
26
+ # need the below any more.
27
+ # I'm guessing the stack size can't ever reach this
28
+ @next_level = 32000
29
+
30
+ @next_thread = nil
31
+ if @settings[:traceprint]
32
+ @core.step_count = 1 # traceprint will avoid stopping
33
+ else
34
+ @core.step_count = -1 # No more event stepping
35
+ end
36
+ @leave_cmd_loop = true # Break out of the processor command loop.
33
37
  end
34
38
 
35
39
  # Does whatever setup needs to be done to set to ignore stepping
36
40
  # to the finish of the current method.
37
41
  def finish(level_count=0, opts={})
38
- step(0, opts)
39
- @next_level = @frame.stack_size - level_count
40
- @next_thread = Thread.current
41
- @stop_events = Set.new(%w(return leave yield))
42
-
43
- # Try high-speed (run-time-assisted) method
44
- @frame.trace_off = true # No more tracing in this frame
45
- @frame.return_stop = true # don't need to
42
+ step(0, opts)
43
+ # @next_level = @frame.stack_size - level_count
44
+ # @next_thread = Thread.current
45
+ # @stop_events = Set.new(%w(return leave yield))
46
+
47
+ # Try high-speed (run-time-assisted) method
48
+ # FIXME: if frame is not the top frame, then we should to do more...
49
+ @frame.step_out
46
50
  end
47
51
 
48
52
  # Does whatever needs to be done to set to do "step over" or ignore
49
- # stepping into methods called from this stack but step into any in
53
+ # stepping into methods called from this stack but step into any in
50
54
  # the same level. We do this by keeping track of the number of
51
55
  # stack frames and the current thread. Elsewhere in "skipping_step?"
52
56
  # we do the checking.
53
57
  def next(step_count=1, opts={})
54
- step(step_count, opts)
55
- @next_level = @top_frame.stack_size
56
- @next_thread = Thread.current
58
+ step(step_count, opts)
59
+ # FIXME: if frame is not the top frame, then we should to do more...
60
+ # Try high-speed (run-time-assisted) method
61
+ @frame.step_over
62
+ # @next_level = @top_frame.stack_size
63
+ # @next_thread = Thread.current
57
64
  end
58
65
 
59
66
  # Does whatever needs to be done to set to step program
60
67
  # execution.
61
68
  def step(step_count=1, opts={}, condition=nil)
62
- continue
63
- @core.step_count = step_count
64
- @different_pos = opts[:different_pos] if
65
- opts.keys.member?(:different_pos)
66
- @stop_condition = condition
67
- @stop_events = opts[:stop_events] if
68
- opts.keys.member?(:stop_events)
69
- @to_method = opts[:to_method]
69
+ @frame.step_in if @frame
70
+ continue
71
+ @core.step_count = step_count
72
+ @different_pos = opts[:different_pos] if
73
+ opts.keys.member?(:different_pos)
74
+ @stop_condition = condition
75
+ @stop_events = opts[:stop_events] if
76
+ opts.keys.member?(:stop_events)
77
+ @to_method = opts[:to_method]
70
78
  end
71
79
 
72
80
  def quit(cmd='quit')
@@ -81,26 +89,26 @@ class Trepan
81
89
  end
82
90
 
83
91
  def parse_next_step_suffix(step_cmd)
84
- opts = {}
85
- case step_cmd[-1..-1]
86
- when '-'
87
- opts[:different_pos] = false
88
- when '+'
89
- opts[:different_pos] = 'nostack'
90
- when '='
91
- opts[:different_pos] = true
92
- when '!'
93
- opts[:stop_events] = Set.new(%w(raise))
94
- when '<'
95
- opts[:stop_events] = Set.new(%w(c-return return))
96
- when '>'
97
- if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
98
- opts[:stop_events] = Set.new(%w(c-call c-return call return))
99
- else
100
- opts[:stop_events] = Set.new(%w(c-call call))
92
+ opts = {}
93
+ case step_cmd[-1..-1]
94
+ when '-'
95
+ opts[:different_pos] = false
96
+ when '+'
97
+ opts[:different_pos] = 'nostack'
98
+ when '='
99
+ opts[:different_pos] = true
100
+ when '!'
101
+ opts[:stop_events] = Set.new(%w(raise))
102
+ when '<'
103
+ opts[:stop_events] = Set.new(%w(c_return return))
104
+ when '>'
105
+ if step_cmd.size > 1 && step_cmd[-2..-2] == '<'
106
+ opts[:stop_events] = Set.new(%w(c_call c_return call return))
107
+ else
108
+ opts[:stop_events] = Set.new(%w(c_call call))
109
+ end
101
110
  end
102
- end
103
- return opts
111
+ return opts
104
112
  end
105
113
 
106
114
  def running_initialize
@@ -111,67 +119,69 @@ class Trepan
111
119
 
112
120
  def stepping_skip?
113
121
 
114
- return true if @core.step_count < 0
122
+ return true if @core.step_count < 0
123
+
124
+ if @settings[:'debugskip']
125
+ msg "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
126
+ msg "step_count : #{@core.step_count}"
127
+ msg "next_level : #{@next_level}, ssize : #{@stack_size}"
128
+ msg "next_thread : #{@next_thread}, thread: #{Thread.current}"
129
+ end
115
130
 
116
- if @settings[:'debugskip']
117
- msg "diff: #{@different_pos}, event : #{@event}, #{@stop_events.inspect}"
118
- msg "step_count : #{@core.step_count}"
119
- msg "next_level : #{@next_level}, ssize : #{@stack_size}"
120
- msg "next_thread : #{@next_thread}, thread: #{Thread.current}"
121
- end
122
131
 
123
- return true if
124
- !frame || (@next_level < @frame.stack_size &&
125
- Thread.current == @next_thread && @event != 'raise')
132
+ # FIXME: with the ruby-supported stepping, we might not
133
+ # need @next_level an the below test.
134
+ return true if
135
+ !frame || (@next_level < @frame.stack_size &&
136
+ Thread.current == @next_thread && @event.to_s != 'raise')
126
137
 
127
- new_pos = [@frame.source_container, frame_line,
128
- @stack_size, @current_thread, @event, @frame.pc_offset]
138
+ new_pos = [@frame.source_container, frame_line,
139
+ @stack_size, @current_thread, @event, @frame.pc_offset]
129
140
 
130
- skip_val = @stop_events && !@stop_events.member?(@event)
141
+ skip_val = @stop_events && !@stop_events.member?(@event.to_s)
131
142
 
132
- # If the last stop was a breakpoint, don't stop again if we are at
133
- # the same location with a line event.
134
- skip_val ||= (@last_pos[4] == 'brkpt' &&
135
- @event == 'line' &&
136
- @frame.pc_offset == @last_pos[5])
143
+ # If the last stop was a breakpoint, don't stop again if we are at
144
+ # the same location with a line event.
145
+ skip_val ||= (@last_pos[4] == 'brkpt' &&
146
+ @event.to_s == 'line' &&
147
+ @frame.pc_offset == @last_pos[5])
137
148
 
138
- if @settings[:'debugskip']
139
- puts "skip: #{skip_val.inspect}, last: #{@last_pos}, new: #{new_pos}"
140
- end
149
+ if @settings[:'debugskip']
150
+ puts "skip: #{skip_val.inspect}, last: #{@last_pos}, new: #{new_pos}"
151
+ end
141
152
 
142
- @last_pos[2] = new_pos[2] if 'nostack' == @different_pos
143
- unless skip_val
144
- condition_met =
145
- if @stop_condition
153
+ @last_pos[2] = new_pos[2] if 'nostack' == @different_pos
154
+ unless skip_val
155
+ condition_met =
156
+ if @stop_condition
146
157
  puts 'stop_cond' if @settings[:'debugskip']
147
- debug_eval_no_errmsg(@stop_condition)
148
- elsif @to_method
149
- puts "method #{@frame.method} #{@to_method}" if
150
- @settings[:'debugskip']
151
- @frame.method == @to_method
152
- else
153
- puts 'uncond' if @settings[:'debugskip']
154
- true
155
- end
156
-
157
- msg("condition_met: #{condition_met}, last: #{@last_pos}, " +
158
- "new: #{new_pos}, different #{@different_pos.inspect}") if
159
- @settings[:'debugskip']
160
- skip_val = ((@last_pos[0..3] == new_pos[0..3] && @different_pos) ||
161
- !condition_met)
162
- end
163
-
164
- @last_pos = new_pos if !@stop_events || @stop_events.member?(@event)
165
-
166
- unless skip_val
167
- # Set up the default values for the
168
- # next time we consider skipping.
169
- @different_pos = @settings[:different]
170
- @stop_events = nil
171
- end
172
-
173
- return skip_val
174
- end
158
+ debug_eval_no_errmsg(@stop_condition)
159
+ elsif @to_method
160
+ puts "method #{@frame.method} #{@to_method}" if
161
+ @settings[:'debugskip']
162
+ @frame.method == @to_method
163
+ else
164
+ puts 'uncond' if @settings[:'debugskip']
165
+ true
166
+ end
167
+
168
+ msg("condition_met: #{condition_met}, last: #{@last_pos}, " +
169
+ "new: #{new_pos}, different #{@different_pos.inspect}") if
170
+ @settings[:'debugskip']
171
+ skip_val = ((@last_pos[0..3] == new_pos[0..3] && @different_pos) ||
172
+ !condition_met)
173
+ end
175
174
 
175
+ @last_pos = new_pos if !@stop_events || @stop_events.member?(@event)
176
+
177
+ unless skip_val
178
+ # Set up the default values for the
179
+ # next time we consider skipping.
180
+ @different_pos = @settings[:different]
181
+ @stop_events = nil
182
+ end
183
+
184
+ return skip_val
185
+ end
176
186
  end
177
187
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
1
+ # Copyright (C) 2010-2011, 2013, 2015 Rocky Bernstein <rockyb@rubyforge.net>
2
2
 
3
3
  # Trepan command input validation routines. A String type is
4
4
  # usually passed in as the argument to validation routines.
@@ -17,409 +17,437 @@ require_relative 'msg' # for errmsg, msg
17
17
  require_relative 'virtual'
18
18
 
19
19
  class Trepan
20
- class CmdProcessor < VirtualCmdProcessor
21
-
22
- attr_reader :dbgr_script_iseqs
23
- attr_reader :dbgr_iseqs
24
- attr_reader :file_exists_proc # Like File.exists? but checks using
25
- # cached files
26
-
27
- include Trepanning
28
- include Trepan::ThreadHelper
29
- include Trepan::Condition
30
-
31
- # Check that arg is an Integer between opts[:min_value] and
32
- # opts[:max_value]
33
- def get_an_int(arg, opts={})
34
- ret_value = get_int_noerr(arg)
35
- if !ret_value
36
- if opts[:msg_on_error]
37
- errmsg(opts[:msg_on_error])
38
- else
39
- errmsg("Expecting an integer, got: #{arg}.")
20
+ class CmdProcessor < VirtualCmdProcessor
21
+
22
+ attr_reader :dbgr_script_iseqs
23
+ attr_reader :dbgr_iseqs
24
+ attr_reader :file_exists_proc # Like File.exists? but checks using
25
+ # cached files
26
+
27
+ include Trepanning
28
+ include Trepan::ThreadHelper
29
+ include Trepan::Condition
30
+
31
+ # Return true if file is a text file. We do this based on
32
+ # reading the beginning portion and checking the encoding
33
+ # This code has been adapted from ptools. We've upped the threshhold though
34
+ # from about 30% to 90% to be able to handle DLs which have a fair amount of
35
+ # text in them.
36
+ def text_file?(file)
37
+ return false unless File.readable?(file)
38
+ bytes = File.stat(file).blksize
39
+ bytes = 4096 if bytes > 4096
40
+ s = (File.read(file, bytes) || "")
41
+ s = s.encode('US-ASCII', :undef => :replace).split(//)
42
+ return (s.grep(" ".."~").size.to_f / s.size.to_f) > 0.85
40
43
  end
41
- return nil
42
- end
43
- if opts[:min_value] and ret_value < opts[:min_value]
44
- errmsg("Expecting integer value to be at least %d; got %d." %
45
- [opts[:min_value], ret_value])
46
- return nil
47
- elsif opts[:max_value] and ret_value > opts[:max_value]
48
- errmsg("Expecting integer value to be at most %d; got %d." %
49
- [opts[:max_value], ret_value])
50
- return nil
51
- end
52
- return ret_value
53
- end
54
-
55
- unless defined?(DEFAULT_GET_INT_OPTS)
56
- DEFAULT_GET_INT_OPTS = {
57
- :min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
58
- end
59
44
 
60
- # If argument parameter 'arg' is not given, then use what is in
61
- # opts[:default]. If String 'arg' evaluates to an integer between
62
- # least min_value and at_most, use that. Otherwise report an
63
- # error. If there's a stack frame use that for bindings in
64
- # evaluation.
65
- def get_int(arg, opts={})
66
-
67
- return default unless arg
68
- opts = DEFAULT_GET_INT_OPTS.merge(opts)
69
- val = arg ? get_int_noerr(arg) : opts[:default]
70
- unless val
71
- if opts[:cmdname]
72
- errmsg(("Command '%s' expects an integer; " +
73
- "got: %s.") % [opts[:cmdname], arg])
74
- else
75
- errmsg('Expecting a positive integer, got: %s' % arg)
76
- end
77
- return nil
78
- end
79
-
80
- if val < opts[:min_value]
81
- if opts[:cmdname]
82
- errmsg(("Command '%s' expects an integer at least" +
83
- ' %d; got: %d.') %
84
- [opts[:cmdname], opts[:min_value], opts[:default]])
85
- else
86
- errmsg(("Expecting a positive integer at least" +
87
- ' %d; got: %d') %
88
- [opts[:min_value], opts[:default]])
89
- end
90
- return nil
91
- elsif opts[:max_value] and val > opts[:max_value]
92
- if opts[:cmdname]
93
- errmsg(("Command '%s' expects an integer at most" +
94
- ' %d; got: %d.') %
95
- [opts[:cmdname], opts[:max_value], val])
96
- else
97
- errmsg(("Expecting an integer at most %d; got: %d") %
98
- [opts[:max_value], val])
45
+ # Check that arg is an Integer between opts[:min_value] and
46
+ # opts[:max_value]
47
+ def get_an_int(arg, opts={})
48
+ ret_value = get_int_noerr(arg)
49
+ if !ret_value
50
+ if opts[:msg_on_error]
51
+ errmsg(opts[:msg_on_error])
52
+ else
53
+ errmsg("Expecting an integer, got: #{arg}.")
54
+ end
55
+ return nil
56
+ end
57
+ if opts[:min_value] and ret_value < opts[:min_value]
58
+ errmsg("Expecting integer value to be at least %d; got %d." %
59
+ [opts[:min_value], ret_value])
60
+ return nil
61
+ elsif opts[:max_value] and ret_value > opts[:max_value]
62
+ errmsg("Expecting integer value to be at most %d; got %d." %
63
+ [opts[:max_value], ret_value])
64
+ return nil
65
+ end
66
+ return ret_value
99
67
  end
100
- return nil
101
- end
102
- return val
103
- end
104
-
105
- def get_int_list(args, opts={})
106
- args.map{|arg| get_an_int(arg, opts)}.compact
107
- end
108
-
109
- # Eval arg and it is an integer return the value. Otherwise
110
- # return nil
111
- def get_int_noerr(arg)
112
- b = @frame ? @frame.binding : nil
113
- val = Integer(eval(arg, b))
114
- rescue SyntaxError
115
- nil
116
- rescue
117
- nil
118
- end
119
68
 
120
- def get_thread_from_string(id_or_num_str)
121
- if id_or_num_str == '.'
122
- Thread.current
123
- elsif id_or_num_str.downcase == 'm'
124
- Thread.main
125
- else
126
- num = get_int_noerr(id_or_num_str)
127
- if num
128
- get_thread(num)
129
- else
130
- nil
69
+ unless defined?(DEFAULT_GET_INT_OPTS)
70
+ DEFAULT_GET_INT_OPTS = {
71
+ :min_value => 0, :default => 1, :cmdname => nil, :max_value => nil}
131
72
  end
132
- end
133
- end
134
73
 
135
- # Return the instruction sequence associated with string
136
- # OBJECT_STRING or nil if no instruction sequence
137
- def object_iseq(object_string)
138
- iseqs = find_iseqs(ISEQS__, object_string)
139
- # FIXME: do something if there is more than one.
140
- if iseqs.size == 1
141
- iseqs[-1]
142
- elsif meth = method?(object_string)
143
- meth.iseq
144
- else
145
- nil
146
- end
147
- rescue
148
- nil
149
- end
150
-
151
- def position_to_line_and_offset(iseq, filename, position, offset_type)
152
- case offset_type
153
- when :line
154
- if ary = iseq.lineoffsets[position]
155
- # Normally the first offset is a trace instruction and doesn't
156
- # register as the given line, so we need to take the next instruction
157
- # after the first one, when available.
158
- vm_offset = ary.size > 1 ? ary[1] : ary[0]
159
- line_no = position
160
- elsif found_iseq = find_iseqs_with_lineno(filename, position)
161
- return position_to_line_and_offset(found_iseq, filename, position,
162
- offset_type)
163
- elsif found_iseq = find_iseq_with_line_from_iseq(iseq, position)
164
- return position_to_line_and_offset(found_iseq, filename, position,
165
- offset_type)
166
- else
167
- errmsg("Unable to find offset for line #{position}\n\t" +
168
- "in #{iseq.name} of file #{filename}")
169
- return [nil, nil]
74
+ # If argument parameter 'arg' is not given, then use what is in
75
+ # opts[:default]. If String 'arg' evaluates to an integer between
76
+ # least min_value and at_most, use that. Otherwise report an
77
+ # error. If there's a stack frame use that for bindings in
78
+ # evaluation.
79
+ def get_int(arg, opts={})
80
+
81
+ return default unless arg
82
+ opts = DEFAULT_GET_INT_OPTS.merge(opts)
83
+ val = arg ? get_int_noerr(arg) : opts[:default]
84
+ unless val
85
+ if opts[:cmdname]
86
+ errmsg(("Command '%s' expects an integer; " +
87
+ "got: %s.") % [opts[:cmdname], arg])
88
+ else
89
+ errmsg('Expecting a positive integer, got: %s' % arg)
90
+ end
91
+ return nil
92
+ end
93
+
94
+ if val < opts[:min_value]
95
+ if opts[:cmdname]
96
+ errmsg(("Command '%s' expects an integer at least" +
97
+ ' %d; got: %d.') %
98
+ [opts[:cmdname], opts[:min_value], opts[:default]])
99
+ else
100
+ errmsg(("Expecting a positive integer at least" +
101
+ ' %d; got: %d') %
102
+ [opts[:min_value], opts[:default]])
103
+ end
104
+ return nil
105
+ elsif opts[:max_value] and val > opts[:max_value]
106
+ if opts[:cmdname]
107
+ errmsg(("Command '%s' expects an integer at most" +
108
+ ' %d; got: %d.') %
109
+ [opts[:cmdname], opts[:max_value], val])
110
+ else
111
+ errmsg(("Expecting an integer at most %d; got: %d") %
112
+ [opts[:max_value], val])
113
+ end
114
+ return nil
115
+ end
116
+ return val
170
117
  end
171
- when :offset
172
- position = position.position unless position.kind_of?(Fixnum)
173
- if ary=iseq.offset2lines(position)
174
- line_no = ary.first
175
- vm_offset = position
176
- else
177
- errmsg "Unable to find line for offset #{position} in #{iseq}"
178
- return [nil, nil]
118
+
119
+ def get_int_list(args, opts={})
120
+ args.map{|arg| get_an_int(arg, opts)}.compact
179
121
  end
180
- when nil
181
- vm_offset = 0
182
- line_no = iseq.offset2lines(vm_offset).first
183
- else
184
- errmsg "Bad parse offset_type: #{offset_type.inspect}"
185
- return [nil, nil]
186
- end
187
- return [iseq, line_no, vm_offset]
188
- end
189
122
 
190
- # Parse a breakpoint position. On success return:
191
- # - the instruction sequence to use
192
- # - the line number - a Fixnum
193
- # - vm_offset - a Fixnum
194
- # - the condition (by default 'true') to use for this breakpoint
195
- # - true condition should be negated. Used in *condition* if/unless
196
- def breakpoint_position(position_str, allow_condition)
197
- break_cmd_parse = if allow_condition
198
- parse_breakpoint(position_str)
199
- else
200
- parse_breakpoint_no_condition(position_str)
201
- end
202
- return [nil] * 5 unless break_cmd_parse
203
- tail = [break_cmd_parse.condition, break_cmd_parse.negate]
204
- meth_or_frame, file, position, offset_type =
205
- parse_position(break_cmd_parse.position)
206
- if meth_or_frame
207
- if iseq = meth_or_frame.iseq
208
- iseq, line_no, vm_offset =
209
- position_to_line_and_offset(iseq, file, position, offset_type)
210
- if vm_offset && line_no
211
- return [iseq, line_no, vm_offset] + tail
212
- end
213
- else
214
- errmsg("Unable to set breakpoint in #{meth_or_frame}")
123
+ # Eval arg and it is an integer return the value. Otherwise
124
+ # return nil
125
+ def get_int_noerr(arg)
126
+ b = @frame ? @frame.binding : nil
127
+ val = Integer(eval(arg, b))
128
+ rescue SyntaxError
129
+ nil
130
+ rescue
131
+ nil
215
132
  end
216
- elsif file && position
217
- if :line == offset_type
218
- iseq = find_iseqs_with_lineno(file, position)
219
- if iseq
220
- junk, line_no, vm_offset =
221
- position_to_line_and_offset(iseq, file, position, offset_type)
222
- return [@frame.iseq, line_no, vm_offset] + tail
223
- else
224
- errmsg("Unable to find instruction sequence for" +
225
- " position #{position} in #{file}")
226
- end
227
- else
228
- errmsg "Come back later..."
133
+
134
+ def get_thread_from_string(id_or_num_str)
135
+ if id_or_num_str == '.'
136
+ Thread.current
137
+ elsif id_or_num_str.downcase == 'm'
138
+ Thread.main
139
+ else
140
+ num = get_int_noerr(id_or_num_str)
141
+ if num
142
+ get_thread(num)
143
+ else
144
+ nil
145
+ end
146
+ end
229
147
  end
230
- elsif @frame.respond_to?(:file) and @frame.file == file
231
- line_no, vm_offset = position_to_line_and_offset(@frame.iseq, position,
232
- offset_type)
233
- return [@frame.iseq, line_no, vm_offset] + tail
234
- else
235
- errmsg("Unable to parse breakpoint position #{position_str}")
236
- end
237
- return [nil] * 5
238
- end
239
148
 
240
- # Return true if arg is 'on' or 1 and false arg is 'off' or 0.
241
- # Any other value is raises TypeError.
242
- def get_onoff(arg, default=nil, print_error=true)
243
- unless arg
244
- if !default
245
- if print_error
246
- errmsg("Expecting 'on', 1, 'off', or 0. Got nothing.")
247
- end
248
- raise TypeError
149
+ # Return the instruction sequence associated with string
150
+ # OBJECT_STRING or nil if no instruction sequence
151
+ def object_iseq(object_string)
152
+ iseqs = find_iseqs(ISEQS__, object_string)
153
+ # FIXME: do something if there is more than one.
154
+ if iseqs.size == 1
155
+ iseqs[-1]
156
+ elsif meth = method?(object_string)
157
+ meth.iseq
158
+ else
159
+ nil
160
+ end
161
+ rescue
162
+ nil
249
163
  end
250
- return default
251
- end
252
- darg = arg.downcase
253
- return true if arg == '1' || darg == 'on'
254
- return false if arg == '0' || darg =='off'
255
-
256
- errmsg("Expecting 'on', 1, 'off', or 0. Got: %s." % arg.to_s) if
257
- print_error
258
- raise TypeError
259
- end
260
164
 
261
- include CmdParser
165
+ def position_to_line_and_offset(iseq, filename, position, offset_type)
166
+ case offset_type
167
+ when :line
168
+ if ary = iseq.lineoffsets[position]
169
+ # Also, there may be multiple offsets for a given line.
170
+ # we pick the *first* one for the line.
171
+ vm_offset = ary[0]
172
+ line_no = position
173
+ elsif found_iseq = find_iseqs_with_lineno(filename, position)
174
+ return position_to_line_and_offset(found_iseq, filename, position,
175
+ offset_type)
176
+ elsif found_iseq = find_iseq_with_line_from_iseq(iseq, position)
177
+ return position_to_line_and_offset(found_iseq, filename, position,
178
+ offset_type)
179
+ else
180
+ errmsg("Unable to find offset for line #{position}\n\t" +
181
+ "in #{iseq.label} of file #{filename}")
182
+ return [nil, nil]
183
+ end
184
+ when :offset
185
+ position = position.position unless position.kind_of?(Fixnum)
186
+ start_insn = iseq.start_insn(position)
187
+ if ary=iseq.offset2lines(start_insn)
188
+ line_no = ary.first
189
+ vm_offset = start_insn
190
+ else
191
+ errmsg "Unable to find line for offset #{position} in #{iseq}"
192
+ return [nil, nil]
193
+ end
194
+ when nil
195
+ vm_offset = 0
196
+ line_no = iseq.offset2lines(vm_offset).first
197
+ else
198
+ errmsg "Bad parse offset_type: #{offset_type.inspect}"
199
+ return [nil, nil]
200
+ end
201
+ return [iseq, line_no, vm_offset]
202
+ end
262
203
 
263
- def get_method(meth)
264
- start_binding =
265
- begin
266
- @frame.binding
267
- rescue
268
- binding
204
+ # Parse a breakpoint position. On success return:
205
+ # - the instruction sequence to use
206
+ # - the line number - a Fixnum
207
+ # - vm_offset - a Fixnum
208
+ # - the condition (by default 'true') to use for this breakpoint
209
+ # - true condition should be negated. Used in *condition* if/unless
210
+ def breakpoint_position(position_str, allow_condition)
211
+ break_cmd_parse = if allow_condition
212
+ parse_breakpoint(position_str)
213
+ else
214
+ parse_breakpoint_no_condition(position_str)
215
+ end
216
+ return [nil] * 5 unless break_cmd_parse
217
+ tail = [break_cmd_parse.condition, break_cmd_parse.negate]
218
+ meth_or_frame, file, position, offset_type =
219
+ parse_position(break_cmd_parse.position)
220
+ if meth_or_frame
221
+ if iseq = meth_or_frame.iseq
222
+ iseq, line_no, vm_offset =
223
+ position_to_line_and_offset(iseq, file, position,
224
+ offset_type)
225
+ if vm_offset && line_no
226
+ return [iseq, line_no, vm_offset] + tail
227
+ end
228
+ else
229
+ errmsg("Unable to set breakpoint in #{meth_or_frame}")
230
+ end
231
+ elsif file && position
232
+ if :line == offset_type
233
+ iseq = find_iseqs_with_lineno(file, position)
234
+ if iseq
235
+ junk, line_no, vm_offset =
236
+ position_to_line_and_offset(iseq, file, position,
237
+ offset_type)
238
+ return [@frame.iseq, line_no, vm_offset] + tail
239
+ else
240
+ errmsg("Unable to find instruction sequence for" +
241
+ " position #{position} in #{file}")
242
+ end
243
+ else
244
+ errmsg "Come back later..."
245
+ end
246
+ elsif @frame.respond_to?(:file) and @frame.file == file
247
+ puts "parsing line and offset #{position}, #{offset_type}"
248
+ line_no, vm_offset = position_to_line_and_offset(@frame.iseq, position,
249
+ offset_type)
250
+ return [@frame.iseq, line_no, vm_offset] + tail
251
+ else
252
+ errmsg("Unable to parse breakpoint position #{position_str}")
253
+ end
254
+ return [nil] * 5
269
255
  end
270
- if meth.kind_of?(String)
271
- meth_for_string(meth, start_binding)
272
- else
273
- begin
274
- meth_for_parse_struct(meth, start_binding)
275
- rescue NameError
276
- errmsg("Can't evaluate #{meth.name} to get a method")
277
- return nil
256
+
257
+ # Return true if arg is 'on' or 1 and false arg is 'off' or 0.
258
+ # Any other value is raises TypeError.
259
+ def get_onoff(arg, default=nil, print_error=true)
260
+ unless arg
261
+ if !default
262
+ if print_error
263
+ errmsg("Expecting 'on', or 'off'. Got nothing.")
264
+ end
265
+ raise TypeError
266
+ end
267
+ return default
268
+ end
269
+ darg = arg.downcase
270
+ return true if arg == '1' || darg == 'on'
271
+ return false if arg == '0' || darg =='off'
272
+
273
+ errmsg("Expecting 'on', or 'off'. Got: %s." % arg.to_s) if
274
+ print_error
275
+ raise TypeError
278
276
  end
279
- end
280
- end
281
277
 
282
- # FIXME: this is a ? method but we return
283
- # the method value.
284
- def method?(meth)
285
- get_method(meth)
286
- end
278
+ include CmdParser
279
+
280
+ def get_method(meth)
281
+ start_binding =
282
+ begin
283
+ @frame.binding
284
+ rescue
285
+ binding
286
+ end
287
+ if meth.kind_of?(String)
288
+ meth_for_string(meth, start_binding)
289
+ else
290
+ begin
291
+ meth_for_parse_struct(meth, start_binding)
292
+ rescue NameError
293
+ errmsg("Can't evaluate #{meth.name} to get a method")
294
+ return nil
295
+ end
296
+ end
297
+ end
287
298
 
288
- # parse_position(self)->(meth, filename, offset, offset_type)
289
- # See app/cmd_parser.kpeg for the syntax of a position which
290
- # should include things like:
291
- # Parse arg as [filename:]lineno | function | module
292
- # Make sure it works for C:\foo\bar.py:12
293
- def parse_position(info)
294
- ## FIXME: push into parse
295
- if RbConfig::CONFIG['target_os'].start_with?('mingw') and
296
- info =~ /^[A-Za-z]:/
297
- drive_letter = info[0..1]
298
- info = info[2..-1]
299
- else
300
- drive_leter = nil
301
- end
302
- info = parse_location(info) if info.kind_of?(String)
303
- case info.container_type
304
- when :fn
305
- if (meth = method?(info.container)) && meth.iseq
306
- return [meth, meth.iseq.source_container[1], info.position,
307
- info.position_type]
308
- else
309
- return [nil] * 4
299
+ # FIXME: this is a ? method but we return
300
+ # the method value.
301
+ def method?(meth)
302
+ get_method(meth)
310
303
  end
311
- when :file
312
- filename = canonic_file(info.container)
313
- # ?? Try to look up method here?
314
- container = frame_container(@frame, false)
315
- try_filename = container[1]
316
- frame = (canonic_file(try_filename) == filename) ? @frame : nil
317
- # else
318
- # LineCache.compiled_method(filename)
319
- # end
320
- return frame, filename, info.position, info.position_type
321
- when nil
322
- if [:line, :offset].member?(info.position_type)
323
- container = frame_container(@frame, false)
324
- filename = container[1]
325
- return @frame, canonic_file(filename), info.position, info.position_type
326
- elsif !info.position_type
327
- errmsg "Can't parse #{arg} as a position"
328
- return [nil] * 4
329
- else
330
- errmsg "Unknown position type #{info.position_type} for location #{arg}"
331
- return [nil] * 4
304
+
305
+ # parse_position(self)->(meth, filename, offset, offset_type)
306
+ # See app/cmd_parser.kpeg for the syntax of a position which
307
+ # should include things like:
308
+ # Parse arg as [filename:]lineno | function | module
309
+ # Make sure it works for C:\foo\bar.py:12
310
+ def parse_position(info)
311
+ ## FIXME: push into parse
312
+ if RbConfig::CONFIG['target_os'].start_with?('mingw') and
313
+ info =~ /^[A-Za-z]:/
314
+ drive_letter = info[0..1]
315
+ info = info[2..-1]
316
+ else
317
+ drive_leter = nil
318
+ end
319
+ info = parse_location(info) if info.kind_of?(String)
320
+ case info.container_type
321
+ when :fn
322
+ if (meth = method?(info.container)) && meth.iseq
323
+ return [meth, meth.iseq.source_container[1], info.position,
324
+ info.position_type]
325
+ else
326
+ return [nil] * 4
327
+ end
328
+ when :file
329
+ filename = canonic_file(info.container)
330
+ # ?? Try to look up method here?
331
+ frame =
332
+ if @frame
333
+ container = frame_container(@frame, false)
334
+ try_filename = container[1]
335
+ frame = (canonic_file(try_filename) == filename) ? @frame : nil
336
+ else
337
+ nil
338
+ end
339
+ # else
340
+ # LineCache.compiled_method(filename)
341
+ # end
342
+ return frame, filename, info.position, info.position_type
343
+ when nil
344
+ if [:line, :offset].member?(info.position_type)
345
+ if @frame
346
+ container = frame_container(@frame, false)
347
+ filename = container[1]
348
+ else
349
+ errmsg "No stack"
350
+ return [nil] * 4
351
+ end
352
+
353
+ return @frame, canonic_file(filename), info.position, info.position_type
354
+ elsif !info.position_type
355
+ errmsg "Can't parse #{arg} as a position"
356
+ return [nil] * 4
357
+ else
358
+ errmsg "Unknown position type #{info.position_type} for location #{arg}"
359
+ return [nil] * 4
360
+ end
361
+ else
362
+ errmsg "Unknown container type #{info.container_type} for location #{arg}"
363
+ return [nil] * 4
364
+ end
332
365
  end
333
- else
334
- errmsg "Unknown container type #{info.container_type} for location #{arg}"
335
- return [nil] * 4
336
- end
337
- end
338
366
 
339
- def validate_initialize
340
- ## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
341
- ## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
342
- @file_exists_proc = Proc.new {|filename|
343
- if LineCache.cached?(filename) || LineCache.cached_script?(filename) ||
344
- (File.readable?(filename) && !File.directory?(filename))
345
- true
346
- else
347
- matches = find_scripts(filename)
348
- if matches.size == 1
349
- LineCache.remap_file(filename, matches[0])
350
- true
351
- else
352
- false
353
- end
367
+ def validate_initialize
368
+ ## top_srcdir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
369
+ ## @dbgr_script_iseqs, @dbgr_iseqs = filter_scripts(top_srcdir)
370
+ @file_exists_proc = Proc.new {|filename|
371
+ if LineCache.cached?(filename) || LineCache.cached_script?(filename) ||
372
+ (File.readable?(filename) && !File.directory?(filename))
373
+ true
374
+ else
375
+ matches = find_scripts(filename)
376
+ if matches.size == 1
377
+ LineCache.remap_file(filename, matches[0])
378
+ true
379
+ else
380
+ false
381
+ end
382
+ end
383
+ }
354
384
  end
355
- }
356
385
  end
357
- end
358
386
  end
359
387
 
360
388
  if __FILE__ == $0
361
- # Demo it.
362
- if !(ARGV.size == 1 && ARGV[0] == 'noload')
363
- ARGV[0..-1] = ['noload']
364
- load(__FILE__)
365
- else
366
- require 'thread_frame'
367
- require_relative '../app/mock'
368
- require_relative './default'
369
- require_relative 'frame'
370
-
371
- # FIXME: Have to include before defining CmdProcessor!
372
- require_relative '../processor'
373
-
374
- cmdproc = Trepan::CmdProcessor.new(Trepan::MockCore.new())
375
- cmdproc.frame_initialize
376
- cmdproc.instance_variable_set('@settings',
377
- Trepan::CmdProcessor::DEFAULT_SETTINGS)
378
- cmdproc.frame_setup(RubyVM::Frame.current)
379
- onoff = %w(1 0 on off)
380
- onoff.each { |val| puts "onoff(#{val}) = #{cmdproc.get_onoff(val)}" }
381
- %w(1 1E bad 1+1 -5).each do |val|
382
- puts "get_int_noerr(#{val}) = #{cmdproc.get_int_noerr(val).inspect}"
383
- end
384
- def foo; 5 end
385
- def cmdproc.errmsg(msg)
386
- puts msg
387
- end
388
- # puts cmdproc.object_iseq('food').inspect
389
- # puts cmdproc.object_iseq('foo').inspect
389
+ # Demo it.
390
+ if !(ARGV.size == 1 && ARGV[0] == 'noload')
391
+ ARGV[0..-1] = ['noload']
392
+ load(__FILE__)
393
+ else
394
+ require 'thread_frame'
395
+ require_relative '../app/mock'
396
+ require_relative './default'
397
+ require_relative 'frame'
398
+
399
+ # FIXME: Have to include before defining CmdProcessor!
400
+ require_relative '../processor'
401
+
402
+ cmdproc = Trepan::CmdProcessor.new(Trepan::MockCore.new())
403
+ cmdproc.frame_initialize
404
+ cmdproc.instance_variable_set('@settings',
405
+ Trepan::CmdProcessor::DEFAULT_SETTINGS)
406
+ cmdproc.frame_setup(RubyVM::Frame.get)
407
+ onoff = %w(1 0 on off)
408
+ onoff.each { |val| puts "onoff(#{val}) = #{cmdproc.get_onoff(val)}" }
409
+ %w(1 1E bad 1+1 -5).each do |val|
410
+ puts "get_int_noerr(#{val}) = #{cmdproc.get_int_noerr(val).inspect}"
411
+ end
412
+ def foo; 5 end
413
+ def cmdproc.errmsg(msg)
414
+ puts msg
415
+ end
416
+ # puts cmdproc.object_iseq('food').inspect
417
+ # puts cmdproc.object_iseq('foo').inspect
390
418
 
391
- # puts cmdproc.object_iseq('foo@validate.rb').inspect
392
- # puts cmdproc.object_iseq('cmdproc.object_iseq').inspect
419
+ # puts cmdproc.object_iseq('foo@validate.rb').inspect
420
+ # puts cmdproc.object_iseq('cmdproc.object_iseq').inspect
393
421
 
394
- puts cmdproc.parse_position(__FILE__).inspect
395
- puts cmdproc.parse_position('@8').inspect
396
- puts cmdproc.parse_position('8').inspect
397
- puts cmdproc.parse_position("#{__FILE__} #{__LINE__}").inspect
422
+ puts cmdproc.parse_position(__FILE__).inspect
423
+ puts cmdproc.parse_position('@8').inspect
424
+ puts cmdproc.parse_position('8').inspect
425
+ puts cmdproc.parse_position("#{__FILE__} #{__LINE__}").inspect
398
426
 
399
- puts '=' * 40
400
- ['Array.map', 'Trepan::CmdProcessor.new',
401
- 'foo', 'cmdproc.errmsg'].each do |str|
402
- puts "#{str} should be method: #{!!cmdproc.method?(str)}"
403
- end
404
- puts '=' * 40
427
+ puts '=' * 40
428
+ ['Array.map', 'Trepan::CmdProcessor.new',
429
+ 'foo', 'cmdproc.errmsg'].each do |str|
430
+ puts "#{str} should be method: #{!!cmdproc.method?(str)}"
431
+ end
432
+ puts '=' * 40
405
433
 
406
- # FIXME:
407
- puts "Trepan::CmdProcessor.allocate is: #{cmdproc.get_method('Trepan::CmdProcessor.allocate')}"
434
+ # FIXME:
435
+ puts "Trepan::CmdProcessor.allocate is: #{cmdproc.get_method('Trepan::CmdProcessor.allocate')}"
408
436
 
409
- ['food', '.errmsg'].each do |str|
410
- puts "#{str} should be false: #{cmdproc.method?(str).to_s}"
437
+ ['food', '.errmsg'].each do |str|
438
+ puts "#{str} should be false: #{cmdproc.method?(str).to_s}"
439
+ end
440
+ puts '-' * 20
441
+ p cmdproc.breakpoint_position('foo', true)
442
+ p cmdproc.breakpoint_position('@0', true)
443
+ p cmdproc.breakpoint_position("#{__LINE__}", true)
444
+ p cmdproc.breakpoint_position("#{__FILE__} @0", false)
445
+ p cmdproc.breakpoint_position("#{__FILE__}:#{__LINE__}", true)
446
+ p cmdproc.breakpoint_position("#{__FILE__} #{__LINE__} if 1 == a", true)
447
+ p cmdproc.breakpoint_position("cmdproc.errmsg", false)
448
+ p cmdproc.breakpoint_position("cmdproc.errmsg:@0", false)
449
+ ### p cmdproc.breakpoint_position(%w(2 if a > b))
450
+ p cmdproc.get_int_list(%w(1+0 3-1 3))
451
+ p cmdproc.get_int_list(%w(a 2 3))
411
452
  end
412
- puts '-' * 20
413
- p cmdproc.breakpoint_position('foo', true)
414
- p cmdproc.breakpoint_position('@0', true)
415
- p cmdproc.breakpoint_position("#{__LINE__}", true)
416
- p cmdproc.breakpoint_position("#{__FILE__} @0", false)
417
- p cmdproc.breakpoint_position("#{__FILE__}:#{__LINE__}", true)
418
- p cmdproc.breakpoint_position("#{__FILE__} #{__LINE__} if 1 == a", true)
419
- p cmdproc.breakpoint_position("cmdproc.errmsg", false)
420
- p cmdproc.breakpoint_position("cmdproc.errmsg:@0", false)
421
- ### p cmdproc.breakpoint_position(%w(2 if a > b))
422
- p cmdproc.get_int_list(%w(1+0 3-1 3))
423
- p cmdproc.get_int_list(%w(a 2 3))
424
- end
425
453
  end