--!The Automatic Cross-platform Build Tool -- -- XMake is free software; you can redistribute it and/or modify -- it under the terms of the GNU Lesser General Public License as published by -- the Free Software Foundation; either version 2.1 of the License, or -- (at your option) any later version. -- -- XMake is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public License -- along with XMake; -- If not, see http://www.gnu.org/licenses/ -- -- Copyright (C) 2015 - 2016, ruki All rights reserved. -- -- @author ruki -- @file try.lua -- -- load modules local utils = require("base/utils") local table = require("base/table") local string = require("base/string") local option = require("base/option") -- define module local sandbox_try = sandbox_try or {} -- traceback function sandbox_try._traceback(errors) -- not verbose? if not option.get("verbose") then if errors then -- remove the prefix info local _, pos = errors:find(":%d+: ") if pos then return errors:sub(pos + 1) end end return errors end -- init results local results = "" if errors then results = errors .. "\n" end results = results .. "stack traceback:\n" -- make results local level = 2 while true do -- get debug info local info = debug.getinfo(level, "Sln") -- end? if not info or (info.name and info.name == "xpcall") then break end -- function? if info.what == "C" then results = results .. string.format(" [C]: in function '%s'\n", info.name) elseif info.name then results = results .. string.format(" [%s:%d]: in function '%s'\n", info.short_src, info.currentline, info.name) elseif info.what == "main" then results = results .. string.format(" [%s:%d]: in main chunk\n", info.short_src, info.currentline) break else results = results .. string.format(" [%s:%d]:\n", info.short_src, info.currentline) end -- next level = level + 1 end -- ok? return results end -- try function sandbox_try.try(block) -- get the try function local try = block[1] assert(try) -- get catch and finally functions local funcs = block[2] if funcs and block[3] then table.join2(funcs, block[2]) end -- try to call it local ok, errors = xpcall(try, sandbox_try._traceback) if not ok then -- run the catch function if funcs and funcs.catch then funcs.catch(errors) end end -- run the finally function if funcs and funcs.finally then funcs.finally(utils.ifelse(ok, errors, nil)) end -- ok? return utils.ifelse(ok, errors, nil) end -- return module return sandbox_try.try