Додавання нового мовного процесора

Керівництво по додаванню підтримки мов програмування, наведене тут, відноситься до системи ejudge версії не нижче 2.3.8.

Мовний процесор (ЯП) - це або компілятор, або інтерпретатор деякого мови програмування.

Оскільки система ejudge підтримує кілька варіантів одного і того ж мови програмування (наприклад, Free Pascal, Borland Kylix, і т. Д.), Правильніше говорити не про підтримку мов програмування, а про підтримку мовних процесорів.

Додавання підтримки нового ЯП в систему ejudge виконується в кілька кроків.

  1. Визначення параметрів додається ЯП
  2. Написання настроечного скрипта (lang-version.in)
  3. Написання скрипта компіляції (lang.in)
  4. Переконфігурація підтримуваних ЯП за допомогою програми ejudge-configure-compilers
  5. Перезапуск системи ejudge

Визначення параметрів ЯП

Параметри ЯП, необхідні для його підтримки в системі ejudge, перераховані нижче:

прапор підтримки безпечного режиму

коротка назва ЯП (як правило, визначається автоматично)

повна назва ЯП

стандартний суфікс файлу з вихідним текстом для даного ЯП

стандартний суфікс виконуваного файлу для даного ЯП

аргумент, вказаний при конфігуруванні ЯП програмами ejudge-setup або ejudge-configure-compilers

Основний параметр ЯП - це архітектура (arch). Під архітектурою розуміється системне оточення, в якому запускається тестована програма. Система ejudge підтримує наступні архітектури:

  • linux - статично скомпонована виконується програма
  • linux-shared - динамічно скомпонована виконується програма (в тому числі і скрипти)
  • java - байт-код java
  • msil - байт-код .NET
  • dos - додатки DOS

Архітектура linux є архітектурою за замовчуванням. Якщо ЯП має архітектуру linux, то параметр arch для цього ЯП повинен або відсутні, або мати порожнє значення.

Другий параметр ЯП - це прапор, чи коректно працює тестована програма для даного ЯП при запуску в безпечному режимі. Якщо ЯП має архітектуру linux, java або dos, то тестовані програми для такого ЯП, як правило, коректно працюють в безпечному режимі, при цьому підтримуються всі обмеження безпеки. Якщо ЯП має архітектуру msil, то безпечний режим для нього не підтримуються. Програми для такого ЯП можуть тестуватися, але при цьому ніяких обмежень безпеки на роботу програми накладатися не буде. Якщо ЯП має архітектуру linux-shared, то безпечний режим для такого ЯП підтримується, проте тестована програма в безпечному режимі може працювати некоректно чи не працювати взагалі.

У будь-якому випадку, якщо є сумніви в працездатності програми в безпечному режимі, потрібна перевірка на простих програмах, як працюють зі стандартними потоками, так і працюють з файлами.

Якщо додається ЯП не підтримує безпечний режим, то параметр ЯП insecure має дорівнювати 1. Якщо безпечний режим підтримується, то параметр повинен бути відсутнім або мати порожнє значення.

