61 "Differences two input files while allowing small differences"
62 " in floating point values."),
81 double v = strtod(s.c_str(), &p);
92 input1Option(
'1',
"input1",
"First file to take the input from.",
true),
93 input2Option(
'2',
"input2",
"Second file to take the input from.",
true),
94 lineSkipOption(
'l',
"lines",
"Number of lines to skip at beginning of file."),
95 epsilonOption(
'e',
"epsilon",
"Percent allowable difference in floating point values."),
96 outputOption(
'o',
"output",
"A file to receive the output. The default is stdout."),
97 regexOption(
'X',
"regexclude",
"Exclude lines matching a regular"
99 igregOption(
'I',
"ign-reg",
"Ignore column X (starting with 0) on"
100 " lines matching regular expression Y, ARG=X,Y"),
101 lastLineOption(
'z',
"last",
"ignore the last X lines of the file");
106 input1Fn = input1Option.getValue()[0];
107 input2Fn = input2Option.getValue()[0];
109 input1.open(input1Fn.c_str(), istringstream::in);
110 input2.open(input2Fn.c_str(), istringstream::in);
114 cerr <<
"Could not open: " << input1Fn << endl;
121 cerr <<
"Could not open: " << input2Fn << endl;
128 while (getline(input1, line))
132 cout <<
"File 1 has " << totalLines <<
" lines" << endl;
138 totalLines = totalLines - lastlineValue;
142 input1.seekg(0,ios::beg);
144 if (outputOption.getCount())
145 outputFn = outputOption.getValue()[0];
147 if (outputFn==
"-" || outputFn==
"")
149 output.copyfmt(cout);
150 output.clear(cout.rdstate());
151 output.ios::rdbuf(cout.rdbuf());
152 outputFn =
"<stdout>";
156 output.open(outputFn.c_str(), ios::out);
161 cerr <<
"Could not open: " << outputFn << endl;
166 if (epsilonOption.getCount())
169 if (lineSkipOption.getCount())
172 if (regexOption.getCount())
173 regexclude = regexOption.getValue();
175 if (igregOption.getCount())
177 vector<string> igvec(igregOption.getValue());
178 for (
unsigned i = 0; i < igvec.size(); i++)
182 cerr <<
"Invalid spec \"" << igvec[i]
183 <<
"\", expecting column,regex" << endl;
190 cerr <<
"Invalid spec \"" << igvec[i]
191 <<
"\", expecting column,regex" << endl;
203 output <<
"First file " << input1Fn << endl
204 <<
"Second file " << input2Fn << endl
205 <<
"Output file " << outputFn << endl
206 <<
"Epsilon " << epsilon << endl
207 <<
"Skipping " << linesToSkip <<
" lines at beginning" << endl
208 <<
"Skipping " << lastlineValue <<
" lines at end" << endl;
221 for (
long lineNumber = 1; lineNumber < totalLines; lineNumber++)
224 if (!getline(input1, line1) || !getline(input2, line2))
230 if (lineNumber <= linesToSkip)
237 bool skipregex =
false;
238 for (
unsigned i = 0; i < regexclude.size(); i++)
251 istringstream ss1(line1);
252 istringstream ss2(line2);
253 bool lineDiff =
false;
255 set<unsigned> skipCols;
257 for (
unsigned i = 0; i < recs.size(); i++)
262 skipCols.insert(recs[i].col);
265 while ((ss1 >> s1) && (ss2 >> s2))
267 if (skipCols.count(column++))
274 double d1 = stringToDouble(s1, df1);
275 double d2 = stringToDouble(s2, df2);
283 if (abs(
err) > epsilon)
295 if (verboseLevel && lineDiff)
297 output <<
"f1, " << lineNumber <<
":" << line1 << endl
298 <<
"f2, " << lineNumber <<
":" << line2 << endl;
304 catch (std::exception& e)
306 cout << e.what() << endl;
311 output <<
"Total differences: " << exitCode << endl;
331 int main(
int argc,
char *argv[])