diff options
| author | Louis Burda <quent.burda@gmail.com> | 2023-01-29 01:49:01 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2023-01-29 01:49:01 +0100 |
| commit | 6e3ea85cccec28f645a3678d38d8532e3dedac56 (patch) | |
| tree | 313382d9f68dcab6daaba22c44047ce7f4cc6675 | |
| download | hexdiff-6e3ea85cccec28f645a3678d38d8532e3dedac56.tar.gz hexdiff-6e3ea85cccec28f645a3678d38d8532e3dedac56.zip | |
Initial version
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 19 | ||||
| -rw-r--r-- | hexdiff.c | 113 |
3 files changed, 133 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecc2344 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +hexdiff diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a85bee --- /dev/null +++ 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 new file mode 100644 index 0000000..1f34efc --- /dev/null +++ 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); +} |
