// -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*- // vi: set ts=2 noet: // :noTabs=false:tabSize=4:indentSize=4: // // (c) Copyright Rosetta Commons Member Institutions. // (c) This file is part of the Rosetta software suite and is made available under license. // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons. // (c) For more information, see http://www.rosettacommons.org. Questions about this can be // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu. /// @file test/UTools.hh /// @brief Unit test Tracer/Diff system /// @author Sergey Lyskov /// #ifndef INCLUDED_UTools_HH #define INCLUDED_UTools_HH #include #include #include #include #include #include //required by GCC 4.3.2 namespace test { namespace utools { enum ItemType { _IT_None_, // type was not set yet. _IT_String_, _IT_Number_, _IT_MarkupAbsTolerance_, _IT_MarkupRelTolerance_ }; struct Item { Item(ItemType t=_IT_None_, double n=0.0, std::string const & s="") : type(t), num(n), str(s) {} ItemType type; double num; /// number and markup value stored here std::string str; }; inline std::ostream& operator <<(std::ostream &os, std::vector const & v) { os << "["; for(unsigned int i=0; i= s.size() ) return false; // if( s.size() == 0 ) return false; if( isMarkup ) { if( s[start_pos] == ' ' ) return false; // we don't want it to skip spaces } else { if( s[start_pos] != ' ' ) return false; // we always want at least one space before number if( start_pos + 1 < s.size() ) { if( s[start_pos+1] == ' ' ) return false; // only one space before number is allowed } } char const * end = &s[start_pos]; res = strtod(&s[start_pos], (char **)&end); end_pos = end - (&s[0]); if( !isMarkup ) { if( end_pos < s.size() ) { // check if number end up with space (only if its not the end of a line) if( s[end_pos] != ' ' ) return false; } } if( end_pos > start_pos ) return true; else return false; } inline bool isMarkup(std::string const &s, unsigned int start_pos, double &res, unsigned int &end_pos, std::string markup) { //std::string markup="set_abs_tolerance("; if( start_pos >= s.size() ) return false; // if( s.size() == 0 ) return false; unsigned int r = s.find(markup, start_pos); if( r != start_pos ) return false; unsigned int end; if( !isFloatNumber(s, r+markup.size(), res, end, true) ) return false; if( end >= s.size() ) return false; if( s[end] != ')' ) return false; end_pos = end + 1; return true; } inline bool smartAdd(bool f, double const &res, Item &I, ItemType type, std::vector &V) { if(f) { if( I.type == _IT_String_ ) { //I.num = 0; V.push_back(I); } I = Item(type, res); //I.type = type; //I.num = res; V.push_back(I); //I = Item(); I.type = _IT_None_; } return f; } /// Parse string in to vector of items inline std::vector ParseString(std::string const &s) { std::vector V; Item r; for(unsigned int i=0; i v1 = ParseString(" " + s1 + " "); std::vector v2 = ParseString(" " + s2 + " "); // Removing markup from vector 2. for(int i=v2.size()-1; i>=0; i--) { if( v2[i].type == _IT_None_ ) { error_message = "Wrong Item type: _IT_None_! Probably a bug in UTools.hh..."; return false; } if( v2[i].type == _IT_MarkupAbsTolerance_ || v2[i].type == _IT_MarkupRelTolerance_ ) { v2.erase( v2.begin() + i ); continue; } } unsigned int i=0, j=0; for(; i= v2.size() ) break; if( I1.type != I2.type ) return false; if( I1.type == _IT_String_ ) { if( I1.str != I2.str ) { error_message = I1.str + " != " + I2.str; return false; } j++; continue; } if( I1.type == _IT_Number_ ) { double p = (I1.num + I2.num)/2. * rel_tolerance; p = std::max(abs_tolerance, p); if( fabs(I1.num - I2.num) > p ) { std::ostringstream s; s << I1.num << "!=" << I2.num << " [abs_tolerance=" << abs_tolerance << ", rel_tolerance=" << rel_tolerance << "]"; error_message = s.str(); return false; } j++; continue; } error_message = "Unknow Item type! Probably a bug in UTools.hh..."; return false; } if( i