Parse returns one slice per simple command in src, in source order. Each is [program] or [program, arg], where arg is the first non-flag positional argument. Program names are normalized to their base name (e.g. /usr/bin/go becomes go). Some malformed inputs (e.g. trailing unterminated tokens after
(src string)
| 18 | // a non-nil err as a signal to fall back to the raw input rather than |
| 19 | // display the partial. |
| 20 | func Parse(src string) ([][]string, error) { |
| 21 | if src == "" { |
| 22 | return nil, nil |
| 23 | } |
| 24 | f, err := syntax.NewParser().Parse(strings.NewReader(src), "") |
| 25 | if f == nil { |
| 26 | return nil, err |
| 27 | } |
| 28 | |
| 29 | var out [][]string |
| 30 | syntax.Walk(f, func(node syntax.Node) bool { |
| 31 | call, ok := node.(*syntax.CallExpr) |
| 32 | if !ok || len(call.Args) == 0 { |
| 33 | return true |
| 34 | } |
| 35 | prog := wordLiteral(call.Args[0]) |
| 36 | if prog == "" { |
| 37 | return true |
| 38 | } |
| 39 | step := []string{cmdBase(prog)} |
| 40 | if arg := firstNonFlagLiteral(call.Args[1:]); arg != "" { |
| 41 | step = append(step, arg) |
| 42 | } |
| 43 | out = append(out, step) |
| 44 | return true |
| 45 | }) |
| 46 | return out, err |
| 47 | } |
| 48 | |
| 49 | // wordLiteral returns the literal content of w by concatenating the |
| 50 | // literal pieces of its parts. Bare literals, single-quoted strings, |