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<string> StrUtils::readFile(istream& is, char comment)
00037 {
00038 string line;
00039 Array<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<string> StrUtils::splitIntoLines(const string& input)
00051 {
00052 int begin = 0;
00053 Array<string> rtn;
00054
00055 for (unsigned int p=0; p<input.length(); p++)
00056 {
00057 if (input[p]=='\n' || input[p]=='\0' || input[p]=='\r')
00058 {
00059 if (p-begin > 1) rtn.append(subString(input, begin, p));
00060 begin = p+1;
00061 }
00062 }
00063 return rtn;
00064 }
00065
00066
00067 Array<Array<string> > StrUtils::tokenizeFile(istream& is, char comment)
00068 {
00069 string line;
00070 Array<Array<string> > rtn(0);
00071 Array<string> lines = readFile(is, comment);
00072 rtn.reserve(lines.length());
00073
00074 int count = 0;
00075 for (int i=0; i<lines.length(); i++)
00076 {
00077 if (lines[i].length() == 0) continue;
00078 Array<string> tokens = stringTokenizer(lines[i]);
00079 if (tokens.length() == 0) continue;
00080 rtn.append(tokens);
00081 count++;
00082 }
00083
00084 return rtn;
00085 }
00086
00087 bool StrUtils::readLine(istream& is, string& line)
00088 {
00089 char c[500];
00090 if (line.length() > 0) line[0] = '\0';
00091
00092 if (is.eof()) return false;
00093 if (is.getline(c, 499))
00094 {
00095 line = string(c);
00096 }
00097
00098 return true;
00099 }
00100
00101
00102
00103 Array<string> StrUtils::getTokensPlusWhitespace(const string& str){
00104 Array<string> rtn(0);
00105 unsigned int start = 0;
00106
00107 while(start < str.length())
00108 {
00109 int wordStart = findNextNonWhitespace(str, start);
00110
00111 if (wordStart > start)
00112 {
00113 rtn.append(subString(str, start, wordStart));
00114 }
00115 start = wordStart;
00116
00117 int stop = findNextWhitespace(str, start);
00118 if (start-stop == 0) return rtn;
00119 string sub = subString(str, start, stop);
00120 rtn.append(sub);
00121 start = stop;
00122 }
00123 return rtn;
00124 }
00125
00126 Array<string> StrUtils::stringTokenizer(const string& str){
00127 Array<string> rtn(0);
00128 unsigned int start = 0;
00129
00130 while(start < str.length())
00131 {
00132 start = findNextNonWhitespace(str, start);
00133 int stop = findNextWhitespace(str, start);
00134 if (start-stop == 0) return rtn;
00135 string sub = subString(str, start, stop);
00136 rtn.append(sub);
00137 start = findNextNonWhitespace(str, stop);
00138 }
00139 return rtn;
00140 }
00141
00142 string StrUtils::reassembleFromTokens(const Array<string>& tokens, int iStart)
00143 {
00144 string rtn;
00145
00146 for (int i=iStart; i<tokens.length(); i++)
00147 {
00148 rtn += tokens[i];
00149 if (i < (tokens.length()-1)) rtn += " ";
00150 }
00151 return rtn;
00152 }
00153
00154 void StrUtils::splitList(const string& big, Array<string>& list)
00155 {
00156 if (subString(big, 0,1)!="[")
00157 {
00158 list.resize(1);
00159 list[0] = big;
00160 return;
00161 }
00162
00163 int parenDepth = 0;
00164 int localCount = 0;
00165 string tmp(big);
00166 list.resize(0);
00167
00168
00169
00170 for (unsigned int i=1; i<big.length(); i++)
00171 {
00172 if (big[i]=='(') parenDepth++;
00173 if (big[i]==')') parenDepth--;
00174 if (big[i]==']')
00175 {
00176 tmp[localCount]='\0';
00177 list.append(tmp);
00178 break;
00179 }
00180 if (big[i]==',' && parenDepth==0)
00181 {
00182 tmp[localCount]='\0';
00183 list.append(tmp);
00184 tmp = big;
00185 localCount = 0;
00186 continue;
00187 }
00188 tmp[localCount] = big[i];
00189 localCount++;
00190 }
00191 }
00192
00193
00194
00195
00196
00197 int StrUtils::findNextWhitespace(const string& str, int offset)
00198 {
00199 for (unsigned int i=0; i<(str.length()-offset); i++)
00200 {
00201 if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')
00202 {
00203 return i+offset;
00204 }
00205 }
00206 return str.length();
00207 }
00208
00209 int StrUtils::findNextNonWhitespace(const string& str, int offset)
00210 {
00211 for (unsigned int i=0; i<(str.length()-offset); i++)
00212 {
00213 if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n'))
00214 {
00215 return i+offset;
00216 }
00217 }
00218 return str.length();
00219 }
00220
00221
00222 string StrUtils::varTableSubstitute(const string& rawLine,
00223 const Array<string>& varNames,
00224 const Array<string>& varValues)
00225 {
00226 TEST_FOR_EXCEPTION(varNames.length() != varValues.length(),
00227 runtime_error,
00228 "mismatched variable tables in varTableSubstitute");
00229
00230 string line = rawLine;
00231 for (int i=0; i<varNames.length(); i++)
00232 {
00233 line = varSubstitute(line, varNames[i], varValues[i]);
00234 }
00235 return line;
00236 }
00237
00238
00239
00240
00241 string StrUtils::varSubstitute(const string& rawLine,
00242 const string& varName,
00243 const string& varValue)
00244 {
00245 string line = rawLine;
00246
00247
00248 while (find(line, varName) >= 0)
00249 {
00250 string b = before(line, varName);
00251 string a = after(line, varName);
00252 line = b + varValue + a;
00253 }
00254 return line;
00255 }
00256
00257
00258 string StrUtils::before(const string& str, char sub)
00259 {
00260 char c[2];
00261 c[0] = sub;
00262 c[1] = 0;
00263 return before(str, c);
00264 }
00265
00266 string StrUtils::before(const string& str, const string& sub)
00267 {
00268 TEST_FOR_EXCEPTION(sub.c_str()==0,
00269 runtime_error, "String::before: arg is null pointer");
00270
00271 char* p = strstr((char*) str.c_str(), (char*) sub.c_str());
00272 if (p==0) return str;
00273 int subLen = p-str.c_str();
00274 string rtn(str.c_str(), subLen);
00275 return rtn;
00276 }
00277
00278 string StrUtils::after(const string& str, const string& sub)
00279 {
00280 TEST_FOR_EXCEPTION(sub.c_str()==0,
00281 runtime_error, "String::after: arg is null pointer");
00282
00283
00284 char* p = strstr((char*) str.c_str(), (char*) sub.c_str()) ;
00285
00286 if (p==0) return string();
00287
00288 p+= strlen(sub.c_str());
00289 return string(p);
00290 }
00291
00292 int StrUtils::find(const string& str, const string& sub)
00293 {
00294 char* p = strstr((char*) str.c_str(), (char*) sub.c_str());
00295 if (p==0) return -1;
00296 return p-str.c_str();
00297 }
00298
00299 bool StrUtils::isWhite(const string& str)
00300 {
00301 for (int i=0; i<str.length(); i++)
00302 {
00303 unsigned char c = str[i];
00304 if (c >= 33 || c <= 126)
00305 {
00306 return false;
00307 }
00308 }
00309 return true;
00310 }
00311
00312 string StrUtils::fixUnprintableCharacters(const string& str)
00313 {
00314 string rtn = str;
00315 for (int i=0; i<rtn.length(); i++)
00316 {
00317 unsigned char c = rtn[i];
00318 if (c < 33 || c > 126)
00319 {
00320 if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ')
00321 {
00322 rtn[i] = ' ';
00323 }
00324 }
00325 }
00326 return rtn;
00327 }
00328
00329 string StrUtils::between(const string& str, const string& begin,
00330 const string& end, string& front,
00331 string& back)
00332 {
00333 front = before(str, begin);
00334 string middle = before(after(str, begin), end);
00335 back = after(str, end);
00336 return middle;
00337 }
00338
00339
00340 string StrUtils::subString(const string& str, int begin, int end)
00341 {
00342 return string(str.c_str()+begin, end-begin);
00343 }
00344
00345 string StrUtils::readFromStream(istream& is)
00346 {
00347 TEST_FOR_EXCEPTION(true, logic_error,
00348 "StrUtils::readFromStream isn't implemented yet");
00349
00350 return "";
00351 }
00352
00353 string StrUtils::allCaps(const string& s)
00354 {
00355 string rtn = s;
00356 for (unsigned int i=0; i<rtn.length(); i++)
00357 {
00358 rtn[i] = toupper(rtn[i]);
00359 }
00360 return rtn;
00361 }
00362
00363 double StrUtils::atof(const string& s)
00364 {
00365 return ::atof(s.c_str());
00366 }
00367
00368 int StrUtils::atoi(const string& s)
00369 {
00370 return ::atoi(s.c_str());
00371 }
00372
00373
00374
00375