github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/cmd/go/internal/load/path.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package load 6 7 import ( 8 "path/filepath" 9 "strings" 10 ) 11 12 // hasSubdir reports whether dir is a subdirectory of 13 // (possibly multiple levels below) root. 14 // If so, it sets rel to the path fragment that must be 15 // appended to root to reach dir. 16 func hasSubdir(root, dir string) (rel string, ok bool) { 17 if p, err := filepath.EvalSymlinks(root); err == nil { 18 root = p 19 } 20 if p, err := filepath.EvalSymlinks(dir); err == nil { 21 dir = p 22 } 23 const sep = string(filepath.Separator) 24 root = filepath.Clean(root) 25 if !strings.HasSuffix(root, sep) { 26 root += sep 27 } 28 dir = filepath.Clean(dir) 29 if !strings.HasPrefix(dir, root) { 30 return "", false 31 } 32 return filepath.ToSlash(dir[len(root):]), true 33 } 34 35 // hasPathPrefix reports whether the path s begins with the 36 // elements in prefix. 37 func hasPathPrefix(s, prefix string) bool { 38 switch { 39 default: 40 return false 41 case len(s) == len(prefix): 42 return s == prefix 43 case len(s) > len(prefix): 44 if prefix != "" && prefix[len(prefix)-1] == '/' { 45 return strings.HasPrefix(s, prefix) 46 } 47 return s[len(prefix)] == '/' && s[:len(prefix)] == prefix 48 } 49 } 50 51 // expandPath returns the symlink-expanded form of path. 52 func expandPath(p string) string { 53 x, err := filepath.EvalSymlinks(p) 54 if err == nil { 55 return x 56 } 57 return p 58 } 59 60 // hasFilePathPrefix reports whether the filesystem path s begins with the 61 // elements in prefix. 62 func hasFilePathPrefix(s, prefix string) bool { 63 sv := strings.ToUpper(filepath.VolumeName(s)) 64 pv := strings.ToUpper(filepath.VolumeName(prefix)) 65 s = s[len(sv):] 66 prefix = prefix[len(pv):] 67 switch { 68 default: 69 return false 70 case sv != pv: 71 return false 72 case len(s) == len(prefix): 73 return s == prefix 74 case len(s) > len(prefix): 75 if prefix != "" && prefix[len(prefix)-1] == filepath.Separator { 76 return strings.HasPrefix(s, prefix) 77 } 78 return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix 79 } 80 }