mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
od: implement -w (width)
This commit is contained in:
parent
1b01f02e9e
commit
167d7d3ca9
4 changed files with 78 additions and 8 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -667,6 +667,7 @@ dependencies = [
|
||||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unindent 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unindent 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"uucore 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -12,6 +12,7 @@ getopts = "*"
|
||||||
libc = "*"
|
libc = "*"
|
||||||
unindent = "*"
|
unindent = "*"
|
||||||
byteorder = "*"
|
byteorder = "*"
|
||||||
|
uucore = { path="../uucore" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "od"
|
name = "od"
|
||||||
|
|
31
src/od/od.rs
31
src/od/od.rs
|
@ -13,12 +13,16 @@ extern crate getopts;
|
||||||
extern crate unindent;
|
extern crate unindent;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate uucore;
|
||||||
|
|
||||||
mod multifilereader;
|
mod multifilereader;
|
||||||
mod prn_int;
|
mod prn_int;
|
||||||
mod prn_char;
|
mod prn_char;
|
||||||
mod prn_float;
|
mod prn_float;
|
||||||
|
|
||||||
use std::f64;
|
use std::cmp;
|
||||||
|
use std::io::Write;
|
||||||
use unindent::*;
|
use unindent::*;
|
||||||
use byteorder::*;
|
use byteorder::*;
|
||||||
use multifilereader::*;
|
use multifilereader::*;
|
||||||
|
@ -73,7 +77,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
|
|
||||||
opts.optopt("t", "format", "select output format or formats", "TYPE");
|
opts.optopt("t", "format", "select output format or formats", "TYPE");
|
||||||
opts.optflag("v", "output-duplicates", "do not use * to mark line suppression");
|
opts.optflag("v", "output-duplicates", "do not use * to mark line suppression");
|
||||||
opts.optopt("w", "width",
|
opts.optflagopt("w", "width",
|
||||||
("output BYTES bytes per output line. 32 is implied when BYTES is not \
|
("output BYTES bytes per output line. 32 is implied when BYTES is not \
|
||||||
specified."),
|
specified."),
|
||||||
"BYTES");
|
"BYTES");
|
||||||
|
@ -209,23 +213,36 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
formats.push(mkfmt(2, &oct)); // 2 byte octal is the default
|
formats.push(mkfmt(2, &oct)); // 2 byte octal is the default
|
||||||
}
|
}
|
||||||
|
|
||||||
odfunc(&input_offset_base, &inputs, &formats[..])
|
let mut line_bytes = match matches.opt_default("w", "32") {
|
||||||
|
None => 16,
|
||||||
|
Some(s) => {
|
||||||
|
match s.parse::<usize>() {
|
||||||
|
Ok(i) => { i }
|
||||||
|
Err(_) => { 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let min_bytes = formats.iter().fold(2, |max, next| cmp::max(max, next.itembytes));
|
||||||
|
if line_bytes % min_bytes != 0 {
|
||||||
|
show_warning!("invalid width {}; using {} instead", line_bytes, min_bytes);
|
||||||
|
line_bytes = min_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINEBYTES:usize = 16;
|
odfunc(line_bytes, &input_offset_base, &inputs, &formats[..])
|
||||||
|
}
|
||||||
|
|
||||||
fn odfunc(input_offset_base: &Radix, fnames: &[InputSource], formats: &[OdFormat]) -> i32 {
|
fn odfunc(line_bytes: usize, input_offset_base: &Radix, fnames: &[InputSource], formats: &[OdFormat]) -> i32 {
|
||||||
|
|
||||||
let mut mf = MultifileReader::new(fnames);
|
let mut mf = MultifileReader::new(fnames);
|
||||||
let mut addr = 0;
|
let mut addr = 0;
|
||||||
let bytes = &mut [b'\x00'; LINEBYTES];
|
let mut bytes: Vec<u8> = vec![b'\x00'; line_bytes];
|
||||||
loop {
|
loop {
|
||||||
// print each line data (or multi-format raster of several lines describing the same data).
|
// print each line data (or multi-format raster of several lines describing the same data).
|
||||||
|
|
||||||
print_with_radix(input_offset_base, addr); // print offset
|
print_with_radix(input_offset_base, addr); // print offset
|
||||||
// if printing in multiple formats offset is printed only once
|
// if printing in multiple formats offset is printed only once
|
||||||
|
|
||||||
match mf.f_read(bytes) {
|
match mf.f_read(bytes.as_mut_slice()) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
print!("\n");
|
print!("\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -223,3 +223,54 @@ fn mit_die_umlauten_getesten() {
|
||||||
"0000000 U n i v e r s i t ä ** t T ü **\n0000020 b i n g e n\n0000026")
|
"0000000 U n i v e r s i t ä ** t T ü **\n0000020 b i n g e n\n0000026")
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_width(){
|
||||||
|
|
||||||
|
let input : [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||||
|
let expected_output = unindent("
|
||||||
|
0000000 000000 000000
|
||||||
|
0000004 000000 000000
|
||||||
|
0000010
|
||||||
|
");
|
||||||
|
|
||||||
|
let result = new_ucmd!().arg("-w4").run_piped_stdin(&input[..]);
|
||||||
|
|
||||||
|
assert_empty_stderr!(result);
|
||||||
|
assert!(result.success);
|
||||||
|
assert_eq!(result.stdout, expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_width(){
|
||||||
|
|
||||||
|
let input : [u8; 4] = [0x00, 0x00, 0x00, 0x00];
|
||||||
|
let expected_output = unindent("
|
||||||
|
0000000 000000
|
||||||
|
0000002 000000
|
||||||
|
0000004
|
||||||
|
");
|
||||||
|
|
||||||
|
let result = new_ucmd!().arg("-w5").run_piped_stdin(&input[..]);
|
||||||
|
|
||||||
|
assert_eq!(result.stderr, "od: warning: invalid width 5; using 2 instead\n");
|
||||||
|
assert!(result.success);
|
||||||
|
assert_eq!(result.stdout, expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_width_without_value(){
|
||||||
|
|
||||||
|
let input : [u8; 40] = [0 ; 40];
|
||||||
|
let expected_output = unindent("
|
||||||
|
0000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000
|
||||||
|
0000040 000000 000000 000000 000000
|
||||||
|
0000050
|
||||||
|
");
|
||||||
|
|
||||||
|
let result = new_ucmd!().arg("-w").run_piped_stdin(&input[..]);
|
||||||
|
|
||||||
|
assert_empty_stderr!(result);
|
||||||
|
assert!(result.success);
|
||||||
|
assert_eq!(result.stdout, expected_output);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue