1 /* compare ints - a test utility */
2
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <getopt.h>
7 #include <errno.h>
8 #include <inttypes.h>
9
10 /* Declarations */
11
12 /* Globals */
13
14 /* Functions */
get_data(FILE * f,int64_t * dd,int signed_flag,int bytes)15 int get_data(FILE *f, int64_t *dd, int signed_flag, int bytes) {
16 int res;
17 int8_t d_8;
18 int16_t d_16;
19 uint8_t d_u8;
20 uint16_t d_u16;
21 // TODO Loop on reads until, but catch EOF!!
22 if (signed_flag) {
23 switch (bytes) {
24 case 1:
25 res = fread(&d_8, bytes, 1, f);
26 *dd = d_8;
27 break;
28 case 2:
29 res = fread(&d_16, bytes, 1, f);
30 *dd = d_16;
31 break;
32 default:
33 fprintf(stderr, "Error: unsupported size %d bytes\n", bytes);
34 exit(1);
35 }
36 }
37 else { // unsigned
38 switch (bytes) {
39 case 1:
40 res = fread(&d_u8, bytes, 1, f);
41 *dd = d_u8;
42 break;
43 case 2:
44 res = fread(&d_u16, bytes, 1, f);
45 *dd = d_u16;
46 break;
47 default:
48 fprintf(stderr, "Error: unsupported size %d bytes\n", bytes);
49 exit(1);
50 }
51 }
52
53 if (res != 1) return(0);
54 else return(1);
55 }
56
57
58 /* Main */
59
main(int argc,char * argv[])60 int main(int argc, char *argv[]) {
61
62 char usage[] = "Usage: %s [-b size_in_bytes] [-c] [-s] [-t tolerance] [-n numerrorstoexit] file1 file2\n";
63
64 int bytes = 1;
65 int count_errors = 0;
66 int signed_flag = 0;
67 int tol = 1;
68 int numerrorstoexit = -1;
69
70 int opt;
71 while ((opt = getopt(argc, argv, "b:cst:n:")) != -1) {
72 switch (opt) {
73 case 'b':
74 bytes = atoi(optarg);
75 break;
76 case 'c':
77 count_errors = 1;
78 break;
79 case 's':
80 signed_flag = 1;
81 break;
82 case 'n':
83 numerrorstoexit = atoi(optarg);
84 break;
85 case 't':
86 tol = atof(optarg);
87 break;
88 default:
89 fprintf(stderr, usage, argv[0]);
90 exit(1);
91 }
92 }
93
94 if ((optind + 2) > argc) {
95 fprintf(stderr, usage, argv[0]);
96 exit(1);
97 }
98 char *fname1 = argv[optind++];
99 char *fname2 = argv[optind++];
100
101 FILE *f1 = fopen(fname1, "rb");
102 if (f1 == NULL) {
103 fprintf(stderr, "Error opening file1 \"%s\": ", fname1);
104 perror(NULL);
105 exit(1);
106 }
107
108 FILE *f2 = fopen(fname2, "rb");
109 if (f2 == NULL) {
110 fprintf(stderr, "Error opening file2 \"%s\": ", fname2);
111 perror(NULL);
112 exit(1);
113 }
114
115 // Convert inputs to SIGNED long values
116 int64_t data1, data2;
117
118 int count = 0;
119 int errors = 0;
120 int rms_sum = 0;
121
122 while (get_data(f1, &data1, signed_flag, bytes)) {
123 if (!get_data(f2, &data2, signed_flag, bytes)) {
124 fprintf(stderr, "Error: file2 is shorter\n");
125 exit(1);
126 }
127 uint64_t err = llabs(data1 - data2);
128 if (err > tol) {
129 errors ++;
130 printf("%d %" PRId64 " %" PRId64 "\n", count, data1, data2);
131 if (numerrorstoexit != -1)
132 if (errors > numerrorstoexit) {
133 printf("reached errors: %d, bailing!", numerrorstoexit);
134 exit(1);
135 }
136 }
137 rms_sum += (err * err);
138 count ++;
139 }
140 if (get_data(f2, &data2, signed_flag, bytes)) {
141 fprintf(stderr, "Error: file1 is shorter\n");
142 exit(1);
143 }
144
145 if (count_errors) exit(errors);
146 else {
147 if (errors) {
148 printf("Fail: %d errors\n", errors);
149 printf(" rms error = %f\n", ((double)rms_sum/count));
150 exit(1);
151 }
152 else printf("Pass\n");
153 exit(0);
154 }
155
156 } // main
157
158
159 /* vi:set ts=4 et sts=4: */
160