// GubTraceHook is the callback hook from interpreter. It contains // top-level statement breakout. func GubTraceHook(fr *interp.Frame, instr *ssa2.Instruction, event ssa2.TraceEvent) { if !fr.I().TraceEventMask[event] { return } gubLock.Lock() defer gubLock.Unlock() if skipEvent(fr, event) { return } TraceEvent = event frameInit(fr) if instr == nil && event != ssa2.PROGRAM_TERMINATION { instr = &curBlock.Instrs[fr.PC()] } Instr = instr if event == ssa2.BREAKPOINT && Breakpoints[curBpnum].Kind == "Function" { event = ssa2.CALL_ENTER } if FirstTime { IntroText() FirstTime = false } printLocInfo(topFrame, instr, event) line := "" var err error for InCmdLoop = true; err == nil && InCmdLoop; cmdCount++ { if inputReader != nil { line, err = inputReader.ReadString('\n') } else { line, err = gnureadline.Readline(computePrompt(), true) } if err != nil { break } line = strings.Trim(line, " \t\n") args := strings.Split(line, " ") if len(args) == 0 || len(args[0]) == 0 { if len(LastCommand) == 0 { Msg("Empty line skipped") gnureadline.RemoveHistory(gnureadline.HistoryLength() - 1) continue } else { line = LastCommand args = strings.Split(line, " ") } } if args[0][0] == '#' { gnureadline.RemoveHistory(gnureadline.HistoryLength() - 1) Msg(line) // echo line but do nothing continue } name := args[0] CmdArgstr = strings.TrimLeft(line[len(name):], " ") if newname := LookupCmd(name); newname != "" { name = newname } cmd := Cmds[name] LastCommand = "" if cmd != nil { runCommand(name, args) continue } if len(args) > 0 { if !WhatisName(args[0]) { gnureadline.RemoveHistory(gnureadline.HistoryLength() - 1) } } else { gnureadline.RemoveHistory(gnureadline.HistoryLength() - 1) Errmsg("Unknown command %s\n", cmd) } } }