diff --git a/src/cmp.rs b/src/cmp.rs index 3ff716f..621904d 100644 --- a/src/cmp.rs +++ b/src/cmp.rs @@ -321,7 +321,10 @@ pub fn cmp(params: &Params) -> Result { return Ok(Cmp::Different); } - let smaller = cmp::min(a_size, b_size) as BytesLimitU64; + // The offsets count from the end of the skipped bytes. + let a_left = a_size.saturating_sub(params.skip_a.unwrap_or(0)); + let b_left = b_size.saturating_sub(params.skip_b.unwrap_or(0)); + let smaller = cmp::min(a_left, b_left) as BytesLimitU64; offset_width = cmp::min(smaller, offset_width); } diff --git a/tests/by-util/test_cmp.rs b/tests/by-util/test_cmp.rs index 0053a46..d6b48e5 100644 --- a/tests/by-util/test_cmp.rs +++ b/tests/by-util/test_cmp.rs @@ -31,6 +31,30 @@ fn cmp_verbose_zero_length_metadata() -> Result<(), Box> Ok(()) } +// The offset column is as wide as the bytes left after the skips, as in GNU +// cmp: 9 bytes are compared here, so the offsets take one column. +#[test] +fn cmp_verbose_offset_width_after_skip() -> Result<(), Box> { + let tmp_dir = tempdir()?; + let a_path = tmp_dir.path().join("a"); + let b_path = tmp_dir.path().join("b"); + File::create(&a_path)?.write_all(b"0123456789abcdefghijklmnopqrstuvwxyz")?; + File::create(&b_path)?.write_all(b"0123456789abcdefghijklmnopqrstuvwxyz")?; + + let mut cmd = cargo_bin_cmd!("diffutils"); + cmd.env("LC_ALL", "C"); + cmd.arg("cmp") + .arg("-l") + .arg("--ignore-initial=27:26") + .arg(&a_path) + .arg(&b_path); + cmd.assert() + .code(predicate::eq(1)) + .stdout(predicate::str::starts_with("1 162 161\n2 163 162\n")) + .stderr(predicate::str::ends_with(" after byte 9\n")); + Ok(()) +} + #[test] fn cmp_incompatible_params() -> Result<(), Box> { let mut cmd = cargo_bin_cmd!("diffutils");