Utility code to find longest common prefix/suffix and to quote strings for various shells

This commit is contained in:
Kovid Goyal 2022-09-18 19:31:24 +05:30
parent 1ff4f2df4f
commit cbbda23e01
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 126 additions and 0 deletions

View File

@ -0,0 +1,79 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package utils
import (
"fmt"
"math"
)
var _ = fmt.Print
func slice_iter(strs []string) func() (string, bool) {
i := 0
limit := len(strs)
return func() (string, bool) {
if i < limit {
i++
return strs[i-1], false
}
return "", true
}
}
// Prefix returns the longest common prefix of the provided strings
func Prefix(strs []string) string {
return LongestCommon(slice_iter(strs), true)
}
// Suffix returns the longest common suffix of the provided strings
func Suffix(strs []string) string {
return LongestCommon(slice_iter(strs), false)
}
func min(a ...int) int {
ans := math.MaxInt
for _, x := range a {
if x < ans {
ans = x
}
}
return ans
}
func LongestCommon(next func() (string, bool), prefix bool) string {
xfix, done := next()
if xfix == "" || done {
return ""
}
for {
q, done := next()
if done {
break
}
q_len := len(q)
xfix_len := len(xfix)
max_len := min(q_len, xfix_len)
if max_len == 0 {
return ""
}
if prefix {
for i := 0; i < max_len; i++ {
if xfix[i] != q[i] {
xfix = xfix[:i]
break
}
}
} else {
for i := 0; i < max_len; i++ {
xi := xfix_len - i - 1
si := q_len - i - 1
if xfix[xi] != q[si] {
xfix = xfix[xi+1:]
break
}
}
}
}
return xfix
}

View File

@ -0,0 +1,21 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package utils
import (
"fmt"
"testing"
)
var _ = fmt.Print
func TestLongestCommon(t *testing.T) {
p := func(expected string, items ...string) {
actual := Prefix(items)
if actual != expected {
t.Fatalf("Failed with %#v\nExpected: %#v\nActual: %#v", items, expected, actual)
}
}
p("abc", "abc", "abcd")
p("", "abc", "xy")
}

26
tools/utils/shell.go Normal file
View File

@ -0,0 +1,26 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package utils
import (
"fmt"
"strings"
)
var _ = fmt.Print
// Quotes arbitrary strings for bash, dash and zsh
func QuoteStringForSH(x string) string {
parts := strings.Split(x, "'")
for i, p := range parts {
parts[i] = "'" + p + "'"
}
return strings.Join(parts, "\"'\"")
}
// Quotes arbitrary strings for fish
func QuoteStringForFish(x string) string {
x = strings.ReplaceAll(x, "\\", "\\\\")
x = strings.ReplaceAll(x, "'", "\\'")
return "'" + x + "'"
}