summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2016-01-28 19:00:21 +0800
committerruki <[email protected]>2016-02-15 19:10:26 +0800
commit780a88f1b2e7cb90be32cd20216bd94460824c20 (patch)
treef0d9f8b6189b6cbbc9bffc91eaddf74052387482
parent7639a57c700146b1d70f3b19c395956312e25fd7 (diff)
check xmake.lua syntax errors
-rw-r--r--tests/interpreter/scope.lua2
-rw-r--r--xmake/core/base/interpreter.lua36
-rw-r--r--xmake/core/base/sandbox.lua137
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