ENH: argList::optionReadList now uses ITstream directly

- stricter and robuster than previous solution using List::readList
  since the option input can be fully tokenized prior to list
  conversion.
This commit is contained in:
Mark Olesen
2017-11-24 10:39:20 +01:00
parent d3d82b909e
commit 9985b93cfc
3 changed files with 159 additions and 200 deletions

View File

@ -165,25 +165,25 @@ void Foam::argList::addArgument(const string& argumentName)
void Foam::argList::addBoolOption
(
const word& opt,
const word& optionName,
const string& usage
)
{
addOption(opt, "", usage);
addOption(optionName, "", usage);
}
void Foam::argList::addOption
(
const word& opt,
const word& optionName,
const string& param,
const string& usage
)
{
validOptions.set(opt, param);
validOptions.set(optionName, param);
if (!usage.empty())
{
optionUsage.set(opt, usage);
optionUsage.set(optionName, usage);
}
}
@ -204,17 +204,17 @@ void Foam::argList::addOptionCompat
void Foam::argList::addUsage
(
const word& opt,
const word& optionName,
const string& usage
)
{
if (usage.empty())
{
optionUsage.erase(opt);
optionUsage.erase(optionName);
}
else
{
optionUsage.set(opt, usage);
optionUsage.set(optionName, usage);
}
}
@ -228,10 +228,10 @@ void Foam::argList::addNote(const string& note)
}
void Foam::argList::removeOption(const word& opt)
void Foam::argList::removeOption(const word& optionName)
{
validOptions.erase(opt);
optionUsage.erase(opt);
validOptions.erase(optionName);
optionUsage.erase(optionName);
}
@ -1231,111 +1231,55 @@ Foam::argList::~argList()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::argList::setOption(const word& opt, const string& param)
bool Foam::argList::setOption(const word& optionName, const string& param)
{
bool changed = false;
// Only allow valid options
if (validOptions.found(opt))
// Some options are always protected
if
(
optionName == "case"
|| optionName == "parallel"
|| optionName == "roots"
)
{
// Some options are to be protected
if
(
opt == "case"
|| opt == "parallel"
|| opt == "roots"
)
{
FatalError
<<"used argList::setOption on a protected option: '"
<< opt << "'" << endl;
FatalError.exit();
}
if (validOptions[opt].empty())
{
// Bool option
if (!param.empty())
{
// Disallow change of type
FatalError
<<"used argList::setOption to change bool to non-bool: '"
<< opt << "'" << endl;
FatalError.exit();
}
else
{
// Did not previously exist
changed = !options_.found(opt);
}
}
else
{
// Non-bool option
if (param.empty())
{
// Disallow change of type
FatalError
<<"used argList::setOption to change non-bool to bool: '"
<< opt << "'" << endl;
FatalError.exit();
}
else
{
// Existing value needs changing, or did not previously exist
changed = options_.found(opt) ? options_[opt] != param : true;
}
}
}
else
{
FatalError
<<"used argList::setOption on an invalid option: '"
<< opt << "'" << nl << "allowed are the following:"
<< validOptions << endl;
FatalError.exit();
FatalErrorInFunction
<<"Option: '" << optionName << "' is protected" << nl
<< exit(FatalError);
return false;
}
// Set/change the option as required
if (changed)
if
(
options_.found(optionName)
? (options_[optionName] != param)
: true
)
{
options_.set(opt, param);
options_.set(optionName, param);
return true;
}
return changed;
return false;
}
bool Foam::argList::unsetOption(const word& opt)
bool Foam::argList::unsetOption(const word& optionName)
{
// Only allow valid options
if (validOptions.found(opt))
// Some options are always protected
if
(
optionName == "case"
|| optionName == "parallel"
|| optionName == "roots"
)
{
// Some options are to be protected
if
(
opt == "case"
|| opt == "parallel"
|| opt == "roots"
)
{
FatalError
<<"used argList::unsetOption on a protected option: '"
<< opt << "'" << endl;
FatalError.exit();
}
// Remove the option, return true if state changed
return options_.erase(opt);
FatalErrorInFunction
<<"Option: '" << optionName << "' is protected" << nl
<< exit(FatalError);
return false;
}
FatalError
<<"used argList::unsetOption on an invalid option: '"
<< opt << "'" << nl << "allowed are the following:"
<< validOptions << endl;
FatalError.exit();
return false;
// Remove the option, return true if state changed
return options_.erase(optionName);
}

View File

