--- orig/path_windowsspecific.go 2026-03-28 16:15:19 +++ path_windowsspecific.go 2026-03-28 16:14:52 @@ -2,103 +2,28 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package filepath +package winpath 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 { +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 = '\\' } @@ -112,7 +37,3 @@ } return Clean(b.String()) } - -func sameWord(a, b string) bool { - return strings.EqualFold(a, b) -}