Root/bitcmp/bitcmp.c

Source at commit ebb0d2708b542ee20929375d9a22d37d86b100a5 created 5 years 9 months ago.
By Werner Almesberger, ircstat/README: change date format from MMYY to YYMM
1#include <stdint.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <string.h>
6#include <fcntl.h>
7
8
9#define BUFFER 4096
10
11
12static int do_open(const char *name)
13{
14    int fd;
15
16    fd = open(name, O_RDONLY);
17    if (fd >= 0)
18        return fd;
19
20    perror(name);
21    exit(1);
22}
23
24
25static void usage(const char *name)
26{
27    fprintf(stderr,
28"usage: %s [-w|-l] [-B] file1 file2\n"
29" -w compare words (16 bits; default is bytes)\n"
30" -l compare long words (32 bits; default is bytes)\n"
31" -B use big-endian (default: little-endian)\n"
32    , name);
33    exit(1);
34}
35
36
37int main(int argc, char *const *argv)
38{
39    int little = 1;
40    int bytes = 1;
41    int c;
42    int fd1, fd2;
43    const char *name1, *name2;
44    uint8_t buf1[BUFFER], buf2[BUFFER];
45    ssize_t got1, got2, len;
46    uint32_t a, b;
47    int i, j;
48    static unsigned bin[32][2];
49
50    while ((c = getopt(argc, argv, "Blw")) != EOF) {
51        switch (c) {
52        case 'B':
53            little = 0;
54            break;
55        case 'l':
56            bytes = 4;
57            break;
58        case 'w':
59            bytes = 2;
60            break;
61        default:
62            usage(*argv);
63        }
64    }
65    if (argc-optind != 2)
66        usage(*argv);
67
68    name1 = argv[optind];
69    name2 = argv[optind+1];
70
71    fd1 = do_open(name1);
72    fd2 = do_open(name2);
73
74    while (1) {
75        memset(buf1, 0, BUFFER);
76        memset(buf2, 0, BUFFER);
77        got1 = read(fd1, buf1, BUFFER);
78        if (got1 < 0) {
79            perror(name1);
80            return 1;
81        }
82        got2 = read(fd2, buf2, BUFFER);
83        if (got2 < 0) {
84            perror(name2);
85            return 1;
86        }
87        if (got1 != got2)
88            fprintf(stderr, "%s < %s\n",
89                got1 < got2 ? name1 : name2,
90                got1 < got2 ? name2 : name1);
91        len = got1 < got2 ? got1 : got2;
92        if (!len)
93            break;
94        for (i = 0; i < len; i += bytes) {
95            a = b = 0;
96            switch (bytes) {
97            case 4:
98                a |= buf1[i+2] << 16;
99                b |= buf2[i+2] << 16;
100                a |= buf1[i+3] << 24;
101                b |= buf2[i+3] << 24;
102                /* fall through */
103            case 2:
104                a |= buf1[i+1] << 8;
105                b |= buf2[i+1] << 8;
106                /* fall through */
107            case 1:
108                a |= buf1[i];
109                b |= buf2[i];
110                break;
111            default:
112                abort();
113            }
114            for (j = 0; j != 32; j++)
115                if ((a ^ b) & (1 << j))
116                    bin[j][(b >> j) & 1]++;
117        }
118    }
119
120    for (j = 0; j != 8*bytes; j++) {
121        if (little)
122            i = j;
123        else
124            i = 8*(bytes-1-(j >> 3))+(j & 7);
125        if (bin[i][0] || bin[i][1])
126            printf("%2d: %u %u\n", j, bin[i][0], bin[i][1]);
127    }
128    return 0;
129}
130

Archive Download this file

Branches:
master



interactive