mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-15 06:54:04 +02:00
bitcmp/: little utility to find which bits differ between two files
This commit is contained in:
parent
db8c6d52d1
commit
08a13cd975
3
bitcmp/Makefile
Normal file
3
bitcmp/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
CFLAGS=-Wall
|
||||
|
||||
all: bitcmp
|
125
bitcmp/bitcmp.c
Normal file
125
bitcmp/bitcmp.c
Normal file
@ -0,0 +1,125 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
#define BUFFER 4096
|
||||
|
||||
|
||||
static int do_open(const char *name)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
|
||||
perror(name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s [-w|-l] [-B] file1 file2\n"
|
||||
" -w compare words (16 bits; default is bytes)\n"
|
||||
" -l compare long words (32 bits; default is bytes)\n"
|
||||
" -B use big-endian (default: little-endian)\n"
|
||||
, name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *const *argv)
|
||||
{
|
||||
int little = 1;
|
||||
int bytes = 1;
|
||||
int c;
|
||||
int fd1, fd2;
|
||||
const char *name1, *name2;
|
||||
uint8_t buf1[BUFFER], buf2[BUFFER];
|
||||
ssize_t got1, got2, len;
|
||||
uint32_t diff;
|
||||
int i, j;
|
||||
static unsigned bin[32];
|
||||
|
||||
while ((c = getopt(argc, argv, "Blw")) != EOF) {
|
||||
switch (c) {
|
||||
case 'B':
|
||||
little = 0;
|
||||
break;
|
||||
case 'l':
|
||||
bytes = 4;
|
||||
break;
|
||||
case 'w':
|
||||
bytes = 2;
|
||||
break;
|
||||
default:
|
||||
usage(*argv);
|
||||
}
|
||||
}
|
||||
if (argc-optind != 2)
|
||||
usage(*argv);
|
||||
|
||||
name1 = argv[optind];
|
||||
name2 = argv[optind+1];
|
||||
|
||||
fd1 = do_open(name1);
|
||||
fd2 = do_open(name2);
|
||||
|
||||
while (1) {
|
||||
memset(buf1, 0, BUFFER);
|
||||
memset(buf2, 0, BUFFER);
|
||||
got1 = read(fd1, buf1, BUFFER);
|
||||
if (got1 < 0) {
|
||||
perror(name1);
|
||||
return 1;
|
||||
}
|
||||
got2 = read(fd2, buf2, BUFFER);
|
||||
if (got2 < 0) {
|
||||
perror(name2);
|
||||
return 1;
|
||||
}
|
||||
if (got1 != got2)
|
||||
fprintf(stderr, "%s < %s\n",
|
||||
got1 < got2 ? name1 : name2,
|
||||
got1 < got2 ? name2 : name1);
|
||||
len = got1 < got2 ? got1 : got2;
|
||||
if (!len)
|
||||
break;
|
||||
for (i = 0; i <= len; i += bytes) {
|
||||
diff = 0;
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
diff |= (buf1[i+2] ^ buf2[i+2]) << 16;
|
||||
diff |= (buf1[i+3] ^ buf2[i+3]) << 24;
|
||||
/* fall through */
|
||||
case 2:
|
||||
diff |= (buf1[i+1] ^ buf2[i+1]) << 8;
|
||||
/* fall through */
|
||||
case 1:
|
||||
diff |= buf1[i] ^ buf2[i];
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
for (j = 0; j != 32; j++)
|
||||
if (diff & (1 << j))
|
||||
bin[j]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j != 8*bytes; j++) {
|
||||
if (little)
|
||||
i = j;
|
||||
else
|
||||
i = 8*(bytes-1-(j >> 3))+(j & 7);
|
||||
if (bin[i])
|
||||
printf("%2d: %u\n", j, bin[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user