From 65e2cf96137a1e10bbb923e60b9fe7daf9f78c09 Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 28 Oct 2020 13:31:12 +0800 Subject: [PATCH] =?UTF-8?q?judge:=20=E4=BF=AE=E5=A4=8Djudge=5Fextra=5Ffile?= =?UTF-8?q?s=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hydrojudge/package.json | 2 +- packages/hydrojudge/src/cases.ts | 4 ++-- packages/hydrojudge/src/check.ts | 3 ++- packages/hydrojudge/src/checkers.ts | 22 ++++++++++++++++++---- packages/hydrojudge/src/judge/default.ts | 5 +++-- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/hydrojudge/package.json b/packages/hydrojudge/package.json index 89eb92e34..2bf8b770b 100644 --- a/packages/hydrojudge/package.json +++ b/packages/hydrojudge/package.json @@ -1,7 +1,7 @@ { "name": "@hydrooj/hydrojudge", "bin": "bin/hydrojudge.js", - "version": "2.1.4", + "version": "2.1.5", "main": "package.json", "author": "masnn", "dependencies": { diff --git a/packages/hydrojudge/src/cases.ts b/packages/hydrojudge/src/cases.ts index 2b8c1212a..b5e04c175 100644 --- a/packages/hydrojudge/src/cases.ts +++ b/packages/hydrojudge/src/cases.ts @@ -209,7 +209,7 @@ export = async function readYamlCases(folder: string, cfg: Dictionary, args if (typeof cfg.judge_extra_files === 'string') { config.judge_extra_files = [checkFile(cfg.judge_extra_files, '找不到评测额外文件 ')]; } else if (cfg.judge_extra_files instanceof Array) { - for (const file in cfg.judge_extra_files) { + for (const file of cfg.judge_extra_files) { config.judge_extra_files.push(checkFile(file, '找不到评测额外文件 ')); } } else throw new FormatError('无效的 judge_extra_files 配置项'); @@ -218,7 +218,7 @@ export = async function readYamlCases(folder: string, cfg: Dictionary, args if (typeof cfg.user_extra_files === 'string') { config.user_extra_files = [checkFile(cfg.user_extra_files, '找不到用户额外文件 ')]; } else if (cfg.user_extra_files instanceof Array) { - for (const file in cfg.user_extra_files) { + for (const file of cfg.user_extra_files) { config.user_extra_files.push(checkFile(file, '找不到用户额外文件 ')); } } else throw new FormatError('无效的 user_extra_files 配置项'); diff --git a/packages/hydrojudge/src/check.ts b/packages/hydrojudge/src/check.ts index 22fcc99f4..00482b85a 100644 --- a/packages/hydrojudge/src/check.ts +++ b/packages/hydrojudge/src/check.ts @@ -2,6 +2,7 @@ import fs from 'fs-extra'; import checkers from './checkers'; import compile from './compile'; import { SystemError } from './error'; +import { parseFilename } from './utils'; export async function check(config): Promise<[number, number, string]> { if (!checkers[config.checker_type]) throw new SystemError(`未知比较器类型:${config.checker_type}`); @@ -24,5 +25,5 @@ export async function compileChecker(checkerType: string, checker: string, copyI if (!checkers[checkerType]) { throw new SystemError(`未知比较器类型:${checkerType}`); } const file = await fs.readFile(checker); // TODO cache compiled checker - return await compile(checker.split('.')[1], file.toString(), 'checker', copyIn); + return await compile(parseFilename(checker).split('.')[1], file.toString(), 'checker', copyIn); } diff --git a/packages/hydrojudge/src/checkers.ts b/packages/hydrojudge/src/checkers.ts index 61342f881..3cefa272f 100644 --- a/packages/hydrojudge/src/checkers.ts +++ b/packages/hydrojudge/src/checkers.ts @@ -19,6 +19,7 @@ const checkers: Record = { copyIn: { usrout: { src: config.user_stdout }, stdout: { src: config.output }, + ...config.copyIn, }, }); let status; @@ -70,6 +71,7 @@ const checkers: Record = { usrout: { src: config.user_stdout }, stdout: { src: config.output }, input: { src: config.input }, + ...config.copyIn, }, }); const status = code ? STATUS.STATUS_WRONG_ANSWER : STATUS.STATUS_ACCEPTED; @@ -95,6 +97,7 @@ const checkers: Record = { usrout: { src: config.user_stdout }, stdout: { src: config.output }, input: { src: config.input }, + ...config.copyIn, }, copyOut: ['score', 'message'], }); @@ -119,6 +122,7 @@ const checkers: Record = { copyIn: { usrout: { src: config.user_stdout }, input: { src: config.input }, + ...config.copyIn, }, }); const st = (status === STATUS.STATUS_ACCEPTED) @@ -146,6 +150,7 @@ const checkers: Record = { user_out: { src: config.user_stdout }, answer: { src: config.output }, code: { content: config.code }, + ...config.copyIn, }, }); if (status !== STATUS.STATUS_ACCEPTED) throw new SystemError('Checker returned a non-zero value', [status]); @@ -155,17 +160,26 @@ const checkers: Record = { }, async testlib(config) { - const { stdout, stderr } = await run('${dir}/checker ${dir}/in ${dir}/user_out ${dir}/answer', { + console.log(config); + const { stderr, status } = await run('${dir}/checker ${dir}/in ${dir}/user_out ${dir}/answer', { copyIn: { in: { src: config.input }, user_out: { src: config.user_stdout }, answer: { src: config.output }, + ...config.copyIn, }, }); + if (status !== STATUS.STATUS_ACCEPTED) { + return { + status: STATUS.STATUS_SYSTEM_ERROR, + score: 0, + message: '', + }; + } return { - status: stderr === 'ok \n' ? STATUS.STATUS_ACCEPTED : STATUS.STATUS_WRONG_ANSWER, - score: stderr === 'ok \n' ? config.score : 0, - message: stdout, + status: stderr.startsWith('ok ') ? STATUS.STATUS_ACCEPTED : STATUS.STATUS_WRONG_ANSWER, + score: stderr.startsWith('ok ') ? config.score : 0, + message: stderr.split(' ').splice(1).join(' '), }; }, }; diff --git a/packages/hydrojudge/src/judge/default.ts b/packages/hydrojudge/src/judge/default.ts index 8d0cb0fed..2d7dd9c94 100644 --- a/packages/hydrojudge/src/judge/default.ts +++ b/packages/hydrojudge/src/judge/default.ts @@ -51,7 +51,7 @@ function judgeCase(c) { status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED; } else { [status, score, message] = await check({ - copyIn: copyInDir(path.resolve(ctx.tmpdir, 'checker')), + copyIn: ctx.checker.copyIn, stdin: c.input, stdout: c.output, user_stdout: stdout, @@ -114,7 +114,7 @@ export const judge = async (ctx) => { } else throw new CompileError('Language not supported by provided templates'); } ctx.next({ status: STATUS.STATUS_COMPILING }); - [ctx.execute] = await Promise.all([ + [ctx.execute, ctx.checker] = await Promise.all([ (async () => { const copyIn = {}; for (const file of ctx.config.user_extra_files) { @@ -135,6 +135,7 @@ export const judge = async (ctx) => { ); })(), ]); + ctx.clean.push(ctx.checker.clean); ctx.clean.push(ctx.execute.clean); ctx.next({ status: STATUS.STATUS_JUDGING, progress: 0 }); const tasks = [];