From dbed94e4b1d3a31b17a2b5c3412472718b982753 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Thu, 20 Apr 2023 23:28:32 -0400 Subject: [PATCH] Fix gerbers and drill plot not logging errors Partial fix for https://gitlab.com/kicad/code/kicad/-/issues/14437 --- pcbnew/exporters/gendrill_Excellon_writer.cpp | 8 +++- pcbnew/exporters/gendrill_Excellon_writer.h | 2 +- .../exporters/gendrill_file_writer_base.cpp | 6 ++- pcbnew/exporters/gendrill_file_writer_base.h | 2 +- pcbnew/exporters/gendrill_gerber_writer.cpp | 8 +++- pcbnew/exporters/gendrill_gerber_writer.h | 4 +- pcbnew/pcbnew_jobs_handler.cpp | 41 ++++++++++++++++--- pcbnew/pcbnew_jobs_handler.h | 10 ++++- 8 files changed, 65 insertions(+), 16 deletions(-) diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index b8bfd68c07..5d3b820575 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -73,9 +73,10 @@ EXCELLON_WRITER::EXCELLON_WRITER( BOARD* aPcb ) } -void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, +bool EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER * aReporter ) { + bool success = true; wxFileName fn; wxString msg; @@ -116,6 +117,7 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, { msg.Printf( _( "Failed to create file '%s'." ), fullFilename ); aReporter->Report( msg, RPT_SEVERITY_ERROR ); + success = false; } break; @@ -147,10 +149,12 @@ void EXCELLON_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, } if( aGenMap ) - CreateMapFilesSet( aPlotDirectory, aReporter ); + success &= CreateMapFilesSet( aPlotDirectory, aReporter ); if( aReporter ) aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); + + return success; } diff --git a/pcbnew/exporters/gendrill_Excellon_writer.h b/pcbnew/exporters/gendrill_Excellon_writer.h index 5f1ea13dc5..93be095e41 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.h +++ b/pcbnew/exporters/gendrill_Excellon_writer.h @@ -105,7 +105,7 @@ public: * @param aGenMap set to true to generate a drill map file. * @param aReporter is a #REPORTER to return activity or any message (can be NULL) */ - void CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, + bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER* aReporter = nullptr ); private: diff --git a/pcbnew/exporters/gendrill_file_writer_base.cpp b/pcbnew/exporters/gendrill_file_writer_base.cpp index b100c6605c..4722fc118c 100644 --- a/pcbnew/exporters/gendrill_file_writer_base.cpp +++ b/pcbnew/exporters/gendrill_file_writer_base.cpp @@ -297,7 +297,7 @@ const wxString GENDRILL_WRITER_BASE::getDrillFileName( DRILL_LAYER_PAIR aPair, b return ret; } -void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, +bool GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER * aReporter ) { wxFileName fn; @@ -341,7 +341,7 @@ void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, aReporter->Report( msg, RPT_SEVERITY_ERROR ); } - return; + return false; } else { @@ -353,6 +353,8 @@ void GENDRILL_WRITER_BASE::CreateMapFilesSet( const wxString& aPlotDirectory, } } } + + return true; } diff --git a/pcbnew/exporters/gendrill_file_writer_base.h b/pcbnew/exporters/gendrill_file_writer_base.h index e87d2f48d1..25c04bc62d 100644 --- a/pcbnew/exporters/gendrill_file_writer_base.h +++ b/pcbnew/exporters/gendrill_file_writer_base.h @@ -212,7 +212,7 @@ public: * @param aPlotDirectory is the output folder. * @param aReporter is a REPORTER to return activity or any message (can be NULL) */ - void CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr ); + bool CreateMapFilesSet( const wxString& aPlotDirectory, REPORTER* aReporter = nullptr ); /** * Create a plain text report file giving a list of drill values and drill count for through diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp index d4b3820245..649bc822f2 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.cpp +++ b/pcbnew/exporters/gendrill_gerber_writer.cpp @@ -54,9 +54,10 @@ GERBER_WRITER::GERBER_WRITER( BOARD* aPcb ) } -void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, +bool GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER* aReporter ) { + bool success = true; // Note: In Gerber drill files, NPTH and PTH are always separate files m_merge_PTH_NPTH = false; @@ -100,6 +101,7 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b { msg.Printf( _( "Failed to create file '%s'." ), fullFilename ); aReporter->Report( msg, RPT_SEVERITY_ERROR ); + success = false; } break; @@ -118,10 +120,12 @@ void GERBER_WRITER::CreateDrillandMapFilesSet( const wxString& aPlotDirectory, b } if( aGenMap ) - CreateMapFilesSet( aPlotDirectory, aReporter ); + success &= CreateMapFilesSet( aPlotDirectory, aReporter ); if( aReporter ) aReporter->ReportTail( _( "Done." ), RPT_SEVERITY_INFO ); + + return success; } diff --git a/pcbnew/exporters/gendrill_gerber_writer.h b/pcbnew/exporters/gendrill_gerber_writer.h index c07d829c23..9ab3dd5fee 100644 --- a/pcbnew/exporters/gendrill_gerber_writer.h +++ b/pcbnew/exporters/gendrill_gerber_writer.h @@ -74,8 +74,10 @@ public: * @param aGenDrill set to true to generate the EXCELLON drill file. * @param aGenMap set to true to generate a drill map file. * @param aReporter is a #REPORTER to return activity or any message (can be NULL). + * + * @return True if successful, false if any error occurred */ - void CreateDrillandMapFilesSet( const wxString& aPlotDirectory, + bool CreateDrillandMapFilesSet( const wxString& aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER * aReporter = nullptr ); diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 4a27f27d60..c98bf6709d 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -259,6 +259,7 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob ) int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) { + int exitCode = CLI::EXIT_CODES::OK; JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast( aJob ); if( aGerberJob == nullptr ) @@ -333,6 +334,11 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) PlotBoardLayers( brd, plotter, plotSequence, plotOpts ); plotter->EndPlot(); } + else + { + wxFprintf( stderr, _( "Failed to plot to '%s'.\n" ), fn.GetFullPath() ); + exitCode = CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } delete plotter; } @@ -342,7 +348,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob ) BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ), GerberJobFileExtension ); jobfile_writer.CreateJobFile( fn.GetFullPath() ); - return CLI::EXIT_CODES::OK; + return exitCode; } @@ -371,6 +377,7 @@ void PCBNEW_JOBS_HANDLER::populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) { + int exitCode = CLI::EXIT_CODES::OK; JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast( aJob ); if( aGerberJob == nullptr ) @@ -405,10 +412,15 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) plotOpts ); plotter->EndPlot(); } + else + { + wxFprintf( stderr, _( "Failed to plot to '%s'.\n" ), aGerberJob->m_outputFile ); + exitCode = CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } delete plotter; - return CLI::EXIT_CODES::OK; + return exitCode; } static DRILL_PRECISION precisionListForInches( 2, 4 ); @@ -498,8 +510,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute ); excellonWriter->SetMapFileFormat( mapFormat ); - excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, - aDrillJob->m_generateMap, nullptr ); + if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + aDrillJob->m_generateMap, this ) ) + { + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } } else if( aDrillJob->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER ) { @@ -515,8 +530,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob ) gerberWriter->SetOptions( offset ); gerberWriter->SetMapFileFormat( mapFormat ); - gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, - aDrillJob->m_generateMap, nullptr ); + if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true, + aDrillJob->m_generateMap, this ) ) + { + return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT; + } } return CLI::EXIT_CODES::OK; @@ -783,3 +801,14 @@ int PCBNEW_JOBS_HANDLER::doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPR return CLI::EXIT_CODES::OK; } + + +REPORTER& PCBNEW_JOBS_HANDLER::Report( const wxString& aText, SEVERITY aSeverity ) +{ + if( aSeverity == RPT_SEVERITY_ERROR ) + wxFprintf( stderr, wxS( "%s\n" ), aText ); + else + wxPrintf( wxS( "%s\n" ), aText ); + + return *this; +} \ No newline at end of file diff --git a/pcbnew/pcbnew_jobs_handler.h b/pcbnew/pcbnew_jobs_handler.h index 126ac87d78..33a45cd7cd 100644 --- a/pcbnew/pcbnew_jobs_handler.h +++ b/pcbnew/pcbnew_jobs_handler.h @@ -23,12 +23,13 @@ #include #include +#include class JOB_EXPORT_PCB_GERBER; class JOB_FP_EXPORT_SVG; class FOOTPRINT; -class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER +class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER, REPORTER { public: PCBNEW_JOBS_HANDLER(); @@ -43,6 +44,13 @@ public: int JobExportFpUpgrade( JOB* aJob ); int JobExportFpSvg( JOB* aJob ); + /* + * REPORTER INTERFACE + */ + REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override; + + bool HasMessage() const override { return false; } + private: void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts, JOB_EXPORT_PCB_GERBER* aJob );