ENH: support option aliases with versioning

- can be used for adjusting option names between versions
This commit is contained in:
Mark Olesen 2017-11-22 14:42:31 +01:00
parent 416a3790ea
commit aa112c3f26
6 changed files with 200 additions and 76 deletions

View File

@ -38,12 +38,24 @@ int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::noFunctionObjects();
// argList::noFunctionObjects();
argList::removeOption("case");
argList::addOption("label", "value", "Test parsing of label");
argList::addOption("scalar", "value", "Test parsing of scalar");
// These are actually lies (never had -parseLabel, -parseScalar etc),
// but good for testing...
// Emits warning about it being old
argList::addOptionCompat("label", {"parseLabel", 1612});
// Specifying version=0 to use alias without any warnings
argList::addOptionCompat("scalar", {"parseScalar", 0});
// Fake a future option...
argList::addOptionCompat("label", {"parse-label", 2112});
argList args(argc, argv);
label ival;

View File

@ -25,36 +25,6 @@ License
#include "dictionary.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
static void warnAboutAge(const int oldVersion)
{
if (oldVersion < 1000)
{
// Emit warning
std::cerr
<< " This keyword is considered to be VERY old!\n"
<< std::endl;
}
#if (OPENFOAM_PLUS > 1600)
else if (OPENFOAM_PLUS > oldVersion)
{
const int months =
(
// YYMM -> months
(12 * (OPENFOAM_PLUS/100) + (OPENFOAM_PLUS % 100))
- (12 * (oldVersion/100) + (oldVersion % 100))
);
std::cerr
<< " This keyword is deemed to be " << months
<< " months old.\n"
<< std::endl;
}
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
@ -78,17 +48,20 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
if (finder.found())
{
// Emit warning
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found [v" << iter.second << "] '"
<< iter.first << "' instead of '"
<< keyword.c_str() << "' in dictionary \""
<< name().c_str() << "\" "
<< nl
<< std::endl;
if (iter.second)
{
// Emit warning, but only if version (non-zero) was provided
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found [v" << iter.second << "] '"
<< iter.first << "' instead of '"
<< keyword.c_str() << "' in dictionary \""
<< name().c_str() << "\" "
<< nl
<< std::endl;
warnAboutAge(iter.second);
error::warnAboutAge("keyword", iter.second);
}
break;
}

View File

@ -31,6 +31,44 @@ License
#include "Pstream.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::error::warnAboutAge
(
const char* what,
const int oldVersion
)
{
if (oldVersion < 1000)
{
// Emit warning
std::cerr
<< " This " << what << " is considered to be VERY old!\n"
<< std::endl;
}
else if (OPENFOAM_PLUS > oldVersion)
{
const int months =
(
// YYMM -> months
(12 * (OPENFOAM_PLUS/100) + (OPENFOAM_PLUS % 100))
- (12 * (oldVersion/100) + (oldVersion % 100))
);
std::cerr
<< " This " << what << " is deemed to be " << months
<< " months old.\n"
<< std::endl;
}
///// Uncertain if this is desirable
/// else if (OPENFOAM_PLUS < oldVersion)
/// {
/// std::cerr
/// << " This " << what << " appears to be a future option\n"
/// << std::endl;
/// }
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

@ -100,6 +100,15 @@ public:
virtual ~error() throw();
// Static Member Functions
//- Emit warning on stderr about something being old.
// \param what description for the warning
// \param oldVersion is a YYMM version value for determining the
// age in months.
static void warnAboutAge(const char* what, const int oldVersion);
// Member functions
string message() const;

View File

@ -54,6 +54,7 @@ Foam::SLList<Foam::string> Foam::argList::validArgs;
Foam::HashTable<Foam::string> Foam::argList::validOptions;
Foam::HashTable<Foam::string> Foam::argList::validParOptions;
Foam::HashTable<Foam::string> Foam::argList::optionUsage;
Foam::HashTable<std::pair<Foam::word,int>> Foam::argList::validOptionsCompat;
Foam::SLList<Foam::string> Foam::argList::notes;
Foam::string::size_type Foam::argList::usageMin = 20;
Foam::string::size_type Foam::argList::usageMax = 80;
@ -97,7 +98,13 @@ Foam::argList::initValidTables::initValidTables()
"fileHandler",
"handler",
"override the fileHandler"
);
);
// Some standard option aliases (with or without version warnings)
// argList::addOptionCompat
// (
// "noFunctionObjects", {"no-function-objects", 0 }
// );
Pstream::addValidParOptions(validParOptions);
}
@ -152,6 +159,7 @@ static void printHostsSubscription(const UList<string>& slaveProcs)
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::argList::addArgument(const string& argumentName)
@ -185,6 +193,20 @@ void Foam::argList::addOption
}
void Foam::argList::addOptionCompat
(
const word& optionName,
std::pair<const char*,int> compat
)
{
validOptionsCompat.insert
(
compat.first,
std::pair<word,int>(optionName, compat.second)
);
}
void Foam::argList::addUsage
(
const word& opt,
@ -388,57 +410,106 @@ bool Foam::argList::postProcess(int argc, char *argv[])
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::word Foam::argList::optionCompat(const word& optionName)
{
if (!validOptionsCompat.empty())
{
auto canonical = validOptionsCompat.cfind(optionName.substr(1));
if (canonical.found())
{
const auto& iter = *canonical;
if (iter.second)
{
// Emit warning, but only if version (non-zero) was provided
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found [v" << iter.second << "] '"
<< optionName << "' instead of '-"
<< iter.first << "' option"
<< nl
<< std::endl;
error::warnAboutAge("option", iter.second);
}
return "-" + iter.first;
}
}
// Nothing found - pass through the original input
return optionName;
}
bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
int nArgs = 1;
unsigned listDepth = 0;
string tmpString;
unsigned depth = 0;
string group; // For grouping ( ... ) arguments
// Note: we rewrite directly into args_
// and use a second pass to sort out args/options
args_[0] = fileName(argv[0]);
for (int argI = 1; argI < argc; ++argI)
for (int argi = 1; argi < argc; ++argi)
{
if (strcmp(argv[argI], "(") == 0)
if (strcmp(argv[argi], "(") == 0)
{
++listDepth;
tmpString += "(";
++depth;
group += '(';
}
else if (strcmp(argv[argI], ")") == 0)
else if (strcmp(argv[argi], ")") == 0)
{
if (listDepth)
if (depth)
{
--listDepth;
tmpString += ")";
if (!listDepth)
--depth;
group += ')';
if (!depth)
{
args_[nArgs++] = tmpString;
tmpString.clear();
args_[nArgs++] = group;
group.clear();
}
}
else
{
args_[nArgs++] = argv[argI];
args_[nArgs++] = argv[argi];
}
}
else if (listDepth)
else if (depth)
{
// Quote each string element
tmpString += "\"";
tmpString += argv[argI];
tmpString += "\"";
group += '"';
group += argv[argi];
group += '"';
}
else if (argv[argi][0] == '-')
{
// Appears to be an option
const char *optionName = &argv[argi][1];
if (validOptions.found(optionName))
{
// Known option name
args_[nArgs++] = argv[argi];
}
else
{
// Try alias for the option name
args_[nArgs++] = optionCompat(argv[argi]);
}
}
else
{
args_[nArgs++] = argv[argI];
args_[nArgs++] = argv[argi];
}
}
if (tmpString.size())
if (group.size())
{
// Group(s) not closed, but flush anything still pending
args_[nArgs++] = tmpString;
args_[nArgs++] = group;
}
args_.setSize(nArgs);
@ -530,11 +601,11 @@ Foam::argList::argList
{
// Check if this run is a parallel run by searching for any parallel option
// If found call runPar which might filter argv
for (int argI = 1; argI < argc; ++argI)
for (int argi = 1; argi < argc; ++argi)
{
if (argv[argI][0] == '-')
if (argv[argi][0] == '-')
{
const char *optionName = &argv[argI][1];
const char *optionName = &argv[argi][1];
if (validParOptions.found(optionName))
{
@ -551,14 +622,14 @@ Foam::argList::argList
// Check arguments and options, argv[0] was already handled
int nArgs = 1;
HashTable<string>::const_iterator optIter;
for (int argI = 1; argI < args_.size(); ++argI)
for (int argi = 1; argi < args_.size(); ++argi)
{
argListStr_ += ' ';
argListStr_ += args_[argI];
argListStr_ += args_[argi];
if (args_[argI][0] == '-')
if (args_[argi][0] == '-')
{
const char *optionName = &args_[argI][1];
const char *optionName = &args_[argi][1];
if (!*optionName)
{
@ -580,8 +651,8 @@ Foam::argList::argList
// If the option is known to require an argument,
// get it or emit a FatalError.
++argI;
if (argI >= args_.size())
++argi;
if (argi >= args_.size())
{
FatalError
<<"Option '-" << optionName
@ -591,9 +662,9 @@ Foam::argList::argList
}
argListStr_ += ' ';
argListStr_ += args_[argI];
argListStr_ += args_[argi];
// Handle duplicates by taking the last -option specified
options_.set(optionName, args_[argI]);
options_.set(optionName, args_[argi]);
}
else
{
@ -605,9 +676,9 @@ Foam::argList::argList
}
else
{
if (nArgs != argI)
if (nArgs != argi)
{
args_[nArgs] = args_[argI];
args_[nArgs] = args_[argi];
}
++nArgs;
}

View File

@ -103,6 +103,7 @@ SourceFiles
#include "parRun.H"
#include "StringStream.H"
#include "OSspecific.H"
#include <utility>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -146,6 +147,9 @@ class argList
// Private Member Functions
//- Helper for resolving aliases for -options within validOptionsCompat
static word optionCompat(const word& optionName);
//- Helper function for printUsage
static void printOptionUsage
(
@ -181,6 +185,10 @@ public:
//- A list of valid parallel options
static HashTable<string> validParOptions;
//- A list of aliases for options.
// Stored as (alias = canonical, version)
static HashTable<std::pair<word,int>> validOptionsCompat;
//- Short usage information for validOptions
static HashTable<string> optionUsage;
@ -369,6 +377,19 @@ public:
const string& usage = ""
);
//- Add an alias for the optionName.
//
// \param optionName the currently used option name
// OpenFOAM version for which they were used.
// \param compat alias name and the last OpenFOAM version
// (YYMM) for when the alias was not needed.
// Setting a version of 0 suppresses warnings about the alias.
static void addOptionCompat
(
const word& optionName,
std::pair<const char*, int> compat
);
//- Add option usage information to optionUsage
static void addUsage
(