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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
require 'libpaths'
local assert = assert
local debug = debug
local pcall = pcall
local type = type
local ipairs = ipairs
local os = os
function paths.is_win()
return paths.uname():match('Windows')
end
function paths.is_mac()
return paths.uname():match('Darwin')
end
if paths.is_win() then
paths.home = os.getenv('HOMEDRIVE') or 'C:'
paths.home = paths.home .. ( os.getenv('HOMEPATH') or '\\' )
else
paths.home = os.getenv('HOME') or '.'
end
function paths.files(s, f)
local d = paths.dir(s)
local n = 0
if type(f) == 'string' then
local pattern = f
f = function(file) return file:find(pattern) end
elseif f and type(f) ~= 'function' then
error("Expecting optional arg 2 to be function or string. Got : "..torch.type(f))
end
f = f or function(file) return true end
local n = 0
return function()
while true do
n = n + 1
if d == nil or n > #d then
return nil
elseif f(d[n]) then
return d[n]
end
end
end
end
function paths.iterdirs(s)
return paths.files(s,
function(dir)
return paths.dirp(paths.concat(s, dir)) and dir ~= '.' and dir ~= '..'
end)
end
function paths.iterfiles(s)
return paths.files(s,
function(file)
return paths.filep(paths.concat(s, file)) and file ~= '.' and file ~= '..'
end)
end
function paths.thisfile(arg, depth)
local s = debug.getinfo(depth or 2).source
if type(s) ~= "string" then
s = nil
elseif s:match("^@") then -- when called from a file
s = paths.concat(s:sub(2))
elseif s:match("^qt[.]") then -- when called from a qtide editor
local function z(s) return qt[s].fileName:tostring() end
local b, f = pcall(z, s:sub(4));
if b and f and f ~= "" then s = f else s = nil end
end
if type(arg) == "string" then
if s then s = paths.concat(paths.dirname(s), arg) else s = arg end
end
return s
end
function paths.dofile(f, depth)
local s = paths.thisfile(nil, 1 + (depth or 2))
if s and s ~= "" then
f = paths.concat(paths.dirname(s),f)
end
return dofile(f)
end
function paths.rmall(d, more)
if more ~= 'yes' then
return nil, "missing second argument ('yes')"
elseif paths.filep(d) then
return os.remove(d)
elseif paths.dirp(d) then
for f in paths.files(d) do
if f ~= '.' and f ~= '..' then
local ff = paths.concat(d, f)
local r0,r1,r2 = paths.rmall(ff, more)
if not r0 then
return r0,r1,ff
end
end
end
return paths.rmdir(d)
else
return nil, "not a file or directory", d
end
end
function paths.findprogram(...)
for _,exe in ipairs{...} do
if paths.is_win() then
if not exe:match('[.]exe$') then
exe = exe .. '.exe'
end
local path, k, x = os.getenv("PATH") or "."
for dir in path:gmatch('[^;]+') do
x = paths.concat(dir, exe)
if paths.filep(x) then return x end
end
local function clean(s)
if s:match('^"') then return s:match('[^"]+') else return s end
end
k = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' .. exe
x = paths.getregistryvalue('HKEY_CURRENT_USER', k, '')
if type(x) == 'string' then return clean(x) end
x = paths.getregistryvalue('HKEY_LOCAL_MACHINE', k, '')
if type(x) == 'string' then return clean(x) end
k = 'Applications\\' .. exe .. '\\shell\\open\\command'
x = paths.getregistryvalue('HKEY_CLASSES_ROOT', k, '')
if type(x) == 'string' then return clean(x) end
else
local path = os.getenv("PATH") or "."
for dir in path:gmatch('[^:]+') do
local x = paths.concat(dir, exe)
if paths.filep(x) then return x end
end
end
end
return nil
end
return paths
|