ENH: provide word::validated() static method

- Constructs a validated word, in which all invalid characters have
  been stripped out and any leading digit is '_'-prefixed.
  Words with leading digits cause parse issues when read back later.

- Replaces previous functionally identical code from src/conversion

--
COMP: test against nullObject instead of checking address for null pointer.
This commit is contained in:
Mark Olesen
2017-02-03 15:13:13 +00:00
parent f532a99dc3
commit 9f91084eef
10 changed files with 114 additions and 201 deletions

View File

@ -69,6 +69,13 @@ int main(int argc, char *argv[])
Info<<"trimRight: " << stringOps::trimRight(test) << endl; Info<<"trimRight: " << stringOps::trimRight(test) << endl;
Info<<"trim: " << stringOps::trim(test) << endl; Info<<"trim: " << stringOps::trim(test) << endl;
Info<< nl;
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<< nl;
// test sub-strings via iterators // test sub-strings via iterators
string::const_iterator iter = test.end(); string::const_iterator iter = test.end();

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,4 +32,63 @@ const char* const Foam::word::typeName = "word";
int Foam::word::debug(Foam::debug::debugSwitch(word::typeName, 0)); int Foam::word::debug(Foam::debug::debugSwitch(word::typeName, 0));
const Foam::word Foam::word::null; const Foam::word Foam::word::null;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::word Foam::word::validated(const std::string& s)
{
std::string::size_type count = 0;
bool prefix = false;
// Count number of valid characters and detect if the first character
// happens to be a digit, which we'd like to avoid having since this
// will cause parse issues when read back later.
for (std::string::const_iterator it = s.cbegin(); it != s.cend(); ++it)
{
const char c = *it;
if (word::valid(c))
{
if (!count && isdigit(c))
{
// First valid character was a digit - prefix with '_'
prefix = true;
++count;
}
++count;
}
}
if (count == s.size() && !prefix)
{
return word(s, false); // Already checked, can just return as word
}
word out;
out.resize(count);
count = 0;
// Copy valid content.
if (prefix)
{
out[count++] = '_';
}
for (std::string::const_iterator it = s.cbegin(); it != s.cend(); ++it)
{
const char c = *it;
if (word::valid(c))
{
out[count++] = c;
}
}
out.resize(count);
return out;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -48,9 +48,9 @@ namespace Foam
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
class word; class word;
inline word operator&(const word&, const word&); inline word operator&(const word& a, const word& b);
Istream& operator>>(Istream&, word&); Istream& operator>>(Istream& is, word& w);
Ostream& operator<<(Ostream&, const word&); Ostream& operator<<(Ostream& os, const word& w);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -84,55 +84,60 @@ public:
inline word(); inline word();
//- Construct as copy //- Construct as copy
inline word(const word&); inline word(const word& w);
//- Construct as copy of character array //- Construct as copy of character array
inline word(const char*, const bool doStripInvalid=true); inline word(const char* s, const bool doStripInvalid=true);
//- Construct as copy with a maximum number of characters //- Construct as copy with a maximum number of characters
inline word inline word
( (
const char*, const char* s,
const size_type, const size_type,
const bool doStripInvalid const bool doStripInvalid
); );
//- Construct as copy of string //- Construct as copy of string
inline word(const string&, const bool doStripInvalid=true); inline word(const string& s, const bool doStripInvalid=true);
//- Construct as copy of std::string //- Construct as copy of std::string
inline word(const std::string&, const bool doStripInvalid=true); inline word(const std::string& s, const bool doStripInvalid=true);
//- Construct from Istream //- Construct from Istream
word(Istream&); word(Istream& is);
// Member functions // Member functions
//- Is this character valid for a word //- Is this character valid for a word?
inline static bool valid(char); inline static bool valid(char c);
//- Construct a validated word, in which all invalid characters have
// been stripped out and any leading digit is '_'-prefixed.
static word validated(const std::string& s);
// Member operators // Member operators
// Assignment // Assignment
inline void operator=(const word&); inline void operator=(const word& w);
inline void operator=(const string&); inline void operator=(const string& s);
inline void operator=(const std::string&); inline void operator=(const std::string& s);
inline void operator=(const char*); inline void operator=(const char* s);
// Friend Operators // Friend Operators
//- Join word a and bm capitalising first letter of b //- Join word a and b, capitalising the first letter of b
// (so-called camelCase)
friend word operator&(const word& a, const word& b); friend word operator&(const word& a, const word& b);
// IOstream operators // IOstream operators
friend Istream& operator>>(Istream&, word&); friend Istream& operator>>(Istream& is, word& w);
friend Ostream& operator<<(Ostream&, const word&); friend Ostream& operator<<(Ostream& os, const word& w);
}; };

