package shellquote
import (
"bytes"
"errors"
"strings"
"unicode/utf8"
)
var (
UnterminatedSingleQuoteError = errors .New ("Unterminated single-quoted string" )
UnterminatedDoubleQuoteError = errors .New ("Unterminated double-quoted string" )
UnterminatedEscapeError = errors .New ("Unterminated backslash-escape" )
)
var (
splitChars = " \n\t"
singleChar = '\''
doubleChar = '"'
escapeChar = '\\'
doubleEscapeChars = "$`\"\n\\"
)
func Split (input string ) (words []string , err error ) {
var buf bytes .Buffer
words = make ([]string , 0 )
for len (input ) > 0 {
c , l := utf8 .DecodeRuneInString (input )
if strings .ContainsRune (splitChars , c ) {
input = input [l :]
continue
} else if c == escapeChar {
next := input [l :]
if len (next ) == 0 {
err = UnterminatedEscapeError
return
}
c2 , l2 := utf8 .DecodeRuneInString (next )
if c2 == '\n' {
input = next [l2 :]
continue
}
}
var word string
word , input , err = splitWord (input , &buf )
if err != nil {
return
}
words = append (words , word )
}
return
}
func splitWord(input string , buf *bytes .Buffer ) (word string , remainder string , err error ) {
buf .Reset ()
raw :
{
cur := input
for len (cur ) > 0 {
c , l := utf8 .DecodeRuneInString (cur )
cur = cur [l :]
if c == singleChar {
buf .WriteString (input [0 : len (input )-len (cur )-l ])
input = cur
goto single
} else if c == doubleChar {
buf .WriteString (input [0 : len (input )-len (cur )-l ])
input = cur
goto double
} else if c == escapeChar {
buf .WriteString (input [0 : len (input )-len (cur )-l ])
input = cur
goto escape
} else if strings .ContainsRune (splitChars , c ) {
buf .WriteString (input [0 : len (input )-len (cur )-l ])
return buf .String (), cur , nil
}
}
if len (input ) > 0 {
buf .WriteString (input )
input = ""
}
goto done
}
escape :
{
if len (input ) == 0 {
return "" , "" , UnterminatedEscapeError
}
c , l := utf8 .DecodeRuneInString (input )
if c == '\n' {
} else {
buf .WriteString (input [:l ])
}
input = input [l :]
}
goto raw
single :
{
i := strings .IndexRune (input , singleChar )
if i == -1 {
return "" , "" , UnterminatedSingleQuoteError
}
buf .WriteString (input [0 :i ])
input = input [i +1 :]
goto raw
}
double :
{
cur := input
for len (cur ) > 0 {
c , l := utf8 .DecodeRuneInString (cur )
cur = cur [l :]
if c == doubleChar {
buf .WriteString (input [0 : len (input )-len (cur )-l ])
input = cur
goto raw
} else if c == escapeChar {
c2 , l2 := utf8 .DecodeRuneInString (cur )
cur = cur [l2 :]
if strings .ContainsRune (doubleEscapeChars , c2 ) {
buf .WriteString (input [0 : len (input )-len (cur )-l -l2 ])
if c2 == '\n' {
} else {
buf .WriteRune (c2 )
}
input = cur
}
}
}
return "" , "" , UnterminatedDoubleQuoteError
}
done :
return buf .String (), input , nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .