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