Commit b2e05dc6 authored by Sergio Ferraris's avatar Sergio Ferraris
Browse files

Merge branch 'feature-string-parsing' into 'develop'

improve consistency in parsing primitives from strings

See merge request !146
parents 4996ac85 13f04876
Test-argList.C
EXE = $(FOAM_USER_APPBIN)/Test-argList
/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
/* EXE_LIBS = -lfiniteVolume */
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "argList.H"
#include "IOstreams.H"
#include "StringStream.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::noFunctionObjects();
argList::removeOption("case");
argList::addOption("label", "value", "Test parsing of label");
argList::addOption("scalar", "value", "Test parsing of scalar");
argList args(argc, argv);
label ival;
scalar sval;
Info<< nl;
Info<< "-label = " << flush;
if (args.optionReadIfPresent("label", ival))
{
Info<< ival << endl;
}
else
{
Info<< "not specified" << endl;
}
Info<< "-scalar = " << flush;
if (args.optionReadIfPresent("scalar", sval))
{
Info<< sval << endl;
}
else
{
Info<< "not specified" << endl;
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //
Test-primitives.C
EXE = $(FOAM_USER_APPBIN)/Test-primitives
EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude
EXE_LIBS = \
-lfileFormats
/*---------------------------------------------------------------------------*\
========= |
\\ / 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-primitives
Description
Parsing etc for primitives.
\*---------------------------------------------------------------------------*/
#include "scalar.H"
#include "label.H"
#include "StringStream.H"
#include "NASCore.H"
#include "parsing.H"
#include "Tuple2.H"
using namespace Foam;
// Shadow fileFormats::NASCore::readNasScalar
inline scalar readNasScalar(const std::string& str)
{
return fileFormats::NASCore::readNasScalar(str);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class TYPE>
unsigned testParsing
(
TYPE (*function)(const std::string&),
const List<Tuple2<std::string, bool>>& tests
)
{
unsigned nFail = 0;
// Expect some failures
const bool prev = FatalIOError.throwExceptions();
for (const Tuple2<std::string, bool>& test : tests)
{
const std::string& str = test.first();
const bool expected = test.second();
bool parsed = true;
TYPE val;
try
{
val = function (str);
}
catch (Foam::error& err)
{
parsed = false;
}
if (parsed)
{
if (expected)
{
Info<< "(pass) parsed " << str << " = " << val << nl;
}
else
{
++nFail;
Info<< "(fail) unexpected success for " << str << nl;
}
}
else
{
if (expected)
{
++nFail;
Info<< "(fail) unexpected failure " << str << nl;
}
else
{
Info<< "(pass) expected failure " << str << nl;
}
}
}
FatalIOError.throwExceptions(prev);
return nFail;
}
int main(int argc, char *argv[])
{
unsigned nFail = 0;
{
Info<< nl << "Test readDouble:" << nl;
nFail += testParsing
(
&readDouble,
{
{ "", false },
{ " ", false },
{ " xxx ", false },
{ " 1234E-", false },
{ " 1234E junk", false },
{ " 3.14159 ", true },
{ " 31.4159E-1 " , true },
}
);
}
{
Info<< nl << "Test readFloat:" << nl;
nFail += testParsing
(
&readFloat,
{
{ " 3.14159 ", true },
{ " 31.4159E-1 " , true },
{ " 31.4159E200 " , false },
{ " 31.4159E20 " , true },
}
);
}
{
Info<< nl << "Test readNasScalar:" << nl;
nFail += testParsing
(
&readNasScalar,
{
{ " 3.14159 ", true },
{ " 31.4159E-1 " , true },
{ " 314.159-2 " , true },
{ " 31.4159E200 " , true },
{ " 31.4159E20 " , true },
}
);
}
{
Info<< nl << "Test readInt32 (max= " << INT32_MAX << "):" << nl;
nFail += testParsing
(
&readInt32,
{
{ " 3.14159 ", false },
{ " 31.4159E-1 " , false },
{ "100" , true },
{ " 2147483644" , true },
{ " 2147483700 " , false },
}
);
}
{
Info<< nl << "Test readUint32 (max= " << INT32_MAX << "):" << nl;
nFail += testParsing
(
&readUint32,
{
{ " 2147483644" , true },
{ " 2147483700 " , true },
}
);
}
if (nFail)
{
Info<< nl << "failed " << nFail << " tests" << nl;
return 1;
}
Info<< nl << "passed all tests" << nl;
return 0;
}
// ************************************************************************* //
......@@ -93,8 +93,8 @@ int main(int argc, char *argv[])
const scalar scaleFactor = args.optionLookupOrDefault("scale", 1.0);
bool readBlank = !args.optionFound("noBlank");
bool singleBlock = args.optionFound("singleBlock");
const bool readBlank = !args.optionFound("noBlank");
const bool singleBlock = args.optionFound("singleBlock");
scalar twoDThickness = -1;
if (args.optionReadIfPresent("2D", twoDThickness))
{
......
......@@ -28,7 +28,7 @@ License
#include "IFstream.H"
#include "StringStream.H"
#include <inttypes.h>
#include <cinttypes>
#include <cxxabi.h>
#include <execinfo.h>
#include <dlfcn.h>
......
......@@ -114,6 +114,7 @@ $(strings)/wordRe/wordRe.C
$(strings)/wordRes/wordRes.C
$(strings)/lists/hashedWordList.C
$(strings)/stringOps/stringOps.C
$(strings)/parsing/parsing.C
ops = primitives/ops
$(ops)/flipOp.C
......
......@@ -143,7 +143,7 @@ void Foam::dimensionSet::tokeniser::splitWord(const word& w)
const word subWord = w.substr(start, i-start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readScalar(IStringStream(subWord)())));
push(token(readScalar(subWord)));
}
else
{
......@@ -154,7 +154,9 @@ void Foam::dimensionSet::tokeniser::splitWord(const word& w)
{
if (isdigit(w[i]))
{
push(token(readScalar(IStringStream(w[i])())));
// Single digit: as scalar value
const scalar val = (w[i] - '0');
push(token(val));
}
else
{
......@@ -169,7 +171,7 @@ void Foam::dimensionSet::tokeniser::splitWord(const word& w)
const word subWord = w.substr(start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readScalar(IStringStream(subWord)())));
push(token(readScalar(subWord)));
}
else
{
......@@ -539,7 +541,7 @@ Foam::Istream& Foam::dimensionSet::read
{
const word symbol = symbolPow.substr(0, index);
const word exp = symbolPow.substr(index+1);
scalar exponent = readScalar(IStringStream(exp)());
scalar exponent = readScalar(exp);
dimensionedScalar s;
s.read(readSet[symbol], readSet);
......
......@@ -281,10 +281,10 @@ public:
inline T argRead(const label index) const;
//- Return options
inline const Foam::HashTable<string>& options() const;
inline const HashTable<string>& options() const;
//- Return non-const access to options
inline Foam::HashTable<string>& options();
inline HashTable<string>& options();
//- Return the argument string associated with the named option
inline const string& option(const word& opt) const;
......@@ -302,7 +302,7 @@ public:
//- Read a value from the named option if present.
// Return true if the named option was found.
template<class T>
inline bool optionReadIfPresent(const word& opt, T&) const;
inline bool optionReadIfPresent(const word& opt, T& val) const;
//- Read a value from the named option if present.
// Return true if the named option was found, otherwise
......@@ -311,7 +311,7 @@ public:
inline bool optionReadIfPresent
(
const word& opt,
T&,
T& val,
const T& deflt
) const;
......@@ -328,7 +328,7 @@ public:
template<class T>
List<T> optionReadList(const word& opt) const
{
return readList<T>(optionLookup(opt)());
return Foam::readList<T>(optionLookup(opt)());
}
......@@ -369,7 +369,7 @@ public:
//- Add extra notes for the usage information
// This string is used "as-is" without additional formatting
static void addNote(const string&);
static void addNote(const string& note);
//- Remove option from validOptions and from optionUsage
static void removeOption(const word& opt);
......
......@@ -127,53 +127,84 @@ inline Foam::IStringStream Foam::argList::optionLookup(const word& opt) const
namespace Foam
{
// Template specialization for string
//
// Specializations for argRead
//
template<>
inline Foam::string
Foam::argList::argRead<Foam::string>(const label index) const
argList::argRead<Foam::string>(const label index) const
{
return args_[index];
}
// Template specialization for word
template<>
inline Foam::word
Foam::argList::argRead<Foam::word>(const label index) const
argList::argRead<Foam::word>(const label index) const
{
return args_[index];
}
// Template specialization for fileName
template<>
inline Foam::fileName
Foam::argList::argRead<Foam::fileName>(const label index) const
argList::argRead<Foam::fileName>(const label index) const
{
return args_[index];
}
// Template specialization for string
template<>
inline Foam::label
argList::argRead<Foam::label>(const label index) const
{
return Foam::readLabel(args_[index]);
}
template<>
inline Foam::scalar
argList::argRead<Foam::scalar>(const label index) const
{
return Foam::readScalar(args_[index]);
}
//
// Specializations for optionRead
//
template<>
inline Foam::string
Foam::argList::optionRead<Foam::string>(const word& opt) const
argList::optionRead<Foam::string>(const word& opt) const
{
return options_[opt];
}
// Template specialization for word
template<>
inline Foam::word
Foam::argList::optionRead<Foam::word>(const word& opt) const
argList::optionRead<Foam::word>(const word& opt) const
{
return options_[opt];
}
// Template specialization for fileName
template<>
inline Foam::fileName
Foam::argList::optionRead<Foam::fileName>(const word& opt) const
argList::optionRead<Foam::fileName>(const word& opt) const
{
return options_[opt];
}
template<>
inline Foam::label
argList::optionRead<Foam::label>(const word& opt) const
{
return Foam::readLabel(options_[opt]);
}
template<>
inline Foam::scalar
argList::optionRead<Foam::scalar>(const word& opt) const
{
return Foam::readScalar(options_[opt]);
}
}
......
......@@ -71,7 +71,7 @@ namespace Foam
<< exit(FatalError);
}
return readScalar(IStringStream(splitted[componentColumns_[0]])());
return readScalar(splitted[componentColumns_[0]]);
}
......@@ -80,7 +80,7 @@ namespace Foam
{
Type result;
for(label i = 0;i < pTraits<Type>::nComponents; i++)
for (label i = 0; i < pTraits<Type>::nComponents; ++i)
{
if (componentColumns_[i] >= splitted.size())
{
......@@ -90,10 +90,7 @@ namespace Foam
<< exit(FatalError);
}
result[i] = readScalar
(
IStringStream(splitted[componentColumns_[i]])()
);
result[i] = readScalar(splitted[componentColumns_[i]]);
}
return result;
......@@ -150,7 +147,7 @@ void Foam::csvTableReader<Type>::operator()
break;
}
scalar time = readScalar(IStringStream(splitted[timeColumn_])());
scalar time = readScalar(splitted[timeColumn_]);
Type value = readValue(splitted);
values.append(Tuple2<scalar,Type>(time, value));
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -42,9 +42,9 @@ const Scalar pTraits<Scalar>::rootMax = ScalarROOTVGREAT;
const char* const pTraits<Scalar>::componentNames[] = { "" };
pTraits<Scalar>::pTraits(const Scalar& p)
pTraits<Scalar>::pTraits(const Scalar& val)
:
p_(p)
p_(val)
{}
......@@ -54,7 +54,7 @@ pTraits<Scalar>::pTraits(Istream& is)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IO/Conversion * * * * * * * * * * * * * * * //
word name(const Scalar val)
{
......@@ -76,18 +76,59 @@ word name(const std::string& fmt, const Scalar val)
}
Scalar ScalarRead(const char* buf)
{
char* endptr = nullptr;
errno = 0;
const Scalar val = ScalarConvert(buf, &endptr);
const parsing::errorType err = parsing::checkConversion(buf, endptr);
if (err != parsing::errorType::NONE)
{
FatalIOErrorInFunction("unknown")
<< parsing::errorNames[err] << " '" << buf << "'"
<< exit(FatalIOError);
}
return val;
}
bool readScalar(const char* buf, Scalar& val)
{
char* endptr = nullptr;
errno = 0;
val = ScalarConvert(buf, &endptr);
const parsing::errorType err = parsing::checkConversion(buf, endptr);
if (