From 1f1ba3045ff1ec41e39c0e112924c36266553d06 Mon Sep 17 00:00:00 2001 From: xenofem Date: Wed, 26 Feb 2025 01:37:58 -0500 Subject: [PATCH 1/3] flake update --- flake.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 93ca65a..d515893 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1709675310, - "narHash": "sha256-w61tqFEmuJ+/1rAwU7nkYZ+dN6sLwyobfLwX2Yn42FE=", + "lastModified": 1740396192, + "narHash": "sha256-ATMHHrg3sG1KgpQA5x8I+zcYpp5Sf17FaFj/fN+8OoQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "43d259f8d726113fac056e8bb17d5ac2dea3e0a8", + "rev": "d9b69c3ec2a2e2e971c534065bdd53374bd68b97", "type": "github" }, "original": { @@ -42,11 +42,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1709126324, - "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { From a01fdc7de73f59f486e65d56ae80c7afe56f2062 Mon Sep 17 00:00:00 2001 From: xenofem Date: Wed, 26 Feb 2025 01:39:52 -0500 Subject: [PATCH 2/3] update clap crate --- Cargo.lock | 133 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54b001e..615e169 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -13,15 +13,16 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] @@ -46,17 +47,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys", + "once_cell", + "windows-sys 0.59.0", ] [[package]] @@ -67,9 +69,9 @@ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "clap" -version = "4.4.2" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -77,9 +79,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -89,9 +91,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", @@ -101,9 +103,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -128,6 +130,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "lazy_static" version = "1.4.0" @@ -140,6 +148,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + [[package]] name = "proc-macro2" version = "1.0.66" @@ -242,7 +256,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -251,13 +274,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -266,38 +305,86 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" From 9e62430e2d734477136c7ac542e560eefac842c4 Mon Sep 17 00:00:00 2001 From: xenofem Date: Wed, 26 Feb 2025 02:40:21 -0500 Subject: [PATCH 3/3] add more compact output to bytediff --- src/bin/bytediff.rs | 138 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 28 deletions(-) diff --git a/src/bin/bytediff.rs b/src/bin/bytediff.rs index e63c600..c865f98 100644 --- a/src/bin/bytediff.rs +++ b/src/bin/bytediff.rs @@ -1,7 +1,53 @@ use std::fs::File; use std::io::{prelude::*, BufReader}; +use std::path::PathBuf; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result}; +use clap::Parser; + +#[derive(Parser, Debug)] +#[clap(author, version)] +/// diff binary files +/// +/// bytediff checks whether binary files match, and prints out +/// a list of differences at the byte level if they don't. +struct Cli { + /// Print out a full hexdump of differing bytes, not just a summary of differences + #[arg(short, long)] + detailed: bool, + + /// First file to diff + #[arg(required = true)] + file1: PathBuf, + + /// Second file to diff + #[arg(required = true)] + file2: PathBuf, +} + +#[derive(PartialEq, Eq)] +enum DiffState { + Same, + DifferNonZero, + DifferAZero, + DifferBZero, +} + +fn is_byte_vec_zero(v: &[u8]) -> bool { + v.iter().all(|c| *c == 0u8) +} + +fn compare_byte_vecs(a: &[u8], b: &[u8]) -> DiffState { + if a == b { + DiffState::Same + } else if is_byte_vec_zero(a) { + DiffState::DifferAZero + } else if is_byte_vec_zero(b) { + DiffState::DifferBZero + } else { + DiffState::DifferNonZero + } +} struct ZipLonger { a: A, @@ -83,53 +129,89 @@ fn color_byte_display(this: &[u8], that: &[u8], color: u8) -> String { } fn main() -> Result<()> { - let mut args = std::env::args(); - let name = args - .next() - .ok_or_else(|| anyhow!("Missing executable name in args"))?; - let (a, b) = match (args.next(), args.next()) { - (Some(a), Some(b)) => (a, b), - _ => return Err(anyhow!("Usage: {} file file", name)), - }; + let cli = Cli::parse(); + + let a = cli.file1; + let b = cli.file2; let a_bytes = BufReader::new( - File::open(a.clone()).with_context(|| format!("Failed to open input file {}", a))?, + File::open(a.clone()) + .with_context(|| format!("Failed to open input file {}", a.display()))?, ) .bytes(); let b_bytes = BufReader::new( - File::open(b.clone()).with_context(|| format!("Failed to open input file {}", b))?, + File::open(b.clone()) + .with_context(|| format!("Failed to open input file {}", b.display()))?, ) .bytes(); - let mut in_differing_region = false; + let mut diff_state = DiffState::Same; + let mut region_start: usize = 0; for (i, (rva, rvb)) in ZipLonger::new(Chunks::new(a_bytes, 16), Chunks::new(b_bytes, 16)).enumerate() { let va: Vec = rva .transpose() - .with_context(|| format!("Error reading from input file {}", a))? + .with_context(|| format!("Error reading from input file {}", a.display()))? .unwrap_or_default(); let vb: Vec = rvb .transpose() - .with_context(|| format!("Error reading from input file {}", b))? + .with_context(|| format!("Error reading from input file {}", b.display()))? .unwrap_or_default(); - if va == vb { - if in_differing_region { - in_differing_region = false; - println!("---"); - } - continue; - } - in_differing_region = true; + let new_diff_state = compare_byte_vecs(&va, &vb); - println!( - "{0:08x}: {1}\n{0:08x}: {2}", - i * 16, - color_byte_display(&va, &vb, 31), - color_byte_display(&vb, &va, 32), - ); + if cli.detailed { + if new_diff_state == DiffState::Same { + if diff_state != DiffState::Same { + println!("---"); + } + } else { + println!( + "{0:08x}: {1}\n{0:08x}: {2}", + i * 16, + color_byte_display(&va, &vb, 31), + color_byte_display(&vb, &va, 32), + ); + } + } else { + if new_diff_state != diff_state { + if diff_state != DiffState::Same { + print!("{0:08x} to {1:08x}: ", region_start, i * 16); + } + match diff_state { + DiffState::Same => (), + DiffState::DifferAZero => { + println!("First file is zero bytes"); + } + DiffState::DifferBZero => { + println!("Second file is zero bytes"); + } + DiffState::DifferNonZero => { + println!("Files differ"); + } + } + region_start = i * 16; + } + } + diff_state = new_diff_state; + } + + match diff_state { + DiffState::Same => (), + DiffState::DifferAZero => { + println!("First file is zero bytes from {0:08x} to end", region_start); + } + DiffState::DifferBZero => { + println!( + "Second file is zero bytes from {0:08x} to end", + region_start + ); + } + DiffState::DifferNonZero => { + println!("Files differ from {0:08x} to end", region_start); + } } Ok(())