ENH: consistency improvements for keyType and wordRe

- simplify compile/uncompile, reading, assignment

- implicit construct wordRe from keyType (was explicit) to simplify
  future API changes.

- make Foam::isspace consistent with std::isspace (C-locale)
  by including vertical tab and form feed

ENH: improve #ifeq float/label comparisons
This commit is contained in:
Mark Olesen 2021-04-09 11:53:59 +02:00 committed by Andrew Heather
parent 57c1fceabf
commit 96a1b86fb9
33 changed files with 759 additions and 665 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,7 +41,7 @@ using namespace Foam;
int main(int argc, char *argv[])
{
stringList strLst
stringList strings
{
"hello",
"heello",
@ -53,51 +53,57 @@ int main(int argc, char *argv[])
"okkey",
"okkkey",
};
labelList matches;
wordRes reLst(IStringStream("( okey \"[hy]e+.*\" )")());
wordRes matcher1(IStringStream("( okey \"[hy]e+.*\" )")());
Info<< "stringList " << strLst << nl;
Info<< "stringList " << strings << nl;
labelList matches = findStrings(regExp(".*ee.*"), strLst);
Info<< "matches found for regexp .*ee.* :" << nl << matches << nl;
forAll(matches, i)
{
Info<< " -> " << strLst[matches[i]] << nl;
keyType key(".*ee.*", keyType::REGEX);
matches = findMatchingStrings(regExp(key), strings);
Info<< "matches found for regexp " << key << " :" << nl
<< matches << nl;
for (const label idx : matches)
{
Info<< " -> " << strings[idx] << nl;
}
}
Info<< "Match found using ListOps = "
<< ListOps::found(strLst, regExp(".*ee.*")) << nl;
<< ListOps::found(strings, regExp(".*ee.*")) << nl;
Info<< "First index = "
<< ListOps::find(strLst, regExp(".*ee.*")) << nl;
<< ListOps::find(strings, regExp(".*ee.*")) << nl;
Info<< endl;
matches = findStrings(reLst, strLst);
matches = findMatchingStrings(matcher1, strings);
Info<< "matching " << flatOutput(reLst) << " => "
<< reLst.matching(strLst) << nl;
Info<< "matches found for " << flatOutput(reLst) << " => "
Info<< "matching " << flatOutput(matcher1) << " => "
<< matcher1.matching(strings) << nl;
Info<< "matches found for " << flatOutput(matcher1) << " => "
<< matches << nl;
forAll(matches, i)
for (const label idx : matches)
{
Info<< " -> " << strLst[matches[i]] << nl;
Info<< " -> " << strings[idx] << nl;
}
Info<< endl;
stringList subLst = subsetStrings(regExp(".*ee.*"), strLst);
stringList subLst = subsetStrings(regExp(".*ee.*"), strings);
Info<< "subset stringList: " << subLst << nl;
subLst = subsetStrings(reLst, strLst);
subLst = subsetStrings(matcher1, strings);
Info<< "subset stringList: " << subLst << nl;
inplaceSubsetStrings(reLst, strLst);
Info<< "subsetted stringList: " << strLst << nl;
inplaceSubsetStrings(matcher1, strings);
Info<< "subsetted stringList: " << strings << nl;
inplaceSubsetStrings(regExp(".*l.*"), strLst);
Info<< "subsetted stringList: " << strLst << nl;
inplaceSubsetStrings(regExp(".*l.*"), strings);
Info<< "subsetted stringList: " << strings << nl;
Info<< "\nEnd\n" << endl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,8 +38,12 @@ Description
using namespace Foam;
// Simple utility
template<class String>
void printSubStrings(const String& str, const SubStrings<String>& split)
template<class StringType>
void printSubStrings
(
const StringType& str,
const SubStrings<StringType>& split
)
{
Info<< "string {" << str.size() << " chars} = " << str << nl
<< split.size() << " elements {" << split.length() << " chars}"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,6 +32,7 @@ Description
#include "IOstreams.H"
#include "IOobject.H"
#include "IFstream.H"
#include "ITstream.H"
#include "List.H"
#include "Tuple2.H"
#include "keyType.H"
@ -51,11 +52,84 @@ word typeOf(wordRe::compOption retval)
}
Ostream& printInfo(const wordRe& wre)
{
if (wre.isPattern())
{
Info<< "wordRe(regex) ";
}
else
{
Info<< "wordRe(plain) ";
}
Info<< wre;
return Info;
}
// Could use something like this for reading wordRes
void exptl_reading(Istream& is, wordRes& list)
{
token tok(is);
bool ok = ((tok.isWord() || tok.isQuotedString()) && !tok.isCompound());
if (ok)
{
list.resize(1);
ok = list[0].assign(tok);
}
if (!ok)
{
if (tok.good())
{
is.putBack(tok);
}
list.readList(is);
}
}
bool testReadList_wordRes(const std::string& input)
{
ITstream is("input", input);
wordRes list;
exptl_reading(is, list);
const label nTrailing = is.nRemainingTokens();
Info<< "input:<<<<" << nl << input.c_str() << nl
<< ">>>> with " << nTrailing << " tokens remaining" << nl
<< "list: " << flatOutput(list) << nl;
return !nTrailing;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
if (true)
{
Info<< "Test input for wordRes" << nl << nl;
testReadList_wordRes
(
"("
"this \"x.*\" \"file[a-b]\" xvalues \"xv.*\""
")"
);
testReadList_wordRes
(
"\".*\""
);
Info<< nl << nl;
}
wordRe wre;
std::string s1("this .* file");
Foam::string s2("this .* file");
@ -64,13 +138,13 @@ int main(int argc, char *argv[])
keyType keyre("x.*", keyType::REGEX);
wordRes wordrelist
{
({
{"this", wordRe::LITERAL},
{"x.*", wordRe::REGEX},
{"file[a-b]", wordRe::REGEX},
{"xvalues", wordRe::LITERAL},
{"xv.*", wordRe::REGEX},
};
});
if (false)
{
@ -169,45 +243,45 @@ int main(int argc, char *argv[])
}
Info<< nl;
wordRe(s1, wordRe::DETECT).info(Info) << nl;
wordRe(s2).info(Info) << nl;
wordRe(s2, wordRe::DETECT).info(Info) << nl;
wordRe(s3, wordRe::REGEX).info(Info) << nl;
printInfo(wordRe(s1, wordRe::DETECT)) << nl;
printInfo(wordRe(s2)) << nl;
printInfo(wordRe(s2, wordRe::DETECT)) << nl;
printInfo(wordRe(s3, wordRe::REGEX)) << nl;
wre = "this .* file";
Info<<"substring: " << wre.substr(4) << nl;
wre.info(Info) << nl;
printInfo(wre) << nl;
wre = s1;
wre.info(Info) << nl;
printInfo(wre) << nl;
wre.uncompile();
wre.info(Info) << nl;
printInfo(wre) << nl;
wre = "something";
wre.info(Info) << " before" << nl;
printInfo(wre) << " before" << nl;
wre.uncompile();
wre.info(Info) << " uncompiled" << nl;
printInfo(wre) << " uncompiled" << nl;
wre.compile(wordRe::DETECT);
wre.info(Info) << " after DETECT" << nl;
printInfo(wre) << " after DETECT" << nl;
wre.compile(wordRe::ICASE);
wre.info(Info) << " after ICASE" << nl;
printInfo(wre) << " after ICASE" << nl;
wre.compile(wordRe::DETECT_ICASE);
wre.info(Info) << " after DETECT_ICASE" << nl;
printInfo(wre) << " after DETECT_ICASE" << nl;
wre = "something .* value";
wre.info(Info) << " before" << nl;
printInfo(wre) << " before" << nl;
wre.uncompile();
wre.info(Info) << " uncompiled" << nl;
printInfo(wre) << " uncompiled" << nl;
wre.compile(wordRe::DETECT);
wre.info(Info) << " after DETECT" << nl;
printInfo(wre) << " after DETECT" << nl;
wre.uncompile();
wre.info(Info) << " uncompiled" << nl;
printInfo(wre) << " uncompiled" << nl;
wre.compile();
wre.info(Info) << " re-compiled" << nl;
printInfo(wre) << " re-compiled" << nl;
wre.set("something .* value", wordRe::LITERAL);
wre.info(Info) << " set as LITERAL" << nl;
printInfo(wre) << " set as LITERAL" << nl;
IOobject::writeDivider(Info);
@ -220,7 +294,7 @@ int main(int argc, char *argv[])
const wordRe& wre = rawList[elemI].first();
const string& str = rawList[elemI].second();
wre.info(Info)
printInfo(wre)
<< " equals:" << (wre == str)
<< "(" << wre.match(str, true) << ")"
<< " match:" << wre.match(str)
@ -230,11 +304,10 @@ int main(int argc, char *argv[])
wordRe wre2;
wre2.set(wre, wordRe::ICASE);
wre2.info(Info)
printInfo(wre2)
<< " match:" << wre2.match(str)
<< " str=" << str
<< nl;
}
Info<< "\nEnd\n" << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenFOAM Foundation
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -205,6 +205,10 @@ bool Foam::functionEntries::ifeqEntry::equalToken
{
return equal(t1.floatToken(), t2.floatToken());
}
else if (t2.isLabel())
{
return t1.floatToken() == t2.labelToken();
}
else if (t2.isScalar())
{
return t1.scalarToken() == t2.scalarToken();
@ -216,6 +220,10 @@ bool Foam::functionEntries::ifeqEntry::equalToken
{
return equal(t1.doubleToken(), t2.doubleToken());
}
else if (t2.isLabel())
{
return t1.doubleToken() == t2.labelToken();
}
else if (t2.isScalar())
{
return t1.scalarToken() == t2.scalarToken();

View File

@ -61,15 +61,17 @@ Ostream& operator<<(Ostream& os, const char c);
//- Write a nul-terminated C-string
Ostream& operator<<(Ostream& os, const char* str);
//- Test for whitespace
inline bool isspace(char c)
//- Test for whitespace (C-locale)
inline bool isspace(char c) noexcept
{
return
(
c == ' '
|| c == '\n'
|| c == '\r'
|| c == '\t'
c == ' ' // (0x20) space (SPC)
|| c == '\t' // (0x09) horizontal tab (TAB)
|| c == '\n' // (0x0a) newline (LF)
|| c == '\v' // (0x0b) vertical tab (VT)
|| c == '\f' // (0x0c) feed (FF)
|| c == '\r' // (0x0d) carriage return (CR)
);
}

View File

@ -41,7 +41,6 @@ SourceFiles
#define Enum_H
#include "wordList.H"
#include <initializer_list>
#include <ostream>
#include <utility>

View File

@ -41,6 +41,7 @@ Description
#include "uLabel.H"
#include "Hasher.H"
#include "fileName.H"
#include "keyType.H"
#include "wordRe.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -464,12 +464,6 @@ Foam::fileName Foam::fileName::relative
}
bool Foam::fileName::hasExt(const wordRe& ending) const
{
return string::hasExt(ending);
}
Foam::wordList Foam::fileName::components(const char delim) const
{
const auto parsed = stringOps::split<string>(*this, delim);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -55,14 +55,13 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class fileName;
class token;
template<class T> class List;
template<class T> class UList;
typedef List<word> wordList;
class wordRe;
class fileName;
/*---------------------------------------------------------------------------*\
Class fileName Declaration
\*---------------------------------------------------------------------------*/
@ -100,7 +99,7 @@ public:
// Constructors
//- Construct null
//- Default construct
fileName() = default;
//- Copy construct
@ -142,6 +141,13 @@ public:
// Member Functions
//- Inherit all regular string assign() methods
using string::assign;
//- Assign from word or string token.
// \return false if the token was the incorrect type
bool assign(const token& tok);
//- Is this character valid for a fileName?
inline static bool valid(char c);
@ -322,17 +328,11 @@ public:
// or when the file name is empty or ended with a '/'.
inline fileName& ext(const word& ending);
//- Return true if it has an extension or simply ends with a '.'
inline bool hasExt() const;
//- Return true if the extension is the same as the given ending.
inline bool hasExt(const word& ending) const;
//- Return true if the extension matches the given ending.
bool hasExt(const wordRe& ending) const;
//- Various checks for extensions
using string::hasExt;
//- Remove extension, returning true if string changed.
inline bool removeExt();
using string::removeExt;
//- Return path components as wordList
@ -389,7 +389,7 @@ public:
inline fileName& operator=(const char* str);
// Other operators
// Other Operators
//- Append a path element with '/' separator.
// No '/' separator is added if this or the argument are empty.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -171,18 +171,6 @@ inline bool Foam::fileName::hasPath() const
}
inline bool Foam::fileName::hasExt() const
{
return string::hasExt();
}
inline bool Foam::fileName::hasExt(const word& ending) const
{
return string::hasExt(ending);
}
inline std::string Foam::fileName::path(const std::string& str)
{
const auto i = str.rfind('/');
@ -256,12 +244,6 @@ inline bool Foam::fileName::removePath()
}
inline bool Foam::fileName::removeExt()
{
return string::removeExt();
}
inline Foam::fileName& Foam::fileName::ext(const word& ending)
{
string::ext(ending);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,46 +29,60 @@ License
#include "fileName.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fileName::fileName(Istream& is)
:
string()
{
is >> *this;
}
Foam::Istream& Foam::operator>>(Istream& is, fileName& val)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fileName::assign(const token& tok)
{
token t(is);
if (!t.good())
{
FatalIOErrorInFunction(is)
<< "Bad token - could not get string"
<< exit(FatalIOError);
is.setBad();
return is;
}
if (t.isStringType())
if (tok.isWord())
{
// Also accept a plain word as a fileName
val = t.stringToken();
assign(tok.wordToken());
return true;
}
else
else if (tok.isQuotedString())
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected string, found "
<< t.info()
<< exit(FatalIOError);
assign(tok.stringToken());
stripInvalid(); // More stringent for fileName than string
return true;
}
return false;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, fileName& val)
{
token tok(is);
if (!val.assign(tok))
{
FatalIOErrorInFunction(is);
if (tok.good())
{
FatalIOError
<< "Wrong token type - expected string, found "
<< tok.info();
}
else
{
FatalIOError
<< "Bad token - could not get fileName";
}
FatalIOError << exit(FatalIOError);
is.setBad();
return is;
}
val.stripInvalid();
is.check(FUNCTION_NAME);
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,9 @@ License
#include "keyType.H"
#include "regExp.H"
#include "token.H"
#include "IOstreams.H"
#include <algorithm> // For swap
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -38,9 +40,6 @@ const Foam::keyType Foam::keyType::null;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::keyType::keyType(Istream& is)
:
word(),
type_(option::LITERAL)
{
is >> *this;
}
@ -48,6 +47,18 @@ Foam::keyType::keyType(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::keyType::swap(keyType& rhs)
{
if (this == &rhs)
{
return; // Self-swap is a no-op
}
word::swap(static_cast<word&>(rhs));
std::swap(type_, rhs.type_);
}
bool Foam::keyType::match(const std::string& text, bool literal) const
{
if (!literal && isPattern())
@ -59,37 +70,40 @@ bool Foam::keyType::match(const std::string& text, bool literal) const
}
bool Foam::keyType::assign(const token& tok)
{
if (tok.isWord())
{
// Assign from word - literal
assign(tok.wordToken());
uncompile();
return true;
}
else if (tok.isQuotedString())
{
// Assign from quoted string - regular expression
assign(tok.stringToken());
compile();
return true;
}
return false;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, keyType& val)
{
token t(is);
token tok(is);
if (!t.good())
if (val.assign(tok))
{
FatalIOErrorInFunction(is)
<< "Bad token - could not get a word/regex"
<< exit(FatalIOError);
is.setBad();
return is;
}
if (t.isWord())
{
val = t.wordToken();
val.setType(keyType::LITERAL);
}
else if (t.isString())
{
// Assign from string, treat as regular expression
val = t.stringToken();
val.setType(keyType::REGEX);
// Flag empty strings as an error
if (val.empty())
{
// Empty strings are an error
FatalIOErrorInFunction(is)
<< "Empty word/expression"
<< "Zero-length regex"
<< exit(FatalIOError);
is.setBad();
return is;
@ -97,10 +111,19 @@ Foam::Istream& Foam::operator>>(Istream& is, keyType& val)
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected word or string, found "
<< t.info()
<< exit(FatalIOError);
FatalIOErrorInFunction(is);
if (tok.good())
{
FatalIOError
<< "Wrong token type - expected word or string, found "
<< tok.info();
}
else
{
FatalIOError
<< "Bad token - could not get keyType";
}
FatalIOError << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,6 +36,7 @@ Description
SourceFiles
keyType.C
keyTypeI.H
\*---------------------------------------------------------------------------*/
@ -43,6 +44,7 @@ SourceFiles
#define keyType_H
#include "word.H"
#include "wordRe.H"
#include "stdFoam.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,8 +53,10 @@ namespace Foam
{
// Forward Declarations
class Istream;
class Ostream;
class keyType;
class token;
Istream& operator>>(Istream& is, keyType& val);
Ostream& operator<<(Ostream& os, const keyType& val);
/*---------------------------------------------------------------------------*\
Class keyType Declaration
@ -90,12 +94,6 @@ private:
option type_;
// Private Member Functions
//- No assignment where we cannot determine string/word type
void operator=(const std::string&) = delete;
public:
// Static Data Members
@ -106,69 +104,82 @@ public:
// Constructors
//- Construct null
//- Default construct, empty literal
inline keyType();
//- Copy construct, retaining type (literal or regex)
inline keyType(const keyType& s);
//- Copy construct
keyType(const keyType&) = default;
//- Copy construct from word, treat as literal.
inline keyType(const word& s);
//- Move construct
keyType(keyType&&) = default;
//- Copy construct from string, treat as regular expression.
inline keyType(const string& s);
//- Implicit copy construct from word, treat as LITERAL
inline keyType(const word& str);
//- Construct as copy of character array, treat as literal.
inline keyType(const char* s);
//- Implicit move construct from word, treat as LITERAL
inline keyType(word&& str);
//- Implicit copy construct from Foam::string, treat as REGEX
inline keyType(const string& str);
//- Implicit move construct from Foam::string, treat as REGEX
inline keyType(string&& str);
//- Copy construct from std::string with specified treatment
inline keyType(const std::string& s, option opt);
//- Move construct, retaining type (literal or regex)
inline keyType(keyType&& s);
//- Move construct from word, treat as literal.
inline keyType(word&& s);
//- Move construct from string, treat as regular expression.
inline keyType(string&& s);
inline keyType(const std::string& str, option opt);
//- Move construct from std::string with specified treatment
inline keyType(std::string&& s, option opt);
inline keyType(std::string&& str, option opt);
//- Construct from Istream
//- Implicit construct from character array,
//- with specified compile option (default is LITERAL)
inline keyType(const char* str, option opt = option::LITERAL);
//- Construct from Istream by reading a token
// Treat as regular expression if surrounded by quotation marks.
explicit keyType(Istream& is);
// Member Functions
//- Is this character valid for a keyType?
// This is largely identical with what word accepts, but also
// permit brace-brackets, which are valid for some regexs.
inline static bool valid(char c);
//- Test for valid keyType character?
// Like Foam::word, but with brace-brackets,
// which are valid for some regexs.
inline static bool valid(const char c);
// Access
//- The keyType is treated as literal, not as pattern.
inline bool isLiteral() const;
inline bool isLiteral() const noexcept;
//- The keyType is treated as a pattern, not as literal string.
inline bool isPattern() const;
inline bool isPattern() const noexcept;
// Infrastructure
//- Change the representation
//- Inherit all regular string assign() methods
using word::assign;
//- Assign from word or string token.
// Words are treated as literals, strings as regex
// \return false if the token was the incorrect type
bool assign(const token& tok);
//- Change the representation, optionally stripping invalid word
//- characters when changing to a literal
inline void setType(option opt, bool adjust = false);
//- Mark as regular expression
inline bool compile();
inline bool compile() noexcept;
//- Mark as literal, instead of a regular expression.
// Optionally strip invalid word characters.
inline void uncompile(bool adjust = false);
//- Mark as literal string
inline void uncompile() noexcept;
//- Mark as literal string, optionally strip invalid word
//- characters when changing to a literal
inline void uncompile(bool adjust);
// Editing
@ -177,7 +188,7 @@ public:
inline void clear();
//- Swap contents. Self-swapping is a no-op.
inline void swap(keyType& s);
void swap(keyType& rhs);
// Matching/Searching
@ -193,23 +204,25 @@ public:
// Allows use as a predicate.
inline bool operator()(const std::string& text) const;
//- No assignment where type could be indeterminate
void operator=(const std::string&) = delete;
//- Copy assignment, retaining type (literal or regex)
// Self-assignment is a no-op.
inline void operator=(const keyType& s);
inline void operator=(const keyType& str);
//- Move assignment, retaining type (literal or regex)
// Self-assignment is a no-op.
inline void operator=(keyType&& s);
inline void operator=(keyType&& str);
//- Assign as word, treat as literal
inline void operator=(const word& s);
//- Assign from word, treat as literal
inline void operator=(const word& str);
//- Assign from Foam::string, treat as regular expression
inline void operator=(const string& s);
inline void operator=(const string& str);
//- Assign as word, treat as literal
inline void operator=(const char* s);
//- Assign from character array, treat as literal
inline void operator=(const char* str);
// Housekeeping

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,20 +26,12 @@ License
\*---------------------------------------------------------------------------*/
#include <algorithm>
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
inline bool Foam::keyType::valid(char c)
inline bool Foam::keyType::valid(const char c)
{
return
(
!isspace(c)
&& c != '"' // string quote
&& c != '\'' // string quote
&& c != '/' // path separator
&& c != ';' // end statement
);
// Also accept '{' and '}' (for regex grouping?)
return (word::valid(c) || c == '{' || c == '}');
}
@ -52,80 +44,64 @@ inline Foam::keyType::keyType()
{}
inline Foam::keyType::keyType(const keyType& s)
inline Foam::keyType::keyType(const word& str)
:
word(s, false),
type_(s.type_)
{}
inline Foam::keyType::keyType(const word& s)
:
word(s, false),
word(str),
type_(option::LITERAL)
{}
inline Foam::keyType::keyType(const string& s)
inline Foam::keyType::keyType(word&& str)
:
word(s, false),
word(std::move(str)),
type_(option::LITERAL)
{}
inline Foam::keyType::keyType(const string& str)
:
word(str, false), // No stripping
type_(option::REGEX)
{}
inline Foam::keyType::keyType(const char* s)
inline Foam::keyType::keyType(string&& str)
:
word(s, false),
type_(option::LITERAL)
word(std::move(str), false), // No stripping
type_(option::REGEX)
{}
inline Foam::keyType::keyType(const std::string& s, option opt)
inline Foam::keyType::keyType(const std::string& str, option opt)
:
word(s, false),
word(str, false), // No stripping
type_(option(opt & 0x0F))
{}
inline Foam::keyType::keyType(keyType&& s)
inline Foam::keyType::keyType(std::string&& str, option opt)
:
word(std::move(static_cast<word&>(s)), false),
type_(s.type_)
{
s.type_ = option::LITERAL;
}
inline Foam::keyType::keyType(word&& s)
:
word(std::move(s), false),
type_(option::LITERAL)
word(std::move(str), false), // No stripping
type_(option(opt & 0x0F))
{}
inline Foam::keyType::keyType(string&& s)
inline Foam::keyType::keyType(const char* str, option opt)
:
word(std::move(s), false),
type_(option::REGEX)
{}
inline Foam::keyType::keyType(std::string&& s, option opt)
:
word(std::move(s), false),
word(str, false), // No stripping
type_(option(opt & 0x0F))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::keyType::isLiteral() const
inline bool Foam::keyType::isLiteral() const noexcept
{
return (type_ != option::REGEX);
return !(type_ & option::REGEX);
}
inline bool Foam::keyType::isPattern() const
inline bool Foam::keyType::isPattern() const noexcept
{
return (type_ & option::REGEX);
}
@ -138,7 +114,7 @@ inline void Foam::keyType::setType(option opt, bool adjust)
if (type_ != opt)
{
// Only strip when debug is active (potentially costly operation)
if (isPattern() && adjust && word::debug)
if (adjust && isPattern() && word::debug)
{
string::stripInvalid<word>(*this);
}
@ -148,16 +124,28 @@ inline void Foam::keyType::setType(option opt, bool adjust)
}
inline bool Foam::keyType::compile()
inline bool Foam::keyType::compile() noexcept
{
type_ = option::REGEX;
return true;
}
inline void Foam::keyType::uncompile() noexcept
{
type_ = option::LITERAL;
}
inline void Foam::keyType::uncompile(bool adjust)
{
setType(option::LITERAL, adjust);
// Only strip when debug is active (potentially costly operation)
if (adjust && isPattern() && word::debug)
{
string::stripInvalid<word>(*this);
}
type_ = option::LITERAL;
}
@ -168,18 +156,6 @@ inline void Foam::keyType::clear()
}
inline void Foam::keyType::swap(keyType& s)
{
if (this == &s)
{
return; // Self-swap is a no-op
}
word::swap(static_cast<word&>(s));
std::swap(type_, s.type_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::keyType::operator()(const std::string& text) const
@ -188,49 +164,49 @@ inline bool Foam::keyType::operator()(const std::string& text) const
}
inline void Foam::keyType::operator=(const keyType& s)
inline void Foam::keyType::operator=(const keyType& str)
{
if (this == &s)
if (this == &str)
{
return; // Self-assignment is a no-op
}
assign(s); // Bypasses char checking
type_ = s.type_;
assign(str); // Bypasses char checking
type_ = str.type_;
}
inline void Foam::keyType::operator=(keyType&& s)
inline void Foam::keyType::operator=(keyType&& str)
{
if (this == &s)
if (this == &str)
{
return; // Self-assignment is a no-op
}
clear();
swap(s);
swap(str);
}
inline void Foam::keyType::operator=(const word& s)
inline void Foam::keyType::operator=(const char* str)
{
assign(s); // Bypasses char checking
assign(str); // Bypasses char checking
type_ = option::LITERAL;
}
inline void Foam::keyType::operator=(const string& s)
inline void Foam::keyType::operator=(const word& str)
{
assign(s); // Bypasses char checking
assign(str); // Bypasses char checking
type_ = option::LITERAL;
}
inline void Foam::keyType::operator=(const string& str)
{
assign(str); // Bypasses char checking
type_ = option::REGEX;
}
inline void Foam::keyType::operator=(const char* s)
{
assign(s); // Bypasses char checking
type_ = option::LITERAL;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,7 +61,7 @@ namespace Foam
{
// Forward Declarations
template<class String> class SubStrings;
template<class StringType> class SubStrings;
/*---------------------------------------------------------------------------*\
Class CStringList Declaration
@ -111,7 +111,7 @@ public:
// Constructors
//- Construct empty, adding content later (via reset).
//- Default construct, adding content later (via reset).
inline CStringList();
//- Copy construct from a list of strings
@ -190,7 +190,7 @@ public:
static inline List<StringType> asList(const char * const argv[]);
// Member operators
// Member Operators
//- Return element at the given index. No bounds checking.
inline const char* operator[](int i) const;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,7 +35,7 @@ Description
#ifndef SubStrings_H
#define SubStrings_H
#include <regex>
#include <regex> // For std::sub_match
#include <string>
#include <vector>
@ -48,21 +48,22 @@ namespace Foam
Class SubStrings Declaration
\*---------------------------------------------------------------------------*/
template<class String>
template<class StringType>
class SubStrings
:
public std::vector<std::sub_match<typename String::const_iterator>>
public std::vector<std::sub_match<typename StringType::const_iterator>>
{
public:
// Typedefs
// Types
//- The element type
using value_type =
typename std::sub_match<typename String::const_iterator>;
typename std::sub_match<typename StringType::const_iterator>;
//- The const_iterator for the underlying string type
using string_iterator = typename String::const_iterator;
using string_iterator =
typename StringType::const_iterator;
// Constructors
@ -87,12 +88,11 @@ public:
return len;
}
//- Append sub-string defined by begin/end iterators
void append
(
const typename String::const_iterator& b,
const typename String::const_iterator& e
const typename StringType::const_iterator& b,
const typename StringType::const_iterator& e
)
{
value_type range;
@ -103,7 +103,6 @@ public:
this->push_back(range);
}
//- Const reference to the first element,
//- for consistency with other OpenFOAM containers
auto first() const -> decltype(this->front())
@ -111,7 +110,6 @@ public:
return this->front();
}
//- Const reference to the last element,
//- for consistency with other OpenFOAM containers
auto last() const -> decltype(this->back())
@ -119,9 +117,8 @@ public:
return this->back();
}
//- Get element pos, converted to a string type.
String str(size_t pos) const
//- Get element at pos, converted to a string type.
StringType str(size_t pos) const
{
return (*this)[pos].str();
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -78,34 +78,21 @@ bool Foam::string::ext(const word& ending)
}
bool Foam::string::hasExt(const word& ending) const
{
auto i = find_ext();
if (i == npos)
{
return false;
}
++i; // Compare *after* the dot
return
(
// Lengths must match
((size() - i) == ending.size())
&& !compare(i, npos, ending)
);
}
bool Foam::string::hasExt(const wordRe& ending) const
{
if (ending.isLiteral() || ending.empty())
{
return hasExt(static_cast<const std::string&>(ending));
}
const auto i = find_ext();
if (i == npos)
{
return false;
}
const std::string end = substr(i+1); // Compare *after* the dot
return ending.match(end);
// Regex match - compare *after* the dot
return ending.match(substr(i+1));
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -122,7 +122,10 @@ protected:
inline bool hasExt() const;
//- Return true if the extension is the same as the given ending.
bool hasExt(const word& ending) const;
inline bool hasExt(const char* ending) const;
//- Return true if the extension is the same as the given ending.
inline bool hasExt(const std::string& ending) const;
//- Return true if the extension matches the given ending.
bool hasExt(const wordRe& ending) const;
@ -161,7 +164,7 @@ public:
// Constructors
//- Construct null
//- Default construct
string() = default;
//- Copy construct from std::string
@ -189,16 +192,16 @@ public:
// Static Member Functions
//- Does the string contain valid characters only?
template<class String>
template<class StringType>
static inline bool valid(const std::string& str);
//- Strip invalid characters from the given string
template<class String>
template<class StringType>
static inline bool stripInvalid(std::string& str);
//- Return a valid String from the given string
template<class String>
static inline String validate(const std::string& str);
template<class StringType>
static inline StringType validate(const std::string& str);
// Member Functions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -59,6 +59,26 @@ inline bool Foam::string::hasExt() const
}
inline bool Foam::string::hasExt(const char* ending) const
{
return (ending && string::hasExt(std::string(ending)));
}
inline bool Foam::string::hasExt(const std::string& ending) const
{
const auto len = ending.size();
auto i = find_ext();
if (i == npos || !len)
{
return false;
}
++i; // Compare *after* the dot
return ((size() - i) == len) && !compare(i, npos, ending);
}
inline bool Foam::string::removePath()
{
const auto i = rfind('/');
@ -128,12 +148,12 @@ inline Foam::string::string(const size_type len, const char c)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class String>
template<class StringType>
inline bool Foam::string::valid(const std::string& str)
{
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
if (!String::valid(*iter))
if (!StringType::valid(*iter))
{
return false;
}
@ -143,10 +163,10 @@ inline bool Foam::string::valid(const std::string& str)
}
template<class String>
template<class StringType>
inline bool Foam::string::stripInvalid(std::string& str)
{
if (!valid<String>(str))
if (!string::valid<StringType>(str))
{
size_type nChar = 0;
iterator outIter = str.begin();
@ -155,7 +175,7 @@ inline bool Foam::string::stripInvalid(std::string& str)
{
const char c = *iter;
if (String::valid(c))
if (StringType::valid(c))
{
*outIter = c;
++outIter;
@ -172,17 +192,17 @@ inline bool Foam::string::stripInvalid(std::string& str)
}
template<class String>
inline String Foam::string::validate(const std::string& str)
template<class StringType>
inline StringType Foam::string::validate(const std::string& str)
{
String out;
StringType out;
out.resize(str.size());
size_type len = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
const char c = *iter;
if (String::valid(c))
if (StringType::valid(c))
{
out[len] = c;
++len;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "string.H"
#include "token.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -41,27 +42,27 @@ Foam::string::string(Istream& is)
Foam::Istream& Foam::operator>>(Istream& is, string& val)
{
token t(is);
token tok(is);
if (!t.good())
if (tok.isString())
{
FatalIOErrorInFunction(is)
<< "Bad token - could not get string"
<< exit(FatalIOError);
is.setBad();
return is;
}
if (t.isString())
{
val = t.stringToken();
val = tok.stringToken();
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected string, found "
<< t.info()
<< exit(FatalIOError);
FatalIOErrorInFunction(is);
if (tok.good())
{
FatalIOError
<< "Wrong token type - expected string, found "
<< tok.info();
}
else
{
FatalIOError
<< "Bad token - could not get string";
}
FatalIOError << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -112,7 +112,7 @@ Foam::word Foam::word::validate
Foam::word Foam::word::lessExt() const
{
const size_type i = find_ext();
const auto i = find_ext();
if (i == npos)
{
@ -136,18 +136,6 @@ Foam::word& Foam::word::ext(const word& ending)
}
bool Foam::word::hasExt(const word& ending) const
{
return string::hasExt(ending);
}
bool Foam::word::hasExt(const wordRe& ending) const
{
return string::hasExt(ending);
}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
Foam::word Foam::operator&(const word& a, const word& b)

View File

@ -50,11 +50,10 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class word;
Istream& operator>>(Istream& is, word& w);
Ostream& operator<<(Ostream& os, const word& w);
Istream& operator>>(Istream& is, word& val);
Ostream& operator<<(Ostream& os, const word& val);
/*---------------------------------------------------------------------------*\
Class word Declaration
@ -80,7 +79,7 @@ public:
// Constructors
//- Construct null
//- Default construct
word() = default;
//- Copy construct
@ -169,17 +168,11 @@ public:
// or when the file name is empty or ended with a '/'.
word& ext(const word& ending);
//- Return true if it has an extension or simply ends with a '.'
inline bool hasExt() const;
//- Return true if the extension is the same as the given ending.
bool hasExt(const word& ending) const;
//- Return true if the extension matches the given ending.
bool hasExt(const wordRe& ending) const;
//- Various checks for extensions
using string::hasExt;
//- Remove extension, returning true if string changed.
inline bool removeExt();
using string::removeExt;
// Member Operators

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,7 +26,6 @@ License
\*---------------------------------------------------------------------------*/
#include <cctype>
#include <iostream> // For std::cerr
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -57,6 +56,21 @@ inline Foam::word Foam::word::printf
}
inline bool Foam::word::valid(char c)
{
return
(
!isspace(c)
&& c != '"' // string quote
&& c != '\'' // string quote
&& c != '/' // path separator
&& c != ';' // end statement
&& c != '{' // beg block (eg, subdict)
&& c != '}' // end block (eg, subdict)
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::word::word(const string& s, bool doStrip)
@ -127,21 +141,6 @@ inline Foam::word::word(const char* s, size_type len, bool doStrip)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::word::valid(char c)
{
return
(
!isspace(c)
&& c != '"' // string quote
&& c != '\'' // string quote
&& c != '/' // path separator
&& c != ';' // end statement
&& c != '{' // beg subdict
&& c != '}' // end subdict
);
}
inline void Foam::word::stripInvalid()
{
// Only strip when debug is active (potentially costly operation)
@ -162,18 +161,6 @@ inline void Foam::word::stripInvalid()
}
inline bool Foam::word::hasExt() const
{
return string::hasExt();
}
inline bool Foam::word::removeExt()
{
return string::removeExt();
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline Foam::word& Foam::word::operator=(const word& s)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,58 +27,59 @@ License
\*---------------------------------------------------------------------------*/
#include "word.H"
#include "token.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::word::word(Istream& is)
:
string()
{
is >> *this;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, word& val)
{
token t(is);
token tok(is);
if (!t.good())
if (tok.isWord())
{
FatalIOErrorInFunction(is)
<< "Bad token - could not get word"
<< exit(FatalIOError);
is.setBad();
return is;
val = tok.wordToken();
}
if (t.isWord())
{
val = t.wordToken();
}
else if (t.isString())
else if (tok.isQuotedString())
{
// Try a bit harder and convert string to word
val = t.stringToken();
val = tok.stringToken();
const auto oldLen = val.length();
string::stripInvalid<word>(val);
// Flag empty strings and bad chars as an error
if (val.empty() || val.size() != t.stringToken().size())
if (val.empty() || val.length() != oldLen)
{
FatalIOErrorInFunction(is)
<< "Empty word or non-word characters "
<< t.info()
<< exit(FatalIOError);
<< tok.info() << exit(FatalIOError);
is.setBad();
return is;
}
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected word, found "
<< t.info()
<< exit(FatalIOError);
FatalIOErrorInFunction(is);
if (tok.good())
{
FatalIOError
<< "Wrong token type - expected word, found "
<< tok.info();
}
else
{
FatalIOError
<< "Bad token - could not get word";
}
FatalIOError << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,8 +27,9 @@ License
\*---------------------------------------------------------------------------*/
#include "wordRe.H"
#include "keyType.H"
#include "token.H"
#include "IOstreams.H"
#include "InfoProxy.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -37,59 +38,75 @@ const Foam::wordRe Foam::wordRe::null;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::wordRe::wordRe(Istream& is)
Foam::wordRe::wordRe(const keyType& str)
:
word(),
re_(nullptr)
word(str, false) // No stripping
{
if (str.isPattern())
{
compile();
}
}
Foam::wordRe::wordRe(Istream& is)
{
is >> *this;
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::wordRe::info(Ostream& os) const
bool Foam::wordRe::assign(const token& tok)
{
if (isPattern())
if (tok.isWord())
{
os << "wordRe(regex) " << *this;
// Assign from word - literal
assign(tok.wordToken());
uncompile();
return true;
}
else
else if (tok.isQuotedString())
{
os << "wordRe(plain) \"" << *this << '"';
// Assign from quoted string - auto-detect regex
assign(tok.stringToken());
compile(wordRe::DETECT);
return true;
}
return os;
return false;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::wordRe::operator=(const keyType& str)
{
assign(str);
if (str.isPattern())
{
compile();
}
else
{
uncompile();
}
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, wordRe& val)
{
token t(is);
token tok(is);
if (!t.good())
if (val.assign(tok))
{
FatalIOErrorInFunction(is)
<< "Bad token - could not get wordRe"
<< exit(FatalIOError);
is.setBad();
return is;
}
if (t.isWord())
{
val = t.wordToken();
}
else if (t.isString())
{
// Auto-detects regex
val = t.stringToken();
// Flag empty strings as an error
if (val.empty())
{
// Empty strings are an error
FatalIOErrorInFunction(is)
<< "Empty word/expression"
<< "Zero-length regex"
<< exit(FatalIOError);
is.setBad();
return is;
@ -97,10 +114,19 @@ Foam::Istream& Foam::operator>>(Istream& is, wordRe& val)
}
else
{
FatalIOErrorInFunction(is)
<< "Wrong token type - expected word or string, found "
<< t.info()
<< exit(FatalIOError);
FatalIOErrorInFunction(is);
if (tok.good())
{
FatalIOError
<< "Wrong token type - expected word or string, found "
<< tok.info();
}
else
{
FatalIOError
<< "Bad token - could not get wordRe";
}
FatalIOError << exit(FatalIOError);
is.setBad();
return is;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,10 +42,11 @@ Description
Note
If the string contents are changed - eg, by the operator+=() or by
string::replace(), etc - it will be necessary to use compile() to
synchronize the regular expression.
string::replace(), etc - it will be necessary to use compile()
or uncompile() to synchronize the regular expression.
SourceFiles
wordReI.H
wordRe.C
\*---------------------------------------------------------------------------*/
@ -55,7 +56,7 @@ SourceFiles
#include "word.H"
#include "regExp.H"
#include "keyType.H"
#include "stdFoam.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -63,8 +64,11 @@ namespace Foam
{
// Forward Declarations
class Istream;
class Ostream;
class keyType;
class token;
class wordRe;
Istream& operator>>(Istream& is, wordRe& val);
Ostream& operator<<(Ostream& os, const wordRe& val);
/*---------------------------------------------------------------------------*\
Class wordRe Declaration
@ -99,7 +103,7 @@ public:
ICASE = 2, //!< Ignore case in regular expression
NOCASE = 2, //!< \deprecated(2018-04) Alias for ICASE
DETECT = 4, //!< Detect if the string contains meta-characters
UNKNOWN = 4, //!< Unknown content.
UNKNOWN = 4, //!< Unknown content (for return value).
REGEX_ICASE = (REGEX|ICASE), //!< Combined REGEX and ICASE
DETECT_ICASE = (DETECT|ICASE), //!< Combined DETECT and ICASE
};
@ -107,7 +111,7 @@ public:
// Constructors
//- Construct null
//- Default construct, empty literal
inline wordRe();
//- Copy construct
@ -116,69 +120,75 @@ public:
//- Move construct
inline wordRe(wordRe&& str);
//- Construct from keyType, using its compile information
inline explicit wordRe(const keyType& str);
//- Implicit copy construct from word, as LITERAL
inline wordRe(const word& str);
//- Copy from character array, treat as a literal
inline explicit wordRe(const char* str);
//- Implicit move construct from word, as LITERAL
inline wordRe(word&& str);
//- Copy from std::string, treat as a literal
inline explicit wordRe(const std::string& str);
//- Implicit copy construct from other string-types,
//- with specified compile option (default is LITERAL)
inline wordRe
(
const std::string& str,
const compOption opt = compOption::LITERAL
);
//- Copy from string, treat as a literal
inline explicit wordRe(const string& str);
//- Implicit construct from character array,
//- with specified compile option (default is LITERAL)
inline wordRe
(
const char* str,
const compOption opt = compOption::LITERAL
);
//- Copy from word, treat as a literal
inline explicit wordRe(const word& str);
//- Implicit copy construct from keyType, using its compile type
wordRe(const keyType& str);
//- Copy from keyType, use specified compile option
inline wordRe(const keyType& str, const compOption opt);
//- Copy from character array, use specified compile option
inline wordRe(const char* str, const compOption opt);
//- Copy from std::string, use specified compile option
inline wordRe(const std::string& str, const compOption opt);
//- Copy from string, use specified compile option
inline wordRe(const string& str, const compOption opt);
//- Copy from word, use specified compile option
inline wordRe(const word& str, const compOption opt);
//- Construct from Istream
// Words are treated as literals, strings with an auto-test
//- Construct from Istream by reading a token
// Words are treated as literals, strings with an auto-detect
explicit wordRe(Istream& is);
// Member Functions
//- Is this character valid for a wordRe?
// This is largely identical with what word accepts, but also
// permit brace-brackets, which are valid for some regexs.
inline static bool valid(char c);
//- Test for valid wordRe character?
// Like Foam::word, but with brace-brackets,
// which are valid for some regexs.
inline static bool valid(const char c);
// Access
//- The wordRe is treated as literal string, not as pattern.
inline bool isLiteral() const;
inline bool isLiteral() const noexcept;
//- The wordRe is treated as a pattern, not as literal string.
inline bool isPattern() const;
inline bool isPattern() const noexcept;
// Infrastructure
//- Compile the regular expression
//- Inherit all regular string assign() methods
using word::assign;
//- Assign from word or string token.
// Words are treated as literals, strings with an auto-detect
// \return false if the token was the incorrect type
bool assign(const token& tok);
//- Compile as regular expression
inline bool compile();
//- Mark as literal string, remove any regular expression
inline void uncompile();
//- Possibly compile the regular expression, with greater control
inline bool compile(const compOption opt);
//- Make wordRe a literal again, instead of a regular expression.
// Optionally strip invalid word characters.
inline void uncompile(bool adjust = false);
//- Mark as literal string, optionally stripping invalid word
//- characters when changing to a literal
inline void uncompile(bool adjust);
// Editing
@ -203,12 +213,6 @@ public:
inline bool match(const std::string& text, bool literal=false) const;
// Miscellaneous
//- Output some basic info
Ostream& info(Ostream& os) const;
// Member Operators
//- Perform smart match on text, as per match()
@ -225,7 +229,7 @@ public:
//- Copy keyType and its type (literal or regex)
// Always case sensitive
inline void operator=(const keyType& str);
void operator=(const keyType& str);
//- Copy string, auto-test for regular expression
// Always case sensitive

View File

@ -28,9 +28,10 @@ License
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
inline bool Foam::wordRe::valid(char c)
inline bool Foam::wordRe::valid(const char c)
{
return keyType::valid(c);
// Also accept '{' and '}' (for regex grouping?)
return (word::valid(c) || c == '{' || c == '}');
}
@ -45,8 +46,7 @@ inline Foam::wordRe::wordRe()
inline Foam::wordRe::wordRe(const wordRe& str)
:
word(str, false),
re_()
word(static_cast<const word&>(str))
{
if (str.isPattern())
{
@ -62,52 +62,23 @@ inline Foam::wordRe::wordRe(wordRe&& str)
{}
inline Foam::wordRe::wordRe(const keyType& str)
:
word(str, false),
re_()
{
if (str.isPattern())
{
compile();
}
}
inline Foam::wordRe::wordRe(const char* str)
:
word(str, false),
re_()
{}
inline Foam::wordRe::wordRe(const std::string& str)
:
word(str, false),
re_()
{}
inline Foam::wordRe::wordRe(const string& str)
:
word(str, false),
re_()
{}
inline Foam::wordRe::wordRe(const word& str)
:
word(str, false),
re_()
word(str)
{}
inline Foam::wordRe::wordRe(const keyType& str, const compOption opt)
inline Foam::wordRe::wordRe(word&& str)
:
word(str, false),
re_()
word(std::move(str))
{}
inline Foam::wordRe::wordRe(const std::string& str, const compOption opt)
:
word(str, false) // No stripping
{
if (str.isPattern())
if (opt != wordRe::LITERAL)
{
compile(opt);
}
@ -116,45 +87,24 @@ inline Foam::wordRe::wordRe(const keyType& str, const compOption opt)
inline Foam::wordRe::wordRe(const char* str, const compOption opt)
:
wordRe(str)
word(str, false) // No stripping
{
compile(opt);
}
inline Foam::wordRe::wordRe(const std::string& str, const compOption opt)
:
wordRe(str)
{
compile(opt);
}
inline Foam::wordRe::wordRe(const string& str, const compOption opt)
:
wordRe(str)
{
compile(opt);
}
inline Foam::wordRe::wordRe(const word& str, const compOption opt)
:
wordRe(str)
{
compile(opt);
if (opt != wordRe::LITERAL)
{
compile(opt);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::wordRe::isLiteral() const
inline bool Foam::wordRe::isLiteral() const noexcept
{
return !re_.exists();
}
inline bool Foam::wordRe::isPattern() const
inline bool Foam::wordRe::isPattern() const noexcept
{
return re_.exists();
}
@ -162,7 +112,7 @@ inline bool Foam::wordRe::isPattern() const
inline bool Foam::wordRe::compile(const compOption opt)
{
if (opt)
if (opt != wordRe::LITERAL)
{
bool comp = false;
@ -197,13 +147,20 @@ inline bool Foam::wordRe::compile()
}
inline void Foam::wordRe::uncompile()
{
re_.clear();
}
inline void Foam::wordRe::uncompile(bool adjust)
{
// Only strip when debug is active (potentially costly operation)
if (re_.clear() && adjust && word::debug)
if (adjust && isPattern() && word::debug)
{
string::stripInvalid<word>(*this);
}
re_.clear();
}
@ -285,20 +242,6 @@ inline void Foam::wordRe::operator=(const word& str)
}
inline void Foam::wordRe::operator=(const keyType& str)
{
assign(str);
if (str.isPattern())
{
compile();
}
else
{
re_.clear();
}
}
inline void Foam::wordRe::operator=(const string& str)
{
assign(str);

View File

@ -56,21 +56,22 @@ class wordRes
// Private Methods
//- Smart match as literal or regex, stopping on the first match.
inline static bool found_match
// \return index of first match, -1 if not found
inline static label first_match
(
const UList<wordRe>& patterns,
const UList<wordRe>& selectors,
const std::string& text,
bool literal=false
const bool literal=false
);
//- Smart match across entire list, returning the match type.
//- Smart match across entire list, returning the best match type.
// Stops on the first literal match, or continues to examine
// if a regex match occurs.
// \return wordRe::LITERAL, wordRe::REGEX on match and
// wordRe::UNKNOWN otherwise.
inline static wordRe::compOption found_matched
(
const UList<wordRe>& patterns,
const UList<wordRe>& selectors,
const std::string& text
);
@ -84,17 +85,14 @@ public:
{
const UList<wordRe>& values;
matcher(const UList<wordRe>& list)
matcher(const UList<wordRe>& selectors)
:
values(list)
values(selectors)
{}
//- Return true if string matches ANY of the regular expressions
//- True if text matches ANY of the entries.
// Allows use as a predicate.
bool operator()(const std::string& text) const
{
return found_match(values, text);
}
inline bool operator()(const std::string& text) const;
};
@ -104,7 +102,7 @@ public:
inline static const wordRes& null();
//- Return a wordRes with duplicate entries filtered out.
// No distinction made between literals or regular expressions.
// No distinction made between literals and regular expressions.
static wordRes uniq(const UList<wordRe>& input);
@ -121,7 +119,7 @@ public:
// Member Functions
//- Filter out duplicate entries (inplace).
// No distinction made between literals or regular expressions.
// No distinction made between literals and regular expressions.
void uniq();
//- Smart match as literal or regex, stopping on the first match.
@ -133,16 +131,16 @@ public:
//- Smart match in the list of matchers, returning the match type.
// It stops if there is a literal match, or continues to examine
// other regexs.
// \return LITERAL if a lteral match was found, REGEX if a regex
// match was found and UNKNOWN otherwise.
// \return LITERAL if a lteral match was found,
// REGEX if any regex match was found,
// UNKNOWN otherwise.
inline wordRe::compOption matched(const std::string& text) const;
//- Extract list indices for all matches.
//- Return list indices for all matches.
//
// \param input A list of string inputs to match against
// \param invert invert the matching logic
// \return The locations (indices) in the input list where match()
// is true
// \return indices of the matches in the input list
template<class StringType>
inline labelList matching
(

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,34 +33,36 @@ inline const Foam::wordRes& Foam::wordRes::null()
}
inline bool Foam::wordRes::found_match
inline Foam::label Foam::wordRes::first_match
(
const UList<wordRe>& patterns,
const UList<wordRe>& selectors,
const std::string& text,
bool literal
const bool literal
)
{
for (const wordRe& select : patterns)
label index = 0;
for (const wordRe& select : selectors)
{
if (select.match(text, literal))
{
return true;
return index;
}
++index;
}
return false;
return -1;
}
inline Foam::wordRe::compOption Foam::wordRes::found_matched
(
const UList<wordRe>& patterns,
const UList<wordRe>& selectors,
const std::string& text
)
{
auto retval(wordRe::compOption::UNKNOWN);
for (const wordRe& select : patterns)
for (const wordRe& select : selectors)
{
if (select.isLiteral())
{
@ -69,12 +71,14 @@ inline Foam::wordRe::compOption Foam::wordRes::found_matched
return wordRe::compOption::LITERAL;
}
}
else if (wordRe::compOption::UNKNOWN == retval)
else if
(
// Only match regex once
retval == wordRe::compOption::UNKNOWN
&& select.match(text, false)
)
{
if (select.match(text, false))
{
retval = wordRe::compOption::REGEX;
}
retval = wordRe::compOption::REGEX;
}
}
@ -86,7 +90,7 @@ inline Foam::wordRe::compOption Foam::wordRes::found_matched
inline bool Foam::wordRes::match(const std::string& text, bool literal) const
{
return found_match(*this, text, literal);
return (first_match(*this, text, literal) >= 0);
}
@ -127,7 +131,13 @@ inline Foam::labelList Foam::wordRes::matching
inline bool Foam::wordRes::operator()(const std::string& text) const
{
return found_match(*this, text);
return (wordRes::first_match(*this, text) >= 0);
}
inline bool Foam::wordRes::matcher::operator()(const std::string& text) const
{
return (wordRes::first_match(values, text) >= 0);
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,8 +35,8 @@ Description
#ifndef functionObjects_fieldInfo_H
#define functionObjects_fieldInfo_H
#include "wordRe.H"
#include "label.H"
#include "wordRes.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,19 +46,20 @@ namespace Foam
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class fieldInfo Declaration
\*---------------------------------------------------------------------------*/
// Forward Declarations
class fieldInfo;
Istream& operator>>(Istream&, fieldInfo&);
Ostream& operator<<(Ostream&, const fieldInfo&);
/*---------------------------------------------------------------------------*\
Class fieldInfo Declaration
\*---------------------------------------------------------------------------*/
class fieldInfo
{
// Pivate data
// Pivate Data
//- Pattern for the field name
//- Pattern for the field name(s)
wordRe name_;
//- Field component
@ -72,10 +73,10 @@ public:
// Constructors
//- Null constructor
//- Default construct
fieldInfo()
:
name_(word::null),
name_(),
component_(-1),
found_(false)
{}
@ -153,6 +154,7 @@ public:
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -321,12 +321,20 @@ Foam::wordList Foam::coordinateSystems::names(const keyType& key) const
Foam::wordList Foam::coordinateSystems::names(const wordRe& matcher) const
{
if (matcher.empty())
{
return wordList();
}
return PtrListOps::names(*this, matcher);
}
Foam::wordList Foam::coordinateSystems::names(const wordRes& matcher) const
{
if (matcher.empty())
{
return wordList();
}
return PtrListOps::names(*this, matcher);
}

View File

@ -0,0 +1,31 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object dictionary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// (label == scalar) ?
#ifeq 0 0.0
labelEqScalar true;
#else
labelEqScalar false; } // Provoke parse error if we see this branch
#endif
// (scalar == label) ?
#ifeq 0.0 0
scalarEqLabel true;
#else
scalarEqLabel false; } // Provoke parse error if we see this branch
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //