Merge branch 'feature-token-passing' into 'develop'

Improvements to token handling

See merge request Development/OpenFOAM-plus!160
This commit is contained in:
Mark Olesen
2017-11-07 14:16:22 +00:00
74 changed files with 2949 additions and 1204 deletions

View File

@ -0,0 +1,3 @@
Test-ITstream.C
EXE = $(FOAM_USER_APPBIN)/Test-ITstream

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,137 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Description
\*---------------------------------------------------------------------------*/
#include "ListStream.H"
#include "UListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
#include "ITstream.H"
using namespace Foam;
template<class T>
Ostream& toString(Ostream& os, const T& str)
{
os << str;
return os;
}
template<>
Ostream& toString(Ostream& os, const UList<char>& list)
{
for (const char c : list)
{
os << c;
}
return os;
}
template<>
Ostream& toString(Ostream& os, const List<char>& list)
{
for (const char c : list)
{
os << c;
}
return os;
}
void printTokens(Istream& is)
{
label count = 0;
token t;
while (is.good())
{
is >> t;
if (t.good())
{
++count;
Info<<"token: " << t << endl;
}
}
Info<< count << " tokens" << endl;
}
template<class BUF>
void doTest(const string& name, const BUF& input, bool verbose=false)
{
Info<<"test " << name.c_str() << ":" << nl
<<"====" << nl;
toString(Info, input)
<< nl
<<"====" << nl << endl;
ITstream its(name, input);
Info<< "got " << its.size() << " tokens - index at "
<< its.tokenIndex() << endl;
if (verbose)
{
for (const token& tok : its)
{
Info<< " " << tok.info() << nl;
}
Info<< nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
const char* charInput =
"( const char input \"string\" to tokenize )"
"List<label> 5(0 1 2 3 4);";
string stringInput("( string ; input \"string\" to tokenize )");
List<char> listInput(stringInput.cbegin(), stringInput.cend());
doTest("char*", charInput, true);
doTest("string", stringInput, true);
doTest("List<char>", listInput, true);
reverse(listInput);
doTest("List<char>", listInput, true);
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -95,6 +95,14 @@ boundaryField
#include "testDict2"
verbatim #{
This is a somewhat larger chunk of verbatim text that we would much
prefer to move as a token rather than copying its entire content each
time we do parsing or need to resize the token list.
#};
foo
{
$active

View File

@ -0,0 +1,4 @@
Test-dictionaryTokens.C
dictionaryTokens.C
EXE = $(FOAM_USER_APPBIN)/Test-dictionaryTokens

View File

@ -0,0 +1 @@
EXE_INC =

View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Application
printDictionary
Description
Test dictionaryTokens
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOstreams.H"
#include "IOobject.H"
#include "IFstream.H"
#include "dictionaryTokens.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::noFunctionObjects();
argList::addBoolOption("info", "report token info");
argList::addBoolOption("value", "report token value");
argList::validArgs.insert("dict .. dictN");
argList args(argc, argv, false, true);
const bool optInfo = args.optionFound("info");
const bool optValue = args.optionFound("value");
for (label argi=1; argi < args.size(); ++argi)
{
IFstream is(args[argi]);
dictionary dict(is);
dictionaryTokens dictTokens(dict);
while (dictTokens.good())
{
if (optInfo)
{
// Token info
Info<< (*dictTokens).info() << nl;
}
else if (optValue)
{
// Token value
Info<< *dictTokens << nl;
}
else
{
// Token type
Info<< (*dictTokens).name() << nl;
}
++dictTokens;
}
Info<< nl;
}
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,309 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "dictionaryTokens.H"
#include "IOstream.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::token Foam::dictionaryTokens::keywordToken(const entry& e)
{
const keyType& k = e.keyword();
if (k.empty())
{
return token::undefinedToken;
}
if (k.isPattern())
{
return token(static_cast<string>(k)); // quoted
}
else
{
return token(static_cast<word>(k)); // unquoted
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::dictionaryTokens::setIterator() const
{
primIter_.clear();
dictIter_.clear();
if (entryIter_ != dict_.cend())
{
const entry& base = *entryIter_;
if (isA<primitiveEntry>(base))
{
primIter_.reset
(
new dictionaryTokens::primitive_iterator
(
dynamicCast<const primitiveEntry&>(base)
)
);
return true;
}
else if (isA<dictionaryListEntry>(base))
{
// Must check for isA<dictionaryListEntry> before checking
// for isA<dictionaryEntry> !
dictIter_.reset
(
new dictionaryTokens::dictionary_iterator
(
dynamicCast<const dictionaryListEntry&>(base)
)
);
return true;
}
else if (isA<dictionaryEntry>(base))
{
dictIter_.reset
(
new dictionaryTokens::dictionary_iterator
(
dynamicCast<const dictionaryEntry&>(base)
)
);
return true;
}
}
return false;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dictionaryTokens::dictionaryTokens(const dictionary& dict)
:
dict_(dict),
entryIter_(dict_.cbegin()),
primIter_(nullptr),
dictIter_(nullptr)
{
rewind();
}
Foam::dictionaryTokens::primitive_iterator::primitive_iterator
(
const primitiveEntry& e
)
:
tokensPtr_(&(static_cast<const tokenList&>(e))),
key_(dictionaryTokens::keywordToken(e)),
end_(token::punctuationToken::END_STATEMENT),
pos_((key_.good() ? -1 : 0))
{}
Foam::dictionaryTokens::dictionary_iterator::dictionary_iterator
(
const dictionaryEntry& e
)
:
key_(dictionaryTokens::keywordToken(e)),
lbrace_(token::punctuationToken::BEGIN_BLOCK),
rbrace_(token::punctuationToken::END_BLOCK),
state_(key_.good() ? states::KEY : states::OPEN),
dictTokens_(e.dict())
{}
Foam::dictionaryTokens::dictionary_iterator::dictionary_iterator
(
const dictionaryListEntry& e
)
:
key_(e.size()),
lbrace_(token::punctuationToken::BEGIN_LIST),
rbrace_(token::punctuationToken::END_LIST),
state_(states::KEY),
dictTokens_(e.dict())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::dictionaryTokens::good() const
{
return
(
entryIter_ != dict_.cend()
&&
(
(primIter_.valid() && primIter_().good())
|| (dictIter_.valid() && dictIter_().good())
)
);
}
bool Foam::dictionaryTokens::primitive_iterator::good() const
{
return (tokensPtr_ && pos_ <= tokensPtr_->size());
}
bool Foam::dictionaryTokens::dictionary_iterator::good() const
{
return (state_ != states::END);
}
const Foam::token& Foam::dictionaryTokens::operator*() const
{
if (good())
{
if (primIter_.valid()) return *(primIter_());
if (dictIter_.valid()) return *(dictIter_());
}
return token::undefinedToken;
}
const Foam::token&
Foam::dictionaryTokens::primitive_iterator::operator*() const
{
if (good())
{
if (pos_ == -1)
{
return key_;
}
else if (pos_ >= tokensPtr_->size())
{
return end_; // The trailing ';'
}
return tokensPtr_->operator[](pos_);
}
return token::undefinedToken;
}
const Foam::token&
Foam::dictionaryTokens::dictionary_iterator::operator*() const
{
if (good())
{
if (state_ == states::KEY)
{
return key_; // keyword
}
if (state_ == states::OPEN)
{
return lbrace_; // Opening '{'
}
if (state_ == states::CONTENT)
{
return *(dictTokens_);
}
if (state_ == states::CLOSE)
{
return rbrace_; // Closing '}'
}
}
return token::undefinedToken;
}
bool Foam::dictionaryTokens::operator++()
{
bool ok = good();
if (ok)
{
if (primIter_.valid()) ok = ++(primIter_());
if (dictIter_.valid()) ok = ++(dictIter_());
if (!ok)
{
++entryIter_; // Next entry
setIterator();
}
}
return ok;
}
bool Foam::dictionaryTokens::primitive_iterator::operator++()
{
// Advance good iterators.
//
// Going beyond trailing ';' makes it into an end iterator
if (tokensPtr_ && (++pos_ > tokensPtr_->size()))
{
tokensPtr_ = nullptr;
return false;
}
return this->good();
}
bool Foam::dictionaryTokens::dictionary_iterator::operator++()
{
if
(
state_ == states::KEY
|| state_ == states::OPEN
|| state_ == states::CLOSE
)
{
++state_;
}
else if (state_ == states::CONTENT && !(++dictTokens_))
{
++state_;
}
return good();
}
void Foam::dictionaryTokens::rewind()
{
entryIter_ = dict_.cbegin();
setIterator();
}
// ************************************************************************* //

View File

@ -0,0 +1,289 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Class
Foam::dictionaryTokens
Description
Provides a stream of tokens from a dictionary.
This can be used to return a stream of tokens from a dictionary
without overhead or needing to reparse information.
For example,
\code
OPstream os = ...;
dictionaryTokens toks(dict);
while (toks.good())
{
os.write(*toks);
++toks;
}
\endcode
Or alternatively,
\code
dictionaryTokens toks(dict);
while (toks.good())
{
os << *toks << nl;
++toks;
}
\endcode
SourceFiles
dictionaryTokens.C
\*---------------------------------------------------------------------------*/
#ifndef dictionaryTokens_H
#define dictionaryTokens_H
#include "dictionary.H"
#include "primitiveEntry.H"
#include "dictionaryEntry.H"
#include "dictionaryListEntry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class dictionaryTokens;
/*---------------------------------------------------------------------------*\
Class dictionaryTokens Declaration
\*---------------------------------------------------------------------------*/
class dictionaryTokens
{
public:
// Forward declarations
class primitive_iterator;
class dictionary_iterator;
private:
// Private Member Data
//- Reference to the dictionary being streamed.
const dictionary& dict_;
//- The current entry iterator
IDLList<entry>::const_iterator entryIter_;
//- The current entry iterator for primitiveEntry types
mutable autoPtr<primitive_iterator> primIter_;
//- The current entry iterator for dictionaryEntry and
//- dictionaryListEntry types
mutable autoPtr<dictionary_iterator> dictIter_;
//- Set/unset primitive and dictionary when changing to next entry
bool setIterator() const;
// Private Member Functions
//- Disallow bitwise copy/assignment
dictionaryTokens(const dictionaryTokens&) = delete;
void operator=(const dictionaryTokens&) = delete;
public:
// Static Member Functions
//- The entry keyword as word or string token
static token keywordToken(const entry& e);
// Constructors
//- Construct from reference to dictionary to be streamed
dictionaryTokens(const dictionary& dict);
// Member Functions
//- True if the token stream is in a valid state
bool good() const;
//- The current token, or undefined if the stream is in an invalid
//- invalid state.
const token& operator*() const;
//- Advance to the next token and return the updated stream stream.
bool operator++();
//- Reset to beginning
void rewind();
};
/*---------------------------------------------------------------------------*\
Class dictionaryTokens::primitive_iterator Declaration
\*---------------------------------------------------------------------------*/
//- An iterator for a primitiveEntry
//
// The token stream output has the form
//
// \verbatim
// keyword content tokens ';'
// \endverbatim
//
class dictionaryTokens::primitive_iterator
{
// Private Member Data
//- Reference to the tokenList being streamed.
const tokenList* tokensPtr_;
//- The keyword as a token (string, word or undefined)
const token key_;
//- The closing ';' as a token
const token end_;
//- The current position within the tokenList
label pos_;
// Private Member Functions
//- Disallow bitwise copy/assignment
primitive_iterator(const primitive_iterator&) = delete;
void operator=(const primitive_iterator&) = delete;
public:
// Constructors
//- Construct from reference to primitiveEntry
primitive_iterator(const primitiveEntry& e);
// Member Functions
//- True if the entry has keyword or tokens and has not indexed beyond
//- the final trailing ';'
bool good() const;
//- The current token, or undefined if the stream is invalid.
const token& operator*() const;
//- Advance to the next token and return the updated stream stream.
bool operator++();
};
/*---------------------------------------------------------------------------*\
Class dictionaryTokens::dictionary_iterator Declaration
\*---------------------------------------------------------------------------*/
//- An iterator for a dictionaryEntry and dictionaryListEntry
//
// The token stream output has the form
//
// \verbatim
// keyword '{' content '}'
// \endverbatim
//
// or for the dictionaryListEntry the form
//
// \verbatim
// size '(' content ')'
// \endverbatim
//
class dictionaryTokens::dictionary_iterator
{
// Private Member Data
//- The possible output states
enum states { KEY=0, OPEN, CONTENT, CLOSE, END };
//- The keyword or the size (dictionaryListEntry) as a token
const token key_;
//- The opening brace '{' or bracket '('
const token lbrace_;
//- The closing brace ')' or bracket ')'
const token rbrace_;
//- The current output state
int state_;
//- A streamer for the dictionary content
dictionaryTokens dictTokens_;
// Private Member Functions
//- Disallow bitwise copy/assignment
dictionary_iterator(const dictionary_iterator&) = delete;
void operator=(const dictionary_iterator&) = delete;
public:
// Constructors
//- Construct from reference to dictionaryEntry
dictionary_iterator(const dictionaryEntry& e);
//- Construct from reference to dictionaryListEntry
dictionary_iterator(const dictionaryListEntry& e);
// Member Functions
//- In a valid state
bool good() const;
//- The current token, or undefined if the stream is invalid.
const token& operator*() const;
//- Advance to the next token and return the updated stream stream.
bool operator++();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#endif
// ************************************************************************* //

View File

@ -120,6 +120,24 @@ void testMapDistribute()
}
// Print to Perr
template<class T>
Ostream& perrInfo(const T& data)
{
Perr<< data;
return Perr;
}
// Print to Perr
template<>
Ostream& perrInfo(const string& data)
{
Perr<< data << " (size: " << data.size() << ")";
return Perr;
}
template<class T>
void testTransfer(const T& input)
{
@ -127,7 +145,8 @@ void testTransfer(const T& input)
if (Pstream::master())
{
Perr<<"test transfer (" << (typeid(T).name()) << "): " << data << nl << endl;
Perr<<"test transfer (" << (typeid(T).name()) << "): ";
perrInfo(data) << nl << endl;
}
if (Pstream::myProcNo() != Pstream::masterNo())
@ -141,7 +160,7 @@ void testTransfer(const T& input)
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
fromMaster >> data;
Perr<< data << endl;
perrInfo(data) << endl;
}
else
{
@ -155,7 +174,7 @@ void testTransfer(const T& input)
Perr<< "master receiving from slave " << slave << endl;
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
fromSlave >> data;
Perr<< data << endl;
perrInfo(data) << endl;
}
for
@ -258,6 +277,15 @@ int main(int argc, char *argv[])
testTransfer(scalar(3.14159));
testTransfer(string("test string"));
testTransfer(string(" x "));
{
// Slightly roundabout way to construct with a nul in string
string str1("embedded. nul character in string");
str1[8] = '\0';
Info<< "len: " << str1.size() << endl;
testTransfer(str1);
}
testTransfer(word("3.141 59")); // bad word, but transfer doesn't care
testTokenized(label(1234));

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,7 +44,7 @@ int main(int argc, char *argv[])
Info<< "Test expressions:" << rawList << endl;
IOobject::writeDivider(Info) << endl;
List<string> groups;
List<std::string> groups;
// Report matches:
forAll(rawList, elemI)
@ -74,7 +74,23 @@ int main(int argc, char *argv[])
Info<< "false";
}
}
Info<< endl;
if (false)
{
regExp re2(std::move(re));
Info<<"move construct: " << re.exists() << "/" << re2.exists()
<< endl;
re = std::move(re2);
Info<<"move assign: " << re.exists() << "/" << re2.exists()
<< endl;
re.swap(re2);
Info<<"swap: " << re.exists() << "/" << re2.exists()
<< endl;
}
}
Info<< nl << "test regExp(const char*) ..." << endl;

View File

@ -69,6 +69,65 @@ int main(int argc, char *argv[])
Info<<"trimRight: " << stringOps::trimRight(test) << endl;
Info<<"trim: " << stringOps::trim(test) << endl;
if (false)
{
Info<<"test move construct - string size:" << test.size() << nl;
string test2(std::move(test));
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
Info<<"test move assign - string sizes:"
<< test.size() << "/" << test2.size() << nl;
test = std::move(test2);
Info<<"input size:" << test.size() << nl;
Info<<"moved size:" << test2.size() << nl;
}
if (false)
{
std::string str("some text");
Info<<"test move construct to string:" << str.size() << nl;
Foam::string test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
}
if (false)
{
Foam::string str("thisIsAWord");
Info<<"test move construct to word:" << str.size() << nl;
word test2(std::move(str));
Info<<"input/moved sizes:" << str.size() << "/" << test2.size() << nl;
str = std::move(test2);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
// move back
test2.swap(str);
Info<<"test move assign - sizes:"
<< str.size() << "/" << test2.size() << nl;
string str2(std::move(test2));
Info<<"input/moved sizes:" << test2.size() << "/" << str2.size() << nl;
}
{
fileName test1("libFooBar.so");

View File

@ -0,0 +1,3 @@
Test-token.C
EXE = $(FOAM_USER_APPBIN)/Test-token

View File

@ -0,0 +1 @@
/* EXE_INC = */

View File

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Description
Test token construct assign etc.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "IOobject.H"
#include "IOstreams.H"
#include "IFstream.H"
#include "StringStream.H"
#include "cpuTime.H"
#include "DynamicList.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList args(argc, argv, false, true);
token tok1;
Info<< "construct null: " << tok1.info() << endl;
tok1 = double(3.14159);
Info<< "assign double: " << tok1.info() << endl;
token tok2(tok1);
Info<< "copy construct: " << tok2.info() << endl;
tok1 = word("this-word");
Info<< "assign word: " << tok1.info() << endl;
token tok3(tok1);
Info<< "copy construct: " << tok3.info() << endl;
Info<< "orig: " << tok1.info() << endl;
token tok4(std::move(tok1));
Info<< "move construct: " << tok4.info() << endl;
Info<< "orig: " << tok1.info() << endl;
tok3 = tok4;
Info<< "assign token: " << tok3.info() << endl;
Info<< "orig: " << tok4.info() << endl;
return 0;
}
// ************************************************************************* //

View File

@ -33,6 +33,7 @@ Description
#include "IFstream.H"
#include "StringStream.H"
#include "cpuTime.H"
#include "DynamicList.H"
using namespace Foam;
@ -69,6 +70,8 @@ int main(int argc, char *argv[])
IStringStream is(rawArg);
DynamicList<token> tokens;
while (is.good())
{
token tok(is);
@ -83,12 +86,23 @@ int main(int argc, char *argv[])
<< " lookahead: '" << char(lookahead) << "'"
<< endl;
}
if (tok.good())
{
tokens.append(std::move(tok));
if (verbose)
{
Info<< "after append: " << tok.info() << endl;
}
}
}
if (verbose)
{
Info<< nl;
IOobject::writeDivider(Info);
Info<< "tokenList:" << tokens << endl;
}
}
}

