aboutsummaryrefslogtreecommitdiff
path: root/compat53
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2024-08-29 17:16:49 -0300
committerGitHub <noreply@github.com>2024-08-29 17:16:49 -0300
commit7a82c38437075cb2beb2fe7c6453aa91e019d6b7 (patch)
tree4b77c7e02eb1e6e5f2b875f7a5947b4fdf23c0f5 /compat53
parent1c679a282bf1255cddfbb6b3e8c5c72d9ebe57e8 (diff)
downloadlua-compat-5.3-7a82c38437075cb2beb2fe7c6453aa91e019d6b7.tar.gz
lua-compat-5.3-7a82c38437075cb2beb2fe7c6453aa91e019d6b7.tar.bz2
lua-compat-5.3-7a82c38437075cb2beb2fe7c6453aa91e019d6b7.zip
adjust file metatables even in compat53.module mode (#67)
* adjust file metatables even in compat53.module mode * apply tweaks only to LuaJIT; file:write() only to compat=none
Diffstat (limited to 'compat53')
-rw-r--r--compat53/file_mt.lua71
-rw-r--r--compat53/init.lua62
-rw-r--r--compat53/module.lua66
3 files changed, 143 insertions, 56 deletions
diff --git a/compat53/file_mt.lua b/compat53/file_mt.lua
new file mode 100644
index 0000000..6433619
--- /dev/null
+++ b/compat53/file_mt.lua
@@ -0,0 +1,71 @@
1local lua_version = _VERSION:sub(-3)
2
3local M = {}
4
5local unpack = lua_version == "5.1" and unpack or table.unpack
6
7local function addasterisk(fmt)
8 if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then
9 return "*"..fmt
10 else
11 return fmt
12 end
13end
14
15function M.update_file_meta(file_meta, is_luajit52)
16
17 -- make '*' optional for file:read and file:lines
18
19 local file_lines = file_meta.__index.lines
20 file_meta.__index.lines = function(self, ...)
21 local n = select('#', ...)
22 for i = 1, n do
23 local a = select(i, ...)
24 local b = addasterisk(a)
25 -- as an optimization we only allocate a table for the
26 -- modified format arguments when we have a '*' somewhere
27 if a ~= b then
28 local args = { ... }
29 args[i] = b
30 for j = i+1, n do
31 args[j] = addasterisk(args[j])
32 end
33 return file_lines(self, unpack(args, 1, n))
34 end
35 end
36 return file_lines(self, ...)
37 end
38
39 local file_read = file_meta.__index.read
40 file_meta.__index.read = function(self, ...)
41 local n = select('#', ...)
42 for i = 1, n do
43 local a = select(i, ...)
44 local b = addasterisk(a)
45 -- as an optimization we only allocate a table for the
46 -- modified format arguments when we have a '*' somewhere
47 if a ~= b then
48 local args = { ... }
49 args[i] = b
50 for j = i+1, n do
51 args[j] = addasterisk(args[j])
52 end
53 return file_read(self, unpack(args, 1, n))
54 end
55 end
56 return file_read(self, ...)
57 end
58
59 if not is_luajit52 then
60 local file_write = file_meta.__index.write
61 file_meta.__index.write = function(self, ...)
62 local ret, err = file_write(self, ...)
63 if ret then
64 return self
65 end
66 return ret, err
67 end
68 end
69end
70
71return M
diff --git a/compat53/init.lua b/compat53/init.lua
index a7f0c80..b507571 100644
--- a/compat53/init.lua
+++ b/compat53/init.lua
@@ -17,57 +17,15 @@ if lua_version < "5.3" then
17 local file_meta = gmt(io.stdout) 17 local file_meta = gmt(io.stdout)
18 18
19 19
20 -- make '*' optional for file:read and file:lines 20 -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag)
21 if type(file_meta) == "table" and type(file_meta.__index) == "table" then 21 local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ"
22 22 local is_luajit52 = is_luajit and
23 local function addasterisk(fmt) 23 #setmetatable({}, { __len = function() return 1 end }) == 1
24 if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then
25 return "*"..fmt
26 else
27 return fmt
28 end
29 end
30
31 local file_lines = file_meta.__index.lines
32 file_meta.__index.lines = function(self, ...)
33 local n = select('#', ...)
34 for i = 1, n do
35 local a = select(i, ...)
36 local b = addasterisk(a)
37 -- as an optimization we only allocate a table for the
38 -- modified format arguments when we have a '*' somewhere
39 if a ~= b then
40 local args = { ... }
41 args[i] = b
42 for j = i+1, n do
43 args[j] = addasterisk(args[j])
44 end
45 return file_lines(self, unpack(args, 1, n))
46 end
47 end
48 return file_lines(self, ...)
49 end
50 24
51 local file_read = file_meta.__index.read
52 file_meta.__index.read = function(self, ...)
53 local n = select('#', ...)
54 for i = 1, n do
55 local a = select(i, ...)
56 local b = addasterisk(a)
57 -- as an optimization we only allocate a table for the
58 -- modified format arguments when we have a '*' somewhere
59 if a ~= b then
60 local args = { ... }
61 args[i] = b
62 for j = i+1, n do
63 args[j] = addasterisk(args[j])
64 end
65 return file_read(self, unpack(args, 1, n))
66 end
67 end
68 return file_read(self, ...)
69 end
70 25
26 if type(file_meta) == "table" and type(file_meta.__index) == "table" then
27 local file_mt = require("compat53.file_mt")
28 file_mt.update_file_meta(file_meta, is_luajit52)
71 end -- got a valid metatable for file objects 29 end -- got a valid metatable for file objects
72 30
73 31
@@ -85,12 +43,6 @@ if lua_version < "5.3" then
85 local io_type = io.type 43 local io_type = io.type
86 44
87 45
88 -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag)
89 local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ"
90 local is_luajit52 = is_luajit and
91 #setmetatable({}, { __len = function() return 1 end }) == 1
92
93
94 -- make package.searchers available as an alias for package.loaders 46 -- make package.searchers available as an alias for package.loaders
95 local p_index = { searchers = package.loaders } 47 local p_index = { searchers = package.loaders }
96 setmetatable(package, { 48 setmetatable(package, {
diff --git a/compat53/module.lua b/compat53/module.lua
index 67b2a4a..90b2f06 100644
--- a/compat53/module.lua
+++ b/compat53/module.lua
@@ -13,7 +13,11 @@ if lua_version < "5.3" then
13 debug, io, math, package, string, table 13 debug, io, math, package, string, table
14 local io_lines = io.lines 14 local io_lines = io.lines
15 local io_read = io.read 15 local io_read = io.read
16 local io_open = io.open
17 local io_popen = io.popen
18 local io_tmpfile = io.tmpfile
16 local unpack = lua_version == "5.1" and unpack or table.unpack 19 local unpack = lua_version == "5.1" and unpack or table.unpack
20 local debug_setmetatable = type(debug) == "table" and debug.setmetatable
17 21
18 -- create module table 22 -- create module table
19 M = {} 23 M = {}
@@ -451,7 +455,6 @@ if lua_version < "5.3" then
451 if type(debug) == "table" then 455 if type(debug) == "table" then
452 local debug_setfenv = debug.setfenv 456 local debug_setfenv = debug.setfenv
453 local debug_getfenv = debug.getfenv 457 local debug_getfenv = debug.getfenv
454 local debug_setmetatable = debug.setmetatable
455 458
456 M.debug = setmetatable({}, { __index = debug }) 459 M.debug = setmetatable({}, { __index = debug })
457 460
@@ -823,6 +826,67 @@ if lua_version < "5.3" then
823 end 826 end
824 end -- not luajit 827 end -- not luajit
825 828
829 if is_luajit then
830 local compat_file_meta = {}
831 local compat_file_meta_loaded = false
832
833 local function load_compat_file_meta(file_meta)
834 -- fill compat_file_meta with original entries
835 for k, v in pairs(file_meta) do
836 compat_file_meta[k] = v
837 end
838 compat_file_meta.__index = {}
839 for k, v in pairs(file_meta.__index) do
840 compat_file_meta.__index[k] = v
841 end
842
843 -- update it with compatibility functions
844 local file_mt = require("compat53.file_mt")
845 file_mt.update_file_meta(compat_file_meta, is_luajit52)
846
847 compat_file_meta_loaded = true
848 end
849
850 function M.io.open(...)
851 local fd, err = io_open(...)
852 if fd and debug_setmetatable then
853 if not compat_file_meta_loaded then
854 local file_meta = gmt(fd)
855 load_compat_file_meta(file_meta)
856 end
857 debug_setmetatable(fd, compat_file_meta)
858 end
859
860 return fd, err
861 end
862
863 function M.io.popen(...)
864 local fd, err = io_popen(...)
865 if fd and debug_setmetatable then
866 if not compat_file_meta_loaded then
867 local file_meta = gmt(fd)
868 load_compat_file_meta(file_meta)
869 end
870 debug_setmetatable(fd, compat_file_meta)
871 end
872
873 return fd, err
874 end
875
876 function M.io.tmpfile(...)
877 local fd, err = io_tmpfile(...)
878 if fd and debug_setmetatable then
879 if not compat_file_meta_loaded then
880 local file_meta = gmt(fd)
881 load_compat_file_meta(file_meta)
882 end
883 debug_setmetatable(fd, compat_file_meta)
884 end
885
886 return fd, err
887 end
888 end
889
826 end -- lua 5.1 890 end -- lua 5.1
827 891
828 -- further write should be forwarded to _G 892 -- further write should be forwarded to _G