diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index 150cdd332acfcabb2878a6b97258824b402e108c..fb87138a81f4c30ca1dc73c55ed8af53ebbf5cec 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -1028,7 +1028,16 @@ func parseStackArgs(argstr string) (int, bool, error) { } func listCommand(t *Term, ctx callContext, args string) error { - if ctx.Prefix == scopePrefix { + switch { + case len(args) == 0 && ctx.Prefix != scopePrefix: + state, err := t.client.GetState() + if err != nil { + return err + } + printcontext(t, state) + return printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true) + + case len(args) == 0 && ctx.Prefix == scopePrefix: locs, err := t.client.Stacktrace(ctx.Scope.GoroutineID, ctx.Scope.Frame, nil) if err != nil { return err @@ -1037,28 +1046,31 @@ func listCommand(t *Term, ctx callContext, args string) error { return fmt.Errorf("Frame %d does not exist in goroutine %d", ctx.Scope.Frame, ctx.Scope.GoroutineID) } loc := locs[ctx.Scope.Frame] + gid := ctx.Scope.GoroutineID + if gid < 0 { + state, err := t.client.GetState() + if err != nil { + return err + } + if state.SelectedGoroutine != nil { + gid = state.SelectedGoroutine.ID + } + } + fmt.Printf("Goroutine %d frame %d at %s:%d (PC: %#x)\n", gid, ctx.Scope.Frame, loc.File, loc.Line, loc.PC) return printfile(t, loc.File, loc.Line, true) - } - if len(args) == 0 { - state, err := t.client.GetState() + default: + locs, err := t.client.FindLocation(ctx.Scope, args) if err != nil { return err } - printcontext(t, state) - printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true) - return nil - } - - locs, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, args) - if err != nil { - return err - } - if len(locs) > 1 { - return debugger.AmbiguousLocationError{Location: args, CandidatesLocation: locs} + if len(locs) > 1 { + return debugger.AmbiguousLocationError{Location: args, CandidatesLocation: locs} + } + loc := locs[0] + fmt.Printf("Showing %s:%d (PC: %#x)\n", loc.File, loc.Line, loc.PC) + return printfile(t, loc.File, loc.Line, false) } - printfile(t, locs[0].File, locs[0].Line, false) - return nil } func (c *Commands) sourceCommand(t *Term, ctx callContext, args string) error { diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 96f24981ec9b63e9e06c8cb6afa3560c1ef8d8d6..7f404d15df385342cac70c93b053103aa492ab12 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -7,6 +7,7 @@ import ( "net" "os" "path/filepath" + "regexp" "strconv" "strings" "testing" @@ -43,10 +44,10 @@ func (ft *FakeTerminal) Exec(cmdstr string) (outstr string, err error) { ft.t.Fatalf("could not create temporary file: %v", err) } - stdout, stderr := os.Stdout, os.Stderr - os.Stdout, os.Stderr = outfh, outfh + stdout, stderr, termstdout := os.Stdout, os.Stderr, ft.Term.stdout + os.Stdout, os.Stderr, ft.Term.stdout = outfh, outfh, outfh defer func() { - os.Stdout, os.Stderr = stdout, stderr + os.Stdout, os.Stderr, ft.Term.stdout = stdout, stderr, termstdout outfh.Close() outbs, err1 := ioutil.ReadFile(outfh.Name()) if err1 != nil { @@ -482,3 +483,57 @@ func TestIssue387(t *testing.T) { } }) } + +func listIsAt(t *testing.T, term *FakeTerminal, listcmd string, cur, start, end int) { + outstr := term.MustExec(listcmd) + lines := strings.Split(outstr, "\n") + + t.Logf("%q: %q", listcmd, outstr) + + if strings.Index(lines[0], fmt.Sprintf(":%d", cur)) < 0 { + t.Fatalf("Could not find current line number in first output line: %q", lines[0]) + } + + re := regexp.MustCompile(`(=>)?\s+(\d+):`) + + outStart, outEnd := 0, 0 + + for i, line := range lines[1:] { + if line == "" { + continue + } + v := re.FindStringSubmatch(line) + if len(v) != 3 { + t.Fatalf("Could not parse line %d: %q\n", i+1, line) + } + curline, _ := strconv.Atoi(v[2]) + if v[1] == "=>" { + if cur != curline { + t.Fatalf("Wrong current line, got %d expected %d", curline, cur) + } + } + if outStart == 0 { + outStart = curline + } + outEnd = curline + } + + if outStart != start || outEnd != end { + t.Fatalf("Wrong output range, got %d:%d expected %d:%d", outStart, outEnd, start, end) + } +} + +func TestListCmd(t *testing.T) { + withTestTerminal("testvariables", t, func(term *FakeTerminal) { + term.MustExec("continue") + term.MustExec("continue") + listIsAt(t, term, "list", 24, 19, 29) + listIsAt(t, term, "list 69", 69, 64, 70) + listIsAt(t, term, "frame 1 list", 62, 57, 67) + listIsAt(t, term, "frame 1 list 69", 69, 64, 70) + _, err := term.Exec("frame 50 list") + if err == nil { + t.Fatalf("Expected error requesting 50th frame") + } + }) +}