Added aliases to commands

Added:
- break: b
- continue: c
- step: si
- next: n
- print: p

Taken from the gdb command list

Also updated .gitignore to ignore built dlv file in cmd/dlv
This commit is contained in:
Jason Del Ponte
2014-11-13 21:51:32 -08:00
committed by Derek Parker
parent 29d0cd0bde
commit d54a3262d2
3 changed files with 62 additions and 34 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ notes.txt
.tags* .tags*
tags tags
.dbg_history .dbg_history
cmd/dlv/dlv

View File

@ -17,47 +17,80 @@ import (
type cmdfunc func(proc *proctl.DebuggedProcess, args ...string) error type cmdfunc func(proc *proctl.DebuggedProcess, args ...string) error
type command struct {
aliases []string
helpMsg string
cmdFn cmdfunc
}
// Returns true if the command string matches one of the aliases for this command
func (c command) match(cmdstr string) bool {
for _, v := range c.aliases {
if v == cmdstr {
return true
}
}
return false
}
type Commands struct { type Commands struct {
cmds map[string]cmdfunc cmds []command
lastCmd cmdfunc
} }
// Returns a Commands struct with default commands defined. // Returns a Commands struct with default commands defined.
func DebugCommands() *Commands { func DebugCommands() *Commands {
cmds := map[string]cmdfunc{ c := &Commands{}
"help": help,
"continue": cont, c.cmds = []command{
"next": next, command{aliases: []string{"help"}, cmdFn: c.help, helpMsg: "help - Prints the help message."},
"break": breakpoint, command{aliases: []string{"break", "b"}, cmdFn: breakpoint, helpMsg: "break|b - Set break point at the entry point of a function, or at a specific file/line. Example: break foo.go:13"},
"step": step, command{aliases: []string{"continue", "c"}, cmdFn: cont, helpMsg: "continue|c - Run until breakpoint or program termination."},
"clear": clear, command{aliases: []string{"step", "si"}, cmdFn: step, helpMsg: "step|si - Single step through program."},
"print": printVar, command{aliases: []string{"next", "n"}, cmdFn: next, helpMsg: "next|n - Step over to next source line."},
"threads": threads, command{aliases: []string{"threads"}, cmdFn: threads, helpMsg: "threads - Print out info for every traced thread."},
"goroutines": goroutines, command{aliases: []string{"clear"}, cmdFn: clear, helpMsg: "clear - Deletes breakpoint."},
"": nullCommand, command{aliases: []string{"goroutines"}, cmdFn: goroutines, helpMsg: "goroutines - Print out info for every goroutine."},
command{aliases: []string{"print", "p"}, cmdFn: printVar, helpMsg: "print|p $var - Evaluate a variable."},
command{aliases: []string{"exit"}, cmdFn: nullCommand, helpMsg: "exit - Exit the debugger."},
} }
return &Commands{cmds} return c
} }
// Register custom commands. Expects cf to be a func of type cmdfunc, // Register custom commands. Expects cf to be a func of type cmdfunc,
// returning only an error. // returning only an error.
func (c *Commands) Register(cmdstr string, cf cmdfunc) { func (c *Commands) Register(cmdstr string, cf cmdfunc, helpMsg string) {
c.cmds[cmdstr] = cf for _, v := range c.cmds {
if v.match(cmdstr) {
v.cmdFn = cf
return
}
}
c.cmds = append(c.cmds, command{aliases: []string{cmdstr}, cmdFn: cf, helpMsg: helpMsg})
} }
// Find will look up the command function for the given command input. // Find will look up the command function for the given command input.
// If it cannot find the command it will defualt to noCmdAvailable(). // If it cannot find the command it will defualt to noCmdAvailable().
// If the command is an empty string it will replay the last command. // If the command is an empty string it will replay the last command.
func (c *Commands) Find(cmdstr string) cmdfunc { func (c *Commands) Find(cmdstr string) cmdfunc {
cmd, ok := c.cmds[cmdstr] // If <enter> use last command, if there was one.
if !ok { if cmdstr == "" {
return noCmdAvailable if c.lastCmd != nil {
return c.lastCmd
}
return nullCommand
} }
// Allow <enter> to replay last command for _, v := range c.cmds {
c.cmds[""] = cmd if v.match(cmdstr) {
c.lastCmd = v.cmdFn
return v.cmdFn
}
}
return cmd return noCmdAvailable
} }
func CommandFunc(fn func() error) cmdfunc { func CommandFunc(fn func() error) cmdfunc {
@ -74,17 +107,11 @@ func nullCommand(p *proctl.DebuggedProcess, ars ...string) error {
return nil return nil
} }
func help(p *proctl.DebuggedProcess, ars ...string) error { func (c *Commands) help(p *proctl.DebuggedProcess, ars ...string) error {
fmt.Println(`The following commands are available: fmt.Println("The following commands are available:")
break - Set break point at the entry point of a function, or at a specific file/line. Example: break foo.go:13. for _, cmd := range c.cmds {
continue - Run until breakpoint or program termination. fmt.Printf("\t%s\n", cmd.helpMsg)
step - Single step through program. }
next - Step over to next source line.
threads - Print out info for every traced thread.
goroutines - Print out info for every goroutine.
print $var - Evaluate a variable.
exit - Exit the debugger.`)
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
func TestCommandDefault(t *testing.T) { func TestCommandDefault(t *testing.T) {
var ( var (
cmds = Commands{make(map[string]cmdfunc)} cmds = Commands{}
cmd = cmds.Find("non-existant-command") cmd = cmds.Find("non-existant-command")
) )
@ -25,7 +25,7 @@ func TestCommandDefault(t *testing.T) {
func TestCommandReplay(t *testing.T) { func TestCommandReplay(t *testing.T) {
cmds := DebugCommands() cmds := DebugCommands()
cmds.Register("foo", func(p *proctl.DebuggedProcess, args ...string) error { return fmt.Errorf("registered command") }) cmds.Register("foo", func(p *proctl.DebuggedProcess, args ...string) error { return fmt.Errorf("registered command") }, "foo command")
cmd := cmds.Find("foo") cmd := cmds.Find("foo")
err := cmd(nil) err := cmd(nil)