summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2023-02-01 23:19:19 +0800
committerruki <[email protected]>2023-02-01 23:19:19 +0800
commit8d09077f31b043b1d94494f42f6ae2a3109535ea (patch)
treea3167de651aa3a52976e7748d72eaca45a14171a
parent8658eae245dafc3b539c6b4280455773caa0ef8a (diff)
add probable value
-rw-r--r--xmake/core/base/string.lua37
-rw-r--r--xmake/plugins/check/checkers/api/api_checker.lua20
2 files changed, 56 insertions, 1 deletions
diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua
index 43b0096b4..625678c6c 100644
--- a/xmake/core/base/string.lua
+++ b/xmake/core/base/string.lua
@@ -379,5 +379,42 @@ function string:wcswidth(idx)
return width
end
+-- compute the Levenshtein distance between two strings
+function string:levenshtein(str2)
+ local str1 = self
+ local len1 = #str1
+ local len2 = #str2
+ local matrix = {}
+ local cost = 0
+
+ if len1 == 0 then
+ return len2
+ elseif len2 == 0 then
+ return len1
+ elseif str1 == str2 then
+ return 0
+ end
+
+ for i = 0, len1, 1 do
+ matrix[i] = {}
+ matrix[i][0] = i
+ end
+ for j = 0, len2, 1 do
+ matrix[0][j] = j
+ end
+
+ for i = 1, len1, 1 do
+ for j = 1, len2, 1 do
+ if (str1:byte(i) == str2:byte(j)) then
+ cost = 0
+ else
+ cost = 1
+ end
+ matrix[i][j] = math.min(matrix[i-1][j] + 1, matrix[i][j-1] + 1, matrix[i-1][j-1] + cost)
+ end
+ end
+ return matrix[len1][len2]
+end
+
-- return module: string
return string
diff --git a/xmake/plugins/check/checkers/api/api_checker.lua b/xmake/plugins/check/checkers/api/api_checker.lua
index e71a28b24..ba7e81255 100644
--- a/xmake/plugins/check/checkers/api/api_checker.lua
+++ b/xmake/plugins/check/checkers/api/api_checker.lua
@@ -24,6 +24,20 @@ import("core.base.hashset")
import("core.project.project")
import("..checker")
+-- get the most probable value
+function _get_most_probable_value(value, valueset)
+ local result
+ local mindist
+ for v in valueset:keys() do
+ local dist = value:levenshtein(v)
+ if not mindist or dist < mindist then
+ mindist = dist
+ result = v
+ end
+ end
+ return result
+end
+
-- show result
function _show(apiname, value, target, opt)
opt = opt or {}
@@ -57,6 +71,10 @@ function _show(apiname, value, target, opt)
_g.showed = _g.showed or {}
local showed = _g.showed
local infostr = string.format("%s%s: unknown %s value '%s'", sourcetips, level_tips, apiname, value)
+ local probable_value = _get_most_probable_value(value, opt.valueset)
+ if probable_value then
+ infostr = string.format("%s, it may be '%s'", infostr, probable_value)
+ end
if not showed[infostr] then
cprint(infostr)
showed[infostr] = true
@@ -73,7 +91,7 @@ function check_targets(apiname, opt)
local values = target:get(apiname)
for _, value in ipairs(values) do
if not valueset:has(value) then
- local reported = _show(apiname, value, target, {level = level})
+ local reported = _show(apiname, value, target, {valueset = valueset, level = level})
if reported then
checker.update_stats(level)
end