#!/usr/bin/env python
-def compile(e):
- pass
+import os.path
+import moe
+import moe.box
+import moe.eval
+import moe.util
+import moe.pipeline
+import moe.testcase
+import shutil
+
+def normalize_ext(e, ext):
+ alias = e["ALIAS_EXT_" + ext]
+ return alias if alias != "" else ext
+
+def try_ext(e, ext):
+ for e in e["EXTENSIONS"].split():
+ if e == ext:
+ return
+ raise moe.MoeError, "Unknown extension: " + ext
+
+def locate(e, filename=None):
+ e.log.progress("Locating source... ")
+ task = e["TASK"]
+ if filename is None:
+ dir = ""
+ file = task
+ else:
+ dir, file = os.path.split(filename)
+ if dir == "":
+ dir = e["SDIR"]
+
+ base, ext = os.path.splitext(file)
+ if ext != "":
+ if not os.path.exists(os.path.join(dir, file)):
+ raise moe.SolutionError, "No solution of %s called %s found" % (task,file)
+ ext = ext[1:]
+ try_ext(e, ext)
+ else:
+ found = []
+ for ext in e["EXTENSIONS"].split():
+ if os.path.exists(os.path.join(dir, base + "." + ext)):
+ found.append(ext)
+ if len(found) == 0:
+ raise moe.SolutionError, "No solution of %s found" % task
+ if len(found) > 1:
+ raise moe.SolutionError, "Multiple solutions of %s found" % task
+ ext = found[0]
+ file = base + "." + ext
+
+ orig_path = os.path.join(dir, file)
+ norm_ext = normalize_ext(e, ext)
+ e.log.verbose("Found solution %s\n" % orig_path)
+
+ copy = e["TASK"] + "." + norm_ext
+ copy_path = os.path.join(e["TDIR"], copy)
+ if file != copy:
+ e.log.verbose("Renaming to %s\n" % copy)
+ moe.util.link_or_copy(orig_path, copy_path)
+
+ e.builtins.set("SRC", copy)
+ e.builtins.set("EXT", norm_ext)
+ e.cfgs.apply_overrides("EXT_" + norm_ext + "_")
+
+ e.stat["source"] = file
+ e.stat["lang"] = ext
+ e.log.progress(file + "\n")
+
+def compile_init(e):
+ e.log.progress("Compiling... ")
+ boxdir = moe.box.setup(e)
+ pdir = e["PDIR"]
+ tdir = e["TDIR"]
+ shutil.copyfile(os.path.join(tdir, e["SRC"]), os.path.join(boxdir, e["SRC"]))
+ for x in e["EXTRAS"].split() + e["COMP_EXTRAS"].split():
+ xx = os.path.join(tdir, x)
+ if not os.path.isfile(xx):
+ xx = os.path.join(pdir, x)
+ e.log.verbose("Copying extra file %s\n" % xx)
+ shutil.copyfile(xx, os.path.join(boxdir, x))
+
+def compile_run(e):
+ moe.box.show(e, "compiler input")
+ cc = e["COMP"]
+ e.log.verbose("Compilation command: %s\n" % cc)
+ rc = moe.box.run(e, e["COMP_SANDBOX_OPTS"], cc)
+ if rc > 0:
+ e.log.progress("FAILED\n")
+ ## FIXME: status file ... or generate an exception?
+ raise moe.pipeline.MoeAbortPipeline(200)
+ moe.box.show(e, "compiler output")
+
+def compile_done(e):
+ try:
+ shutil.copyfile(os.path.join(e["BOXDIR"], e["EXE"]), os.path.join(e["TDIR"], e["EXE"]))
+ except IOError:
+ raise moe.MoeError, "Compiler succeeded, but produced no output"
+ e.log.progress("OK\n")
+
+def test_in(e):
+ tdir = e["TDIR"]
+ boxdir = moe.box.setup(e)
+ inn = e["TESTCASE_IN"]
+ in_type = e["IN_TYPE"] or e["IO_TYPE"]
+ out_type = e["OUT_TYPE"] or e["IO_TYPE"]
+ is_interactive = e["TASK_TYPE"] == "interactive"
+ sandbox_opts = "-M" + os.path.join(tdir, e["TESTCASE_STATUS"])
+
+ if not os.path.exists(os.path.join(tdir, e["EXE"])):
+ raise TestError("Compilation failed", "CE")
+ shutil.copyfile(os.path.join(tdir, e["EXE"]), os.path.join(boxdir, e["EXE"]))
+ os.chmod(os.path.join(boxdir, e["EXE"]), 0555)
+
+ if in_type == "file":
+ in_name = e["IN_NAME"]
+ e.log.verbose("Input file: %s (copied from %s)\n" % (in_name, os.path.join(e["PDIR"], inn)))
+ try:
+ shutil.copyfile(os.path.join(tdir, inn), os.path.join(boxdir, in_name))
+ except IOError:
+ raise moe.MoeError, "Input file not found"
+ if not is_interactive:
+ sandbox_opts += " -i/dev/null"
+ elif in_type == "stdio":
+ e.log.verbose("Input file: <stdin> (copied from %s)\n" % os.path.join(e["PDIR"], inn))
+ try:
+ shutil.copyfile(os.path.join(tdir, inn), os.path.join(boxdir, ".stdin"))
+ except IOError:
+ raise moe.MoeError, "Input file not found"
+ sandbox_opts += " -i.stdin"
+ elif in_type == "none":
+ e.log.verbose("Input file: <none>\n")
+ if not is_interactive:
+ sandbox_opts += " -i/dev/null"
+ elif in_type == "dir":
+ ## FIXME
+ raise MoeError, "Directory input not yet implemented"
+ else:
+ raise MoeError, "Unknown input type %s" % in_type
+
+ if out_type == "file":
+ out_name = e["OUT_NAME"]
+ e.log.verbose("Output file: %s\n" % out_name)
+ if not is_interactive:
+ sandbox_opts += " -o/dev/null"
+ elif out_type == "stdio":
+ e.log.verbose("Output file: <stdout>\n")
+ sandbox_opts += " -o.stdout"
+ elif out_type == "none":
+ e.log.verbose("Output file: <none>\n")
+ if not is_interactive:
+ sandbox_opts += " -o/dev/null"
+ else:
+ raise MoeError, "Unknown output type %s" % out_type
+
+ e.test_builtins.set("BOX_IO_OPTS", sandbox_opts)
+
+def test_run(e):
+ e.log.verbose("Time limit: %s s\n" % e["TIME_LIMIT"])
+ e.log.verbose("Memory limit: %s KB\n" % e["MEM_LIMIT"])
+ moe.box.show(e, "test input")
+ e.log.progress("<run> ")
+ rc = moe.box.run(e, e["TEST_SANDBOX_OPTS"], e["TEST_EXEC_CMD"])
+ moe.testcase.collect_status(e)
+ moe.box.show(e, "test output")
+ if rc > 0:
+ raise moe.TestError("Wrong answer", "WA")
+
+def test_collect(e):
+ tdir = e["TDIR"]
+ boxdir = e["BOXDIR"]
+ out_type = e["OUT_TYPE"] or e["IO_TYPE"]
+ is_interactive = e["TASK_TYPE"] == "interactive"
+
+ if out_type == "file":
+ out_path = e["OUT_NAME"]
+ elif out_type == "stdio":
+ out_path = ".stdout"
+ if not os.path.exists(os.path.join(boxdir, out_path)):
+ raise moe.TestError("No output file", "NO")
+ shutil.copyfile(os.path.join(boxdir, out_path), os.path.join(tdir, e["TESTCASE_OUT"]))
def tests(e):
- pass
+ e.log.progress("\n")
+ e.test_pipe.insert(100, "prepare", test_in)
+ e.test_pipe.insert(200, "run", test_run)
+ e.test_pipe.insert(300, "collect", test_collect)
+ moe.testcase.run_tests(e)
-def locate(e, file=None):
- pass
+def prepare_pipe(e):
+ e.main_pipe.insert(100, "compile-init", compile_init)
+ e.main_pipe.insert(150, "compile-run", compile_run)
+ e.main_pipe.insert(190, "compile-done", compile_done)
+ e.main_pipe.insert(200, "batch-tests", tests)