77 lines
1.2 KiB
Go
77 lines
1.2 KiB
Go
package commandparser
|
|
|
|
import "unicode"
|
|
|
|
const (
|
|
stateLooking = "looking"
|
|
stateQuoted = "quoted"
|
|
stateEscape = "escape"
|
|
stateFilling = "filling"
|
|
)
|
|
|
|
func Parse(in string) []string {
|
|
nextArg := ""
|
|
out := []string{}
|
|
state := stateLooking
|
|
for _, c := range in {
|
|
switch state {
|
|
case stateLooking:
|
|
if unicode.IsSpace(c) {
|
|
continue
|
|
}
|
|
if c == '"' {
|
|
state = stateQuoted
|
|
continue
|
|
}
|
|
|
|
state = stateFilling
|
|
nextArg += string(c)
|
|
case stateFilling:
|
|
if unicode.IsSpace(c) {
|
|
state = stateLooking
|
|
out = append(out, nextArg)
|
|
nextArg = ""
|
|
continue
|
|
}
|
|
|
|
nextArg += string(c)
|
|
case stateQuoted:
|
|
if c == '"' {
|
|
state = stateLooking
|
|
out = append(out, nextArg)
|
|
nextArg = ""
|
|
continue
|
|
}
|
|
|
|
if c == '\\' {
|
|
state = stateEscape
|
|
continue
|
|
}
|
|
|
|
nextArg += string(c)
|
|
case stateEscape:
|
|
if c == '"' {
|
|
state = stateQuoted
|
|
nextArg += string(c)
|
|
continue
|
|
}
|
|
|
|
// Not escaping quotes, so we readd the backslash
|
|
nextArg += string('\\')
|
|
nextArg += string(c)
|
|
default:
|
|
panic("unexpected state")
|
|
}
|
|
}
|
|
|
|
if state == stateEscape {
|
|
nextArg += string('\\')
|
|
}
|
|
|
|
if state == stateFilling {
|
|
out = append(out, nextArg)
|
|
}
|
|
|
|
return out
|
|
}
|