З ЯП підтримуваних системою ejudge в стандартному постачанні в версії 2.3.8, небезпечними є ЯП gcj (GNU Java), gfortran (GNU Fortran), mcs (Mono C #), mzscheme (MzScheme), php (PHP), vbnc (Mono Visual Basic ), yabasic (YaBasic).

Параметр short_name - це коротка назва ЯП. Коротка назва використовується в таблиці посилок користувачів і ряді інших місць. Коротка назва ЯП - це, по суті, ідентифікатор ЯП. Він повинен являти собою одне слово, що не довше 32 символів і що складається з великих і малих латинських букв, цифр і знаків +, -, _. Як правило, коротка назва ЯП визначається автоматично з імені скрипта компіляції та налаштування. Наприклад, якщо скрипт компіляції (точніше, шаблон скрипта компіляції) має ім'я foo.in. то за замовчуванням кратне назву ЯП дорівнюватиме foo. Зверніть увагу, що в unix-системах імена файлів чутливі до регістру букв. Значення параметра short_name також чутливо до регістру букв.

Параметр long_name - це розгорнуте (повне) назву ЯП. Наприклад, коротке ім'я ЯП може бути foo. а повне - "GNU Foo Interpreter". Зверніть увагу, що в повну назву ЯП не входить номер версії.

Параметр src_sfx - це стандартний суфікс вихідних файлів для даного ЯП. Наприклад, якщо для ЯП GNU Foo вихідні файли називаються file.foo. то суфіксом вихідних файлів буде рядок .foo (зверніть увагу, що "точка" входить в суфікс).

Параметр exe_sfx визначає стандартний суфікс для виконуваних файлів для даного ЯП. Як правило, суфікс виконуваних файлів залежить від архітектури ЯП. Так, для архітектур linux і linux-shared стандартний суфікс виконуваних файлів не потрібно, тому параметр exe_sfx може бути опущений або мати порожнє значення. Для архітектур dos і msil стандартний суфікс виконуваних файлів - .exe. а для архітектури java - .jar.

Параметри arch. insecure. short_name. long_name. src_sfx. exe_sfx описують властивості власне ЯП, тому для даного ЯП не змінюються від інсталяції до інсталяції системи ejudge.

Параметри version і arg описують властивості інсталяції даного ЯП в конкретній системі, тому їх значення можуть змінюватися від інсталяції до інсталяції.

Параметр version визначає версію ЯП. Якщо значення цього параметра порожнім, то вважається, що відповідний ЯП ні виявлено в системі. Тому значення цього параметра не повинно бути порожнім. Версія ЯП визначається Настроювальна скриптом, як правило, за допомогою запуску ЯП зі спеціальними опціями і обробки отриманого висновку.

Параметр arg містить аргумент конфігурації ЯП, переданий в скрипти налаштування ejudge-setup або ejudge-configure-compilers. Наприклад, якщо запустити програму ejudge-configure-compilers з опцією --with-foo = / usr / local / bin / foo, то параметр / usr / local / bin / foo буде переданий скрипту конфігурації ЯП foo-version. Крім того, цей параметр може бути встановлений і в інтерактивному режимі в програмах ejudge-setup і ejudge-configure-compilers. Як правило, цей параметр задає шлях до ЯП в файлової системі, і корисний у випадках, коли ЯП розміщується в нестандартних місцях.

Структура файлів для підтримки ЯП

Припустимо, що система ejudge проінстальована в каталог / opt / ejudge, а каталог для даних встановлено в / home / ejudge. Тоді в каталозі / home / ejudge / compile розміщуються конфігураційні файли і скрипти для сервера компіляції програм.

compile.cfg

Файл /home/ejudge/compile/conf/compile.cfg - основний конфігураційний файл сервера компіляції compile. У файлі міститься інформація, необхідна для компіляції для всіх підтримуваних в даній інсталяції ЯП. Наприклад, для ЯП foo секція опису ЯП може виглядати наступним чином:

Тут id - це числовий ідентифікатор ЯП, унікальний для всіх ЯП в даній інсталяції. Решта інформації про ЯП береться з параметрів ЯП, описаних в попередньому розділі.

Файл /home/ejudge/compile/conf/compile.cfg автоматично записується при кожному виклику програми ejudge-configure-compilers. Всі зміни, внесені в нього вручну, губляться при кожному запуску ejudge-configure-compilers.

Версія ЯП і прапор, що відповідний ЯП в системі виявлено, не містяться в цьому файлі конфігурації, а зчитуються безпосередньо з конфігураційного файлу ЯП при кожному запуску програми compile.

lang_ids.cfg

Ідентифікатори id ЯП, підтримуваних в стандартному постачанні, зберігаються в файлі $ / libexec / ejudge / lang / lang_ids.cfg. Якщо інформація про новий ЯП в цьому файлі відсутній, його ідентифікатор призначається автоматично: береться перший ще не використаний у файлі compile.cfg. Користувач може скопіювати файл lang_ids.cfg в каталог $ / compile / scripts і вносити в нього довільні зміни. Модифікувати файл $ / libexec / ejudge / lang / lang_ids.cfg не рекомендується, так як він буде перезаписаний при оновленні системи.

Каталог lang.d

Каталог /home/ejudge/compile/conf/lang.d містить файли конфігураційних налаштувань всіх підтримуваних системою ejudge ЯП. Для ЯП foo конфігураційний файл називається foo.cfg. Його вміст може бути приблизно таким:

Файл записується в синтаксисі / bin / sh. Цей файл використовується як програмами системи ejudge, такими як compile, super-serve, так і безпосередньо скриптами foo і foo-version. Він генерується скриптом foo-version, що запускаються в спеціальному режимі.

Крім параметрів ЯП, описаних вище, файл може містити визначення довільних змінних, необхідних для роботи скриптів foo або foo-version. На прикладі вище це змінна FOOPATH.

Каталог in

В каталозі in знаходяться заготовки для скриптів конфігурації і компіляції ЯП. У каталозі / opt / ejudge / libexec / ejudge / lang / in знаходяться заготовки скриптів для ЯП, підтримуваних в стандартному постачанні системи ejudge. У каталозі / home / ejudge / compile / scripts / in знаходяться заготовки скриптів користувача. Останній каталог більш пріоритетним, тобто якщо заготовка скрипта виявлена ​​в каталозі / home / ejudge / compile / scripts / in, системний каталог перевірятися не буде. Тому, якщо необхідно модифікувати поставляється скрипт, його потрібно попередньо скопіювати в цей каталог, потім модифікувати. Модифікувати файли безпосередньо в каталозі / opt / ejudge / libexec / ejudge / lang / in не рекомендується, так як ці файли перезаписувати при оновленні системи ejudge.

Каталог scripts

У каталозі / home / ejudge / compile / scripts знаходяться оброблені заготовки скриптів, готові до використання всіма програмами системи ejudge. Заготовки скриптів обробляються і копіюються з каталогів / opt / ejudge / libexec / ejudge / lang / in і / home / ejudge / compile / scripts / in в цей каталог програмою ejudge-configure-compilers.

заготовки скриптів

Для ЯП foo повинні бути написані заготовки скриптів foo.in і foo-version.in. Заготовки скриптів повинні бути поміщені в каталог / home / ejudge / compile / scripts / in. Заготовки скриптів за змістом відповідають заготівлях файлів Makefile.in, config.h.in в системі GNU autotools. Тобто в заготовках скриптів виконується заміна змінних виду @ var @ на їх значення.

Підтримувані підстановки перераховані в таблиці

соотв. опція configure

Її конфігураційний скрипт

Її конфігураційний скрипт повинен підтримувати кілька режимів запуску. Режими задаються за допомогою опцій командного рядка. Всі режими роботи розглядаються на прикладі настроечного скрипта foo-version

-r - режим конфігурації

В режимі конфігурації повинна бути перевірена підтримка ЯП в даній інсталяції. На стандартний потік виведення має бути надруковано новий вміст конфігураційного файлу ЯП foo.cfg. Крім того, якщо вказана опція -v, на стандартний потік помилок повинна бути надрукована додаткова інформація про процес конфігурації. При успішному конфигурировании код завершення має дорівнювати 0, а при невдачі - 1. В параметрі ARG передається шлях, який вказав користувач в опції --with-foo = ARG при конфігуруванні в пакетному режимі, або шлях, введений нею при конфігуруванні в діалоговому режимі .

Так, якщо ЯП foo підтримується в даній інсталяції, сценарій запуску може бути наступним:

Останній рядок (checking.) Виводиться на стандартний потік помилок.

Якщо ЯП foo не підтримуються в даній інсталяції, сценарій запуску може бути наступним:

Останній рядок (checking.) Виводиться на стандартний потік помилок.

-l - режим отримання списку

У режимі отримання списків ЯП на стандартний потік виведення повинна бути надрукована рядок інформації про ЯП. Рядок інформації друкується незалежно від того, чи підтримується даний ЯП в даній інсталяції. Код завершення завжди має дорівнювати 0.

Так, для ЯП foo сценарій запуску може бути наступним:

Режим отримання списку ЯП використовується програмою ejudge-configure-compilers при запуску її з опцією --list.

-p - друк шляху до ЯП

У режимі друку шляху до ЯП на стандартний потік виведення повинен бути надрукований шлях до ЯП. Код завершення має дорівнювати 0. Якщо ЯП не підтримуються в даній інсталяції, висновок повинен бути порожній, а код завершення дорівнює 1. У цьому випадку на стандартний потік помилок може виводитися діагностичне повідомлення.

Так, якщо ЯП foo підтримується в даній інсталяції, сценарій запуску може бути наступним:

Режим друку використовується програмою super-serve в деяких спеціальних випадках.

-f - друк повного імені та версії

У режимі друку повної назви ЯП на стандартний потік виведення має бути надруковано повне ім'я ЯП і номер версії ЯП. У разі, якщо ЯП не підтримує на даній системі (в даній інсталяції), стандартний потік виведення повинен бути порожній, а код повернення дорівнює 1. На стандартний потік помилок при цьому може виводитися діагностичне повідомлення.

Так, якщо ЯП foo підтримується в даній інсталяції, сценарій запуску може бути наступним:

Якщо ЯП foo не підтримується, то наступним:

в цьому випадку повідомлення виводиться на стандартний потік помилок.

Режим друку версії використовується програмою super-serve в процесі настройки ЯП при редагуванні турніру.

друк версії

У режимі друку версій, який задається запуском скрипта без параметрів, на стандартний потік виведення повинен бути надрукований номер версії ЯП. У разі, якщо ЯП не підтримує на даній системі (в даній інсталяції), стандартний потік виведення повинен бути порожній, а код повернення дорівнює 1. На стандартний потік помилок при цьому може виводитися діагностичне повідомлення.

Так, якщо ЯП foo підтримується в даній інсталяції, сценарій запуску може бути наступним:

Якщо ЯП foo не підтримується, то наступним:

в цьому випадку повідомлення виводиться на стандартний потік помилок.

Режим друку версії використовується програмою super-serve в процесі настройки ЯП при редагуванні турніру.

Реалізація

Розглянемо реалізацію скрипта конфігурації ЯП foo foo-version.in. За зразок для цього (гіпотетичного) скрипта узятий скрипт для конфігурації ЯП Ruby.

скрипт компіляції

Скрипт компіляції приймає в якості параметрів ім'я файлу з вихідним текстом програми для ЯП і ім'я файлу результату. Завдання скрипта компіляції - отримати на виході файл, готовий до запуску в оточенні, що задається архітектурою мови.

Для компільованих мов результатом роботи скрипта компіляції є бінарний виконуваний файл. Для різних мов результатом роботи скрипта компіляції є скрипт, готовий до запуску. Як правило, для різних мов для цього достатньо записати в початок файлу конструкцію

і встановити біт x дозволу виконання файлу. Тут INTERP-PATH - це повний шлях до інтерпретатора відповідної мови.

Далі скрипт компіляції розглядається на прикладі гіпотетичного інтерпретується мови foo.

Інтерфейс скрипта компіляції дуже простий

Тут SRC-FILE - ім'я вхідного файлу, DST-FILE - ім'я вихідного файлу. Система ejudge формує імена вхідного і вихідного файлів з використанням суфіксів вихідного файлу та файлу результату, як зазначено в файлі конфігурації ЯП. Таким чином, ніякої додаткової обробки імен вхідного і вихідного файлу виконувати не потрібно.

Додатково в змінної оточення EJUDGE_FLAGS можуть задаватися прапори для ЯП. Адміністратор турніру має можливість встановлювати прапори при редагуванні турніру. Тому скрипт компіляції повинен підтримувати завдання додаткових опцій за допомогою еременной оточення EJUDGE_FLAGS.

Реалізація

Приклад реалізації скрипта компіляції foo.in. За зразок для цього (гіпотетичного) скрипта узятий скрипт для компіляції ЯП Ruby.

Переконфігурація підтримуваних ЯП

Після того, як скрипти foo-version.in і foo.in поміщені в каталог / home / ejudge / compile / scripts / in досить запустити програму ejudge-configure-compilers. Якщо скрипти написані правильно, версія ЯП повинна бути визначена коректно, після чого мова готова до використання.

В турнір мову може бути доданий при редагуванні налаштувань турніру за допомогою CGI-програми serve-control.

перезапуск ejudge

Після виконання всіх кроків не забудьте перезапустити ejudge, щоб сервер компіляції compile вважав новий конфігураційний файл.