1 #include <libgen.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <limits.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <ctype.h>
9 #include <string>
10 #include <map>
11 #include <iostream>
12 #include <istream>
13 #include <fstream>
14 #include <ostream>
15 #include <sstream>
16 #include <math.h>
17 #include <algorithm>
18 #include <cfenv>
19 #include <cmath>
20 #include <cfloat>
21 #include <stdlib.h>
22
23 static int gResult = 0;
24 static int gError = 0;
25
26 using namespace std;
27
isopt(char * argv[],const char * name)28 static bool isopt(char* argv[], const char* name)
29 {
30 for (int i = 0; argv[i]; i++) if (!strcmp(argv[i], name)) return true;
31 return false;
32 }
33
compareFiles(istream * in1,istream * in2,double tolerance,bool is_part)34 static bool compareFiles(istream* in1, istream* in2, double tolerance, bool is_part)
35 {
36 string line1, line2, dummy;
37 int input1, input2, output1, output2, count1, count2;
38
39 // Read inputs
40 {
41 getline(*in1, line1);
42 getline(*in2, line2);
43
44 if ((in1->rdstate() & ifstream::eofbit)) {
45 return false;
46 }
47
48 if ((in2->rdstate() & ifstream::eofbit)) {
49 return false;
50 }
51
52 stringstream l1reader(line1);
53 stringstream l2reader(line2);
54
55 // Ignore "number_of_inputs" and ":" tokens
56 l1reader >> dummy; l1reader >> dummy;
57 l2reader >> dummy; l2reader >> dummy;
58
59 l1reader >> input1;
60 l2reader >> input2;
61
62 if (input1 != input2) {
63 cerr << "input1 : " << input1 << " different from input2 : " << input2 << endl;
64 gResult = 1;
65 exit(gResult);
66 }
67 }
68
69 // Read outputs
70 {
71 getline(*in1, line1);
72 getline(*in2, line2);
73
74 if ((in1->rdstate() & ifstream::eofbit)) {
75 return false;
76 }
77
78 if ((in2->rdstate() & ifstream::eofbit)) {
79 return false;
80 }
81
82 stringstream l1reader(line1);
83 stringstream l2reader(line2);
84
85 // Ignore "number_of_outputs" and ":" tokens
86 l1reader >> dummy; l1reader >> dummy;
87 l2reader >> dummy; l2reader >> dummy;
88
89 l1reader >> output1;
90 l2reader >> output2;
91
92 if (output1 != output2) {
93 cerr << "output1 : " << output1 << " different from output2 : " << output2 << endl;
94 gResult = 1;
95 exit(gResult);
96 }
97 }
98
99 // Read count
100 {
101 getline(*in1, line1);
102 getline(*in2, line2);
103
104 if ((in1->rdstate() & ifstream::eofbit)) {
105 return false;
106 }
107
108 if ((in2->rdstate() & ifstream::eofbit)) {
109 return false;
110 }
111
112 stringstream l1reader(line1);
113 stringstream l2reader(line2);
114
115 // Ignore "line_num" and ":" tokens
116 l1reader >> dummy; l1reader >> dummy;
117 l2reader >> dummy; l2reader >> dummy;
118
119 l1reader >> count1;
120 l2reader >> count2;
121
122 if ((count1 != count2) && !is_part) {
123 cerr << "count1 : " << count1 << " different from count2 : " << count2 << endl;
124 gResult = 1;
125 exit(gResult);
126 }
127 }
128
129 // Compare samples
130 for (int i = 0; i < count1; i++) {
131
132 getline(*in1, line1);
133 getline(*in2, line2);
134
135 if ((in1->rdstate() & ifstream::eofbit)) {
136 return false;
137 }
138
139 if ((in2->rdstate() & ifstream::eofbit)) {
140 return false;
141 }
142
143 stringstream l1reader(line1);
144 stringstream l2reader(line2);
145
146 // Keep line_num and ignore ":" tokens
147 string line_num1, line_num2;
148 l1reader >> line_num1; l1reader >> dummy;
149 l2reader >> line_num2; l2reader >> dummy;
150
151 double sample1, sample2;
152
153 for (int j = 0; j < output1; j++) {
154
155 l1reader >> sample1;
156 l2reader >> sample2;
157 double delta = fabs(sample1 - sample2);
158
159 if (delta > tolerance) {
160
161 cerr << "Line : " << line_num1 << " output : " << j << " sample1 : " << sample1 << " different from sample2 : " << sample2 << " delta : " << delta << endl;
162 gResult = 1;
163 if (gError++ > 10) {
164 cerr << "Too much errors, stops..." << endl;
165 exit(gResult);
166 }
167 }
168 }
169 }
170 return true;
171 }
172
main(int argc,char * argv[])173 int main(int argc, char* argv[])
174 {
175 double tolerance = 2e-06;
176 if (argc == 4) {
177 double param = strtod(argv[3], NULL);
178 // -1 value used to take default value
179 tolerance = (param > 0) ? param : tolerance;
180 }
181
182 // Possibly only compare a subpart of the reference file, starting from the beginning
183 bool is_part = isopt(argv, "-part");
184
185 // Test files may have several consecutive impulse responses, test all of them in sequence with the same reference
186 ifstream test(argv[1]);
187 bool compare = false;
188 do {
189 ifstream reference(argv[2]);
190 compare = compareFiles(&test, &reference, tolerance, is_part);
191 } while (compare);
192
193 exit(gResult);
194 }
195