forked from ernestrc/logd
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathluvipath.lua
124 lines (113 loc) · 2.72 KB
/
luvipath.lua
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
local luvi = require('luvi')
local getPrefix, splitPath, joinParts
local isWindows
if _G.jit then
isWindows = _G.jit.os == "Windows"
else
isWindows = not not package.path:match("\\")
end
if isWindows then
-- Windows aware path utilities
function getPrefix(path)
return path:match("^%a:\\") or
path:match("^/") or
path:match("^\\+")
end
function splitPath(path)
local parts = {}
for part in string.gmatch(path, '([^/\\]+)') do
table.insert(parts, part)
end
return parts
end
function joinParts(prefix, parts, i, j)
if not prefix then
return table.concat(parts, '/', i, j)
elseif prefix ~= '/' then
return prefix .. table.concat(parts, '\\', i, j)
else
return prefix .. table.concat(parts, '/', i, j)
end
end
else
-- Simple optimized versions for UNIX systems
function getPrefix(path)
return path:match("^/")
end
function splitPath(path)
local parts = {}
for part in string.gmatch(path, '([^/]+)') do
table.insert(parts, part)
end
return parts
end
function joinParts(prefix, parts, i, j)
if prefix then
return prefix .. table.concat(parts, '/', i, j)
end
return table.concat(parts, '/', i, j)
end
end
local function pathJoin(...)
local inputs = {...}
local l = #inputs
-- Find the last segment that is an absolute path
-- Or if all are relative, prefix will be nil
local i = l
local prefix
while true do
prefix = getPrefix(inputs[i])
if prefix or i <= 1 then break end
i = i - 1
end
-- If there was one, remove its prefix from its segment
if prefix then
inputs[i] = inputs[i]:sub(#prefix)
end
-- Split all the paths segments into one large list
local parts = {}
while i <= l do
local sub = splitPath(inputs[i])
for j = 1, #sub do
parts[#parts + 1] = sub[j]
end
i = i + 1
end
-- Evaluate special segments in reverse order.
local skip = 0
local reversed = {}
for idx = #parts, 1, -1 do
local part = parts[idx]
if part ~= '.' then
if part == '..' then
skip = skip + 1
elseif skip > 0 then
skip = skip - 1
else
reversed[#reversed + 1] = part
end
end
end
-- Reverse the list again to get the correct order
parts = reversed
for idx = 1, #parts / 2 do
local j = #parts - idx + 1
parts[idx], parts[j] = parts[j], parts[idx]
end
local path = joinParts(prefix, parts)
return path
end
-- Legacy path exports
luvi.path = {
join = pathJoin,
getPrefix = getPrefix,
splitPath = splitPath,
joinparts = joinParts,
}
package.loaded['luvipath'] = {
isWindows = isWindows,
getPrefix = getPrefix,
splitPath = splitPath,
joinParts = joinParts,
pathJoin = pathJoin,
}