ENH: additional dictionary compatibility/migration methods

- when dictionary keywords change between versions, the programmer
  can use these compatibility methods to help with migration.

    * csearchCompat, foundCompat, lookupEntryPtrCompat, lookupEntryCompat,
      lookupCompat, lookupOrDefaultCompat, readIfPresentCompat, ...

  They behave like their similarly named base versions, but accept an
  additional list of older keyword names augmented by a version number.
  For example,

      dict.readIfPresentCompat
      (
          "key", {{"olderName", 1612}, {"veryOld", 240}},
          myscalar
      );

   where 1612=OpenFOAM-v1612, 240=OpenFOAM-v2.4.x, etc.
This commit is contained in:
Mark Olesen
2017-11-08 19:08:10 +01:00
parent 8d5f28bcc0
commit c7392f7fb0
5 changed files with 433 additions and 11 deletions

View File

@ -112,7 +112,8 @@ int main(int argc, char *argv[])
// overwrite existing // overwrite existing
{ {
entry* e = dict1.set(word("dict2"), 1000); // overwrite dict1.set("entry3", 1000); // overwrite
entry* e = dict1.set(word("dict3"), 1000); // overwrite
entryInfo(e); entryInfo(e);
} }
@ -124,10 +125,86 @@ int main(int argc, char *argv[])
entry* e = dict1.add(word("dict4"), tmpdict, true); // merge entry* e = dict1.add(word("dict4"), tmpdict, true); // merge
entryInfo(e); entryInfo(e);
if (e) if (e) Info<< nl << "=> " << *e << nl;
Info<< nl << "=> " << *e << nl;
tmpdict.clear();
tmpdict.add(word("other"), 2.718281);
dict1.add(word("dict1"), tmpdict, true); // merge
} }
Info<< nl << "dictionary" << nl << nl;
dict1.write(Info, false);
{
dict1.foundCompat
(
"newEntry", {{"entry1", 1612}, {"entry15", 1606}}
);
dict1.foundCompat
(
"newEntry", {{"entry15", 1612}, {"entry2", 1606}}
);
dict1.foundCompat
(
"newEntry", {{"entry3", 240}, {"entry2", 1606}}
);
// And some success
dict1.foundCompat
(
"entry4", {{"none", 240}, {"entry2", 1606}}
);
}
{
label lval = readLabel
(
dict1.lookupCompat
(
"entry400", {{"none", 240}, {"entry3", 1606}}
)
);
Info<< "int value: " << lval << nl;
}
// Could have different dictionary names and different entries names etc.
// Quite ugly!
{
scalar sval = readScalar
(
dict1.csearchCompat
(
"newdictName", {{"dict4", 1706}, {"dict1", 1606}}
)
.dict()
.lookupCompat
(
"newval", {{"something", 1606}, {"other", 1612}}
)
);
Info<< "scalar value: " << sval << nl;
sval = readScalar
(
dict1.csearchCompat
(
"newdictName", {{"dict1", 1606}, {"dict4", 1706}}
)
.dict()
.lookupCompat
(
"newval", {{"something", 1606}, {"other", 1612}}
)
);
Info<< "scalar value = " << sval << nl;
}
Info<< nl << "dictionary" << nl << nl; Info<< nl << "dictionary" << nl << nl;
dict1.write(Info, false); dict1.write(Info, false);

View File

@ -203,6 +203,7 @@ dictionary = db/dictionary
$(dictionary)/dictionary.C $(dictionary)/dictionary.C
$(dictionary)/dictionaryIO.C $(dictionary)/dictionaryIO.C
$(dictionary)/dictionarySearch.C $(dictionary)/dictionarySearch.C
$(dictionary)/dictionaryCompat.C
entry = $(dictionary)/entry entry = $(dictionary)/entry
$(entry)/entry.C $(entry)/entry.C

View File

@ -908,6 +908,127 @@ public:
dictionary* makeScopedDictPtr(const fileName& dictPath); dictionary* makeScopedDictPtr(const fileName& dictPath);
// Compatibility helpers
//- Search dictionary for given keyword and any compatibility names
// Default search: non-recursive with patterns.
//
// \param compat list of old compatibility keywords and the last
// OpenFOAM version for which they were used.
// Old version 1600=OpenFOAM-v3.0, 240=OpenFOAM-2.4.x,
// 170=OpenFOAM-1.7.x,...
//
// \param recursive search parent dictionaries
// \param patternMatch use regular expressions
const_searcher csearchCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive = false,
bool patternMatch = true
) const;
//- Search dictionary for given keyword and any compatibility names
// 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
bool foundCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive = false,
bool patternMatch = true
) const;
//- Find and return an entry pointer if present, or return a nullptr,
//- using any compatibility names it needed.
//
// \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
const entry* lookupEntryPtrCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const;
//- Find and return an entry if present otherwise error,
//- using any compatibility names it needed.
//
// \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
const entry& lookupEntryCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const;
//- Find and return an entry data stream,
//- using any compatibility names it needed.
// 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
ITstream& lookupCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive = false,
bool patternMatch = true
) const;
//- Find and return a T, or return the given default value
//- using any compatibility names it needed.
// 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 lookupOrDefaultCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
const T& deflt,
bool recursive = false,
bool patternMatch = true
) const;
//- Find an entry if present, and assign to T val
//- using any compatibility names it needed.
// 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 readIfPresentCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
T& val,
bool recursive = false,
bool patternMatch = true
) const;
// Member Operators // Member Operators
//- Find and return an entry data stream (identical to #lookup method). //- Find and return an entry data stream (identical to #lookup method).

