FreeFOAM The Cross-Platform CFD Toolkit
string.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "string.H"
27 #include <OpenFOAM/OSspecific.H>
28 
29 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
30 
31 const char* const Foam::string::typeName = "string";
32 int Foam::string::debug(debug::debugSwitch(string::typeName, 0));
34 
35 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
36 
37 // Count and return the number of a given character in the string
38 Foam::string::size_type Foam::string::count(const char c) const
39 {
40  register size_type cCount = 0;
41 
42  for (const_iterator iter = begin(); iter != end(); ++iter)
43  {
44  if (*iter == c)
45  {
46  cCount++;
47  }
48  }
49 
50  return cCount;
51 }
52 
53 
54 // Replace first occurence of sub-string oldStr with newStr
56 (
57  const string& oldStr,
58  const string& newStr,
59  size_type start
60 )
61 {
62  size_type newStart = start;
63 
64  if ((newStart = find(oldStr, newStart)) != npos)
65  {
66  std::string::replace(newStart, oldStr.size(), newStr);
67  }
68 
69  return *this;
70 }
71 
72 
73 // Replace all occurences of sub-string oldStr with newStr
75 (
76  const string& oldStr,
77  const string& newStr,
78  size_type start
79 )
80 {
81  if (oldStr.size())
82  {
83  size_type newStart = start;
84 
85  while ((newStart = find(oldStr, newStart)) != npos)
86  {
87  std::string::replace(newStart, oldStr.size(), newStr);
88  newStart += newStr.size();
89  }
90  }
91 
92  return *this;
93 }
94 
95 
96 // Expand all occurences of environment variables and initial tilde sequences
98 {
99  size_type startEnvar = 0;
100 
101  // Expand $VARS
102  // Repeat until nothing more is found
103  while
104  (
105  (startEnvar = find('$', startEnvar)) != npos
106  && startEnvar < size()-1
107  )
108  {
109  if (startEnvar == 0 || operator[](startEnvar-1) != '\\')
110  {
111  // Find end of first occurrence
112  size_type endEnvar = startEnvar;
113  size_type nd = 0;
114 
115  if (operator[](startEnvar+1) == '{')
116  {
117  endEnvar = find('}', startEnvar);
118  nd = 1;
119  }
120  else
121  {
122  iterator iter = begin() + startEnvar + 1;
123 
124  while (iter != end() && (isalnum(*iter) || *iter == '_'))
125  {
126  ++iter;
127  ++endEnvar;
128  }
129  }
130 
131  if (endEnvar != npos && endEnvar != startEnvar)
132  {
133  string enVar = substr
134  (
135  startEnvar + 1 + nd,
136  endEnvar - startEnvar - 2*nd
137  );
138 
139  string enVarString = getEnv(enVar);
140 
141  if (enVarString.size())
142  {
143  std::string::replace
144  (
145  startEnvar,
146  endEnvar - startEnvar + 1,
147  enVarString
148  );
149  startEnvar += enVarString.size();
150  }
151  else
152  {
153  //startEnvar = endEnvar;
154 
155  FatalErrorIn("string::expand()")
156  << "Unknown variable name " << enVar << '.'
157  << exit(FatalError);
158  }
159  }
160  else
161  {
162  break;
163  }
164  }
165  else
166  {
167  startEnvar++;
168  }
169  }
170 
171  if (size())
172  {
173  if (operator[](0) == '~')
174  {
175  // Expand initial ~
176  // ~/ => home directory
177  // ~FreeFOAM => site/user FreeFOAM configuration directory
178  // ~OpenFOAM => site/user FreeFOAM configuration directory (alias for FreeFOAM)
179  // ~user => home directory for specified user
180 
181  word user;
182  fileName file;
183 
184  if ((startEnvar = find('/')) != npos)
185  {
186  user = substr(1, startEnvar - 1);
187  file = substr(startEnvar + 1);
188  }
189  else
190  {
191  user = substr(1);
192  }
193 
194  // NB: be a bit lazy and expand ~unknownUser as an
195  // empty string rather than leaving it untouched.
196  // otherwise add extra test
197  if (user == "FreeFOAM" || user == "OpenFOAM")
198  {
199  *this = findEtcFile(file);
200  }
201  else
202  {
203  *this = home(user)/file;
204  }
205  }
206  else if (operator[](0) == '.')
207  {
208  // Expand initial '.' and './' into cwd
209  if (size() == 1)
210  {
211  *this = cwd();
212  }
213  else if (operator[](1) == '/')
214  {
215  std::string::replace(0, 1, cwd());
216  }
217  }
218  }
219 
220  return *this;
221 }
222 
223 
224 // Remove repeated characters returning true if string changed
225 bool Foam::string::removeRepeated(const char character)
226 {
227  bool changed = false;
228 
229  if (character && find(character) != npos)
230  {
231  register string::size_type nChar=0;
232  iterator iter2 = begin();
233 
234  register char prev = 0;
235 
236  for
237  (
238  string::const_iterator iter1 = iter2;
239  iter1 != end();
240  iter1++
241  )
242  {
243  register char c = *iter1;
244 
245  if (prev == c && c == character)
246  {
247  changed = true;
248  }
249  else
250  {
251  *iter2 = prev = c;
252  ++iter2;
253  ++nChar;
254  }
255  }
256  resize(nChar);
257  }
258 
259  return changed;
260 }
261 
262 
263 // Return string with repeated characters removed
264 Foam::string Foam::string::removeRepeated(const char character) const
265 {
266  string str(*this);
267  str.removeRepeated(character);
268  return str;
269 }
270 
271 
272 // Remove trailing character returning true if string changed
273 bool Foam::string::removeTrailing(const char character)
274 {
275  bool changed = false;
276 
277  string::size_type nChar = size();
278  if (character && nChar > 1 && operator[](nChar-1) == character)
279  {
280  resize(nChar-1);
281  changed = true;
282  }
283 
284  return changed;
285 }
286 
287 
288 // Return string with trailing character removed
289 Foam::string Foam::string::removeTrailing(const char character) const
290 {
291  string str(*this);
292  str.removeTrailing(character);
293  return str;
294 }
295 
296 
297 // ************************ vim: set sw=4 sts=4 et: ************************ //