trepanning 1.93.35 → 2.15.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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