From c418b2575691b44851f9643c0258c690cb10feac Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Sun, 14 Aug 2022 18:40:54 -0400 Subject: [PATCH] Centralize the parseDouble functions in the parsers and gcc specialcase --- common/drawing_sheet/drawing_sheet_parser.cpp | 14 +----- common/dsnlexer.cpp | 50 ++++++++++++++++++- common/stroke_params.cpp | 15 +----- .../sch_plugins/kicad/sch_sexpr_parser.cpp | 23 --------- eeschema/sch_plugins/kicad/sch_sexpr_parser.h | 20 -------- include/dsnlexer.h | 21 ++++++++ pcbnew/pcb_plot_params.cpp | 15 +----- pcbnew/plugins/kicad/pcb_parser.cpp | 19 ------- pcbnew/plugins/kicad/pcb_parser.h | 12 ----- 9 files changed, 73 insertions(+), 116 deletions(-) diff --git a/common/drawing_sheet/drawing_sheet_parser.cpp b/common/drawing_sheet/drawing_sheet_parser.cpp index 35313d0c2f..7e2bea9e50 100644 --- a/common/drawing_sheet/drawing_sheet_parser.cpp +++ b/common/drawing_sheet/drawing_sheet_parser.cpp @@ -849,20 +849,8 @@ double DRAWING_SHEET_PARSER::parseDouble() if( token != 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() ) - { - wxString error; - error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ), - CurSource(), CurLineNumber(), CurOffset() ); - - THROW_IO_ERROR( error ); - } - - return dval; + return DSNLEXER::parseDouble(); } // defaultDrawingSheet is the default drawing sheet using the S expr. diff --git a/common/dsnlexer.cpp b/common/dsnlexer.cpp index 07d533ae56..23c63070c5 100644 --- a/common/dsnlexer.cpp +++ b/common/dsnlexer.cpp @@ -23,7 +23,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - +#include #include #include #include // bsearch() @@ -820,3 +820,51 @@ wxArrayString* DSNLEXER::ReadCommentLines() 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 +} \ No newline at end of file diff --git a/common/stroke_params.cpp b/common/stroke_params.cpp index b0e0d00d57..b0fa5eb77b 100644 --- a/common/stroke_params.cpp +++ b/common/stroke_params.cpp @@ -316,20 +316,7 @@ double STROKE_PARAMS_PARSER::parseDouble( const char* aText ) if( token != T_NUMBER ) Expecting( aText ); - 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; + return DSNLEXER::parseDouble(); } diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index e2db8f2489..b65cd41b53 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -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() { auto retval = parseDouble() * IU_PER_MM; diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h index 6cde8d3012..f6de89dfbe 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h @@ -117,26 +117,6 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER 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( const char* aExpected ); diff --git a/include/dsnlexer.h b/include/dsnlexer.h index 5ac81f3dd7..2156c12e3d 100644 --- a/include/dsnlexer.h +++ b/include/dsnlexer.h @@ -498,6 +498,27 @@ protected: 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 + inline double parseDouble( T aToken ) + { + return parseDouble( GetTokenText( aToken ) ); + } + bool iOwnReaders; ///< on readerStack, should I delete them? const char* start; const char* next; diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index f8473973fe..77597a1c6e 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -660,20 +660,7 @@ double PCB_PLOT_PARAMS_PARSER::parseDouble() if( token != 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() ) - { - wxString error; - error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ), - CurSource(), CurLineNumber(), CurOffset() ); - - THROW_IO_ERROR( error ); - } - - return dval; + return DSNLEXER::parseDouble(); } diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index 4a2fab9e5e..7f05405c4d 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -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() { // There should be no major rounding issues here, since the values in diff --git a/pcbnew/plugins/kicad/pcb_parser.h b/pcbnew/plugins/kicad/pcb_parser.h index aa41b35b33..382bb600d5 100644 --- a/pcbnew/plugins/kicad/pcb_parser.h +++ b/pcbnew/plugins/kicad/pcb_parser.h @@ -282,18 +282,6 @@ private: * @return The result of the parsed 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();