提交 bb95d534 编写于 作者: J Joe Shaw 提交者: Derek Parker

terminal/command: add list command to display source

Without arguments, `list` displays source around the current context.  A
linespec argument can be taken to display source around that location.

Fixes #58
上级 e68e760a
......@@ -228,6 +228,25 @@ func (loc *NormalLocationSpec) FileMatch(path string) bool {
return strings.HasSuffix(path, loc.Base) && (path[len(path)-len(loc.Base)-1] == filepath.Separator)
}
type AmbiguousLocationError struct {
Location string
CandidatesString []string
CandidatesLocation []api.Location
}
func (ale AmbiguousLocationError) Error() string {
var candidates []string
if ale.CandidatesLocation != nil {
for i := range ale.CandidatesLocation {
candidates = append(candidates, ale.CandidatesLocation[i].Function.Name)
}
} else {
candidates = ale.CandidatesString
}
return fmt.Sprintf("Location \"%s\" ambiguous: %s…", ale.Location, strings.Join(candidates, ", "))
}
func (loc *NormalLocationSpec) Find(d *Debugger, locStr string) ([]api.Location, error) {
funcs := d.process.Funcs()
files := d.process.Sources()
......@@ -280,7 +299,7 @@ func (loc *NormalLocationSpec) Find(d *Debugger, locStr string) ([]api.Location,
case 0:
return nil, fmt.Errorf("Location \"%s\" not found", locStr)
default:
return nil, fmt.Errorf("Location \"%s\" ambiguous: %s…", locStr, strings.Join(candidates, ", "))
return nil, AmbiguousLocationError{Location: locStr, CandidatesString: candidates}
}
}
......
......@@ -15,6 +15,7 @@ import (
"github.com/derekparker/delve/service"
"github.com/derekparker/delve/service/api"
"github.com/derekparker/delve/service/debugger"
)
type cmdfunc func(client service.Client, args ...string) error
......@@ -68,6 +69,7 @@ func DebugCommands(client service.Client) *Commands {
{aliases: []string{"regs"}, cmdFn: regs, helpMsg: "Print contents of CPU registers."},
{aliases: []string{"exit", "quit", "q"}, cmdFn: exitCommand, helpMsg: "Exit the debugger."},
{aliases: []string{"stack", "bt"}, cmdFn: stackCommand, helpMsg: "stack [<depth> [<goroutine id>]]. Prints stack."},
{aliases: []string{"list"}, cmdFn: listCommand, helpMsg: "list <linespec>. Show source around current point or provided linespec."},
}
return c
......@@ -503,6 +505,29 @@ func stackCommand(client service.Client, args ...string) error {
return nil
}
func listCommand(client service.Client, args ...string) error {
if len(args) == 0 {
state, err := client.GetState()
if err != nil {
return err
}
printcontext(state)
return nil
}
locs, err := client.FindLocation(args[0])
if err != nil {
return err
}
if len(locs) > 1 {
return debugger.AmbiguousLocationError{Location: args[0], CandidatesLocation: locs}
}
printfile(locs[0].File, locs[0].Line, false)
return nil
}
func printStack(stack []api.Location, ind string) {
for i := range stack {
name := "(nil)"
......@@ -525,8 +550,6 @@ func printcontext(state *api.DebuggerState) error {
return nil
}
var context []string
var fn *api.Function
if state.CurrentThread.Function != nil {
fn = state.CurrentThread.Function
......@@ -564,14 +587,20 @@ func printcontext(state *api.DebuggerState) error {
return nil
}
file, err := os.Open(state.CurrentThread.File)
return printfile(state.CurrentThread.File, state.CurrentThread.Line, true)
}
func printfile(filename string, line int, showArrow bool) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
var context []string
buf := bufio.NewReader(file)
l := state.CurrentThread.Line
l := line
for i := 1; i < l-5; i++ {
_, err := buf.ReadString('\n')
if err != nil && err != io.EOF {
......@@ -579,7 +608,12 @@ func printcontext(state *api.DebuggerState) error {
}
}
for i := l - 5; i <= l+5; i++ {
s := l - 5
if s < 1 {
s = 1
}
for i := s; i <= l+5; i++ {
line, err := buf.ReadString('\n')
if err != nil {
if err != io.EOF {
......@@ -591,9 +625,12 @@ func printcontext(state *api.DebuggerState) error {
}
}
arrow := " "
if i == l {
arrow = "=>"
var arrow string
if showArrow {
arrow = " "
if i == l {
arrow = "=>"
}
}
var lineNum string
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册