src/pkg/path/filepath/path.go | 12 +++++++++--- src/pkg/path/filepath/path_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++---- diff --git a/src/pkg/path/filepath/path.go b/src/pkg/path/filepath/path.go index f1cda7c53045d59e7b26277aa2bf0912755d3c9e..3dc52aab4672873a6ab1a00b1d7f66b4174bdd5c 100644 --- a/src/pkg/path/filepath/path.go +++ b/src/pkg/path/filepath/path.go @@ -426,6 +426,8 @@ // Strip trailing slashes. for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) { path = path[0 : len(path)-1] } + // Throw away volume name + path = path[len(VolumeName(path)):] // Find the last element i := len(path) - 1 for i >= 0 && !os.IsPathSeparator(path[i]) { @@ -447,8 +449,12 @@ // If the path is empty, Dir returns ".". // If the path consists entirely of separators, Dir returns a single separator. // The returned path does not end in a separator unless it is the root directory. func Dir(path string) string { - dir, _ := Split(path) - dir = Clean(dir) + vol := VolumeName(path) + i := len(path) - 1 + for i >= len(vol) && !os.IsPathSeparator(path[i]) { + i-- + } + dir := Clean(path[len(vol) : i+1]) last := len(dir) - 1 if last > 0 && os.IsPathSeparator(dir[last]) { dir = dir[:last] @@ -456,5 +462,5 @@ } if dir == "" { dir = "." } - return dir + return vol + dir } diff --git a/src/pkg/path/filepath/path_test.go b/src/pkg/path/filepath/path_test.go index 49a7135b4aed9923376143e03ef3c4cda2cd9a7a..966b08e4f861a6e34b2caf9670aa5c1c33e1b1f2 100644 --- a/src/pkg/path/filepath/path_test.go +++ b/src/pkg/path/filepath/path_test.go @@ -423,9 +423,29 @@ {"a/b/c.", "c."}, {"a/b/c.x", "c.x"}, } +var winbasetests = []PathTest{ + {`c:\`, `\`}, + {`c:.`, `.`}, + {`c:\a\b`, `b`}, + {`c:a\b`, `b`}, + {`c:a\b\c`, `c`}, + {`\\host\share\`, `\`}, + {`\\host\share\a`, `a`}, + {`\\host\share\a\b`, `b`}, +} + func TestBase(t *testing.T) { - for _, test := range basetests { - if s := filepath.ToSlash(filepath.Base(test.path)); s != test.result { + tests := basetests + if runtime.GOOS == "windows" { + // make unix tests work on windows + for i, _ := range tests { + tests[i].result = filepath.Clean(tests[i].result) + } + // add windows specific tests + tests = append(tests, winbasetests...) + } + for _, test := range tests { + if s := filepath.Base(test.path); s != test.result { t.Errorf("Base(%q) = %q, want %q", test.path, s, test.result) } } @@ -446,9 +466,29 @@ {"a/b/c.", "a/b"}, {"a/b/c.x", "a/b"}, } +var windirtests = []PathTest{ + {`c:\`, `c:\`}, + {`c:.`, `c:.`}, + {`c:\a\b`, `c:\a`}, + {`c:a\b`, `c:a`}, + {`c:a\b\c`, `c:a\b`}, + {`\\host\share\`, `\\host\share\`}, + {`\\host\share\a`, `\\host\share\`}, + {`\\host\share\a\b`, `\\host\share\a`}, +} + func TestDir(t *testing.T) { - for _, test := range dirtests { - if s := filepath.ToSlash(filepath.Dir(test.path)); s != test.result { + tests := dirtests + if runtime.GOOS == "windows" { + // make unix tests work on windows + for i, _ := range tests { + tests[i].result = filepath.Clean(tests[i].result) + } + // add windows specific tests + tests = append(tests, windirtests...) + } + for _, test := range tests { + if s := filepath.Dir(test.path); s != test.result { t.Errorf("Dir(%q) = %q, want %q", test.path, s, test.result) } }