78 lines
2.7 KiB
Lua
78 lines
2.7 KiB
Lua
---@class ProblemContext
|
|
---@field contest string Contest name (e.g. "atcoder", "codeforces")
|
|
---@field contest_id string Contest ID (e.g. "abc123", "1933")
|
|
---@field problem_id? string Problem ID for AtCoder/Codeforces (e.g. "a", "b")
|
|
---@field source_file string Source filename (e.g. "abc123a.cpp")
|
|
---@field binary_file string Binary output path (e.g. "build/abc123a.run")
|
|
---@field input_file string Input test file path (e.g. "io/abc123a.in")
|
|
---@field output_file string Output file path (e.g. "io/abc123a.out")
|
|
---@field expected_file string Expected output path (e.g. "io/abc123a.expected")
|
|
---@field problem_name string Canonical problem identifier (e.g. "abc123a")
|
|
|
|
local M = {}
|
|
|
|
---@param contest string
|
|
---@param contest_id string
|
|
---@param problem_id? string
|
|
---@param config cp.Config
|
|
---@param language? string
|
|
---@return ProblemContext
|
|
function M.create_context(contest, contest_id, problem_id, config, language)
|
|
vim.validate({
|
|
contest = { contest, 'string' },
|
|
contest_id = { contest_id, 'string' },
|
|
problem_id = { problem_id, { 'string', 'nil' }, true },
|
|
config = { config, 'table' },
|
|
language = { language, { 'string', 'nil' }, true },
|
|
})
|
|
|
|
local contest_config = config.contests[contest]
|
|
if not contest_config then
|
|
error(("No contest config found for '%s'"):format(contest))
|
|
end
|
|
|
|
local target_language = language or contest_config.default_language
|
|
local language_config = contest_config[target_language]
|
|
if not language_config then
|
|
error(
|
|
("No language config found for '%s' in contest '%s'"):format(
|
|
target_language,
|
|
contest
|
|
)
|
|
)
|
|
end
|
|
if not language_config.extension then
|
|
error(
|
|
("No extension configured for language '%s' in contest '%s'"):format(
|
|
target_language,
|
|
contest
|
|
)
|
|
)
|
|
end
|
|
|
|
local base_name
|
|
if config.filename then
|
|
local source_file =
|
|
config.filename(contest, contest_id, problem_id, config, language)
|
|
base_name = vim.fn.fnamemodify(source_file, ':t:r')
|
|
else
|
|
local default_filename = require('cp.config').default_filename
|
|
base_name = default_filename(contest_id, problem_id)
|
|
end
|
|
|
|
local source_file = base_name .. '.' .. language_config.extension
|
|
|
|
return {
|
|
contest = contest,
|
|
contest_id = contest_id,
|
|
problem_id = problem_id,
|
|
source_file = source_file,
|
|
binary_file = ('build/%s.run'):format(base_name),
|
|
input_file = ('io/%s.cpin'):format(base_name),
|
|
output_file = ('io/%s.cpout'):format(base_name),
|
|
expected_file = ('io/%s.expected'):format(base_name),
|
|
problem_name = base_name,
|
|
}
|
|
end
|
|
|
|
return M
|