View File

@ -0,0 +1,162 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "dictionary.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
static void warnAboutAge(const int oldVersion)
{
if (oldVersion < 1000)
{
// Emit warning
std::cerr
<< " This keyword is considered to be VERY old!\n"
<< std::endl;
}
#if (OPENFOAM_PLUS > 1600)
else if (OPENFOAM_PLUS > oldVersion)
{
const int months =
(
// YYMM -> months
(12 * (OPENFOAM_PLUS/100) + (OPENFOAM_PLUS % 100))
- (12 * (oldVersion/100) + (oldVersion % 100))
);
std::cerr
<< " This keyword is deemed to be " << months
<< " months old.\n"
<< std::endl;
}
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
const_searcher finder(csearch(keyword, recursive,patternMatch));
if (finder.found())
{
return finder;
}
for (const std::pair<const char*,int>& iter : compat)
{
finder = csearch(word::validate(iter.first), recursive,patternMatch);
if (finder.found())
{
// Emit warning
std::cerr
<< "--> FOAM IOWarning :" << nl
<< " Found [v" << iter.second << "] '"
<< iter.first << "' instead of '"
<< keyword.c_str() << "' in dictionary \""
<< name().c_str() << "\" "
<< nl
<< std::endl;
warnAboutAge(iter.second);
break;
}
}
return finder;
}
bool Foam::dictionary::foundCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
return csearchCompat(keyword, compat, recursive,patternMatch).found();
}
const Foam::entry* Foam::dictionary::lookupEntryPtrCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
return csearchCompat(keyword, compat, recursive,patternMatch).ptr();
}
const Foam::entry& Foam::dictionary::lookupEntryCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
const const_searcher
finder(csearchCompat(keyword, compat, recursive,patternMatch));
if (!finder.found())
{
FatalIOErrorInFunction
(
*this
) << "keyword " << keyword << " is undefined in dictionary "
<< name()
<< exit(FatalIOError);
}
return finder.ref();
}
Foam::ITstream& Foam::dictionary::lookupCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
bool recursive,
bool patternMatch
) const
{
return lookupEntryCompat(keyword, compat, recursive,patternMatch).stream();
}
// ************************************************************************* //

View File

@ -35,6 +35,20 @@ Foam::wordList Foam::dictionary::sortedToc(const Compare& comp) const
} }
template<class T>
Foam::entry* Foam::dictionary::add(const keyType& k, const T& v, bool overwrite)
{
return add(new primitiveEntry(k, v), overwrite);
}
template<class T>
Foam::entry* Foam::dictionary::set(const keyType& k, const T& v)
{
return set(new primitiveEntry(k, v));
}
template<class T> template<class T>
T Foam::dictionary::lookupType T Foam::dictionary::lookupType
( (
@ -43,7 +57,7 @@ T Foam::dictionary::lookupType
bool patternMatch bool patternMatch
) const ) const
{ {
auto finder = csearch(keyword, recursive, patternMatch); const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (!finder.found()) if (!finder.found())
{ {
@ -68,7 +82,7 @@ T Foam::dictionary::lookupOrDefault
bool patternMatch bool patternMatch
) const ) const
{ {
auto finder = csearch(keyword, recursive, patternMatch); const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found()) if (finder.found())
{ {
@ -96,7 +110,7 @@ T Foam::dictionary::lookupOrAddDefault
bool patternMatch bool patternMatch
) )
{ {
auto finder = csearch(keyword, recursive, patternMatch); const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found()) if (finder.found())
{ {
@ -125,7 +139,7 @@ bool Foam::dictionary::readIfPresent
bool patternMatch bool patternMatch
) const ) const
{ {
auto finder = csearch(keyword, recursive, patternMatch); const const_searcher finder(csearch(keyword, recursive, patternMatch));
if (finder.found()) if (finder.found())
{ {
@ -146,16 +160,63 @@ bool Foam::dictionary::readIfPresent
template<class T> template<class T>
Foam::entry* Foam::dictionary::add(const keyType& k, const T& v, bool overwrite) T Foam::dictionary::lookupOrDefaultCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
const T& deflt,
bool recursive,
bool patternMatch
) const
{ {
return add(new primitiveEntry(k, v), overwrite); const const_searcher
finder(csearchCompat(keyword, compat, recursive, patternMatch));
if (finder.found())
{
return pTraits<T>(finder.ptr()->stream());
}
if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " returning the default value '" << deflt << "'"
<< endl;
}
return deflt;
} }
template<class T> template<class T>
Foam::entry* Foam::dictionary::set(const keyType& k, const T& v) bool Foam::dictionary::readIfPresentCompat
(
const word& keyword,
std::initializer_list<std::pair<const char*,int>> compat,
T& val,
bool recursive,
bool patternMatch
) const
{ {
return set(new primitiveEntry(k, v)); const const_searcher
finder(csearchCompat(keyword, compat, recursive, patternMatch));
if (finder.found())
{
finder.ptr()->stream() >> val;
return true;
}
if (writeOptionalEntries)
{
IOInfoInFunction(*this)
<< "Optional entry '" << keyword << "' is not present,"
<< " the default value '" << val << "' will be used."
<< endl;
}
return false;
} }