|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include "Teuchos_StrUtils.hpp" 00043 #include "Teuchos_Assert.hpp" 00044 00045 00046 namespace Teuchos { 00047 00048 00049 Array<std::string> StrUtils::readFile(std::istream& is, char comment) 00050 { 00051 std::string line; 00052 Array<std::string> rtn(0); 00053 00054 while (readLine(is, line)) 00055 { 00056 if (line.length() > 0) rtn.append(before(line, comment)); 00057 line=""; 00058 } 00059 00060 return rtn; 00061 } 00062 00063 00064 Array<std::string> StrUtils::splitIntoLines(const std::string& input) 00065 { 00066 int begin = 0; 00067 Array<std::string> rtn; 00068 const unsigned int len = input.length(); 00069 for (unsigned int p=0; p<len; ++p) { 00070 const bool isEnd = p==len-1; 00071 if( input[p]=='\n' || input[p]=='\0' || input[p]=='\r' || isEnd ) 00072 { 00073 if (p-begin > 1) 00074 rtn.append( 00075 subString( input, begin, p+(isEnd?(input[len-1]=='\n'?0:1):0) ) 00076 ); 00077 begin = p+1; 00078 } 00079 } 00080 return rtn; 00081 } 00082 00083 00084 Array<Array<std::string> > StrUtils::tokenizeFile(std::istream& is, char comment) 00085 { 00086 std::string line; 00087 Array<Array<std::string> > rtn(0); 00088 Array<std::string> lines = readFile(is, comment); 00089 rtn.reserve(lines.length()); 00090 00091 int count = 0; 00092 for (int i=0; i<lines.length(); i++) 00093 { 00094 if (lines[i].length() == 0) continue; 00095 Array<std::string> tokens = stringTokenizer(lines[i]); 00096 if (tokens.length() == 0) continue; 00097 rtn.append(tokens); 00098 count++; 00099 } 00100 00101 return rtn; 00102 } 00103 00104 00105 bool StrUtils::readLine(std::istream& is, std::string& line) 00106 { 00107 char c[500]; 00108 if (line.length() > 0) line[0] = '\0'; 00109 00110 if (is.eof()) return false; 00111 if (is.getline(c, 499)) 00112 { 00113 line = std::string(c); 00114 } 00115 00116 return true; 00117 } 00118 00119 00120 Array<std::string> StrUtils::getTokensPlusWhitespace(const std::string& str){ 00121 Array<std::string> rtn(0); 00122 unsigned int start = 0; 00123 00124 while(start < str.length()) 00125 { 00126 unsigned int wordStart = findNextNonWhitespace(str, start); 00127 /* add any preceding whitespace */ 00128 if (wordStart > start) 00129 { 00130 rtn.append(subString(str, start, wordStart)); 00131 } 00132 start = wordStart; 00133 /* add the next word */ 00134 int stop = findNextWhitespace(str, start); 00135 if (start-stop == 0) return rtn; 00136 std::string sub = subString(str, start, stop); 00137 rtn.append(sub); 00138 start = stop;// findNextNonWhitespace(str, stop); 00139 } 00140 return rtn; 00141 } 00142 00143 00144 Array<std::string> StrUtils::stringTokenizer(const std::string& str){ 00145 Array<std::string> rtn(0); 00146 unsigned int start = 0; 00147 00148 while(start < str.length()) 00149 { 00150 start = findNextNonWhitespace(str, start); 00151 int stop = findNextWhitespace(str, start); 00152 if (start-stop == 0) return rtn; 00153 std::string sub = subString(str, start, stop); 00154 rtn.append(sub); 00155 start = findNextNonWhitespace(str, stop); 00156 } 00157 return rtn; 00158 } 00159 00160 00161 std::string StrUtils::reassembleFromTokens(const Array<std::string>& tokens, 00162 int iStart) 00163 { 00164 std::string rtn; 00165 00166 for (int i=iStart; i<tokens.length(); i++) 00167 { 00168 rtn += tokens[i]; 00169 if (i < (tokens.length()-1)) rtn += " "; 00170 } 00171 return rtn; 00172 } 00173 00174 00175 void StrUtils::splitList(const std::string& big, Array<std::string>& list) 00176 { 00177 if (subString(big, 0,1)!="[") 00178 { 00179 list.resize(1); 00180 list[0] = big; 00181 return; 00182 } 00183 00184 int parenDepth = 0; 00185 int localCount = 0; 00186 std::string tmp(big); 00187 list.resize(0); 00188 00189 // start at 1 to ignore '['; 00190 00191 for (unsigned int i=1; i<big.length(); i++) 00192 { 00193 if (big[i]=='(') parenDepth++; 00194 if (big[i]==')') parenDepth--; 00195 if (big[i]==']') 00196 { 00197 tmp[localCount]='\0'; 00198 list.append(tmp); 00199 break; 00200 } 00201 if (big[i]==',' && parenDepth==0) 00202 { 00203 tmp[localCount]='\0'; 00204 list.append(tmp); 00205 tmp = big; 00206 localCount = 0; 00207 continue; 00208 } 00209 tmp[localCount] = big[i]; 00210 localCount++; 00211 } 00212 } 00213 00214 00215 // return the position of the next whitespace in a std::string. 00216 // If no whitespace, return -1; 00217 00218 int StrUtils::findNextWhitespace(const std::string& str, int offset) 00219 { 00220 for (unsigned int i=0; i<(str.length()-offset); i++) 00221 { 00222 if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n') 00223 { 00224 return i+offset; 00225 } 00226 } 00227 return str.length(); 00228 } 00229 00230 00231 int StrUtils::findNextNonWhitespace(const std::string& str, int offset) 00232 { 00233 for (unsigned int i=0; i<(str.length()-offset); i++) 00234 { 00235 if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')) 00236 { 00237 return i+offset; 00238 } 00239 } 00240 return str.length(); 00241 } 00242 00243 00244 std::string StrUtils::varTableSubstitute(const std::string& rawLine, 00245 const Array<std::string>& varNames, 00246 const Array<std::string>& varValues) 00247 { 00248 TEUCHOS_TEST_FOR_EXCEPTION(varNames.length() != varValues.length(), 00249 std::runtime_error, 00250 "mismatched variable tables in varTableSubstitute"); 00251 00252 std::string line = rawLine; 00253 for (int i=0; i<varNames.length(); i++) 00254 { 00255 line = varSubstitute(line, varNames[i], varValues[i]); 00256 } 00257 return line; 00258 } 00259 00260 00261 std::string StrUtils::varSubstitute(const std::string& rawLine, 00262 const std::string& varName, 00263 const std::string& varValue) 00264 { 00265 std::string line = rawLine; 00266 00267 // iterate because there might be more than one occurance on this line 00268 while (find(line, varName) >= 0) 00269 { 00270 std::string b = before(line, varName); 00271 std::string a = after(line, varName); 00272 line = b + varValue + a; 00273 } 00274 return line; 00275 } 00276 00277 00278 std::string StrUtils::before(const std::string& str, char sub) 00279 { 00280 char c[2]; 00281 c[0] = sub; 00282 c[1] = 0; 00283 return before(str, c); 00284 } 00285 00286 00287 std::string StrUtils::before(const std::string& str, const std::string& sub) 00288 { 00289 TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0, 00290 std::runtime_error, "String::before: arg is null pointer"); 00291 00292 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()); 00293 if (p==0) return str; 00294 int subLen = p-str.c_str(); 00295 std::string rtn(str.c_str(), subLen); 00296 return rtn; 00297 } 00298 00299 00300 std::string StrUtils::after(const std::string& str, const std::string& sub) 00301 { 00302 TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0, 00303 std::runtime_error, "String::after: arg is null pointer"); 00304 00305 // find beginning of substring 00306 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ; 00307 // if substring not found, return empty std::string 00308 if (p==0) return std::string(); 00309 // offset to end of substring 00310 p+= std::strlen(sub.c_str()); 00311 return std::string(p); 00312 } 00313 00314 00315 int StrUtils::find(const std::string& str, const std::string& sub) 00316 { 00317 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()); 00318 if (p==0) return -1; 00319 return p-str.c_str(); 00320 } 00321 00322 00323 bool StrUtils::isWhite(const std::string& str) 00324 { 00325 for (unsigned int i=0; i<str.length(); i++) 00326 { 00327 unsigned char c = str[i]; 00328 if (c >= 33 && c <= 126) 00329 { 00330 return false; 00331 } 00332 } 00333 return true; 00334 } 00335 00336 00337 std::string StrUtils::fixUnprintableCharacters(const std::string& str) 00338 { 00339 std::string rtn = str; 00340 for (unsigned int i=0; i<rtn.length(); i++) 00341 { 00342 unsigned char c = rtn[i]; 00343 if (c < 33 || c > 126) 00344 { 00345 if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ') 00346 { 00347 rtn[i] = ' '; 00348 } 00349 } 00350 } 00351 return rtn; 00352 } 00353 00354 00355 std::string StrUtils::between(const std::string& str, const std::string& begin, 00356 const std::string& end, std::string& front, 00357 std::string& back) 00358 { 00359 front = before(str, begin); 00360 std::string middle = before(after(str, begin), end); 00361 back = after(str, end); 00362 return middle; 00363 } 00364 00365 00366 std::string StrUtils::subString(const std::string& str, int begin, int end) 00367 { 00368 return std::string(str.c_str()+begin, end-begin); 00369 } 00370 00371 00372 std::string StrUtils::readFromStream(std::istream& is) 00373 { 00374 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, 00375 "StrUtils::readFromStream isn't implemented yet"); 00376 00377 // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the 00378 // return statement below is unreachable. Some older compilers 00379 // might not realize this. That's why the return statement was put 00380 // there, so that those compilers don't warn that this function 00381 // doesn't return a value. If it's a choice between one warning and 00382 // another, I would prefer the choice that produces less code and 00383 // doesn't have unreachable code (which never gets tested). 00384 00385 //return ""; 00386 } 00387 00388 00389 std::string StrUtils::allCaps(const std::string& s) 00390 { 00391 std::string rtn = s; 00392 for (unsigned int i=0; i<rtn.length(); i++) 00393 { 00394 rtn[i] = toupper(rtn[i]); 00395 } 00396 return rtn; 00397 } 00398 00399 00400 double StrUtils::atof(const std::string& s) 00401 { 00402 return std::atof(s.c_str()); 00403 } 00404 00405 00406 int StrUtils::atoi(const std::string& s) 00407 { 00408 return std::atoi(s.c_str()); 00409 } 00410 00411 00412 std::ostream& StrUtils::printLines( 00413 std::ostream &os 00414 ,const std::string &linePrefix 00415 ,const std::string &lines 00416 ) 00417 { 00418 typedef Teuchos::Array<std::string> array_t; 00419 array_t linesArray = splitIntoLines(lines); 00420 for( int i = 0; i < static_cast<int>(linesArray.size()); ++i ) 00421 { 00422 os << linePrefix << linesArray[i] << "\n"; 00423 } 00424 return os; 00425 } 00426 00427 00428 std::string StrUtils::removeAllSpaces(std::string stringToClean) 00429 { 00430 std::string::size_type pos=0; 00431 bool spacesLeft = true; 00432 00433 while(spacesLeft){ 00434 pos = stringToClean.find(" "); 00435 if(pos != string::npos){ 00436 stringToClean.erase(pos,1); 00437 } 00438 else{ 00439 spacesLeft = false; 00440 } 00441 } 00442 return stringToClean; 00443 } 00444 00445 00446 } // namespace Teuchos
1.7.6.1