152 lines
2.6 KiB
Go
152 lines
2.6 KiB
Go
package exql
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
// isBlankSymbol returns true if the given byte is either space, tab, carriage
|
|
// return or newline.
|
|
func isBlankSymbol(in byte) bool {
|
|
return in == ' ' || in == '\t' || in == '\r' || in == '\n'
|
|
}
|
|
|
|
// trimString returns a slice of s with a leading and trailing blank symbols
|
|
// (as defined by isBlankSymbol) removed.
|
|
func trimString(s string) string {
|
|
|
|
// This conversion is rather slow.
|
|
// return string(trimBytes([]byte(s)))
|
|
|
|
start, end := 0, len(s)-1
|
|
|
|
if end < start {
|
|
return ""
|
|
}
|
|
|
|
for isBlankSymbol(s[start]) {
|
|
start++
|
|
if start >= end {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
for isBlankSymbol(s[end]) {
|
|
end--
|
|
}
|
|
|
|
return s[start : end+1]
|
|
}
|
|
|
|
// trimBytes returns a slice of s with a leading and trailing blank symbols (as
|
|
// defined by isBlankSymbol) removed.
|
|
func trimBytes(s []byte) []byte {
|
|
|
|
start, end := 0, len(s)-1
|
|
|
|
if end < start {
|
|
return []byte{}
|
|
}
|
|
|
|
for isBlankSymbol(s[start]) {
|
|
start++
|
|
if start >= end {
|
|
return []byte{}
|
|
}
|
|
}
|
|
|
|
for isBlankSymbol(s[end]) {
|
|
end--
|
|
}
|
|
|
|
return s[start : end+1]
|
|
}
|
|
|
|
/*
|
|
// Separates by a comma, ignoring spaces too.
|
|
// This was slower than strings.Split.
|
|
func separateByComma(in string) (out []string) {
|
|
|
|
out = []string{}
|
|
|
|
start, lim := 0, len(in)-1
|
|
|
|
for start < lim {
|
|
var end int
|
|
|
|
for end = start; end <= lim; end++ {
|
|
// Is a comma?
|
|
if in[end] == ',' {
|
|
break
|
|
}
|
|
}
|
|
|
|
out = append(out, trimString(in[start:end]))
|
|
|
|
start = end + 1
|
|
}
|
|
|
|
return
|
|
}
|
|
*/
|
|
|
|
// Separates by a comma, ignoring spaces too.
|
|
func separateByComma(in string) (out []string) {
|
|
out = strings.Split(in, ",")
|
|
for i := range out {
|
|
out[i] = trimString(out[i])
|
|
}
|
|
return
|
|
}
|
|
|
|
// Separates by spaces, ignoring spaces too.
|
|
func separateBySpace(in string) (out []string) {
|
|
if len(in) == 0 {
|
|
return []string{""}
|
|
}
|
|
|
|
pre := strings.Split(in, " ")
|
|
out = make([]string, 0, len(pre))
|
|
|
|
for i := range pre {
|
|
pre[i] = trimString(pre[i])
|
|
if pre[i] != "" {
|
|
out = append(out, pre[i])
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func separateByAS(in string) (out []string) {
|
|
out = []string{}
|
|
|
|
if len(in) < 6 {
|
|
// The minimum expression with the AS keyword is "x AS y", 6 chars.
|
|
return []string{in}
|
|
}
|
|
|
|
start, lim := 0, len(in)-1
|
|
|
|
for start <= lim {
|
|
var end int
|
|
|
|
for end = start; end <= lim; end++ {
|
|
if end > 3 && isBlankSymbol(in[end]) && isBlankSymbol(in[end-3]) {
|
|
if (in[end-1] == 's' || in[end-1] == 'S') && (in[end-2] == 'a' || in[end-2] == 'A') {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if end < lim {
|
|
out = append(out, trimString(in[start:end-3]))
|
|
} else {
|
|
out = append(out, trimString(in[start:end]))
|
|
}
|
|
|
|
start = end + 1
|
|
}
|
|
|
|
return
|
|
}
|