2022-11-10 22:52:51 +01:00
|
|
|
package utilfn
|
|
|
|
|
|
|
|
import (
|
2022-11-14 22:56:50 +01:00
|
|
|
"regexp"
|
2022-11-10 22:52:51 +01:00
|
|
|
"strings"
|
2022-11-22 01:37:09 +01:00
|
|
|
"unicode/utf8"
|
2022-11-10 22:52:51 +01:00
|
|
|
)
|
|
|
|
|
2022-11-17 07:17:38 +01:00
|
|
|
var HexDigits = []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}
|
|
|
|
|
2022-11-10 22:52:51 +01:00
|
|
|
func GetStrArr(v interface{}, field string) []string {
|
|
|
|
if v == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
m, ok := v.(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
fieldVal := m[field]
|
|
|
|
if fieldVal == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
iarr, ok := fieldVal.([]interface{})
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
var sarr []string
|
|
|
|
for _, iv := range iarr {
|
|
|
|
if sv, ok := iv.(string); ok {
|
|
|
|
sarr = append(sarr, sv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sarr
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetBool(v interface{}, field string) bool {
|
|
|
|
if v == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
m, ok := v.(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
fieldVal := m[field]
|
|
|
|
if fieldVal == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
bval, ok := fieldVal.(bool)
|
|
|
|
if !ok {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return bval
|
|
|
|
}
|
|
|
|
|
2022-11-14 22:56:50 +01:00
|
|
|
var needsQuoteRe = regexp.MustCompile(`[^\w@%:,./=+-]`)
|
|
|
|
|
2022-11-10 22:52:51 +01:00
|
|
|
// minimum maxlen=6
|
|
|
|
func ShellQuote(val string, forceQuote bool, maxLen int) string {
|
|
|
|
if maxLen < 6 {
|
|
|
|
maxLen = 6
|
|
|
|
}
|
2022-11-14 22:56:50 +01:00
|
|
|
rtn := val
|
|
|
|
if needsQuoteRe.MatchString(val) {
|
|
|
|
rtn = "'" + strings.ReplaceAll(val, "'", `'"'"'`) + "'"
|
|
|
|
}
|
2022-11-10 22:52:51 +01:00
|
|
|
if strings.HasPrefix(rtn, "\"") || strings.HasPrefix(rtn, "'") {
|
|
|
|
if len(rtn) > maxLen {
|
|
|
|
return rtn[0:maxLen-4] + "..." + rtn[0:1]
|
|
|
|
}
|
|
|
|
return rtn
|
|
|
|
}
|
|
|
|
if forceQuote {
|
|
|
|
if len(rtn) > maxLen-2 {
|
|
|
|
return "\"" + rtn[0:maxLen-5] + "...\""
|
|
|
|
}
|
|
|
|
return "\"" + rtn + "\""
|
|
|
|
} else {
|
|
|
|
if len(rtn) > maxLen {
|
|
|
|
return rtn[0:maxLen-3] + "..."
|
|
|
|
}
|
|
|
|
return rtn
|
|
|
|
}
|
|
|
|
}
|
2022-11-11 00:28:39 +01:00
|
|
|
|
|
|
|
func LongestPrefix(root string, strs []string) string {
|
|
|
|
if len(strs) == 0 {
|
|
|
|
return root
|
|
|
|
}
|
|
|
|
if len(strs) == 1 {
|
|
|
|
comp := strs[0]
|
|
|
|
if len(comp) >= len(root) && strings.HasPrefix(comp, root) {
|
|
|
|
if strings.HasSuffix(comp, "/") {
|
|
|
|
return strs[0]
|
|
|
|
}
|
|
|
|
return strs[0]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lcp := strs[0]
|
|
|
|
for i := 1; i < len(strs); i++ {
|
|
|
|
s := strs[i]
|
|
|
|
for j := 0; j < len(lcp); j++ {
|
|
|
|
if j >= len(s) || lcp[j] != s[j] {
|
|
|
|
lcp = lcp[0:j]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(lcp) < len(root) || !strings.HasPrefix(lcp, root) {
|
|
|
|
return root
|
|
|
|
}
|
|
|
|
return lcp
|
|
|
|
}
|
|
|
|
|
|
|
|
func ContainsStr(strs []string, test string) bool {
|
|
|
|
for _, s := range strs {
|
|
|
|
if s == test {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2022-11-18 23:26:52 +01:00
|
|
|
|
2022-11-22 09:32:27 +01:00
|
|
|
func IsPrefix(strs []string, test string) bool {
|
|
|
|
for _, s := range strs {
|
|
|
|
if len(s) > len(test) && strings.HasPrefix(s, test) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-11-18 23:26:52 +01:00
|
|
|
type StrWithPos struct {
|
|
|
|
Str string
|
2022-11-22 01:37:09 +01:00
|
|
|
Pos int // this is a 'rune' position (not a byte position)
|
2022-11-18 23:26:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sp StrWithPos) String() string {
|
|
|
|
return strWithCursor(sp.Str, sp.Pos)
|
|
|
|
}
|
|
|
|
|
2022-11-19 04:05:03 +01:00
|
|
|
func ParseToSP(s string) StrWithPos {
|
|
|
|
idx := strings.Index(s, "[*]")
|
|
|
|
if idx == -1 {
|
|
|
|
return StrWithPos{Str: s}
|
|
|
|
}
|
2022-11-22 01:37:09 +01:00
|
|
|
return StrWithPos{Str: s[0:idx] + s[idx+3:], Pos: utf8.RuneCountInString(s[0:idx])}
|
2022-11-19 04:05:03 +01:00
|
|
|
}
|
|
|
|
|
2022-11-18 23:26:52 +01:00
|
|
|
func strWithCursor(str string, pos int) string {
|
|
|
|
if pos < 0 {
|
|
|
|
return "[*]_" + str
|
|
|
|
}
|
|
|
|
if pos >= len(str) {
|
|
|
|
if pos > len(str) {
|
|
|
|
return str + "_[*]"
|
|
|
|
}
|
|
|
|
return str + "[*]"
|
|
|
|
}
|
2022-11-22 01:37:09 +01:00
|
|
|
|
|
|
|
var rtn []rune
|
|
|
|
for _, ch := range str {
|
|
|
|
if len(rtn) == pos {
|
|
|
|
rtn = append(rtn, '[', '*', ']')
|
|
|
|
}
|
|
|
|
rtn = append(rtn, ch)
|
|
|
|
}
|
|
|
|
return string(rtn)
|
2022-11-18 23:26:52 +01:00
|
|
|
}
|
2022-11-22 08:06:58 +01:00
|
|
|
|
|
|
|
func (sp StrWithPos) Prepend(str string) StrWithPos {
|
|
|
|
return StrWithPos{Str: str + sp.Str, Pos: utf8.RuneCountInString(str) + sp.Pos}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sp StrWithPos) Append(str string) StrWithPos {
|
|
|
|
return StrWithPos{Str: sp.Str + str, Pos: sp.Pos}
|
|
|
|
}
|