ENH: add argList option ignoring for compatibility upgrades

- can be used to handle when options become redundant, but it is
  undesirable to treat its presence as an error. Can now tag it as
  being ignored.

     argList::ignoreOptionCompat({"oldOption", 1706}, true);
     argList::ignoreOptionCompat({"oldBoolOpttion", 1706}, false);

     command  -oldOption xyz -oldBoolOpttion
This commit is contained in:
Mark Olesen 2018-01-08 16:25:27 +01:00
parent 345a2a42f1
commit adbbd0e678
3 changed files with 185 additions and 2 deletions

View File

@ -57,6 +57,15 @@ int main(int argc, char *argv[])
// Fake a future option...
argList::addOptionCompat("label", {"parse-label", 2112});
// Ignore an old bool option
argList::ignoreOptionCompat({"xml", 1700}, false);
// Ignore an old option with arg. Specified version=0 to suppress warnings
argList::ignoreOptionCompat({"format", 0}, true);
// Ignore a future option? Fairly pointless
argList::ignoreOptionCompat({"ascii", 2112}, false);
argList::addArgument("label");
argList::addArgument("...");
argList::addArgument("label");
@ -64,6 +73,7 @@ int main(int argc, char *argv[])
argList args(argc, argv, false, true);
Info<<"have: "
<<args.count({"label", "scalar"}) << " options" << nl;

View File

