From df50f26dc2a287369ce029b2ffc63806edc263d4 Mon Sep 17 00:00:00 2001 From: Jay Hemnani <193022578+jayhemnani9910@users.noreply.github.com> Date: Mon, 26 Oct 2026 00:36:24 +0530 Subject: [PATCH] cmp: size the -l offset column from the bytes left after the skips The offsets count from the end of the skipped bytes, so the widest one is the smaller file size minus its skip, as GNU cmp computes it. --- src/cmp.rs | 5 ++++- tests/by-util/test_cmp.rs | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) 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");