diff --git a/applications/test/dictionary2/Test-dictionary2.C b/applications/test/dictionary2/Test-dictionary2.C index 36460568e6c58543f26d585e455125bca75c86b3..fc883a9cf58e9380dad2a17ae5a8ddd6672c0c33 100644 --- a/applications/test/dictionary2/Test-dictionary2.C +++ b/applications/test/dictionary2/Test-dictionary2.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -25,8 +25,7 @@ Application Test-dictionary2 Description - - Test dictionary insertion + Test dictionary insertion and some reading functionality. \*---------------------------------------------------------------------------*/ @@ -208,6 +207,83 @@ int main(int argc, char *argv[]) Info<< nl << "dictionary" << nl << nl; dict1.write(Info, false); + + { + Info<< nl << "Test reading good/bad/empty scalar entries" << nl; + dictionary dict2 + ( + IStringStream + ( + "good 3.14159;\n" + "empty;\n" + // "bad text;\n" // always fails + // "bad 3.14159 1234;\n" // fails for readScalar + )() + ); + dict2.write(Info); + + + // With readScalar + { + 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); + } + + + // With get<scalar> + { + 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); + } + } + + Info<< "\nDone\n" << endl; return 0; diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C index 580744d06cea2a470fedff5fce39995ee0eeb8cc..125c73e127941f86ab595f1ed1a1ef8597fe20b2 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.C +++ b/src/OpenFOAM/db/dictionary/dictionary.C @@ -48,24 +48,59 @@ bool Foam::dictionary::writeOptionalEntries // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -void Foam::dictionary::excessTokens +void Foam::dictionary::checkITstream ( const word& keyword, const ITstream& is ) const { - const label nExcess = is.nRemainingTokens(); - - if (!nExcess) + if (is.nRemainingTokens()) { - return; - } + 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; - // Similar to SafeFatalIOError + std::cerr + << "file: " << this->name() + << " at line " << is.lineNumber() << '.' << nl + << std::endl; - if (JobInfo::constructed) + ::exit(1); + } + } + else if (!is.size()) { - OSstream& err = + // Similar to SafeFatalIOError + if (JobInfo::constructed) + { FatalIOError ( "", // functionName @@ -73,31 +108,24 @@ void Foam::dictionary::excessTokens 0, // sourceFileLineNumber this->name(), // ioFileName is.lineNumber() // ioStartLineNumber - ); - - err << "'" << keyword << "' has " - << nExcess << " 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 " - << nExcess << " excess tokens in stream" << nl << nl; + ) + << "'" << 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; + std::cerr + << "file: " << this->name() + << " at line " << is.lineNumber() << '.' << nl + << std::endl; - ::exit(1); + ::exit(1); + } } } diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H index 384efa081b72b0428486c6e1d380519931ad37ac..dafb0b5179c2315106cca2438ff0b62736b80f4c 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.H +++ b/src/OpenFOAM/db/dictionary/dictionary.H @@ -383,8 +383,10 @@ private: ) const; - //- Emit FatalIOError if excess tokens exist - void excessTokens(const word& keyword, const ITstream& is) const; + //- 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 word& keyword, const ITstream& is) const; public: diff --git a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C index 95cd8ab8a720f5c0ea7b7651b45506d3553ba23b..fab47e648891b2e09ac68aef6cdeac7a22543bae 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C +++ b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C @@ -97,7 +97,7 @@ bool Foam::dictionary::readCompat ITstream& is = finder.ptr()->stream(); is >> val; - excessTokens(keyword, is); + checkITstream(keyword, is); return true; } @@ -144,7 +144,7 @@ T Foam::dictionary::lookupOrDefault ITstream& is = finder.ptr()->stream(); is >> val; - excessTokens(keyword, is); + checkITstream(keyword, is); return val; } @@ -178,7 +178,7 @@ T Foam::dictionary::lookupOrAddDefault ITstream& is = finder.ptr()->stream(); is >> val; - excessTokens(keyword, is); + checkITstream(keyword, is); return val; } @@ -212,7 +212,7 @@ bool Foam::dictionary::readEntry ITstream& is = finder.ptr()->stream(); is >> val; - excessTokens(keyword, is); + checkITstream(keyword, is); return true; } @@ -262,7 +262,7 @@ T Foam::dictionary::lookupOrDefaultCompat ITstream& is = finder.ptr()->stream(); is >> val; - excessTokens(keyword, is); + checkITstream(keyword, is); return val; } diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index bb03845536a9dd571a28046414c5a197b78c3ac4..84a6736bd6abff4e444866c9a7a54b520c733758 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -202,32 +202,46 @@ static void printBuildInfo(const bool full=true) // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // -void Foam::argList::warnTrailing(const ITstream& is, const label index) +void Foam::argList::checkITstream(const ITstream& is, const label index) { - const label nExcess = is.nRemainingTokens(); + const label remaining = is.nRemainingTokens(); - if (nExcess) + if (remaining) { std::cerr << nl << "--> FOAM WARNING:" << nl << "argument " << index << " has " - << nExcess << " excess tokens" << nl << nl; + << remaining << " excess tokens" << nl << nl; + } + else if (!is.size()) + { + std::cerr + << nl + << "--> FOAM WARNING:" << nl + << "argument " << index << " had no tokens" << nl << nl; } } -void Foam::argList::warnTrailing(const ITstream& is, const word& optName) +void Foam::argList::checkITstream(const ITstream& is, const word& optName) { - const label nExcess = is.nRemainingTokens(); + const label remaining = is.nRemainingTokens(); - if (nExcess) + if (remaining) { std::cerr << nl << "--> FOAM WARNING:" << nl << "option -" << optName << " has " - << nExcess << " excess tokens" << nl << nl; + << remaining << " excess tokens" << nl << nl; + } + else if (!is.size()) + { + std::cerr + << nl + << "--> FOAM WARNING:" << nl + << "option -" << optName << " had no tokens" << nl << nl; } } @@ -1141,7 +1155,7 @@ void Foam::argList::parse source = "-hostRoots"; ITstream is = this->lookup("hostRoots"); List<Tuple2<wordRe, fileName>> hostRoots(is); - warnTrailing(is, "hostRoots"); + checkITstream(is, "hostRoots"); for (const auto& hostRoot : hostRoots) { diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index ba1baa8f3ae0fef5acb2b54ca90192381728469d..3bcc32ea1e23a2c84f8cc16dc790c5a34c402a08 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -161,11 +161,15 @@ class argList const string& str ); - //- Warn if there are input tokens remaining on the stream - static void warnTrailing(const ITstream& is, const label index); - - //- Warn if there are input tokens remaining on the stream - static void warnTrailing(const ITstream& is, const word& optName); + //- Check after reading if the input token stream has unconsumed + //- tokens remaining or if there were no tokens in the first place. + // Emits Warning + static void checkITstream(const ITstream& is, const label index); + + //- Check after reading if the input token stream has unconsumed + //- tokens remaining or if there were no tokens in the first place. + // Emits Warning + static void checkITstream(const ITstream& is, const word& optName); //- Read a List of values from ITstream, //- treating a single entry like a list of size 1. diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H index 8457a4cf82e9d29c10faf1577e275b660586f2d2..c473becff175d198ede8c035cf1e6991aa350dfc 100644 --- a/src/OpenFOAM/global/argList/argListI.H +++ b/src/OpenFOAM/global/argList/argListI.H @@ -230,7 +230,7 @@ inline T Foam::argList::get(const label index) const T val; is >> val; - warnTrailing(is, index); + checkITstream(is, index); return val; } @@ -244,7 +244,7 @@ inline T Foam::argList::opt(const word& optName) const T val; is >> val; - warnTrailing(is, optName); + checkITstream(is, optName); return val; } @@ -309,7 +309,7 @@ inline Foam::List<T> Foam::argList::getList(const label index) const List<T> list; readList(is, list); - warnTrailing(is, index); + checkITstream(is, index); return list; } @@ -323,7 +323,7 @@ inline Foam::List<T> Foam::argList::getList(const word& optName) const List<T> list; readList(is, list); - warnTrailing(is, optName); + checkITstream(is, optName); return list; } @@ -341,7 +341,7 @@ inline bool Foam::argList::readListIfPresent ITstream is(optName, options_[optName]); readList(is, list); - warnTrailing(is, optName); + checkITstream(is, optName); return true; }