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:
Mark Olesen 2018-10-16 11:13:35 +02:00
parent 8a923518a5
commit 77017e58f4
8 changed files with 257 additions and 75 deletions

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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);
};

View File

@ -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;

View File

@ -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);
}

View File

@ -66,7 +66,7 @@ class dynamicCodeContext
//- Optional "codeOptions" entry
string options_;
//- Optional "codeLib" entry
//- Optional "codeLibs" entry
string libs_;
//- Calculated SHA1Digest