-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathwindows.jl
90 lines (72 loc) · 2.6 KB
/
windows.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
struct WindowsPath <: AbstractPath
parts::Tuple{Vararg{String}}
drive::String
root::String
end
function _win_splitdrive(path::String)
m = match(r"^([^\\]+:|\\\\[^\\]+\\[^\\]+|\\\\\?\\UNC\\[^\\]+\\[^\\]+|\\\\\?\\[^\\]+:|)(.*)$", path)
String(m.captures[1]), String(m.captures[2])
end
WindowsPath() = WindowsPath(tuple(), "", "")
function WindowsPath(parts::Tuple)
if parts[1]==WIN_PATH_SEPARATOR
return WindowsPath(parts, "", WIN_PATH_SEPARATOR)
elseif occursin(":", parts[1])
l_drive, l_path = _win_splitdrive(parts[1])
return WindowsPath(parts, l_drive, l_path)
else
WindowsPath(parts, "", "")
end
end
function WindowsPath(str::AbstractString)
if isempty(str)
return WindowsPath(tuple("."), "", "")
end
if startswith(str, "\\\\?\\")
error("The \\\\?\\ prefix is currently not supported.")
end
str = replace(str, POSIX_PATH_SEPARATOR => WIN_PATH_SEPARATOR)
if startswith(str, "\\\\")
error("UNC paths are currently not supported.")
elseif startswith(str, "\\")
tokenized = split(str, WIN_PATH_SEPARATOR)
return WindowsPath(tuple(WIN_PATH_SEPARATOR, String.(tokenized[2:end])...), "", WIN_PATH_SEPARATOR)
elseif occursin(":", str)
l_drive, l_path = _win_splitdrive(str)
tokenized = split(l_path, WIN_PATH_SEPARATOR)
l_root = isempty(tokenized[1]) ? WIN_PATH_SEPARATOR : ""
if isempty(tokenized[1])
tokenized = tokenized[2:end]
end
if !isempty(l_drive) || !isempty(l_root)
tokenized = tuple(string(l_drive, l_root), tokenized...)
end
return WindowsPath(tuple(String.(tokenized)...), l_drive, l_root)
else
tokenized = split(str, WIN_PATH_SEPARATOR)
return WindowsPath(tuple(String.(tokenized)...), "", "")
end
end
function ==(a::WindowsPath, b::WindowsPath)
return lowercase.(parts(a)) == lowercase.(parts(b)) &&
lowercase(drive(a)) == lowercase(drive(b)) &&
lowercase(root(a)) == lowercase(root(b))
end
Base.String(path::WindowsPath) = joinpath(parts(path)...)
parts(path::WindowsPath) = path.parts
drive(path::WindowsPath) = path.drive
root(path::WindowsPath) = path.root
function Base.show(io::IO, path::WindowsPath)
print(io, "p\"")
if isabs(path)
print(io, replace(anchor(path), "\\" => "/"))
print(io, join(parts(path)[2:end], "/"))
else
print(io, join(parts(path), "/"))
end
print(io, "\"")
end
function isabs(path::WindowsPath)
return !isempty(drive(path)) || !isempty(root(path))
end
expanduser(path::WindowsPath) = path