View File

@ -56,6 +56,56 @@ int main(int argc, char *argv[])
{"file[a-b]", wordRe::REGEX},
};
if (true)
{
Info<<"keyType: " << keyre << endl;
keyType key2(std::move(keyre));
Info<<"move construct: <" << keyre << "> <" << key2 << ">" << endl;
keyre = std::move(key2);
Info<<"move assign: <" << keyre << "> <" << key2 << ">" << endl;
keyType key3;
keyre.swap(key3);
Info<<"swap: <" << keyre << "> <" << key3 << ">" << endl;
keyre = std::move(key3);
Info<<"move assign: <" << keyre << "> <" << key3 << ">" << endl;
return 0;
}
if (false)
{
wordRe keyre("y.*", wordRe::REGEX);
Info<<"wordRe: " << keyre << endl;
wordRe key2(std::move(keyre));
Info<<"keyTypes: " << keyre << " " << key2 << endl;
keyre = std::move(key2);
Info<<"keyTypes: " << keyre << " " << key2 << endl;
wordRe key3;
keyre.swap(key3);
Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl;
keyre = std::move(key3);
Info<<"keyTypes: <" << keyre << "> <" << key3 << ">" << endl;
return 0;
}
wordRes wrelist(wordrelist);
Info<< "re-list:" << wrelist() << endl;
@ -76,7 +126,7 @@ int main(int argc, char *argv[])
wre = "this .* file";
Info<<"substring: " << wre(4) << endl;
Info<<"substring: " << wre.substr(4) << endl;
wre.info(Info) << endl;
wre = s1;

View File

@ -4,7 +4,7 @@
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
# \\/ M anipulation |
# \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
#-------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
@ -26,50 +26,90 @@
# mpirunDebug
#
# Description
# Driver script to run mpi jobs with the processes in separate
# windows or to separate log files.
# Driver script to run mpi jobs with the processes in a separate XTerm
# or to separate log files.
# Requires bash on all processors.
#------------------------------------------------------------------------------
if [ `uname -s` = Linux ]
then
ECHO='echo -e'
else
ECHO='echo'
fi
usage()
{
usage() {
exec 1>&2
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE
Usage: ${0##*/} -np <dd> <executable> <args>
Usage: ${0##*/} [OPTION] -np <N> <executable> <args>
* This will run like mpirun but with each process in an XTerm
options:
-method=MODE Run mode
(0) normal
(1) gdb+xterm
(2) gdb
(3) log
(4) log+xterm
(5) xterm+valgrind
(6) gperftools(callgrind)
-spawn=TYPE Spawn type: (1) local (2) remote
-log Alias for -method=3
-local Alias for -spawn=1
-yes Start without additional prompt
-help Print the usage
Invoke mpirun but with each process in a separate XTerm, or to separate logfile
USAGE
exit 1
}
unset nProcs exec args
case "$(uname -s)" in
Linux)
ECHO='echo -e'
;;
*)
ECHO='echo'
;;
esac
while [ "$1" != "" ]
unset nProcs appName appArgs
unset method spawn optNoAsk
# parse options
while [ "$#" -gt 0 ]
do
echo "$1"
case $1 in
# echo "$1" 1>&2
case "$1" in
-help)
usage
;;
-method=[0-6])
method="${1#*=}"
;;
-spawn=[1-2])
spawn="${1#*=}"
;;
-log)
method=3
;;
-local)
spawn=1
;;
-yes)
optNoAsk=true
;;
-np)
nProcs=$2
shift
;;
*)
if [ ! "$exec" ]
if [ -z "$appName" ]
then
exec=$1
elif [ ! "$args" ]
then
args="\"$1\""
appName="$1"
else
args="$args \"$1\""
appArgs="${appArgs}${appArgs:+ }\"$1\""
fi
;;
esac
@ -77,54 +117,61 @@ do
done
echo "nProcs=$nProcs"
echo "exec=$exec"
echo "args=$args"
echo "exec=$appName"
echo "args=$appArgs"
[ "$nProcs" ] || usage
[ "$args" ] || usage
[ "$exec" ] || usage
[ -n "$nProcs" ] || usage
[ -n "$appArgs" ] || usage
[ -n "$appName" ] || usage
exec=`which $exec`
if [ ! -x "$exec" ]
then
echo "Cannot find executable $exec or is not executable"
usage
fi
exec=$(command -v $appName)
[ -x "$exec" ] || {
echo "Cannot find executable $appName or is not executable"
usage
}
if [ ! "$PWD" ]
then
PWD=`pwd`
fi
[ -n "$PWD" ] || PWD=$(pwd)
echo "run $args" > $PWD/gdbCommands
echo "run $appArgs" > $PWD/gdbCommands
echo "where" >> $PWD/gdbCommands
echo "Constructed gdb initialization file $PWD/gdbCommands"
$ECHO "Choose running method: 0)normal 1)gdb+xterm 2)gdb 3)log 4)log+xterm 5)xterm+valgrind 6)gperftools(callgrind): \c"
read method
case "$method" in
0 | 1 | 2 | 3 | 4 | 5 | 6)
# okay
;;
*)
usage
;;
esac
$ECHO "Run all processes local or distributed? 1)local 2)remote: \c"
read spawn
if [ "$spawn" -ne 1 -a "$spawn" -ne 2 ]
# Choose method
if [ -z "$method" ]
then
usage
$ECHO "Choose running method: 0)normal 1)gdb+xterm 2)gdb 3)log 4)log+xterm 5)xterm+valgrind 6)gperftools(callgrind): \c"
read method
case "$method" in
0 | 1 | 2 | 3 | 4 | 5 | 6)
# okay
;;
*)
usage
;;
esac
fi
# Choose spawn
if [ -z "$spawn" ]
then
$ECHO "Run all processes local or distributed? 1)local 2)remote: \c"
read spawn
case "$spawn" in
1 | 2)
# okay
;;
*)
usage
;;
esac
fi
# check ~/.$WM_PROJECT/$WM_PROJECT_VERSION/
# check ~/.$WM_PROJECT/
# check <installedProject>/etc/
if [ "$WM_PROJECT" ]
if [ -n "$WM_PROJECT" ]
then
for i in \
$HOME/.$WM_PROJECT/$WM_PROJECT_VERSION \
$HOME/.$WM_PROJECT \
@ -143,7 +190,7 @@ fi
# Source OpenFOAM settings if OpenFOAM environment not set.
# attempt to preserve the installation directory 'FOAM_INST_DIR'
# use FOAM_SETTINGS to pass command-line settings
if [ "$FOAM_INST_DIR" ]
if [ -n "$FOAM_INST_DIR" ]
then
sourceFoam="FOAM_INST_DIR=$FOAM_INST_DIR . $sourceFoam $FOAM_SETTINGS"
else
@ -162,49 +209,53 @@ for ((proc=0; proc<$nProcs; proc++))
do
procCmdFile="$PWD/processor${proc}.sh"
procLog="processor${proc}.log"
geom="-geometry 120x15+$xpos+$ypos"
xterm="xterm -font fixed -title processor${proc} -geometry 120x15+$xpos+$ypos"
unset node
case "$WM_MPLIB" in
*OPENMPI)
node="-np 1 "
;;
*)
node=""
esac
echo "#!/bin/bash" > $procCmdFile
echo "$sourceFoam" >> $procCmdFile
echo "cd $PWD" >> $procCmdFile
case "$method" in
0)
echo "$sourceFoam; cd $PWD; $exec $args | tee $procLog" >> $procCmdFile
echo "${node}$procCmdFile" >> $PWD/mpirun.schema
echo "$exec $appArgs | tee $procLog" >> $procCmdFile
;;
1)
echo "$sourceFoam; cd $PWD; gdb -command $PWD/gdbCommands $exec 2>&1 | tee $procLog; read dummy" >> $procCmdFile
#echo "$sourceFoam; cd $PWD; $exec $args; read dummy" >> $procCmdFile
echo "${node}xterm -font fixed -title 'processor'$proc $geom -e $procCmdFile" >> $PWD/mpirun.schema
echo "${node}$xterm -e $procCmdFile" >> $PWD/mpirun.schema
echo "gdb -command $PWD/gdbCommands $exec 2>&1 | tee $procLog"
echo "read dummy"
;;
2)
echo "$sourceFoam; cd $PWD; gdb -command $PWD/gdbCommands $exec > $procLog 2>&1" >> $procCmdFile
echo "${node}$procCmdFile" >> $PWD/mpirun.schema
echo "gdb -command $PWD/gdbCommands $exec > $procLog 2>&1"
;;
3)
echo "$sourceFoam; cd $PWD; $exec $args > $procLog 2>&1" >> $procCmdFile
echo "${node}$procCmdFile" >> $PWD/mpirun.schema
echo "$exec $appArgs > $procLog 2>&1"
;;
4)
echo "$sourceFoam; cd $PWD; $exec $args 2>&1 | tee $procLog; read dummy" >> $procCmdFile
echo "${node}xterm -font fixed -title 'processor'$proc $geom -e $procCmdFile" >> $PWD/mpirun.schema
echo "${node}$xterm -e $procCmdFile" >> $PWD/mpirun.schema
echo "$exec $appArgs 2>&1 | tee $procLog"
echo "read dummy"
;;
5)
echo "$sourceFoam; cd $PWD; valgrind --leak-check=full --show-reachable=yes $exec $args 2>&1 | tee $procLog; read dummy" >> $procCmdFile
echo "${node}xterm -font fixed -title 'processor'$proc $geom -e $procCmdFile" >> $PWD/mpirun.schema
echo "${node}$xterm -e $procCmdFile" >> $PWD/mpirun.schema
echo "valgrind --leak-check=full --show-reachable=yes $exec $appArgs 2>&1 | tee $procLog"
echo "read dummy"
;;
6)
echo "$sourceFoam; cd $PWD; CPUPROFILE=log.profiler_$proc $exec $args; \
pprof --callgrind $exec log.profiler_$proc > log.profiler_$proc.callgrind;" >> $procCmdFile
echo "${node}$procCmdFile" >> $PWD/mpirun.schema
echo "CPUPROFILE=log.profiler_$proc $exec $appArgs"
echo "pprof --callgrind $exec log.profiler_$proc > log.profiler_$proc.callgrind"
;;
esac
esac >> $procCmdFile
chmod +x $procCmdFile
@ -255,11 +306,20 @@ MPICH)
esac
echo "Constructed $PWD/mpirun.schema file."
echo ""
echo
echo " $cmd"
echo ""
$ECHO "Press return to execute.\c"
read dummy
echo
if [ -n "$optNoAsk" ]
then
echo "starting: " $(date '+%Y-%m-%d %H:%M:%S %z' 2>/dev/null)
echo
else
# Pause before running
$ECHO "Press return to execute.\c"
read dummy
fi
exec $cmd
#------------------------------------------------------------------------------

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 |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -113,6 +113,9 @@ public:
//- Construct from string, optionally ignore case
inline regExp(const std::string& pattern, bool ignoreCase);
//- Move construct
inline regExp(regExp&& rgx);
//- Destructor
inline ~regExp();
@ -146,6 +149,9 @@ public:
// \return True if expression had existed prior to the clear.
bool clear();
//- Swap contents
inline void swap(regExp& rgx);
// Matching/Searching
@ -177,6 +183,10 @@ public:
//- Assign and compile pattern from string
// Always case sensitive
inline void operator=(const std::string& pattern);
//- Move assignment
inline void operator=(regExp&& rgx);
};

