# -*- coding: utf-8 -*- # Copyright (C) 2010, 2011 Rocky Bernstein require_relative '../../frame' require_relative '../../base/subsubcmd' require_relative '../substitute' class Trepan::SubSubcommand::SetSubstituteEval < Trepan::SubSubcommand unless defined?(HELP) HELP = 'set substitute eval [FRAME-NUM] Causes lines in an EVAL frame to show up as we stop/step through them. The text for the eval string comes from the current frame. FRAME-NUM is a relative frame number unless prefaced with an "=" which indicates how many frames prior to move. The default is "0" (alternatively "=0", the current frame. This is largely done automatically anytime the debugger discovers an EVAL frame. We have this here for completeness and just in case. ' MIN_ABBREV = 'ev'.size MAX_ARGS = 1 NAME = File.basename(__FILE__, '.rb') SHORT_HELP = 'Set eval string text of an filename' PREFIX = %w(set substitute string) end def run(args) frame = if args.size == 2 absolute, count_str = if '=' == args[1][0] [true, args[1][1..-1].dup] else [false, args[1]] end stack_size = @proc.top_frame.stack_size - @hide_level opts = { :msg_on_error => "The 'eval' command argument must eval to an integer. Got: %s" % count_str, :min_value => -stack_size, :max_value => stack_size-1 } count = @proc.get_an_int(count_str, opts) @proc.get_frame(count, absolute)[0] else @proc.frame end return unless frame if 'EVAL' != frame.type errmsg "Current frame has to be of type EVAL, not #{frame.type}" return end unless frame.iseq errmsg "Can't get instruction sequence for frame." return end prev = frame.prev if 'CFUNC' != prev.type errmsg "Previous frame has to be of type CFUNC, not #{frame.type}" return end if 'eval' != prev.method errmsg "Previous frame has to be of type CFUNC, not #{frame.method}" return end @proc.frame_eval_remap end end if __FILE__ == $0 # Demo it. require_relative '../../../mock' require_relative '../../../subcmd' name = File.basename(__FILE__, '.rb') # FIXME: DRY the below code dbgr, set_cmd = MockDebugger::setup('set') set_cmd.proc.send('frame_initialize') testcmdMgr = Trepan::Subcmd.new(set_cmd) cmd_name = Trepan::SubSubcommand::SetSubstituteEval::PREFIX.join('') setx_cmd = Trepan::SubSubcommand::SetSubstituteEval.new(set_cmd.proc, set_cmd, cmd_name) setx_cmd.run([]) # require_relative '../../../../lib/trepanning' # dbgr = Trepan.new # dbgr.debugger eval('set_cmd.proc.frame_setup(RubyVM::Frame::current); setx_cmd.run([])') # name = File.basename(__FILE__, '.rb') # subcommand.summary_help(name) end