@ -277,47 +277,46 @@ public:
//- Return the path to the caseName
inline fileName path() const;
//- Return arguments
//- The command arguments (non-options)
inline const stringList& args() const;
//- Return non-const access to arguments
//- Non-const access to the command arguments (non-options)
inline stringList& args();
//- Return the argument corresponding to index.
inline const string& arg(const label index) const;
//- Return the number of arguments
//- Return the number of arguments, which includes the name of
//- the executable
inline label size() const;
//- Read a value from the argument at index.
//- Read a value from the argument at the given index.
// Index 0 corresponds to the name of the executable.
// Index 1 corresponds to the first argument.
template<class T>
inline T argRead(const label index) const;
inline T argRead(const label argIndex) const;
//- Return options
//- Return the command options
inline const HashTable<string>& options() const;
//- Return non-const access to options
//- Return non-const access to the command options
inline HashTable<string>& options();
//- Return the argument string associated with the named option
inline const string& option(const word& opt) const;
//- Return true if the named option is found
inline bool optionFound(const word& opt) const;
inline bool optionFound(const word& optionName) const;
//- Return an IStringStream from the named option
inline IStringStream optionLookup(const word& opt) const;
inline IStringStream optionLookup(const word& optionName) const;
//- Read a value from the named option
template<class T>
inline T optionRead(const word& opt) const;
inline T optionRead(const word& optionName) const;
//- Read a value from the named option if present.
// Return true if the named option was found.
template<class T>
inline bool optionReadIfPresent(const word& opt, T& val) const;
inline bool optionReadIfPresent
(
const word& optionName,
T& val
) const;
//- Read a value from the named option if present.
// Return true if the named option was found, otherwise
@ -325,7 +324,7 @@ public:
template<class T>
inline bool optionReadIfPresent
(
const word& opt,
const word& optionName,
T& val,
const T& deflt
) const;
@ -335,25 +334,23 @@ public:
template<class T>
inline T optionLookupOrDefault
(
const word& opt,
const word& optionName,
const T& deflt
) const;
//- Read a List of values from the named option
//- Read a List of values from the named option,
//- treating a single entry like a list of size 1.
template<class T>
List<T> optionReadList(const word& opt) const
{
return Foam::readList<T>(optionLookup(opt)());
}
inline List<T> optionReadList(const word& optionName) const;
//- Return the argument corresponding to index.
// Index 0 corresponds to the name of the executable.
// Index 1 corresponds to the first argument.
inline const string& operator[](const label index) const;
inline const string& operator[](const label argIndex) const;
//- Return the argument string associated with the named option
inline const string& operator[](const word& opt) const;
//- Return the string associated with the named option
inline const string& operator[](const word& optionName) const;
// Edit
@ -364,7 +361,7 @@ public:
//- Add a bool option to validOptions with usage information
static void addBoolOption
(
const word& opt,
const word& optionName,
const string& usage = ""
);
@ -372,7 +369,7 @@ public:
// An option with an empty param is a bool option
static void addOption
(
const word& opt,
const word& optionName,
const string& param = "",
const string& usage = ""
);
@ -393,7 +390,7 @@ public:
//- Add option usage information to optionUsage
static void addUsage
(
const word& opt,
const word& optionName,
const string& usage
);
@ -402,7 +399,7 @@ public:
static void addNote(const string& note);
//- Remove option from validOptions and from optionUsage
static void removeOption(const word& opt);
static void removeOption(const word& optionName);
//- Flag command arguments as being non-mandatory
static void nonMandatoryArgs();
@ -432,14 +429,14 @@ public:
//- Set option directly (use with caution)
// An option with an empty param is a bool option.
// Not all valid options can also be set: eg, -case, -roots, ...
// Return true if the existing option value needed changing,
// or if the option did not previously exist.
bool setOption(const word& opt, const string& param = "");
// \return true if the existing option value was changed or
// did not previously exist.
bool setOption(const word& optionName, const string& param="");
//- Unset option directly (use with caution)
// Not all valid options can also be unset: eg, -case, -roots ...
// Return true if the option existed before being unset.
bool unsetOption(const word& opt);
// \return true if the option existed before being unset.
bool unsetOption(const word& optionName);
// Print

View File