View File

@ -23,6 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include <algorithm>
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -78,6 +80,14 @@ inline Foam::regExp::regExp(const std::string& pattern, bool ignoreCase)
}
inline Foam::regExp::regExp(regExp&& rgx)
:
preg_(rgx.preg_)
{
rgx.preg_ = nullptr;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
inline Foam::regExp::~regExp()
@ -112,6 +122,12 @@ inline bool Foam::regExp::search(const std::string& text) const
}
inline void Foam::regExp::swap(regExp& rgx)
{
std::swap(preg_, rgx.preg_);
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
inline bool Foam::regExp::operator()(const std::string& text) const
@ -132,4 +148,11 @@ inline void Foam::regExp::operator=(const std::string& pattern)
}
inline void Foam::regExp::operator=(regExp&& rgx)
{
clear();
swap(rgx);
}
// ************************************************************************* //

View File

@ -217,7 +217,6 @@ $(dictionaryEntry)/dictionaryEntry.C
$(dictionaryEntry)/dictionaryEntryIO.C
dictionaryListEntry = $(dictionary)/dictionaryListEntry
$(dictionaryListEntry)/dictionaryListEntry.C
$(dictionaryListEntry)/dictionaryListEntryIO.C
functionEntries = $(dictionary)/functionEntries

View File

@ -249,6 +249,9 @@ public:
//- Append an element to the end of this list.
inline DynamicList<T, SizeMin>& append(const T& val);
//- Move append an element
inline DynamicList<T, SizeMin>& append(T&& val);
//- Append another list to the end of this list.
inline DynamicList<T, SizeMin>& append(const UList<T>& lst);

View File

@ -492,7 +492,22 @@ Foam::DynamicList<T, SizeMin>::append
const label idx = List<T>::size();
setSize(idx + 1);
this->operator[](idx) = val;
this->operator[](idx) = val; // copy element
return *this;
}
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>&
Foam::DynamicList<T, SizeMin>::append
(
T&& val
)
{
const label idx = List<T>::size();
setSize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element
return *this;
}
@ -510,12 +525,13 @@ Foam::DynamicList<T, SizeMin>::append
<< "Attempted appending to self" << abort(FatalError);
}
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
@ -529,12 +545,12 @@ Foam::DynamicList<T, SizeMin>::append
const FixedList<T, FixedSize>& lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
@ -547,12 +563,13 @@ Foam::DynamicList<T, SizeMin>::append
std::initializer_list<T> lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (const T& val : lst)
{
this->operator[](nextFree++) = val;
this->operator[](idx++) = val; // copy element
}
return *this;
}
@ -565,12 +582,14 @@ Foam::DynamicList<T, SizeMin>::append
const UIndirectList<T>& lst
)
{
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
const label n = lst.size();
forAll(lst, elemI)
setSize(idx + n);
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[elemI];
this->operator[](idx++) = lst[i]; // copy element
}
return *this;
}
@ -589,12 +608,13 @@ Foam::DynamicList<T, SizeMin>::append
<< "Attempted appending to self" << abort(FatalError);
}
label nextFree = List<T>::size();
setSize(nextFree + lst.size());
label idx = List<T>::size();
setSize(idx + lst.size());
for (T& val : lst)
{
Foam::Swap(this->operator[](nextFree++), val);
Foam::Swap(this->operator[](idx++), val); // moved content
}
lst.clear();
@ -779,11 +799,13 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
const FixedList<T, FixedSize>& lst
)
{
setSize(lst.size());
const label n = lst.size();
forAll(lst, i)
setSize(n);
for (label i=0; i<n; ++i)
{
this->operator[](i) = lst[i];
this->operator[](i) = lst[i]; // copy element
}
}

View File

@ -226,7 +226,10 @@ public:
//- Append an element at the end of the list
inline void append(const T& val);
//- Append a List at the end of this list
//- Move append an element at the end of the list
inline void append(T&& val);
//- Append a List to the end of this list
inline void append(const UList<T>& lst);
//- Append a UIndirectList at the end of this list

View File

@ -172,7 +172,17 @@ inline Foam::Xfer<Foam::List<T>> Foam::List<T>::xfer()
template<class T>
inline void Foam::List<T>::append(const T& val)
{
setSize(this->size()+1, val);
setSize(this->size() + 1, val); // copy element
}
template<class T>
inline void Foam::List<T>::append(T&& val)
{
const label idx = this->size();
setSize(idx + 1);
this->operator[](idx) = std::move(val); // move assign element
}
@ -185,12 +195,14 @@ inline void Foam::List<T>::append(const UList<T>& lst)
<< "attempted appending to self" << abort(FatalError);
}
label nextFree = this->size();
setSize(nextFree + lst.size());
label idx = this->size();
const label n = lst.size();
forAll(lst, i)
setSize(idx + n);
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[i];
this->operator[](idx++) = lst[i]; // copy element
}
}
@ -198,12 +210,14 @@ inline void Foam::List<T>::append(const UList<T>& lst)
template<class T>
inline void Foam::List<T>::append(const UIndirectList<T>& lst)
{
label nextFree = this->size();
setSize(nextFree + lst.size());
label idx = this->size();
const label n = lst.size();
forAll(lst, i)
setSize(idx + n);
for (label i=0; i<n; ++i)
{
this->operator[](nextFree++) = lst[i];
this->operator[](idx++) = lst[i]; // copy element
}
}

View File

