|
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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include "Teuchos_StrUtils.hpp" 00030 #include "Teuchos_TestForException.hpp" 00031 00032 00033 using namespace Teuchos; 00034 00035 00036 Array<std::string> StrUtils::readFile(std::istream& is, char comment) 00037 { 00038 std::string line; 00039 Array<std::string> rtn(0); 00040 00041 while (readLine(is, line)) 00042 { 00043 if (line.length() > 0) rtn.append(before(line, comment)); 00044 line=""; 00045 } 00046 00047 return rtn; 00048 } 00049 00050 Array<std::string> StrUtils::splitIntoLines(const std::string& input) 00051 { 00052 int begin = 0; 00053 Array<std::string> rtn; 00054 const unsigned int len = input.length(); 00055 for (unsigned int p=0; p<len; ++p) { 00056 const bool isEnd = p==len-1; 00057 if( input[p]=='\n' || input[p]=='\0' || input[p]=='\r' || isEnd ) 00058 { 00059 if (p-begin > 1) 00060 rtn.append( 00061 subString( input, begin, p+(isEnd?(input[len-1]=='\n'?0:1):0) ) 00062 ); 00063 begin = p+1; 00064 } 00065 } 00066 return rtn; 00067 } 00068 00069 Array<Array<std::string> > StrUtils::tokenizeFile(std::istream& is, char comment) 00070 { 00071 std::string line; 00072 Array<Array<std::string> > rtn(0); 00073 Array<std::string> lines = readFile(is, comment); 00074 rtn.reserve(lines.length()); 00075 00076 int count = 0; 00077 for (int i=0; i<lines.length(); i++) 00078 { 00079 if (lines[i].length() == 0) continue; 00080 Array<std::string> tokens = stringTokenizer(lines[i]); 00081 if (tokens.length() == 0) continue; 00082 rtn.append(tokens); 00083 count++; 00084 } 00085 00086 return rtn; 00087 } 00088 00089 bool StrUtils::readLine(std::istream& is, std::string& line) 00090 { 00091 char c[500]; 00092 if (line.length() > 0) line[0] = '\0'; 00093 00094 if (is.eof()) return false; 00095 if (is.getline(c, 499)) 00096 { 00097 line = std::string(c); 00098 } 00099 00100 return true; 00101 } 00102 00103 00104 00105 Array<std::string> StrUtils::getTokensPlusWhitespace(const std::string& str){ 00106 Array<std::string> rtn(0); 00107 unsigned int start = 0; 00108 00109 while(start < str.length()) 00110 { 00111 unsigned int wordStart = findNextNonWhitespace(str, start); 00112 /* add any preceding whitespace */ 00113 if (wordStart > start) 00114 { 00115 rtn.append(subString(str, start, wordStart)); 00116 } 00117 start = wordStart; 00118 /* add the next word */ 00119 int stop = findNextWhitespace(str, start); 00120 if (start-stop == 0) return rtn; 00121 std::string sub = subString(str, start, stop); 00122 rtn.append(sub); 00123 start = stop;// findNextNonWhitespace(str, stop); 00124 } 00125 return rtn; 00126 } 00127 00128 Array<std::string> StrUtils::stringTokenizer(const std::string& str){ 00129 Array<std::string> rtn(0); 00130 unsigned int start = 0; 00131 00132 while(start < str.length()) 00133 { 00134 start = findNextNonWhitespace(str, start); 00135 int stop = findNextWhitespace(str, start); 00136 if (start-stop == 0) return rtn; 00137 std::string sub = subString(str, start, stop); 00138 rtn.append(sub); 00139 start = findNextNonWhitespace(str, stop); 00140 } 00141 return rtn; 00142 } 00143 00144 std::string StrUtils::reassembleFromTokens(const Array<std::string>& tokens, int iStart) 00145 { 00146 std::string rtn; 00147 00148 for (int i=iStart; i<tokens.length(); i++) 00149 { 00150 rtn += tokens[i]; 00151 if (i < (tokens.length()-1)) rtn += " "; 00152 } 00153 return rtn; 00154 } 00155 00156 void StrUtils::splitList(const std::string& big, Array<std::string>& list) 00157 { 00158 if (subString(big, 0,1)!="[") 00159 { 00160 list.resize(1); 00161 list[0] = big; 00162 return; 00163 } 00164 00165 int parenDepth = 0; 00166 int localCount = 0; 00167 std::string tmp(big); 00168 list.resize(0); 00169 00170 // start at 1 to ignore '['; 00171 00172 for (unsigned int i=1; i<big.length(); i++) 00173 { 00174 if (big[i]=='(') parenDepth++; 00175 if (big[i]==')') parenDepth--; 00176 if (big[i]==']') 00177 { 00178 tmp[localCount]='\0'; 00179 list.append(tmp); 00180 break; 00181 } 00182 if (big[i]==',' && parenDepth==0) 00183 { 00184 tmp[localCount]='\0'; 00185 list.append(tmp); 00186 tmp = big; 00187 localCount = 0; 00188 continue; 00189 } 00190 tmp[localCount] = big[i]; 00191 localCount++; 00192 } 00193 } 00194 00195 00196 // return the position of the next whitespace in a std::string. 00197 // If no whitespace, return -1; 00198 00199 int StrUtils::findNextWhitespace(const std::string& str, int offset) 00200 { 00201 for (unsigned int i=0; i<(str.length()-offset); i++) 00202 { 00203 if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n') 00204 { 00205 return i+offset; 00206 } 00207 } 00208 return str.length(); 00209 } 00210 00211 int StrUtils::findNextNonWhitespace(const std::string& str, int offset) 00212 { 00213 for (unsigned int i=0; i<(str.length()-offset); i++) 00214 { 00215 if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')) 00216 { 00217 return i+offset; 00218 } 00219 } 00220 return str.length(); 00221 } 00222 00223 00224 std::string StrUtils::varTableSubstitute(const std::string& rawLine, 00225 const Array<std::string>& varNames, 00226 const Array<std::string>& varValues) 00227 { 00228 TEST_FOR_EXCEPTION(varNames.length() != varValues.length(), 00229 std::runtime_error, 00230 "mismatched variable tables in varTableSubstitute"); 00231 00232 std::string line = rawLine; 00233 for (int i=0; i<varNames.length(); i++) 00234 { 00235 line = varSubstitute(line, varNames[i], varValues[i]); 00236 } 00237 return line; 00238 } 00239 00240 00241 00242 00243 std::string StrUtils::varSubstitute(const std::string& rawLine, 00244 const std::string& varName, 00245 const std::string& varValue) 00246 { 00247 std::string line = rawLine; 00248 00249 // iterate because there might be more than one occurance on this line 00250 while (find(line, varName) >= 0) 00251 { 00252 std::string b = before(line, varName); 00253 std::string a = after(line, varName); 00254 line = b + varValue + a; 00255 } 00256 return line; 00257 } 00258 00259 00260 std::string StrUtils::before(const std::string& str, char sub) 00261 { 00262 char c[2]; 00263 c[0] = sub; 00264 c[1] = 0; 00265 return before(str, c); 00266 } 00267 00268 std::string StrUtils::before(const std::string& str, const std::string& sub) 00269 { 00270 TEST_FOR_EXCEPTION(sub.c_str()==0, 00271 std::runtime_error, "String::before: arg is null pointer"); 00272 00273 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()); 00274 if (p==0) return str; 00275 int subLen = p-str.c_str(); 00276 std::string rtn(str.c_str(), subLen); 00277 return rtn; 00278 } 00279 00280 std::string StrUtils::after(const std::string& str, const std::string& sub) 00281 { 00282 TEST_FOR_EXCEPTION(sub.c_str()==0, 00283 std::runtime_error, "String::after: arg is null pointer"); 00284 00285 // find beginning of substring 00286 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ; 00287 // if substring not found, return empty std::string 00288 if (p==0) return std::string(); 00289 // offset to end of substring 00290 p+= std::strlen(sub.c_str()); 00291 return std::string(p); 00292 } 00293 00294 int StrUtils::find(const std::string& str, const std::string& sub) 00295 { 00296 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()); 00297 if (p==0) return -1; 00298 return p-str.c_str(); 00299 } 00300 00301 bool StrUtils::isWhite(const std::string& str) 00302 { 00303 for (unsigned int i=0; i<str.length(); i++) 00304 { 00305 unsigned char c = str[i]; 00306 if (c >= 33 && c <= 126) 00307 { 00308 return false; 00309 } 00310 } 00311 return true; 00312 } 00313 00314 std::string StrUtils::fixUnprintableCharacters(const std::string& str) 00315 { 00316 std::string rtn = str; 00317 for (unsigned int i=0; i<rtn.length(); i++) 00318 { 00319 unsigned char c = rtn[i]; 00320 if (c < 33 || c > 126) 00321 { 00322 if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ') 00323 { 00324 rtn[i] = ' '; 00325 } 00326 } 00327 } 00328 return rtn; 00329 } 00330 00331 std::string StrUtils::between(const std::string& str, const std::string& begin, 00332 const std::string& end, std::string& front, 00333 std::string& back) 00334 { 00335 front = before(str, begin); 00336 std::string middle = before(after(str, begin), end); 00337 back = after(str, end); 00338 return middle; 00339 } 00340 00341 00342 std::string StrUtils::subString(const std::string& str, int begin, int end) 00343 { 00344 return std::string(str.c_str()+begin, end-begin); 00345 } 00346 00347 std::string StrUtils::readFromStream(std::istream& is) 00348 { 00349 TEST_FOR_EXCEPTION(true, std::logic_error, 00350 "StrUtils::readFromStream isn't implemented yet"); 00351 00352 return ""; 00353 } 00354 00355 std::string StrUtils::allCaps(const std::string& s) 00356 { 00357 std::string rtn = s; 00358 for (unsigned int i=0; i<rtn.length(); i++) 00359 { 00360 rtn[i] = toupper(rtn[i]); 00361 } 00362 return rtn; 00363 } 00364 00365 double StrUtils::atof(const std::string& s) 00366 { 00367 return std::atof(s.c_str()); 00368 } 00369 00370 int StrUtils::atoi(const std::string& s) 00371 { 00372 return std::atoi(s.c_str()); 00373 } 00374 00375 std::ostream& StrUtils::printLines( 00376 std::ostream &os 00377 ,const std::string &linePrefix 00378 ,const std::string &lines 00379 ) 00380 { 00381 typedef Teuchos::Array<std::string> array_t; 00382 array_t linesArray = splitIntoLines(lines); 00383 for( int i = 0; i < static_cast<int>(linesArray.size()); ++i ) 00384 { 00385 os << linePrefix << linesArray[i] << "\n"; 00386 } 00387 return os; 00388 } 00389 00390 00391
1.7.4