00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef NUMERICFILECOMPARISON_HPP_
00029 #define NUMERICFILECOMPARISON_HPP_
00030
00031 #include "OutputFileHandler.hpp"
00032 #define A_WORD DBL_MAX
00033 #define NOTHING_TO_READ DBL_MIN
00034
00037 class NumericFileComparison
00038 {
00039 private:
00040 std::string mFilename1;
00041 std::string mFilename2;
00043 std::ifstream* mpFile1;
00044 std::ifstream* mpFile2;
00045 public:
00053 NumericFileComparison(std::string fileName1, std::string fileName2):
00054 mFilename1(fileName1),
00055 mFilename2(fileName2)
00056 {
00057 mpFile1 = new std::ifstream(fileName1.c_str());
00058
00059 if (!mpFile1->is_open())
00060 {
00061 mpFile1 = NULL;
00062 EXCEPTION("Couldn't open file: " + fileName1);
00063 }
00064
00065 mpFile2 = new std::ifstream(fileName2.c_str());
00066
00067 if (!mpFile2->is_open())
00068 {
00069 mpFile1->close();
00070 mpFile1 = NULL;
00071 mpFile2 = NULL;
00072 EXCEPTION("Couldn't open file: " + fileName2);
00073 }
00074 }
00078 ~NumericFileComparison()
00079 {
00080 if (mpFile1)
00081 {
00082 mpFile1->close();
00083 }
00084 if (mpFile2)
00085 {
00086 mpFile2->close();
00087 }
00088 delete mpFile1;
00089 delete mpFile2;
00090 }
00098 bool CompareFiles(double absTolerance=DBL_EPSILON, unsigned ignoreFirstFewLines=0)
00099 {
00100 double data1;
00101 double data2;
00102 unsigned failures = 0;
00103 double max_error = 0.0;
00104 unsigned max_failures = 10;
00105
00106 for (unsigned line_number=0; line_number<ignoreFirstFewLines; line_number++)
00107 {
00108 char buffer[1024];
00109 mpFile1->getline(buffer, 1024);
00110 mpFile2->getline(buffer, 1024);
00111 TS_ASSERT(!mpFile1->fail());
00112 TS_ASSERT(!mpFile2->fail());
00113 }
00114
00115 do
00116 {
00117 if (!(*mpFile1>>data1))
00118 {
00119
00120 std::string word;
00121 mpFile1->clear();
00122 if (*mpFile1>>word)
00123 {
00124 data1=A_WORD;
00125 if (word == "#" || word == "!")
00126 {
00127
00128 mpFile1->ignore(1024, '\n');
00129 }
00130 }
00131 else
00132 {
00133 mpFile1->clear();
00134 data1=NOTHING_TO_READ;
00135 }
00136 }
00137 if (!(*mpFile2>>data2))
00138 {
00139
00140 std::string word;
00141 mpFile2->clear();
00142 if (*mpFile2>>word)
00143 {
00144 data2=A_WORD;
00145 if (word == "#" || word == "!")
00146 {
00147
00148 mpFile2->ignore(1024, '\n');
00149 }
00150 }
00151 else
00152 {
00153 mpFile2->clear();
00154 data2=NOTHING_TO_READ;
00155 }
00156 }
00157
00158 double error = fabs(data1 - data2);
00159 if ( error > absTolerance )
00160 {
00161 failures++;
00162
00163 TS_ASSERT_DELTA(data1, data2, absTolerance);
00164 if (error > max_error)
00165 {
00166 max_error = error;
00167 }
00168 }
00169 if (failures > max_failures)
00170 {
00171 break;
00172 }
00173 }
00174 while (data1 != NOTHING_TO_READ && data2 != NOTHING_TO_READ);
00175
00176
00177 TS_ASSERT_LESS_THAN(max_error, absTolerance);
00178
00179 if (max_error >= absTolerance)
00180 {
00181 #define COVERAGE_IGNORE
00182
00183 TS_TRACE("Files " + mFilename1 + " and " + mFilename2 + " numerically differ.");
00184 #undef COVERAGE_IGNORE
00185 }
00186 return (failures==0);
00187 }
00188 };
00189
00190 #endif