diff --git a/cmake/CheckBannedFunctions.cmake b/cmake/CheckBannedFunctions.cmake index 2539f28b66..9580de817c 100644 --- a/cmake/CheckBannedFunctions.cmake +++ b/cmake/CheckBannedFunctions.cmake @@ -44,7 +44,7 @@ macro(check_banned_functions) # Only error if the line does not end with //format:allow (allow spaces between // and format) # we allow this for specific cases where the format specifier is needed because the # string is shown to the user and needs to be formatted in their locale e.g. error messages - if(line MATCHES "%\\d*\\.?\\d*[fg]" AND NOT line MATCHES "format:allow") + if(line MATCHES "%[0-9]*\\.?[0-9]*[fg]" AND NOT line MATCHES "format:allow") message(FATAL_ERROR "Banned format specifier '%f' or '%g' found in ${file}") endif() endforeach() diff --git a/common/page_info.cpp b/common/page_info.cpp index d6273bacef..a4db85526f 100644 --- a/common/page_info.cpp +++ b/common/page_info.cpp @@ -26,6 +26,7 @@ #include #include #include // for OUTPUTFORMATTER and IO_ERROR +#include // late arriving wxPAPER_A0, wxPAPER_A1 @@ -280,9 +281,9 @@ void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter ) const // Internally, the page size is in mils if( GetType() == PAGE_INFO::Custom ) { - aFormatter->Print( " %g %g", - GetWidthMils() * 25.4 / 1000.0, - GetHeightMils() * 25.4 / 1000.0 ); + aFormatter->Print( " %s %s", + FormatDouble2Str( GetWidthMils() * 25.4 / 1000.0 ).c_str(), + FormatDouble2Str( GetHeightMils() * 25.4 / 1000.0 ).c_str() ); } if( !IsCustom() && IsPortrait() ) diff --git a/eeschema/erc/erc_report.cpp b/eeschema/erc/erc_report.cpp index 425d870070..c4296fe107 100644 --- a/eeschema/erc/erc_report.cpp +++ b/eeschema/erc/erc_report.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,9 @@ ERC_REPORT::ERC_REPORT( SCHEMATIC* aSchematic, EDA_UNITS aReportUnits ) : wxString ERC_REPORT::GetTextReport() { + // We need the global LOCALE_IO here in order to + // write the report in the c-locale. + LOCALE_IO locale; UNITS_PROVIDER unitsProvider( schIUScale, m_reportUnits ); wxString msg = wxString::Format( _( "ERC report (%s, Encoding UTF8)\n" ), @@ -119,6 +123,10 @@ bool ERC_REPORT::WriteTextReport( const wxString& aFullFileName ) bool ERC_REPORT::WriteJsonReport( const wxString& aFullFileName ) { + // We need the global LOCALE_IO here in order to + // write the report in the c-locale. + LOCALE_IO locale; + std::ofstream jsonFileStream( aFullFileName.fn_str() ); UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits ); diff --git a/eeschema/erc/erc_report.h b/eeschema/erc/erc_report.h index fc586b3ae2..b5096abe64 100644 --- a/eeschema/erc/erc_report.h +++ b/eeschema/erc/erc_report.h @@ -33,7 +33,7 @@ public: ERC_REPORT( SCHEMATIC* aSchematic, EDA_UNITS aReportUnits ); /** - * Returns the ERC report in "text" (human readable) format + * Returns the ERC report in "text" (human readable) format in the C-locale. * * @return The complete report */ @@ -47,7 +47,7 @@ public: bool WriteTextReport( const wxString& aFullFileName ); /** - * Writes a JSON formatted ERC Report to the given file path + * Writes a JSON formatted ERC Report to the given file path in the c-locale * * @return True if the file write completed successfully, false otherwise */ diff --git a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp index f8ef30cc52..27d05fcb8d 100644 --- a/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp +++ b/eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp @@ -989,11 +989,11 @@ void SCH_IO_KICAD_SEXPR::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSh stroke.SetWidth( aSheet->GetBorderWidth() ); stroke.Format( m_out, schIUScale ); - m_out->Print( "(fill (color %d %d %d %0.4f))", + m_out->Print( "(fill (color %d %d %d %s))", KiROUND( aSheet->GetBackgroundColor().r * 255.0 ), KiROUND( aSheet->GetBackgroundColor().g * 255.0 ), KiROUND( aSheet->GetBackgroundColor().b * 255.0 ), - aSheet->GetBackgroundColor().a ); + FormatDouble2Str( aSheet->GetBackgroundColor().a ).c_str() ); KICAD_FORMAT::FormatUuid( m_out, aSheet->m_Uuid ); diff --git a/pcbnew/board_stackup_manager/board_stackup.cpp b/pcbnew/board_stackup_manager/board_stackup.cpp index 0770dfee83..fb08d87a33 100644 --- a/pcbnew/board_stackup_manager/board_stackup.cpp +++ b/pcbnew/board_stackup_manager/board_stackup.cpp @@ -793,7 +793,7 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter, const BOARD } if( item->HasEpsilonRValue() && item->HasMaterialValue( idx ) ) - aFormatter->Print( "(epsilon_r %g)", item->GetEpsilonR( idx ) ); + aFormatter->Print( "(epsilon_r %s)", FormatDouble2Str( item->GetEpsilonR( idx ) ).c_str() ); if( item->HasLossTangentValue() && item->HasMaterialValue( idx ) ) { diff --git a/pcbnew/drc/drc_report.cpp b/pcbnew/drc/drc_report.cpp index eb39966edc..8713457355 100644 --- a/pcbnew/drc/drc_report.cpp +++ b/pcbnew/drc/drc_report.cpp @@ -24,11 +24,12 @@ #include #include "drc_report.h" #include -#include +#include #include #include #include +#include DRC_REPORT::DRC_REPORT( BOARD* aBoard, EDA_UNITS aReportUnits, std::shared_ptr aMarkersProvider, @@ -46,7 +47,10 @@ DRC_REPORT::DRC_REPORT( BOARD* aBoard, EDA_UNITS aReportUnits, bool DRC_REPORT::WriteTextReport( const wxString& aFullFileName ) { - FILE* fp = wxFopen( aFullFileName, wxT( "w" ) ); + // We need the global LOCALE_IO here in order to + // write the report in the c-locale. + LOCALE_IO locale; + FILE* fp = wxFopen( aFullFileName, wxT( "w" ) ); if( fp == nullptr ) return false; @@ -113,6 +117,9 @@ bool DRC_REPORT::WriteTextReport( const wxString& aFullFileName ) bool DRC_REPORT::WriteJsonReport( const wxString& aFullFileName ) { + // We need the global LOCALE_IO here in order to + // write the report in the c-locale. + LOCALE_IO locale; std::ofstream jsonFileStream( aFullFileName.fn_str() ); UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits ); diff --git a/pcbnew/exporters/place_file_exporter.cpp b/pcbnew/exporters/place_file_exporter.cpp index 7ba8dc7fd1..25207f3507 100644 --- a/pcbnew/exporters/place_file_exporter.cpp +++ b/pcbnew/exporters/place_file_exporter.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include class LIST_MOD // An helper class used to build a list of useful footprints. @@ -298,15 +300,11 @@ std::string PLACE_FILE_EXPORTER::GenReportData() LOCALE_IO toggle; // Generate header file comments.) - char line[1024]; - snprintf( line, sizeof(line), "## Footprint report - date %s\n", - TO_UTF8( GetISO8601CurrentDateTime() ) ); - buffer += line; + + buffer += fmt::format( "## Footprint report - date {}\n", TO_UTF8( GetISO8601CurrentDateTime() ) ); wxString Title = GetBuildVersion(); - snprintf( line, sizeof(line), "## Created by KiCad version %s\n", - TO_UTF8( Title ) ); - buffer += line; + buffer += fmt::format( "## Printed by KiCad version {}\n", TO_UTF8( Title ) ); buffer += unit_text; @@ -316,15 +314,9 @@ std::string PLACE_FILE_EXPORTER::GenReportData() buffer += "\n$BOARD\n"; - snprintf( line, sizeof(line), "upper_left_corner %9.6f %9.6f\n", + buffer += fmt::format( "upper_left_corner {:9.6f} {:9.6f}\n", bbbox.GetX() * conv_unit, bbbox.GetY() * conv_unit ); - buffer += line; - - snprintf( line, sizeof(line), "lower_right_corner %9.6f %9.6f\n", - bbbox.GetRight() * conv_unit, - bbbox.GetBottom() * conv_unit ); - buffer += line; buffer += "$EndBOARD\n\n"; @@ -344,13 +336,11 @@ std::string PLACE_FILE_EXPORTER::GenReportData() wxString ref = footprint->Reference().GetShownText( false ); wxString value = footprint->Value().GetShownText( false ); - snprintf( line, sizeof(line), "$MODULE %s\n", TO_UTF8( ref ) ); - buffer += line; + buffer += fmt::format( "$MODULE {}\n", TO_UTF8( ref ) ); - snprintf( line, sizeof(line), "reference %s\n", TO_UTF8( ref ) ); - snprintf( line, sizeof(line), "value %s\n", TO_UTF8( value ) ); - snprintf( line, sizeof(line), "footprint %s\n", footprint->GetFPID().Format().c_str() ); - buffer += line; + buffer += fmt::format( "reference {}\n", TO_UTF8( ref ) ); + buffer += fmt::format( "value {}\n", TO_UTF8( value ) ); + buffer += fmt::format( "footprint {}\n", footprint->GetFPID().Format().c_str() ); buffer += "attribut"; @@ -368,11 +358,10 @@ std::string PLACE_FILE_EXPORTER::GenReportData() VECTOR2I footprint_pos = footprint->GetPosition(); footprint_pos -= m_place_Offset; - snprintf( line, sizeof(line), "position %9.6f %9.6f orientation %.2f\n", + buffer += fmt::format( "position {:9.6f} {:9.6f} orientation {:.2f}\n", footprint_pos.x * conv_unit, footprint_pos.y * conv_unit, footprint->GetOrientation().AsDegrees() ); - buffer += line; if( footprint->GetLayer() == F_Cu ) buffer += "layer front\n"; @@ -394,8 +383,7 @@ std::string PLACE_FILE_EXPORTER::GenReportData() for( PAD* pad : sortedPads ) { - snprintf( line, sizeof(line), "$PAD \"%s\"\n", TO_UTF8( pad->GetNumber() ) ); - buffer += line; + buffer += fmt::format( "$PAD \"{}\"\n", TO_UTF8( pad->GetNumber() ) ); int layer = 0; @@ -407,34 +395,29 @@ std::string PLACE_FILE_EXPORTER::GenReportData() // TODO(JE) padstacks static const char* layer_name[4] = { "nocopper", "back", "front", "both" }; - snprintf( line, sizeof(line), "Shape %s Layer %s\n", + buffer += fmt::format( "Shape {} Layer {}\n", TO_UTF8( pad->ShowPadShape( PADSTACK::ALL_LAYERS ) ), layer_name[layer] ); - buffer += line; VECTOR2I padPos = pad->GetFPRelativePosition(); - snprintf( line, sizeof(line), "position %9.6f %9.6f size %9.6f %9.6f orientation %.2f\n", + buffer += fmt::format( "position {:9.6f} {:9.6f} size {:9.6f} {:9.6f} orientation {:.2f}\n", padPos.x * conv_unit, padPos.y * conv_unit, pad->GetSize( PADSTACK::ALL_LAYERS ).x * conv_unit, pad->GetSize( PADSTACK::ALL_LAYERS ).y * conv_unit, - ( pad->GetOrientation() - footprint->GetOrientation() ).AsDegrees() ); - buffer += line; + pad->GetOrientation().AsDegrees() ); - snprintf( line, sizeof(line), "drill %9.6f\n", pad->GetDrillSize().x * conv_unit ); - buffer += line; + buffer += fmt::format( "drill {:9.6f}\n", pad->GetDrillSize().x * conv_unit ); - snprintf( line, sizeof(line), "shape_offset %9.6f %9.6f\n", + buffer += fmt::format( "shape_offset {:9.6f} {:9.6f}\n", pad->GetOffset( PADSTACK::ALL_LAYERS ).x * conv_unit, pad->GetOffset( PADSTACK::ALL_LAYERS ).y * conv_unit ); - buffer += line; buffer += "$EndPAD\n"; } - snprintf( line, sizeof(line), "$EndMODULE %s\n\n", TO_UTF8( ref ) ); - buffer += line; + buffer += fmt::format( "$EndMODULE {}\n\n", TO_UTF8( ref ) ); } // Generate EOF. diff --git a/pcbnew/specctra_import_export/specctra.cpp b/pcbnew/specctra_import_export/specctra.cpp index a30256093d..0c5961d00e 100644 --- a/pcbnew/specctra_import_export/specctra.cpp +++ b/pcbnew/specctra_import_export/specctra.cpp @@ -55,6 +55,7 @@ #include #include +#include #include "specctra.h" #include @@ -3949,9 +3950,9 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) if( m_hasVertex ) { - out->Print( 0, " %.6f %.6f", m_vertex.x, m_vertex.y ); + out->Print( 0, " %s %s", FormatDouble2Str( m_vertex.x ).c_str(), FormatDouble2Str( m_vertex.y ).c_str() ); out->Print( 0, " %s", GetTokenText( m_side ) ); - out->Print( 0, " %.6f", m_rotation ); + out->Print( 0, " %s", FormatDouble2Str( m_rotation ).c_str() ); } const char* space = " "; // one space, as c string.