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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
--
-- os.lua
-- Additions to the OS namespace.
-- Copyright (c) 2002-2011 Jason Perkins and the Premake project
--
--
-- Same as os.execute(), but accepts string formatting arguments.
--
function os.executef(cmd, ...)
local arg={...}
cmd = string.format(cmd, table.unpack(arg))
return os.execute(cmd)
end
--
-- Scan the well-known system locations for a particular library.
--
local function parse_ld_so_conf(conf_file)
-- Linux ldconfig file parser to find system library locations
local first, last
local dirs = { }
local file = io.open(conf_file)
-- Handle missing ld.so.conf (BSDs) gracefully
if file == nil then
return dirs
end
for line in file:lines() do
-- ignore comments
first = line:find("#", 1, true)
if first ~= nil then
line = line:sub(1, first - 1)
end
if line ~= "" then
-- check for include files
first, last = line:find("include%s+")
if first ~= nil then
-- found include glob
local include_glob = line:sub(last + 1)
local includes = os.matchfiles(include_glob)
for _, v in ipairs(includes) do
dirs = table.join(dirs, parse_ld_so_conf(v))
end
else
-- found an actual ld path entry
table.insert(dirs, line)
end
end
end
return dirs
end
function os.findlib(libname)
local path, formats
-- assemble a search path, depending on the platform
if os.is("windows") then
formats = { "%s.dll", "%s" }
path = os.getenv("PATH")
else
if os.is("macosx") then
formats = { "lib%s.dylib", "%s.dylib" }
path = os.getenv("DYLD_LIBRARY_PATH")
else
formats = { "lib%s.so", "%s.so" }
path = os.getenv("LD_LIBRARY_PATH") or ""
for _, v in ipairs(parse_ld_so_conf("/etc/ld.so.conf")) do
path = path .. ":" .. v
end
end
table.insert(formats, "%s")
path = path or ""
if os.is64bit() then
path = path .. ":/lib64:/usr/lib64/:usr/local/lib64"
end
path = path .. ":/lib:/usr/lib:/usr/local/lib"
end
for _, fmt in ipairs(formats) do
local name = string.format(fmt, libname)
local result = os.pathsearch(name, path)
if result then return result end
end
end
--
-- Retrieve the current operating system ID string.
--
function os.get()
return _OPTIONS.os or _OS
end
--
-- Check the current operating system; may be set with the /os command line flag.
--
function os.is(id)
return (os.get():lower() == id:lower())
end
--
-- Determine if the current system is running a 64-bit architecture
--
local _64BitHostTypes = {
"x86_64",
"ia64",
"amd64",
"ppc64",
"powerpc64",
"sparc64",
"arm64"
}
function os.is64bit()
-- Call the native code implementation. If this returns true then
-- we're 64-bit, otherwise do more checking locally
if (os._is64bit()) then
return true
end
-- Identify the system
local arch = ""
if _OS == "windows" then
arch = os.getenv("PROCESSOR_ARCHITECTURE")
elseif _OS == "macosx" then
arch = os.outputof("echo $HOSTTYPE")
else
arch = os.outputof("uname -m")
end
if nil ~= arch then
-- Check our known 64-bit identifiers
arch = arch:lower()
for _, hosttype in ipairs(_64BitHostTypes) do
if arch:find(hosttype) then
return true
end
end
end
return false
end
--
-- The os.matchdirs() and os.matchfiles() functions
--
local function domatch(result, mask, wantfiles)
-- need to remove extraneous path info from the mask to ensure a match
-- against the paths returned by the OS. Haven't come up with a good
-- way to do it yet, so will handle cases as they come up
if mask:startswith("./") then
mask = mask:sub(3)
end
-- strip off any leading directory information to find out
-- where the search should take place
local basedir = mask
local starpos = mask:find("%*")
if starpos then
basedir = basedir:sub(1, starpos - 1)
end
basedir = path.getdirectory(basedir)
if (basedir == ".") then basedir = "" end
-- recurse into subdirectories?
local recurse = mask:find("**", nil, true)
-- convert mask to a Lua pattern
mask = path.wildcards(mask)
local function matchwalker(basedir)
local wildcard = path.join(basedir, "*")
-- retrieve files from OS and test against mask
local m = os.matchstart(wildcard)
while (os.matchnext(m)) do
local isfile = os.matchisfile(m)
if ((wantfiles and isfile) or (not wantfiles and not isfile)) then
local fname = path.join(basedir, os.matchname(m))
if fname:match(mask) == fname then
table.insert(result, fname)
end
end
end
os.matchdone(m)
-- check subdirectories
if recurse then
m = os.matchstart(wildcard)
while (os.matchnext(m)) do
if not os.matchisfile(m) then
local dirname = os.matchname(m)
matchwalker(path.join(basedir, dirname))
end
end
os.matchdone(m)
end
end
matchwalker(basedir)
end
function os.matchdirs(...)
local arg={...}
local result = { }
for _, mask in ipairs(arg) do
domatch(result, mask, false)
end
return result
end
function os.matchfiles(...)
local arg={...}
local result = { }
for _, mask in ipairs(arg) do
domatch(result, mask, true)
end
return result
end
--
-- An overload of the os.mkdir() function, which will create any missing
-- subdirectories along the path.
--
local builtin_mkdir = os.mkdir
function os.mkdir(p)
local dir = iif(p:startswith("/"), "/", "")
for part in p:gmatch("[^/]+") do
dir = dir .. part
if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then
local ok, err = builtin_mkdir(dir)
if (not ok) then
return nil, err
end
end
dir = dir .. "/"
end
return true
end
--
-- Run a shell command and return the output.
--
function os.outputof(cmd)
local pipe = io.popen(cmd)
local result = pipe:read('*a')
pipe:close()
return result
end
--
-- Remove a directory, along with any contained files or subdirectories.
--
local builtin_rmdir = os.rmdir
function os.rmdir(p)
-- recursively remove subdirectories
local dirs = os.matchdirs(p .. "/*")
for _, dname in ipairs(dirs) do
os.rmdir(dname)
end
-- remove any files
local files = os.matchfiles(p .. "/*")
for _, fname in ipairs(files) do
os.remove(fname)
end
-- remove this directory
builtin_rmdir(p)
end
|