initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / primitives / strings / string / string.C
blobe80b1e82210f73951883a284b02eae4d170e9e50
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "string.H"
28 #include "OSspecific.H"
30 /* * * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * * */
32 const char* const Foam::string::typeName = "string";
33 int Foam::string::debug(debug::debugSwitch(string::typeName, 0));
34 const Foam::string Foam::string::null;
36 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
38 // Count and return the number of a given character in the string
39 Foam::string::size_type Foam::string::count(const char c) const
41     register size_type cCount = 0;
43     for (const_iterator iter = begin(); iter != end(); ++iter)
44     {
45         if (*iter == c)
46         {
47             cCount++;
48         }
49     }
51     return cCount;
55 // Replace first occurence of sub-string oldStr with newStr
56 Foam::string& Foam::string::replace
58     const string& oldStr,
59     const string& newStr,
60     size_type start
63     size_type newStart = start;
65     if ((newStart = find(oldStr, newStart)) != npos)
66     {
67         std::string::replace(newStart, oldStr.size(), newStr);
68     }
70     return *this;
74 // Replace all occurences of sub-string oldStr with newStr
75 Foam::string& Foam::string::replaceAll
77     const string& oldStr,
78     const string& newStr,
79     size_type start
82     if (oldStr.size())
83     {
84         size_type newStart = start;
86         while ((newStart = find(oldStr, newStart)) != npos)
87         {
88             std::string::replace(newStart, oldStr.size(), newStr);
89             newStart += newStr.size();
90         }
91     }
93     return *this;
97 // Expand all occurences of environment variables and initial tilde sequences
98 Foam::string& Foam::string::expand()
100     size_type startEnvar = 0;
102     // Expand $VARS
103     // Repeat until nothing more is found
104     while
105     (
106         (startEnvar = find('$', startEnvar)) != npos
107      && startEnvar < size()-1
108     )
109     {
110         if (startEnvar == 0 || operator[](startEnvar-1) != '\\')
111         {
112             // Find end of first occurrence
113             size_type endEnvar = startEnvar;
114             size_type nd = 0;
116             if (operator[](startEnvar+1) == '{')
117             {
118                 endEnvar = find('}', startEnvar);
119                 nd = 1;
120             }
121             else
122             {
123                 iterator iter = begin() + startEnvar + 1;
125                 while (iter != end() && (isalnum(*iter) || *iter == '_'))
126                 {
127                     ++iter;
128                     ++endEnvar;
129                 }
130             }
132             if (endEnvar != npos && endEnvar != startEnvar)
133             {
134                 string enVar = substr
135                 (
136                     startEnvar + 1 + nd,
137                     endEnvar - startEnvar - 2*nd
138                 );
140                 string enVarString = getEnv(enVar);
142                 if (enVarString.size())
143                 {
144                     std::string::replace
145                     (
146                         startEnvar,
147                         endEnvar - startEnvar + 1,
148                         enVarString
149                     );
150                     startEnvar += enVarString.size();
151                 }
152                 else
153                 {
154                     //startEnvar = endEnvar;
156                     FatalErrorIn("string::expand()")
157                         << "Unknown variable name " << enVar << '.'
158                         << exit(FatalError);
159                 }
160             }
161             else
162             {
163                 break;
164             }
165         }
166         else
167         {
168             startEnvar++;
169         }
170     }
172     if (size())
173     {
174         if (operator[](0) == '~')
175         {
176             // Expand initial ~
177             //   ~/        => home directory
178             //   ~OpenFOAM => site/user OpenFOAM configuration directory
179             //   ~user     => home directory for specified user
181             word user;
182             fileName file;
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             }
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 == "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     }
220     return *this;
224 // Remove repeated characters returning true if string changed
225 bool Foam::string::removeRepeated(const char character)
227     bool changed = false;
229     if (character && find(character) != npos)
230     {
231         register string::size_type nChar=0;
232         iterator iter2 = begin();
234         register char prev = 0;
236         for
237         (
238             string::const_iterator iter1 = iter2;
239             iter1 != end();
240             iter1++
241         )
242         {
243             register char c = *iter1;
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     }
259     return changed;
263 // Return string with repeated characters removed
264 Foam::string Foam::string::removeRepeated(const char character) const
266     string str(*this);
267     str.removeRepeated(character);
268     return str;
272 // Remove trailing character returning true if string changed
273 bool Foam::string::removeTrailing(const char character)
275     bool changed = false;
277     string::size_type nChar = size();
278     if (character && nChar > 1 && operator[](nChar-1) == character)
279     {
280         resize(nChar-1);
281         changed = true;
282     }
284     return changed;
288 // Return string with trailing character removed
289 Foam::string Foam::string::removeTrailing(const char character) const
291     string str(*this);
292     str.removeTrailing(character);
293     return str;
297 // ************************************************************************* //