rpn(1): handles errors when writing to stdout
This commit is contained in:
parent
232629f4d3
commit
cc53dab035
27
src/rpn.rs
27
src/rpn.rs
@ -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 {
|
|||||||
|
|
||||||
/* I’m no math nerd but I want the highest possible approximation of 0.9
|
/* I’m 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user