github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/os/path_windows.go (about)

     1  // Copyright 2011 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 os
     6  
     7  const (
     8  	PathSeparator     = '\\' // OS-specific path separator
     9  	PathListSeparator = ';'  // OS-specific path list separator
    10  )
    11  
    12  // IsPathSeparator reports whether c is a directory separator character.
    13  func IsPathSeparator(c uint8) bool {
    14  	// NOTE: Windows accept / as path separator.
    15  	return c == '\\' || c == '/'
    16  }
    17  
    18  // basename removes trailing slashes and the leading
    19  // directory name and drive letter from path name.
    20  func basename(name string) string {
    21  	// Remove drive letter
    22  	if len(name) == 2 && name[1] == ':' {
    23  		name = "."
    24  	} else if len(name) > 2 && name[1] == ':' {
    25  		name = name[2:]
    26  	}
    27  	i := len(name) - 1
    28  	// Remove trailing slashes
    29  	for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
    30  		name = name[:i]
    31  	}
    32  	// Remove leading directory name
    33  	for i--; i >= 0; i-- {
    34  		if name[i] == '/' || name[i] == '\\' {
    35  			name = name[i+1:]
    36  			break
    37  		}
    38  	}
    39  	return name
    40  }
    41  
    42  func isAbs(path string) (b bool) {
    43  	v := volumeName(path)
    44  	if v == "" {
    45  		return false
    46  	}
    47  	path = path[len(v):]
    48  	if path == "" {
    49  		return false
    50  	}
    51  	return IsPathSeparator(path[0])
    52  }
    53  
    54  func volumeName(path string) (v string) {
    55  	if len(path) < 2 {
    56  		return ""
    57  	}
    58  	// with drive letter
    59  	c := path[0]
    60  	if path[1] == ':' &&
    61  		('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
    62  			'A' <= c && c <= 'Z') {
    63  		return path[:2]
    64  	}
    65  	// is it UNC
    66  	if l := len(path); l >= 5 && IsPathSeparator(path[0]) && IsPathSeparator(path[1]) &&
    67  		!IsPathSeparator(path[2]) && path[2] != '.' {
    68  		// first, leading `\\` and next shouldn't be `\`. its server name.
    69  		for n := 3; n < l-1; n++ {
    70  			// second, next '\' shouldn't be repeated.
    71  			if IsPathSeparator(path[n]) {
    72  				n++
    73  				// third, following something characters. its share name.
    74  				if !IsPathSeparator(path[n]) {
    75  					if path[n] == '.' {
    76  						break
    77  					}
    78  					for ; n < l; n++ {
    79  						if IsPathSeparator(path[n]) {
    80  							break
    81  						}
    82  					}
    83  					return path[:n]
    84  				}
    85  				break
    86  			}
    87  		}
    88  	}
    89  	return ""
    90  }
    91  
    92  func fromSlash(path string) string {
    93  	// Replace each '/' with '\\' if present
    94  	var pathbuf []byte
    95  	var lastSlash int
    96  	for i, b := range path {
    97  		if b == '/' {
    98  			if pathbuf == nil {
    99  				pathbuf = make([]byte, len(path))
   100  			}
   101  			copy(pathbuf[lastSlash:], path[lastSlash:i])
   102  			pathbuf[i] = '\\'
   103  			lastSlash = i + 1
   104  		}
   105  	}
   106  	if pathbuf == nil {
   107  		return path
   108  	}
   109  
   110  	copy(pathbuf[lastSlash:], path[lastSlash:])
   111  	return string(pathbuf)
   112  }
   113  
   114  func dirname(path string) string {
   115  	vol := volumeName(path)
   116  	i := len(path) - 1
   117  	for i >= len(vol) && !IsPathSeparator(path[i]) {
   118  		i--
   119  	}
   120  	dir := path[len(vol) : i+1]
   121  	last := len(dir) - 1
   122  	if last > 0 && IsPathSeparator(dir[last]) {
   123  		dir = dir[:last]
   124  	}
   125  	if dir == "" {
   126  		dir = "."
   127  	}
   128  	return vol + dir
   129  }