Skip to content

Commit a6602cd

Browse files
committed
Feature: Use vim builtin json functions
1 parent e0bd683 commit a6602cd

1 file changed

Lines changed: 53 additions & 70 deletions

File tree

lua/cmake-tools/scanner.lua

Lines changed: 53 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,7 @@
1-
local const = require("cmake-tools.const")
21
local scanner = {}
3-
-- Configuration
4-
scanner.KITS_FILE = const.cmake_kits_path
52

63
--Helper functions
7-
-- Simple JSON encoder
8-
function scanner.json_encode(obj, indent)
9-
indent = indent or 0
10-
local spaces = string.rep(" ", indent)
11-
12-
if type(obj) == "table" then
13-
local is_array = #obj > 0
14-
local result = "{\n"
15-
local first = true
16-
17-
for k, v in pairs(obj) do
18-
if not first then
19-
result = result .. ",\n"
20-
end
21-
first = false
22-
23-
if is_array then
24-
result = result .. spaces .. " " .. scanner.json_encode(v, indent + 1)
25-
else
26-
result = result .. spaces .. ' "' .. k .. '": ' .. scanner.json_encode(v, indent + 1)
27-
end
28-
end
29-
30-
return result .. "\n" .. spaces .. "}"
31-
elseif type(obj) == "string" then
32-
return '"' .. obj:gsub("\\", "\\\\"):gsub('"', '\\"') .. '"'
33-
elseif type(obj) == "number" or type(obj) == "boolean" then
34-
return tostring(obj)
35-
elseif obj == nil then
36-
return "null"
37-
end
38-
end
39-
40-
function scanner.execute_command(cmd)
4+
local function execute_command(cmd)
415
local handle = io.popen(cmd .. " 2>&1")
426
if handle == nil then
437
return false, -1, ""
@@ -46,15 +10,18 @@ function scanner.execute_command(cmd)
4610
if result == nil then
4711
result = ""
4812
end
49-
local success, exit_type, exit_code = handle:close()
50-
-- io.popen's close() returns: true on success, or nil, "exit", code on failure
13+
local success, exit_code = handle:close()
5114
if success == nil then
5215
return false, exit_code or -1, result
5316
end
5417
return true, 0, result
5518
end
5619

57-
function scanner.file_exists(path)
20+
local function file_exists(path)
21+
if path == nil then
22+
vim.notify("Path is empty", vim.log.levels.ERROR)
23+
return
24+
end
5825
local file = io.open(path, "r")
5926
if file then
6027
file:close()
@@ -64,7 +31,7 @@ function scanner.file_exists(path)
6431
end
6532
end
6633

67-
function scanner.split_path(path_env)
34+
local function split_path(path_env)
6835
local paths = {}
6936
local sep = package.config:sub(1, 1) == "\\" and ";" or ":"
7037
for path in string.gmatch(path_env, "([^" .. sep .. "]+)") do
@@ -73,8 +40,8 @@ function scanner.split_path(path_env)
7340
return paths
7441
end
7542

76-
function scanner.get_gcc_version(gcc_path)
77-
local success, exit_code, output = scanner.execute_command('"' .. gcc_path .. '" --version')
43+
local function get_gcc_version(gcc_path)
44+
local success, exit_code, output = execute_command('"' .. gcc_path .. '" --version')
7845
if output == nil then
7946
return nil
8047
end
@@ -84,16 +51,16 @@ function scanner.get_gcc_version(gcc_path)
8451
return version
8552
end
8653

87-
function scanner.get_clang_version(clang_path)
88-
local success, exit_code, output = scanner.execute_command('"' .. clang_path .. '" --version ')
54+
local function get_clang_version(clang_path)
55+
local success, exit_code, output = execute_command('"' .. clang_path .. '" --version ')
8956
if output == nil then
9057
return nil
9158
end
9259
local version_line = output:match("clang version ([%d%.]+)")
9360
return version_line
9461
end
9562

96-
function scanner.find_compiler_pair(dir, c_compiler)
63+
local function find_compiler_pair(dir, c_compiler)
9764
local base_name = c_compiler:match("([^/\\]+)$")
9865
local cxx_name
9966
if base_name:match("gcc") then
@@ -104,69 +71,77 @@ function scanner.find_compiler_pair(dir, c_compiler)
10471
return nil
10572
end
10673
local cxx_path = dir .. "/" .. cxx_name
107-
if scanner.file_exists(cxx_path) then
74+
if file_exists(cxx_path) then
10875
return cxx_path
10976
end
11077
return nil
11178
end
11279

