115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package filepath
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
// HasPrefix exists for historical compatibility and should not be used.
|
|
//
|
|
// Deprecated: HasPrefix does not respect path boundaries and
|
|
// does not ignore case when required.
|
|
func HasPrefix(p, prefix string) bool {
|
|
if strings.HasPrefix(p, prefix) {
|
|
return true
|
|
}
|
|
return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix))
|
|
}
|
|
|
|
func splitList(path string) []string {
|
|
// The same implementation is used in LookPath in os/exec;
|
|
// consider changing os/exec when changing this.
|
|
|
|
if path == "" {
|
|
return []string{}
|
|
}
|
|
|
|
// Split path, respecting but preserving quotes.
|
|
list := []string{}
|
|
start := 0
|
|
quo := false
|
|
for i := 0; i < len(path); i++ {
|
|
switch c := path[i]; {
|
|
case c == '"':
|
|
quo = !quo
|
|
case c == ListSeparator && !quo:
|
|
list = append(list, path[start:i])
|
|
start = i + 1
|
|
}
|
|
}
|
|
list = append(list, path[start:])
|
|
|
|
// Remove quotes.
|
|
for i, s := range list {
|
|
list[i] = strings.ReplaceAll(s, `"`, ``)
|
|
}
|
|
|
|
return list
|
|
}
|
|
|
|
func abs(path string) (string, error) {
|
|
if path == "" {
|
|
// syscall.FullPath returns an error on empty path, because it's not a valid path.
|
|
// To implement Abs behavior of returning working directory on empty string input,
|
|
// special-case empty path by changing it to "." path. See golang.org/issue/24441.
|
|
path = "."
|
|
}
|
|
fullPath, err := syscall.FullPath(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return Clean(fullPath), nil
|
|
}
|
|
|
|
func join(elem []string) string {
|
|
var b strings.Builder
|
|
var lastChar byte
|
|
for _, e := range elem {
|
|
switch {
|
|
case b.Len() == 0:
|
|
// Add the first non-empty path element unchanged.
|
|
case os.IsPathSeparator(lastChar):
|
|
// If the path ends in a slash, strip any leading slashes from the next
|
|
// path element to avoid creating a UNC path (any path starting with "\\")
|
|
// from non-UNC elements.
|
|
//
|
|
// The correct behavior for Join when the first element is an incomplete UNC
|
|
// path (for example, "\\") is underspecified. We currently join subsequent
|
|
// elements so Join("\\", "host", "share") produces "\\host\share".
|
|
for len(e) > 0 && os.IsPathSeparator(e[0]) {
|
|
e = e[1:]
|
|
}
|
|
// If the path is \ and the next path element is ??,
|
|
// add an extra .\ to create \.\?? rather than \??\
|
|
// (a Root Local Device path).
|
|
if b.Len() == 1 && strings.HasPrefix(e, "??") && (len(e) == len("??") || os.IsPathSeparator(e[2])) {
|
|
b.WriteString(`.\`)
|
|
}
|
|
case lastChar == ':':
|
|
// If the path ends in a colon, keep the path relative to the current directory
|
|
// on a drive and don't add a separator. Preserve leading slashes in the next
|
|
// path element, which may make the path absolute.
|
|
//
|
|
// Join(`C:`, `f`) = `C:f`
|
|
// Join(`C:`, `\f`) = `C:\f`
|
|
default:
|
|
// In all other cases, add a separator between elements.
|
|
b.WriteByte('\\')
|
|
lastChar = '\\'
|
|
}
|
|
if len(e) > 0 {
|
|
b.WriteString(e)
|
|
lastChar = e[len(e)-1]
|
|
}
|
|
}
|
|
if b.Len() == 0 {
|
|
return ""
|
|
}
|
|
return Clean(b.String())
|
|
}
|
|
|
|
func sameWord(a, b string) bool {
|
|
return strings.EqualFold(a, b)
|
|
}
|