fileName.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
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 "fileName.H"
27 #include "wordList.H"
28 #include "DynamicList.H"
29 #include "OSspecific.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 const char* const Foam::fileName::typeName = "fileName";
34 int Foam::fileName::debug(debug::debugSwitch(fileName::typeName, 0));
36 
37 
38 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39 
41 {
42  forAll(lst, elemI)
43  {
44  operator=((*this)/lst[elemI]);
45  }
46 }
47 
48 
49 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
50 
52 (
53  const bool checkVariants,
54  const bool followLink
55 ) const
56 {
57  return ::Foam::type(*this, checkVariants, followLink);
58 }
59 
60 
62 {
63  return find('/') == npos;
64 }
65 
66 
68 {
69  return find('/') != npos;
70 }
71 
72 
74 {
75  return !empty() && operator[](0) == '/';
76 }
77 
78 
80 {
81  fileName& f = *this;
82 
83  if (!f.isAbsolute())
84  {
85  f = cwd()/f;
86  f.clean();
87  }
88 
89  return f;
90 }
91 
92 
94 {
95  // The top slash - we are never allowed to go above it
96  string::size_type top = this->find('/');
97 
98  // No slashes - nothing to do
99  if (top == string::npos)
100  {
101  return false;
102  }
103 
104  // Start with the '/' found:
105  char prev = '/';
106  string::size_type nChar = top+1;
107  string::size_type maxLen = this->size();
108 
109  for
110  (
111  string::size_type src = nChar;
112  src < maxLen;
113  )
114  {
115  char c = operator[](src++);
116 
117  if (prev == '/')
118  {
119  // Repeated '/' - skip it
120  if (c == '/')
121  {
122  continue;
123  }
124 
125  // Could be '/./' or '/../'
126  if (c == '.')
127  {
128  // Found trailing '/.' - skip it
129  if (src >= maxLen)
130  {
131  continue;
132  }
133 
134 
135  // Peek at the next character
136  char c1 = operator[](src);
137 
138  // Found '/./' - skip it
139  if (c1 == '/')
140  {
141  src++;
142  continue;
143  }
144 
145  // It is '/..' or '/../'
146  if (c1 == '.' && (src+1 >= maxLen || operator[](src+1) == '/'))
147  {
148  string::size_type parent;
149 
150  // Backtrack to find the parent directory
151  // Minimum of 3 characters: '/x/../'
152  // Strip it, provided it is above the top point
153  if
154  (
155  nChar > 2
156  && (parent = this->rfind('/', nChar-2)) != string::npos
157  && parent >= top
158  )
159  {
160  nChar = parent + 1; // Retain '/' from the parent
161  src += 2;
162  continue;
163  }
164 
165  // Bad resolution, eg 'abc/../../'
166  // Retain the sequence, but move the top to avoid it being
167  // considered a valid parent later
168  top = nChar + 2;
169  }
170  }
171  }
172  operator[](nChar++) = prev = c;
173  }
174 
175  // Remove trailing slash
176  if (nChar > 1 && operator[](nChar-1) == '/')
177  {
178  nChar--;
179  }
180 
181  this->resize(nChar);
182 
183  return (nChar != maxLen);
184 }
185 
186 
188 {
189  fileName fName(*this);
190  fName.clean();
191  return fName;
192 }
193 
194 
196 {
197  size_type i = rfind('/');
198 
199  if (i == npos)
200  {
201  return *this;
202  }
203  else
204  {
205  return substr(i+1, npos);
206  }
207 }
208 
209 
211 {
212  string cName = *this;
213 
214  const string caseStr(getEnv("FOAM_CASE"));
215 
216  const size_type i = find(caseStr);
217 
218  if (i == npos)
219  {
220  return cName;
221  }
222  else
223  {
224  return cName.replace(i, caseStr.size(), string("$FOAM_CASE"));
225  }
226 }
227 
228 
230 {
231  string cName = *this;
232 
233  const string caseStr(getEnv("FOAM_CASE"));
234 
235  const size_type i = find(caseStr);
236 
237  if (i == npos)
238  {
239  return cName;
240  }
241  else
242  {
243  return cName.erase(i, caseStr.size() + 1);
244  }
245 }
246 
247 
248 Foam::word Foam::fileName::name(const bool noExt) const
249 {
250  if (noExt)
251  {
252  size_type beg = rfind('/');
253  if (beg == npos)
254  {
255  beg = 0;
256  }
257  else
258  {
259  ++beg;
260  }
261 
262  size_type dot = rfind('.');
263  if (dot != npos && dot <= beg)
264  {
265  dot = npos;
266  }
267 
268  if (dot == npos)
269  {
270  return substr(beg, npos);
271  }
272  else
273  {
274  return substr(beg, dot - beg);
275  }
276  }
277  else
278  {
279  return this->name();
280  }
281 }
282 
283 
285 {
286  size_type i = rfind('/');
287 
288  if (i == npos)
289  {
290  return ".";
291  }
292  else if (i)
293  {
294  return substr(0, i);
295  }
296  else
297  {
298  return "/";
299  }
300 }
301 
302 
304 {
305  size_type i = find_last_of("./");
306 
307  if (i == npos || i == 0 || operator[](i) == '/')
308  {
309  return *this;
310  }
311  else
312  {
313  return substr(0, i);
314  }
315 }
316 
317 
319 {
320  size_type i = find_last_of("./");
321 
322  if (i == npos || i == 0 || operator[](i) == '/')
323  {
324  return word::null;
325  }
326  else
327  {
328  return substr(i+1, npos);
329  }
330 }
331 
332 
333 Foam::wordList Foam::fileName::components(const char delimiter) const
334 {
335  DynamicList<word> wrdList(20);
336 
337  size_type beg=0, end=0;
338 
339  while ((end = find(delimiter, beg)) != npos)
340  {
341  // Avoid empty element (caused by doubled slashes)
342  if (beg < end)
343  {
344  wrdList.append(substr(beg, end-beg));
345  }
346  beg = end + 1;
347  }
348 
349  // Avoid empty trailing element
350  if (beg < size())
351  {
352  wrdList.append(substr(beg, npos));
353  }
354 
355  // Transfer to wordList
356  return wordList(move(wrdList));
357 }
358 
359 
361 (
362  const size_type cmpt,
363  const char delimiter
364 ) const
365 {
366  return components(delimiter)[cmpt];
367 }
368 
369 
370 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
371 
373 {
374  string::operator=(str);
375 }
376 
377 
379 {
380  string::operator=(move(str));
381 }
382 
383 
385 {
386  string::operator=(str);
387 }
388 
389 
390 void Foam::fileName::operator=(const string& str)
391 {
392  string::operator=(str);
393  stripInvalid();
394 }
395 
396 
397 void Foam::fileName::operator=(const std::string& str)
398 {
399  string::operator=(str);
400  stripInvalid();
401 }
402 
403 
404 void Foam::fileName::operator=(const char* str)
405 {
406  string::operator=(str);
407  stripInvalid();
408 }
409 
410 
411 void Foam::fileName::operator/=(const string& str)
412 {
413  operator=(operator/(*this, str));
414 }
415 
416 
417 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
418 
419 Foam::fileName Foam::operator/(const string& a, const string& b)
420 {
421  if (a.size()) // First string non-null
422  {
423  if (b.size()) // Second string non-null
424  {
425  return fileName(a + '/' + b);
426  }
427  else // Second string null
428  {
429  return a;
430  }
431  }
432  else // First string null
433  {
434  if (b.size()) // Second string non-null
435  {
436  return b;
437  }
438  else // Second string null
439  {
440  return fileName();
441  }
442  }
443 }
444 
445 
446 // ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
A class for handling file names.
Definition: fileName.H:82
bool isName() const
Return true if file name is a name without a path.
Definition: fileName.C:61
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:73
bool clean()
Cleanup file name.
Definition: fileName.C:93
string caseName() const
Return file name (part beyond last /), substitute for FOAM_CASE.
Definition: fileName.C:210
wordList components(const char delimiter='/') const
Return path components as wordList.
Definition: fileName.C:333
word name() const
Return file name (part beyond last /)
Definition: fileName.C:195
bool hasPath() const
Return true if file name has a path.
Definition: fileName.C:67
fileName()
Construct null.
Definition: fileNameI.H:52
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:303
fileType type(const bool checkVariants=true, const bool followLink=true) const
Return the file type: file, directory, undefined or.
Definition: fileName.C:52
void operator=(const fileName &)
Definition: fileName.C:372
static const fileName null
An empty fileName.
Definition: fileName.H:97
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:318
fileName & toAbsolute()
Convert from relative to absolute.
Definition: fileName.C:79
fileName path() const
Return directory path name (part before last /)
Definition: fileName.C:284
static int debug
Definition: fileName.H:94
word component(const size_type, const char delimiter='/') const
Return a single component of the path.
Definition: fileName.C:361
void operator/=(const string &)
Add a string to the fileName with a '/' separator.
Definition: fileName.C:411
string relativePath() const
Return file name part relative to FOAM_CASE.
Definition: fileName.C:229
static const char *const typeName
Definition: fileName.H:93
A class for handling character strings derived from std::string.
Definition: string.H:79
string & replace(const string &oldStr, const string &newStr, size_type start=0)
In this string replace first occurrence of sub-string oldStr.
Definition: string.C:64
void operator=(const string &)
Definition: stringI.H:229
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
volScalarField & b
Definition: createFields.H:27
const dimensionedScalar c1
First radiation constant: default SI units: [W/m^2].
const dimensionedScalar c
Speed of light in a vacuum.
int debugSwitch(const char *name, const int defaultValue=0)
Lookup debug switch or add default value.
Definition: debug.C:211
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
void dot(LagrangianPatchField< typename innerProduct< Type1, Type2 >::type > &f, const LagrangianPatchField< Type1 > &f1, const LagrangianPatchField< Type2 > &f2)
List< word > wordList
A List of words.
Definition: fileName.H:54
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
fileType
Enumeration of file types.
Definition: fileName.H:67
tmp< fvMatrix< Type > > operator/(const fvMatrix< Type > &, const volScalarField::Internal &)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
labelList f(nPoints)
triSurfaceToAgglom resize(surfacesMesh.size())