mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support usage descriptions for command arguments
This commit is contained in:
@ -55,6 +55,8 @@ Foam::SLList<Foam::string> Foam::argList::validArgs;
|
||||
Foam::HashSet<Foam::string> Foam::argList::advancedOptions;
|
||||
Foam::HashTable<Foam::string> Foam::argList::validOptions;
|
||||
Foam::HashTable<Foam::string> Foam::argList::validParOptions;
|
||||
Foam::HashTable<Foam::string, Foam::label, Foam::Hash<Foam::label>>
|
||||
Foam::argList::argUsage;
|
||||
Foam::HashTable<Foam::string> Foam::argList::optionUsage;
|
||||
Foam::HashTable<std::pair<Foam::word,int>> Foam::argList::validOptionsCompat;
|
||||
Foam::HashTable<std::pair<bool,int>> Foam::argList::ignoreOptionsCompat;
|
||||
@ -68,32 +70,44 @@ Foam::argList::initValidTables::initValidTables()
|
||||
{
|
||||
argList::addOption
|
||||
(
|
||||
"case", "dir",
|
||||
"case",
|
||||
"dir",
|
||||
"Specify case directory to use (instead of the cwd)"
|
||||
);
|
||||
argList::addBoolOption("parallel", "Run in parallel");
|
||||
validParOptions.set("parallel", "");
|
||||
argList::addOption
|
||||
(
|
||||
"roots", "(dir1 .. dirN)",
|
||||
"roots",
|
||||
"(dir1 .. dirN)",
|
||||
"Slave root directories for distributed running",
|
||||
true // advanced option
|
||||
);
|
||||
validParOptions.set("roots", "(dir1 .. dirN)");
|
||||
validParOptions.set
|
||||
(
|
||||
"roots",
|
||||
"(dir1 .. dirN)"
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"decomposeParDict", "file",
|
||||
"decomposeParDict",
|
||||
"file",
|
||||
"Use specified file for decomposePar dictionary"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"hostRoots", "(((host1 dir1) .. (hostN dirN))",
|
||||
"hostRoots",
|
||||
"(((host1 dir1) .. (hostN dirN))",
|
||||
"slave root directories (per host) for distributed running. "
|
||||
"The host specification can use a regex.",
|
||||
true // advanced option
|
||||
);
|
||||
validParOptions.set("hostRoots", "((host1 dir1) .. (hostN dirN))");
|
||||
validParOptions.set
|
||||
(
|
||||
"hostRoots",
|
||||
"((host1 dir1) .. (hostN dirN))"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
@ -103,7 +117,8 @@ Foam::argList::initValidTables::initValidTables()
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"fileHandler", "handler",
|
||||
"fileHandler",
|
||||
"handler",
|
||||
"Override the file handler type",
|
||||
true // advanced option
|
||||
);
|
||||
@ -229,9 +244,26 @@ void Foam::argList::checkITstream(const ITstream& is, const word& optName)
|
||||
}
|
||||
|
||||
|
||||
void Foam::argList::addArgument(const string& argName)
|
||||
void Foam::argList::addArgument
|
||||
(
|
||||
const string& argName,
|
||||
const string& usage
|
||||
)
|
||||
{
|
||||
validArgs.append(argName);
|
||||
|
||||
// The first program argument starts at 1 - obtain index after the append
|
||||
|
||||
const label index = validArgs.size();
|
||||
|
||||
if (usage.empty())
|
||||
{
|
||||
argUsage.erase(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
argUsage.set(index, usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -212,16 +212,19 @@ public:
|
||||
// Stored as (option = bool, version)
|
||||
static HashTable<std::pair<bool,int>> ignoreOptionsCompat;
|
||||
|
||||
//- Short usage information for validOptions
|
||||
//- Short description for program arguments
|
||||
static HashTable<string, label, Hash<label>> argUsage;
|
||||
|
||||
//- Short description for validOptions
|
||||
static HashTable<string> optionUsage;
|
||||
|
||||
//- Additional notes for usage
|
||||
//- General usage notes
|
||||
static SLList<string> notes;
|
||||
|
||||
//- Min offset for displaying usage (default: 20)
|
||||
//- Min indentation when displaying usage (default: 20)
|
||||
static std::string::size_type usageMin;
|
||||
|
||||
//- Max screen width for displaying usage (default: 80)
|
||||
//- Max screen width when displaying usage (default: 80)
|
||||
static std::string::size_type usageMax;
|
||||
|
||||
//- Standard name for the post-processing option
|
||||
@ -341,11 +344,16 @@ public:
|
||||
//- Return an input stream from the named option
|
||||
inline ITstream lookup(const word& optName) const;
|
||||
|
||||
//- Read a value from the named option
|
||||
//- Get a value from the named option
|
||||
// The default template parameter is string (ie, no conversion).
|
||||
template<class T=string>
|
||||
inline T opt(const word& optName) const;
|
||||
|
||||
//- Get a value from the named option if present, or return default.
|
||||
// Identical to lookupOrDefault().
|
||||
template<class T>
|
||||
inline T opt(const word& optName, const T& deflt) const;
|
||||
|
||||
//- Read a value from the named option if present.
|
||||
// \return true if the named option was found.
|
||||
template<class T>
|
||||
@ -362,8 +370,7 @@ public:
|
||||
const T& deflt
|
||||
) const;
|
||||
|
||||
//- Read a value from the named option if present.
|
||||
// Return supplied default otherwise.
|
||||
//- Get a value from the named option if present, or return default.
|
||||
template<class T>
|
||||
inline T lookupOrDefault
|
||||
(
|
||||
@ -389,7 +396,11 @@ public:
|
||||
// Edit
|
||||
|
||||
//- Append a (mandatory) argument to validArgs
|
||||
static void addArgument(const string& argName);
|
||||
static void addArgument
|
||||
(
|
||||
const string& argName,
|
||||
const string& usage = ""
|
||||
);
|
||||
|
||||
//- Add a bool option to validOptions with usage information
|
||||
static void addBoolOption
|
||||
|
||||
@ -240,6 +240,35 @@ void Foam::argList::printMan() const
|
||||
}
|
||||
|
||||
|
||||
// Arguments output
|
||||
if (validArgs.size())
|
||||
{
|
||||
// .SH "ARGUMENTS"
|
||||
Info<< ".SH \"ARGUMENTS\"" << nl;
|
||||
|
||||
label argIndex = 0;
|
||||
for (const std::string& argName : validArgs)
|
||||
{
|
||||
++argIndex;
|
||||
|
||||
Info<< ".TP\n\\fI" << argName.c_str() << "\\fR";
|
||||
Info<< nl;
|
||||
|
||||
// Arg has usage information?
|
||||
|
||||
const auto usageIter = argList::argUsage.cfind(argIndex);
|
||||
if (usageIter.found())
|
||||
{
|
||||
stringOps::writeWrapped(Info, *usageIter, usageMax, 0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// .SH "OPTIONS"
|
||||
Info<< ".SH \"OPTIONS\"" << nl;
|
||||
|
||||
@ -320,6 +349,34 @@ void Foam::argList::printUsage(bool full) const
|
||||
}
|
||||
Info<< nl;
|
||||
|
||||
// Arguments output
|
||||
// Currently only if there is also usage information, but may wish to
|
||||
// change this to remind developers to add some description.
|
||||
if (validArgs.size() && argUsage.size())
|
||||
{
|
||||
Info<< "Arguments:\n";
|
||||
|
||||
label argIndex = 0;
|
||||
for (const std::string& argName : validArgs)
|
||||
{
|
||||
++argIndex;
|
||||
|
||||
Info<< " <" << argName.c_str() << '>';
|
||||
|
||||
const auto usageIter = argList::argUsage.cfind(argIndex);
|
||||
if (usageIter.found())
|
||||
{
|
||||
const label len = argName.size() + 4;
|
||||
|
||||
printOptionUsage(len, usageIter());
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Options:\n";
|
||||
|
||||
for (const word& optName : validOptions.sortedToc())
|
||||
|
||||
@ -256,6 +256,18 @@ inline T Foam::argList::opt(const word& optName) const
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline T Foam::argList::opt(const word& optName, const T& deflt) const
|
||||
{
|
||||
if (found(optName))
|
||||
{
|
||||
return opt<T>(optName);
|
||||
}
|
||||
|
||||
return deflt;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::argList::readIfPresent
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user