From 5a9edf3f5ce3b5d050168df380d61dc9672f4212 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 4 Apr 2022 21:25:32 +0100 Subject: [PATCH] Added testing features for buffering output, and ignoring output errors. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for reverse's current commit: Curse − 凶 --- .gitignore | 5 +++++ Cargo.toml | 6 ++++++ src/main.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..846c168 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ /target + +perf.* +*.png +flamegraph.svg +vgcore.* diff --git a/Cargo.toml b/Cargo.toml index 49ec163..5b77d45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,12 @@ output-lines = [] # Print each string escaped output-quoted = [] +# Buffer output to conserve syscalls, useful for very large inputs (can cause higher memory usage, but generally speeds output up considerably) +buffer-output = [] + +# Do not attempt to handle output errors +ignore-output-errors = [] + [profile.release] opt-level = 3 lto = "fat" diff --git a/src/main.rs b/src/main.rs index 28b2b09..e71afe9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,27 +17,72 @@ fn binsearch<'a, V: ?Sized, T: PartialEq + 'a>(slice: &'a [T], find: &V) -> O { match slice { [ref a, pivot @ .., ref b] => { - match (a==find, b==find) { - (true, _) => Some(a), - (_, true) => Some(b), - _ => binsearch(pivot, find), - } + match (a==find, b==find) { + (true, _) => Some(a), + (_, true) => Some(b), + _ => binsearch(pivot, find), + } }, [ref a] if a == find => Some(a), _ => None, } } +fn collect_input() -> Box + 'static> +{ + if std::env::args_os().len() <= 1 { + use std::io::{ + self, + BufRead, + }; + // No args, collect stdin lines + Box::new(io::BufReader::new(io::stdin() + .lock()) + .lines() + .filter_map(Result::ok)) + } else { + // Has arguments, return them + Box::new(std::env::args().skip(1)) + } +} + +#[inline(always)] +fn handle_fmt_err(res: std::io::Result) +{ + #[cfg(not(feature="ignore-output-errors"))] + res.expect("[!] failed to write"); + let _ = res; +} + fn main() { - let mut args: Vec = std::env::args().skip(1).collect(); + let mut args: Vec = collect_input().collect(); reverse(&mut args[..]); //eprintln!("{:?}", binsearch(&args[..], "1")); // It works! #[cfg(feature="output-lines")] { + #[allow(unused_imports)] + use std::io::{ + Write, BufWriter, + }; + #[cfg(feature="buffer-output")] + let mut out = BufWriter::new(std::io::stdout().lock()); + #[cfg(not(feature="buffer-output"))] + let mut out = std::io::stdout().lock(); for x in args.iter() { - #[cfg(feature="output-quoted")] println!("{:?}", x); - #[cfg(not(feature="output-quoted"))] println!("{}", x); + handle_fmt_err({ + if cfg!(feature="output-quoted") { + writeln!(&mut out, "{:?}", x) + } + else { + //writeln!(&mut out, "{}", x) + out.write(x.as_bytes()) + .and_then(|_| out.write(b"\n")) + .map(|_| {}) + } + }); } + //#[cfg(feature="buffer-output")] + handle_fmt_err(out.flush()); } #[cfg(not(feature="output-lines"))] println!("{:?}", args);