summaryrefslogtreecommitdiff
path: root/xmake/core/base
diff options
context:
space:
mode:
authorruki <[email protected]>2024-04-17 22:50:06 +0800
committerruki <[email protected]>2024-04-17 22:50:06 +0800
commit2190b08db954738da36feeb820e8771383caa5e0 (patch)
treed0a1fd3d98c6c21dfbe2acdf0c5be1f46788d54f /xmake/core/base
parente39ff9d876e33cc36e4eb9e196ca665ecefc9f96 (diff)
support logical expr for selecting script
Diffstat (limited to 'xmake/core/base')
-rw-r--r--xmake/core/base/interpreter.lua2
-rw-r--r--xmake/core/base/private/select_script.lua39
2 files changed, 37 insertions, 4 deletions
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index e1cd08a78..1c85d870e 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -323,7 +323,7 @@ function interpreter:_api_register_xxx_script(scope_kind, action, ...)
assert(type(pattern) == "string")
-- convert pattern to a lua pattern ('*' => '.*')
- pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1")
+ pattern = pattern:gsub("([%+%.%-%^%$%%])", "%%%1")
pattern = pattern:gsub("%*", "\001")
pattern = pattern:gsub("\001", ".*")
diff --git a/xmake/core/base/private/select_script.lua b/xmake/core/base/private/select_script.lua
index 23c8b55b6..243e41a60 100644
--- a/xmake/core/base/private/select_script.lua
+++ b/xmake/core/base/private/select_script.lua
@@ -19,8 +19,9 @@
--
-- load modules
-local table = require("base/table")
-local utils = require("base/utils")
+local table = require("base/table")
+local utils = require("base/utils")
+local hashset = require("base/hashset")
-- match pattern, matched mode: plat|arch, excluded mode: !plat|arch
function _match_pattern(pattern, plat, arch, opt)
@@ -124,7 +125,7 @@ end
-- `!android|armeabi-v7a@!linux|!x86_64`
-- `!linux|*`
--
-function _match_script(pattern, opt)
+function _match_script_pattern(pattern, opt)
opt = opt or {}
local splitinfo = pattern:split("@", {strict = true, plain = true})
local plat_part = splitinfo[1]
@@ -156,6 +157,38 @@ function _match_script(pattern, opt)
end
end
+-- match the script expression pattern
+function _match_script(pattern, opt)
+ local idx = 0
+ local funcs = {}
+ local keywords = hashset.of("and", "or")
+ local has_logical_op = false
+ local pattern_expr = pattern:gsub("[^%(%)%s]+", function (w)
+ if keywords:has(w) then
+ has_logical_op = true
+ return
+ end
+ local name = "func_" .. idx
+ local func = function ()
+ return _match_script_pattern(w, opt)
+ end
+ funcs[name] = func
+ idx = idx + 1
+ return name .. "()"
+ end)
+ if has_logical_op then
+ local script = assert(load("return (" .. pattern_expr .. ")"), "invalid pattern: " .. pattern)
+ setfenv(script, funcs)
+ local ok, results = utils.trycall(script)
+ if not ok then
+ os.raise("invalid pattern: %s, error: %s", pattern, results or "unknown")
+ end
+ return results
+ else
+ return _match_script_pattern(pattern, opt)
+ end
+end
+
-- select the matched pattern script for the current platform/architecture
function select_script(scripts, opt)
opt = opt or {}