Commit 61534989 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: simplify primitiveEntry parsing code, move append new tokens

- simplify string output code
parent c4de3e0a
......@@ -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
......
......@@ -217,7 +217,6 @@ $(dictionaryEntry)/dictionaryEntry.C
$(dictionaryEntry)/dictionaryEntryIO.C
dictionaryListEntry = $(dictionary)/dictionaryListEntry
$(dictionaryListEntry)/dictionaryListEntry.C
$(dictionaryListEntry)/dictionaryListEntryIO.C
functionEntries = $(dictionary)/functionEntries
......
......@@ -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;
......
......@@ -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
{
......
......@@ -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);
......
......@@ -164,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 :
......@@ -288,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;
......@@ -308,9 +308,9 @@ Foam::Istream& Foam::ISstream::read(token& t)
)
)
{
if (asLabel)
if (labelVal)
{
asLabel = isdigit(c);
labelVal = isdigit(c);
}
buf[nChar++] = c;
......@@ -344,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;
......
......@@ -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))
......
......@@ -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.
......@@ -28,21 +28,21 @@ License
#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;
}
......@@ -77,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;
......@@ -114,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());
......@@ -122,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_ += stringOps::count(str, token::NL);
os_ << str;
}
setState(os_.rdstate());
return *this;
return writeQuoted(str, true);
}
......
......@@ -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.
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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.
......
......@@ -134,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())
{
......@@ -170,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();
}
}
......@@ -238,6 +238,7 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
void Foam::ITstream::rewind()
{
tokenIndex_ = 0;
lineNumber_ = 0;
if (size())
{
......
......@@ -208,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&);
......
......@@ -217,14 +217,16 @@ Foam::tokenList Foam::dictionary::tokens() const
// Serialize dictionary 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))
// Parse string as tokens
token tok;
while (is.read(tok))
{
tokens.append(t);
tokens.append(std::move(tok));
}
return tokenList(tokens.xfer());
......
......@@ -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;
}
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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)
{}
// ************************************************************************* //
......@@ -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,
......
......@@ -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
);
}
}