Commit c2db86f0 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

Merge branch 'style-string-access' into 'develop'

Consistent use of string methods

See merge request !128
parents 17898d23 a2195d7e
......@@ -83,7 +83,8 @@ int main(int argc, char *argv[])
Info<<"camel-case => " << (word("camel") & "case") << nl;
for (const auto& s : { " text with \"spaces'", "08/15 value" })
{
Info<<"validated \"" << s << "\" => " << word::validated(s) << nl;
Info<<"validated \"" << s << "\" => "
<< word::validated(s, true) << nl;
}
Info<< nl;
......
Test-stringSplit.C
EXE = $(FOAM_USER_APPBIN)/Test-stringSplit
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
Test-stringSplit
Description
Test string splitting
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "fileName.H"
#include "stringOps.H"
using namespace Foam;
template<class String>
void printSplitting(const String& str, const char delimiter)
{
auto split = stringOps::split(str, delimiter);
Info<< "string {" << str.size() << " chars} = " << str << nl
<< split.size() << " elements {" << split.length() << " chars}"
<< nl;
unsigned i = 0;
for (const auto s : split)
{
Info<< "[" << i++ << "] {" << s.length() << " chars} = "
<< s.str() << nl;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList args(argc, argv, false, true);
if (args.size() <= 1 && args.options().empty())
{
args.printUsage();
}
for (label argi=1; argi < args.size(); ++argi)
{
printSplitting(args[argi], '/');
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
......@@ -221,6 +221,7 @@ redundantBlock {space}({comment}|{unknownPeriodicFace}|{periodicFace
endOfSection {space}")"{space}
/* balance "-quoted for editor */
/* ------------------------------------------------------------------------ *\
----- Exclusive start states -----
......@@ -693,7 +694,7 @@ endOfSection {space}")"{space}
{lbrac}{label} {
Warning
<< "Found unknown block of type: "
<< Foam::string(YYText())(1, YYLeng()-1) << nl
<< std::string(YYText()).substr(1, YYLeng()-1) << nl
<< " on line " << lineNo << endl;
yy_push_state(ignoreBlock);
......
......@@ -903,10 +903,10 @@ int main(int argc, char *argv[])
}
// Strip off anything after #
string::size_type i = rawLine.find_first_of("#");
string::size_type i = rawLine.find('#');
if (i != string::npos)
{
rawLine = rawLine(0, i);
rawLine.resize(i);
}
if (rawLine.empty())
......
......@@ -254,7 +254,7 @@ bool merge
if (key[0] == '~')
{
word eraseKey = key(1, key.size()-1);
const word eraseKey = key.substr(1);
if (thisDict.remove(eraseKey))
{
// Mark thisDict entry as having been match for wildcard
......@@ -325,7 +325,7 @@ bool merge
if (key[0] == '~')
{
word eraseKey = key(1, key.size()-1);
const word eraseKey = key.substr(1);
// List of indices into thisKeys
labelList matches
......
......@@ -88,7 +88,7 @@ static inline bool isBackupName(const Foam::fileName& name)
{
return false;
}
else if (name[name.size()-1] == '~')
else if (name.back() == '~')
{
return true;
}
......
......@@ -40,12 +40,11 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
string pOpen(const string &cmd, label line=0)
string pOpen(const string& cmd, label line=0)
{
string res = "\n";
string res;
FILE *cmdPipe = popen(cmd.c_str(), "r");
if (cmdPipe)
{
char *buf = nullptr;
......@@ -54,8 +53,7 @@ string pOpen(const string &cmd, label line=0)
for (label cnt = 0; cnt <= line; cnt++)
{
size_t linecap = 0;
ssize_t linelen;
linelen = ::getline(&buf, &linecap, cmdPipe);
ssize_t linelen = ::getline(&buf, &linecap, cmdPipe);
if (linelen < 0)
{
......@@ -65,6 +63,11 @@ string pOpen(const string &cmd, label line=0)
if (cnt == line)
{
res = string(buf);
// Trim trailing newline
if (res.size())
{
res.resize(res.size()-1);
}
break;
}
}
......@@ -77,7 +80,7 @@ string pOpen(const string &cmd, label line=0)
pclose(cmdPipe);
}
return res.substr(0, res.size() - 1);
return res;
}
......
......@@ -604,13 +604,14 @@ Foam::Istream& Foam::ISstream::readVariable(string& str)
// Read, counting brackets
buf[nChar++] = c;
// Also allow '/' between ${...} blocks for slash-scoping of entries
while
(
get(c)
&& (
c == token::BEGIN_BLOCK
|| c == token::END_BLOCK
|| word::valid(c)
|| word::valid(c) || c == '/'
)
)
{
......@@ -620,7 +621,7 @@ Foam::Istream& Foam::ISstream::readVariable(string& str)
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "word '" << buf << "...'\n"
<< "variable '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
......@@ -656,7 +657,7 @@ Foam::Istream& Foam::ISstream::readVariable(string& str)
buf[errLen] = '\0';
FatalIOErrorInFunction(*this)
<< "word '" << buf << "...'\n"
<< "variable '" << buf << "...'\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
......
......@@ -130,7 +130,7 @@ bool Foam::dictionary::read(Istream& is)
bool Foam::dictionary::substituteKeyword(const word& keyword, bool mergeEntry)
{
const word varName = keyword(1, keyword.size()-1);
const word varName = keyword.substr(1);
// Lookup the variable name in the given dictionary
const entry* ePtr = lookupEntryPtr(varName, true, true);
......
......@@ -210,7 +210,7 @@ bool Foam::functionObjectList::readFunctionObject
{
if (argLevel == 0)
{
funcName = funcNameArgs(start, i - start);
funcName = funcNameArgs.substr(start, i - start);
start = i+1;
}
++argLevel;
......@@ -226,7 +226,7 @@ bool Foam::functionObjectList::readFunctionObject
Tuple2<word, string>
(
argName,
funcNameArgs(start, i - start)
funcNameArgs.substr(start, i - start)
)
);
namedArg = false;
......@@ -235,7 +235,10 @@ bool Foam::functionObjectList::readFunctionObject
{
args.append
(
string::validate<word>(funcNameArgs(start, i - start))
string::validate<word>
(
funcNameArgs.substr(start, i - start)
)
);
}
start = i+1;
......@@ -252,7 +255,11 @@ bool Foam::functionObjectList::readFunctionObject
}
else if (c == '=')
{
argName = string::validate<word>(funcNameArgs(start, i - start));
argName = string::validate<word>
(
funcNameArgs.substr(start, i - start)
);
start = i+1;
namedArg = true;
}
......
......@@ -140,7 +140,7 @@ void Foam::dimensionSet::tokeniser::splitWord(const word& w)
{
if (i > start)
{
word subWord = w(start, i-start);
const word subWord = w.substr(start, i-start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readScalar(IStringStream(subWord)())));
......@@ -166,7 +166,7 @@ void Foam::dimensionSet::tokeniser::splitWord(const word& w)
}
if (start < w.size())
{
word subWord = w(start, w.size()-start);
const word subWord = w.substr(start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readScalar(IStringStream(subWord)())));
......@@ -524,9 +524,9 @@ Foam::Istream& Foam::dimensionSet::read
do
{
word symbolPow = nextToken.wordToken();
if (symbolPow[symbolPow.size()-1] == token::END_SQR)
if (symbolPow.back() == token::END_SQR)
{
symbolPow = symbolPow(0, symbolPow.size()-1);
symbolPow.resize(symbolPow.size()-1);
continueParsing = false;
}
......@@ -537,8 +537,8 @@ Foam::Istream& Foam::dimensionSet::read
size_t index = symbolPow.find('^');
if (index != string::npos)
{
word symbol = symbolPow(0, index);
word exp = symbolPow(index+1, symbolPow.size()-index+1);
const word symbol = symbolPow.substr(0, index);
const word exp = symbolPow.substr(index+1);
scalar exponent = readScalar(IStringStream(exp)());
dimensionedScalar s;
......@@ -580,9 +580,9 @@ Foam::Istream& Foam::dimensionSet::read
{
// Read first five dimensions
exponents_[dimensionSet::MASS] = nextToken.number();
for (int Dimension=1; Dimension<dimensionSet::CURRENT; Dimension++)
for (int d=1; d < dimensionSet::CURRENT; ++d)
{
is >> exponents_[Dimension];
is >> exponents_[d];
}
// Read next token
......
......@@ -76,16 +76,13 @@ void Foam::solution::read(const dictionary& dict)
const word& e = entryNames[i];
scalar value = readScalar(relaxDict.lookup(e));
if (e(0, 1) == "p")
if (e.startsWith("p"))
{
fieldRelaxDict_.add(e, value);
}
else if (e.length() >= 3)
else if (e.startsWith("rho"))
{
if (e(0, 3) == "rho")
{
fieldRelaxDict_.add(e, value);
}
fieldRelaxDict_.add(e, value);
}
}
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::SubStrings
Description
Sub-ranges of a string with a structure similar to std::match_results,
but without the underlying regular expression matching.
\*---------------------------------------------------------------------------*/
#ifndef SubStrings_H
#define SubStrings_H
#include <string>
#include <regex>
#include <vector>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class SubStrings Declaration
\*---------------------------------------------------------------------------*/
template<class String>
class SubStrings
:
public std::vector<std::sub_match<typename String::const_iterator>>
{
public:
// Typedefs
//- The element type
using value_type =
typename std::sub_match<typename String::const_iterator>;
//- The const_iterator for the underlying string type
using string_iterator = typename String::const_iterator;
// Constructors
//- Construct null
SubStrings()
{}
// Member Functions
//- The total length of all sub-elements.
// Use size() for the number elements.
std::string::size_type length() const
{
std::string::size_type len = 0;
for (const auto& elem : *this)
{
len += elem.length();
}
return len;
}
//- Append sub-string defined by begin/end iterators
void append(string_iterator b, string_iterator e)
{
value_type range;
range.first = b;
range.second = e;
range.matched = true;
this->push_back(range);
}
//- Const reference to the first element,
// for consistency with other OpenFOAM containers
auto first() const -> decltype(this->front())
{
return this->front();
}
//- Const reference to the last element,
// for consistency with other OpenFOAM containers
auto last() const -> decltype(this->back())
{
return this->back();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
......@@ -30,12 +30,14 @@ Description
SourceFiles
stringOps.C
stringOpsTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef stringOps_H
#define stringOps_H
#include "string.H"
#include "SubStrings.H"
#include "word.H"
#include "dictionary.H"
#include "HashTable.H"
......@@ -302,14 +304,21 @@ namespace stringOps
Foam::word name(const std::string& fmt, const PrimitiveType& val);
} // End namespace stringOps
//- Split a string into sub-strings at the delimiter character.
// An empty sub-strings are suppressed.
template<class StringType>
Foam::SubStrings<StringType> split
(
const StringType& str,
const char delimiter
);
} // End namespace stringOps
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -65,4 +65,36 @@ Foam::word Foam::stringOps::name
}
template<class StringType>
Foam::SubStrings<StringType> Foam::stringOps::split
(
const StringType& str,
const char delimiter
)
{
Foam::SubStrings<StringType> lst;
lst.reserve(20);
std::string::size_type beg = 0, end = 0;
while ((end = str.find(delimiter, beg)) != std::string::npos)
{
if (beg < end)
{
// (Non-empty) intermediate element
lst.append(str.cbegin() + beg, str.cbegin() + end);
}
beg = end + 1;
}
// (Non-empty) trailing element
if (beg < str.size())
{
lst.append(str.cbegin() + beg, str.cbegin() + str.size());
}
return lst;
}
// ************************************************************************* //
......@@ -113,9 +113,9 @@ public:
inline static bool valid(char c);
//- Construct a validated word, in which all invalid characters have
// been stripped out. Normally also prefix any leading digit
// been stripped out. Optionally prefix any leading digit
// with '_' to have words that work nicely as dictionary keywords.
static word validated(const std::string& s, const bool prefix=true);
static word validated(const std::string& s, const bool prefix=false);
// File-like functions
......
......@@ -34,16 +34,15 @@ Foam::autoPtr<Foam::reactionRateFlameArea> Foam::reactionRateFlameArea::New
const combustionModel& combModel
)
{
word reactionRateFlameAreaType
const word modelType
(
dict.lookup("reactionRateFlameArea")
);