Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add D support #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,117 @@ fn run_golang(context: &RunContext) -> Result<ExecResult> {
})
}

fn run_dlang(context: &RunContext) -> Result<ExecResult> {
let tmp_dir = tempfile::tempdir()?;

let mut output_path = tmp_dir.path().to_path_buf();
output_path.push("sol");

let mut res = Command::new("ldc2")
.args(vec![
"-O",
"-release",
"--of=",
output_path.to_str().unwrap(),
context.abs_solution().to_str().unwrap(),
])
.spawn()?;

match res.wait() {
Ok(status) => {
info!("Finished compilation of the target: {output_path:?} with exit code: {status}");
if let Some(code) = status.code() {
if code != 0 {
return Err(anyhow::anyhow!(
"Failed to compile solution file: none-zero exit code"
));
}
}
}
Err(e) => return Err(anyhow::anyhow!("Failed to compile solution file: {e:?}")),
}

let mut input_file = tmp_dir.path().to_path_buf();
input_file.push("input.txt");
let mut output_file = tmp_dir.path().to_path_buf();
output_file.push("output.txt");

info!(
"Symlinking file from: {:?} to {:?}",
context.input_file, input_file
);

std::os::unix::fs::symlink(context.input_file, &input_file)?;

let mut times = vec![];
for i in 0..context.times {
debug!("Starting execution #{i}");
let start_time = Instant::now();
let mut child = Command::new(output_path.to_str().unwrap())
.current_dir(&tmp_dir)
.spawn()?;

let pid = child.id();
debug!("The current started process has pid: {pid}");
move_to_cgroup(pid, context)?;
debug!(
"Moved process to cgroup {} successfully",
context.cgroup_path
);

match child.wait_timeout(context.timeout) {
Ok(Some(result)) => {
info!(
"Finished execution of the solution with status: {:?}",
result.code()
);
if let Some(code) = result.code() {
if code != 0 {
return Err(anyhow::anyhow!(
"Failed to run the solution file: none-zero exit code"
));
}
}
}
Ok(None) => {
debug!("Child process timed out");
child.kill().unwrap();
let code = child.wait()?.code();
debug!("Killed with exit code: {code:?}");
return Ok(ExecResult {
verdict: Verdict::Tle,
times,
});
}
Err(e) => {
return Err(anyhow::anyhow!("Failed to run the solution file: {e:?}"));
}
}

let elapsed = Instant::now() - start_time;
debug!("Execution #{i} finished in: {elapsed:?}");
times.push(elapsed);

debug!(
"Computing verdict using {output_file:?} and {:?}",
context.expected_output
);
let verdict = compute_verdict(&output_file, context.expected_output)?;
if !matches!(verdict, Verdict::Ac) {
debug!("Submission is not correct, aborting further runs");
return Ok(ExecResult {
verdict: Verdict::Wa,
times,
});
}
}

Ok(ExecResult {
verdict: Verdict::Ac,
times,
})
}

fn extract_language(context: &RunContext) -> String {
context
.solution_file
Expand Down Expand Up @@ -877,6 +988,7 @@ fn run_file(context: &RunContext) -> Result<ExecResult> {
"rs" => run_rust(context),
"php" => run_php(context),
"go" => run_golang(context),
"d" => run_dlang(context),
_ => Ok(ExecResult {
verdict: Verdict::UnknownExt,
times: vec![],
Expand Down