ENH: improve infrastructure for detecting excess tokens (issue #762)

- Always used for optional dictionary entries, since these are individual
  values, and not meant to be embedded in a larger stream of tokens.

  Methods:
     - lookupOrDefault, lookupOrAddDefault, lookupOrDefaultCompat
     - readIfPresent, readIfPresentCompat

- Handling mandatory dictionary entries is slightly more complex,
  since these may be part of larger stream of tokens, and are often
  used in a constructor context. For example,

      word modelType(dict.lookup("type"));

  Or they are used without a definite context. For example,

      dict.lookup("format") >> outputFormat;

  Newly introduced methods for mandatory dictionary entries:
     - get, getCompat
     - read, readCompat

  In a constructor or assignment context:

      word modelType(dict.get<word>("type"));
      outputFormat = dict.lookup("format");

  without copy/move (similar to readIfPresent):

      dict.read("format", outputFormat);
This commit is contained in:
Mark Olesen
2018-06-01 11:55:57 +02:00
parent a6f524b1df
commit 511b35629d
8 changed files with 279 additions and 220 deletions

View File

@ -138,7 +138,7 @@ const T* Foam::DictionaryBase<IDLListType, T>::lookup(const word& keyword) const
if (iter == hashedTs_.end())
{
FatalErrorInFunction
<< keyword << " is undefined"
<< "'" << keyword << "' not found"
<< exit(FatalError);
}
@ -154,7 +154,7 @@ T* Foam::DictionaryBase<IDLListType, T>::lookup(const word& keyword)
if (iter == hashedTs_.end())
{
FatalErrorInFunction
<< keyword << " is undefined"
<< "'" << keyword << "' not found"
<< exit(FatalError);
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,6 +24,8 @@ License
\*---------------------------------------------------------------------------*/
#include "dictionary.H"
#include "error.H"
#include "JobInfo.H"
#include "primitiveEntry.H"
#include "dictionaryEntry.H"
#include "regExp.H"
@ -48,7 +50,6 @@ bool Foam::dictionary::writeOptionalEntries
void Foam::dictionary::excessTokens
(
OSstream& msg,
const word& keyword,
const ITstream& is
) const
@ -60,12 +61,44 @@ void Foam::dictionary::excessTokens
return;
}
msg << "entry '" << keyword << "' has "
<< nExcess << " excess tokens, near line: " << is.lineNumber() << nl
<< "dictionary: " << name() << nl
<< "stream: ";
is.writeList(msg, 0);
msg << nl;
// Similar to SafeFatalIOError
if (JobInfo::constructed)
{
OSstream& err =
FatalIOError
(
"", // functionName
"", // sourceFileName
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;
std::cerr
<< "file: " << this->name()
<< " at line " << is.lineNumber() << '.' << nl
<< std::endl;
::exit(1);
}
}
@ -296,10 +329,8 @@ const Foam::entry& Foam::dictionary::lookupEntry
if (!finder.found())
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
@ -422,10 +453,8 @@ const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
if (!finder.found())
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
@ -441,10 +470,8 @@ Foam::dictionary& Foam::dictionary::subDict(const word& keyword)
if (!finder.found())
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
@ -470,20 +497,18 @@ Foam::dictionary Foam::dictionary::subOrEmptyDict
if (mustRead)
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword
<< " is not a sub-dictionary in dictionary "
FatalIOErrorInFunction(*this)
<< "'" << keyword
<< "' is not a sub-dictionary in dictionary "
<< name()
<< exit(FatalIOError);
}
if (finder.found())
{
IOWarningInFunction((*this))
<< "keyword " << keyword
<< " found but not a sub-dictionary in dictionary "
IOWarningInFunction(*this)
<< "'" << keyword
<< "' found but not a sub-dictionary in dictionary "
<< name() << endl;
}
@ -506,9 +531,9 @@ const Foam::dictionary& Foam::dictionary::optionalSubDict
if (finder.found())
{
IOWarningInFunction((*this))
<< "keyword " << keyword
<< " found but not a sub-dictionary in dictionary "
IOWarningInFunction(*this)
<< "'" << keyword
<< "' found but not a sub-dictionary in dictionary "
<< name() << endl;
}
@ -597,7 +622,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
}
IOWarningInFunction((*this))
IOWarningInFunction(*this)
<< "problem replacing entry "<< entryPtr->keyword()
<< " in dictionary " << name() << endl;
@ -626,7 +651,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
}
IOWarningInFunction((*this))
IOWarningInFunction(*this)
<< "attempt to add entry " << entryPtr->keyword()
<< " which already exists in dictionary " << name()
<< endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -143,18 +143,18 @@ public:
return name_;
}
//- Return the dictionary name
//- Return the dictionary name for modification (use with caution).
fileName& name()
{
return name_;
}
//- Return the local dictionary name (final part of scoped name)
const word dictName() const
word dictName() const
{
const word scopedName = name_.name();
const auto i = scopedName.rfind('.');
word scopedName(name_.name());
const auto i = scopedName.rfind('.');
if (i == std::string::npos)
{
return scopedName;
@ -383,13 +383,8 @@ private:
) const;
//- Add report of excess tokens to the messageStream
void excessTokens
(
OSstream& msg,
const word& keyword,
const ITstream& is
) const;
//- Emit FatalIOError if excess tokens exist
void excessTokens(const word& keyword, const ITstream& is) const;
public:
@ -505,7 +500,7 @@ public:
) const;
//- Find and return an entry pointer for manipulation if present,
// or return a nullptr.
//- or return a nullptr.
//
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
@ -516,7 +511,7 @@ public:
bool patternMatch
);
//- Find and return an entry if present otherwise error.
//- Find and return an entry if present, otherwise FatalIOError.
//
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
@ -528,7 +523,7 @@ public:
) const;
//- Find and return a T.
//- FatalError if not found, or if there are excess tokens.
//- FatalIOError if not found, or if there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param recursive search parent dictionaries
@ -554,13 +549,13 @@ public:
) const;
//- Find and return a T.
//- FatalError if not found, or if there are excess tokens.
//- FatalIOError if not found, or if there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
//
// \note same as get()
// \deprecated - same as the get() method
template<class T>
T lookupType
(
@ -570,7 +565,7 @@ public:
) const;
//- Find and return a T, or return the given default value
//- FatalError if it is found and there are excess tokens.
//- FatalIOError if it is found and there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param recursive search parent dictionaries
@ -586,7 +581,7 @@ public:
//- Find and return a T, or return the given default value
//- and add it to dictionary.
//- FatalError if it is found and there are excess tokens.
//- FatalIOError if it is found and there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param recursive search parent dictionaries
@ -600,8 +595,26 @@ public:
bool patternMatch = true
);
//- Find entry and assign to T val.
//- FatalIOError if it is found and there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
//
// \return true if the entry was found.
template<class T>
bool read
(
const word& keyword,
T& val,
bool recursive = false,
bool patternMatch = true,
bool mandatory = true
) const;
//- Find an entry if present, and assign to T val.
//- FatalError if it is found and there are excess tokens.
//- FatalIOError if it is found and there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param val the value to read
@ -662,7 +675,7 @@ public:
dictionary& subDict(const word& keyword);
//- Find and return a sub-dictionary as a copy, otherwise return
// an empty dictionary.
//- an empty dictionary.
// Warn if the entry exists but is not a sub-dictionary.
//
// Search type: non-recursive with patterns.
@ -984,7 +997,7 @@ public:
bool patternMatch
) const;
//- Find and return an entry if present otherwise error,
//- Find and return an entry if present, otherwise FatalIOError,
//- using any compatibility names if needed.
//
// \param compat list of old compatibility keywords and the last
@ -999,6 +1012,24 @@ public:
bool patternMatch
) const;
//- Find and return a T
//- using any compatibility names if needed.
//- FatalIOError if not found, or if there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param compat list of old compatibility keywords and the last
// OpenFOAM version for which they were used.
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
template<class T>
T getCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive = false,
bool patternMatch = true
) const;
//- Find and return an entry data stream,
//- using any compatibility names if needed.
// Default search: non-recursive with patterns.
@ -1033,8 +1064,32 @@ public:
bool patternMatch = true
) const;
//- Find entry and assign to T val
//- using any compatibility names if needed.
//- FatalIOError if there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param compat list of old compatibility keywords and the last
// OpenFOAM version for which they were used.
// \param val the value to read
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
//
// \return true if the entry was found.
template<class T>
bool readCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
T& val,
bool recursive = false,
bool patternMatch = true,
bool mandatory = true
) const;
//- Find an entry if present, and assign to T val
//- using any compatibility names if needed.
//- FatalIOError if it is found and there are excess tokens.
// Default search: non-recursive with patterns.
//
// \param compat list of old compatibility keywords and the last

