diff --git a/src/od/od.rs b/src/od/od.rs index 48ee18b4e..779bd60e5 100644 --- a/src/od/od.rs +++ b/src/od/od.rs @@ -38,7 +38,7 @@ pub fn uumain(args: Vec) -> isize { specified."), "BYTES"), getopts::optflag("h", "help", "display this help and exit."), - getopts::optflag("v", "version", "output version information and exit."), + getopts::optflag("", "version", "output version information and exit."), ]; let matches = match getopts::getopts(args.tail(), &opts) { @@ -46,26 +46,22 @@ pub fn uumain(args: Vec) -> isize { Err(f) => panic!("Invalid options\n{}", f) }; - - let mut rad = Radix::Octal; - if matches.opt_present("A") { - rad = parse_radix(matches.opt_str("A")); - } else { - println!("{}", getopts::usage("od", &opts)); - } - - let mut fname; - match args.last() { - Some(n) => fname = n, - None => { panic!("Need fname for now") ; } + let input_offset_base = match parse_radix(matches.opt_str("A")) { + Ok(r) => r, + Err(f) => { panic!("Invalid -A/--address-radix\n{}", f) } }; - main(rad, fname.clone()); + let fname = match args.last() { + Some(n) => n, + None => { panic!("Need fname for now") ; } + }; + + main(&input_offset_base, fname.as_slice()); 0 } -fn main(radix: Radix, fname: String) { +fn main(input_offset_base: &Radix, fname: &str) { let mut f = match File::open(&Path::new(fname)) { Ok(f) => f, Err(e) => panic!("file error: {}", e) @@ -76,53 +72,55 @@ fn main(radix: Radix, fname: String) { loop { match f.read(bytes) { Ok(n) => { - print!("{:07o}", addr); - match radix { - Radix::Decimal => {}, - Radix::Octal => { - for b in range(0, n / std::u16::BYTES) { - let bs = &bytes[(2 * b) .. (2 * b + 2)]; - let p: u16 = (bs[1] as u16) << 8 | bs[0] as u16; - print!(" {:06o}", p); - } - if n % std::u16::BYTES == 1 { - print!(" {:06o}", bytes[n - 1]); - } - } - _ => { } - }; + print_with_radix(input_offset_base, addr); + for b in range(0, n / std::u16::BYTES) { + let bs = &bytes[(2 * b) .. (2 * b + 2)]; + let p: u16 = (bs[1] as u16) << 8 | bs[0] as u16; + print!(" {:06o}", p); + } + if n % std::u16::BYTES == 1 { + print!(" {:06o}", bytes[n - 1]); + } print!("\n"); addr += n; }, - Err(_) => { println!("{:07o}", addr); break; } + Err(_) => { + print_with_radix(input_offset_base, addr); + break; + } }; }; } -fn parse_radix(radix_str: Option) -> Radix { - let rad = match radix_str { +fn parse_radix(radix_str: Option) -> Result { + match radix_str { + None => Ok(Radix::Octal), Some(s) => { let st = s.into_bytes(); if st.len() != 1 { - panic!("Radix must be one of [d, o, b, x]\n"); - } - - let radix: char = *(st.get(0) - .expect("byte string of length 1 lacks a 0th elem")) as char; - if radix == 'd' { - Radix::Decimal - } else if radix == 'x' { - Radix::Hexadecimal - } else if radix == 'o' { - Radix::Octal - } else if radix == 'b' { - Radix::Binary + Err("Radix must be one of [d, o, b, x]\n") } else { - panic!("Radix must be one of [d, o, b, x]\n"); + let radix: char = *(st.get(0) + .expect("byte string of length 1 lacks a 0th elem")) as char; + match radix { + 'd' => Ok(Radix::Decimal), + 'x' => Ok(Radix::Hexadecimal), + 'o' => Ok(Radix::Octal), + 'b' => Ok(Radix::Binary), + _ => Err("Radix must be one of [d, o, b, x]\n") + } } - }, - None => Radix::Octal - }; - - rad + } + } +} + +fn print_with_radix(r: &Radix, x: usize) { + // TODO(keunwoo): field widths should be based on sizeof(x), or chosen dynamically based on the + // expected range of address values. Binary in particular is not great here. + match *r { + Radix::Decimal => print!("{:07}", x), + Radix::Hexadecimal => print!("{:07X}", x), + Radix::Octal => print!("{:07o}", x), + Radix::Binary => print!("{:07b}", x) + } }