diff --git a/.changes/judge-line.md b/.changes/judge-line.md new file mode 100644 index 0000000..e7244b5 --- /dev/null +++ b/.changes/judge-line.md @@ -0,0 +1,5 @@ +--- +"eval-stack": patch:feat +--- + +Judge outputs for each line of expected outputs. diff --git a/.cspell.json b/.cspell.json index f1b1b89..b3a38f6 100644 --- a/.cspell.json +++ b/.cspell.json @@ -14,6 +14,7 @@ "rlimit", "rustc", "rustup", + "serde", "setrlimit", "SIGBUS", "SIGILL", @@ -21,5 +22,8 @@ "statm", "sysconf", "unistd" + ], + "ignorePaths": [ + "Cargo.lock" ] } diff --git a/src/judge.rs b/src/judge.rs index b26907b..ae06d09 100644 --- a/src/judge.rs +++ b/src/judge.rs @@ -1,5 +1,10 @@ use std::{ - fs, future::Future, io::Read, os::unix::process::ExitStatusExt, path::PathBuf, task::Poll, + fs, + future::Future, + io::{BufRead, BufReader}, + os::unix::process::ExitStatusExt, + path::PathBuf, + task::Poll, time::Duration, }; @@ -51,18 +56,34 @@ impl Future for Judge { drop(self.child.stdin.take()); drop(self.child.stdout.take()); if status.success() { - let mut stdout = fs::File::open(&self.stdout_file)?; - let mut expected_out = fs::File::open(&self.expected_output_file)?; + let stdout = BufReader::new(fs::File::open(&self.stdout_file)?); + let expected_out = BufReader::new(fs::File::open(&self.expected_output_file)?); - let mut output = String::new(); - let mut expected_output = String::new(); - stdout.read_to_string(&mut output)?; - expected_out.read_to_string(&mut expected_output)?; - - if output.trim_end_matches(|c: char| c.is_whitespace() || c == '\n') - == expected_output - .trim_end_matches(|c: char| c.is_whitespace() || c == '\n') + let mut stdout_lines = stdout.lines(); + let mut expected_out_lines = expected_out.lines(); + let mut matched = true; + while let (Some(output), Some(expected_output)) = + (stdout_lines.next(), expected_out_lines.next()) { + if output?.trim_end_matches(|c: char| c.is_whitespace() || c == '\n') + != expected_output? + .trim_end_matches(|c: char| c.is_whitespace() || c == '\n') + { + matched = false; + break; + } + } + + while let Some(extra_line) = stdout_lines.next() { + if extra_line?.trim_end_matches(|c: char| c.is_whitespace() || c == '\n') + != "" + { + matched = false; + break; + } + } + + if matched { Poll::Ready(Ok(JudgeResult { status: JudgeStatus::Accepted, time_used: self.time_used, diff --git a/tests/test.cpp b/tests/test.cpp index 23d286a..d8e34e9 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -8,6 +8,6 @@ int main() { i64 a, b; cin >> a >> b; - cout << a + b << endl; + cout << a + b << endl << endl << endl; return 0; }