View File

@ -52,7 +52,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
bool patternMatch
) const
{
const_searcher finder(csearch(keyword, recursive,patternMatch));
const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found())
{
@ -61,7 +61,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
for (const std::pair<const char*,int>& iter : compat)
{
finder = csearch(word::validate(iter.first), recursive,patternMatch);
finder = csearch(word::validate(iter.first), recursive, patternMatch);
if (finder.found())
{
@ -95,7 +95,7 @@ bool Foam::dictionary::foundCompat
bool patternMatch
) const
{
return csearchCompat(keyword, compat, recursive,patternMatch).found();
return csearchCompat(keyword, compat, recursive, patternMatch).found();
}
@ -107,7 +107,7 @@ const Foam::entry* Foam::dictionary::lookupEntryPtrCompat
bool patternMatch
) const
{
return csearchCompat(keyword, compat, recursive,patternMatch).ptr();
return csearchCompat(keyword, compat, recursive, patternMatch).ptr();
}
@ -120,14 +120,12 @@ const Foam::entry& Foam::dictionary::lookupEntryCompat
) const
{
const const_searcher
finder(csearchCompat(keyword, compat, recursive,patternMatch));
finder(csearchCompat(keyword, compat, recursive, patternMatch));
if (!finder.found())
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
@ -144,7 +142,8 @@ Foam::ITstream& Foam::dictionary::lookupCompat
bool patternMatch
) const
{
return lookupEntryCompat(keyword, compat, recursive,patternMatch).stream();
return
lookupEntryCompat(keyword, compat, recursive, patternMatch).stream();
}

