Source file src/path/filepath/path_windows.go

     1  package filepath
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  	"syscall"
     7  )
     8  
     9  // HasPrefix exists for historical compatibility and should not be used.
    10  //
    11  // Deprecated: HasPrefix does not respect path boundaries and
    12  // does not ignore case when required.
    13  func HasPrefix(p, prefix string) bool {
    14  	if strings.HasPrefix(p, prefix) {
    15  		return true
    16  	}
    17  	return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix))
    18  }
    19  
    20  func splitList(path string) []string {
    21  	// The same implementation is used in LookPath in os/exec;
    22  	// consider changing os/exec when changing this.
    23  
    24  	if path == "" {
    25  		return []string{}
    26  	}
    27  
    28  	// Split path, respecting but preserving quotes.
    29  	list := []string{}
    30  	start := 0
    31  	quo := false
    32  	for i := 0; i < len(path); i++ {
    33  		switch c := path[i]; {
    34  		case c == '"':
    35  			quo = !quo
    36  		case c == ListSeparator && !quo:
    37  			list = append(list, path[start:i])
    38  			start = i + 1
    39  		}
    40  	}
    41  	list = append(list, path[start:])
    42  
    43  	// Remove quotes.
    44  	for i, s := range list {
    45  		list[i] = strings.ReplaceAll(s, `"`, ``)
    46  	}
    47  
    48  	return list
    49  }
    50  
    51  func abs(path string) (string, error) {
    52  	if path == "" {
    53  		// syscall.FullPath returns an error on empty path, because it's not a valid path.
    54  		// To implement Abs behavior of returning working directory on empty string input,
    55  		// special-case empty path by changing it to "." path. See golang.org/issue/24441.
    56  		path = "."
    57  	}
    58  	fullPath, err := syscall.FullPath(path)
    59  	if err != nil {
    60  		return "", err
    61  	}
    62  	return Clean(fullPath), nil
    63  }
    64  
    65  func join(elem []string) string {
    66  	var b strings.Builder
    67  	var lastChar byte
    68  	for _, e := range elem {
    69  		switch {
    70  		case b.Len() == 0:
    71  			// Add the first non-empty path element unchanged.
    72  		case os.IsPathSeparator(lastChar):
    73  			// If the path ends in a slash, strip any leading slashes from the next
    74  			// path element to avoid creating a UNC path (any path starting with "\\")
    75  			// from non-UNC elements.
    76  			//
    77  			// The correct behavior for Join when the first element is an incomplete UNC
    78  			// path (for example, "\\") is underspecified. We currently join subsequent
    79  			// elements so Join("\\", "host", "share") produces "\\host\share".
    80  			for len(e) > 0 && os.IsPathSeparator(e[0]) {
    81  				e = e[1:]
    82  			}
    83  			// If the path is \ and the next path element is ??,
    84  			// add an extra .\ to create \.\?? rather than \??\
    85  			// (a Root Local Device path).
    86  			if b.Len() == 1 && strings.HasPrefix(e, "??") && (len(e) == len("??") || os.IsPathSeparator(e[2])) {
    87  				b.WriteString(`.\`)
    88  			}
    89  		case lastChar == ':':
    90  			// If the path ends in a colon, keep the path relative to the current directory
    91  			// on a drive and don't add a separator. Preserve leading slashes in the next
    92  			// path element, which may make the path absolute.
    93  			//
    94  			// 	Join(`C:`, `f`) = `C:f`
    95  			//	Join(`C:`, `\f`) = `C:\f`
    96  		default:
    97  			// In all other cases, add a separator between elements.
    98  			b.WriteByte('\\')
    99  			lastChar = '\\'
   100  		}
   101  		if len(e) > 0 {
   102  			b.WriteString(e)
   103  			lastChar = e[len(e)-1]
   104  		}
   105  	}
   106  	if b.Len() == 0 {
   107  		return ""
   108  	}
   109  	return Clean(b.String())
   110  }
   111  
   112  func sameWord(a, b string) bool {
   113  	return strings.EqualFold(a, b)
   114  }
   115  

View as plain text