diff options
| author | ruki <[email protected]> | 2016-01-16 22:05:45 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-02-15 19:10:24 +0800 |
| commit | 0ad84316db1fee3d4010b31d12353eddf430eddc (patch) | |
| tree | 2da0aad2cc88d191da895c0edb9bc69847058a17 | |
| parent | c358344c4ae08ef99ba965d7a05a3f8d4a9a9a74 (diff) | |
impl sandbox traceback
| -rw-r--r-- | tests/sandbox/scope.lua | 9 | ||||
| -rw-r--r-- | tests/sandbox/tests.lua | 47 | ||||
| -rw-r--r-- | xmake/core/base/project.lua | 2 | ||||
| -rw-r--r-- | xmake/core/sandbox/sandbox.lua | 70 |
4 files changed, 127 insertions, 1 deletions
diff --git a/tests/sandbox/scope.lua b/tests/sandbox/scope.lua new file mode 100644 index 000000000..438470d5c --- /dev/null +++ b/tests/sandbox/scope.lua @@ -0,0 +1,9 @@ + +print("hello") + +function test() + assert(false) +end +test() + +print("hello") diff --git a/tests/sandbox/tests.lua b/tests/sandbox/tests.lua new file mode 100644 index 000000000..860df4cee --- /dev/null +++ b/tests/sandbox/tests.lua @@ -0,0 +1,47 @@ +--!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 <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file tests.lua +-- + +-- define module: tests +local tests = tests or {} + +-- load modules +local sandbox = require("sandbox/sandbox") + +-- the main function +function tests.main(self, file) + + -- check + assert(file and #file == 1) + + -- load it + local ok, errors = sandbox.load(file[1]) + if not ok then + print(errors) + return false + end + + -- ok + return true +end + +-- return module: tests +return tests diff --git a/xmake/core/base/project.lua b/xmake/core/base/project.lua index 9ea8a2fac..e5afc88dc 100644 --- a/xmake/core/base/project.lua +++ b/xmake/core/base/project.lua @@ -1161,7 +1161,7 @@ function project._load_targets(file) -- load the project script local script = loadfile(file) if not script then - return string.format("load %s failed!", file) + return nil, string.format("load %s failed!", file) end -- set the current project file directory diff --git a/xmake/core/sandbox/sandbox.lua b/xmake/core/sandbox/sandbox.lua index 1fd4468f9..1e534a928 100644 --- a/xmake/core/sandbox/sandbox.lua +++ b/xmake/core/sandbox/sandbox.lua @@ -27,5 +27,75 @@ local sandbox = sandbox or {} local os = require("base/os") local utils = require("base/utils") +-- traceback +function sandbox._traceback(errors) + + -- 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) + else + results = results .. string.format(" [%s:%d]:\n", info.short_src, info.currentline) + end + + -- next + level = level + 1 + end + + -- ok? + return results +end + +-- load sandbox +function sandbox.load(file) + + -- check + assert(file) + + -- load the script + local script = loadfile(file) + if not script then + return nil, string.format("load %s failed!", file) + end + + -- init the private scope + local private = {} + + -- bind the environment + local env = {_PRIVATE = private} +-- setfenv(script, env) + + -- done the script + local ok, errors = xpcall(script, sandbox._traceback) + if not ok then + return nil, errors + end + + -- get results + return nil +end + -- return module: sandbox return sandbox |