@ -42,6 +42,7 @@ License
#include "CStringList.H"
#include "uncollatedFileOperation.H"
#include "masterUncollatedFileOperation.H"
#include "IOmanip.H"
#include <cctype>
@ -55,6 +56,7 @@ 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::HashTable<std::pair<bool,int>> Foam::argList::ignoreOptionsCompat;
Foam::SLList<Foam::string> Foam::argList::notes;
Foam::string::size_type Foam::argList::usageMin = 20;
Foam::string::size_type Foam::argList::usageMax = 80;
@ -216,6 +218,20 @@ void Foam::argList::addOptionCompat
}
void Foam::argList::ignoreOptionCompat
(
std::pair<const char*,int> compat,
const bool expectArg
)
{
ignoreOptionsCompat.insert
(
compat.first,
std::pair<bool,int>(expectArg, compat.second)
);
}
void Foam::argList::addUsage
(
const word& optName,
@ -466,9 +482,59 @@ Foam::word Foam::argList::optionCompat(const word& optName)
}
int Foam::argList::optionIgnore(const word& optName)
{
// NB: optName is without the leading '-'
if (!ignoreOptionsCompat.empty())
{
const auto fnd = ignoreOptionsCompat.cfind(optName);
if (fnd.found())
{
const auto& iter = *fnd;
// Number to skip (including the option itself)
// '-option ARG' or '-option'
const int nskip = (iter.first ? 2 : 1);
// Emit warning if there is versioning (non-zero) and it is not
// tagged as future change (ie, ThisVersion > version).
if
(
iter.second
&&
(
(OPENFOAM_PLUS > 1700) // Guard against bad #define value
? (OPENFOAM_PLUS > iter.second)
: true
)
)
{
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Ignoring [v" << iter.second << "] '-"
<< optName << (nskip > 1 ? " ARG" : "")
<< "' option"
<< nl
<< std::endl;
error::warnAboutAge("option", iter.second);
}
return nskip;
}
}
return 0; // Do not skip
}
bool Foam::argList::regroupArgv(int& argc, char**& argv)
{
int nArgs = 1;
int ignore = 0;
unsigned depth = 0;
string group; // For grouping ( ... ) arguments
@ -517,6 +583,14 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
// Known option name
args_[nArgs++] = argv[argi];
}
else if ((ignore = optionIgnore(optName)) > 0)
{
// Option to be ignored (with/without an argument)
if (ignore > 1)
{
++argi;
}
}
else
{
// Try alias for the option name
@ -754,9 +828,11 @@ void Foam::argList::parse
// -help-full print the full usage
// -doc display application documentation in browser
// -doc-source display source code in browser
// -list-compat print compatibility information
{
bool quickExit = false;
// Only display one or the other
if (options_.found("help-full"))
{
printUsage(true);
@ -784,6 +860,12 @@ void Foam::argList::parse
quickExit = true;
}
if (options_.found("list-compat"))
{
printCompat();
quickExit = true;
}
if (quickExit)
{
::exit(0);
@ -1452,6 +1534,75 @@ void Foam::argList::printUsage(bool full) const
}
void Foam::argList::printCompat() const
{
const label nopt
(
argList::validOptionsCompat.size()
+ argList::ignoreOptionsCompat.size()
);
Info<< nopt << " compatibility options for " << executable_ << nl;
if (nopt)
{
Info<< setf(ios_base::left) << setw(34) << "old option"
<< setf(ios_base::left) << setw(32) << "new option"
<< "version" << nl
<< setf(ios_base::left) << setw(34) << "~~~~~~~~~~"
<< setf(ios_base::left) << setw(32) << "~~~~~~~~~~"
<< "~~~~~~~" << nl;
for (const word& k : argList::validOptionsCompat.sortedToc())
{
const auto& iter = *argList::validOptionsCompat.cfind(k);
Info<< " -"
<< setf(ios_base::left) << setw(32) << k
<< " -"
<< setf(ios_base::left) << setw(30) << iter.first;
if (iter.second)
{
Info<< " " << iter.second;
}
else
{
Info<< " -";
}
Info<< nl;
}
for (const word& k : argList::ignoreOptionsCompat.sortedToc())
{
const auto& iter = *argList::ignoreOptionsCompat.cfind(k);
if (iter.first)
{
Info<< " -"
<< setf(ios_base::left) << setw(32)
<< (k + " <arg>").c_str();
}
else
{
Info<< " -"
<< setf(ios_base::left) << setw(32) << k;
}
Info<< setf(ios_base::left) << setw(32) << " removed";
if (iter.second)
{
Info<< " " << iter.second;
}
else
{
Info<< " -";
}
Info<< nl;
}
}
}
void Foam::argList::displayDoc(bool source) const
{
const dictionary& docDict = debug::controlDict().subDict("Documentation");

View File

@ -150,6 +150,9 @@ class argList
//- Helper for resolving aliases for -options within validOptionsCompat
static word optionCompat(const word& optName);
//- Helper for resolving ignored options
static int optionIgnore(const word& optName);
//- Helper function for printUsage
static void printOptionUsage
(
@ -189,6 +192,10 @@ public:
// Stored as (alias = canonical, version)
static HashTable<std::pair<word,int>> validOptionsCompat;
//- A list of options to ignore.
// Stored as (option = bool, version)
static HashTable<std::pair<bool,int>> ignoreOptionsCompat;
//- Short usage information for validOptions
static HashTable<string> optionUsage;
@ -431,8 +438,8 @@ public:
//- Specify an alias for the option name.
//
// \param optName the currently used option name
// \param compat alias name and the last OpenFOAM version
// (YYMM) for when the alias was not needed.
// \param compat alias name and the last OpenFOAM version (YYMM)
// when the alias was not needed.
// Setting a version of 0 suppresses warnings about the alias.
static void addOptionCompat
(
@ -440,6 +447,18 @@ public:
std::pair<const char*, int> compat
);
//- Specify an option to be ignored.
//
// \param compat optName and the last OpenFOAM version (YYMM)
// when the option was directly supported.
// Setting a version of 0 suppresses warnings about the alias.
// \param expectArg the option is non-bool
static void ignoreOptionCompat
(
std::pair<const char*,int> compat,
const bool expectArg
);
//- Add option usage information to optionUsage
static void addUsage
(
@ -494,6 +513,9 @@ public:
// Print
//- Print option compatibility
void printCompat() const;
//- Print notes (if any)
void printNotes() const;