diff --git a/README.md b/README.md index daddcb1c7..5c4e0a593 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Supported languages include: The judge can also grade in the languages listed below: * Ada +* Algol 68 * AWK * Brain\*\*\*\* * COBOL diff --git a/dmoj/executors/ALGL68.py b/dmoj/executors/ALGL68.py new file mode 100644 index 000000000..0e3de0eb4 --- /dev/null +++ b/dmoj/executors/ALGL68.py @@ -0,0 +1,42 @@ +from typing import List + +from dmoj.cptbox.handlers import ACCESS_EACCES +from dmoj.executors.compiled_executor import CompiledExecutor + + +class Executor(CompiledExecutor): + ext = 'a' + command = 'a68g' + + test_program = """ +BEGIN + STRING input; + get(standin, input); + print((input, newline)) +END +""" + + data_grace = 131072 + syscalls = [ + ('mkdir', ACCESS_EACCES), + ('mkdirat', ACCESS_EACCES), + 'alarm', + 'setitimer', + ] + + def get_compile_args(self) -> List[str]: + command = self.get_command() + assert command is not None + assert self._code is not None + # This doesn't actually compile anything, but will generate useful + # output if the program is malformed. + return [command, '--norun', '--noportcheck', '--nopragmats', self._code] + + def get_cmdline(self, **kwargs) -> List[str]: + command = self.get_command() + assert command is not None + assert self._code is not None + return [command, '--nowarnings', '--noportcheck', '--nopragmats', self._code] + + def get_executable(self): + return self.get_command() diff --git a/dmoj/executors/compiled_executor.py b/dmoj/executors/compiled_executor.py index d59a2f1ff..964e3a204 100644 --- a/dmoj/executors/compiled_executor.py +++ b/dmoj/executors/compiled_executor.py @@ -1,6 +1,9 @@ +import fcntl import hashlib import os import pty +import struct +import termios from typing import Any, Dict, IO, List, Optional, Tuple, Union import pylru @@ -126,6 +129,11 @@ def create_compile_process(self, args: List[str]) -> TracedPopen: # # Emulate the streams of a process connected to a terminal: stdin, stdout, and stderr are all ptys. _master, _slave = pty.openpty() + + # Some runtimes helpfully try to word-wrap error messages by determining the width of the screen. Lie and say + # we're a 1024x1024 terminal, so they don't try wrapping to 1-column width. + fcntl.ioctl(_slave, termios.TIOCSWINSZ, struct.pack('HHHH', 1024, 1024, 0, 0)) + # Some runtimes *cough cough* Swift *cough cough* actually check the environment variables too. env = self.get_compile_env() or os.environ.copy() env['TERM'] = 'xterm'