forked from thenumbernine/lua-ext
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathio.lua
More file actions
144 lines (127 loc) · 3.67 KB
/
io.lua
File metadata and controls
144 lines (127 loc) · 3.67 KB
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
local io = {}
for k,v in pairs(require 'io') do io[k] = v end
-- io or os? io since it is shorthand for io.open():read()
function io.readfile(fn)
local f, err = io.open(fn, 'rb')
if not f then return false, err end
-- file.read compat (tested on Windows)
-- *a a *l l
-- lua-5.3.5: yes yes yes yes jit == nil and _VERSION == 'Lua 5.3'
-- lua-5.2.4: yes no yes no jit == nil and _VERSION == 'Lua 5.2'
-- lua-5.1.5: yes no yes no jit == nil and _VERSION == 'Lua 5.1'
-- luajit-2.1.0-beta3: yes yes yes yes (jit.version == 'LuaJIT 2.1.0-beta3' / jit.version_num == 20100)
-- luajit-2.0.5 yes no yes no (jit.version == 'LuaJIT 2.0.5' / jit.version_num == 20005)
local d = f:read('*a')
f:close()
return d
end
function io.writefile(fn, d)
local f, err = io.open(fn, 'wb')
if not f then return false, err end
if d then f:write(d) end
f:close()
return true
end
function io.appendfile(fn, d)
local f, err = io.open(fn, 'ab')
if not f then return false, err end
if d then f:write(d) end
f:close()
return true
end
function io.readproc(cmd)
local f, err = io.popen(cmd)
if not f then return false, err end
local d = f:read('*a')
f:close()
return d
end
function io.getfiledir(fn)
local dir, name = fn:match'^(.*)/([^/]-)$'
if dir == '' then
-- "/" => "/", "/"
if name == '' then return '/', '/' end
-- "/x" => "/", "x"
return '/', name
elseif not dir then
return '.', fn
end
return dir, name
end
-- this should really return the extension first.
-- that is the function name, after all.
function io.getfileext(fn)
local front, ext = fn:match('^(.*)%.([^%./]-)$')
if front then
return front, ext
end
-- no ext? then leave that field nil - just return the base filename
return fn, nil
end
-- in Lua 5.3.5 at least:
-- (for file = getmetatable(io.open(something)))
-- io.read ~= file.read
-- file.__index == file
-- within meta.lua, simply modifying the file metatable
-- but if someone requires ext/io.lua and not lua then io.open and all subsequently created files will need to be modified
--[[ TODO FIXME
if jit or (not jit and _VERSION < 'Lua 5.2') then
local function fixfilereadargs(...)
print(...)
if select('#', ...) == 0 then return ... end
local fmt = select(1, ...)
if fmt == 'a' then fmt = '*a'
elseif fmt == 'l' then fmt = '*l'
elseif fmt == 'n' then fmt = '*n'
end
return fmt, fixfilereadargs(select(2, ...))
end
-- even though io.read is basically the same as file.read, they are still different functions
-- so file.read will still have to be separately overridden
local oldfileread
local function newfileread(...)
return oldfileread(fixfilereadargs(...))
end
io.read = function(...)
return newfileread(io.stdout, ...)
end
local oldfilemeta = debug.getmetatable(io.stdout)
local newfilemeta = {}
for k,v in pairs(oldfilemeta) do
newfilemeta[k] = v
end
-- override file:read
oldfileread = oldfilemeta.read
newfilemeta.read = newfileread
-- should these be overridden in this case, or only when running ext/meta.lua?
debug.setmetatable(io.stdin, newfilemeta)
debug.setmetatable(io.stdout, newfilemeta)
debug.setmetatable(io.stderr, newfilemeta)
local function fixfilemeta(...)
if select('#', ...) > 0 then
local f = select(1, ...)
if f then
debug.setmetatable(f, newfilemeta)
end
end
return ...
end
local oldioopen = io.open
function io.open(...)
return fixfilemeta(oldioopen(...))
end
end
--]]
-- [[ add lfs lock/unlock to files
do
local detect_lfs = require 'ext.detect_lfs'
local lfs = detect_lfs()
if lfs then
-- can I do this? yes on Lua 5.3. Yes on LuaJIT 2.1.0-beta3
local filemeta = debug.getmetatable(io.stdout)
filemeta.lock = lfs.lock
filemeta.unlock = lfs.unlock
end
end
--]]
return io