diff options
| author | ruki <[email protected]> | 2016-01-28 19:00:21 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-02-15 19:10:26 +0800 |
| commit | 780a88f1b2e7cb90be32cd20216bd94460824c20 (patch) | |
| tree | f0d9f8b6189b6cbbc9bffc91eaddf74052387482 | |
| parent | 7639a57c700146b1d70f3b19c395956312e25fd7 (diff) | |
check xmake.lua syntax errors
| -rw-r--r-- | tests/interpreter/scope.lua | 2 | ||||
| -rw-r--r-- | xmake/core/base/interpreter.lua | 36 | ||||
| -rw-r--r-- | xmake/core/base/sandbox.lua | 137 |
3 files changed, 171 insertions, 4 deletions
diff --git a/tests/interpreter/scope.lua b/tests/interpreter/scope.lua index 2893dfeaf..150f51374 100644 --- a/tests/interpreter/scope.lua +++ b/tests/interpreter/scope.lua @@ -1,5 +1,5 @@ -set_kind("static") +set_kind("static" add_files("root.c") add_target("target1") diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index acca229dd..eae94ee9c 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -29,6 +29,7 @@ local path = require("base/path") local table = require("base/table") local utils = require("base/utils") local string = require("base/string") +local sandbox = require("base/sandbox") -- traceback function interpreter._traceback(errors) @@ -216,7 +217,7 @@ function interpreter._api_builtin_add_subdirfiles(self, isdirs, ...) self._PRIVATE._CURFILE = file -- load the file script - local script = loadfile(file) + local script, errors = loadfile(file) if script then -- bind public scope @@ -231,6 +232,9 @@ function interpreter._api_builtin_add_subdirfiles(self, isdirs, ...) -- get mtime of the file self._PRIVATE._MTIMES[path.relative(file, self._PRIVATE._ROOTDIR)] = os.mtime(file) + else + utils.error(errors) + utils.abort() end end end @@ -460,9 +464,9 @@ function interpreter.load(self, file, scope_kind, remove_repeat, enable_filter) assert(self and self._PUBLIC and self._PRIVATE and file) -- load the script - local script = loadfile(file) + local script, errors = loadfile(file) if not script then - return nil, string.format("load %s failed!", file) + return nil, errors end -- clear first @@ -762,6 +766,32 @@ function interpreter.api_register_add_array(self, scope_kind, prefix, ...) self:_api_register_xxx_values(scope_kind, "add", prefix, implementation, ...) end +-- register api for set_script +function interpreter.api_register_set_script(self, scope_kind, prefix, ...) + + -- check + assert(self) + + -- define implementation + local implementation = function (self, scope, name, script) + + -- bind sandbox to script + local ok, errors = sandbox.init():bind(script) + if not ok then + utils.error("set_%s(\"%s\"): %s", scope, name, errors) + utils.abort() + end + + -- update script? + scope[name] = {} + table.insert(scope[name], script) + + end + + -- register implementation + self:_api_register_xxx_values(scope_kind, "set", prefix, implementation, ...) +end + -- register api for set_keyvalues function interpreter.api_register_set_keyvalues(self, scope_kind, prefix, ...) diff --git a/xmake/core/base/sandbox.lua b/xmake/core/base/sandbox.lua new file mode 100644 index 000000000..b6d9f29a3 --- /dev/null +++ b/xmake/core/base/sandbox.lua @@ -0,0 +1,137 @@ +--!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 sandbox.lua +-- + +-- define module: sandbox +local sandbox = sandbox or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local table = require("base/table") +local utils = require("base/utils") +local string = require("base/string") + +-- 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) + break + else + results = results .. string.format(" [%s:%d]:\n", info.short_src, info.currentline) + end + + -- next + level = level + 1 + end + + -- ok? + return results +end + +-- init sandbox +function sandbox.init() + + -- init an sandbox instance + local box = { _PUBLIC = {} + , _PRIVATE = {}} + + -- inherit the interfaces of sandbox + for k, v in pairs(sandbox) do + if type(v) == "function" then + box[k] = v + end + end + + -- ok? + return box +end + +-- bind sandbox to script +function sandbox.bind(self, script) + + -- check + assert(self and self._PUBLIC) + + -- this script is file? load it first + if type(script) == "string" and os.isfile(script) then + + -- load it + local filescript, errors = loadfile(script) + if filescript then + + -- bind public scope + setfenv(filescript, self._PUBLIC) + + -- get main script + script = filescript() + if type(script) == "table" and script.main then + script = script.main + end + else + return false, errors + end + end + + -- no script? + if script == nil then + return false, "no script!" + end + + -- invalid script? + if script ~= nil and type(script) ~= "function" then + return false, "invalid script!" + end + + -- bind public scope + setfenv(script, self._PUBLIC) + + -- ok + return true +end + +-- return module: sandbox +return sandbox |
