Go to the documentation of this file.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
00029
00030
00031
00032
00033
00034
00035 #ifndef OPENMS_CONCEPT_FUZZYSTRINGCOMPARATOR_H
00036 #define OPENMS_CONCEPT_FUZZYSTRINGCOMPARATOR_H
00037
00038 #include <OpenMS/CONCEPT/Types.h>
00039 #include <OpenMS/DATASTRUCTURES/String.h>
00040 #include <OpenMS/DATASTRUCTURES/StringList.h>
00041
00042 #include <cstdlib>
00043 #include <fstream>
00044 #include <iostream>
00045 #include <cctype>
00046 #include <limits>
00047 #include <sstream>
00048 #include <map>
00049
00050 namespace OpenMS
00051 {
00052 namespace Internal
00053 {
00054 namespace ClassTest
00055 {
00056 void OPENMS_DLLAPI
00057 testStringSimilar(const char * file, int line,
00058 const std::string & string_1,
00059 const char * string_1_stringified,
00060 const std::string & string_2,
00061 const char * string_2_stringified);
00062 bool OPENMS_DLLAPI
00063 isFileSimilar(const std::string &, const std::string &);
00064 }
00065 }
00066
00071 class OPENMS_DLLAPI FuzzyStringComparator
00072 {
00073
00074 friend void OPENMS_DLLAPI
00075 Internal::ClassTest::testStringSimilar(
00076 const char * file,
00077 int line,
00078 const std::string & string_1,
00079 const char * string_1_stringified,
00080 const std::string & string_2,
00081 const char * string_2_stringified);
00082 friend bool OPENMS_DLLAPI
00083 Internal::ClassTest::isFileSimilar(const std::string &,
00084 const std::string &);
00085
00087 struct AbortComparison
00088 {
00089 };
00090
00091 public:
00092
00094
00095
00097 FuzzyStringComparator();
00098
00100 virtual
00101 ~FuzzyStringComparator();
00102
00104 FuzzyStringComparator(const FuzzyStringComparator & rhs);
00105
00107 FuzzyStringComparator &
00108 operator=(const FuzzyStringComparator & rhs);
00109
00111
00113 const double &
00114 getAcceptableRelative() const
00115 {
00116 return ratio_max_allowed_;
00117 }
00118
00120 void
00121 setAcceptableRelative(const double rhs)
00122 {
00123 this->ratio_max_allowed_ = rhs;
00124 if (ratio_max_allowed_ < 1.0)
00125 ratio_max_allowed_ = 1
00126 / ratio_max_allowed_;
00127
00128 }
00129
00131 const double &
00132 getAcceptableAbsolute() const
00133 {
00134 return absdiff_max_allowed_;
00135 }
00136
00138 void
00139 setAcceptableAbsolute(const double rhs)
00140 {
00141 this->absdiff_max_allowed_ = rhs;
00142 if (absdiff_max_allowed_ < 0.0)
00143 absdiff_max_allowed_
00144 = -absdiff_max_allowed_;
00145 }
00146
00148 const StringList &
00149 getWhitelist() const
00150 {
00151 return whitelist_;
00152 }
00153
00155 StringList &
00156 getWhitelist()
00157 {
00158 return whitelist_;
00159 }
00160
00162 void
00163 setWhitelist(const StringList & rhs)
00164 {
00165 whitelist_ = rhs;
00166 }
00167
00176 const int &
00177 getVerboseLevel() const
00178 {
00179 return verbose_level_;
00180 }
00181
00190 void
00191 setVerboseLevel(const int rhs)
00192 {
00193 this->verbose_level_ = rhs;
00194 }
00195
00198 const int &
00199 getTabWidth() const
00200 {
00201 return tab_width_;
00202 }
00203
00206 void
00207 setTabWidth(const int rhs)
00208 {
00209 this->tab_width_ = rhs;
00210 }
00211
00214 const int &
00215 getFirstColumn() const
00216 {
00217 return first_column_;
00218 }
00219
00222 void
00223 setFirstColumn(const int rhs)
00224 {
00225 this->first_column_ = rhs;
00226 }
00227
00233 std::ostream &
00234 getLogDestination() const
00235 {
00236 return *log_dest_;
00237 }
00238
00248 void
00249 setLogDestination(std::ostream & rhs)
00250 {
00251 this->log_dest_ = &rhs;
00252 }
00253
00260 bool
00261 compareStrings(std::string const & lhs, std::string const & rhs);
00262
00270 bool
00271 compareStreams(std::istream & input_1, std::istream & input_2);
00272
00286 bool
00287 compareFiles(const std::string & filename_1,
00288 const std::string & filename_2);
00289
00290 protected:
00291
00299 bool
00300 compareLines_(std::string const & line_str_1,
00301 std::string const & line_str_2);
00302
00304 void
00305 reportSuccess_() const;
00306
00309 void
00310 reportFailure_(char const * const message) const;
00311
00313 void writeWhitelistCases_(const std::string & prefix) const;
00314
00317 void readNextLine_(std::istream & input_stream, std::string & line_string, int & line_number) const;
00318
00320 bool openInputFileStream_(const std::string & filename, std::ifstream & input_stream) const;
00321
00323 std::ostream * log_dest_;
00324
00326 std::string input_1_name_;
00328 std::string input_2_name_;
00329
00331 struct InputLine
00332 {
00333 std::stringstream line_;
00334 std::ios::pos_type line_position_;
00335
00336 InputLine() :
00337 line_()
00338 {
00339 }
00340
00342 void setToString(const std::string & s)
00343 {
00344 line_.str(s);
00345 line_.seekp(0);
00346 line_.clear();
00347 line_.unsetf(std::ios::skipws);
00348
00349 line_position_ = line_.tellg();
00350 }
00351
00353 void updatePosition()
00354 {
00355 line_position_ = (Int(line_.tellg()) != -1 ? line_.tellg() : std::ios::pos_type(line_.str().length()));
00356 }
00357
00359 void seekGToSavedPosition()
00360 {
00361 line_.clear();
00362 line_.seekg(line_position_);
00363 }
00364
00372 operator void *() const
00373 {
00374 return line_.operator void *();
00375 }
00376 };
00377
00378 InputLine input_line_1_;
00379 InputLine input_line_2_;
00380
00381 int line_num_1_;
00382 int line_num_2_;
00383
00384 int line_num_1_max_;
00385 int line_num_2_max_;
00386
00387 std::string line_str_1_max_;
00388 std::string line_str_2_max_;
00389
00391 double ratio_max_allowed_;
00392
00394 double ratio_max_;
00395
00397 double absdiff_max_allowed_;
00398
00400 double absdiff_max_;
00401
00403 struct StreamElement_
00404 {
00405 double number;
00406 unsigned char letter;
00407 bool is_number;
00408 bool is_space;
00409
00410 StreamElement_() :
00411 number(0),
00412 letter(0),
00413 is_number(false),
00414 is_space(false)
00415 {}
00416
00418 void reset()
00419 {
00420 is_number = false;
00421 is_space = false;
00422 letter = '\0';
00423 number = std::numeric_limits<double>::quiet_NaN();
00424 }
00425
00427 void fillFromInputLine(InputLine & input_line)
00428 {
00429
00430
00431 reset();
00432
00433 input_line.updatePosition();
00434 input_line.line_ >> letter;
00435 if ((is_space = (isspace(letter) != 0)))
00436 {
00437 input_line.line_ >> std::ws;
00438 }
00439 else
00440 {
00441 input_line.seekGToSavedPosition();
00442 if ((is_number = ((input_line.line_ >> number) != 0)))
00443 {
00444 }
00445 else
00446 {
00447 input_line.seekGToSavedPosition();
00448 input_line.line_ >> letter;
00449 }
00450 }
00451 }
00452
00453 };
00454
00456 StreamElement_ element_1_;
00458 StreamElement_ element_2_;
00459
00461 struct PrefixInfo_
00462 {
00463 OpenMS::String prefix;
00464 OpenMS::String prefix_whitespaces;
00465 int line_column;
00466
00467 PrefixInfo_(const InputLine & input_line, const int tab_width_, const int first_column_) :
00468 prefix(input_line.line_.str()), line_column(0)
00469 {
00470 prefix = prefix.prefix(size_t(input_line.line_position_));
00471 prefix_whitespaces = prefix;
00472 for (String::iterator iter = prefix_whitespaces.begin(); iter != prefix_whitespaces.end(); ++iter)
00473 {
00474 if (*iter != '\t')
00475 {
00476 * iter = ' ';
00477 ++line_column;
00478 }
00479 else
00480 {
00481 line_column = (line_column / tab_width_ + 1) * tab_width_;
00482 }
00483 }
00484 line_column += first_column_;
00485 }
00486
00487 };
00488
00489 bool is_absdiff_small_;
00490
00491 int verbose_level_;
00492 int tab_width_;
00493 int first_column_;
00494
00498 bool is_status_success_;
00499
00501 bool use_prefix_;
00502
00503 StringList whitelist_;
00504 std::map<String, UInt> whitelist_cases_;
00505
00506 };
00507
00508 }
00509
00510 #endif //OPENMS_CONCEPT_FUZZYSTRINGCOMPARATOR_H