module Byebug::FrameFunctions
def adjust_frame(frame_pos, absolute)
def adjust_frame(frame_pos, absolute) if absolute abs_frame_pos = switch_to_frame(frame_pos) return errmsg "Can't navigate to c-frame\n" if c_frame?(abs_frame_pos) else abs_frame_pos = navigate_to_frame(frame_pos) end return errmsg "Can't navigate beyond the oldest frame\n" if abs_frame_pos >= @state.context.stack_size return errmsg "Can't navigate beyond the newest frame\n" if abs_frame_pos < 0 if @state.frame_pos != abs_frame_pos @state.previous_line = nil @state.frame_pos = abs_frame_pos end @state.file = @state.context.frame_file @state.frame_pos @state.line = @state.context.frame_line @state.frame_pos ListCommand.new(@state).execute end
def c_frame?(frame_no)
def c_frame?(frame_no) @state.context.frame_binding(frame_no).nil? end
def get_frame_args(style, pos)
def get_frame_args(style, pos) args = @state.context.frame_args pos return '' if args.empty? locals = @state.context.frame_locals pos if style == :long my_args = args.map do |arg| case arg[0] when :block prefix, default = '&', 'block' when :rest prefix, default = '*', 'args' else prefix, default = '', nil end klass = style == :long && arg[1] ? "##{locals[arg[1]].class}" : '' "#{prefix}#{arg[1] || default}#{klass}" end return "(#{my_args.join(', ')})" end
def get_frame_block_and_method(pos)
def get_frame_block_and_method(pos) frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/ frame_deco_method = "#{@state.context.frame_method pos}" frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2] return frame_block_and_method.map{ |x| x.nil? ? '' : x } end
def get_frame_call(prefix, pos)
def get_frame_call(prefix, pos) frame_block, frame_method = get_frame_block_and_method(pos) frame_class = get_frame_class(Command.settings[:callstyle], pos) frame_args = get_frame_args(Command.settings[:callstyle], pos) call_str = frame_block + frame_class + frame_method + frame_args max_call_str_size = Command.settings[:width] - prefix.size if call_str.size > max_call_str_size call_str = call_str[0..max_call_str_size - 5] + "...)" end return call_str end
def get_frame_class(style, pos)
def get_frame_class(style, pos) frame_class = style == :short ? '' : "#{@state.context.frame_class pos}" return frame_class == '' ? '' : "#{frame_class}." end
def navigate_to_frame(jump_no)
def navigate_to_frame(jump_no) return if jump_no == 0 total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos step = jump_no/total_jumps loop do new_pos += step return new_pos if new_pos < 0 || new_pos >= @state.context.stack_size next if c_frame?(new_pos) current_jumps += 1 break if current_jumps == total_jumps end return new_pos end
def print_backtrace
def print_backtrace realsize = caller.drop_while {|e| e[/\(eval\)|byebug/] }.size if @state.context.stack_size != realsize errmsg "Warning, Byebug's stacksize (#{@state.context.stack_size}) is" \ " incorrect (must be #{realsize}). This might be a bug in " \ "byebug or ruby's debugging API's\n" end (0...realsize).each do |idx| print_frame(idx) end end
def print_frame(pos, mark_current = true)
def print_frame(pos, mark_current = true) file = @state.context.frame_file pos line = @state.context.frame_line pos unless Command.settings[:frame_fullpath] path_components = file.split(/[\\\/]/) if path_components.size > 3 path_components[0...-3] = '...' file = path_components.join(File::ALT_SEPARATOR || File::SEPARATOR) end end if mark_current frame_str = (pos == @state.frame_pos) ? '--> ' : ' ' else frame_str = "" end frame_str += c_frame?(pos) ? ' ͱ-- ' : '' frame_str += sprintf "#%-2d ", pos frame_str += get_frame_call frame_str, pos file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}" if frame_str.size + file_line.size + 1 > Command.settings[:width] frame_str += "\n #{file_line}\n" else frame_str += " #{file_line}\n" end print frame_str end
def switch_to_frame(frame_no)
def switch_to_frame(frame_no) if frame_no < 0 abs_frame_no = @state.context.stack_size + frame_no else abs_frame_no = frame_no end end