diff --git a/src/swab.rs b/src/swab.rs index 5942c38..771d352 100644 --- a/src/swab.rs +++ b/src/swab.rs @@ -27,15 +27,12 @@ extern crate getopt; use getopt::GetOpt; extern crate sysexits; -use sysexits::{ EX_OK, EX_OSERR, EX_USAGE }; +use sysexits::{ EX_IOERR, EX_OK, EX_USAGE }; extern crate strerror; use strerror::StrError; -fn oserr(s: &str, e: Error) -> ExitCode { - eprintln!("{}: {}", s, e.strerror()); - ExitCode::from(EX_OSERR as u8) -} +fn err(s: &str, e: Error) { eprintln!("{}: {}", s, e.strerror()); } fn usage(s: &str) -> ExitCode { eprintln!("Usage: {} [-f] [-w word_size]", s); @@ -44,19 +41,20 @@ fn usage(s: &str) -> ExitCode { fn main() -> ExitCode { let argv = args().collect::>(); - let mut buf: Vec = Vec::new(); + let mut buf: Vec = Vec::new(); // holds the sequence getting swabbed let mut input = stdin(); let mut output = stdout().lock(); let mut force = false; - let mut wordsize: usize = 2; + let mut wordsize: usize = 2; // default; mimics dd(1p) conv=swab while let Some(opt) = argv.getopt("fw:") { match opt.opt() { Ok("f") => force = true, - Ok("w") => { + Ok("w") => { // sets new sequence length if let Some(arg) = opt.arg() { match arg.parse::() { + // an odd sequence length is nonsensical Ok(w) if w % 2 == 0 => { wordsize = w; () }, _ => { return usage(&argv[0]); }, } @@ -70,21 +68,28 @@ fn main() -> ExitCode { loop { match input.read(&mut buf) { - Ok(0) => break ExitCode::from(EX_OK as u8), - Ok(v) if v == wordsize => { + Ok(0) => break ExitCode::from(EX_OK as u8), // read nothing; bye + Ok(v) if v == wordsize => { // read full block; swab let (left, right) = buf.split_at(v/2); + if let Err(e) = output.write(&right) .and_then(|_| output.write(&left)) { - break oserr(&argv[0], e) + err(&argv[0], e); + break EX_IOERR // write error } + }, - Ok(v) => { + Ok(v) => { // partial read; partially write if let Err(e) = output.write(&buf[..v]) { - break oserr(&argv[0], e) + err(&argv[0], e); + break EX_IOERR // write error } }, Err(e) if e.kind() == ErrorKind::Interrupted && force => continue, - Err(e) => break oserr(&argv[0], e) + Err(e) => { + err(&argv[0], e); + break EX_IOERR // read error (or signal) + } } } }