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 #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
00113 if (wordStart > start)
00114 {
00115 rtn.append(subString(str, start, wordStart));
00116 }
00117 start = wordStart;
00118
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;
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
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
00197
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
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
00286 char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ;
00287
00288 if (p==0) return std::string();
00289
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