-- Common functions used by different modules of the static analyzer explcheck.
-- Convert a byte number in a file to a line and column number in a file.
local function convert_byte_to_line_and_column(line_starting_byte_numbers, byte_number)
local line_number = 0
for _, line_starting_byte_number in ipairs(line_starting_byte_numbers) do
if line_starting_byte_number > byte_number then
break
end
line_number = line_number + 1
end
assert(line_number > 0)
local line_starting_byte_number = line_starting_byte_numbers[line_number]
assert(line_starting_byte_number <= byte_number)
local column_number = byte_number - line_starting_byte_number + 1
return line_number, column_number
end
-- Convert a pathname of a file to the suffix of the file.
local function get_suffix(pathname)
return pathname:gsub(".*%.", "."):lower()
end
-- Convert a pathname of a file to the base name of the file.
local function get_basename(pathname)
return pathname:gsub(".*[\\/]", "")
end
-- Convert a pathname of a file to the stem of the file.
local function get_stem(pathname)
return get_basename(pathname):gsub("%..*", "")
end
-- Convert a pathname of a file to the pathname of its parent directory.
local function get_parent(pathname)
if pathname:find("[\\/]") then
return pathname:gsub("(.*)[\\/].*", "%1")
else
return "."
end
end
-- Return all parameters unchanged, mostly used for no-op map-back and map-forward functions.
local function identity(...)
return ...
end
-- Run all processing steps.
local function process_with_all_steps(pathname, content, issues, analysis_results, options)
local get_option = require("explcheck-config").get_option
local preprocessing = require("explcheck-preprocessing")
local lexical_analysis = require("explcheck-lexical-analysis")
local syntactic_analysis = require("explcheck-syntactic-analysis")
local semantic_analysis = require("explcheck-semantic-analysis")
local steps = {preprocessing, lexical_analysis, syntactic_analysis, semantic_analysis}
for _, step in ipairs(steps) do
step.process(pathname, content, issues, analysis_results, options)
-- If a processing step ended with error, skip all following steps.
if #issues.errors > 0 and get_option('fail_fast', options, pathname) then
return
end
end
end