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