mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support search modes for etcFiles()
- similar to the foamEtcFile script -mode=... option, the specific
search location (user/group/other) can now also specified for
string expansions and as a numerical value for etcFile()
For example, if searching for group or other (project) controlDict,
but not wishing to see the user controlDict:
1. foamEtcFile -mode=go controlDict
2. fileName dictFile("<etc:go>/controlDict");
dictFile.expand();
3. etcFile(controlDict, false, 0077);
The default behaviour for searching all contexts is unchanged.
1. foamEtcFile controlDict
2. fileName dictFile("<etc>/controlDict");
dictFile.expand();
3. etcFile(controlDict);
This commit is contained in:
@ -102,6 +102,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This should and will fail:
|
||||
//// Info<<"find bad file:" << nl
|
||||
//// << findEtcFile("##BadName##", true) << "FAIL" << endl;
|
||||
|
||||
|
||||
const bool listAll = (args.found("all") || args.found("list"));
|
||||
|
||||
int error = 0;
|
||||
|
||||
@ -102,6 +102,13 @@ int main(int argc, char *argv[])
|
||||
:
|
||||
{
|
||||
"~OpenFOAM/controlDict", "<etc>/controlDict",
|
||||
"<etc:ugo>/controlDict",
|
||||
"<etc:u>/controlDict",
|
||||
"<etc:ug>/controlDict",
|
||||
"<etc:go>/controlDict",
|
||||
"<etc:o>/controlDict",
|
||||
"<etc:JUNK>/controlDict", // rubbish input
|
||||
"<etc:>/controlDict", // rubbish input
|
||||
"$FOAM_CASE/xyz", "<case>/xyz",
|
||||
"$FOAM_CASE/constant/xyz", "<constant>/xyz",
|
||||
"$FOAM_CASE/system/xyz", "<system>/xyz",
|
||||
|
||||
@ -240,12 +240,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
fileName baseDir
|
||||
(
|
||||
"${WM_PROJECT_DIR}/etc/caseDicts/createZeroDirectoryTemplates"
|
||||
args.opt<fileName>
|
||||
(
|
||||
"templateDir",
|
||||
// Default is from PROJECT/etc directory
|
||||
"<etc:o>/caseDicts/createZeroDirectoryTemplates"
|
||||
)
|
||||
);
|
||||
if (args.found("templateDir"))
|
||||
{
|
||||
baseDir = args["templateDir"];
|
||||
}
|
||||
|
||||
baseDir.expand();
|
||||
baseDir.toAbsolute();
|
||||
|
||||
@ -30,12 +30,32 @@ License
|
||||
// * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * * //
|
||||
|
||||
//
|
||||
// These could be exposed too (if required), but are fairly special purpose.
|
||||
// Some of these could be exposed too (if required),
|
||||
// but are fairly special purpose.
|
||||
//
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Return the file location mode as a string.
|
||||
//
|
||||
// - u : location mask 0700
|
||||
// - g : location mask 0070
|
||||
// - o : location mask 0007
|
||||
//
|
||||
static inline std::string locationToString(unsigned short location)
|
||||
{
|
||||
std::string mode;
|
||||
|
||||
if (location & 0700) { mode += 'u'; } // User
|
||||
if (location & 0070) { mode += 'g'; } // Group
|
||||
if (location & 0007) { mode += 'o'; } // Other
|
||||
if (mode.empty()) { mode = "???"; }
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
// Assign 'queried' parameter to the user resource directory.
|
||||
// Return true if this directory exists.
|
||||
//
|
||||
@ -64,6 +84,7 @@ static inline bool userResourceDir(Foam::fileName& queried)
|
||||
|
||||
// Assign 'queried' parameter to the group resource directory.
|
||||
// Return true if this directory exists.
|
||||
// Otherwise clears the parameter and returns false.
|
||||
//
|
||||
// Corresponds to foamEtcFile -mode=g
|
||||
// Looks for
|
||||
@ -102,6 +123,7 @@ static inline bool groupResourceDir(Foam::fileName& queried)
|
||||
|
||||
// Assign 'queried' parameter to the OpenFOAM etc/ resource directory.
|
||||
// Return true if it exists.
|
||||
// Otherwise clears the parameter and returns false.
|
||||
//
|
||||
// Corresponds to foamEtcFile -mode=o
|
||||
// Looks for
|
||||
@ -122,6 +144,7 @@ static inline bool projectResourceDir(Foam::fileName& queried)
|
||||
Foam::fileNameList searchEtc
|
||||
(
|
||||
const Foam::fileName& name,
|
||||
unsigned short location,
|
||||
const bool findFirst,
|
||||
bool (*accept)(const Foam::fileName&)
|
||||
)
|
||||
@ -131,13 +154,23 @@ Foam::fileNameList searchEtc
|
||||
const Foam::fileName version(std::to_string(Foam::foamVersion::api));
|
||||
|
||||
Foam::fileNameList list;
|
||||
Foam::fileName dir, candidate;
|
||||
Foam::fileName queried, candidate;
|
||||
|
||||
if (!(location & 0777))
|
||||
{
|
||||
// Warn about bad location (mode) ... or make it FATAL?
|
||||
std::cerr
|
||||
<< "--> FOAM Error :\n "
|
||||
"No user/group/other location specified for 'etc' file"
|
||||
" or directory\n '"
|
||||
<< name.c_str() << "'\n\n" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
// User resource directories
|
||||
if (userResourceDir(dir))
|
||||
if ((location & 0700) && userResourceDir(queried))
|
||||
{
|
||||
candidate = dir/version/name;
|
||||
candidate = queried/version/name;
|
||||
if (accept(candidate))
|
||||
{
|
||||
list.append(std::move(candidate));
|
||||
@ -147,7 +180,7 @@ Foam::fileNameList searchEtc
|
||||
}
|
||||
}
|
||||
|
||||
candidate = dir/name;
|
||||
candidate = queried/name;
|
||||
if (accept(candidate))
|
||||
{
|
||||
list.append(std::move(candidate));
|
||||
@ -159,9 +192,9 @@ Foam::fileNameList searchEtc
|
||||
}
|
||||
|
||||
// Group (site) resource directories
|
||||
if (groupResourceDir(dir))
|
||||
if ((location & 0070) && groupResourceDir(queried))
|
||||
{
|
||||
candidate = dir/version/name;
|
||||
candidate = queried/version/name;
|
||||
if (accept(candidate))
|
||||
{
|
||||
list.append(std::move(candidate));
|
||||
@ -171,7 +204,7 @@ Foam::fileNameList searchEtc
|
||||
}
|
||||
}
|
||||
|
||||
candidate = dir/name;
|
||||
candidate = queried/name;
|
||||
if (accept(candidate))
|
||||
{
|
||||
list.append(std::move(candidate));
|
||||
@ -183,9 +216,9 @@ Foam::fileNameList searchEtc
|
||||
}
|
||||
|
||||
// Other (project) resource directory
|
||||
if (projectResourceDir(dir))
|
||||
if ((location & 0007) && projectResourceDir(queried))
|
||||
{
|
||||
candidate = dir/name;
|
||||
candidate = queried/name;
|
||||
if (accept(candidate))
|
||||
{
|
||||
list.append(std::move(candidate));
|
||||
@ -207,27 +240,27 @@ Foam::fileNameList Foam::etcDirs(bool test)
|
||||
const Foam::fileName version(std::to_string(Foam::foamVersion::api));
|
||||
|
||||
Foam::fileNameList list(5);
|
||||
Foam::fileName dir;
|
||||
Foam::fileName queried;
|
||||
label nDirs = 0;
|
||||
|
||||
// User resource directories
|
||||
if (userResourceDir(dir) || (!test && dir.size()))
|
||||
if (userResourceDir(queried) || (!test && queried.size()))
|
||||
{
|
||||
list[nDirs++] = dir/version;
|
||||
list[nDirs++] = dir;
|
||||
list[nDirs++] = queried/version;
|
||||
list[nDirs++] = queried;
|
||||
}
|
||||
|
||||
// Group (site) resource directories
|
||||
if (groupResourceDir(dir) || (!test && dir.size()))
|
||||
if (groupResourceDir(queried) || (!test && queried.size()))
|
||||
{
|
||||
list[nDirs++] = dir/version;
|
||||
list[nDirs++] = dir;
|
||||
list[nDirs++] = queried/version;
|
||||
list[nDirs++] = queried;
|
||||
}
|
||||
|
||||
// Other (project) resource directory
|
||||
if (projectResourceDir(dir) || (!test && dir.size()))
|
||||
if (projectResourceDir(queried) || (!test && queried.size()))
|
||||
{
|
||||
list[nDirs++] = dir;
|
||||
list[nDirs++] = queried;
|
||||
}
|
||||
|
||||
list.resize(nDirs);
|
||||
@ -239,13 +272,15 @@ Foam::fileNameList Foam::etcDirs(bool test)
|
||||
Foam::fileNameList Foam::findEtcDirs
|
||||
(
|
||||
const fileName& name,
|
||||
const bool findFirst
|
||||
const bool findFirst,
|
||||
unsigned short location
|
||||
)
|
||||
{
|
||||
return
|
||||
searchEtc
|
||||
(
|
||||
name,
|
||||
location,
|
||||
findFirst,
|
||||
[](const fileName& f){ return Foam::isDir(f); }
|
||||
);
|
||||
@ -256,7 +291,8 @@ Foam::fileNameList Foam::findEtcFiles
|
||||
(
|
||||
const fileName& name,
|
||||
const bool mandatory,
|
||||
const bool findFirst
|
||||
const bool findFirst,
|
||||
unsigned short location
|
||||
)
|
||||
{
|
||||
fileNameList list;
|
||||
@ -267,6 +303,7 @@ Foam::fileNameList Foam::findEtcFiles
|
||||
list = searchEtc
|
||||
(
|
||||
name,
|
||||
location,
|
||||
findFirst,
|
||||
[](const fileName& f){ return Foam::isFile(f); }
|
||||
);
|
||||
@ -274,11 +311,16 @@ Foam::fileNameList Foam::findEtcFiles
|
||||
|
||||
if (mandatory && list.empty())
|
||||
{
|
||||
// Abort if file is mandatory but not found
|
||||
// Abort if file is mandatory but not found.
|
||||
// Use a direct exit, since this could occur before anything is
|
||||
// setup at all.
|
||||
|
||||
std::cerr
|
||||
<< "--> FOAM FATAL ERROR in Foam::findEtcFiles()"
|
||||
" : could not find mandatory file\n '"
|
||||
<< name.c_str() << "'\n\n" << std::endl;
|
||||
<< "--> FOAM FATAL ERROR :\n "
|
||||
"Could not find mandatory etc file (mode="
|
||||
<< locationToString(location) << ")\n '"
|
||||
<< name.c_str() << "'\n"
|
||||
<< std::endl;
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
@ -286,16 +328,42 @@ Foam::fileNameList Foam::findEtcFiles
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::findEtcFile(const fileName& name, const bool mandatory)
|
||||
Foam::fileName Foam::findEtcDir
|
||||
(
|
||||
const fileName& name,
|
||||
unsigned short location
|
||||
)
|
||||
{
|
||||
fileNameList list(findEtcFiles(name, mandatory, true));
|
||||
fileNameList list(findEtcDirs(name, true, location));
|
||||
|
||||
fileName found;
|
||||
|
||||
if (list.size())
|
||||
{
|
||||
return list.first();
|
||||
found = std::move(list.first());
|
||||
}
|
||||
|
||||
return fileName();
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::findEtcFile
|
||||
(
|
||||
const fileName& name,
|
||||
const bool mandatory,
|
||||
unsigned short location
|
||||
)
|
||||
{
|
||||
fileNameList list(findEtcFiles(name, mandatory, true, location));
|
||||
|
||||
fileName found;
|
||||
|
||||
if (list.size())
|
||||
{
|
||||
found = std::move(list.first());
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -60,25 +60,38 @@ fileNameList etcDirs(bool test=true);
|
||||
fileNameList findEtcDirs
|
||||
(
|
||||
const fileName& name, //!< The directory to search for
|
||||
const bool findFirst=false //!< Stop after locating the first directory
|
||||
const bool findFirst=false, //!< Stop after locating the first directory
|
||||
unsigned short location=0777 //!< User/group/other location
|
||||
);
|
||||
|
||||
|
||||
//- Search for a single directory using findEtcDirs().
|
||||
//
|
||||
// \return The full path name of the first directory found in the
|
||||
// search hierarchy or an empty fileName if the name cannot be found.
|
||||
fileName findEtcDir
|
||||
(
|
||||
const fileName& name, //!< The directory to search for
|
||||
unsigned short location=0777 //!< User/group/other location
|
||||
);
|
||||
|
||||
//- Search for files from user/group/other directories.
|
||||
//
|
||||
// The search hierarchy corresponds to that of the foamEtcFile script,
|
||||
// which allows for version-specific and version-independent files:
|
||||
// -# \b user settings
|
||||
// The search hierarchy corresponds to that of the \c foamEtcFile script,
|
||||
// which allows for version-specific and version-independent files.
|
||||
//
|
||||
// -# \b user settings (\c location=0700)
|
||||
// - ~/.OpenFOAM/{PROJECT_API}
|
||||
// - ~/.OpenFOAM/
|
||||
// -# \b group settings
|
||||
// -# \b group settings (\c location=0070)
|
||||
// - $WM_PROJECT_SITE/{PROJECT_API}/etc/
|
||||
// - $WM_PROJECT_SITE/etc/
|
||||
// -# \b other (shipped) settings
|
||||
// -# \b other (shipped) settings (\c location=0007)
|
||||
// - $WM_PROJECT_DIR/etc/
|
||||
//
|
||||
// Where {PROJECT_API} is the value of the OPENFOAM define.
|
||||
// - \b \$WM_PROJECT_SITE : If unset, uses $WM_PROJECT_DIR/site
|
||||
// Where {PROJECT_API} corresponds to the foamVersion::api value.
|
||||
//
|
||||
// \note When \c \$WM_PROJECT_SITE is unset, uses \c $WM_PROJECT_DIR/site
|
||||
//
|
||||
// \return The list of full paths of all the matching files or
|
||||
// an empty list if the name cannot be found.
|
||||
@ -86,7 +99,8 @@ fileNameList findEtcFiles
|
||||
(
|
||||
const fileName& name, //!< The file to search for
|
||||
const bool mandatory=false, //!< Abort if the file cannot be found
|
||||
const bool findFirst=false //!< Stop after locating the first directory
|
||||
const bool findFirst=false, //!< Stop after locating the first directory
|
||||
unsigned short location=0777 //!< User/group/other location
|
||||
);
|
||||
|
||||
|
||||
@ -97,7 +111,8 @@ fileNameList findEtcFiles
|
||||
fileName findEtcFile
|
||||
(
|
||||
const fileName& name, //!< The file to search for
|
||||
const bool mandatory=false //!< Abort if the file cannot be found
|
||||
const bool mandatory=false, //!< Abort if the file cannot be found
|
||||
unsigned short location=0777 //!< User/group/other location
|
||||
);
|
||||
|
||||
|
||||
|
||||
@ -37,10 +37,33 @@ License
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Return the file location mode (string) as a numerical value.
|
||||
//
|
||||
// - u : location mask 0700
|
||||
// - g : location mask 0070
|
||||
// - o : location mask 0007
|
||||
//
|
||||
static inline unsigned short modeToLocation
|
||||
(
|
||||
const std::string& mode,
|
||||
std::size_t pos = 0
|
||||
)
|
||||
{
|
||||
unsigned short where(0);
|
||||
|
||||
if (std::string::npos != mode.find('u', pos)) { where |= 0700; } // User
|
||||
if (std::string::npos != mode.find('g', pos)) { where |= 0070; } // Group
|
||||
if (std::string::npos != mode.find('o', pos)) { where |= 0007; } // Other
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
|
||||
// Expand a leading <tag>/
|
||||
// Convenient for frequently used directories
|
||||
//
|
||||
// <etc>/ => user/group/other OpenFOAM directory
|
||||
// <etc>/ => user/group/other etc - findEtcFile()
|
||||
// <etc(:[ugo]+)?>/ => user/group/other etc - findEtcFile()
|
||||
// <case>/ => FOAM_CASE directory
|
||||
// <constant>/ => FOAM_CASE/constant directory
|
||||
// <system>/ => FOAM_CASE/system directory
|
||||
@ -52,7 +75,7 @@ static void expandLeadingTag(std::string& s, const char b, const char e)
|
||||
}
|
||||
|
||||
auto delim = s.find(e);
|
||||
if (delim == std::string::npos)
|
||||
if (std::string::npos == delim)
|
||||
{
|
||||
return; // Error: no closing delim - ignore expansion
|
||||
}
|
||||
@ -73,6 +96,7 @@ static void expandLeadingTag(std::string& s, const char b, const char e)
|
||||
}
|
||||
|
||||
const std::string tag(s, 1, delim-2);
|
||||
const auto tagLen = tag.length();
|
||||
|
||||
// Note that file is also allowed to be an empty string.
|
||||
|
||||
@ -88,6 +112,12 @@ static void expandLeadingTag(std::string& s, const char b, const char e)
|
||||
{
|
||||
s = fileName(Foam::getEnv("FOAM_CASE"))/tag/file;
|
||||
}
|
||||
else if (tagLen >= 4 && tag.compare(0, 4, "etc:") == 0)
|
||||
{
|
||||
// <etc:ugo> type of tag - convert "ugo" to numeric
|
||||
|
||||
s = findEtcFile(file, false, modeToLocation(tag, 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -219,31 +219,46 @@ namespace stringOps
|
||||
// -# environment variables
|
||||
// - "$VAR", "${VAR}"
|
||||
// -# current directory
|
||||
// - leading "./" : the current directory
|
||||
// - leading "./"
|
||||
// : the current directory - Foam::cwd()
|
||||
// -# leading tag expansion for commonly used directories
|
||||
// - \<etc\>/ : user/group/other OpenFOAM directory
|
||||
// - \<case\>/ : FOAM_CASE directory
|
||||
// - \<constant\>/ : FOAM_CASE/constant directory
|
||||
// - \<system\>/ : FOAM_CASE/system directory
|
||||
// - <b> \<etc\>/ </b>
|
||||
// : user/group/other OpenFOAM etc directory
|
||||
// - <b> \<etc:</b><em>[ugo]+</em>)<b>\>/ </b>
|
||||
// : user/group/other etc with specified location mode
|
||||
// - <b> \<case\>/ </b>
|
||||
// : The \c $FOAM_CASE directory
|
||||
// - <b> \<constant\>/ </b>
|
||||
// : The \c $FOAM_CASE/constant directory
|
||||
// - <b> \<system\>/ </b>
|
||||
// : The \c $FOAM_CASE/system directory
|
||||
// -# tilde expansion
|
||||
// - leading "~/" : home directory
|
||||
// - leading "~user" : home directory for specified user
|
||||
//
|
||||
// Supports default and alternative values as per the POSIX shell.
|
||||
// \code
|
||||
// a) "${parameter:-defValue}"
|
||||
// b) "${parameter:+altValue}"
|
||||
// 1. "${parameter:-defValue}"
|
||||
// 2. "${parameter:+altValue}"
|
||||
// \endcode
|
||||
// a) If parameter is unset or null, the \c defValue is substituted.
|
||||
// -# If parameter is unset or null, the \c defValue is substituted.
|
||||
// Otherwise, the value of parameter is substituted.
|
||||
//
|
||||
// b) If parameter is unset or null, nothing is substituted.
|
||||
// -# If parameter is unset or null, nothing is substituted.
|
||||
// Otherwise the \c altValue is substituted.
|
||||
// .
|
||||
//
|
||||
// General behavior:
|
||||
// - Any unknown entries are removed silently, if allowEmpty is true.
|
||||
// - Malformed entries (eg, brace mismatch, sigil followed by bad chars)
|
||||
// are left as is.
|
||||
//
|
||||
// An example of using the specified location mode
|
||||
// \code
|
||||
// fileName controlDict(stringOps::expand("<etc:o>/controlDict"));
|
||||
// // OR
|
||||
// fileName controlDict(findEtcFile("controlDict", false, 0007));
|
||||
// \endcode
|
||||
//
|
||||
// \note Deprecated(2018-11) Use "<etc>" instead of the rarely used
|
||||
// "~OpenFOAM" expansion
|
||||
//
|
||||
@ -263,25 +278,32 @@ namespace stringOps
|
||||
// -# current directory
|
||||
// - leading "./" : the current directory
|
||||
// -# leading tag expansion for commonly used directories
|
||||
// - \<etc\>/ : user/group/other OpenFOAM directory
|
||||
// - \<case\>/ : FOAM_CASE directory
|
||||
// - \<constant\>/ : FOAM_CASE/constant directory
|
||||
// - \<system\>/ : FOAM_CASE/system directory
|
||||
// - <b> \<etc\>/ </b>
|
||||
// : user/group/other OpenFOAM etc directory
|
||||
// - <b> \<etc:</b><em>[ugo]+</em>)<b>\>/ </b>
|
||||
// : user/group/other etc with specified location mode
|
||||
// - <b> \<case\>/ </b>
|
||||
// : The \c $FOAM_CASE directory
|
||||
// - <b> \<constant\>/ </b>
|
||||
// : The \c $FOAM_CASE/constant directory
|
||||
// - <b> \<system\>/ </b>
|
||||
// : The \c $FOAM_CASE/system directory
|
||||
// -# tilde expansion
|
||||
// - leading "~/" : home directory
|
||||
// - leading "~user" : home directory for specified user
|
||||
//
|
||||
// Supports default and alternative values as per the POSIX shell.
|
||||
// \code
|
||||
// a) "${parameter:-defValue}"
|
||||
// b) "${parameter:+altValue}"
|
||||
// 1. "${parameter:-defValue}"
|
||||
// 2. "${parameter:+altValue}"
|
||||
// \endcode
|
||||
// a) If parameter is unset or null, the \c defValue is substituted.
|
||||
// -# If parameter is unset or null, the \c defValue is substituted.
|
||||
// Otherwise, the value of parameter is substituted.
|
||||
//
|
||||
// b) If parameter is unset or null, nothing is substituted.
|
||||
// -# If parameter is unset or null, nothing is substituted.
|
||||
// Otherwise the \c altValue is substituted.
|
||||
// .
|
||||
//
|
||||
// General behavior:
|
||||
// - Any unknown entries are removed silently if allowEmpty is true.
|
||||
// - Malformed entries (eg, brace mismatch, sigil followed by bad chars)
|
||||
// are left as is.
|
||||
|
||||
Reference in New Issue
Block a user