Teuchos_StrUtils.cpp

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<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       /* add any preceding whitespace */
00111       if (wordStart > start)
00112         {
00113           rtn.append(subString(str, start, wordStart));
00114         }
00115       start = wordStart;
00116       /* add the next word */
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;// findNextNonWhitespace(str, 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   // start at 1 to ignore '[';
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 // return the position of the next whitespace in a string. 
00195 // If no whitespace, return -1;
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   // iterate because there might be more than one occurance on this line
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   // find beginning of substring
00284   char* p = strstr((char*) str.c_str(), (char*) sub.c_str()) ;
00285   // if substring not found, return empty string
00286   if (p==0) return string();
00287   // offset to end of substring
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   

Generated on Thu Sep 18 12:39:10 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1