@ -92,7 +92,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
}
else
{
// uniform content (delimiter == token::BEGIN_BLOCK)
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
@ -141,7 +141,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
// Putback the opening bracket
is.putBack(firstToken);
// Now read as a singly-linked list
// Read as a singly-linked list
SLList<T> sll(is);
// Convert the singly-linked list to this list
@ -176,8 +176,11 @@ Foam::List<T> Foam::readList(Istream& is)
<< exit(FatalIOError);
}
// Read via a singly-linked list
L = SLList<T>(is);
// Read as singly-linked list
SLList<T> sll(is);
// Convert the singly-linked list to this list
L = sll;
}
else
{

View File

@ -27,7 +27,7 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::Istream::putBack(const token& t)
void Foam::Istream::putBack(const token& tok)
{
if (bad())
{
@ -43,13 +43,13 @@ void Foam::Istream::putBack(const token& t)
}
else
{
putBackToken_ = t;
putBackToken_ = tok;
putBack_ = true;
}
}
bool Foam::Istream::getBack(token& t)
bool Foam::Istream::getBack(token& tok)
{
if (bad())
{
@ -59,7 +59,7 @@ bool Foam::Istream::getBack(token& t)
}
else if (putBack_)
{
t = putBackToken_;
tok = putBackToken_;
putBack_ = false;
return true;
}
@ -68,15 +68,15 @@ bool Foam::Istream::getBack(token& t)
}
bool Foam::Istream::peekBack(token& t)
bool Foam::Istream::peekBack(token& tok)
{
if (putBack_)
{
t = putBackToken_;
tok = putBackToken_;
}
else
{
t = token::undefinedToken;
tok = token::undefinedToken;
}
return putBack_;

View File

@ -96,16 +96,16 @@ public:
//- Put back token
// Only a single put back is permitted
void putBack(const token&);
void putBack(const token& tok);
//- Get the put back token if there is one and return true.
// Return false if no put back token is available.
bool getBack(token&);
bool getBack(token& tok);
//- Peek at the put back token without removing it.
// Returns false if no put back token is available and set the
// token to undefined.
bool peekBack(token&);
bool peekBack(token& tok);
//- Return next token from stream
virtual Istream& read(token&) = 0;
@ -116,7 +116,7 @@ public:
//- Read a word
virtual Istream& read(word&) = 0;
// Read a string (including enclosing double-quotes)
//- Read a string (including enclosing double-quotes)
virtual Istream& read(string&) = 0;
//- Read a label

View File

@ -97,7 +97,7 @@ public:
// Write functions
//- Write next token to stream
virtual Ostream& write(const token& t) = 0;
virtual Ostream& write(const token& tok) = 0;
//- Write character
virtual Ostream& write(const char c) = 0;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,12 +42,12 @@ inline void Foam::UIPstream::checkEof()
template<class T>
inline void Foam::UIPstream::readFromBuffer(T& t)
inline void Foam::UIPstream::readFromBuffer(T& val)
{
const size_t align = sizeof(T);
externalBufPosition_ = align + ((externalBufPosition_ - 1) & ~(align - 1));
t = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
val = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
externalBufPosition_ += sizeof(T);
checkEof();
}
@ -67,10 +67,14 @@ inline void Foam::UIPstream::readFromBuffer
+ ((externalBufPosition_ - 1) & ~(align - 1));
}
const char* bufPtr = &externalBuf_[externalBufPosition_];
char* dataPtr = reinterpret_cast<char*>(data);
size_t i = count;
while (i--) *dataPtr++ = *bufPtr++;
const char* const __restrict__ buf = &externalBuf_[externalBufPosition_];
char* const __restrict__ output = reinterpret_cast<char*>(data);
for (size_t i = 0; i < count; ++i)
{
output[i] = buf[i];
}
externalBufPosition_ += count;
checkEof();
}
@ -78,14 +82,15 @@ inline void Foam::UIPstream::readFromBuffer
inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str)
{
// Use std::string::assign() to copy content, including '\0'.
// Stripping (when desired) is the responsibility of the sending side.
size_t len;
readFromBuffer(len);
// Uses the underlying std::string::operator=()
// - no stripInvalid invoked (the sending side should have done that)
// - relies on trailing '\0' char (so cannot send anything with an embedded
// nul char)
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
str.assign(&externalBuf_[externalBufPosition_], len);
externalBufPosition_ += len;
checkEof();
return *this;
@ -159,22 +164,20 @@ Foam::Istream& Foam::UIPstream::read(token& t)
// Word
case token::tokenType::WORD :
{
word* pval = new word;
if (read(*pval))
word val;
if (read(val))
{
if (token::compound::isCompound(*pval))
if (token::compound::isCompound(val))
{
t = token::compound::New(*pval, *this).ptr();
delete pval;
t = token::compound::New(val, *this).ptr();
}
else
{
t = pval;
t = std::move(val);
}
}
else
{
delete pval;
t.setBad();
}
return *this;
@ -185,26 +188,25 @@ Foam::Istream& Foam::UIPstream::read(token& t)
{
// Recurse to read actual string
read(t);
t.type() = token::tokenType::VERBATIMSTRING;
t.setType(token::tokenType::VERBATIMSTRING);
return *this;
}
case token::tokenType::VARIABLE :
{
// Recurse to read actual string
read(t);
t.type() = token::tokenType::VARIABLE;
t.setType(token::tokenType::VARIABLE);
return *this;
}
case token::tokenType::STRING :
{
string* pval = new string;
if (read(*pval))
string val;
if (read(val))
{
t = pval;
t = std::move(val);
}
else
{
delete pval;
t.setBad();
}
return *this;
@ -276,7 +278,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
Foam::Istream& Foam::UIPstream::read(char& c)
{
c = externalBuf_[externalBufPosition_];
externalBufPosition_++;
++externalBufPosition_;
checkEof();
return *this;
}

View File

@ -80,7 +80,7 @@ class UIPstream
//- Read a T from the transfer buffer
template<class T>
inline void readFromBuffer(T& t);
inline void readFromBuffer(T& val);
//- Read count bytes of data from the transfer buffer
// using align byte alignment

View File

@ -109,7 +109,7 @@ inline void Foam::UOPstream::writeStringToBuffer(const std::string& str)
{
const size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
writeToBuffer(str.data(), len, 1);
}
@ -185,18 +185,18 @@ Foam::UOPstream::~UOPstream()
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Ostream& Foam::UOPstream::write(const token& t)
Foam::Ostream& Foam::UOPstream::write(const token& tok)
{
// Raw token output only supported for verbatim strings for now
if (t.type() == token::tokenType::VERBATIMSTRING)
if (tok.type() == token::tokenType::VERBATIMSTRING)
{
writeToBuffer(char(token::tokenType::VERBATIMSTRING));
write(t.stringToken());
write(tok.stringToken());
}
else if (t.type() == token::tokenType::VARIABLE)
else if (tok.type() == token::tokenType::VARIABLE)
{
writeToBuffer(char(token::tokenType::VARIABLE));
write(t.stringToken());
write(tok.stringToken());
}
else
{

View File

@ -147,7 +147,7 @@ public:
);
//- Write next token to stream
Ostream& write(const token& t);
Ostream& write(const token& tok);
//- Write single character. Whitespace is suppressed.
Ostream& write(const char c);

View File

@ -116,21 +116,18 @@ char Foam::ISstream::nextValid()
void Foam::ISstream::readWordToken(token& t)
{
word* wPtr = new word;
if (read(*wPtr).bad())
word val;
if (read(val).bad())
{
delete wPtr;
t.setBad();
}
else if (token::compound::isCompound(*wPtr))
else if (token::compound::isCompound(val))
{
t = token::compound::New(*wPtr, *this).ptr();
delete wPtr;
t = token::compound::New(val, *this).ptr();
}
else
{
t = wPtr; // Token takes ownership
t = std::move(val); // Move contents to token
}
}
@ -167,7 +164,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Analyse input starting with this character.
switch (c)
{
// Check for punctuation first
// Check for punctuation first - same as token::isSeparator
case token::END_STATEMENT :
case token::BEGIN_LIST :
@ -192,16 +189,15 @@ Foam::Istream& Foam::ISstream::read(token& t)
case token::BEGIN_STRING :
{
putback(c);
string* sPtr = new string;
if (read(*sPtr).bad())
string val;
if (read(val).bad())
{
delete sPtr;
t.setBad();
}
else
{
t = sPtr; // Token takes ownership
t = std::move(val); // Move contents to token
}
return *this;
@ -219,17 +215,16 @@ Foam::Istream& Foam::ISstream::read(token& t)
else if (nextC == token::BEGIN_BLOCK)
{
// Verbatim string: #{ ... #}
string* sPtr = new string;
if (readVerbatim(*sPtr).bad())
string val;
if (readVerbatim(val).bad())
{
delete sPtr;
t.setBad();
}
else
{
t = sPtr; // Token takes ownership
t.type() = token::tokenType::VERBATIMSTRING;
t = std::move(val); // Move contents to token
t.setType(token::tokenType::VERBATIMSTRING);
}
}
else
@ -259,17 +254,15 @@ Foam::Istream& Foam::ISstream::read(token& t)
putback(nextC);
putback(c);
string* sPtr = new string;
if (readVariable(*sPtr).bad())
string val;
if (readVariable(val).bad())
{
delete sPtr;
t.setBad();
}
else
{
t = sPtr; // Token takes ownership
t.type() = token::tokenType::VARIABLE;
t = std::move(val); // Move contents to token
t.setType(token::tokenType::VARIABLE);
}
}
else
@ -295,7 +288,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
case '0' : case '1' : case '2' : case '3' : case '4' :
case '5' : case '6' : case '7' : case '8' : case '9' :
{
bool asLabel = (c != '.');
label labelVal = (c != '.'); // used as bool here
unsigned nChar = 0;
buf[nChar++] = c;
@ -315,9 +308,9 @@ Foam::Istream& Foam::ISstream::read(token& t)
)
)
{
if (asLabel)
if (labelVal)
{
asLabel = isdigit(c);
labelVal = isdigit(c);
}
buf[nChar++] = c;
@ -351,16 +344,15 @@ Foam::Istream& Foam::ISstream::read(token& t)
// A single '-' is punctuation
t = token::punctuationToken(token::SUBTRACT);
}
else if (labelVal && Foam::read(buf, labelVal))
{
t = labelVal;
}
else
{
label labelVal;
scalar scalarVal;
if (asLabel && Foam::read(buf, labelVal))
{
t = labelVal;
}
else if (readScalar(buf, scalarVal))
if (readScalar(buf, scalarVal))
{
// A scalar or too big to fit as a label
t = scalarVal;

View File

@ -59,7 +59,7 @@ inline Foam::ISstream& Foam::ISstream::get(char& c)
if (good() && c == '\n')
{
lineNumber_++;
++lineNumber_;
}
return *this;
@ -76,7 +76,7 @@ inline Foam::ISstream& Foam::ISstream::getLine(string& str)
{
std::getline(is_, str);
setState(is_.rdstate());
lineNumber_++;
++lineNumber_;
return *this;
}
@ -86,7 +86,7 @@ inline Foam::ISstream& Foam::ISstream::putback(const char c)
{
if (c == '\n')
{
lineNumber_--;
--lineNumber_;
}
if (!is_.putback(c))

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,24 +24,25 @@ License
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "OSstream.H"
#include "token.H"
#include "OSstream.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::OSstream::write(const token& t)
Foam::Ostream& Foam::OSstream::write(const token& tok)
{
if (t.type() == token::tokenType::VERBATIMSTRING)
if (tok.type() == token::tokenType::VERBATIMSTRING)
{
write(char(token::HASH));
write(char(token::BEGIN_BLOCK));
writeQuoted(t.stringToken(), false);
writeQuoted(tok.stringToken(), false);
write(char(token::HASH));
write(char(token::END_BLOCK));
}
else if (t.type() == token::tokenType::VARIABLE)
else if (tok.type() == token::tokenType::VARIABLE)
{
writeQuoted(t.stringToken(), false);
writeQuoted(tok.stringToken(), false);
}
return *this;
}
@ -52,7 +53,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
os_ << c;
if (c == token::NL)
{
lineNumber_++;
++lineNumber_;
}
setState(os_.rdstate());
return *this;
@ -61,7 +62,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
Foam::Ostream& Foam::OSstream::write(const char* str)
{
lineNumber_ += string(str).count(token::NL);
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
setState(os_.rdstate());
return *this;
@ -76,36 +77,51 @@ Foam::Ostream& Foam::OSstream::write(const word& str)
}
Foam::Ostream& Foam::OSstream::write(const string& str)
Foam::Ostream& Foam::OSstream::writeQuoted
(
const std::string& str,
const bool quoted
)
{
if (!quoted)
{
// Output unquoted, only advance line number on newline
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
setState(os_.rdstate());
return *this;
}
// Output with surrounding quotes and backslash escaping
os_ << token::BEGIN_STRING;
int backslash = 0;
unsigned backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
const char c = *iter;
if (c == '\\')
{
backslash++;
// suppress output until we know if other characters follow
continue;
++backslash;
continue; // only output after escaped character is known
}
else if (c == token::NL)
{
lineNumber_++;
backslash++; // backslash escape for newline
++lineNumber_;
++backslash; // backslash escape for newline
}
else if (c == token::END_STRING)
{
backslash++; // backslash escape for quote
++backslash; // backslash escape for quote
}
// output pending backslashes
// output all pending backslashes
while (backslash)
{
os_ << '\\';
backslash--;
--backslash;
}
os_ << c;
@ -113,7 +129,6 @@ Foam::Ostream& Foam::OSstream::write(const string& str)
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
os_ << token::END_STRING;
setState(os_.rdstate());
@ -121,60 +136,9 @@ Foam::Ostream& Foam::OSstream::write(const string& str)
}
Foam::Ostream& Foam::OSstream::writeQuoted
(
const std::string& str,
const bool quoted
)
Foam::Ostream& Foam::OSstream::write(const string& str)
{
if (quoted)
{
os_ << token::BEGIN_STRING;
int backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
const char c = *iter;
if (c == '\\')
{
backslash++;
// suppress output until we know if other characters follow
continue;
}
else if (c == token::NL)
{
lineNumber_++;
backslash++; // backslash escape for newline
}
else if (c == token::END_STRING)
{
backslash++; // backslash escape for quote
}
// output pending backslashes
while (backslash)
{
os_ << '\\';
backslash--;
}
os_ << c;
}
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
os_ << token::END_STRING;
}
else
{
// output unquoted string, only advance line number on newline
lineNumber_ += string(str).count(token::NL);
os_ << str;
}
setState(os_.rdstate());
return *this;
return writeQuoted(str, true);
}

View File

@ -105,7 +105,7 @@ public:
// Write functions
//- Write next token to stream
virtual Ostream& write(const token& t);
virtual Ostream& write(const token& tok);
//- Write character
virtual Ostream& write(const char c);
@ -116,7 +116,7 @@ public:
//- Write word
virtual Ostream& write(const word& str);
//- Write string
//- Write string (quoted)
// In the rare case that the string contains a final trailing
// backslash, it will be dropped to the appearance of an escaped
// double-quote.

View File

@ -65,19 +65,19 @@ void Foam::prefixOSstream::print(Ostream& os) const
}
Foam::Ostream& Foam::prefixOSstream::write(const token& t)
Foam::Ostream& Foam::prefixOSstream::write(const token& tok)
{
if (t.type() == token::tokenType::VERBATIMSTRING)
if (tok.type() == token::tokenType::VERBATIMSTRING)
{
write(char(token::HASH));
write(char(token::BEGIN_BLOCK));
writeQuoted(t.stringToken(), false);
writeQuoted(tok.stringToken(), false);
write(char(token::HASH));
write(char(token::END_BLOCK));
}
else if (t.type() == token::tokenType::VARIABLE)
else if (tok.type() == token::tokenType::VARIABLE)
{
writeQuoted(t.stringToken(), false);
writeQuoted(tok.stringToken(), false);
}
return *this;
}

View File

@ -99,7 +99,7 @@ public:
// Write functions
//- Write next token to stream
virtual Ostream& write(const token& t);
virtual Ostream& write(const token& tok);
//- Write character
virtual Ostream& write(const char c);

View File

@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,8 +25,89 @@ License
#include "error.H"
#include "ITstream.H"
#include "UIListStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ITstream::toTokenList(ISstream& is)
{
tokenIndex_ = 0;
token tok;
while (!is.read(tok).bad() && tok.good())
{
newElmt(tokenIndex()++) = std::move(tok);
}
tokenList::setSize(tokenIndex());
setOpened();
ITstream::rewind();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ITstream::ITstream
(
const string& name,
const UList<char>& input,
streamFormat format,
versionNumber version
)
:
Istream(format, version),
tokenList(16, token::undefinedToken),
name_(name),
tokenIndex_(0)
{
UIListStream is(input, format, version);
toTokenList(is);
}
Foam::ITstream::ITstream
(
const string& name,
const std::string& input,
streamFormat format,
versionNumber version
)
:
Istream(format, version),
tokenList(16, token::undefinedToken),
name_(name),
tokenIndex_(0)
{
UIListStream is(input.data(), input.size(), format, version);
toTokenList(is);
}
Foam::ITstream::ITstream
(
const string& name,
const char* input,
streamFormat format,
versionNumber version
)
:
Istream(format, version),
tokenList(16, token::undefinedToken),
name_(name),
tokenIndex_(0)
{
const size_t len = strlen(input);
UIListStream is(input, len, format, version);
toTokenList(is);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ITstream::print(Ostream& os) const
{
@ -53,19 +134,19 @@ void Foam::ITstream::print(Ostream& os) const
}
Foam::Istream& Foam::ITstream::read(token& t)
Foam::Istream& Foam::ITstream::read(token& tok)
{
// Return the put back token if it exists
if (Istream::getBack(t))
if (Istream::getBack(tok))
{
lineNumber_ = t.lineNumber();
lineNumber_ = tok.lineNumber();
return *this;
}
if (tokenIndex_ < size())
{
t = operator[](tokenIndex_++);
lineNumber_ = t.lineNumber();
tok = operator[](tokenIndex_++);
lineNumber_ = tok.lineNumber();
if (tokenIndex_ == size())
{
@ -89,15 +170,15 @@ Foam::Istream& Foam::ITstream::read(token& t)
setEof();
}
t = token::undefinedToken;
tok = token::undefinedToken;
if (size())
{
t.lineNumber() = tokenList::last().lineNumber();
tok.lineNumber() = tokenList::last().lineNumber();
}
else
{
t.lineNumber() = lineNumber();
tok.lineNumber() = lineNumber();
}
}
@ -157,6 +238,7 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
void Foam::ITstream::rewind()
{
tokenIndex_ = 0;
lineNumber_ = 0;
if (size())
{

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -43,6 +43,10 @@ SourceFiles
namespace Foam
{
// Forward declaration
class ISstream;
/*---------------------------------------------------------------------------*\
Class ITstream Declaration
\*---------------------------------------------------------------------------*/
@ -61,6 +65,12 @@ class ITstream
label tokenIndex_;
// Private Member Functions
//- Convert input sequence into tokens and append to the token list
void toTokenList(ISstream& input);
public:
// Constructors
@ -103,6 +113,39 @@ public:
}
//- Construct token list by parsing the input character sequence
// Uses UIListStream internally.
ITstream
(
const string& name,
const UList<char>& input,
streamFormat format=ASCII,
versionNumber version=currentVersion
);
//- Construct token list by parsing the input string
// Uses UIListStream internally.
ITstream
(
const string& name,
const std::string& input,
streamFormat format=ASCII,
versionNumber version=currentVersion
);
//- Construct token list by parsing the input character sequence
// Uses UIListStream internally.
ITstream
(
const string& name,
const char* input,
streamFormat format=ASCII,
versionNumber version=currentVersion
);
//- Construct as copy
ITstream(const ITstream& its)
:
@ -165,7 +208,7 @@ public:
// Read functions
//- Return next token from stream
virtual Istream& read(token& t);
virtual Istream& read(token& tok);
//- Read a character
virtual Istream& read(char&);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,14 +29,14 @@ License
namespace Foam
{
const char* const token::typeName = "token";
token token::undefinedToken;
typedef token::compound tokenCompound;
defineTypeNameAndDebug(tokenCompound, 0);
defineRunTimeSelectionTable(tokenCompound, Istream);
}
const char* const Foam::token::typeName = "token";
const Foam::token Foam::token::undefinedToken;
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
@ -94,7 +94,7 @@ Foam::token::compound& Foam::token::transferCompoundToken(const Istream& is)
{
if (type_ == tokenType::COMPOUND)
{
if (compoundTokenPtr_->empty())
if (data_.compoundPtr->empty())
{
FatalIOErrorInFunction(is)
<< "compound has already been transfered from token\n "
@ -102,16 +102,14 @@ Foam::token::compound& Foam::token::transferCompoundToken(const Istream& is)
}
else
{
compoundTokenPtr_->empty() = true;
data_.compoundPtr->empty() = true;
}
return *compoundTokenPtr_;
}
else
{
parseError("compound");
return *compoundTokenPtr_;
return *data_.compoundPtr;
}
parseError("compound");
return *data_.compoundPtr;
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,7 +25,7 @@ Class
Foam::token
Description
A token holds items read from Istream.
A token holds an item read from Istream.
SourceFiles
tokenI.H
@ -64,34 +64,40 @@ Ostream& operator<<(Ostream& os, const token& t);
/*---------------------------------------------------------------------------*\
Class token Declaration
Class token Declaration
\*---------------------------------------------------------------------------*/
class token
{
public:
//- Enumeration defining the types of token
//- Enumeration defining the types of token.
// Since these values are also used to tag content in Pstream,
// the maximum number of types is limited to 30.
enum tokenType
{
UNDEFINED,
UNDEFINED, //!< An undefined token-type
PUNCTUATION,
WORD,
VARIABLE,
STRING,
VERBATIMSTRING,
LABEL,
FLOAT_SCALAR,
DOUBLE_SCALAR,
COMPOUND,
// Fundamental types
PUNCTUATION, //!< single character punctuation
LABEL, //!< label (integer) type
FLOAT_SCALAR, //!< float (single-precision) type
DOUBLE_SCALAR, //!< double (double-precision) type
ERROR
// Pointer types
WORD, //!< Contents represent a Foam::word
STRING, //!< Contents represent a Foam::string
VARIABLE, //!< Contents are a Foam::string representing a
//!< dictionary \c $variable expansion
VERBATIMSTRING, //!< Contents are a Foam::string representing verbatim
//!< content
COMPOUND, //!< Compound type such as List\<label\> etc.
ERROR //!< A token error encountered
};
//- Standard punctuation tokens
//- Standard punctuation tokens (a character)
enum punctuationToken
{
NULL_TOKEN = '\0',
@ -99,25 +105,26 @@ public:
TAB = '\t',
NL = '\n',
END_STATEMENT = ';',
BEGIN_LIST = '(',
END_LIST = ')',
BEGIN_SQR = '[',
END_SQR = ']',
BEGIN_BLOCK = '{',
END_BLOCK = '}',
COLON = ':',
COMMA = ',',
END_STATEMENT = ';', //!< End entry [#isseparator]
BEGIN_LIST = '(', //!< Begin list [#isseparator]
END_LIST = ')', //!< End list [#isseparator]
BEGIN_SQR = '[', //!< Begin dimensions [#isseparator]
END_SQR = ']', //!< End dimensions [#isseparator]
BEGIN_BLOCK = '{', //!< Begin block [#isseparator]
END_BLOCK = '}', //!< End block [#isseparator]
COLON = ':', //!< Colon [#isseparator]
COMMA = ',', //!< Comma [#isseparator]
HASH = '#',
ATSYM = '@',
BEGIN_STRING = '"',
END_STRING = BEGIN_STRING,
ASSIGN = '=',
ADD = '+',
SUBTRACT = '-',
MULTIPLY = '*',
DIVIDE = '/'
ASSIGN = '=', //!< Assigment/equals [#isseparator]
ADD = '+', //!< Addition [#isseparator]
SUBTRACT = '-', //!< Substract or start of negative number
MULTIPLY = '*', //!< Multiply [#isseparator]
DIVIDE = '/' //!< Divide [#isseparator]
};
@ -145,7 +152,6 @@ public:
//- Runtime type information
TypeName("compound");
//- Declare run-time constructor selection table
declareRunTimeSelectionTable
(
@ -169,7 +175,7 @@ public:
// Selectors
//- Select null constructed
static autoPtr<compound> New(const word& type, Istream&);
static autoPtr<compound> New(const word& type, Istream& is);
//- Destructor
@ -178,26 +184,22 @@ public:
// Member Functions
// Access
//- Return true if name is a known compound type
static bool isCompound(const word& name);
//- Return true if name is a compound type
static bool isCompound(const word& name);
bool empty() const
{
return empty_;
}
bool empty() const
{
return empty_;
}
bool& empty()
{
return empty_;
}
bool& empty()
{
return empty_;
}
virtual label size() const = 0;
virtual label size() const = 0;
// Write
virtual void write(Ostream& os) const = 0;
virtual void write(Ostream& os) const = 0;
// IOstream Operators
@ -236,35 +238,49 @@ public:
//- Static undefined token
static token undefinedToken;
static const token undefinedToken;
private:
//- A %union of token types
union content
{
// Fundamental values. Largest first for any {} initialization.
int64_t int64Val;
int32_t int32Val;
punctuationToken punctuationVal;
label labelVal;
floatScalar floatVal;
doubleScalar doubleVal;
// Pointers
word* wordPtr;
string* stringPtr;
mutable compound* compoundPtr;
};
// Private data
//- The data content (as a union).
// For memory alignment this should appear as the first member.
content data_;
//- The token type
tokenType type_;
//- Anonymous Union of token types
union
{
punctuationToken punctuationToken_;
word* wordTokenPtr_;
string* stringTokenPtr_;
label labelToken_;
floatScalar floatScalarToken_;
doubleScalar doubleScalarToken_;
mutable compound* compoundTokenPtr_;
};
//- Line number in the file this token was read from
//- Line number in the file the token was read from
label lineNumber_;
// Private Member Functions
//- Clear any allocated storage (word or string)
//- Set as UNDEFINED and zero the union content without any checking
inline void setUndefined();
//- Clear any allocated storage (word or string) and set to UNDEFINED
inline void clear();
// Parse error, expected 'expected', found ...
@ -283,18 +299,15 @@ public:
//- Construct null
inline token();
//- Construct as copy
//- Copy construct
inline token(const token& t);
//- Move construct. The original token is left as UNDEFINED.
inline token(token&& t);
//- Construct punctuation character token
inline explicit token(punctuationToken p);
//- Construct word token
inline explicit token(const word& w);
//- Construct string token
inline explicit token(const string& str);
//- Construct label token
inline explicit token(const label val);
@ -304,16 +317,16 @@ public:
//- Construct doubleScalar token
inline explicit token(const doubleScalar val);
//- Construct word token by copying word contents
inline explicit token(const word& w);
//- Construct string token by copying string contents
inline explicit token(const string& str);
//- Construct punctuation character token
inline token(punctuationToken p, const label lineNumber);
//- Construct word token
inline token(const word& w, const label lineNumber);
//- Construct string token
inline token(const string& str, const label lineNumber);
//- Construct label token
inline token(const label val, const label lineNumber);
@ -323,6 +336,12 @@ public:
//- Construct doubleScalar token
inline token(const doubleScalar val, const label lineNumber);
//- Construct word token by copying word contents
inline token(const word& w, const label lineNumber);
//- Construct string token by copying string contents
inline token(const string& str, const label lineNumber);
//- Construct from Istream
token(Istream& is);
@ -331,108 +350,216 @@ public:
inline ~token();
// Static member functions
//- True if the character is a punctuation separator (eg, in ISstream).
// Since it could also start a number, SUBTRACT is not included as
// a separator.
//
// \param c the character to test, passed as int for consistency with
// isdigit, isspace etc.
inline static bool isseparator(int c);
// Member functions
// Access
// Status
inline tokenType type() const;
inline tokenType& type();
//- Return the name of the token type
word name() const;
inline bool good() const;
inline bool undefined() const;
inline bool error() const;
//- Return the token type
inline tokenType type() const;
inline bool isPunctuation() const;
inline punctuationToken pToken() const;
//- Change the token type, for similar types.
// This can be used to change between string-like variants
// (eg, STRING, VARIABLE, VERBATIMSTRING)
// To change types entirely (eg, STRING to DOUBLE_SCALAR),
// use the corresponding assignment operator.
//
// \return true if the change was successful or no change was required
inline bool setType(const tokenType variant);
inline bool isWord() const;
inline const word& wordToken() const;
//- The line number for the token
inline label lineNumber() const;
inline bool isVariable() const;
//- The line number for the token
inline label& lineNumber();
inline bool isString() const;
inline const string& stringToken() const;
//- True if token is not UNDEFINED or ERROR
inline bool good() const;
inline bool isLabel() const;
inline label labelToken() const;
//- True if token is UNDEFINED
inline bool undefined() const;
inline bool isFloatScalar() const;
inline floatScalar floatScalarToken() const;
//- True if token is ERROR
inline bool error() const;
inline bool isDoubleScalar() const;
inline doubleScalar doubleScalarToken() const;
//- True if token is PUNCTUATION
inline bool isPunctuation() const;
inline bool isScalar() const;
inline scalar scalarToken() const;
//- True if token is PUNCTUATION and isseparator
inline bool isSeparator() const;
inline bool isNumber() const;
inline scalar number() const;
//- True if token is LABEL
inline bool isLabel() const;
inline bool isCompound() const;
inline const compound& compoundToken() const;
compound& transferCompoundToken(const Istream& is);
//- True if token is FLOAT_SCALAR
inline bool isFloatScalar() const;
inline label lineNumber() const;
inline label& lineNumber();
//- True if token is DOUBLE_SCALAR
inline bool isDoubleScalar() const;
//- True if token is FLOAT_SCALAR or DOUBLE_SCALAR
inline bool isScalar() const;
//- True if token is LABEL, FLOAT_SCALAR or DOUBLE_SCALAR
inline bool isNumber() const;
//- True if token is WORD
inline bool isWord() const;
//- True if token is STRING, VARIABLE or VERBATIMSTRING
inline bool isString() const;
//- True if token is VARIABLE
inline bool isVariable() const;
//- True if token is COMPOUND
inline bool isCompound() const;
// Edit
// Access
//- Set bad
inline void setBad();
//- Return punctuation character.
// Report FatalIOError and return \b \\0 if token is not PUNCTUATION
inline punctuationToken pToken() const;
//- Return label value.
// Report FatalIOError and return \b 0 if token is not LABEL
inline label labelToken() const;
//- Return float value.
// Report FatalIOError and return \b 0.0 if token is not FLOAT_SCALAR
inline floatScalar floatScalarToken() const;
//- Return double value.
// Report FatalIOError and return \b 0.0 if token is not DOUBLE_SCALAR
inline doubleScalar doubleScalarToken() const;
//- Return float or double value.
// Report FatalIOError and return \b 0.0 if token is not a
// FLOAT_SCALAR or DOUBLE_SCALAR
inline scalar scalarToken() const;
//- Return label, float or double value.
// Report FatalIOError and return \b 0.0 if token is not a
// LABEL, FLOAT_SCALAR or DOUBLE_SCALAR
inline scalar number() const;
//- Return const reference to the word contents.
// Report FatalIOError and return \b "" if token is not a WORD
inline const word& wordToken() const;
//- Return const reference to the string contents.
// Report FatalIOError and return \b "" if token is not a
// STRING, VARIABLE or VERBATIMSTRING
inline const string& stringToken() const;
//- Read access for compound token
inline const compound& compoundToken() const;
//- Return reference to compound token and decrease its internal
//- refCound accordingly.
// The Istream is used for reference error messages only.
compound& transferCompoundToken(const Istream& is);
// Info
// Edit
//- Return info proxy.
// Used to print token information to a stream
InfoProxy<token> info() const
{
return *this;
}
//- Clear token and set to be in an error state.
inline void setBad();
//- Swap token contents: type, data, line-number
inline void swap(token& tok);
// Info
//- Return info proxy for printing token information to a stream
InfoProxy<token> info() const
{
return *this;
}
// Member operators
// Assignment
// Assignment
inline void operator=(const token& t);
//- Copy assign
inline void operator=(const token& tok);
inline void operator=(const punctuationToken p);
//- Move assign
inline void operator=(token&& tok);
inline void operator=(word* wPtr);
inline void operator=(const word& w);
//- Copy assign from punctuation
inline void operator=(const punctuationToken p);
inline void operator=(string* strPtr);
inline void operator=(const string& str);
//- Copy assign from label
inline void operator=(const label val);
inline void operator=(const label val);
inline void operator=(const floatScalar val);
inline void operator=(const doubleScalar val);
//- Copy assign from float
inline void operator=(const floatScalar val);
inline void operator=(compound* compPtr);
//- Copy assign from double
inline void operator=(const doubleScalar val);
//- Copy assign from word
inline void operator=(const word& w);
//- Copy assign from string
inline void operator=(const string& str);
//- Move assign from word
inline void operator=(word&& w);
//- Move assign from string
inline void operator=(string&& str);
//- Transfer word pointer to the token
// \deprecated in favour of using move assign from word
inline void operator=(word* wordPtr);
//- Transfer string pointer to the token
// \deprecated in favour of using move assign from string
inline void operator=(string* stringPtr);
//- Assign compound with reference counting to token
inline void operator=(compound* compoundPtr);
// Equality
// Equality
inline bool operator==(const token& t) const;
inline bool operator==(const punctuationToken p) const;
inline bool operator==(const word& w) const;
inline bool operator==(const string& str) const;
inline bool operator==(const label val) const;
inline bool operator==(const floatScalar val) const;
inline bool operator==(const doubleScalar val) const;
inline bool operator==(const token& t) const;
inline bool operator==(const punctuationToken p) const;
inline bool operator==(const label val) const;
inline bool operator==(const floatScalar val) const;
inline bool operator==(const doubleScalar val) const;
inline bool operator==(const word& w) const;
inline bool operator==(const string& str) const;
// Inequality
// Inequality
inline bool operator!=(const token& t) const;
inline bool operator!=(const punctuationToken p) const;
inline bool operator!=(const word& w) const;
inline bool operator!=(const string& str) const;
inline bool operator!=(const label val) const;
inline bool operator!=(const floatScalar val) const;
inline bool operator!=(const doubleScalar val) const;
inline bool operator!=(const token& t) const;
inline bool operator!=(const punctuationToken p) const;
inline bool operator!=(const label val) const;
inline bool operator!=(const floatScalar val) const;
inline bool operator!=(const doubleScalar val) const;
inline bool operator!=(const word& w) const;
inline bool operator!=(const string& str) const;
// IOstream operators

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,32 +25,129 @@ License
#include "error.H"
#include "token.H"
#include "IOstreams.H"
#include "scalar.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
template<class OS>
static OS& printTokenInfo(OS& os, const token& tok)
{
os << "on line " << tok.lineNumber() << ": ";
switch (tok.type())
{
case token::tokenType::UNDEFINED:
os << "undefined token";
break;
case token::tokenType::PUNCTUATION:
os << "punctuation '" << tok.pToken() << '\'';
break;
case token::tokenType::LABEL:
os << "label " << tok.labelToken();
break;
case token::tokenType::FLOAT_SCALAR:
os << "float " << tok.floatScalarToken();
break;
case token::tokenType::DOUBLE_SCALAR:
os << "double " << tok.doubleScalarToken();
break;
case token::tokenType::WORD:
os << "word '" << tok.wordToken() << '\'';
break;
case token::tokenType::STRING:
os << "string " << tok.stringToken();
break;
case token::tokenType::VARIABLE:
os << "variable " << tok.stringToken();
break;
case token::tokenType::VERBATIMSTRING:
os << "verbatim string " << tok.stringToken();
break;
case token::tokenType::COMPOUND:
{
if (tok.compoundToken().empty())
{
os << "empty ";
}
os << "compound of type "
<< tok.compoundToken().type();
}
break;
case token::tokenType::ERROR:
os << "error";
break;
default:
os << "unknown token type '" << int(tok.type()) << '\'';
break;
}
return os;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::token::token(Istream& is)
:
type_(tokenType::UNDEFINED)
token()
{
is.read(*this);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, token& t)
Foam::word Foam::token::name() const
{
t.clear();
return is.read(t);
switch (type_)
{
case token::tokenType::UNDEFINED: return "undefined";
case token::tokenType::PUNCTUATION: return "punctuation";
case token::tokenType::LABEL: return "label";
case token::tokenType::FLOAT_SCALAR: return "float";
case token::tokenType::DOUBLE_SCALAR: return "double";
case token::tokenType::WORD: return "word";
case token::tokenType::STRING: return "string";
case token::tokenType::VERBATIMSTRING: return "verbatim";
case token::tokenType::VARIABLE: return "variable";
case token::tokenType::COMPOUND: return "compound";
case token::tokenType::ERROR: return "error";
default:
break;
}
return "unknown(" + std::to_string(int(type_)) + ")";
}
Foam::Ostream& Foam::operator<<(Ostream& os, const token& t)
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, token& tok)
{
switch (t.type_)
tok.clear();
return is.read(tok);
}
Foam::Ostream& Foam::operator<<(Ostream& os, const token& tok)
{
switch (tok.type_)
{
case token::tokenType::UNDEFINED:
os << "UNDEFINED";
@ -59,37 +156,37 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token& t)
break;
case token::tokenType::PUNCTUATION:
os << t.punctuationToken_;
os << tok.data_.punctuationVal;
break;
case token::tokenType::LABEL:
os << tok.data_.labelVal;
break;
case token::tokenType::FLOAT_SCALAR:
os << tok.data_.floatVal;
break;
case token::tokenType::DOUBLE_SCALAR:
os << tok.data_.doubleVal;
break;
case token::tokenType::WORD:
os << *t.wordTokenPtr_;
os << *tok.data_.wordPtr;
break;
case token::tokenType::STRING:
case token::tokenType::VERBATIMSTRING:
os << *t.stringTokenPtr_;
os << *tok.data_.stringPtr;
break;
case token::tokenType::VARIABLE:
// Behaviour differs according to stream type
os.write(t);
break;
case token::tokenType::LABEL:
os << t.labelToken_;
break;
case token::tokenType::FLOAT_SCALAR:
os << t.floatScalarToken_;
break;
case token::tokenType::DOUBLE_SCALAR:
os << t.doubleScalarToken_;
os.write(tok);
break;
case token::tokenType::COMPOUND:
os << *t.compoundTokenPtr_;
os << *tok.data_.compoundPtr;
break;
case token::tokenType::ERROR:
@ -135,144 +232,14 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const token::compound& ct)
ostream& Foam::operator<<(ostream& os, const InfoProxy<token>& ip)
{
const token& t = ip.t_;
os << "on line " << t.lineNumber();
switch (t.type())
{
case token::tokenType::UNDEFINED:
os << " an undefined token";
break;
case token::tokenType::PUNCTUATION:
os << " the punctuation token " << '\'' << t.pToken() << '\'';
break;
case token::tokenType::WORD:
os << " the word " << '\'' << t.wordToken() << '\'';
break;
case token::tokenType::STRING:
os << " the string " << t.stringToken();
break;
case token::tokenType::VARIABLE:
os << " the variable " << t.stringToken();
break;
case token::tokenType::VERBATIMSTRING:
os << " the verbatim string " << t.stringToken();
break;
case token::tokenType::LABEL:
os << " the label " << t.labelToken();
break;
case token::tokenType::FLOAT_SCALAR:
os << " the floatScalar " << t.floatScalarToken();
break;
case token::tokenType::DOUBLE_SCALAR:
os << " the doubleScalar " << t.doubleScalarToken();
break;
case token::tokenType::COMPOUND:
{
if (t.compoundToken().empty())
{
os << " the empty compound of type "
<< t.compoundToken().type();
}
else
{
os << " the compound of type "
<< t.compoundToken().type();
}
}
break;
case token::tokenType::ERROR:
os << " an error";
break;
default:
os << " an unknown token type " << '\'' << int(t.type()) << '\'';
}
return os;
return printTokenInfo(os, ip.t_);
}
template<>
Foam::Ostream& Foam::operator<<(Ostream& os, const InfoProxy<token>& ip)
{
const token& t = ip.t_;
os << "on line " << t.lineNumber();
switch (t.type())
{
case token::tokenType::UNDEFINED:
os << " an undefined token";
break;
case token::tokenType::PUNCTUATION:
os << " the punctuation token " << '\'' << t.pToken() << '\'';
break;
case token::tokenType::WORD:
os << " the word " << '\'' << t.wordToken() << '\'';
break;
case token::tokenType::STRING:
os << " the string " << t.stringToken();
break;
case token::tokenType::VARIABLE:
os << " the variable " << t.stringToken();
break;
case token::tokenType::VERBATIMSTRING:
os << " the verbatim string " << t.stringToken();
break;
case token::tokenType::LABEL:
os << " the label " << t.labelToken();
break;
case token::tokenType::FLOAT_SCALAR:
os << " the floatScalar " << t.floatScalarToken();
break;
case token::tokenType::DOUBLE_SCALAR:
os << " the doubleScalar " << t.doubleScalarToken();
break;
case token::tokenType::COMPOUND:
{
if (t.compoundToken().empty())
{
os << " the empty compound of type "
<< t.compoundToken().type();
}
else
{
os << " the compound of type "
<< t.compoundToken().type();
}
}
break;
case token::tokenType::ERROR:
os << " an error";
break;
default:
os << " an unknown token type " << '\'' << int(t.type()) << '\'';
}
return os;
return printTokenInfo(os, ip.t_);
}

View File

@ -28,7 +28,6 @@ License
#include "dictionaryEntry.H"
#include "regExp.H"
#include "OSHA1stream.H"
#include "DynamicList.H"
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
@ -214,20 +213,20 @@ Foam::SHA1Digest Foam::dictionary::digest() const
Foam::tokenList Foam::dictionary::tokens() const
{
// Serialize dictionary into a string
// Serialize dictionary entries into a string
OStringStream os;
write(os, false);
IStringStream is(os.str());
// Parse string as tokens
DynamicList<token> tokens;
token t;
while (is.read(t))
// Process entries
forAllConstIter(parent_type, *this, iter)
{
tokens.append(t);
os << *iter;
}
return tokenList(tokens.xfer());
// String re-parsed as a list of tokens
return static_cast<tokenList>
(
ITstream("tokens", os.str(), os.format(), os.version())
);
}

View File

@ -58,10 +58,8 @@ Foam::label Foam::dictionaryEntry::startLineNumber() const
{
return first()->startLineNumber();
}
else
{
return -1;
}
return -1;
}
@ -71,10 +69,8 @@ Foam::label Foam::dictionaryEntry::endLineNumber() const
{
return last()->endLineNumber();
}
else
{
return -1;
}
return -1;
}

View File

@ -1,40 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ 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 "dictionaryListEntry.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dictionaryListEntry::dictionaryListEntry
(
const dictionary& parentDict,
const dictionaryListEntry& dictEnt
)
:
dictionaryEntry(parentDict, dictEnt)
{}
// ************************************************************************* //

View File

@ -44,6 +44,16 @@ static Foam::label realSize(const Foam::dictionary& dict)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dictionaryListEntry::dictionaryListEntry
(
const dictionary& parentDict,
const dictionaryListEntry& dictEnt
)
:
dictionaryEntry(parentDict, dictEnt)
{}
Foam::dictionaryListEntry::dictionaryListEntry
(
const dictionary& parentDict,

View File

@ -56,7 +56,8 @@ bool Foam::entry::getKeyword(keyType& keyword, token& keyToken, Istream& is)
keyword = keyToken.wordToken();
return true;
}
else if (keyToken.isString())
if (keyToken.isString())
{
// Enable wildcards
keyword = keyToken.stringToken();
@ -136,7 +137,8 @@ bool Foam::entry::New
{
return false;
}
else if
if
(
keyToken.isLabel()
|| (keyToken.isPunctuation() && keyToken.pToken() == token::BEGIN_LIST)
@ -162,9 +164,10 @@ bool Foam::entry::New
return false;
}
if (keyword[0] == '#')
{
// Function entry
// Function entry - #function
if (disableFunctionEntries)
{
@ -183,9 +186,11 @@ bool Foam::entry::New
const word functionName(keyword.substr(1), false);
return functionEntry::execute(functionName, parentDict, is);
}
else if (!disableFunctionEntries && keyword[0] == '$')
if (!disableFunctionEntries && keyword[0] == '$')
{
// Substitution entry
// Substitution entry - $variable
token nextToken(is);
is.putBack(nextToken);
@ -245,10 +250,10 @@ bool Foam::entry::New
return true;
}
else
{
// Normal or scoped entry
// Normal or scoped entry
{
token nextToken(is);
is.putBack(nextToken);
@ -399,11 +404,9 @@ bool Foam::entry::New
);
}
}
else
{
// Some error finding/creating intermediate dictionaries
return false;
}
// Some error finding/creating intermediate dictionaries
return false;
}
else
{

View File

@ -0,0 +1,30 @@
| directive | context | content | line oriented?
|-------------------|-------------------|-------------------|-----------------
#inputMode | dict | word
#default | dict | entry introducer
#merge | dict | entry introducer
#overwrite | dict | entry introducer
#warn | dict | entry introducer
#error | dict | entry introducer
| |
#remove | dict | readList<keyType>
| |
#include | dict/primitive | string
#includeEtc | dict/primitive | string
#includeIfPresent | dict/primitive | string
#includeFunc | dict | word
| |
#calcEntry | dict/primitive | string
#codeStream | dict/primitive | dictionary
Pending future extensions
| directive | context | content | line oriented?
|-------------------|-------------------|-------------------|-----------------
#define | dict | entry introducer
#local | dict | entry introducer
#undef | dict | readList<word>
2017-11-05

View File

@ -66,7 +66,7 @@ bool Foam::functionEntries::calcEntry::execute
Istream& is
)
{
Info<< "Using #calcEntry at line " << is.lineNumber()
Info<< "Using #calc at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity
@ -110,7 +110,7 @@ bool Foam::functionEntries::calcEntry::execute
Istream& is
)
{
Info<< "Using #calcEntry at line " << is.lineNumber()
Info<< "Using #calc at line " << is.lineNumber()
<< " in file " << parentDict.name() << endl;
dynamicCode::checkSecurity

View File

@ -160,13 +160,16 @@ bool Foam::functionEntry::execute
void Foam::functionEntry::write(Ostream& os) const
{
// Contents should be single string token
const token& t = operator[](0);
const string& s = t.stringToken();
const token& tok = operator[](0);
const string& s = tok.stringToken();
for (size_t i = 0; i < s.size(); i++)
// Write character-wise for literal output
for (size_t i = 0; i < s.size(); ++i)
{
os.write(s[i]);
}
os << nl;
}

View File

@ -30,15 +30,26 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::primitiveEntry::append(const UList<token>& varTokens)
void Foam::primitiveEntry::appendTokenList(const UList<token>& toks)
{
for (const token& tok : varTokens)
for (const token& tok : toks)
{
newElmt(tokenIndex()++) = tok;
newElmt(tokenIndex()++) = tok; // copy append
}
}
void Foam::primitiveEntry::appendTokenList(List<token>&& toks)
{
for (token& tok : toks)
{
newElmt(tokenIndex()++) = std::move(tok); // move append
}
toks.clear();
}
bool Foam::primitiveEntry::expandVariable
(
const string& varName,
@ -85,17 +96,21 @@ bool Foam::primitiveEntry::expandVariable
return false;
}
append(tokenList(IStringStream('(' + str + ')')()));
// String parsed as a list of tokens
ITstream its("env", str);
appendTokenList(std::move(static_cast<tokenList&>(its)));
}
else if (eptr->isDict())
{
// Found dictionary entry
append(eptr->dict().tokens());
tokenList toks(eptr->dict().tokens().xfer());
appendTokenList(std::move(toks));
}
else
{
// Found primitive entry
append(eptr->stream());
appendTokenList(eptr->stream());
}
return true;
@ -113,10 +128,10 @@ Foam::primitiveEntry::primitiveEntry(const keyType& key, const ITstream& is)
}
Foam::primitiveEntry::primitiveEntry(const keyType& key, const token& t)
Foam::primitiveEntry::primitiveEntry(const keyType& key, const token& tok)
:
entry(key),
ITstream(key, tokenList(1, t))
ITstream(key, tokenList(1, tok))
{}
@ -148,14 +163,12 @@ Foam::label Foam::primitiveEntry::startLineNumber() const
{
const tokenList& tokens = *this;
if (tokens.empty())
if (tokens.size())
{
return -1;
}
else
{
return tokens.first().lineNumber();
tokens.first().lineNumber();
}
return -1;
}
@ -163,14 +176,12 @@ Foam::label Foam::primitiveEntry::endLineNumber() const
{
const tokenList& tokens = *this;
if (tokens.empty())
{
return -1;
}
else
if (tokens.size())
{
return tokens.last().lineNumber();
}
return -1;
}

View File

@ -64,17 +64,24 @@ class primitiveEntry
{
// Private Member Functions
//- Append the given tokens starting at the current tokenIndex
void append(const UList<token>& varTokens);
//- Append the given token to this entry
void append
//- Test if token is acceptable after filtering for function entries
//- and variable expansions.
bool acceptToken
(
const token& currToken,
const token& tok,
const dictionary& dict,
Istream& is
);
//- Copy append the given tokens at the current tokenIndex
// No filtering on the tokens.
void appendTokenList(const UList<token>& toks);
//- Move append the given tokens at the current tokenIndex
// No filtering on the tokens.
void appendTokenList(List<token>&& toks);
//- Expand the given variable.
// The keyword starts with '$', but has been removed by the caller
// and thus passed as a varName.
@ -113,7 +120,7 @@ public:
primitiveEntry(const keyType& key, const ITstream& is);
//- Construct from keyword and a single token
primitiveEntry(const keyType& key, const token& t);
primitiveEntry(const keyType& key, const token& tok);
//- Construct from keyword and a list of tokens
primitiveEntry(const keyType& key, const UList<token>& tokens);
@ -123,7 +130,7 @@ public:
//- Construct from keyword and a T
template<class T>
primitiveEntry(const keyType& key, const T& t);
primitiveEntry(const keyType& key, const T& val);
autoPtr<entry> clone(const dictionary&) const
{

View File

@ -28,18 +28,20 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::primitiveEntry::append
bool Foam::primitiveEntry::acceptToken
(
const token& currToken,
const token& tok,
const dictionary& dict,
Istream& is
)
{
if (currToken.isWord())
{
const word& key = currToken.wordToken();
bool accept = tok.good();
if
if (tok.isWord())
{
const word& key = tok.wordToken();
accept =
(
disableFunctionEntries
|| key.size() == 1
@ -47,16 +49,13 @@ void Foam::primitiveEntry::append
!(key[0] == '$' && expandVariable(key.substr(1), dict))
&& !(key[0] == '#' && expandFunction(key.substr(1), dict, is))
)
)
{
newElmt(tokenIndex()++) = currToken;
}
);
}
else if (currToken.isVariable())
else if (tok.isVariable())
{
const string& key = currToken.stringToken();
const string& key = tok.stringToken();
if
accept =
(
disableFunctionEntries
|| key.size() <= 3
@ -65,15 +64,10 @@ void Foam::primitiveEntry::append
&& key[1] == token::BEGIN_BLOCK
&& expandVariable(key.substr(1), dict)
)
)
{
newElmt(tokenIndex()++) = currToken;
}
}
else
{
newElmt(tokenIndex()++) = currToken;
);
}
return accept;
}
@ -92,65 +86,41 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
{
is.fatalCheck(FUNCTION_NAME);
label blockCount = 0;
token currToken;
label depth = 0;
token tok;
if
while
(
!is.read(currToken).bad()
&& currToken.good()
&& currToken != token::END_STATEMENT
!is.read(tok).bad() && tok.good()
&& !(tok == token::END_STATEMENT && depth == 0)
)
{
append(currToken, dict, is);
if
(
currToken == token::BEGIN_BLOCK
|| currToken == token::BEGIN_LIST
)
if (tok.isPunctuation())
{
blockCount++;
const char c = tok.pToken();
if (c == token::BEGIN_BLOCK || c == token::BEGIN_LIST)
{
++depth;
}
else if (c == token::END_BLOCK || c == token::END_LIST)
{
--depth;
}
}
while
(
!is.read(currToken).bad()
&& currToken.good()
&& !(currToken == token::END_STATEMENT && blockCount == 0)
)
if (acceptToken(tok, dict, is))
{
if
(
currToken == token::BEGIN_BLOCK
|| currToken == token::BEGIN_LIST
)
{
blockCount++;
}
else if
(
currToken == token::END_BLOCK
|| currToken == token::END_LIST
)
{
blockCount--;
}
append(currToken, dict, is);
newElmt(tokenIndex()++) = std::move(tok);
}
// With/without move: clear any old content and force to have a
// known good token so that we can rely on it for the return value.
tok = token::punctuationToken::NULL_TOKEN;
}
is.fatalCheck(FUNCTION_NAME);
if (currToken.good())
{
return true;
}
else
{
return false;
}
return tok.good();
}
@ -227,24 +197,27 @@ void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const
os.writeKeyword(keyword());
}
bool space = false; // Separate from previous tokens with a space
for (const token& t : *this)
bool addSpace = false; // Separate from previous tokens with a space
for (const token& tok : *this)
{
if (space)
{
os << token::SPACE;
}
space = true; // Prefix any following tokens
if (t.type() == token::tokenType::VERBATIMSTRING)
if (tok.type() == token::tokenType::VERBATIMSTRING)
{
// Bypass token output operator to avoid losing verbatimness.
// Handle in Ostreams themselves
os.write(t);
// Handled in the Ostreams themselves
if (addSpace) os << token::SPACE;
os.write(tok);
addSpace = true; // Separate from following tokens
}
else
{
os << t;
if (addSpace) os << token::SPACE;
os << tok;
addSpace = true; // Separate from following tokens
}
}

View File

@ -30,13 +30,13 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
Foam::primitiveEntry::primitiveEntry(const keyType& key, const T& t)
Foam::primitiveEntry::primitiveEntry(const keyType& key, const T& val)
:
entry(key),
ITstream(key, tokenList(10))
{
OStringStream os;
os << t << token::END_STATEMENT;
os << val << token::END_STATEMENT;
readEntry(dictionary::null, IStringStream(os.str())());
}

View File

@ -36,8 +36,6 @@ See also
#ifndef refCount_H
#define refCount_H
#include "bool.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -50,20 +48,10 @@ namespace Foam
class refCount
{
// Private data
int count_;
int count_;
// Private Member Functions
//- Dissallow copy
refCount(const refCount&);
//- Dissallow bitwise assignment
void operator=(const refCount&);
protected:
public:
// Constructors
@ -74,8 +62,6 @@ protected:
{}
public:
// Member Functions
//- Return the current reference count
@ -87,7 +73,7 @@ public:
//- Return true if the reference count is zero
bool unique() const
{
return count_ == 0;
return !count_;
}
@ -96,25 +82,25 @@ public:
//- Increment the reference count
void operator++()
{
count_++;
++count_;
}
//- Increment the reference count
void operator++(int)
{
count_++;
++count_;
}
//- Decrement the reference count
void operator--()
{
count_--;
--count_;
}
//- Decrement the reference count
void operator--(int)
{
count_--;
--count_;
}
};

View File

@ -161,7 +161,7 @@ public:
//- Assignment to pointer changing this tmp to a temporary T
inline void operator=(T* tPtr);
//- Assignment transfering the temporary T to this tmp
//- Assignment transferring the temporary T to this tmp
inline void operator=(const tmp<T>& t);
};

View File

@ -359,10 +359,8 @@ std::string Foam::fileName::path(const std::string& str)
{
return str.substr(0, i);
}
else
{
return "/";
}
return "/";
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -72,7 +72,7 @@ class keyType
// Private Member Functions
//- Disallow assignments where we cannot determine string/word type
//- No assignment where we cannot determine string/word type
void operator=(const std::string&) = delete;
public:
@ -88,22 +88,34 @@ public:
//- Construct null
inline keyType();
//- Construct as copy, retaining type (literal or regex)
//- Copy construct, retaining type (literal or regex)
inline keyType(const keyType& s);
//- Construct as copy of word. Not treated as a regular expression
//- Copy construct from word. Not treated as a regular expression
inline keyType(const word& s);
//- Construct as copy of string. Treat as regular expression.
//- Copy construct from string. Treat as regular expression.
inline keyType(const string& s);
//- Construct as copy of character array.
// Not treated as a regular expression
inline keyType(const char* s);
//- Construct as copy of std::string with specified treatment
//- Copy construct from std::string with specified treatment
inline keyType(const std::string& s, const bool isPattern);
//- Move construct, retaining type (literal or regex)
inline keyType(keyType&& s);
//- Move construct from word. Not treated as a regular expression
inline keyType(word&& s);
//- Move construct from string. Treat as regular expression.
inline keyType(string&& s);
//- Move construct from std::string with specified treatment
inline keyType(std::string&& s, const bool isPattern);
//- Construct from Istream
// Treat as regular expression if surrounded by quotation marks.
keyType(Istream& is);
@ -119,6 +131,9 @@ public:
//- Treat as a pattern rather than a literal string?
inline bool isPattern() const;
//- Swap contents
inline void swap(keyType& s);
//- Smart match as regular expression or as a string.
// Optionally force a literal match only
bool match(const std::string& text, bool literal = false) const;
@ -126,27 +141,25 @@ public:
// Member operators
//- Avoid masking the normal operator()
using word::operator();
//- Perform smart match on text
inline bool operator()(const std::string& text) const;
// Assignment
//- Assignment operator, retaining type (literal or regex)
//- Copy assignment, retaining type (literal or regex)
inline void operator=(const keyType& s);
//- Assign as word, not treated as a regular expression.
inline void operator=(const word& s);
//- Assign as regular expression
//- Assign from Foam::string as regular expression
inline void operator=(const string& s);
//- Assign as word, not treated as a regular expression.
inline void operator=(const char* s);
//- Move assignment, retaining type (literal or regex)
inline void operator=(keyType&& s);
// IOstream operators

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -23,6 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#include <algorithm>
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
inline bool Foam::keyType::valid(char c)
@ -75,17 +77,44 @@ inline Foam::keyType::keyType(const char* s)
{}
inline Foam::keyType::keyType
(
const std::string& s,
const bool isPattern
)
inline Foam::keyType::keyType(const std::string& s, const bool isPattern)
:
word(s, false),
isPattern_(isPattern)
{}
inline Foam::keyType::keyType(keyType&& s)
:
word(std::move(static_cast<word&>(s)), false),
isPattern_(s.isPattern())
{
s.isPattern_ = false;
}
inline Foam::keyType::keyType(word&& s)
:
word(std::move(s), false),
isPattern_(false)
{}
inline Foam::keyType::keyType(string&& s)
:
word(std::move(s), false),
isPattern_(true)
{}
inline Foam::keyType::keyType(std::string&& s, const bool isPattern)
:
word(std::move(s), false),
isPattern_(isPattern)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::keyType::isPattern() const
@ -94,6 +123,13 @@ inline bool Foam::keyType::isPattern() const
}
inline void Foam::keyType::swap(keyType& s)
{
word::swap(static_cast<word&>(s));
std::swap(isPattern_, s.isPattern_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::keyType::operator()(const std::string& text) const
@ -104,30 +140,37 @@ inline bool Foam::keyType::operator()(const std::string& text) const
inline void Foam::keyType::operator=(const keyType& s)
{
string::operator=(s); // Bypass checking
string::operator=(s); // Bypass char checking
isPattern_ = s.isPattern_;
}
inline void Foam::keyType::operator=(const word& s)
{
string::operator=(s); // Bypass checking
string::operator=(s); // Bypass char checking
isPattern_ = false;
}
inline void Foam::keyType::operator=(const string& s)
{
string::operator=(s); // Bypass checking
string::operator=(s); // Bypass char checking
isPattern_ = true;
}
inline void Foam::keyType::operator=(const char* s)
{
string::operator=(s); // Bypass checking
string::operator=(s); // Bypass char checking
isPattern_ = false;
}
inline void Foam::keyType::operator=(keyType&& s)
{
clear();
swap(s);
}
// ************************************************************************* //

View File

@ -101,17 +101,7 @@ bool Foam::string::hasExt(const wordRe& ending) const
Foam::string::size_type Foam::string::count(const char c) const
{
size_type nChar = 0;
for (auto iter = cbegin(); iter != cend(); ++iter)
{
if (*iter == c)
{
++nChar;
}
}
return nChar;
return stringOps::count(*this, c);
}

View File

@ -153,13 +153,18 @@ public:
//- Construct from copies of a single character
inline string(const size_type len, const char c);
//- Move construct from std::string
inline string(std::string&& str);
//- Construct from Istream
string(Istream& is);
// Member Functions
//- Count and return the number of a given character in the string
//- Count the number of occurences of the specified character
//- in the string
// Partially deprecated (NOV-2017) in favour of stringOps::count
size_type count(const char c) const;
//- Does the string contain valid characters only?
@ -194,7 +199,7 @@ public:
using std::string::replace;
//- Replace first occurence of sub-string oldStr with newStr,
// beginning at start
//- beginning at start
string& replace
(
const string& oldStr,
@ -203,7 +208,7 @@ public:
);
//- Replace all occurences of sub-string oldStr with newStr,
// beginning at start. This is a no-op if oldStr is empty.
//- beginning at start. This is a no-op if oldStr is empty.
string& replaceAll
(
const string& oldStr,

View File

@ -99,6 +99,12 @@ inline Foam::string::string(const size_type len, const char c)
{}
inline Foam::string::string(std::string&& str)
:
std::string(std::move(str))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class String>

View File

@ -132,6 +132,47 @@ static inline int findParameterAlternative
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
std::string::size_type Foam::stringOps::count
(
const std::string& str,
const char c
)
{
std::string::size_type n = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
if (*iter == c)
{
++n;
}
}
return n;
}
std::string::size_type Foam::stringOps::count(const char* str, const char c)
{
if (!str)
{
return 0;
}
std::string::size_type n = 0;
for (const char *iter = str; *iter; ++iter)
{
if (*iter == c)
{
++n;
}
}
return n;
}
Foam::string Foam::stringOps::expand
(
const string& original,

View File

@ -54,6 +54,14 @@ namespace Foam
namespace stringOps
{
//- Count the number of occurences of the specified character
std::string::size_type count(const std::string& str, const char c);
//- Count the number of occurences of the specified character
// Correctly handles nullptr.
std::string::size_type count(const char* str, const char c);
//- Expand occurences of variables according to the mapping
// Expansion includes:
// -# variables

View File

@ -25,6 +25,7 @@ License
#include "word.H"
#include "debug.H"
#include <cctype>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -77,10 +78,8 @@ Foam::word Foam::word::lessExt() const
{
return *this;
}
else
{
return substr(0, i);
}
return substr(0, i);
}
@ -109,4 +108,28 @@ bool Foam::word::hasExt(const wordRe& ending) const
}
// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
Foam::word Foam::operator&(const word& a, const word& b)
{
if (a.size())
{
if (b.size())
{
// Two non-empty words: can concatenate and perform camel case
word camelCase(a + b);
camelCase[a.size()] = char(toupper(b[0]));
return camelCase;
}
return a;
}
// Or, if the first string is empty (or both are empty)
return b;
}
// ************************************************************************* //

View File

@ -31,6 +31,7 @@ Description
semicolons or brace brackets. Words are delimited by whitespace.
SourceFiles
wordI.H
word.C
wordIO.C
@ -48,7 +49,6 @@ namespace Foam
// Forward declaration of friend functions and operators
class word;
inline word operator&(const word& a, const word& b);
Istream& operator>>(Istream& is, word& w);
Ostream& operator<<(Ostream& os, const word& w);
@ -84,7 +84,7 @@ public:
//- Construct null
inline word();
//- Construct as copy
//- Copy construct
inline word(const word& w);
//- Construct as copy of character array
@ -98,12 +98,21 @@ public:
const bool doStripInvalid
);
//- Construct as copy of string
//- Construct as copy of Foam::string
inline word(const string& s, const bool doStripInvalid=true);
//- Construct as copy of std::string
inline word(const std::string& s, const bool doStripInvalid=true);
//- Move construct
inline word(word&& w);
//- Move construct from Foam::string
inline word(string&& s, const bool doStripInvalid=true);
//- Move construct from std::string
inline word(std::string&& s, const bool doStripInvalid=true);
//- Construct from Istream
word(Istream& is);
@ -149,24 +158,26 @@ public:
// Assignment
//- Copy, no character validation required
//- Copy assignment, no character validation required
inline void operator=(const word& w);
//- Copy, stripping invalid characters
//- Copy assignment from Foam::string, stripping invalid characters
inline void operator=(const string& s);
//- Copy, stripping invalid characters
//- Copy assignment from std::string, stripping invalid characters
inline void operator=(const std::string& s);
//- Copy, stripping invalid characters
inline void operator=(const char* s);
//- Move assignment
inline void operator=(word&& w);
// Friend Operators
//- Move assignment from Foam::string, stripping invalid characters
inline void operator=(string&& s);
//- Join word a and b, capitalising the first letter of b
// (so-called camelCase)
friend word operator&(const word& a, const word& b);
//- Move assignment from std::string, stripping invalid characters
inline void operator=(std::string&& s);
// IOstream operators
@ -176,6 +187,13 @@ public:
};
// Global Operators
//- Join words as camelCase, capitalizing the first letter of b.
// No effect if either argument is empty.
word operator&(const word& a, const word& b);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -111,6 +111,34 @@ inline Foam::word::word
}
inline Foam::word::word(word&& w)
:
string(std::move(w))
{}
inline Foam::word::word(string&& s, const bool doStripInvalid)
:
string(std::move(s))
{
if (doStripInvalid)
{
stripInvalid();
}
}
inline Foam::word::word(std::string&& s, const bool doStripInvalid)
:
string(std::move(s))
{
if (doStripInvalid)
{
stripInvalid();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::word::valid(char c)
@ -148,6 +176,12 @@ inline void Foam::word::operator=(const word& w)
}
inline void Foam::word::operator=(word&& w)
{
string::operator=(std::move(w));
}
inline void Foam::word::operator=(const string& s)
{
string::operator=(s);
@ -155,6 +189,13 @@ inline void Foam::word::operator=(const string& s)
}
inline void Foam::word::operator=(string&& s)
{
string::operator=(std::move(s));
stripInvalid();
}
inline void Foam::word::operator=(const std::string& s)
{
string::operator=(s);
@ -162,6 +203,13 @@ inline void Foam::word::operator=(const std::string& s)
}
inline void Foam::word::operator=(std::string&& s)
{
string::operator=(std::move(s));
stripInvalid();
}
inline void Foam::word::operator=(const char* s)
{
string::operator=(s);
@ -169,22 +217,4 @@ inline void Foam::word::operator=(const char* s)
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline Foam::word Foam::operator&(const word& a, const word& b)
{
if (b.size())
{
string ub = b;
ub.string::operator[](0) = char(toupper(ub.string::operator[](0)));
return a + ub;
}
else
{
return a;
}
}
// ************************************************************************* //

View File

@ -154,6 +154,9 @@ public:
//- Construct as copy of word, use specified compile option
inline wordRe(const word& str, const compOption);
//- Move construct
inline wordRe(wordRe&& str);
//- Construct from Istream
// Words are treated as literals, strings with an auto-test
wordRe(Istream& is);
@ -191,6 +194,9 @@ public:
//- Clear string and regular expression
inline void clear();
//- Swap contents
inline void swap(wordRe& str);
// Matching/Searching
@ -210,17 +216,11 @@ public:
// Member operators
//- Avoid masking the normal operator()
using word::operator();
//- Perform smart match on text, as per match()
inline bool operator()(const std::string& text) const;
// Assignment
//- Copy wordRe and its type (literal or regex)
// Always case sensitive
//- Copy assignment, retaining type (literal or regex)
inline void operator=(const wordRe& str);
//- Copy word, never a regular expression
@ -242,6 +242,9 @@ public:
// Always case sensitive
inline void operator=(const char* str);
//- Move assignment.
inline void operator=(wordRe&& str);
// IOstream operators

View File

@ -148,6 +148,13 @@ inline Foam::wordRe::wordRe(const word& str, const compOption opt)
}
inline Foam::wordRe::wordRe(wordRe&& str)
:
word(std::move(static_cast<word&>(str))),
re_(std::move(str.re_))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline bool Foam::wordRe::isPattern() const
@ -249,6 +256,13 @@ inline void Foam::wordRe::set(const char* str, const compOption opt)
}
inline void Foam::wordRe::swap(wordRe& str)
{
word::swap(static_cast<word&>(str));
re_.swap(str.re_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline bool Foam::wordRe::operator()(const std::string& text) const
@ -313,4 +327,11 @@ inline void Foam::wordRe::operator=(const char* str)
}
inline void Foam::wordRe::operator=(wordRe&& str)
{
clear();
swap(str);
}
// ************************************************************************* //

View File

@ -48,9 +48,10 @@ void Foam::OBJstream::writeAndCheck(const char c)
startOfLine_ = false;
if (c == 'v')
{
nVertices_++;
++nVertices_;
}
}
OFstream::write(c);
}
@ -88,9 +89,9 @@ Foam::Ostream& Foam::OBJstream::write(const char c)
Foam::Ostream& Foam::OBJstream::write(const char* str)
{
for (const char* p = str; *p != '\0'; ++p)
for (const char* iter = str; *iter; ++iter)
{
writeAndCheck(*p);
writeAndCheck(*iter);
}
return *this;
}
@ -114,54 +115,53 @@ Foam::Ostream& Foam::OBJstream::writeQuoted
const bool quoted
)
{
if (quoted)
if (!quoted)
{
OFstream::write(token::BEGIN_STRING);
int backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
const char c = *iter;
if (c == '\\')
{
backslash++;
// suppress output until we know if other characters follow
continue;
}
else if (c == token::NL)
{
lineNumber_++;
backslash++; // backslash escape for newline
}
else if (c == token::END_STRING)
{
backslash++; // backslash escape for quote
}
// output pending backslashes
while (backslash)
{
OFstream::write('\\');
backslash--;
}
writeAndCheck(c);
}
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
OFstream::write(token::END_STRING);
}
else
{
// output unquoted string, only advance line number on newline
// Output unquoted, only advance line number on newline
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
writeAndCheck(*iter);
}
return *this;
}
OFstream::write(token::BEGIN_STRING);
unsigned backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
{
const char c = *iter;
if (c == '\\')
{
++backslash;
continue; // only output after escaped character is known
}
else if (c == token::NL)
{
++lineNumber_;
++backslash; // backslash escape for newline
}
else if (c == token::END_STRING)
{
++backslash; // backslash escape for quote
}
// output all pending backslashes
while (backslash)
{
OFstream::write('\\');
--backslash;
}
writeAndCheck(c);
}
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
OFstream::write(token::END_STRING);
return *this;
}