mirror of
https://github.com/osmarks/random-stuff
synced 2024-12-28 02:50:33 +00:00
86 lines
3.0 KiB
Python
86 lines
3.0 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
import random
|
||
|
import collections
|
||
|
import subprocess
|
||
|
import ctypes
|
||
|
import tempfile
|
||
|
import os
|
||
|
import shutil
|
||
|
import os.path
|
||
|
import base64
|
||
|
|
||
|
class CWrapper:
|
||
|
def __init__(self, file):
|
||
|
self.filename = file
|
||
|
def __enter__(self):
|
||
|
self.tempfile = tempfile.mktemp(prefix="shlib-")
|
||
|
print("Compiling C file", self.filename)
|
||
|
if subprocess.run(["gcc", self.filename, "-o", self.tempfile , "-shared", "-fPIC"]).returncode != 0:
|
||
|
raise ValueError("compilation failed")
|
||
|
library = ctypes.CDLL(self.tempfile)
|
||
|
self.function = entry = library.entry
|
||
|
entry.restype = ctypes.c_char_p
|
||
|
return self
|
||
|
|
||
|
def __call__(self, s): return self.function(ctypes.c_char_p(s.encode("ascii"))).decode("ascii")
|
||
|
def __repr__(self): return f"<wrapper for C solution {self.filename}>"
|
||
|
def __exit__(self, type, value, traceback): os.unlink(self.tempfile)
|
||
|
|
||
|
class JavaWrapper:
|
||
|
main = """
|
||
|
import java.io.*;
|
||
|
public class Main {
|
||
|
public static void main(String[] args) {
|
||
|
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||
|
try {
|
||
|
while (true) {
|
||
|
String line = br.readLine();
|
||
|
if (line == null) { return; }
|
||
|
System.err.println("got");
|
||
|
System.err.println(line);
|
||
|
System.out.println(Entry.entry(line));
|
||
|
}
|
||
|
} catch (IOException ioe) {
|
||
|
System.err.println(ioe);
|
||
|
System.exit(1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def __init__(self, file):
|
||
|
self.filename = file
|
||
|
def __enter__(self):
|
||
|
self.tempdir = tempfile.mkdtemp(prefix="javacompile-")
|
||
|
code_path = os.path.join(self.tempdir, "Entry.java")
|
||
|
shutil.copyfile(self.filename, code_path)
|
||
|
main_path = os.path.join(self.tempdir, "Main.java")
|
||
|
with open(main_path, "w") as f:
|
||
|
f.write(JavaWrapper.main)
|
||
|
print("Compiling Java file", self.filename)
|
||
|
if subprocess.run(["javac", code_path, main_path]).returncode != 0:
|
||
|
raise ValueError("compilation failed")
|
||
|
main_class_path = os.path.join(self.tempdir, "Main.class")
|
||
|
self.process = subprocess.Popen(["java", "-cp", self.tempdir, "Main"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||
|
return self
|
||
|
|
||
|
def __call__(self, s):
|
||
|
self.process.stdin.write(s.encode("ascii") + os.linesep.encode("ascii"))
|
||
|
self.process.stdin.flush()
|
||
|
return self.process.stdout.readline().decode("ascii")
|
||
|
def __repr__(self): return f"<wrapper for Java solution {self.filename}>"
|
||
|
def __exit__(self, type, value, traceback):
|
||
|
shutil.rmtree(self.tempdir)
|
||
|
self.process.kill()
|
||
|
|
||
|
def test(entry):
|
||
|
for _ in range(500):
|
||
|
s = "".join(chr(random.randint(32, 126)) for _ in range(random.randint(1, 256)))
|
||
|
answer = base64.b32encode(s.encode("ascii")).decode("ascii")
|
||
|
result = entry(s)
|
||
|
assert answer == result, f"test failed for {entry}: got {result}, should be {answer}, for {s}"
|
||
|
print(entry, "passed all tests")
|
||
|
|
||
|
import base32
|
||
|
test(base32.entry)
|