1 // glocate -- ZFS-diff-friendly locate-like utility
2 // Copyright (C) 2022-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 func IsDir(s string) bool {
26 return s[len(s)-1] == '/'
29 type ByName [][]string
31 func (a ByName) Len() int {
35 func (a ByName) Swap(i, j int) {
36 a[i], a[j] = a[j], a[i]
39 func (a ByName) Less(i, j int) bool {
40 return namesCmp(a[i], a[j]) < 0
43 func nameSplit(name string) []string {
44 cols := strings.Split(name, "/")
46 cols = cols[:len(cols)-1]
47 cols[len(cols)-1] += "/"
52 func nameJoin(name []string) (s string) {
53 s = path.Join(name...)
54 if IsDir(name[len(name)-1]) {
60 func namesCmp(n1, n2 []string) int {
66 for i := 0; i < min; i++ {
67 t1 = strings.TrimSuffix(n1[i], "/")
68 t2 = strings.TrimSuffix(n2[i], "/")
76 if len(n1) > len(n2) {
79 if len(n1) < len(n2) {
85 func hasPrefix(name, prefix []string) bool {
86 if len(name) < len(prefix) {
89 return namesCmp(name[:len(prefix)], prefix) == 0
92 func deoctalize(s string) string {
93 chars := make([]byte, 0, len(s))
94 for i := 0; i < len(s); i++ {
96 b, err := strconv.ParseUint(s[i+1:i+1+4], 0, 8)
100 chars = append(chars, byte(b))
103 chars = append(chars, s[i])