ENH: support token stream checking to entry (issue #762)
- Eg, scalar val(-GREAT); const entry* eptr = dict.findEntry(k); if (eptr) { val = eptr.get<scalar>(); // Or eptr.readEntry(val); }
This commit is contained in:
parent
8a923518a5
commit
77017e58f4
@ -48,6 +48,102 @@ void entryInfo(entry* e)
|
||||
}
|
||||
|
||||
|
||||
// Try with readScalar
|
||||
scalar try_readScalar(const dictionary& dict, const word& k)
|
||||
{
|
||||
scalar val(-GREAT);
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
|
||||
try
|
||||
{
|
||||
val = readScalar(dict.lookup(k));
|
||||
Info<< "readScalar(" << k << ") = " << val << nl;
|
||||
}
|
||||
catch (Foam::IOerror& err)
|
||||
{
|
||||
Info<< "readScalar(" << k << ") Caught FatalIOError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
catch (Foam::error& err)
|
||||
{
|
||||
Info<< "readScalar(" << k << ") Caught FatalError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
// Try with get<scalar>
|
||||
scalar try_getScalar(const dictionary& dict, const word& k)
|
||||
{
|
||||
scalar val(-GREAT);
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
|
||||
try
|
||||
{
|
||||
val = dict.get<scalar>(k);
|
||||
Info<< "get<scalar>(" << k << ") = " << val << nl;
|
||||
}
|
||||
catch (Foam::IOerror& err)
|
||||
{
|
||||
Info<< "get<scalar>(" << k << ") Caught FatalIOError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
catch (Foam::error& err)
|
||||
{
|
||||
Info<< "get<scalar>(" << k << ") Caught FatalError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
// Try with *entry (from findEntry) and get<scalar>
|
||||
scalar try_getScalar(const entry* eptr, const word& k)
|
||||
{
|
||||
scalar val(-GREAT);
|
||||
|
||||
if (!eptr)
|
||||
{
|
||||
Info<< "No entry" << k << nl;
|
||||
return val;
|
||||
}
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
|
||||
try
|
||||
{
|
||||
val = eptr->get<scalar>();
|
||||
Info<< "entry get<scalar>(" << k << ") = " << val << nl;
|
||||
}
|
||||
catch (Foam::IOerror& err)
|
||||
{
|
||||
Info<< "entry get<scalar>(" << k << ") Caught FatalIOError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
catch (Foam::error& err)
|
||||
{
|
||||
Info<< "entry get<scalar>(" << k << ") Caught FatalError "
|
||||
<< err << nl << endl;
|
||||
}
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
@ -227,29 +323,9 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< nl << "Test some bad input with readScalar()" << nl;
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
|
||||
try
|
||||
{
|
||||
scalar val1 = readScalar(dict2.lookup("good"));
|
||||
// scalar val2 = readScalar(dict2.lookup("bad"));
|
||||
scalar val2 = -1;
|
||||
scalar val3 = readScalar(dict2.lookup("empty"));
|
||||
|
||||
Info<< "got good=" << val1 << " bad=" << val2
|
||||
<< " empty=" << val3 << nl;
|
||||
}
|
||||
catch (Foam::IOerror& err)
|
||||
{
|
||||
Info<< "Caught FatalIOError " << err << nl << endl;
|
||||
}
|
||||
catch (Foam::error& err)
|
||||
{
|
||||
Info<< "Caught FatalError " << err << nl << endl;
|
||||
}
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
try_readScalar(dict2, "good");
|
||||
// try_readScalar(dict2, "bad");
|
||||
try_readScalar(dict2, "empty");
|
||||
}
|
||||
|
||||
|
||||
@ -257,29 +333,19 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< nl << "Test some bad input with get<scalar>()" << nl;
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
try_getScalar(dict2, "good");
|
||||
// try_getScalar(dict2, "bad");
|
||||
try_getScalar(dict2, "empty");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
scalar val1 = dict2.get<scalar>("good");
|
||||
// scalar val2 = dict2.get<scalar>("bad");
|
||||
scalar val2 = -1;
|
||||
scalar val3 = dict2.get<scalar>("empty");
|
||||
// With findEntry and get<scalar>
|
||||
{
|
||||
Info<< nl
|
||||
<< "Test some bad input with findEntry + get<scalar>()" << nl;
|
||||
|
||||
Info<< "got good=" << val1 << " bad=" << val2
|
||||
<< " empty=" << val3 << nl;
|
||||
}
|
||||
catch (Foam::IOerror& err)
|
||||
{
|
||||
Info<< "Caught FatalIOError " << err << nl << endl;
|
||||
}
|
||||
catch (Foam::error& err)
|
||||
{
|
||||
Info<< "Caught FatalError " << err << nl << endl;
|
||||
}
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
try_getScalar(dict2.findEntry("good"), "good");
|
||||
// try_getScalar(dict2.findEntry("bad"), "bad");
|
||||
try_getScalar(dict2.findEntry("empty"), "empty");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,17 +50,16 @@ bool checkDictionaryContent(const dictionary& dict1, const dictionary& dict2)
|
||||
}
|
||||
|
||||
|
||||
forAllConstIter(dictionary, dict1, iter1)
|
||||
for (const entry& entry1 : dict1)
|
||||
{
|
||||
const entry* eptr =
|
||||
dict2.findEntry(iter1().keyword(), keyType::LITERAL);
|
||||
dict2.findEntry(entry1.keyword(), keyType::LITERAL);
|
||||
|
||||
if (!eptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const entry& entry1 = iter1();
|
||||
const entry& entry2 = *eptr;
|
||||
|
||||
bool ok = false;
|
||||
|
@ -111,26 +111,26 @@ public:
|
||||
// Member functions
|
||||
|
||||
//- Return the scoped dictionary name (eg, dictA.dictB.dictC)
|
||||
const fileName& name() const
|
||||
virtual const fileName& name() const
|
||||
{
|
||||
return dictionary::name();
|
||||
}
|
||||
|
||||
//- Return the scoped dictionary name (eg, dictA.dictB.dictC)
|
||||
fileName& name()
|
||||
virtual fileName& name()
|
||||
{
|
||||
return dictionary::name();
|
||||
}
|
||||
|
||||
//- Return line number of first token in dictionary
|
||||
label startLineNumber() const;
|
||||
virtual label startLineNumber() const;
|
||||
|
||||
//- Return line number of last token in dictionary
|
||||
label endLineNumber() const;
|
||||
virtual label endLineNumber() const;
|
||||
|
||||
//- This entry is not a primitive,
|
||||
// calling this function generates a FatalError
|
||||
ITstream& stream() const;
|
||||
virtual ITstream& stream() const;
|
||||
|
||||
|
||||
//- Return pointer to this dictionary
|
||||
@ -140,14 +140,14 @@ public:
|
||||
virtual dictionary* dictPtr();
|
||||
|
||||
//- Return dictionary
|
||||
const dictionary& dict() const;
|
||||
virtual const dictionary& dict() const;
|
||||
|
||||
//- Return non-const access to dictionary
|
||||
dictionary& dict();
|
||||
virtual dictionary& dict();
|
||||
|
||||
|
||||
//- Write
|
||||
void write(Ostream& os) const;
|
||||
virtual void write(Ostream& os) const;
|
||||
|
||||
//- Return info proxy.
|
||||
// Used to print token information to a stream
|
||||
|
@ -26,6 +26,7 @@ License
|
||||
#include "entry.H"
|
||||
#include "dictionary.H"
|
||||
#include "StringStream.H"
|
||||
#include "JobInfo.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -46,6 +47,88 @@ void Foam::entry::resetInputMode()
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::entry::checkITstream(const ITstream& is) const
|
||||
{
|
||||
const word& keyword = keyword_;
|
||||
|
||||
if (is.nRemainingTokens())
|
||||
{
|
||||
const label remaining = is.nRemainingTokens();
|
||||
|
||||
// Similar to SafeFatalIOError
|
||||
if (JobInfo::constructed)
|
||||
{
|
||||
OSstream& err =
|
||||
FatalIOError
|
||||
(
|
||||
"", // functionName
|
||||
"", // sourceFileName
|
||||
0, // sourceFileLineNumber
|
||||
this->name(), // ioFileName
|
||||
is.lineNumber() // ioStartLineNumber
|
||||
);
|
||||
|
||||
err << "'" << keyword << "' has "
|
||||
<< remaining << " excess tokens in stream" << nl << nl
|
||||
<< " ";
|
||||
is.writeList(err, 0);
|
||||
|
||||
err << exit(FatalIOError);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr
|
||||
<< nl
|
||||
<< "--> FOAM FATAL IO ERROR:" << nl;
|
||||
|
||||
std::cerr
|
||||
<< "'" << keyword << "' has "
|
||||
<< remaining << " excess tokens in stream" << nl << nl;
|
||||
|
||||
std::cerr
|
||||
<< "file: " << this->name()
|
||||
<< " at line " << is.lineNumber() << '.' << nl
|
||||
<< std::endl;
|
||||
|
||||
::exit(1);
|
||||
}
|
||||
}
|
||||
else if (!is.size())
|
||||
{
|
||||
// Similar to SafeFatalIOError
|
||||
if (JobInfo::constructed)
|
||||
{
|
||||
FatalIOError
|
||||
(
|
||||
"", // functionName
|
||||
"", // sourceFileName
|
||||
0, // sourceFileLineNumber
|
||||
this->name(), // ioFileName
|
||||
is.lineNumber() // ioStartLineNumber
|
||||
)
|
||||
<< "'" << keyword << "' had no tokens in stream" << nl << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr
|
||||
<< nl
|
||||
<< "--> FOAM FATAL IO ERROR:" << nl
|
||||
<< "'" << keyword << "' had no tokens in stream" << nl << nl;
|
||||
|
||||
std::cerr
|
||||
<< "file: " << this->name()
|
||||
<< " at line " << is.lineNumber() << '.' << nl
|
||||
<< std::endl;
|
||||
|
||||
::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::entry::entry(const keyType& keyword)
|
||||
|
@ -107,6 +107,11 @@ private:
|
||||
// \return True if it is a valid keyType.
|
||||
static bool getKeyword(keyType& keyword, Istream& is);
|
||||
|
||||
//- Check after reading if the input token stream has unconsumed
|
||||
//- tokens remaining or if there were no tokens in the first place.
|
||||
// Emits FatalIOError
|
||||
void checkITstream(const ITstream& is) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -176,7 +181,7 @@ public:
|
||||
virtual ~entry() = default;
|
||||
|
||||
|
||||
// Member functions
|
||||
// Member Functions
|
||||
|
||||
//- Return keyword
|
||||
const keyType& keyword() const
|
||||
@ -244,7 +249,31 @@ public:
|
||||
virtual void write(Ostream& os) const = 0;
|
||||
|
||||
|
||||
// Member operators
|
||||
//- Get a T from the stream,
|
||||
//- FatalIOError if the number of tokens is incorrect.
|
||||
template<class T>
|
||||
T get() const
|
||||
{
|
||||
T val;
|
||||
readEntry<T>(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
//- Assign to T val,
|
||||
//- FatalIOError if the number of tokens is incorrect.
|
||||
//
|
||||
// \param val the value to read into
|
||||
template<class T>
|
||||
void readEntry(T& val) const
|
||||
{
|
||||
ITstream& is = this->stream();
|
||||
is >> val;
|
||||
|
||||
checkITstream(is);
|
||||
}
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
void operator=(const entry& e);
|
||||
|
||||
@ -252,7 +281,7 @@ public:
|
||||
bool operator!=(const entry& e) const;
|
||||
|
||||
|
||||
// Ostream operator
|
||||
// Ostream Operator
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const entry& e);
|
||||
};
|
||||
|
@ -138,51 +138,51 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Member functions
|
||||
// Member Functions
|
||||
|
||||
//- Inherit read from ITstream
|
||||
using ITstream::read;
|
||||
|
||||
//- Return the dictionary name
|
||||
const fileName& name() const
|
||||
virtual const fileName& name() const
|
||||
{
|
||||
return ITstream::name();
|
||||
}
|
||||
|
||||
//- Return the dictionary name
|
||||
fileName& name()
|
||||
virtual fileName& name()
|
||||
{
|
||||
return ITstream::name();
|
||||
}
|
||||
|
||||
//- Return line number of first token in dictionary
|
||||
label startLineNumber() const;
|
||||
virtual label startLineNumber() const;
|
||||
|
||||
//- Return line number of last token in dictionary
|
||||
label endLineNumber() const;
|
||||
virtual label endLineNumber() const;
|
||||
|
||||
//- Return true because this entry is a stream
|
||||
bool isStream() const
|
||||
//- Return true - this entry is a stream
|
||||
virtual bool isStream() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//- Return token stream for this primitive entry
|
||||
ITstream& stream() const;
|
||||
virtual ITstream& stream() const;
|
||||
|
||||
//- This entry is not a dictionary,
|
||||
// calling this function generates a FatalError
|
||||
const dictionary& dict() const;
|
||||
virtual const dictionary& dict() const;
|
||||
|
||||
//- This entry is not a dictionary,
|
||||
// calling this function generates a FatalError
|
||||
dictionary& dict();
|
||||
virtual dictionary& dict();
|
||||
|
||||
//- Read tokens from the given stream
|
||||
virtual bool read(const dictionary& dict, Istream& is);
|
||||
|
||||
//- Write
|
||||
void write(Ostream& os) const;
|
||||
virtual void write(Ostream& os) const;
|
||||
|
||||
//- Write, optionally with contents only (no keyword, etc)
|
||||
void write(Ostream& os, const bool contentsOnly) const;
|
||||
|
@ -48,7 +48,8 @@ Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
|
||||
|
||||
if (codePtr)
|
||||
{
|
||||
code_ = stringOps::trim(codePtr->stream());
|
||||
codePtr->readEntry(code_);
|
||||
stringOps::inplaceTrim(code_);
|
||||
stringOps::inplaceExpand(code_, dict);
|
||||
}
|
||||
|
||||
@ -56,7 +57,8 @@ Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
|
||||
|
||||
if (includePtr)
|
||||
{
|
||||
include_ = stringOps::trim(includePtr->stream());
|
||||
includePtr->readEntry(include_);
|
||||
stringOps::inplaceTrim(include_);
|
||||
stringOps::inplaceExpand(include_, dict);
|
||||
}
|
||||
|
||||
@ -64,7 +66,8 @@ Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
|
||||
|
||||
if (optionsPtr)
|
||||
{
|
||||
options_ = stringOps::trim(optionsPtr->stream());
|
||||
optionsPtr->readEntry(options_);
|
||||
stringOps::inplaceTrim(options_);
|
||||
stringOps::inplaceExpand(options_, dict);
|
||||
}
|
||||
|
||||
@ -72,7 +75,8 @@ Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
|
||||
|
||||
if (libsPtr)
|
||||
{
|
||||
libs_ = stringOps::trim(libsPtr->stream());
|
||||
libsPtr->readEntry(libs_);
|
||||
stringOps::inplaceTrim(libs_);
|
||||
stringOps::inplaceExpand(libs_, dict);
|
||||
}
|
||||
|
||||
@ -80,7 +84,8 @@ Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
|
||||
|
||||
if (localPtr)
|
||||
{
|
||||
localCode_ = stringOps::trim(localPtr->stream());
|
||||
localPtr->readEntry(localCode_);
|
||||
stringOps::inplaceTrim(localCode_);
|
||||
stringOps::inplaceExpand(localCode_, dict);
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ class dynamicCodeContext
|
||||
//- Optional "codeOptions" entry
|
||||
string options_;
|
||||
|
||||
//- Optional "codeLib" entry
|
||||
//- Optional "codeLibs" entry
|
||||
string libs_;
|
||||
|
||||
//- Calculated SHA1Digest
|
||||
|
Loading…
Reference in New Issue
Block a user