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