Centralize the parseDouble functions in the parsers and gcc specialcase
This commit is contained in:
parent
84138d5039
commit
c418b25756
|
@ -849,20 +849,8 @@ double DRAWING_SHEET_PARSER::parseDouble()
|
||||||
if( token != T_NUMBER )
|
if( token != T_NUMBER )
|
||||||
Expecting( T_NUMBER );
|
Expecting( T_NUMBER );
|
||||||
|
|
||||||
double dval{};
|
|
||||||
const std::string& str = CurStr();
|
|
||||||
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
return DSNLEXER::parseDouble();
|
||||||
{
|
|
||||||
wxString error;
|
|
||||||
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
|
||||||
CurSource(), CurLineNumber(), CurOffset() );
|
|
||||||
|
|
||||||
THROW_IO_ERROR( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
return dval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultDrawingSheet is the default drawing sheet using the S expr.
|
// defaultDrawingSheet is the default drawing sheet using the S expr.
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib> // bsearch()
|
#include <cstdlib> // bsearch()
|
||||||
|
@ -820,3 +820,51 @@ wxArrayString* DSNLEXER::ReadCommentLines()
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double DSNLEXER::parseDouble()
|
||||||
|
{
|
||||||
|
#if ( defined( __GNUC__ ) && __GNUC__ < 11 ) || ( defined( __clang__ ) && __clang_major__ < 13 )
|
||||||
|
// GCC older than 11 "supports" C++17 without supporting the C++17 std::from_chars for doubles
|
||||||
|
// clang is similar
|
||||||
|
|
||||||
|
char* tmp;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
double fval = strtod( CurText(), &tmp );
|
||||||
|
|
||||||
|
if( errno )
|
||||||
|
{
|
||||||
|
wxString error;
|
||||||
|
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
||||||
|
CurSource(), CurLineNumber(), CurOffset() );
|
||||||
|
|
||||||
|
THROW_IO_ERROR( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( CurText() == tmp )
|
||||||
|
{
|
||||||
|
wxString error;
|
||||||
|
error.Printf( _( "Missing floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
||||||
|
CurSource(), CurLineNumber(), CurOffset() );
|
||||||
|
|
||||||
|
THROW_IO_ERROR( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
return fval;
|
||||||
|
#else
|
||||||
|
// Use std::from_chars which is designed to be locale independent and performance oriented for data interchange
|
||||||
|
double dval{};
|
||||||
|
const std::string& str = CurStr();
|
||||||
|
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
||||||
|
|
||||||
|
if( res.ec != std::errc() )
|
||||||
|
{
|
||||||
|
THROW_PARSE_ERROR( _( "Invalid floating point number" ), CurSource(), CurLine(),
|
||||||
|
CurLineNumber(), CurOffset() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return dval;
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -316,20 +316,7 @@ double STROKE_PARAMS_PARSER::parseDouble( const char* aText )
|
||||||
if( token != T_NUMBER )
|
if( token != T_NUMBER )
|
||||||
Expecting( aText );
|
Expecting( aText );
|
||||||
|
|
||||||
double dval{};
|
return DSNLEXER::parseDouble();
|
||||||
const std::string& str = CurStr();
|
|
||||||
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
|
||||||
{
|
|
||||||
wxString error;
|
|
||||||
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
|
||||||
CurSource(), CurLineNumber(), CurOffset() );
|
|
||||||
|
|
||||||
THROW_IO_ERROR( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
return dval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -422,29 +422,6 @@ LIB_ITEM* SCH_SEXPR_PARSER::ParseDrawItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double SCH_SEXPR_PARSER::parseDouble()
|
|
||||||
{
|
|
||||||
// In case the file got saved with the wrong locale.
|
|
||||||
if( strchr( CurText(), ',' ) != nullptr )
|
|
||||||
{
|
|
||||||
THROW_PARSE_ERROR( _( "Floating point number with incorrect locale" ), CurSource(),
|
|
||||||
CurLine(), CurLineNumber(), CurOffset() );
|
|
||||||
}
|
|
||||||
|
|
||||||
double dval{};
|
|
||||||
const std::string& str = CurStr();
|
|
||||||
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
|
||||||
{
|
|
||||||
THROW_PARSE_ERROR( _( "Invalid floating point number" ), CurSource(), CurLine(),
|
|
||||||
CurLineNumber(), CurOffset() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return dval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SCH_SEXPR_PARSER::parseInternalUnits()
|
int SCH_SEXPR_PARSER::parseInternalUnits()
|
||||||
{
|
{
|
||||||
auto retval = parseDouble() * IU_PER_MM;
|
auto retval = parseDouble() * IU_PER_MM;
|
||||||
|
|
|
@ -117,26 +117,6 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
|
||||||
return parseInt();
|
return parseInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the current token as an ASCII numeric string with possible leading
|
|
||||||
* whitespace into a double precision floating point number.
|
|
||||||
*
|
|
||||||
* @throw IO_ERROR if an error occurs attempting to convert the current token.
|
|
||||||
* @return The result of the parsed token.
|
|
||||||
*/
|
|
||||||
double parseDouble();
|
|
||||||
|
|
||||||
inline double parseDouble( const char* aExpected )
|
|
||||||
{
|
|
||||||
NeedNUMBER( aExpected );
|
|
||||||
return parseDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double parseDouble( TSCHEMATIC_T::T aToken )
|
|
||||||
{
|
|
||||||
return parseDouble( GetTokenText( aToken ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
int parseInternalUnits();
|
int parseInternalUnits();
|
||||||
|
|
||||||
int parseInternalUnits( const char* aExpected );
|
int parseInternalUnits( const char* aExpected );
|
||||||
|
|
|
@ -498,6 +498,27 @@ protected:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the current token as an ASCII numeric string with possible leading
|
||||||
|
* whitespace into a double precision floating point number.
|
||||||
|
*
|
||||||
|
* @throw IO_ERROR if an error occurs attempting to convert the current token.
|
||||||
|
* @return The result of the parsed token.
|
||||||
|
*/
|
||||||
|
double parseDouble();
|
||||||
|
|
||||||
|
double parseDouble( const char* aExpected )
|
||||||
|
{
|
||||||
|
NeedNUMBER( aExpected );
|
||||||
|
return parseDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline double parseDouble( T aToken )
|
||||||
|
{
|
||||||
|
return parseDouble( GetTokenText( aToken ) );
|
||||||
|
}
|
||||||
|
|
||||||
bool iOwnReaders; ///< on readerStack, should I delete them?
|
bool iOwnReaders; ///< on readerStack, should I delete them?
|
||||||
const char* start;
|
const char* start;
|
||||||
const char* next;
|
const char* next;
|
||||||
|
|
|
@ -660,20 +660,7 @@ double PCB_PLOT_PARAMS_PARSER::parseDouble()
|
||||||
if( token != T_NUMBER )
|
if( token != T_NUMBER )
|
||||||
Expecting( T_NUMBER );
|
Expecting( T_NUMBER );
|
||||||
|
|
||||||
double dval{};
|
return DSNLEXER::parseDouble();
|
||||||
const std::string& str = CurStr();
|
|
||||||
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
|
||||||
{
|
|
||||||
wxString error;
|
|
||||||
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
|
||||||
CurSource(), CurLineNumber(), CurOffset() );
|
|
||||||
|
|
||||||
THROW_IO_ERROR( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
return dval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -175,25 +175,6 @@ void PCB_PARSER::pushValueIntoMap( int aIndex, int aValue )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double PCB_PARSER::parseDouble()
|
|
||||||
{
|
|
||||||
double dval{};
|
|
||||||
const std::string& str = CurStr();
|
|
||||||
std::from_chars_result res = std::from_chars( str.data(), str.data() + str.size(), dval );
|
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
|
||||||
{
|
|
||||||
wxString error;
|
|
||||||
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
|
||||||
CurSource(), CurLineNumber(), CurOffset() );
|
|
||||||
|
|
||||||
THROW_IO_ERROR( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
return dval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PCB_PARSER::parseBoardUnits()
|
int PCB_PARSER::parseBoardUnits()
|
||||||
{
|
{
|
||||||
// There should be no major rounding issues here, since the values in
|
// There should be no major rounding issues here, since the values in
|
||||||
|
|
|
@ -282,18 +282,6 @@ private:
|
||||||
* @return The result of the parsed token.
|
* @return The result of the parsed token.
|
||||||
* @throw IO_ERROR if an error occurs attempting to convert the current token.
|
* @throw IO_ERROR if an error occurs attempting to convert the current token.
|
||||||
*/
|
*/
|
||||||
double parseDouble();
|
|
||||||
|
|
||||||
inline double parseDouble( const char* aExpected )
|
|
||||||
{
|
|
||||||
NeedNUMBER( aExpected );
|
|
||||||
return parseDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double parseDouble( PCB_KEYS_T::T aToken )
|
|
||||||
{
|
|
||||||
return parseDouble( GetTokenText( aToken ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
int parseBoardUnits();
|
int parseBoardUnits();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue