-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
1,201 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,5 @@ config.sub | |
configure | ||
core | ||
lua*/src/*.a | ||
Prototypes.h | ||
config.h.in | ||
libeditorconfig.a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
compat53/init.lua |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,373 @@ | ||
local lua_version = _VERSION:sub(-3) | ||
|
||
|
||
if lua_version < "5.3" then | ||
|
||
local _G, pairs, require, select, type = | ||
_G, pairs, require, select, type | ||
local debug, io = debug, io | ||
local unpack = lua_version == "5.1" and unpack or table.unpack | ||
|
||
local M = require("compat53.module") | ||
|
||
-- select the most powerful getmetatable function available | ||
local gmt = type(debug) == "table" and debug.getmetatable or | ||
getmetatable or function() return false end | ||
-- metatable for file objects from Lua's standard io library | ||
local file_meta = gmt(io.stdout) | ||
|
||
|
||
-- make '*' optional for file:read and file:lines | ||
if type(file_meta) == "table" and type(file_meta.__index) == "table" then | ||
|
||
local function addasterisk(fmt) | ||
if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then | ||
return "*"..fmt | ||
else | ||
return fmt | ||
end | ||
end | ||
|
||
local file_lines = file_meta.__index.lines | ||
file_meta.__index.lines = function(self, ...) | ||
local n = select('#', ...) | ||
for i = 1, n do | ||
local a = select(i, ...) | ||
local b = addasterisk(a) | ||
-- as an optimization we only allocate a table for the | ||
-- modified format arguments when we have a '*' somewhere | ||
if a ~= b then | ||
local args = { ... } | ||
args[i] = b | ||
for j = i+1, n do | ||
args[j] = addasterisk(args[j]) | ||
end | ||
return file_lines(self, unpack(args, 1, n)) | ||
end | ||
end | ||
return file_lines(self, ...) | ||
end | ||
|
||
local file_read = file_meta.__index.read | ||
file_meta.__index.read = function(self, ...) | ||
local n = select('#', ...) | ||
for i = 1, n do | ||
local a = select(i, ...) | ||
local b = addasterisk(a) | ||
-- as an optimization we only allocate a table for the | ||
-- modified format arguments when we have a '*' somewhere | ||
if a ~= b then | ||
local args = { ... } | ||
args[i] = b | ||
for j = i+1, n do | ||
args[j] = addasterisk(args[j]) | ||
end | ||
return file_read(self, unpack(args, 1, n)) | ||
end | ||
end | ||
return file_read(self, ...) | ||
end | ||
|
||
end -- got a valid metatable for file objects | ||
|
||
|
||
-- changes for Lua 5.1 only | ||
if lua_version == "5.1" then | ||
|
||
-- cache globals | ||
local error, pcall, rawset, setmetatable, tostring, xpcall = | ||
error, pcall, rawset, setmetatable, tostring, xpcall | ||
local coroutine, package, string = coroutine, package, string | ||
local coroutine_resume = coroutine.resume | ||
local coroutine_running = coroutine.running | ||
local coroutine_status = coroutine.status | ||
local coroutine_yield = coroutine.yield | ||
local io_type = io.type | ||
|
||
|
||
-- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) | ||
local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" | ||
local is_luajit52 = is_luajit and | ||
#setmetatable({}, { __len = function() return 1 end }) == 1 | ||
|
||
|
||
-- make package.searchers available as an alias for package.loaders | ||
local p_index = { searchers = package.loaders } | ||
setmetatable(package, { | ||
__index = p_index, | ||
__newindex = function(p, k, v) | ||
if k == "searchers" then | ||
rawset(p, "loaders", v) | ||
p_index.searchers = v | ||
else | ||
rawset(p, k, v) | ||
end | ||
end | ||
}) | ||
|
||
|
||
if type(file_meta) == "table" and type(file_meta.__index) == "table" then | ||
if not is_luajit then | ||
local function helper(_, var_1, ...) | ||
if var_1 == nil then | ||
if (...) ~= nil then | ||
error((...), 2) | ||
end | ||
end | ||
return var_1, ... | ||
end | ||
|
||
local function lines_iterator(st) | ||
return helper(st, st.f:read(unpack(st, 1, st.n))) | ||
end | ||
|
||
local file_write = file_meta.__index.write | ||
file_meta.__index.write = function(self, ...) | ||
local res, msg, errno = file_write(self, ...) | ||
if res then | ||
return self | ||
else | ||
return nil, msg, errno | ||
end | ||
end | ||
|
||
file_meta.__index.lines = function(self, ...) | ||
if io_type(self) == "closed file" then | ||
error("attempt to use a closed file", 2) | ||
end | ||
local st = { f=self, n=select('#', ...), ... } | ||
for i = 1, st.n do | ||
local t = type(st[i]) | ||
if t == "string" then | ||
local fmt = st[i]:match("^*?([aln])") | ||
if not fmt then | ||
error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) | ||
end | ||
st[i] = "*"..fmt | ||
elseif t ~= "number" then | ||
error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) | ||
end | ||
end | ||
return lines_iterator, st | ||
end | ||
end -- not luajit | ||
end -- file_meta valid | ||
|
||
|
||
-- the (x)pcall implementations start a new coroutine internally | ||
-- to allow yielding even in Lua 5.1. to allow for accurate | ||
-- stack traces we keep track of the nested coroutine activations | ||
-- in the weak tables below: | ||
local weak_meta = { __mode = "kv" } | ||
-- maps the internal pcall coroutines to the user coroutine that | ||
-- *should* be running if pcall didn't use coroutines internally | ||
local pcall_mainOf = setmetatable({}, weak_meta) | ||
-- table that maps each running coroutine started by pcall to | ||
-- the coroutine that resumed it (user coroutine *or* pcall | ||
-- coroutine!) | ||
local pcall_previous = setmetatable({}, weak_meta) | ||
-- reverse of `pcall_mainOf`. maps a user coroutine to the | ||
-- currently active pcall coroutine started within it | ||
local pcall_callOf = setmetatable({}, weak_meta) | ||
-- similar to `pcall_mainOf` but is used only while executing | ||
-- the error handler of xpcall (thus no nesting is necessary!) | ||
local xpcall_running = setmetatable({}, weak_meta) | ||
|
||
-- handle debug functions | ||
if type(debug) == "table" then | ||
local debug_getinfo = debug.getinfo | ||
local debug_traceback = debug.traceback | ||
|
||
if not is_luajit then | ||
local function calculate_trace_level(co, level) | ||
if level ~= nil then | ||
for out = 1, 1/0 do | ||
local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "") | ||
if info == nil then | ||
local max = out-1 | ||
if level <= max then | ||
return level | ||
end | ||
return nil, level-max | ||
end | ||
end | ||
end | ||
return 1 | ||
end | ||
|
||
local stack_pattern = "\nstack traceback:" | ||
local stack_replace = "" | ||
function debug.traceback(co, msg, level) | ||
local lvl | ||
local nilmsg | ||
if type(co) ~= "thread" then | ||
co, msg, level = coroutine_running(), co, msg | ||
end | ||
if msg == nil then | ||
msg = "" | ||
nilmsg = true | ||
elseif type(msg) ~= "string" then | ||
return msg | ||
end | ||
if co == nil then | ||
msg = debug_traceback(msg, level or 1) | ||
else | ||
local xpco = xpcall_running[co] | ||
if xpco ~= nil then | ||
lvl, level = calculate_trace_level(xpco, level) | ||
if lvl then | ||
msg = debug_traceback(xpco, msg, lvl) | ||
else | ||
msg = msg..stack_pattern | ||
end | ||
lvl, level = calculate_trace_level(co, level) | ||
if lvl then | ||
local trace = debug_traceback(co, "", lvl) | ||
msg = msg..trace:gsub(stack_pattern, stack_replace) | ||
end | ||
else | ||
co = pcall_callOf[co] or co | ||
lvl, level = calculate_trace_level(co, level) | ||
if lvl then | ||
msg = debug_traceback(co, msg, lvl) | ||
else | ||
msg = msg..stack_pattern | ||
end | ||
end | ||
co = pcall_previous[co] | ||
while co ~= nil do | ||
lvl, level = calculate_trace_level(co, level) | ||
if lvl then | ||
local trace = debug_traceback(co, "", lvl) | ||
msg = msg..trace:gsub(stack_pattern, stack_replace) | ||
end | ||
co = pcall_previous[co] | ||
end | ||
end | ||
if nilmsg then | ||
msg = msg:gsub("^\n", "") | ||
end | ||
msg = msg:gsub("\n\t%(tail call%): %?", "\000") | ||
msg = msg:gsub("\n\t%.%.%.\n", "\001\n") | ||
msg = msg:gsub("\n\t%.%.%.$", "\001") | ||
msg = msg:gsub("(%z+)\001(%z+)", function(some, other) | ||
return "\n\t(..."..#some+#other.."+ tail call(s)...)" | ||
end) | ||
msg = msg:gsub("\001(%z+)", function(zeros) | ||
return "\n\t(..."..#zeros.."+ tail call(s)...)" | ||
end) | ||
msg = msg:gsub("(%z+)\001", function(zeros) | ||
return "\n\t(..."..#zeros.."+ tail call(s)...)" | ||
end) | ||
msg = msg:gsub("%z+", function(zeros) | ||
return "\n\t(..."..#zeros.." tail call(s)...)" | ||
end) | ||
msg = msg:gsub("\001", function() | ||
return "\n\t..." | ||
end) | ||
return msg | ||
end | ||
end -- is not luajit | ||
end -- debug table available | ||
|
||
|
||
if not is_luajit52 then | ||
local coroutine_running52 = M.coroutine.running | ||
function M.coroutine.running() | ||
local co, ismain = coroutine_running52() | ||
if ismain then | ||
return co, true | ||
else | ||
return pcall_mainOf[co] or co, false | ||
end | ||
end | ||
end | ||
|
||
if not is_luajit then | ||
local function pcall_results(current, call, success, ...) | ||
if coroutine_status(call) == "suspended" then | ||
return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...))) | ||
end | ||
if pcall_previous then | ||
pcall_previous[call] = nil | ||
local main = pcall_mainOf[call] | ||
if main == current then current = nil end | ||
pcall_callOf[main] = current | ||
end | ||
pcall_mainOf[call] = nil | ||
return success, ... | ||
end | ||
|
||
local function pcall_exec(current, call, ...) | ||
local main = pcall_mainOf[current] or current | ||
pcall_mainOf[call] = main | ||
if pcall_previous then | ||
pcall_previous[call] = current | ||
pcall_callOf[main] = call | ||
end | ||
return pcall_results(current, call, coroutine_resume(call, ...)) | ||
end | ||
|
||
local coroutine_create52 = M.coroutine.create | ||
|
||
local function pcall_coroutine(func) | ||
if type(func) ~= "function" then | ||
local callable = func | ||
func = function (...) return callable(...) end | ||
end | ||
return coroutine_create52(func) | ||
end | ||
|
||
function M.pcall(func, ...) | ||
local current = coroutine_running() | ||
if not current then return pcall(func, ...) end | ||
return pcall_exec(current, pcall_coroutine(func), ...) | ||
end | ||
|
||
local function xpcall_catch(current, call, msgh, success, ...) | ||
if not success then | ||
xpcall_running[current] = call | ||
local ok, result = pcall(msgh, ...) | ||
xpcall_running[current] = nil | ||
if not ok then | ||
return false, "error in error handling ("..tostring(result)..")" | ||
end | ||
return false, result | ||
end | ||
return true, ... | ||
end | ||
|
||
function M.xpcall(f, msgh, ...) | ||
local current = coroutine_running() | ||
if not current then | ||
local args, n = { ... }, select('#', ...) | ||
return xpcall(function() return f(unpack(args, 1, n)) end, msgh) | ||
end | ||
local call = pcall_coroutine(f) | ||
return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...)) | ||
end | ||
end -- not luajit | ||
|
||
end -- lua 5.1 | ||
|
||
|
||
-- handle exporting to global scope | ||
local function extend_table(from, to) | ||
if from ~= to then | ||
for k,v in pairs(from) do | ||
if type(v) == "table" and | ||
type(to[k]) == "table" and | ||
v ~= to[k] then | ||
extend_table(v, to[k]) | ||
else | ||
to[k] = v | ||
end | ||
end | ||
end | ||
end | ||
|
||
extend_table(M, _G) | ||
|
||
end -- lua < 5.3 | ||
|
||
-- vi: set expandtab softtabstop=3 shiftwidth=3 : |
Oops, something went wrong.