View File

@ -27,18 +27,17 @@ License
#include "dictionaryEntry.H"
#include "stringOps.H"
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
namespace
{
// file-scope
//- Walk lists of patterns and regexps for an exact match
// or regular expression match
// Walk lists of patterns and regexps for an exact match
// or a regular expression match
template<class WcIterator, class ReIterator>
static bool findInPatterns
(
const bool patternMatch,
const word& keyword,
const Foam::word& keyword,
WcIterator& wcIter,
ReIterator& reIter
)
@ -61,7 +60,8 @@ namespace Foam
return false;
}
}
} // End anonymous namespace
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -73,7 +73,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped
bool patternMatch
) const
{
std::string::size_type scopePos = keyword.find('.');
auto scopePos = keyword.find('.');
if (scopePos == string::npos)
{
@ -101,10 +101,8 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped
}
else
{
FatalIOErrorInFunction
(
*this
) << "No parent of current dictionary when searching for "
FatalIOErrorInFunction(*this)
<< "No parent of current dictionary when searching for "
<< keyword.substr(1)
<< exit(FatalIOError);
@ -210,10 +208,8 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchSlashScoped
}
else
{
FatalIOErrorInFunction
(
*dictPtr
) << "No parent of current dictionary when searching for "
FatalIOErrorInFunction(*dictPtr)
<< "No parent of current dictionary when searching for "
<< keyword << " at " << cmpt
<< exit(FatalIOError);
break;
@ -424,10 +420,8 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDictPtr
}
else
{
FatalIOErrorInFunction
(
*dictPtr
) << "No parent for dictionary while searching "
FatalIOErrorInFunction(*dictPtr)
<< "No parent for dictionary while searching "
<< path
<< exit(FatalIOError);
@ -451,10 +445,8 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDictPtr
}
else
{
FatalIOErrorInFunction
(
*dictPtr
) << "Found entry '" << cmpt
FatalIOErrorInFunction(*dictPtr)
<< "Found entry '" << cmpt
<< "' but not a dictionary, while searching scoped"
<< nl
<< " " << path
@ -533,10 +525,8 @@ Foam::dictionary* Foam::dictionary::makeScopedDictPtr(const fileName& dictPath)
}
else
{
FatalIOErrorInFunction
(
*dictPtr
) << "No parent for dictionary while searching "
FatalIOErrorInFunction(*dictPtr)
<< "No parent for dictionary while searching "
<< path
<< exit(FatalIOError);
@ -561,10 +551,8 @@ Foam::dictionary* Foam::dictionary::makeScopedDictPtr(const fileName& dictPath)
}
else
{
FatalIOErrorInFunction
(
*dictPtr
) << "Cannot create sub-dictionary entry '" << cmptName
FatalIOErrorInFunction(*dictPtr)
<< "Cannot create sub-dictionary entry '" << cmptName
<< "' - a non-dictionary entry is in the way"
<< nl << "Encountered in scope" << nl
<< " " << path
@ -621,10 +609,8 @@ bool Foam::dictionary::remove(const word& keyword)
return true;
}
else
{
return false;
}
return false;
}
@ -651,10 +637,8 @@ bool Foam::dictionary::changeKeyword
if (iter()->keyword().isPattern())
{
FatalIOErrorInFunction
(
*this
) << "Old keyword "<< oldKeyword
FatalIOErrorInFunction(*this)
<< "Old keyword "<< oldKeyword
<< " is a pattern."
<< "Pattern replacement not yet implemented."
<< exit(FatalIOError);
@ -688,10 +672,8 @@ bool Foam::dictionary::changeKeyword
}
else
{
IOWarningInFunction
(
*this
) << "cannot rename keyword "<< oldKeyword
IOWarningInFunction(*this)
<< "cannot rename keyword "<< oldKeyword
<< " to existing keyword " << newKeyword
<< " in dictionary " << name() << endl;
return false;

View File

@ -57,31 +57,63 @@ T Foam::dictionary::get
bool patternMatch
) const
{
const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (!finder.found())
{
FatalIOErrorInFunction(*this)
<< "keyword " << keyword << " is undefined in dictionary "
<< name()
<< exit(FatalIOError);
}
T val;
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
read<T>(keyword, val, recursive, patternMatch);
return val;
}
template<class T>
T Foam::dictionary::getCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
T val;
readCompat<T>(keyword, compat, val, recursive, patternMatch);
return val;
}
template<class T>
bool Foam::dictionary::readCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
T& val,
bool recursive,
bool patternMatch,
bool mandatory
) const
{
const const_searcher
finder(csearchCompat(keyword, compat, recursive, patternMatch));
if (finder.found())
{
ITstream& is = finder.ptr()->stream();
is >> val;
excessTokens(keyword, is);
return true;
}
else if (mandatory)
{
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
return false;
}
// older name
template<class T>
T Foam::dictionary::lookupType
(
@ -112,21 +144,15 @@ T Foam::dictionary::lookupOrDefault
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
excessTokens(keyword, is);
return val;
}
if (writeOptionalEntries)
else if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " returning the default value '" << deflt << "'"
<< "Optional entry '" << keyword << "' not found,"
<< " using default value '" << deflt << "'"
<< endl;
}
@ -152,21 +178,15 @@ T Foam::dictionary::lookupOrAddDefault
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
excessTokens(keyword, is);
return val;
}
if (writeOptionalEntries)
else if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " adding and returning the default value '" << deflt << "'"
<< "Optional entry '" << keyword << "' not found,"
<< " adding default value '" << deflt << "'"
<< endl;
}
@ -175,6 +195,39 @@ T Foam::dictionary::lookupOrAddDefault
}
template<class T>
bool Foam::dictionary::read
(
const word& keyword,
T& val,
bool recursive,
bool patternMatch,
bool mandatory
) const
{
const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found())
{
ITstream& is = finder.ptr()->stream();
is >> val;
excessTokens(keyword, is);
return true;
}
else if (mandatory)
{
FatalIOErrorInFunction(*this)
<< "'" << keyword << "' not found in dictionary "
<< name()
<< exit(FatalIOError);
}
return false;
}
template<class T>
bool Foam::dictionary::readIfPresent
(
@ -184,32 +237,8 @@ bool Foam::dictionary::readIfPresent
bool patternMatch
) const
{
const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found())
{
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
return true;
}
if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " the default value '" << val << "' will be used."
<< endl;
}
return false;
// Read is non-mandatory
return read<T>(keyword, val, recursive, patternMatch, false);
}
@ -233,21 +262,15 @@ T Foam::dictionary::lookupOrDefaultCompat
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
excessTokens(keyword, is);
return val;
}
if (writeOptionalEntries)
else if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " returning the default value '" << deflt << "'"
<< "Optional entry '" << keyword << "' not found,"
<< " using default value '" << deflt << "'"
<< endl;
}
@ -265,33 +288,8 @@ bool Foam::dictionary::readIfPresentCompat
bool patternMatch
) const
{
const const_searcher
finder(csearchCompat(keyword, compat, recursive, patternMatch));
if (finder.found())
{
ITstream& is = finder.ptr()->stream();
is >> val;
if (!is.eof())
{
auto err = FatalIOErrorInFunction(*this);
excessTokens(err, keyword, is);
err << exit(FatalIOError);
}
return true;
}
if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " the default value '" << val << "' will be used."
<< endl;
}
return false;
// Read is non-mandatory
return readCompat<T>(keyword, compat, recursive, patternMatch, false);
}

View File

@ -139,15 +139,15 @@ void Foam::IOerror::SafeFatalIOError
else
{
std::cerr
<< std::endl
<< "--> FOAM FATAL IO ERROR:" << std::endl
<< nl
<< "--> FOAM FATAL IO ERROR:" << nl
<< msg
<< std::endl
<< nl
<< "file: " << ioStream.name()
<< " at line " << ioStream.lineNumber() << '.'
<< std::endl << std::endl
<< nl << nl
<< " From function " << functionName
<< std::endl
<< nl
<< " in file " << sourceFileName
<< " at line " << sourceFileLineNumber << '.'
<< std::endl;

View File

@ -30,7 +30,7 @@ License
void Foam::Function1Types::ramp::read(const dictionary& coeffs)
{
start_ = coeffs.lookupOrDefault<scalar>("start", 0);
duration_ = coeffs.lookupType<scalar>("duration");
duration_ = coeffs.get<scalar>("duration");
}