@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "ITstream.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -81,12 +82,6 @@ inline Foam::stringList& Foam::argList::args()
}
inline const Foam::string& Foam::argList::arg(const label index) const
{
return args_[index];
}
inline Foam::label Foam::argList::size() const
{
return args_.size();
@ -105,21 +100,18 @@ inline Foam::HashTable<Foam::string>& Foam::argList::options()
}
inline const Foam::string& Foam::argList::option(const word& opt) const
inline bool Foam::argList::optionFound(const word& optionName) const
{
return options_[opt];
return options_.found(optionName);
}
inline bool Foam::argList::optionFound(const word& opt) const
inline Foam::IStringStream Foam::argList::optionLookup
(
const word& optionName
) const
{
return options_.found(opt);
}
inline Foam::IStringStream Foam::argList::optionLookup(const word& opt) const
{
return IStringStream(options_[opt]);
return IStringStream(options_[optionName]);
}
@ -133,37 +125,37 @@ namespace Foam
template<>
inline Foam::string
argList::argRead<Foam::string>(const label index) const
argList::argRead<Foam::string>(const label argIndex) const
{
return args_[index];
return args_[argIndex];
}
template<>
inline Foam::word
argList::argRead<Foam::word>(const label index) const
argList::argRead<Foam::word>(const label argIndex) const
{
return args_[index];
return args_[argIndex];
}
template<>
inline Foam::fileName
argList::argRead<Foam::fileName>(const label index) const
argList::argRead<Foam::fileName>(const label argIndex) const
{
return args_[index];
return args_[argIndex];
}
template<>
inline Foam::label
argList::argRead<Foam::label>(const label index) const
argList::argRead<Foam::label>(const label argIndex) const
{
return Foam::readLabel(args_[index]);
return Foam::readLabel(args_[argIndex]);
}
template<>
inline Foam::scalar
argList::argRead<Foam::scalar>(const label index) const
argList::argRead<Foam::scalar>(const label argIndex) const
{
return Foam::readScalar(args_[index]);
return Foam::readScalar(args_[argIndex]);
}
//
@ -172,37 +164,37 @@ namespace Foam
template<>
inline Foam::string
argList::optionRead<Foam::string>(const word& opt) const
argList::optionRead<Foam::string>(const word& optionName) const
{
return options_[opt];
return options_[optionName];
}
template<>
inline Foam::word
argList::optionRead<Foam::word>(const word& opt) const
argList::optionRead<Foam::word>(const word& optionName) const
{
return options_[opt];
return options_[optionName];
}
template<>
inline Foam::fileName
argList::optionRead<Foam::fileName>(const word& opt) const
argList::optionRead<Foam::fileName>(const word& optionName) const
{
return options_[opt];
return options_[optionName];
}
template<>
inline Foam::label
argList::optionRead<Foam::label>(const word& opt) const
argList::optionRead<Foam::label>(const word& optionName) const
{
return Foam::readLabel(options_[opt]);
return Foam::readLabel(options_[optionName]);
}
template<>
inline Foam::scalar
argList::optionRead<Foam::scalar>(const word& opt) const
argList::optionRead<Foam::scalar>(const word& optionName) const
{
return Foam::readScalar(options_[opt]);
return Foam::readScalar(options_[optionName]);
}
}
@ -211,21 +203,21 @@ namespace Foam
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline T Foam::argList::argRead(const label index) const
inline T Foam::argList::argRead(const label argIndex) const
{
T val;
IStringStream(args_[index])() >> val;
IStringStream(args_[argIndex])() >> val;
return val;
}
template<class T>
inline T Foam::argList::optionRead(const word& opt) const
inline T Foam::argList::optionRead(const word& optionName) const
{
T val;
optionLookup(opt)() >> val;
IStringStream(options_[optionName])() >> val;
return val;
}
@ -233,71 +225,97 @@ inline T Foam::argList::optionRead(const word& opt) const
template<class T>
inline bool Foam::argList::optionReadIfPresent
(
const word& opt,
const word& optionName,
T& val
) const
{
if (optionFound(opt))
if (optionFound(optionName))
{
val = optionRead<T>(opt);
val = optionRead<T>(optionName);
return true;
}
else
{
return false;
}
return false;
}
template<class T>
inline bool Foam::argList::optionReadIfPresent
(
const word& opt,
const word& optionName,
T& val,
const T& deflt
) const
{
if (optionReadIfPresent<T>(opt, val))
if (optionReadIfPresent<T>(optionName, val))
{
return true;
}
else
{
val = deflt;
return false;
}
val = deflt;
return false;
}
template<class T>
inline T Foam::argList::optionLookupOrDefault
(
const word& opt,
const word& optionName,
const T& deflt
) const
{
if (optionFound(opt))
if (optionFound(optionName))
{
return optionRead<T>(opt);
return optionRead<T>(optionName);
}
return deflt;
}
template<class T>
inline Foam::List<T> Foam::argList::optionReadList
(
const word& optionName
) const
{
List<T> list;
ITstream its(optionName, options_[optionName]);
if (its.size() == 1)
{
// Single token - treated like list with one entry
list.setSize(1);
its >> list[0];
}
else
{
return deflt;
its >> list;
}
return list;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline const Foam::string& Foam::argList::operator[](const label index) const
inline const Foam::string& Foam::argList::operator[]
(
const label argIndex
) const
{
return args_[index];
return args_[argIndex];
}
inline const Foam::string& Foam::argList::operator[](const word& opt) const
inline const Foam::string& Foam::argList::operator[]
(
const word& optionName
) const
{
return options_[opt];
return options_[optionName];
}