NumericFileComparison.hpp
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 <cfloat>
00032 #include <string>
00033
00034 #include "OutputFileHandler.hpp"
00035 #include "MathsCustomFunctions.hpp"
00036
00037 #define A_WORD DBL_MAX
00038 #define NOTHING_TO_READ DBL_MIN
00039
00043 class NumericFileComparison
00044 {
00045 private:
00046
00047 std::string mFilename1;
00048 std::string mFilename2;
00050 std::ifstream* mpFile1;
00051 std::ifstream* mpFile2;
00053 public:
00054
00062 NumericFileComparison(std::string fileName1, std::string fileName2):
00063 mFilename1(fileName1),
00064 mFilename2(fileName2)
00065 {
00066 mpFile1 = new std::ifstream(fileName1.c_str());
00067
00068
00069 if (!mpFile1->is_open())
00070 {
00071 delete mpFile1;
00072 mpFile1 = NULL;
00073 EXCEPTION("Couldn't open file: " + fileName1);
00074 }
00075
00076 mpFile2 = new std::ifstream(fileName2.c_str());
00077
00078
00079 if (!mpFile2->is_open())
00080 {
00081 mpFile1->close();
00082 delete mpFile1;
00083 mpFile1 = NULL;
00084 delete mpFile2;
00085 mpFile2 = NULL;
00086 EXCEPTION("Couldn't open file: " + fileName2);
00087 }
00088 }
00089
00093 ~NumericFileComparison()
00094 {
00095 if (mpFile1)
00096 {
00097 mpFile1->close();
00098 }
00099 if (mpFile2)
00100 {
00101 mpFile2->close();
00102 }
00103 delete mpFile1;
00104 delete mpFile2;
00105 }
00106
00116 bool CompareFiles(double absTol=DBL_EPSILON, unsigned ignoreFirstFewLines=0,
00117 double relTol=DBL_EPSILON)
00118 {
00119 double data1;
00120 double data2;
00121 unsigned failures = 0;
00122 unsigned max_display_failures = 10;
00123
00124 for (unsigned line_number=0; line_number<ignoreFirstFewLines; line_number++)
00125 {
00126 char buffer[1024];
00127 mpFile1->getline(buffer, 1024);
00128 mpFile2->getline(buffer, 1024);
00129 TS_ASSERT(!mpFile1->fail());
00130 TS_ASSERT(!mpFile2->fail());
00131 }
00132
00133 do
00134 {
00135 if (!(*mpFile1>>data1))
00136 {
00137
00138 std::string word;
00139 mpFile1->clear();
00140 if (*mpFile1 >> word)
00141 {
00142 data1 = A_WORD;
00143 if (word == "#" || word == "!")
00144 {
00145
00146 mpFile1->ignore(1024, '\n');
00147 }
00148 }
00149 else
00150 {
00151 mpFile1->clear();
00152 data1 = NOTHING_TO_READ;
00153 }
00154 }
00155 if (!(*mpFile2 >> data2))
00156 {
00157
00158 std::string word;
00159 mpFile2->clear();
00160 if (*mpFile2 >> word)
00161 {
00162 data2 = A_WORD;
00163 if (word == "#" || word == "!")
00164 {
00165
00166 mpFile2->ignore(1024, '\n');
00167 }
00168 }
00169 else
00170 {
00171 mpFile2->clear();
00172 data2 = NOTHING_TO_READ;
00173 }
00174 }
00175
00176 bool ok = CompareDoubles::WithinAnyTolerance(data1, data2, relTol, absTol);
00177 if (!ok)
00178 {
00179 if (failures++ < max_display_failures)
00180 {
00181
00182 CompareDoubles::WithinAnyTolerance(data1, data2, relTol, absTol, true);
00183 }
00184 }
00185 }
00186 while (data1 != NOTHING_TO_READ && data2 != NOTHING_TO_READ);
00187
00188
00189 TS_ASSERT_EQUALS(failures, 0u);
00190
00191 if (failures > 0u)
00192 {
00193 #define COVERAGE_IGNORE
00194
00195 TS_TRACE("Files " + mFilename1 + " and " + mFilename2 + " numerically differ.");
00196 #undef COVERAGE_IGNORE
00197 }
00198 return (failures==0);
00199 }
00200 };
00201
00202 #endif