* reload1.c (eliminate_regs_1): Call gen_rtx_raw_SUBREG for SUBREGs
[official-gcc.git] / libgo / go / path / filepath / path_windows.go
blob0d8b62015c56846883da962fe319df7b33635fa9
1 // Copyright 2010 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.
5 package filepath
7 import (
8 "strings"
9 "syscall"
12 func isSlash(c uint8) bool {
13 return c == '\\' || c == '/'
16 // IsAbs reports whether the path is absolute.
17 func IsAbs(path string) (b bool) {
18 l := volumeNameLen(path)
19 if l == 0 {
20 return false
22 path = path[l:]
23 if path == "" {
24 return false
26 return isSlash(path[0])
29 // volumeNameLen returns length of the leading volume name on Windows.
30 // It returns 0 elsewhere.
31 func volumeNameLen(path string) int {
32 if len(path) < 2 {
33 return 0
35 // with drive letter
36 c := path[0]
37 if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
38 return 2
40 // is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
41 if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
42 !isSlash(path[2]) && path[2] != '.' {
43 // first, leading `\\` and next shouldn't be `\`. its server name.
44 for n := 3; n < l-1; n++ {
45 // second, next '\' shouldn't be repeated.
46 if isSlash(path[n]) {
47 n++
48 // third, following something characters. its share name.
49 if !isSlash(path[n]) {
50 if path[n] == '.' {
51 break
53 for ; n < l; n++ {
54 if isSlash(path[n]) {
55 break
58 return n
60 break
64 return 0
67 // HasPrefix exists for historical compatibility and should not be used.
69 // Deprecated: HasPrefix does not respect path boundaries and
70 // does not ignore case when required.
71 func HasPrefix(p, prefix string) bool {
72 if strings.HasPrefix(p, prefix) {
73 return true
75 return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix))
78 func splitList(path string) []string {
79 // The same implementation is used in LookPath in os/exec;
80 // consider changing os/exec when changing this.
82 if path == "" {
83 return []string{}
86 // Split path, respecting but preserving quotes.
87 list := []string{}
88 start := 0
89 quo := false
90 for i := 0; i < len(path); i++ {
91 switch c := path[i]; {
92 case c == '"':
93 quo = !quo
94 case c == ListSeparator && !quo:
95 list = append(list, path[start:i])
96 start = i + 1
99 list = append(list, path[start:])
101 // Remove quotes.
102 for i, s := range list {
103 if strings.Contains(s, `"`) {
104 list[i] = strings.Replace(s, `"`, ``, -1)
108 return list
111 func abs(path string) (string, error) {
112 fullPath, err := syscall.FullPath(path)
113 if err != nil {
114 return "", err
116 return Clean(fullPath), nil
119 func join(elem []string) string {
120 for i, e := range elem {
121 if e != "" {
122 return joinNonEmpty(elem[i:])
125 return ""
128 // joinNonEmpty is like join, but it assumes that the first element is non-empty.
129 func joinNonEmpty(elem []string) string {
130 if len(elem[0]) == 2 && elem[0][1] == ':' {
131 // First element is drive letter without terminating slash.
132 // Keep path relative to current directory on that drive.
133 return Clean(elem[0] + strings.Join(elem[1:], string(Separator)))
135 // The following logic prevents Join from inadvertently creating a
136 // UNC path on Windows. Unless the first element is a UNC path, Join
137 // shouldn't create a UNC path. See golang.org/issue/9167.
138 p := Clean(strings.Join(elem, string(Separator)))
139 if !isUNC(p) {
140 return p
142 // p == UNC only allowed when the first element is a UNC path.
143 head := Clean(elem[0])
144 if isUNC(head) {
145 return p
147 // head + tail == UNC, but joining two non-UNC paths should not result
148 // in a UNC path. Undo creation of UNC path.
149 tail := Clean(strings.Join(elem[1:], string(Separator)))
150 if head[len(head)-1] == Separator {
151 return head + tail
153 return head + string(Separator) + tail
156 // isUNC reports whether path is a UNC path.
157 func isUNC(path string) bool {
158 return volumeNameLen(path) > 2
161 func sameWord(a, b string) bool {
162 return strings.EqualFold(a, b)