View File

@ -31,8 +31,7 @@ License
inline void Foam::word::stripInvalid() inline void Foam::word::stripInvalid()
{ {
// skip stripping unless debug is active to avoid // skip stripping unless debug is active (to avoid costly operations)
// costly operations
if (debug && string::stripInvalid<word>(*this)) if (debug && string::stripInvalid<word>(*this))
{ {
std::cerr std::cerr
@ -132,29 +131,29 @@ inline bool Foam::word::valid(char c)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void Foam::word::operator=(const word& q) inline void Foam::word::operator=(const word& w)
{ {
string::operator=(q); string::operator=(w);
} }
inline void Foam::word::operator=(const string& q) inline void Foam::word::operator=(const string& s)
{ {
string::operator=(q); string::operator=(s);
stripInvalid(); stripInvalid();
} }
inline void Foam::word::operator=(const std::string& q) inline void Foam::word::operator=(const std::string& s)
{ {
string::operator=(q); string::operator=(s);
stripInvalid(); stripInvalid();
} }
inline void Foam::word::operator=(const char* q) inline void Foam::word::operator=(const char* s)
{ {
string::operator=(q); string::operator=(s);
stripInvalid(); stripInvalid();
} }
@ -176,6 +175,5 @@ inline Foam::word Foam::operator&(const word& a, const word& b)
} }
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -166,77 +166,6 @@ std::string Foam::ccm::reader::ccmReadOptstr
} }
Foam::word Foam::ccm::reader::validateWord
(
const std::string& str
)
{
std::string::size_type ngood = 0;
bool prefix = false;
bool first = true;
for
(
std::string::const_iterator iter = str.begin();
iter != str.end();
++iter
)
{
if (word::valid(*iter))
{
++ngood;
if (first)
{
first = false;
// Start with a digit? need to prefix with '_'
if (isdigit(*iter))
{
prefix = true;
++ngood;
}
}
}
}
if (ngood == str.size() && !prefix)
{
return str;
}
Foam::word out;
out.resize(ngood);
ngood = 0;
Foam::word::iterator iter2 = out.begin();
for
(
std::string::const_iterator iter1 = str.begin();
iter1 != str.end();
++iter1
)
{
register char c = *iter1;
if (Foam::word::valid(c))
{
if (prefix)
{
prefix = false;
*(iter2++) = '_';
++ngood;
}
*(iter2++) = c;
++ngood;
}
}
out.resize(ngood);
return out;
}
// Read map data and check error // Read map data and check error
void Foam::ccm::reader::readMap void Foam::ccm::reader::readMap
( (
@ -435,7 +364,7 @@ void Foam::ccm::reader::readProblemDescription_boundaryRegion
} }
else else
{ {
dict.add(opt, validateWord(str)); dict.add(opt, word::validated(str));
} }
} }
@ -476,7 +405,7 @@ void Foam::ccm::reader::readProblemDescription_boundaryRegion
if (!str.empty()) if (!str.empty())
{ {
dict.add(opt, validateWord(str)); dict.add(opt, word::validated(str));
} }
} }
@ -541,7 +470,7 @@ void Foam::ccm::reader::readProblemDescription_cellTable
str = "zone_" + ::Foam::name(Id); str = "zone_" + ::Foam::name(Id);
} }
dict.add(opt, validateWord(str)); dict.add(opt, word::validated(str));
} }
@ -553,7 +482,7 @@ void Foam::ccm::reader::readProblemDescription_cellTable
if (!str.empty()) if (!str.empty())
{ {
dict.add(opt, validateWord(str)); dict.add(opt, word::validated(str));
} }
} }

View File

@ -320,9 +320,6 @@ private:
// return empty string on failure // return empty string on failure
std::string ccmReadOptstr(const char* opt, ccmID node); std::string ccmReadOptstr(const char* opt, ccmID node);
//- Strip invalid characters, prefix leading digit with '_'
static word validateWord(const std::string&);
//- Read map data and check error //- Read map data and check error
void readMap(const ccmID& mapId, labelList& data); void readMap(const ccmID& mapId, labelList& data);

View File

