etcFiles.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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2016 OpenFOAM Foundation
9 Copyright (C) 2017-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "etcFiles.H"
30#include "foamVersion.H"
31#include "OSspecific.H"
32
33#ifdef FULLDEBUG
34#ifndef FOAM_RESOURCE_USER_CONFIG_DIRNAME
35# warning FOAM_RESOURCE_USER_CONFIG_DIRNAME undefined (was this intentional?)
36#endif
37
38#ifndef FOAM_RESOURCE_SITE_ENVNAME
39# warning FOAM_RESOURCE_SITE_ENVNAME undefined (was this intentional?)
40#endif
41
42#ifndef FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
43# warning FOAM_RESOURCE_SITE_FALLBACK_ENVNAME undefined (was this intentional?)
44#endif
45#endif
46
47// Always use these names
48#undef FOAM_PROJECT_ENVNAME
49#define FOAM_PROJECT_ENVNAME "WM_PROJECT_DIR"
50
51// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
52
53//
54// Some of these could be exposed too (if required),
55// but are fairly special purpose.
56//
57
58namespace
59{
60
61// Return the file location mode as a string.
62//
63// - u : location mask 0700
64// - g : location mask 0070
65// - o : location mask 0007
66static inline std::string locationToString(unsigned short location)
67{
68 std::string mode;
69
70 if (location & 0700) { mode += 'u'; } // User
71 if (location & 0070) { mode += 'g'; } // Group
72 if (location & 0007) { mode += 'o'; } // Other
73 if (mode.empty()) { mode = "???"; }
74
75 return mode;
76}
77
78
79// Error handling when a mandatory entry is not found
80static inline void errorMandatoryNotFound
81(
82 const std::string& name,
83 unsigned short location
84)
85{
86 // Abort when mandatory entry was not found.
87 // Use a direct exit, since this could occur before anything is
88 // setup at all.
89
90 std::cerr
91 << "--> FOAM FATAL ERROR :\n"
92 " Could not find mandatory etc entry (mode="
93 << locationToString(location) << ")\n '"
94 << name << "'\n"
95 << std::endl;
96 std::exit(1);
97}
98
99
100// Assign 'queried' parameter to the user resource directory.
101// Return true if this directory exists.
102//
103// Corresponds to foamEtcFile -mode=u
104// Looks for
105// - ~/.OpenFOAM
106static inline bool userResourceDir(Foam::fileName& queried)
107{
108 #ifdef FOAM_RESOURCE_USER_CONFIG_DIRNAME
110 if (Foam::isDir(queried))
111 {
112 // If home() fails, it will have actually queried "./.OpenFOAM"
113 // instead.
114 // But we would have worse problems elsewhere if that were the case.
115 return true;
116 }
117 #endif
118
119 return false;
120}
121
122
123// Assign 'queried' parameter to the group resource directory.
124// Return true if this directory exists.
125// Otherwise clears the parameter and returns false.
126//
127// Corresponds to foamEtcFile -mode=g
128// Looks for
129// - ${WM_PROJECT_SITE}/etc
130// - ${WM_PROJECT_DIR}/site/etc
131//
132// Optionally (compile-time defined):
133// - FOAM_CONFIGURED_PROJECT_DIR/site/etc
134static inline bool groupResourceDir(Foam::fileName& queried)
135{
136 #ifdef FOAM_RESOURCE_SITE_ENVNAME
138 if (queried.size() > 4)
139 {
140 return Foam::isDir(queried);
141 }
142 #endif
143
144 // Fallback when WM_PROJECT_SITE is unset
145
146 #ifdef FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
148 if (queried.size() > 9 && Foam::isDir(queried))
149 {
150 return true;
151 }
152 #endif
153
154 // Compile-time paths
155 #ifdef FOAM_CONFIGURED_PROJECT_DIR
156 queried = FOAM_CONFIGURED_PROJECT_DIR "/site/etc";
157 if (queried.size() > 9 && Foam::isDir(queried))
158 {
159 return true;
160 }
161 #endif
162
163 queried.clear();
164 return false;
165}
166
167
168// Assign 'queried' parameter to the OpenFOAM etc/ resource directory.
169// Return true if it exists.
170// Otherwise clears the parameter and returns false.
171//
172// Corresponds to foamEtcFile -mode=o
173// Looks for
174// - ${WM_PROJECT_DIR}/etc
175//
176// Optionally (compile-time defined):
177// - FOAM_CONFIGURED_PROJECT_ETC
178// - FOAM_CONFIGURED_PROJECT_DIR/"etc"
179static inline bool projectResourceDir(Foam::fileName& queried)
180{
181 queried = Foam::getEnv(FOAM_PROJECT_ENVNAME)/"etc";
182 if (queried.size() > 4 && Foam::isDir(queried))
183 {
184 return true;
185 }
186
187 // Compile-time paths
188
189 #ifdef FOAM_CONFIGURED_PROJECT_ETC
190 queried = FOAM_CONFIGURED_PROJECT_ETC;
191 if (Foam::isDir(queried))
192 {
193 return true;
194 }
195 #endif
196
197 #ifdef FOAM_CONFIGURED_PROJECT_DIR
198 queried = FOAM_CONFIGURED_PROJECT_DIR "/etc";
199 if (queried.size() > 4 && Foam::isDir(queried))
200 {
201 return true;
202 }
203 #endif
204
205 queried.clear();
206 return false;
207}
208
209
210// Check if the named file/directory matches the type required.
211//
212// - typeRequired (UNDEFINED) => accept either FILE or DIRECTORY
213// - typeRequired (FILE | DIRECTORY) => accept only that type
214static inline bool accept
215(
216 const Foam::fileName& name,
217 const Foam::fileName::Type typeRequired
218)
219{
220 // followLink(true), checkGzip(true)
221 // -> returns (UNDEFINED | FILE | DIRECTORY), no need to check for (SYMLINK)
222 const auto t = name.type(true, true);
223
224 return
225 (
226 // Found something?
228 &&
229 (
230 // Any particular type required?
231 Foam::fileName::Type::UNDEFINED == typeRequired
233 : (typeRequired == t)
234 )
235 );
236}
237
238} // End anonymous namespace
239
240
241// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
242
244{
245 // Use foamVersion::api (instead of the OPENFOAM define) to ensure this
246 // stays properly synchronized with the build information
247 const Foam::fileName version(std::to_string(Foam::foamVersion::api));
248
249 Foam::fileNameList list(5);
250 Foam::fileName queried;
251 label nDirs = 0;
252
253 // User resource directories
254 if (userResourceDir(queried) || (!test && queried.size()))
255 {
256 list[nDirs++] = queried/version;
257 list[nDirs++] = queried;
258 }
259
260 // Group (site) resource directories
261 if (groupResourceDir(queried) || (!test && queried.size()))
262 {
263 list[nDirs++] = queried/version;
264 list[nDirs++] = queried;
265 }
266
267 // Other (project) resource directory
268 if (projectResourceDir(queried) || (!test && queried.size()))
269 {
270 list[nDirs++] = queried;
271 }
272
273 list.resize(nDirs);
274
275 return list;
276}
277
278
280(
281 const Foam::fileName& name,
282 unsigned short location,
283 const Foam::fileName::Type typeRequired,
284 const bool findFirst
285)
286{
287 // Debug Tracing
288 // std::cerr
289 // << "search ("<< locationToString(location) << "): "
290 // << name.c_str() << '\n';
291
292 if (!(location & 0777))
293 {
294 // Warn about bad location (mode) ... or make it FATAL?
295 std::cerr
296 << "--> FOAM Error :\n "
297 "No user/group/other location specified for 'etc' file"
298 " or directory\n '"
299 << name.c_str() << "'\n\n" << std::endl;
300 }
301
302 // Use foamVersion::api (instead of the OPENFOAM define) to ensure this
303 // stays properly synchronized with the build information
304 const Foam::fileName version(std::to_string(Foam::foamVersion::api));
305
307 Foam::fileName queried, candidate;
308
309 if (fileName::Type::FILE == typeRequired && name.empty())
310 {
311 // FILE must have a name to be found!
312 return list;
313 }
314
315
316 // User resource directories
317 if ((location & 0700) && userResourceDir(queried))
318 {
319 candidate = queried/version/name;
320 if (accept(candidate, typeRequired))
321 {
322 list.append(std::move(candidate));
323 if (findFirst)
324 {
325 return list;
326 }
327 }
328
329 candidate = queried/name;
330 if (accept(candidate, typeRequired))
331 {
332 list.append(std::move(candidate));
333 if (findFirst)
334 {
335 return list;
336 }
337 }
338 }
339
340
341 // Group (site) resource directories
342 if ((location & 0070) && groupResourceDir(queried))
343 {
344 candidate = queried/version/name;
345 if (accept(candidate, typeRequired))
346 {
347 list.append(std::move(candidate));
348 if (findFirst)
349 {
350 return list;
351 }
352 }
353
354 candidate = queried/name;
355 if (accept(candidate, typeRequired))
356 {
357 list.append(std::move(candidate));
358 if (findFirst)
359 {
360 return list;
361 }
362 }
363 }
364
365
366 // Other (project) resource directory
367 if ((location & 0007) && projectResourceDir(queried))
368 {
369 candidate = queried/name;
370 if (accept(candidate, typeRequired))
371 {
372 list.append(std::move(candidate));
373 }
374 }
375
376 return list;
377}
378
379
381(
382 const fileName& name,
383 unsigned short location,
384 const bool findFirst
385)
386{
387 return findEtcEntries(name, location, fileName::Type::DIRECTORY, findFirst);
388}
389
390
392(
393 const fileName& name,
394 const bool mandatory,
395 unsigned short location,
396 const bool findFirst
397)
398{
399 // Note: findEtcEntries checks name.size() for FILE
400 fileNameList list
401 (
402 findEtcEntries(name, location, fileName::Type::FILE, findFirst)
403 );
404
405 if (mandatory && list.empty())
406 {
407 errorMandatoryNotFound(name, location);
408 }
409
410 return list;
411}
412
413
415(
416 const fileName& name,
417 unsigned short location,
418 const Foam::fileName::Type typeRequired
419)
420{
421 // With findFirst(true)
422 fileNameList list(findEtcEntries(name, location, typeRequired, true));
423
425
426 if (list.size())
427 {
428 found = std::move(list.first());
429 }
430
431 return found;
432}
433
434
436(
437 const fileName& name,
438 unsigned short location
439)
440{
441 return findEtcEntry(name, location, fileName::Type::DIRECTORY);
442}
443
444
446(
447 const fileName& name,
448 const bool mandatory,
449 unsigned short location
450)
451{
452 fileName found(findEtcEntry(name, location, fileName::Type::FILE));
453
454 if (mandatory && found.empty())
455 {
456 errorMandatoryNotFound(name, location);
457 }
458
459 return found;
460}
461
462
463// ************************************************************************* //
#define FOAM_RESOURCE_USER_CONFIG_DIRNAME
Definition: JobInfo.C:40
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
bool found
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
T & first()
Return the first element of the list.
Definition: UListI.H:202
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A class for handling file names.
Definition: fileName.H:76
Type
Enumerations to handle directory entry types.
Definition: fileName.H:81
@ UNDEFINED
Undefined type.
Definition: fileName.H:82
#define FOAM_PROJECT_ENVNAME
Definition: etcFiles.C:49
Functions to search 'etc' directories for configuration files etc.
#define FOAM_RESOURCE_SITE_FALLBACK_ENVNAME
Definition: foamVersion.H:79
#define FOAM_RESOURCE_SITE_ENVNAME
The env name for site-resources to obtain a site-resources directory.
Definition: foamVersion.H:71
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
fileName findEtcFile(const fileName &name, const bool mandatory=false, unsigned short location=0777)
Search for a single FILE within the etc directories.
Definition: etcFiles.C:446
fileName findEtcDir(const fileName &name, unsigned short location=0777)
Search for a single FILE within the etc directories.
Definition: etcFiles.C:436
fileNameList findEtcEntries(const fileName &name, unsigned short location=0777, const fileName::Type typeRequired=fileName::Type::UNDEFINED, const bool findFirst=false)
Search for files or directories from user/group/other etc locations.
Definition: etcFiles.C:280
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
fileNameList findEtcDirs(const fileName &name, unsigned short location=0777, const bool findFirst=false)
Search for directories from user/group/other etc locations.
Definition: etcFiles.C:381
fileNameList etcDirs(bool test=true)
The etc search directories in the normal search order.
Definition: etcFiles.C:243
fileName home()
Return home directory path name for the current user.
Definition: MSwindows.C:457
fileNameList findEtcFiles(const fileName &name, const bool mandatory=false, unsigned short location=0777, const bool findFirst=false)
Search for files from user/group/other etc locations.
Definition: etcFiles.C:392
fileName findEtcEntry(const fileName &name, unsigned short location=0777, const fileName::Type typeRequired=fileName::Type::UNDEFINED)
Search for a single FILE or DIRECTORY within the etc directories.
Definition: etcFiles.C:415
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:651