path/filepath: implement Base and Dir for windows

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5501069
diff --git a/src/pkg/path/filepath/path.go b/src/pkg/path/filepath/path.go
index f1cda7c..3dc52aa 100644
--- a/src/pkg/path/filepath/path.go
+++ b/src/pkg/path/filepath/path.go
@@ -426,6 +426,8 @@
 	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 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 49a7135..966b08e 100644
--- a/src/pkg/path/filepath/path_test.go
+++ b/src/pkg/path/filepath/path_test.go
@@ -423,9 +423,29 @@
 	{"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.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)
 		}
 	}