diff --git a/util.go b/util.go index 7f62040..0c479e3 100644 --- a/util.go +++ b/util.go @@ -20,6 +20,7 @@ func init() { wd = dir } +// Abs func abs(path string) string { if !filepath.IsAbs(path) { path = filepath.Join(wd, path) @@ -27,6 +28,8 @@ func abs(path string) string { return filepath.Clean(path) } +// Appendset +// // TODO(rjeczalik): Sort by directory depth? func appendset(s []string, x string) []string { n := len(s) @@ -46,7 +49,8 @@ func appendset(s []string, x string) []string { return s } -func splitabs(p string) (s []string) { +// Splitpath +func splitpath(p string) (s []string) { if p == "" || p == "." || p == sep { return } @@ -79,3 +83,25 @@ func joinevents(events []Event, isdir bool) (e Event) { } return } + +// Walkpath +func walkpath(p string, fn func(string) bool) bool { + if p == "" || p == "." { + return false + } + i, n := strings.Index(p, sep)+1, len(p) + if i == 0 || i == n { + return false + } + for i < n { + j := strings.Index(p[i:], sep) + if j == -1 { + j = n - i + } + if !fn(p[i : i+j]) { + return i+i+j+2 > n + } + i += j + 1 + } + return true +} diff --git a/util_test.go b/util_test.go index 18ed1d5..5e93d29 100644 --- a/util_test.go +++ b/util_test.go @@ -39,7 +39,7 @@ func TestAppendset(t *testing.T) { } } -func TestSplitabs(t *testing.T) { +func TestSplitpath(t *testing.T) { cases := map[string][]string{ "C:/a/b/c/d.txt": {"a", "b", "c", "d.txt"}, "/a/b/c/d.txt": {"a", "b", "c", "d.txt"}, @@ -48,7 +48,8 @@ func TestSplitabs(t *testing.T) { "C:": nil, } for path, names := range cases { - if s := splitabs(filepath.FromSlash(path)); !reflect.DeepEqual(s, names) { + path = filepath.FromSlash(path) + if s := splitpath(path); !reflect.DeepEqual(s, names) { t.Errorf("want s=%v; got %v (path=%s)", names, s, path) } } @@ -80,3 +81,31 @@ func TestJoinevents(t *testing.T) { } } } + +func TestWalkpath(t *testing.T) { + cases := map[string]struct { + p []string + ok bool + }{ + "C:/a/b/c/d.txt": {[]string{"a", "b", "c", "d.txt"}, true}, + "/a/b/c/d.txt": {[]string{"a", "b", "c", "d.txt"}, true}, + "": {[]string{}, false}, + ".": {[]string{}, false}, + "C:": {[]string{}, false}, + } + var p []string + fn := func(s string) bool { + p = append(p, s) + return s != "break" + } + for path, cas := range cases { + p, path = p[:0], filepath.FromSlash(path) + if ok := walkpath(path, fn); ok != cas.ok { + t.Errorf("want ok=%v; got %v (path=%s)", cas.ok, ok, path) + continue + } + if !reflect.DeepEqual(p, cas.p) { + t.Errorf("want p=%v; got %v (path=%s)", cas.p, p, path) + } + } +}