Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_StrUtils.cpp
Go to the documentation of this file.
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_TestForException.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   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   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   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   TEST_FOR_EXCEPTION(true, std::logic_error, 
00375     "StrUtils::readFromStream isn't implemented yet");
00376 
00377   return "";
00378 }
00379 
00380 
00381 std::string StrUtils::allCaps(const std::string& s)
00382 {
00383   std::string rtn = s;
00384   for (unsigned int i=0; i<rtn.length(); i++)
00385   {
00386     rtn[i] = toupper(rtn[i]);
00387   }
00388   return rtn;
00389 }
00390 
00391 
00392 double StrUtils::atof(const std::string& s)
00393 {
00394   return std::atof(s.c_str());
00395 }
00396 
00397 
00398 int StrUtils::atoi(const std::string& s)
00399 {
00400   return std::atoi(s.c_str());
00401 }
00402 
00403 
00404 std::ostream& StrUtils::printLines(
00405   std::ostream             &os
00406   ,const std::string       &linePrefix
00407   ,const std::string       &lines
00408   )
00409 {
00410   typedef Teuchos::Array<std::string> array_t;
00411   array_t linesArray = splitIntoLines(lines);
00412   for( int i = 0; i < static_cast<int>(linesArray.size()); ++i )
00413   {
00414     os << linePrefix << linesArray[i] << "\n";
00415   }
00416   return os;
00417 }
00418 
00419 
00420 std::string StrUtils::removeAllSpaces(std::string stringToClean)
00421 {
00422   std::string::size_type pos=0;
00423   bool spacesLeft = true;
00424 
00425   while(spacesLeft){
00426     pos = stringToClean.find(" ");
00427     if(pos != string::npos){
00428       stringToClean.erase(pos,1);
00429     }
00430     else{
00431       spacesLeft = false;
00432     }
00433   }
00434   return stringToClean;
00435 }
00436 
00437   
00438 } // namespace Teuchos
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines