diff options
| author | ruki <[email protected]> | 2024-04-17 22:50:06 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2024-04-17 22:50:06 +0800 |
| commit | 2190b08db954738da36feeb820e8771383caa5e0 (patch) | |
| tree | d0a1fd3d98c6c21dfbe2acdf0c5be1f46788d54f /xmake/core/base | |
| parent | e39ff9d876e33cc36e4eb9e196ca665ecefc9f96 (diff) | |
support logical expr for selecting script
Diffstat (limited to 'xmake/core/base')
| -rw-r--r-- | xmake/core/base/interpreter.lua | 2 | ||||
| -rw-r--r-- | xmake/core/base/private/select_script.lua | 39 |
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 {} |