@ -31,80 +31,6 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::word Foam::fileFormats::FIREMeshReader::validateWord
(
const std::string& str
)
{
std::string::size_type ngood = 0;
bool prefix = false;
bool first = true;
for
(
std::string::const_iterator iter = str.begin();
iter != str.end();
++iter
)
{
if (word::valid(*iter))
{
++ngood;
if (first)
{
first = false;
// start with a digit? need to prefix with '_'
if (isdigit(*iter))
{
prefix = true;
}
}
}
}
if (prefix)
{
++ngood;
}
else if (ngood == str.size())
{
return str;
}
Foam::word out;
out.resize(ngood);
ngood = 0;
Foam::word::iterator iter2 = out.begin();
for
(
std::string::const_iterator iter1 = str.begin();
iter1 != str.end();
++iter1
)
{
register char c = *iter1;
if (Foam::word::valid(c))
{
if (prefix)
{
prefix = false;
*(iter2++) = '_';
++ngood;
}
*(iter2++) = c;
++ngood;
}
}
out.resize(ngood);
return out;
}
void Foam::fileFormats::FIREMeshReader::readPoints void Foam::fileFormats::FIREMeshReader::readPoints
( (
ISstream& is, ISstream& is,
@ -229,7 +155,7 @@ void Foam::fileFormats::FIREMeshReader::readSelections(ISstream& is)
// index starting at 1 // index starting at 1
const label selId = ++nCellSelections; const label selId = ++nCellSelections;
cellTable_.setName(selId, validateWord(name)); cellTable_.setName(selId, word::validated(name));
cellTable_.setMaterial(selId, "fluid"); cellTable_.setMaterial(selId, "fluid");
for (label i = 0; i < count; ++i) for (label i = 0; i < count; ++i)
@ -244,7 +170,7 @@ void Foam::fileFormats::FIREMeshReader::readSelections(ISstream& is)
// index starting at 0 // index starting at 0
const label selId = nFaceSelections++; const label selId = nFaceSelections++;
faceNames.append(validateWord(name)); faceNames.append(word::validated(name));
for (label i = 0; i < count; ++i) for (label i = 0; i < count; ++i)
{ {

View File

@ -83,10 +83,6 @@ protected:
void operator=(const FIREMeshReader&) = delete; void operator=(const FIREMeshReader&) = delete;
//- Validate word (eg, avoid leading digits)
static word validateWord(const std::string&);
//- Read the mesh from the file(s) //- Read the mesh from the file(s)
virtual bool readGeometry(const scalar scaleFactor = 1.0); virtual bool readGeometry(const scalar scaleFactor = 1.0);

View File

@ -194,7 +194,7 @@ Foam::label Foam::checkFireEdges
thisEdge.flip(); thisEdge.flip();
} }
if (&points) if (notNull(points))
{ {
forAll(thisEdge, keyI) forAll(thisEdge, keyI)
{ {
@ -220,7 +220,7 @@ Foam::label Foam::checkFireEdges
{ {
labelList keys = strayPoints.sortedToc(); labelList keys = strayPoints.sortedToc();
if (&points) if (notNull(points))
{ {
forAll(keys, keyI) forAll(keys, keyI)
{ {
@ -257,10 +257,9 @@ Foam::label Foam::checkFireEdges
{ {
label nPoints = -1; label nPoints = -1;
if (&points) if (notNull(points))
{ {
nPoints = points.size(); nPoints = points.size();
} }
else else
{ {
@ -287,10 +286,7 @@ Foam::label Foam::checkFireEdges
} }
Foam::label Foam::checkFireEdges Foam::label Foam::checkFireEdges(const polyMesh& mesh)
(
const polyMesh& mesh
)
{ {
return checkFireEdges(mesh.faces(), mesh.pointFaces(), mesh.points()); return checkFireEdges(mesh.faces(), mesh.pointFaces(), mesh.points());
} }

View File

@ -50,9 +50,9 @@ class polyMesh;
//- check edge connectivity //- check edge connectivity
label checkFireEdges label checkFireEdges
( (
const faceList&, const faceList& faces,
const labelListList& pointFaces, const labelListList& pointFaces,
const UList<point>& = UList<point>::null() const UList<point>& points = UList<point>::null()
); );
@ -60,12 +60,12 @@ label checkFireEdges
label checkFireEdges label checkFireEdges
( (
const faceList&, const faceList&,
const UList<point>& = UList<point>::null() const UList<point>& points = UList<point>::null()
); );
//- check edge connectivity //- check edge connectivity
label checkFireEdges(const polyMesh&); label checkFireEdges(const polyMesh& mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //