hexdiff

Highlighted diff for binary files
git clone https://git.sinitax.com/sinitax/hexdiff
Log | Files | Refs | LICENSE | sfeed.txt

commit 6e3ea85cccec28f645a3678d38d8532e3dedac56
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 29 Jan 2023 01:49:01 +0100

Initial version

Diffstat:
A.gitignore | 1+
AMakefile | 19+++++++++++++++++++
Ahexdiff.c | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +hexdiff diff --git a/Makefile b/Makefile @@ -0,0 +1,19 @@ +PREFIX ?= /usr/local +BINDIR ?= /bin + +CFLAGS = -O2 -g + +all: hexdiff + +clean: + rm -f hexdiff + +hexdiff: hexdiff.c + +install: + install -m755 hexdiff -t "$(DESTDIR)$(PREFIX)$(BINDIR)" + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)$(BINDIR)/hexdiff" + +.PHONY: all clean install uninstall diff --git a/hexdiff.c b/hexdiff.c @@ -0,0 +1,113 @@ +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> + +struct file { + const char *fname; + FILE *file; + uint8_t buf[16]; + size_t buflen; +}; + +const int equal_gradient[256] = { + [0] = 241, + [1 ... 31] = 242, + [32 ... 63] = 244, + [64 ... 95] = 246, + [96 ... 127] = 247, + [128 ... 159] = 248, + [160 ... 191] = 250, + [192 ... 223] = 252, + [224 ... 254] = 254, + [255] = 255, +}; + +const int diff_gradient[256] = { + [0] = 52, + [1 ... 95] = 88, + [96 ... 159] = 124, + [160 ... 223] = 160, + [224 ... 255] = 196, +}; + +bool use_color; +bool has_color; + +static inline void +color_byte(uint8_t b1, uint8_t b2) +{ + if (b1 != b2) + printf("\x1b[38:5:%um", diff_gradient[b1]); + else + printf("\x1b[38:5:%um", equal_gradient[b1]); + has_color = true; +} + +static inline void +color_clear(void) +{ + printf("\x1b[0m"); +} + +int +main(int argc, const char **argv) +{ + struct file f1, f2; + const char **arg; + size_t pos, i; + + memset(&f1, 0, sizeof(f1)); + memset(&f2, 0, sizeof(f2)); + + has_color = false; + use_color = true; + for (arg = &argv[1]; *arg; arg++) { + if (!strcmp(*arg, "-c")) { + use_color = true; + } else if (!strcmp(*arg, "-C")) { + use_color = false; + } else if (!f1.fname) { + f1.fname = *arg; + } else if (!f2.fname) { + f2.fname = *arg; + } else { + fprintf(stderr, "Usage: hexdiff [-c] FILE FILE\n"); + return 1; + } + } + + f1.file = fopen(f1.fname, "r"); + if (!f1.file) err(1, "fopen %s", f1.fname); + + f2.file = fopen(f2.fname, "r"); + if (!f2.file) err(1, "fopen %s", f2.fname); + + pos = 0; + while (!feof(f1.file) && !feof(f2.file)) { + f1.buflen = fread(f1.buf, 1, 16, f1.file); + f2.buflen = fread(f2.buf, 1, 16, f2.file); + if (!f1.buflen && !f2.buflen) break; + + printf("%06lx: ", pos); + for (i = 0; i < 16; i++) { + if (use_color) color_byte(f1.buf[i], f2.buf[i]); + printf("%02x ", f1.buf[i]); + if (has_color) color_clear(); + } + printf("| "); + for (i = 0; i < 16; i++) { + if (use_color) color_byte(f2.buf[i], f1.buf[i]); + printf("%02x ", f2.buf[i]); + if (has_color) color_clear(); + } + printf("\n"); + + pos += 16; + } + + fclose(f1.file); + fclose(f2.file); +}