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