diff --git a/applications/test/dictionary2/Test-dictionary2.C b/applications/test/dictionary2/Test-dictionary2.C index fc883a9cf58e9380dad2a17ae5a8ddd6672c0c33..b309da36ebdc2643c831ce2399c0bffe9db7f205 100644 --- a/applications/test/dictionary2/Test-dictionary2.C +++ b/applications/test/dictionary2/Test-dictionary2.C @@ -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 - { - scalar val1 = dict2.get<scalar>("good"); - // scalar val2 = dict2.get<scalar>("bad"); - scalar val2 = -1; - scalar val3 = dict2.get<scalar>("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_getScalar(dict2, "good"); + // try_getScalar(dict2, "bad"); + try_getScalar(dict2, "empty"); + } + + // With findEntry and get<scalar> + { + Info<< nl + << "Test some bad input with findEntry + get<scalar>()" << nl; + + try_getScalar(dict2.findEntry("good"), "good"); + // try_getScalar(dict2.findEntry("bad"), "bad"); + try_getScalar(dict2.findEntry("empty"), "empty"); } } diff --git a/applications/test/fvSolutionCombine/Test-fvSolutionCombine.C b/applications/test/fvSolutionCombine/Test-fvSolutionCombine.C index f3ed8436804b3e01234d51dd4e0e95df68c47df9..71d604395df2609c0713f71c0ccf44a57306d5a7 100644 --- a/applications/test/fvSolutionCombine/Test-fvSolutionCombine.C +++ b/applications/test/fvSolutionCombine/Test-fvSolutionCombine.C @@ -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; diff --git a/src/OpenFOAM/db/dictionary/dictionaryEntry/dictionaryEntry.H b/src/OpenFOAM/db/dictionary/dictionaryEntry/dictionaryEntry.H index c7850f31248e94feb60bd422bc933bff4e390d4f..62f4c8226d73217fa69460cf9c87b7205f2d0496 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryEntry/dictionaryEntry.H +++ b/src/OpenFOAM/db/dictionary/dictionaryEntry/dictionaryEntry.H @@ -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 diff --git a/src/OpenFOAM/db/dictionary/entry/entry.C b/src/OpenFOAM/db/dictionary/entry/entry.C index 81b88563b036c1c2a4a0113a12c8762c83dec6c6..c7f8038092f382402532081781c8c16ca9afebd9 100644 --- a/src/OpenFOAM/db/dictionary/entry/entry.C +++ b/src/OpenFOAM/db/dictionary/entry/entry.C @@ -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) diff --git a/src/OpenFOAM/db/dictionary/entry/entry.H b/src/OpenFOAM/db/dictionary/entry/entry.H index ec7b17bd04624e5d414d39c28851a356cdd61bb5..09d73d051eaa9c71a39e6a06bb5b1e2731e22b51 100644 --- a/src/OpenFOAM/db/dictionary/entry/entry.H +++ b/src/OpenFOAM/db/dictionary/entry/entry.H @@ -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); }; diff --git a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntry.H b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntry.H index 86bea927e5603054c61e3de1a94afb5d1e9363ab..bdbe013ba23c1ed0cc330d6232a89594a3bb91c2 100644 --- a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntry.H +++ b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntry.H @@ -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; diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C index a626aa78740ca1e7ea1d599e41c630286335311d..dbd5fccb40119d6456f1cd3f3c71f5fa2ddf477c 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C @@ -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); } diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H index c114d1303c9cead0521d9a7bf4e2fd4964d432f3..6228a09bd5ce349cd77e8c6e63660d55366504a5 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H @@ -66,7 +66,7 @@ class dynamicCodeContext //- Optional "codeOptions" entry string options_; - //- Optional "codeLib" entry + //- Optional "codeLibs" entry string libs_; //- Calculated SHA1Digest