mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-19 07:17:11 +09:00
use build-in functions to quote / unquote
This commit is contained in:
@@ -223,32 +223,47 @@ func Abs(n int) int {
|
||||
// The returned slice contains at least one string
|
||||
func SplitCommandArgs(input string) []string {
|
||||
var result []string
|
||||
|
||||
curArg := new(bytes.Buffer)
|
||||
inQuote := false
|
||||
escape := false
|
||||
curArg := new(bytes.Buffer)
|
||||
for _, r := range input {
|
||||
if !escape {
|
||||
switch {
|
||||
case r == '\\' && inQuote:
|
||||
escape = true
|
||||
continue
|
||||
case r == '"' && inQuote:
|
||||
inQuote = false
|
||||
continue
|
||||
case r == '"' && !inQuote && curArg.Len() == 0:
|
||||
inQuote = true
|
||||
continue
|
||||
case r == ' ' && !inQuote:
|
||||
result = append(result, curArg.String())
|
||||
curArg.Reset()
|
||||
continue
|
||||
|
||||
appendResult := func() {
|
||||
str := curArg.String()
|
||||
inQuote = false
|
||||
escape = false
|
||||
if strings.HasPrefix(str, `"`) && strings.HasSuffix(str, `"`) {
|
||||
if unquoted, err := strconv.Unquote(str); err == nil {
|
||||
str = unquoted
|
||||
}
|
||||
}
|
||||
escape = false
|
||||
curArg.WriteRune(r)
|
||||
result = append(result, str)
|
||||
curArg.Reset()
|
||||
}
|
||||
result = append(result, curArg.String())
|
||||
|
||||
for _, r := range input {
|
||||
if r == ' ' && !inQuote {
|
||||
appendResult()
|
||||
} else {
|
||||
curArg.WriteRune(r)
|
||||
|
||||
if r == '"' && !inQuote {
|
||||
inQuote = true
|
||||
} else {
|
||||
if inQuote && !escape {
|
||||
if r == '"' {
|
||||
inQuote = false
|
||||
}
|
||||
if r == '\\' {
|
||||
escape = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
escape = false
|
||||
}
|
||||
appendResult()
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -262,17 +277,11 @@ func JoinCommandArgs(args ...string) string {
|
||||
} else {
|
||||
buf.WriteRune(' ')
|
||||
}
|
||||
if !strings.Contains(arg, " ") {
|
||||
buf.WriteString(arg)
|
||||
quoted := strconv.Quote(arg)
|
||||
if quoted[1:len(quoted)-1] != arg || strings.ContainsRune(arg, ' ') {
|
||||
buf.WriteString(quoted)
|
||||
} else {
|
||||
buf.WriteRune('"')
|
||||
for _, r := range arg {
|
||||
if r == '"' || r == '\\' {
|
||||
buf.WriteRune('\\')
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
}
|
||||
buf.WriteRune('"')
|
||||
buf.WriteString(arg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,10 +77,13 @@ func TestJoinAndSplitCommandArgs(t *testing.T) {
|
||||
{[]string{`slash\\\ test`}, `"slash\\\\\\ test"`},
|
||||
{[]string{`path 1`, `path\" 2`}, `"path 1" "path\\\" 2"`},
|
||||
{[]string{`foo`}, `foo`},
|
||||
{[]string{`foo\"bar`}, `foo\"bar`},
|
||||
{[]string{`foo\"bar`}, `"foo\\\"bar"`},
|
||||
{[]string{``}, ``},
|
||||
{[]string{`"`}, `"\""`},
|
||||
{[]string{`a`, ``}, `a `},
|
||||
{[]string{``, ``, ``, ``}, ` `},
|
||||
{[]string{"\n"}, `"\n"`},
|
||||
{[]string{"foo\tbar"}, `"foo\tbar"`},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
@@ -89,8 +92,22 @@ func TestJoinAndSplitCommandArgs(t *testing.T) {
|
||||
}
|
||||
|
||||
if result := SplitCommandArgs(test.Wanted); !reflect.DeepEqual(test.Query, result) {
|
||||
t.Errorf("SplitCommandArgs failed at Test %d\nGot: `%s`", i, result)
|
||||
t.Errorf("SplitCommandArgs failed at Test %d\nGot: `%q`", i, result)
|
||||
}
|
||||
}
|
||||
|
||||
splitTests := []struct {
|
||||
Query string
|
||||
Wanted []string
|
||||
}{
|
||||
{`"hallo""Welt"`, []string{`"hallo""Welt"`}},
|
||||
{`\"`, []string{`\"`}},
|
||||
{`"\"`, []string{`"\"`}},
|
||||
}
|
||||
|
||||
for i, test := range splitTests {
|
||||
if result := SplitCommandArgs(test.Query); !reflect.DeepEqual(test.Wanted, result) {
|
||||
t.Errorf("SplitCommandArgs failed at Split-Test %d\nGot: `%q`", i, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user