1 //===================================================== 2 // File : btl.hh 3 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 4 //===================================================== 5 // 6 // This program is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU General Public License 8 // as published by the Free Software Foundation; either version 2 9 // of the License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 // 19 #ifndef BTL_HH 20 #define BTL_HH 21 22 #include "bench_parameter.hh" 23 #include <iostream> 24 #include <algorithm> 25 #include <vector> 26 #include <string> 27 #include "utilities.h" 28 29 #if (defined __GNUC__) 30 #define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline 31 #else 32 #define BTL_ALWAYS_INLINE inline 33 #endif 34 35 #if (defined __GNUC__) 36 #define BTL_DONT_INLINE __attribute__((noinline)) 37 #else 38 #define BTL_DONT_INLINE 39 #endif 40 41 #if (defined __GNUC__) 42 #define BTL_ASM_COMMENT(X) asm("#" X) 43 #else 44 #define BTL_ASM_COMMENT(X) 45 #endif 46 47 #if (defined __GNUC__) && (!defined __INTEL_COMPILER) && !defined(__arm__) && !defined(__powerpc__) 48 #define BTL_DISABLE_SSE_EXCEPTIONS() { \ 49 int aux; \ 50 asm( \ 51 "stmxcsr %[aux] \n\t" \ 52 "orl $32832, %[aux] \n\t" \ 53 "ldmxcsr %[aux] \n\t" \ 54 : : [aux] "m" (aux)); \ 55 } 56 #else 57 #define BTL_DISABLE_SSE_EXCEPTIONS() 58 #endif 59 60 /** Enhanced std::string 61 */ 62 class BtlString : public std::string 63 { 64 public: BtlString()65 BtlString() : std::string() {} BtlString(const BtlString & str)66 BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {} BtlString(const std::string & str)67 BtlString(const std::string& str) : std::string(str) {} BtlString(const char * str)68 BtlString(const char* str) : std::string(str) {} 69 operator const char*() const70 operator const char* () const { return c_str(); } 71 trim(bool left=true,bool right=true)72 void trim( bool left = true, bool right = true ) 73 { 74 int lspaces, rspaces, len = length(), i; 75 lspaces = rspaces = 0; 76 77 if ( left ) 78 for (i=0; i<len && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); ++lspaces,++i); 79 80 if ( right && lspaces < len ) 81 for(i=len-1; i>=0 && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); rspaces++,i--); 82 83 *this = substr(lspaces, len-lspaces-rspaces); 84 } 85 split(const BtlString & delims="\\t\\n ") const86 std::vector<BtlString> split( const BtlString& delims = "\t\n ") const 87 { 88 std::vector<BtlString> ret; 89 unsigned int numSplits = 0; 90 size_t start, pos; 91 start = 0; 92 do 93 { 94 pos = find_first_of(delims, start); 95 if (pos == start) 96 { 97 ret.push_back(""); 98 start = pos + 1; 99 } 100 else if (pos == npos) 101 ret.push_back( substr(start) ); 102 else 103 { 104 ret.push_back( substr(start, pos - start) ); 105 start = pos + 1; 106 } 107 //start = find_first_not_of(delims, start); 108 ++numSplits; 109 } while (pos != npos); 110 return ret; 111 } 112 endsWith(const BtlString & str) const113 bool endsWith(const BtlString& str) const 114 { 115 if(str.size()>this->size()) 116 return false; 117 return this->substr(this->size()-str.size(),str.size()) == str; 118 } contains(const BtlString & str) const119 bool contains(const BtlString& str) const 120 { 121 return this->find(str)<this->size(); 122 } beginsWith(const BtlString & str) const123 bool beginsWith(const BtlString& str) const 124 { 125 if(str.size()>this->size()) 126 return false; 127 return this->substr(0,str.size()) == str; 128 } 129 toLowerCase(void)130 BtlString toLowerCase( void ) 131 { 132 std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) ); 133 return *this; 134 } toUpperCase(void)135 BtlString toUpperCase( void ) 136 { 137 std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::toupper) ); 138 return *this; 139 } 140 141 /** Case insensitive comparison. 142 */ isEquiv(const BtlString & str) const143 bool isEquiv(const BtlString& str) const 144 { 145 BtlString str0 = *this; 146 str0.toLowerCase(); 147 BtlString str1 = str; 148 str1.toLowerCase(); 149 return str0 == str1; 150 } 151 152 /** Decompose the current string as a path and a file. 153 For instance: "dir1/dir2/file.ext" leads to path="dir1/dir2/" and filename="file.ext" 154 */ decomposePathAndFile(BtlString & path,BtlString & filename) const155 void decomposePathAndFile(BtlString& path, BtlString& filename) const 156 { 157 std::vector<BtlString> elements = this->split("/\\"); 158 path = ""; 159 filename = elements.back(); 160 elements.pop_back(); 161 if (this->at(0)=='/') 162 path = "/"; 163 for (unsigned int i=0 ; i<elements.size() ; ++i) 164 path += elements[i] + "/"; 165 } 166 }; 167 168 class BtlConfig 169 { 170 public: BtlConfig()171 BtlConfig() 172 : overwriteResults(false), checkResults(true), realclock(false), tries(DEFAULT_NB_TRIES) 173 { 174 char * _config; 175 _config = getenv ("BTL_CONFIG"); 176 if (_config!=NULL) 177 { 178 std::vector<BtlString> config = BtlString(_config).split(" \t\n"); 179 for (int i = 0; i<config.size(); i++) 180 { 181 if (config[i].beginsWith("-a")) 182 { 183 if (i+1==config.size()) 184 { 185 std::cerr << "error processing option: " << config[i] << "\n"; 186 exit(2); 187 } 188 Instance.m_selectedActionNames = config[i+1].split(":"); 189 190 i += 1; 191 } 192 else if (config[i].beginsWith("-t")) 193 { 194 if (i+1==config.size()) 195 { 196 std::cerr << "error processing option: " << config[i] << "\n"; 197 exit(2); 198 } 199 Instance.tries = atoi(config[i+1].c_str()); 200 201 i += 1; 202 } 203 else if (config[i].beginsWith("--overwrite")) 204 { 205 Instance.overwriteResults = true; 206 } 207 else if (config[i].beginsWith("--nocheck")) 208 { 209 Instance.checkResults = false; 210 } 211 else if (config[i].beginsWith("--real")) 212 { 213 Instance.realclock = true; 214 } 215 } 216 } 217 218 BTL_DISABLE_SSE_EXCEPTIONS(); 219 } 220 skipAction(const std::string & _name)221 BTL_DONT_INLINE static bool skipAction(const std::string& _name) 222 { 223 if (Instance.m_selectedActionNames.empty()) 224 return false; 225 226 BtlString name(_name); 227 for (int i=0; i<Instance.m_selectedActionNames.size(); ++i) 228 if (name.contains(Instance.m_selectedActionNames[i])) 229 return false; 230 231 return true; 232 } 233 234 static BtlConfig Instance; 235 bool overwriteResults; 236 bool checkResults; 237 bool realclock; 238 int tries; 239 240 protected: 241 std::vector<BtlString> m_selectedActionNames; 242 }; 243 244 #define BTL_MAIN \ 245 BtlConfig BtlConfig::Instance 246 247 #endif // BTL_HH 248