Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_StrUtils.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include "Teuchos_StrUtils.hpp"
43 #include "Teuchos_Assert.hpp"
44 
45 
46 namespace Teuchos {
47 
48 
49 Array<std::string> StrUtils::readFile(std::istream& is, char comment)
50 {
51  std::string line;
52  Array<std::string> rtn(0);
53 
54  while (readLine(is, line))
55  {
56  if (line.length() > 0) rtn.append(before(line, comment));
57  line="";
58  }
59 
60  return rtn;
61 }
62 
63 
65 {
66  int begin = 0;
68  const size_t len = input.length();
69  for (size_t p=0; p<len; ++p) {
70  const bool isEnd = p==len-1;
71  if( input[p]=='\n' || input[p]=='\0' || input[p]=='\r' || isEnd )
72  {
73  if (p-begin > 1)
74  rtn.append(
75  subString( input, begin, p+(isEnd?(input[len-1]=='\n'?0:1):0) )
76  );
77  begin = p+1;
78  }
79  }
80  return rtn;
81 }
82 
83 
84 Array<Array<std::string> > StrUtils::tokenizeFile(std::istream& is, char comment)
85 {
86  std::string line;
87  Array<Array<std::string> > rtn(0);
88  Array<std::string> lines = readFile(is, comment);
89  rtn.reserve(lines.length());
90 
91  int count = 0;
92  for (int i=0; i<lines.length(); i++)
93  {
94  if (lines[i].length() == 0) continue;
95  Array<std::string> tokens = stringTokenizer(lines[i]);
96  if (tokens.length() == 0) continue;
97  rtn.append(tokens);
98  count++;
99  }
100 
101  return rtn;
102 }
103 
104 
105 bool StrUtils::readLine(std::istream& is, std::string& line)
106 {
107  char c[500];
108  if (line.length() > 0) line[0] = '\0';
109 
110  if (is.eof()) return false;
111  if (is.getline(c, 499))
112  {
113  line = std::string(c);
114  }
115 
116  return true;
117 }
118 
119 
121  Array<std::string> rtn(0);
122  unsigned int start = 0;
123 
124  while(start < str.length())
125  {
126  unsigned int wordStart = findNextNonWhitespace(str, start);
127  /* add any preceding whitespace */
128  if (wordStart > start)
129  {
130  rtn.append(subString(str, start, wordStart));
131  }
132  start = wordStart;
133  /* add the next word */
134  int stop = findNextWhitespace(str, start);
135  if (start-stop == 0) return rtn;
136  std::string sub = subString(str, start, stop);
137  rtn.append(sub);
138  start = stop;// findNextNonWhitespace(str, stop);
139  }
140  return rtn;
141 }
142 
143 
145  Array<std::string> rtn(0);
146  unsigned int start = 0;
147 
148  while(start < str.length())
149  {
150  start = findNextNonWhitespace(str, start);
151  int stop = findNextWhitespace(str, start);
152  if (start-stop == 0) return rtn;
153  std::string sub = subString(str, start, stop);
154  rtn.append(sub);
155  start = findNextNonWhitespace(str, stop);
156  }
157  return rtn;
158 }
159 
160 
162  int iStart)
163 {
164  std::string rtn;
165 
166  for (int i=iStart; i<tokens.length(); i++)
167  {
168  rtn += tokens[i];
169  if (i < (tokens.length()-1)) rtn += " ";
170  }
171  return rtn;
172 }
173 
174 
175 void StrUtils::splitList(const std::string& big, Array<std::string>& list)
176 {
177  if (subString(big, 0,1)!="[")
178  {
179  list.resize(1);
180  list[0] = big;
181  return;
182  }
183 
184  int parenDepth = 0;
185  int localCount = 0;
186  std::string tmp(big);
187  list.resize(0);
188 
189  // start at 1 to ignore '[';
190 
191  for (unsigned int i=1; i<big.length(); i++)
192  {
193  if (big[i]=='(') parenDepth++;
194  if (big[i]==')') parenDepth--;
195  if (big[i]==']')
196  {
197  tmp[localCount]='\0';
198  list.append(tmp);
199  break;
200  }
201  if (big[i]==',' && parenDepth==0)
202  {
203  tmp[localCount]='\0';
204  list.append(tmp);
205  tmp = big;
206  localCount = 0;
207  continue;
208  }
209  tmp[localCount] = big[i];
210  localCount++;
211  }
212 }
213 
214 
215 // return the position of the next whitespace in a std::string.
216 // If no whitespace, return -1;
217 
218 int StrUtils::findNextWhitespace(const std::string& str, int offset)
219 {
220  for (unsigned int i=0; i<(str.length()-offset); i++)
221  {
222  if (str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n')
223  {
224  return i+offset;
225  }
226  }
227  return static_cast<int>(str.length());
228 }
229 
230 
231 int StrUtils::findNextNonWhitespace(const std::string& str, int offset)
232 {
233  for (unsigned int i=0; i<(str.length()-offset); i++)
234  {
235  if (!(str[i+offset]==' ' || str[i+offset]=='\t' || str[i+offset]=='\n'))
236  {
237  return i+offset;
238  }
239  }
240  return static_cast<int>(str.length());
241 }
242 
243 
244 std::string StrUtils::varTableSubstitute(const std::string& rawLine,
245  const Array<std::string>& varNames,
246  const Array<std::string>& varValues)
247 {
248  TEUCHOS_TEST_FOR_EXCEPTION(varNames.length() != varValues.length(),
249  std::runtime_error,
250  "mismatched variable tables in varTableSubstitute");
251 
252  std::string line = rawLine;
253  for (int i=0; i<varNames.length(); i++)
254  {
255  line = varSubstitute(line, varNames[i], varValues[i]);
256  }
257  return line;
258 }
259 
260 
261 std::string StrUtils::varSubstitute(const std::string& rawLine,
262  const std::string& varName,
263  const std::string& varValue)
264 {
265  std::string line = rawLine;
266 
267  // iterate because there might be more than one occurrence on this line
268  while (find(line, varName) >= 0)
269  {
270  std::string b = before(line, varName);
271  std::string a = after(line, varName);
272  line = b + varValue + a;
273  }
274  return line;
275 }
276 
277 
278 std::string StrUtils::before(const std::string& str, char sub)
279 {
280  char c[2];
281  c[0] = sub;
282  c[1] = 0;
283  return before(str, c);
284 }
285 
286 
287 std::string StrUtils::before(const std::string& str, const std::string& sub)
288 {
289  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
290  std::runtime_error, "String::before: arg is null pointer");
291 
292  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
293  if (p==0) return str;
294  int subLen = static_cast<int>(p-str.c_str());
295  std::string rtn(str.c_str(), subLen);
296  return rtn;
297 }
298 
299 
300 std::string StrUtils::after(const std::string& str, const std::string& sub)
301 {
302  TEUCHOS_TEST_FOR_EXCEPTION(sub.c_str()==0,
303  std::runtime_error, "String::after: arg is null pointer");
304 
305  // find beginning of substring
306  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str()) ;
307  // if substring not found, return empty std::string
308  if (p==0) return std::string();
309  // offset to end of substring
310  p+= std::strlen(sub.c_str());
311  return std::string(p);
312 }
313 
314 
315 int StrUtils::find(const std::string& str, const std::string& sub)
316 {
317  char* p = std::strstr((char*) str.c_str(), (char*) sub.c_str());
318  if (p==0) return -1;
319  return static_cast<int>(p-str.c_str());
320 }
321 
322 
323 bool StrUtils::isWhite(const std::string& str)
324 {
325  for (unsigned int i=0; i<str.length(); i++)
326  {
327  unsigned char c = str[i];
328  if (c >= 33 && c <= 126)
329  {
330  return false;
331  }
332  }
333  return true;
334 }
335 
336 
337 std::string StrUtils::fixUnprintableCharacters(const std::string& str)
338 {
339  std::string rtn = str;
340  for (unsigned int i=0; i<rtn.length(); i++)
341  {
342  unsigned char c = rtn[i];
343  if (c < 33 || c > 126)
344  {
345  if (c != '\t' && c != '\n'&& c != '\r' && c != '\f' && c != ' ')
346  {
347  rtn[i] = ' ';
348  }
349  }
350  }
351  return rtn;
352 }
353 
354 
355 std::string StrUtils::between(const std::string& str, const std::string& begin,
356  const std::string& end, std::string& front,
357  std::string& back)
358 {
359  front = before(str, begin);
360  std::string middle = before(after(str, begin), end);
361  back = after(str, end);
362  return middle;
363 }
364 
365 
366 std::string StrUtils::subString(const std::string& str, int begin, int end)
367 {
368  return std::string(str.c_str()+begin, end-begin);
369 }
370 
371 
372 std::string StrUtils::readFromStream(std::istream& /* is */)
373 {
374  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
375  "StrUtils::readFromStream isn't implemented yet");
376 
377  // NOTE (mfh 15 Sep 2014): Most compilers have figured out that the
378  // return statement below is unreachable. Some older compilers
379  // might not realize this. That's why the return statement was put
380  // there, so that those compilers don't warn that this function
381  // doesn't return a value. If it's a choice between one warning and
382  // another, I would prefer the choice that produces less code and
383  // doesn't have unreachable code (which never gets tested).
384 
385  //return "";
386 }
387 
388 
389 std::string StrUtils::allCaps(const std::string& s)
390 {
391  std::string rtn = s;
392  for (unsigned int i=0; i<rtn.length(); i++)
393  {
394  rtn[i] = toupper(rtn[i]);
395  }
396  return rtn;
397 }
398 
399 
400 double StrUtils::atof(const std::string& s)
401 {
402  return std::atof(s.c_str());
403 }
404 
405 
406 int StrUtils::atoi(const std::string& s)
407 {
408  return std::atoi(s.c_str());
409 }
410 
411 
412 std::ostream& StrUtils::printLines(
413  std::ostream &os
414  ,const std::string &linePrefix
415  ,const std::string &lines
416  )
417 {
418  typedef Teuchos::Array<std::string> array_t;
419  array_t linesArray = splitIntoLines(lines);
420  for( int i = 0; i < static_cast<int>(linesArray.size()); ++i )
421  {
422  os << linePrefix << linesArray[i] << "\n";
423  }
424  return os;
425 }
426 
427 
428 std::string StrUtils::removeAllSpaces(std::string stringToClean)
429 {
430  std::string::size_type pos=0;
431  bool spacesLeft = true;
432 
433  while(spacesLeft){
434  pos = stringToClean.find(" ");
435  if(pos != string::npos){
436  stringToClean.erase(pos,1);
437  }
438  else{
439  spacesLeft = false;
440  }
441  }
442  return stringToClean;
443 }
444 
445 
446 } // namespace Teuchos
void reserve(size_type n)
static std::string removeAllSpaces(std::string stringToClean)
Removes all the spaces in a string.
Array< T > & append(const T &x)
Add a new entry at the end of the array.
static int findNextNonWhitespace(const std::string &str, int offset)
static std::string allCaps(const std::string &str)
Converts a std::string to all upper case.
static Array< Array< std::string > > tokenizeFile(std::istream &is, char comment)
Tokenize a file into whitespace-delimited tokens.
static std::string after(const std::string &str, const std::string &sub)
Find the substring after a specified substring. For example, before(&quot;abcdefghij&quot;, &quot;gh&quot;) returns &quot;ij&quot;...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static Array< std::string > splitIntoLines(const std::string &input)
Split an input std::string that contains newlines into an array of strings, one for each line...
static std::ostream & printLines(std::ostream &os, const std::string &linePrefix, const std::string &lines)
Print lines with prefix first.
static bool readLine(std::istream &is, std::string &line)
Read a single line into a std::string.
static double atof(const std::string &str)
Returns the double value of a std::string.
A std::string utilities class for Teuchos.
static std::string between(const std::string &str, const std::string &begin, const std::string &end, std::string &front, std::string &back)
Returns the std::string between two delimiting strings, and returns by reference the strings before a...
static std::string varSubstitute(const std::string &rawLine, const std::string &varName, const std::string &varValue)
static std::string subString(const std::string &str, int begin, int end)
Returns the substring between two positions.
static std::string reassembleFromTokens(const Array< std::string > &tokens, int iStart=0)
static std::string before(const std::string &str, const std::string &sub)
Find the substring before a specified substring. For example, before(&quot;abcdefghij&quot;, &quot;gh&quot;) returns &quot;abcdef&quot;.
static std::string varTableSubstitute(const std::string &rawLine, const Array< std::string > &varNames, const Array< std::string > &varValues)
void resize(size_type new_size, const value_type &x=value_type())
static bool isWhite(const std::string &str)
Returns true if a std::string consists entirely of whitespace.
static std::string fixUnprintableCharacters(const std::string &str)
Convert unprintable non-null characters to whitespace.
int length() const
Return number of elements in the array.
static Array< std::string > stringTokenizer(const std::string &str)
static Array< std::string > readFile(std::istream &is, char comment)
Read a file, putting each line into a std::string.
static int atoi(const std::string &str)
Returns the int value of a std::string.
static Array< std::string > getTokensPlusWhitespace(const std::string &str)
static void splitList(const std::string &bigstring, Array< std::string > &elements)
static int findNextWhitespace(const std::string &str, int offset)
static int find(const std::string &str, const std::string &sub)
Find the position at which a substring first occurs. For example, find(&quot;abcdefghij&quot;, &quot;gh&quot;) returns 6.