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