113-
function scanner.find_linker_pair(dir, linker_name)
80+
local function find_linker_pair(dir, linker_name)
11481
if not linker_name then
11582
return nil
11683
end
11784
local linker_path = dir .. "/" .. linker_name
118-
if scanner.file_exists(linker_path) then
85+
if file_exists(linker_path) then
11986
return linker_path
12087
end
12188
return nil
12289
end
12390

124-
function scanner.get_toolchain_file()
91+
local function get_toolchain_file()
12592
local toolchainFile = os.getenv("CMAKE_TOOLCHAIN_FILE")
126-
if toolchainFile and scanner.file_exists(toolchainFile) then
93+
if toolchainFile and file_exists(toolchainFile) then
12794
return toolchainFile
12895
end
12996
return nil
13097
end
13198

132-
function scanner.ensure_directory(path)
99+
local function ensure_directory(path)
100+
if not path then
101+
vim.notify("Path is empty", vim.log.levels.ERROR)
102+
return
103+
end
133104
local pattern = "(.*/)"
134105
local dir = path:match(pattern)
135106
if dir then
136107
vim.fn.mkdir(dir, "p")
137108
end
138109
end
139110

140-
function scanner.save_kits(kits, filepath)
141-
scanner.ensure_directory(filepath)
111+
local function save_kits(kits, filepath)
112+
ensure_directory(filepath)
142113
local file = io.open(filepath, "w")
143114
if not file then
144-
error("Failed to open file for writing: " .. filepath)
115+
vim.notify("Failed to open file for writing: " .. filepath, vim.log.levels.ERROR)
116+
return false
117+
end
118+
if not kits then
119+
vim.notify("Can not encode data to json because it is nil", vim.log.levels.ERROR)
145120
return false
146121
end
147-
local json_content = scanner.json_encode(kits)
122+
local json_content = vim.json.encode(kits)
148123
file:write(json_content)
149124
file:close()
150125
return true
151126
end
152127

153-
-- Main fucntion to scan for kits
128+
-- Main function to scan for kits
154129
function scanner.scan_for_kits()
155130
local kits = {}
156-
131+
local const = require("cmake-tools.const")
157132
local path_env = os.getenv("PATH") or ""
158-
local paths = scanner.split_path(path_env)
133+
local paths = split_path(path_env)
159134

160135
for _, dir in ipairs(paths) do
161-
local linker_path = scanner.find_linker_pair(dir, "lld")
136+
local linker_path = find_linker_pair(dir, "lld")
162137
if linker_path == nil then
163-
linker_path = scanner.find_linker_pair(dir, "ld")
138+
linker_path = find_linker_pair(dir, "ld")
164139
end
165-
local toolchainFile = scanner.get_toolchain_file()
140+
local toolchainFile = get_toolchain_file()
166141
local gcc_path = dir .. "/gcc"
167-
if scanner.file_exists(gcc_path) then
168-
local gcc_version = scanner.get_gcc_version(gcc_path)
169-
local gxx_path = scanner.find_compiler_pair(dir, gcc_path)
142+
if file_exists(gcc_path) then
143+
local gcc_version = get_gcc_version(gcc_path)
144+
local gxx_path = find_compiler_pair(dir, gcc_path)
170145
if gxx_path then
171146
local kit = {
172147
name = "GCC-" .. (gcc_version or "unknown"),
@@ -182,9 +157,9 @@ function scanner.scan_for_kits()
182157
end
183158

184159
local clang_path = dir .. "/clang"
185-
if scanner.file_exists(clang_path) then
186-
local clang_version = scanner.get_clang_version(clang_path)
187-
local clangxx_path = scanner.find_compiler_pair(dir, clang_path)
160+
if file_exists(clang_path) then
161+
local clang_version = get_clang_version(clang_path)
162+
local clangxx_path = find_compiler_pair(dir, clang_path)
188163
if clangxx_path then
189164
local kit = {
190165
name = "Clang-" .. (clang_version or "unknown"),
@@ -201,10 +176,18 @@ function scanner.scan_for_kits()
201176
end
202177

203178
if #kits == 0 then
204-
print("No compilers found in PATH.")
179+
vim.notify("No compilers found in PATH.", vim.log.levels.WARN)
180+
return {}
181+
end
182+
vim.notify("Found kits", vim.log.levels.INFO)
183+
if const.cmake_kits_path == nil then
184+
vim.notify(
185+
"local const variable is nil, it seems that the required module could not be loaded",
186+
vim.log.levels.ERROR
187+
)
205188
return {}
206189
end
207-
scanner.save_kits(kits, scanner.KITS_FILE)
190+
save_kits(kits, const.cmake_kits_path)
208191
return kits
209192
end
210193

0 commit comments

Comments
 (0)