diff options
Diffstat (limited to 'src/pkg/path/filepath/path.go')
| -rw-r--r-- | src/pkg/path/filepath/path.go | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/pkg/path/filepath/path.go b/src/pkg/path/filepath/path.go index 414df7d208..64cef291e6 100644 --- a/src/pkg/path/filepath/path.go +++ b/src/pkg/path/filepath/path.go @@ -13,8 +13,6 @@ import ( "strings" ) -// BUG(niemeyer): Package filepath does not yet work on Windows. - // Clean returns the shortest path name equivalent to path // by purely lexical processing. It applies the following rules // iteratively until no further processing can be done: @@ -38,36 +36,39 @@ func Clean(path string) string { return "." } - rooted := path[0] == Separator - n := len(path) + rooted := IsAbs(path) // Invariants: // reading from path; r is index of next byte to process. // writing to buf; w is index of next byte to write. // dotdot is index in buf where .. must stop, either because // it is the leading slash or it is a leading ../../.. prefix. + prefix := volumeName(path) + path = path[len(prefix):] + n := len(path) buf := []byte(path) r, w, dotdot := 0, 0, 0 if rooted { + buf[0] = Separator r, w, dotdot = 1, 1, 1 } for r < n { switch { - case path[r] == Separator: + case isSeparator(path[r]): // empty path element r++ - case path[r] == '.' && (r+1 == n || path[r+1] == Separator): + case path[r] == '.' && (r+1 == n || isSeparator(path[r+1])): // . element r++ - case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == Separator): + case path[r] == '.' && path[r+1] == '.' && (r+2 == n || isSeparator(path[r+2])): // .. element: remove to last separator r += 2 switch { case w > dotdot: // can backtrack w-- - for w > dotdot && buf[w] != Separator { + for w > dotdot && !isSeparator(buf[w]) { w-- } case !rooted: @@ -90,7 +91,7 @@ func Clean(path string) string { w++ } // copy element - for ; r < n && path[r] != Separator; r++ { + for ; r < n && !isSeparator(path[r]); r++ { buf[w] = path[r] w++ } @@ -103,7 +104,7 @@ func Clean(path string) string { w++ } - return string(buf[0:w]) + return prefix + string(buf[0:w]) } // ToSlash returns the result of replacing each separator character @@ -137,7 +138,10 @@ func SplitList(path string) []string { // If there are no separators in path, Split returns an empty base // and file set to path. func Split(path string) (dir, file string) { - i := strings.LastIndex(path, string(Separator)) + i := len(path) - 1 + for i >= 0 && !isSeparator(path[i]) { + i-- + } return path[:i+1], path[i+1:] } @@ -157,7 +161,7 @@ func Join(elem ...string) string { // in the final element of path; it is empty if there is // no dot. func Ext(path string) string { - for i := len(path) - 1; i >= 0 && path[i] != Separator; i-- { + for i := len(path) - 1; i >= 0 && !isSeparator(path[i]); i-- { if path[i] == '.' { return path[i:] } @@ -250,11 +254,15 @@ func Base(path string) string { return "." } // Strip trailing slashes. - for len(path) > 0 && path[len(path)-1] == Separator { + for len(path) > 0 && isSeparator(path[len(path)-1]) { path = path[0 : len(path)-1] } // Find the last element - if i := strings.LastIndex(path, string(Separator)); i >= 0 { + i := len(path) - 1 + for i >= 0 && !isSeparator(path[i]) { + i-- + } + if i >= 0 { path = path[i+1:] } // If empty now, it had only slashes. @@ -263,8 +271,3 @@ func Base(path string) string { } return path } - -// IsAbs returns true if the path is absolute. -func IsAbs(path string) bool { - return len(path) > 0 && path[0] == Separator -} |
