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 | |
| parent | e39ff9d876e33cc36e4eb9e196ca665ecefc9f96 (diff) | |
support logical expr for selecting script
| -rw-r--r-- | tests/modules/private/select_script/test.lua | 11 | ||||
| -rw-r--r-- | xmake/core/base/interpreter.lua | 2 | ||||
| -rw-r--r-- | xmake/core/base/private/select_script.lua | 39 |
3 files changed, 47 insertions, 5 deletions
diff --git a/tests/modules/private/select_script/test.lua b/tests/modules/private/select_script/test.lua index 90258c232..50ff3acee 100644 --- a/tests/modules/private/select_script/test.lua +++ b/tests/modules/private/select_script/test.lua @@ -3,7 +3,7 @@ import("private.core.base.select_script") function _match_patterns(patterns, opt) local scripts = {} for _, pattern in ipairs(patterns) do - pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") + pattern = pattern:gsub("([%+%.%-%^%$%%])", "%%%1") pattern = pattern:gsub("%*", "\001") pattern = pattern:gsub("\001", ".*") scripts[pattern] = true @@ -28,6 +28,8 @@ function test_plat_only(t) end function test_plat_arch(t) + t:require(_match_patterns("!wasm|!arm*", {plat = "linux", arch = "x86_64"})) + t:require_not(_match_patterns("!wasm|!arm*", {plat = "linux", arch = "arm64"})) t:require(_match_patterns("*|x86_64", {plat = "macosx", arch = "x86_64"})) t:require(_match_patterns("macosx|x86_64", {plat = "macosx", arch = "x86_64"})) t:require(_match_patterns("macosx|x86_64,linux|x86_64", {plat = "macosx", arch = "x86_64"})) @@ -119,3 +121,10 @@ function test_plat_arch_subhost_subarch(t) t:require_not(_match_patterns("iphon*|arm64@macosx|x86_64", {plat = "iphoneos", subhost = "linux", arch = "arm64", subarch = "x86_64"})) t:require(_match_patterns("android|native@macosx|x86_64", {plat = "android", subhost = "macosx", arch = "x86_64", subarch = "x86_64"})) end + +function test_logical_expr(t) + t:require(_match_patterns("!wasm|!arm* and !cross|!arm*", {plat = "linux", arch = "x86_64"})) + t:require_not(_match_patterns("!wasm|!arm* and !cross|!arm*", {plat = "linux", arch = "arm64"})) + t:require_not(_match_patterns("!wasm|!arm* and !cross|!arm*", {plat = "wasm", arch = "x86_64"})) +end + 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 {} |
