Libchecker:Структура проверяющей программы

From EjudgeWiki

Навигация: Главная страница/Система ejudge/Проверяющие программы/libchecker/Структура проверяющей программы

Библиотека представляет собой каркас (framework), в который вставляются необходимые действия по проверке результата. Библиотека определяет функцию main, то есть при старте проверяющей программы управление получает модуль инициализации библиотеки libchecker.

Вместо функции main проверяющая программа должна определить функцию checker_main с прототипом, таким же как у main. После инициализации библиотеки libchecker будет вызвана функция checker_main основной части кода проверяющей программы. Таким образом, функция checker_main проверяющей программы играет роль функции main обычной программы на C или C++.

Если проверяющая программа сама определяет функцию main и не использует функций и переменных, предоставляемых библиотекой libchecker, такая программа может безопасно линковаться с библиотекой, и библиотека никаким образом не повлияет на работу программы. То есть даже автономные проверяющие программы могут безопасно линковаться с библиотекой libchecker.

Простейший случай проверяющей программы

В самом простом случае проверяющая программа требует входной файл и результат работы тестируемой программы на входном файле. Проверяющая программа сама вычисляет правильный ответ и сравнивает его с ответом, выданным тестируемой программой.

Такая проверяющая программа требует как минимум два аргумента командной строки:

  • argv[1] — имя входного файла
  • argv[2] — имя файла с результатом работы тестируемой программы

Если передаётся большее количество аргументов командной строки, остальные аргументы не используются.

Проверяющая программа тогда может выглядеть примерно следующим образом:

#define NEED_CORR 0
#include "checker.h"
int checker_main(int argc, char **argv)
{
   // checker code is here
   checker_OK();
}

Здесь макроопределение NEED_CORR равное 0 включает простейший режим проверки. Макроопределение NEED_CORR должно обязательно присутствовать в проверяющей программе и находиться перед директивой #include.

Функция checker_main должна либо возвращать значение, соответствующее допустимому коду завершения проверяющей программы, либо завершаться вызовом одной из функций checker_OK, fatal_WA, fatal_PE, fatal_CF, fatal_read. В данном примере функция checker_main завершается вызовом checker_OK. Предполагается, что код проверяющей программы будет при необходимости вызывать другие функции, завершающие работу проверяющей программы.

Использование файлов эталонного ответа

В наиболее типичном случае проверяющая программа кроме входного файла и файла с результатом работы тестируемой программы требует и файл с эталонным ответом. Этот файл не обязательно содержит правильный ответ сам по себе, но может содержать данные, необходимые для проверки правильности ответа.

Такая проверяющая программа требует как минимум три аргумента командной строки:

  • argv[1] — имя входного файла
  • argv[2] — имя файла с результатом работы тестируемой программы
  • argv[3] — имя файла с эталонным ответом

Если передаётся большее количество аргументов командной строки, остальные аргументы не используются.

Чтобы в описании задачи указать, что будет использоваться проверяющая программа этого типа, необходимо использовать конфигурационную переменную use_corr.

Проверяющая программа может выглядеть примерно следующим образом:

#define NEED_CORR 1
#include "checker.h"
int checker_main(int argc, char **argv)
{
   // checker code is here
   checker_OK();
}

Здесь макроопределение NEED_CORR равное 1 включает требуемый режим проверки. Макроопределение NEED_CORR должно обязательно присутствовать в проверяющей программе и находиться перед директивой #include.

Требования к функции checker_main описаны выше.

Использование файлов дополнительной информации о тесте

В некоторых ситуациях проверяющей программе для работы требуется файл с дополнительной информацией о тесте, но не требуется файл эталонного ответа.

Такая проверяющая программа требует как минимум три аргумента командной строки:

  • argv[1] — имя входного файла
  • argv[2] — имя файла с результатом работы тестируемой программы
  • argv[3] — имя файла с дополнительной информацией о тесте

Если передаётся большее количество аргументов командной строки, остальные аргументы не используются.

Чтобы в описании задачи указать, что будет использоваться проверяющая программа этого типа, необходимо использовать конфигурационную переменную use_info.

Проверяющая программа может выглядеть примерно следующим образом:

#define NEED_CORR 0
#define NEED_INFO 1
#include "checker.h"
int checker_main(int argc, char **argv)
{
   // checker code is here
   checker_OK();
}

Здесь макроопределение NEED_INFO равное 1 включает требуемый режим проверки. Макроопределение NEED_CORR должно обязательно присутствовать в проверяющей программе и находиться перед директивой #include. Макроопределение NEED_INFO может отсутствовать.

Требования к функции checker_main описаны выше.

Использование подготовленного рабочего каталога

В некоторых ситуациях проверяющей программе для работы требуется специально подготовленный рабочий каталог, в котором запускалась тестируемая программа, но не требуется ни файл эталонного ответа, ни файл дополнительной информации о тесте.

Такая проверяющая программа требует как минимум четыре аргумента командной строки:

  • argv[1] — имя входного файла
  • argv[2] — имя файла с результатом работы тестируемой программы
  • argv[3] — путь к каталогу с содержимым, идентичным рабочему каталогу тестируемой программы на момент запуска
  • argv[4] — путь к рабочему каталогу тестируемой программы

Если передаётся большее количество аргументов командной строки, остальные аргументы не используются.

Чтобы в описании задачи указать, что будет использоваться проверяющая программа этого типа, необходимо использовать конфигурационную переменную use_tgz.

Проверяющая программа может выглядеть примерно следующим образом:

#define NEED_CORR 0
#define NEED_TGZ 1
#include "checker.h"
int checker_main(int argc, char **argv)
{
   // checker code is here
   checker_OK();
}

Здесь макроопределение NEED_TGZ равное 1 включает требуемый режим проверки. Макроопределение NEED_CORR должно обязательно присутствовать в проверяющей программе и находиться перед директивой #include. Макроопределение NEED_TGZ может отсутствовать.

Требования к функции checker_main описаны выше.

Сочетание режимов использования

Используя различные комбинации значений макросов NEED_CORR, NEED_INFO и NEED_TGZ можно задавать все возможные режимы работы проверяющей программы. Проверяющая программа в зависимости от выбранной комбинации значений макросов будет требовать от 2 до 6 параметров командной строки. Например, когда значения всех макросов установлены в 1, проверяющей программе требуется как минимум 6 аргументов командной строки:

  • argv[1] — имя входного файла
  • argv[2] — имя файла с результатом работы тестируемой программы
  • argv[3] — имя файла с эталонным ответом
  • argv[4] — имя файла с дополнительной информацией о тесте
  • argv[5] — путь к каталогу с содержимым, идентичным рабочему каталогу тестируемой программы на момент запуска
  • argv[6] — путь к рабочему каталогу тестируемой программы

Если передаётся большее количество аргументов командной строки, остальные аргументы не используются.