...
Source file src/os/path_windows.go
1
2
3
4
5 package os
6
7 const (
8 PathSeparator = '\\'
9 PathListSeparator = ';'
10 )
11
12
13 func IsPathSeparator(c uint8) bool {
14
15 return c == '\\' || c == '/'
16 }
17
18
19
20 func basename(name string) string {
21
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
29 for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
30 name = name[:i]
31 }
32
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
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
66 if l := len(path); l >= 5 && IsPathSeparator(path[0]) && IsPathSeparator(path[1]) &&
67 !IsPathSeparator(path[2]) && path[2] != '.' {
68
69 for n := 3; n < l-1; n++ {
70
71 if IsPathSeparator(path[n]) {
72 n++
73
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
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 }
130
131
132
133
134
135
136
137
138
139 func fixLongPath(path string) string {
140
141
142
143
144
145
146
147
148
149
150
151 if len(path) < 248 {
152
153
154 return path
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168 if len(path) >= 2 && path[:2] == `\\` {
169
170 return path
171 }
172 if !isAbs(path) {
173
174 return path
175 }
176
177 const prefix = `\\?`
178
179 pathbuf := make([]byte, len(prefix)+len(path)+len(`\`))
180 copy(pathbuf, prefix)
181 n := len(path)
182 r, w := 0, len(prefix)
183 for r < n {
184 switch {
185 case IsPathSeparator(path[r]):
186
187 r++
188 case path[r] == '.' && (r+1 == n || IsPathSeparator(path[r+1])):
189
190 r++
191 case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || IsPathSeparator(path[r+2])):
192
193 return path
194 default:
195 pathbuf[w] = '\\'
196 w++
197 for ; r < n && !IsPathSeparator(path[r]); r++ {
198 pathbuf[w] = path[r]
199 w++
200 }
201 }
202 }
203
204 if w == len(`\\?\c:`) {
205 pathbuf[w] = '\\'
206 w++
207 }
208 return string(pathbuf[:w])
209 }
210
211
212
213 func fixRootDirectory(p string) string {
214 if len(p) == len(`\\?\c:`) {
215 if IsPathSeparator(p[0]) && IsPathSeparator(p[1]) && p[2] == '?' && IsPathSeparator(p[3]) && p[5] == ':' {
216 return p + `\`
217 }
218 }
219 return p
220 }
221
View as plain text