rpn(1): handles errors when writing to stdout

This commit is contained in:
Emma Tebibyte 2024-08-24 18:18:27 -06:00
parent 232629f4d3
commit cc53dab035
Signed by: emma
GPG Key ID: 06FA419A1698C270

View File

@ -46,7 +46,7 @@ use std::{
collections::VecDeque, collections::VecDeque,
env::args, env::args,
fmt::{ self, Display, Formatter }, fmt::{ self, Display, Formatter },
io::stdin, io::{ Error, Write, stdin, stdout },
process::ExitCode, process::ExitCode,
}; };
@ -125,7 +125,7 @@ struct EvaluationError {
/* Im no math nerd but I want the highest possible approximation of 0.9 /* Im no math nerd but I want the highest possible approximation of 0.9
* repeating and it seems this can give it to me */ * repeating and it seems this can give it to me */
const PRECISION_MOD: f64 = 0.9 + f64::EPSILON * 100.0; const PRECISION_MOD: f64 = 0.9 + f64::EPSILON;
fn err(argv0: &String, e: std::io::Error, code: Option<u8>) -> ExitCode { fn err(argv0: &String, e: std::io::Error, code: Option<u8>) -> ExitCode {
eprintln!("{}: {}", argv0, e.strerror()); eprintln!("{}: {}", argv0, e.strerror());
@ -204,16 +204,16 @@ fn round_precise(value: &f64) -> f64 {
(value * multiplier).round() / multiplier (value * multiplier).round() / multiplier
} }
fn unstack(stack: VecDeque<f64>, op: bool) -> bool { fn unstack(stack: VecDeque<f64>, op: bool) -> Result<bool, Error> {
if let Some(val) = stack.iter().last() { if let Some(val) = stack.iter().last() {
if !op { return true; } if !op { return Ok(true); }
println!("{}", round_precise(val).to_string()); let out = round_precise(val).to_string() + &'\n'.to_string();
return stdout().write_all(out.as_bytes()).map(|_| true);
} else { } else {
return false; return Ok(false);
} }
return true;
} }
fn main() -> ExitCode { fn main() -> ExitCode {
@ -240,7 +240,9 @@ fn main() -> ExitCode {
match eval(&input, stack) { match eval(&input, stack) {
Ok(s) => { Ok(s) => {
let _ = unstack(s.0.clone(), s.1.clone()); if let Err(e) = unstack(s.0.clone(), s.1.clone()) {
return err(&argv[0], e, Some(EX_IOERR));
}
return ExitCode::SUCCESS; return ExitCode::SUCCESS;
} }
Err(e) => { Err(e) => {
@ -261,8 +263,11 @@ fn main() -> ExitCode {
buf.clear(); buf.clear();
stack = s.0.clone(); stack = s.0.clone();
if unstack(s.0, s.1) { continue; } match unstack(s.0, s.1) {
else { break; } Ok(b) if b => continue,
Ok(_) => break,
Err(e) => return err(&argv[0], e, Some(EX_IOERR)),
};
}, },
Err(e) => { Err(e) => {
eprintln!("{}: {}", argv[0], e.message); eprintln!("{}: {}", argv[0], e.message);