ENH: improve consistency in parsing primitives from strings (issue #590)

- Any trailing whitespace when parsing from strings or character buffers
  is ignored rather than being treated as an error. This is consistent
  with behaviour when reading from an Istream and with leading whitespace
  being ignored in the underlying atof/atod, strtof/strtod... functions.

- Allow parsing directly from a std::string instead of just from a 'char*'.
  This reflects the C++11 addition of std::stod to complement the C
  functions strtod. This also makes it easier to parse string directly
  without using an IStringStream.

- Two-parameter parsing methods return success/failure.
  Eg,

      if (readInt32(str, &int32Val)) ...

- One-parameter parsing methods return the value on success or
  emit a FatalIOError.
  Eg,

      const char* buf;
      int32Val = readInt32(buf, &);

- Improved consistency when parsing unsigned ints.
  Use strtoimax and strtoumax throughout.

- Rename readDoubleScalar -> readDouble, readFloatScalar -> readFloat.
  Using the primitive name directly instead of the Foam typedef for
  better consistency with readInt32 etc.

- Clean/improve parseNasScalar.
  Handle normal numbers directly, reduce some operations.
This commit is contained in:
Mark Olesen
2017-09-18 10:47:07 +02:00
parent 61c603f174
commit accebc74ee
35 changed files with 1310 additions and 370 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,7 +24,55 @@ License
\*---------------------------------------------------------------------------*/
#include "NASCore.H"
#include "StringStream.H"
#include "parsing.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::scalar Foam::fileFormats::NASCore::readNasScalar(const string& str)
{
const auto signPos = str.find_last_of("+-");
if
(
signPos == std::string::npos
|| signPos == 0
|| str[signPos-1] == 'E' || str[signPos-1] == 'e'
|| isspace(str[signPos-1])
)
{
// A normal number format
return readScalar(str);
}
// Nastran compact number format.
// Eg, "1234-2" instead of "1234E-2"
scalar value = 0;
int exponent = 0; // Any integer
if
(
readScalar(str.substr(0, signPos), value) // Mantissa
&& readInt(str.substr(signPos), exponent) // Exponent (with sign)
)
{
// Note: this does not catch underflow/overflow
// (especially when scalar is a float)
value *= ::pow(10, exponent);
}
else
{
FatalIOErrorInFunction("unknown")
<< parsing::errorNames[parsing::errorType::GENERAL] << str
<< exit(FatalIOError);
value = 0;
}
return value;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -32,36 +80,4 @@ Foam::fileFormats::NASCore::NASCore()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::scalar Foam::fileFormats::NASCore::parseNASCoord(const string& s)
{
scalar value = 0;
const size_t expSign = s.find_last_of("+-");
if (expSign != std::string::npos && expSign > 0 && !isspace(s[expSign-1]))
{
scalar exponent = 0;
// Parse as per strtod/strtof - allowing trailing space or [Ee]
readScalar(s.substr(0, expSign).c_str(), value); // mantissa
readScalar(s.substr(expSign+1).c_str(), exponent);
if (s[expSign] == '-')
{
exponent = -exponent;
}
value *= ::pow(10, exponent);
}
else
{
readScalar(s.c_str(), value);
}
return value;
}
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -56,7 +56,14 @@ public:
// Public Member Functions
//- Extract numbers from things like "-2.358-8" (same as "-2.358e-8")
static scalar parseNASCoord(const string& s);
static scalar readNasScalar(const string& str);
//- Extract numbers from things like "-2.358-8" (same as "-2.358e-8")
// \deprecated use readNasScalar instead (deprecated Sep 2017)
inline static scalar parseNASCoord(const string& str)
{
return readNasScalar(str);
}
// Constructors