aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/rjeczalik/notify/util.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/rjeczalik/notify/util.go')
-rw-r--r--Godeps/_workspace/src/github.com/rjeczalik/notify/util.go150
1 files changed, 150 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/rjeczalik/notify/util.go b/Godeps/_workspace/src/github.com/rjeczalik/notify/util.go
new file mode 100644
index 000000000..67e01fbbd
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/rjeczalik/notify/util.go
@@ -0,0 +1,150 @@
+// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+package notify
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+const all = ^Event(0)
+const sep = string(os.PathSeparator)
+
+var errDepth = errors.New("exceeded allowed iteration count (circular symlink?)")
+
+func min(i, j int) int {
+ if i > j {
+ return j
+ }
+ return i
+}
+
+func max(i, j int) int {
+ if i < j {
+ return j
+ }
+ return i
+}
+
+// must panics if err is non-nil.
+func must(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+// nonil gives first non-nil error from the given arguments.
+func nonil(err ...error) error {
+ for _, err := range err {
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func cleanpath(path string) (realpath string, isrec bool, err error) {
+ if strings.HasSuffix(path, "...") {
+ isrec = true
+ path = path[:len(path)-3]
+ }
+ if path, err = filepath.Abs(path); err != nil {
+ return "", false, err
+ }
+ if path, err = canonical(path); err != nil {
+ return "", false, err
+ }
+ return path, isrec, nil
+}
+
+// canonical resolves any symlink in the given path and returns it in a clean form.
+// It expects the path to be absolute. It fails to resolve circular symlinks by
+// maintaining a simple iteration limit.
+func canonical(p string) (string, error) {
+ p, err := filepath.Abs(p)
+ if err != nil {
+ return "", err
+ }
+ for i, j, depth := 1, 0, 1; i < len(p); i, depth = i+1, depth+1 {
+ if depth > 128 {
+ return "", &os.PathError{Op: "canonical", Path: p, Err: errDepth}
+ }
+ if j = strings.IndexRune(p[i:], '/'); j == -1 {
+ j, i = i, len(p)
+ } else {
+ j, i = i, i+j
+ }
+ fi, err := os.Lstat(p[:i])
+ if err != nil {
+ return "", err
+ }
+ if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
+ s, err := os.Readlink(p[:i])
+ if err != nil {
+ return "", err
+ }
+ if filepath.IsAbs(s) {
+ p = "/" + s + p[i:]
+ } else {
+ p = p[:j] + s + p[i:]
+ }
+ i = 1 // no guarantee s is canonical, start all over
+ }
+ }
+ return filepath.Clean(p), nil
+}
+
+func joinevents(events []Event) (e Event) {
+ if len(events) == 0 {
+ e = All
+ } else {
+ for _, event := range events {
+ e |= event
+ }
+ }
+ return
+}
+
+func split(s string) (string, string) {
+ if i := lastIndexSep(s); i != -1 {
+ return s[:i], s[i+1:]
+ }
+ return "", s
+}
+
+func base(s string) string {
+ if i := lastIndexSep(s); i != -1 {
+ return s[i+1:]
+ }
+ return s
+}
+
+func indexbase(root, name string) int {
+ if n, m := len(root), len(name); m >= n && name[:n] == root &&
+ (n == m || name[n] == os.PathSeparator) {
+ return min(n+1, m)
+ }
+ return -1
+}
+
+func indexSep(s string) int {
+ for i := 0; i < len(s); i++ {
+ if s[i] == os.PathSeparator {
+ return i
+ }
+ }
+ return -1
+}
+
+func lastIndexSep(s string) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == os.PathSeparator {
+ return i
+ }
+ }
+ return -1
+}