diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
commit | adb0401dac41c81571722312d4586b2693f95aa6 (patch) | |
tree | ea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/path | |
parent | 5548ca3540bccbc908a45942896d635ea5f1c23f (diff) | |
download | gcc-adb0401dac41c81571722312d4586b2693f95aa6.zip gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.gz gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.bz2 |
Update Go library to r60.
From-SVN: r178910
Diffstat (limited to 'libgo/go/path')
-rw-r--r-- | libgo/go/path/filepath/match.go | 9 | ||||
-rw-r--r-- | libgo/go/path/filepath/match_test.go | 9 | ||||
-rw-r--r-- | libgo/go/path/filepath/path.go | 59 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_plan9.go | 19 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_test.go | 115 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_unix.go | 19 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_windows.go | 45 |
7 files changed, 170 insertions, 105 deletions
diff --git a/libgo/go/path/filepath/match.go b/libgo/go/path/filepath/match.go index a05bb5f..7fcc214 100644 --- a/libgo/go/path/filepath/match.go +++ b/libgo/go/path/filepath/match.go @@ -124,9 +124,8 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) { s = s[n:] chunk = chunk[1:] // possibly negated - notNegated := true - if len(chunk) > 0 && chunk[0] == '^' { - notNegated = false + negated := chunk[0] == '^' + if negated { chunk = chunk[1:] } // parse all ranges @@ -152,7 +151,7 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) { } nrange++ } - if match != notNegated { + if match == negated { return } @@ -273,7 +272,7 @@ func glob(dir, pattern string, matches []string) (m []string, e os.Error) { if err != nil { return } - sort.SortStrings(names) + sort.Strings(names) for _, n := range names { matched, err := Match(pattern, n) diff --git a/libgo/go/path/filepath/match_test.go b/libgo/go/path/filepath/match_test.go index 0b594fa..5fc7b9c 100644 --- a/libgo/go/path/filepath/match_test.go +++ b/libgo/go/path/filepath/match_test.go @@ -69,6 +69,13 @@ var matchTests = []MatchTest{ {"*x", "xxx", true, nil}, } +func errp(e os.Error) string { + if e == nil { + return "<nil>" + } + return e.String() +} + func TestMatch(t *testing.T) { if runtime.GOOS == "windows" { // XXX: Don't pass for windows. @@ -77,7 +84,7 @@ func TestMatch(t *testing.T) { for _, tt := range matchTests { ok, err := Match(tt.pattern, tt.s) if ok != tt.match || err != tt.err { - t.Errorf("Match(%#q, %#q) = %v, %v want %v, nil", tt.pattern, tt.s, ok, err, tt.match) + t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", tt.pattern, tt.s, ok, errp(err), tt.match, errp(tt.err)) } } } diff --git a/libgo/go/path/filepath/path.go b/libgo/go/path/filepath/path.go index 541a233..3d5b915 100644 --- a/libgo/go/path/filepath/path.go +++ b/libgo/go/path/filepath/path.go @@ -9,13 +9,14 @@ package filepath import ( "bytes" "os" + "runtime" "sort" "strings" ) const ( - SeparatorString = string(Separator) - ListSeparatorString = string(ListSeparator) + Separator = os.PathSeparator + ListSeparator = os.PathListSeparator ) // Clean returns the shortest path name equivalent to path @@ -37,19 +38,19 @@ const ( // Getting Dot-Dot right,'' // http://plan9.bell-labs.com/sys/doc/lexnames.html func Clean(path string) string { + vol := VolumeName(path) + path = path[len(vol):] if path == "" { - return "." + return vol + "." } - rooted := IsAbs(path) + rooted := os.IsPathSeparator(path[0]) // 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 @@ -60,20 +61,20 @@ func Clean(path string) string { for r < n { switch { - case isSeparator(path[r]): + case os.IsPathSeparator(path[r]): // empty path element r++ - case path[r] == '.' && (r+1 == n || isSeparator(path[r+1])): + case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])): // . element r++ - case path[r] == '.' && path[r+1] == '.' && (r+2 == n || isSeparator(path[r+2])): + case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])): // .. element: remove to last separator r += 2 switch { case w > dotdot: // can backtrack w-- - for w > dotdot && !isSeparator(buf[w]) { + for w > dotdot && !os.IsPathSeparator(buf[w]) { w-- } case !rooted: @@ -96,7 +97,7 @@ func Clean(path string) string { w++ } // copy element - for ; r < n && !isSeparator(path[r]); r++ { + for ; r < n && !os.IsPathSeparator(path[r]); r++ { buf[w] = path[r] w++ } @@ -109,7 +110,7 @@ func Clean(path string) string { w++ } - return prefix + string(buf[0:w]) + return FromSlash(vol + string(buf[0:w])) } // ToSlash returns the result of replacing each separator character @@ -118,7 +119,7 @@ func ToSlash(path string) string { if Separator == '/' { return path } - return strings.Replace(path, SeparatorString, "/", -1) + return strings.Replace(path, string(Separator), "/", -1) } // FromSlash returns the result of replacing each slash ('/') character @@ -127,7 +128,7 @@ func FromSlash(path string) string { if Separator == '/' { return path } - return strings.Replace(path, "/", SeparatorString, -1) + return strings.Replace(path, "/", string(Separator), -1) } // SplitList splits a list of paths joined by the OS-specific ListSeparator. @@ -135,16 +136,16 @@ func SplitList(path string) []string { if path == "" { return []string{} } - return strings.Split(path, ListSeparatorString, -1) + return strings.Split(path, string(ListSeparator)) } // Split splits path immediately following the final Separator, -// partitioning it into a directory and a file name components. -// If there are no separators in path, Split returns an empty base +// separating it into a directory and file name component. +// If there is no Separator in path, Split returns an empty dir // and file set to path. func Split(path string) (dir, file string) { i := len(path) - 1 - for i >= 0 && !isSeparator(path[i]) { + for i >= 0 && !os.IsPathSeparator(path[i]) { i-- } return path[:i+1], path[i+1:] @@ -155,7 +156,7 @@ func Split(path string) (dir, file string) { func Join(elem ...string) string { for i, e := range elem { if e != "" { - return Clean(strings.Join(elem[i:], SeparatorString)) + return Clean(strings.Join(elem[i:], string(Separator))) } } return "" @@ -166,7 +167,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 && !isSeparator(path[i]); i-- { + for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- { if path[i] == '.' { return path[i:] } @@ -178,6 +179,14 @@ func Ext(path string) string { // links. // If path is relative it will be evaluated relative to the current directory. func EvalSymlinks(path string) (string, os.Error) { + if runtime.GOOS == "windows" { + // Symlinks are not supported under windows. + _, err := os.Lstat(path) + if err != nil { + return "", err + } + return Clean(path), nil + } const maxIter = 255 originalPath := path // consume path by taking each frontmost path element, @@ -225,7 +234,7 @@ func EvalSymlinks(path string) (string, os.Error) { if IsAbs(dest) { b.Reset() } - path = dest + SeparatorString + path + path = dest + string(Separator) + path } return Clean(b.String()), nil } @@ -236,7 +245,7 @@ func EvalSymlinks(path string) (string, os.Error) { // path name for a given file is not guaranteed to be unique. func Abs(path string) (string, os.Error) { if IsAbs(path) { - return path, nil + return Clean(path), nil } wd, err := os.Getwd() if err != nil { @@ -330,12 +339,12 @@ func Base(path string) string { return "." } // Strip trailing slashes. - for len(path) > 0 && isSeparator(path[len(path)-1]) { + for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) { path = path[0 : len(path)-1] } // Find the last element i := len(path) - 1 - for i >= 0 && !isSeparator(path[i]) { + for i >= 0 && !os.IsPathSeparator(path[i]) { i-- } if i >= 0 { @@ -343,7 +352,7 @@ func Base(path string) string { } // If empty now, it had only slashes. if path == "" { - return SeparatorString + return string(Separator) } return path } diff --git a/libgo/go/path/filepath/path_plan9.go b/libgo/go/path/filepath/path_plan9.go index e400083..17b873f 100644 --- a/libgo/go/path/filepath/path_plan9.go +++ b/libgo/go/path/filepath/path_plan9.go @@ -6,23 +6,18 @@ package filepath import "strings" -const ( - Separator = '/' // OS-specific path separator - ListSeparator = 0 // OS-specific path list separator -) - -// isSeparator returns true if c is a directory separator character. -func isSeparator(c uint8) bool { - return Separator == c -} - // IsAbs returns true if the path is absolute. func IsAbs(path string) bool { return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#") } -// volumeName returns the leading volume name on Windows. +// VolumeName returns the leading volume name on Windows. // It returns "" elsewhere -func volumeName(path string) string { +func VolumeName(path string) string { return "" } + +// HasPrefix tests whether the path p begins with prefix. +func HasPrefix(p, prefix string) bool { + return strings.HasPrefix(p, prefix) +} diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go index 37078f6..e944bf4 100644 --- a/libgo/go/path/filepath/path_test.go +++ b/libgo/go/path/filepath/path_test.go @@ -66,9 +66,27 @@ var cleantests = []PathTest{ {"abc/../../././../def", "../../def"}, } +var wincleantests = []PathTest{ + {`c:`, `c:.`}, + {`c:\`, `c:\`}, + {`c:\abc`, `c:\abc`}, + {`c:abc\..\..\.\.\..\def`, `c:..\..\def`}, + {`c:\abc\def\..\..`, `c:\`}, + {`c:..\abc`, `c:..\abc`}, + {`\`, `\`}, + {`/`, `\`}, +} + func TestClean(t *testing.T) { - for _, test := range cleantests { - if s := filepath.ToSlash(filepath.Clean(test.path)); s != test.result { + tests := cleantests + if runtime.GOOS == "windows" { + for i, _ := range tests { + tests[i].result = filepath.FromSlash(tests[i].result) + } + tests = append(tests, wincleantests...) + } + for _, test := range tests { + if s := filepath.Clean(test.path); s != test.result { t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.result) } } @@ -292,10 +310,6 @@ func (v *TestVisitor) VisitFile(path string, f *os.FileInfo) { } func TestWalk(t *testing.T) { - // TODO(brainman): enable test once Windows version is implemented. - if runtime.GOOS == "windows" { - return - } makeTree(t) // 1) ignore error handling, expect none @@ -314,7 +328,10 @@ func TestWalk(t *testing.T) { } checkMarks(t) - if os.Getuid() > 0 { + // Test permission errors. Only possible if we're not root + // and only on some file systems (AFS, FAT). To avoid errors during + // all.bash on those file systems, skip during gotest -short. + if os.Getuid() > 0 && !testing.Short() { // introduce 2 errors: chmod top-level directories to 0 os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0) os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0) @@ -399,16 +416,30 @@ var winisabstests = []IsAbsTest{ {`C:\`, true}, {`c\`, false}, {`c::`, false}, - {`/`, true}, - {`\`, true}, - {`\Windows`, true}, + {`c:`, false}, + {`/`, false}, + {`\`, false}, + {`\Windows`, false}, + {`c:a\b`, false}, } func TestIsAbs(t *testing.T) { + var tests []IsAbsTest if runtime.GOOS == "windows" { - isabstests = append(isabstests, winisabstests...) + tests = append(tests, winisabstests...) + // All non-windows tests should fail, because they have no volume letter. + for _, test := range isabstests { + tests = append(tests, IsAbsTest{test.path, false}) + } + // All non-windows test should work as intended if prefixed with volume letter. + for _, test := range isabstests { + tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs}) + } + } else { + tests = isabstests } - for _, test := range isabstests { + + for _, test := range tests { if r := filepath.IsAbs(test.path); r != test.isAbs { t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs) } @@ -439,31 +470,48 @@ var EvalSymlinksTests = []EvalSymlinksTest{ {"test/link2/link3/test", "test"}, } -func TestEvalSymlinks(t *testing.T) { - // Symlinks are not supported under windows. - if runtime.GOOS == "windows" { - return +var EvalSymlinksAbsWindowsTests = []EvalSymlinksTest{ + {`c:\`, `c:\`}, +} + +func testEvalSymlinks(t *testing.T, tests []EvalSymlinksTest) { + for _, d := range tests { + if p, err := filepath.EvalSymlinks(d.path); err != nil { + t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) + } else if filepath.Clean(p) != filepath.Clean(d.dest) { + t.Errorf("EvalSymlinks(%q)=%q, want %q", d.path, p, d.dest) + } } +} + +func TestEvalSymlinks(t *testing.T) { defer os.RemoveAll("test") for _, d := range EvalSymlinksTestDirs { var err os.Error if d.dest == "" { err = os.Mkdir(d.path, 0755) } else { - err = os.Symlink(d.dest, d.path) + if runtime.GOOS != "windows" { + err = os.Symlink(d.dest, d.path) + } } if err != nil { t.Fatal(err) } } - // relative - for _, d := range EvalSymlinksTests { - if p, err := filepath.EvalSymlinks(d.path); err != nil { - t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) - } else if p != d.dest { - t.Errorf("EvalSymlinks(%q)=%q, want %q", d.path, p, d.dest) + var tests []EvalSymlinksTest + if runtime.GOOS == "windows" { + for _, d := range EvalSymlinksTests { + if d.path == d.dest { + // will test only real files and directories + tests = append(tests, d) + } } + } else { + tests = EvalSymlinksTests } + // relative + testEvalSymlinks(t, tests) // absolute /* These tests do not work in the gccgo test environment. goroot, err := filepath.EvalSymlinks(os.Getenv("GOROOT")) @@ -471,17 +519,16 @@ func TestEvalSymlinks(t *testing.T) { t.Fatalf("EvalSymlinks(%q) error: %v", os.Getenv("GOROOT"), err) } testroot := filepath.Join(goroot, "src", "pkg", "path", "filepath") - for _, d := range EvalSymlinksTests { - a := EvalSymlinksTest{ - filepath.Join(testroot, d.path), - filepath.Join(testroot, d.dest), - } - if p, err := filepath.EvalSymlinks(a.path); err != nil { - t.Errorf("EvalSymlinks(%q) error: %v", a.path, err) - } else if p != a.dest { - t.Errorf("EvalSymlinks(%q)=%q, want %q", a.path, p, a.dest) + for i, d := range tests { + tests[i].path = filepath.Join(testroot, d.path) + tests[i].dest = filepath.Join(testroot, d.dest) + } + if runtime.GOOS == "windows" { + for _, d := range EvalSymlinksAbsWindowsTests { + tests = append(tests, d) } } + testEvalSymlinks(t, tests) */ } @@ -496,6 +543,7 @@ var abstests = []string{ // Already absolute "$GOROOT/src/Make.pkg", + "$GOROOT/src/../src/Make.pkg", } func TestAbs(t *testing.T) { @@ -524,6 +572,9 @@ func TestAbs(t *testing.T) { if !filepath.IsAbs(abspath) { t.Errorf("Abs(%q)=%q, not an absolute path", path, abspath) } + if filepath.IsAbs(path) && abspath != filepath.Clean(path) { + t.Errorf("Abs(%q)=%q, isn't clean", path, abspath) + } } } diff --git a/libgo/go/path/filepath/path_unix.go b/libgo/go/path/filepath/path_unix.go index f8ac248..b2a4151 100644 --- a/libgo/go/path/filepath/path_unix.go +++ b/libgo/go/path/filepath/path_unix.go @@ -6,23 +6,18 @@ package filepath import "strings" -const ( - Separator = '/' // OS-specific path separator - ListSeparator = ':' // OS-specific path list separator -) - -// isSeparator returns true if c is a directory separator character. -func isSeparator(c uint8) bool { - return Separator == c -} - // IsAbs returns true if the path is absolute. func IsAbs(path string) bool { return strings.HasPrefix(path, "/") } -// volumeName returns the leading volume name on Windows. +// VolumeName returns the leading volume name on Windows. // It returns "" elsewhere. -func volumeName(path string) string { +func VolumeName(path string) string { return "" } + +// HasPrefix tests whether the path p begins with prefix. +func HasPrefix(p, prefix string) bool { + return strings.HasPrefix(p, prefix) +} diff --git a/libgo/go/path/filepath/path_windows.go b/libgo/go/path/filepath/path_windows.go index dbd1c1e..2535697 100644 --- a/libgo/go/path/filepath/path_windows.go +++ b/libgo/go/path/filepath/path_windows.go @@ -4,34 +4,43 @@ package filepath -const ( - Separator = '\\' // OS-specific path separator - ListSeparator = ':' // OS-specific path list separator -) - -// isSeparator returns true if c is a directory separator character. -func isSeparator(c uint8) bool { - // NOTE: Windows accept / as path separator. - return c == '\\' || c == '/' -} +import "strings" // IsAbs returns true if the path is absolute. -func IsAbs(path string) bool { - return path != "" && (volumeName(path) != "" || isSeparator(path[0])) +func IsAbs(path string) (b bool) { + v := VolumeName(path) + if v == "" { + return false + } + path = path[len(v):] + if path == "" { + return false + } + return path[0] == '/' || path[0] == '\\' } -// volumeName return leading volume name. -// If given "C:\foo\bar", return "C:" on windows. -func volumeName(path string) string { - if path == "" { +// VolumeName returns leading volume name. +// Given "C:\foo\bar" it returns "C:" under windows. +// On other platforms it returns "". +func VolumeName(path string) (v string) { + if len(path) < 2 { return "" } // with drive letter c := path[0] - if len(path) > 2 && path[1] == ':' && isSeparator(path[2]) && + if path[1] == ':' && ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') { - return path[0:2] + return path[:2] } return "" } + +// HasPrefix tests whether the path p begins with prefix. +// It ignores case while comparing. +func HasPrefix(p, prefix string) bool { + if strings.HasPrefix(p, prefix) { + return true + } + return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix)) +} |