From f357e79f7781196940520c8d628d3daa230b5c1e Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Thu, 31 Aug 2023 21:45:51 -0400 Subject: [PATCH] Add --define-var / -D to the cli opts for some commands Fixes https://gitlab.com/kicad/code/kicad/-/issues/15437 --- common/jobs/job.h | 20 ++++++++++++-- common/project.cpp | 15 ++++++++++ eeschema/eeschema_jobs_handler.cpp | 5 +++- eeschema/eeschema_jobs_handler.h | 1 + include/project.h | 5 ++++ kicad/cli/command.cpp | 35 ++++++++++++++++++++++++ kicad/cli/command.h | 17 ++++++++++++ kicad/cli/command_fp_export_svg.cpp | 2 ++ kicad/cli/command_pcb_drc.cpp | 6 ++-- kicad/cli/command_pcb_export_3d.cpp | 2 ++ kicad/cli/command_pcb_export_dxf.cpp | 2 ++ kicad/cli/command_pcb_export_gerber.cpp | 2 ++ kicad/cli/command_pcb_export_gerbers.cpp | 1 + kicad/cli/command_pcb_export_pdf.cpp | 2 ++ kicad/cli/command_pcb_export_svg.cpp | 2 ++ kicad/cli/command_sch_erc.cpp | 6 ++-- kicad/cli/command_sch_export_plot.cpp | 2 ++ pcbnew/pcbnew_jobs_handler.cpp | 7 +++++ 18 files changed, 121 insertions(+), 11 deletions(-) diff --git a/common/jobs/job.h b/common/jobs/job.h index 996b217211..8b13a44826 100644 --- a/common/jobs/job.h +++ b/common/jobs/job.h @@ -21,22 +21,38 @@ #ifndef JOB_H #define JOB_H +#include +#include + /** * An simple container class that lets us dispatch output jobs to kifaces */ class JOB { public: - JOB( const std::string& aType, bool aIsCli ) : m_type( aType ), m_isCli( aIsCli ) {} + JOB( const std::string& aType, bool aIsCli ) : + m_type( aType ), + m_isCli( aIsCli ), + m_varOverrides() + { + } virtual ~JOB() {} const std::string& GetType() const { return m_type; }; bool IsCli() const { return m_isCli; }; -private: + const std::map& GetVarOverrides() const { return m_varOverrides; } + + void SetVarOverrides( const std::map& aVarOverrides ) + { + m_varOverrides = aVarOverrides; + } + +protected: std::string m_type; bool m_isCli; + std::map m_varOverrides; }; #endif \ No newline at end of file diff --git a/common/project.cpp b/common/project.cpp index 2e517ad781..d0f56ad222 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -85,6 +85,21 @@ std::map& PROJECT::GetTextVars() const } +void PROJECT::ApplyTextVars( const std::map& aVarsMap ) +{ + if( aVarsMap.size() == 0 ) + return; + + std::map& existingVarsMap = GetTextVars(); + + for( const auto& var : aVarsMap ) + { + // create or update the existing vars + existingVarsMap[var.first] = var.second; + } +} + + void PROJECT::setProjectFullName( const wxString& aFullPathAndName ) { // Compare paths, rather than inodes, to be less surprising to the user. diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index 25b28f6b6d..bc5f85d5d0 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -134,6 +134,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportPlot( JOB* aJob ) return CLI::EXIT_CODES::ERR_UNKNOWN; SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aPlotJob->m_filename, SCH_IO_MGR::SCH_KICAD ); + sch->Prj().ApplyTextVars( aJob->GetVarOverrides() ); if( sch == nullptr ) { @@ -266,6 +267,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportBom( JOB* aJob ) return CLI::EXIT_CODES::ERR_UNKNOWN; SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aBomJob->m_filename, SCH_IO_MGR::SCH_KICAD ); + sch->Prj().ApplyTextVars( aJob->GetVarOverrides() ); if( sch == nullptr ) { @@ -739,6 +741,7 @@ int EESCHEMA_JOBS_HANDLER::JobSchErc( JOB* aJob ) return CLI::EXIT_CODES::ERR_UNKNOWN; SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( ercJob->m_filename, SCH_IO_MGR::SCH_KICAD ); + sch->Prj().ApplyTextVars( aJob->GetVarOverrides() ); if( sch == nullptr ) { @@ -838,4 +841,4 @@ DS_PROXY_VIEW_ITEM* EESCHEMA_JOBS_HANDLER::getDrawingSheetProxyView( SCHEMATIC* drawingSheet->SetSheetPath( "" ); return drawingSheet; -} +} \ No newline at end of file diff --git a/eeschema/eeschema_jobs_handler.h b/eeschema/eeschema_jobs_handler.h index d2c6bc9f2d..9a4dfa11d1 100644 --- a/eeschema/eeschema_jobs_handler.h +++ b/eeschema/eeschema_jobs_handler.h @@ -62,6 +62,7 @@ public: SCHEMATIC* aSch, const wxString& aDrawingSheetOverride = wxEmptyString ); private: + int doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob, KIGFX::SCH_RENDER_SETTINGS* aRenderSettings, LIB_SYMBOL* symbol ); diff --git a/include/project.h b/include/project.h index 73b90a38c7..0fd2eceb28 100644 --- a/include/project.h +++ b/include/project.h @@ -88,6 +88,11 @@ public: virtual std::map& GetTextVars() const; + /** + * Applies the given var map, it will create or update existing vars + */ + virtual void ApplyTextVars( const std::map& aVarsMap ); + /** * Return the full path and name of the project. * diff --git a/kicad/cli/command.cpp b/kicad/cli/command.cpp index 4b7e8099c4..68fc79840b 100644 --- a/kicad/cli/command.cpp +++ b/kicad/cli/command.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -70,6 +71,28 @@ int CLI::COMMAND::Perform( KIWAY& aKiway ) m_argDrawingSheet = FROM_UTF8( m_argParser.get( ARG_DRAWING_SHEET ).c_str() ); } + + if( m_hasDefineArg ) + { + auto defines = m_argParser.get>( ARG_DEFINE_VAR_LONG ); + + for( const std::string& def : defines ) + { + wxString str = FROM_UTF8( def.c_str() ); + wxArrayString bits; + wxStringSplit( str, bits, wxS( '=' ) ); + + if( bits.Count() == 2 ) + { + m_argDefineVars[bits[0]] = bits[1]; + } + else + { + return EXIT_CODES::ERR_ARGS; + } + } + } + return doPerform( aKiway ); } @@ -119,4 +142,16 @@ void CLI::COMMAND::addDrawingSheetArg() m_argParser.add_argument( ARG_DRAWING_SHEET ) .default_value( std::string() ) .help( UTF8STDSTR( _( "Path to drawing sheet, this overrides any existing project defined sheet when used" ) ) ); +} + + +void CLI::COMMAND::addDefineArg() +{ + m_hasDefineArg = true; + + m_argParser.add_argument( ARG_DEFINE_VAR_LONG, ARG_DEFINE_VAR_SHORT ) + .default_value( std::vector() ) + .help( UTF8STDSTR( + _( "Overrides or adds project variables, can be used multiple times to declare " + "multiple variables. Use in the format of '--define-var key=value'" ) ) ); } \ No newline at end of file diff --git a/kicad/cli/command.h b/kicad/cli/command.h index 3b97a6f39d..52b02e4f11 100644 --- a/kicad/cli/command.h +++ b/kicad/cli/command.h @@ -33,6 +33,8 @@ #define ARG_OUTPUT "--output" #define ARG_INPUT "input" #define ARG_DRAWING_SHEET "--drawing-sheet" +#define ARG_DEFINE_VAR_SHORT "-D" +#define ARG_DEFINE_VAR_LONG "--define-var" namespace CLI { @@ -74,6 +76,11 @@ protected: */ void addDrawingSheetArg(); + /** + * Sets up the drawing sheet arg used by many of the export commands + */ + void addDefineArg(); + /** * The internal handler that should be overloaded to implement command specific * processing and work. @@ -104,6 +111,11 @@ protected: */ bool m_hasDrawingSheetArg; + /** + * Whether or not the input arg was added for parsing + */ + bool m_hasDefineArg; + /** * Whether or not the output arg is expecting a directory */ @@ -123,6 +135,11 @@ protected: * Value of the drawing sheet arg if configured */ wxString m_argDrawingSheet; + + /** + * Value of the drawing sheet arg if configured + */ + std::map m_argDefineVars; }; } diff --git a/kicad/cli/command_fp_export_svg.cpp b/kicad/cli/command_fp_export_svg.cpp index 93130dbaa0..41aca8b552 100644 --- a/kicad/cli/command_fp_export_svg.cpp +++ b/kicad/cli/command_fp_export_svg.cpp @@ -36,6 +36,7 @@ CLI::FP_EXPORT_SVG_COMMAND::FP_EXPORT_SVG_COMMAND() : PCB_EXPORT_BASE_COMMAND( " m_argParser.add_description( UTF8STDSTR( _( "Exports the footprint or entire footprint library to SVG" ) ) ); addLayerArg( false ); + addDefineArg(); m_argParser.add_argument( "-t", ARG_THEME ) .default_value( std::string() ) @@ -64,6 +65,7 @@ int CLI::FP_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway ) svgJob->m_outputDirectory = m_argOutput; svgJob->m_blackAndWhite = m_argParser.get( ARG_BLACKANDWHITE ); svgJob->m_footprint = FROM_UTF8( m_argParser.get( ARG_FOOTPRINT ).c_str() ); + svgJob->SetVarOverrides( m_argDefineVars ); if( !wxDir::Exists( svgJob->m_libraryPath ) ) { diff --git a/kicad/cli/command_pcb_drc.cpp b/kicad/cli/command_pcb_drc.cpp index ea96313ca0..4abe3d40b0 100644 --- a/kicad/cli/command_pcb_drc.cpp +++ b/kicad/cli/command_pcb_drc.cpp @@ -40,6 +40,7 @@ CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" ) { addCommonArgs( true, true, false ); + addDefineArg(); m_argParser.add_description( UTF8STDSTR( _( "Runs the Design Rules Check (DRC) on the PCB and creates a report" ) ) ); @@ -81,10 +82,6 @@ CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" ) .help( UTF8STDSTR( _( "Return a exit code depending on whether or not violations exist" ) ) ) .implicit_value( true ) .default_value( false ); - - m_argParser.add_argument( "-o", ARG_OUTPUT ) - .default_value( std::string() ) - .help( UTF8STDSTR( _( "Output file name" ) ) ); } @@ -94,6 +91,7 @@ int CLI::PCB_DRC_COMMAND::doPerform( KIWAY& aKiway ) drcJob->m_outputFile = m_argOutput; drcJob->m_filename = m_argInput; + drcJob->SetVarOverrides( m_argDefineVars ); drcJob->m_reportAllTrackErrors = m_argParser.get( ARG_ALL_TRACK_ERRORS ); drcJob->m_exitCodeViolations = m_argParser.get( ARG_EXIT_CODE_VIOLATIONS ); diff --git a/kicad/cli/command_pcb_export_3d.cpp b/kicad/cli/command_pcb_export_3d.cpp index 08e0b87e2b..631d13da2d 100644 --- a/kicad/cli/command_pcb_export_3d.cpp +++ b/kicad/cli/command_pcb_export_3d.cpp @@ -53,6 +53,7 @@ CLI::PCB_EXPORT_3D_COMMAND::PCB_EXPORT_3D_COMMAND( const std::string& aName, m_format( aFormat ) { addCommonArgs( true, true, false ); + addDefineArg(); if( m_format == JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN ) { @@ -161,6 +162,7 @@ int CLI::PCB_EXPORT_3D_COMMAND::doPerform( KIWAY& aKiway ) step->m_filename = m_argInput; step->m_outputFile = m_argOutput; step->m_format = m_format; + step->SetVarOverrides( m_argDefineVars ); if( step->m_format == JOB_EXPORT_PCB_3D::FORMAT::UNKNOWN ) { diff --git a/kicad/cli/command_pcb_export_dxf.cpp b/kicad/cli/command_pcb_export_dxf.cpp index 829c176b30..173006d7f2 100644 --- a/kicad/cli/command_pcb_export_dxf.cpp +++ b/kicad/cli/command_pcb_export_dxf.cpp @@ -37,6 +37,7 @@ CLI::PCB_EXPORT_DXF_COMMAND::PCB_EXPORT_DXF_COMMAND() : PCB_EXPORT_BASE_COMMAND( { addLayerArg( true ); addDrawingSheetArg(); + addDefineArg(); m_argParser.add_argument( "--erd", ARG_EXCLUDE_REFDES ) .help( UTF8STDSTR( _( "Exclude the reference designator text" ) ) ) @@ -75,6 +76,7 @@ int CLI::PCB_EXPORT_DXF_COMMAND::doPerform( KIWAY& aKiway ) dxfJob->m_filename = m_argInput; dxfJob->m_outputFile = m_argOutput; dxfJob->m_drawingSheet = m_argDrawingSheet; + dxfJob->SetVarOverrides( m_argDefineVars ); if( !wxFile::Exists( dxfJob->m_filename ) ) { diff --git a/kicad/cli/command_pcb_export_gerber.cpp b/kicad/cli/command_pcb_export_gerber.cpp index 1cfebc5d66..aab812e826 100644 --- a/kicad/cli/command_pcb_export_gerber.cpp +++ b/kicad/cli/command_pcb_export_gerber.cpp @@ -36,6 +36,7 @@ CLI::PCB_EXPORT_GERBER_COMMAND::PCB_EXPORT_GERBER_COMMAND( const std::string& aN { addLayerArg( true ); addDrawingSheetArg(); + addDefineArg(); m_argParser.add_description( UTF8STDSTR( _( "Plot given layers to a single gerber file" ) ) ); @@ -101,6 +102,7 @@ int CLI::PCB_EXPORT_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob ) aJob->m_filename = m_argInput; aJob->m_outputFile = m_argOutput; aJob->m_drawingSheet = m_argDrawingSheet; + aJob->SetVarOverrides( m_argDefineVars ); aJob->m_plotFootprintValues = !m_argParser.get( ARG_EXCLUDE_VALUE ); aJob->m_plotRefDes = !m_argParser.get( ARG_EXCLUDE_REFDES ); diff --git a/kicad/cli/command_pcb_export_gerbers.cpp b/kicad/cli/command_pcb_export_gerbers.cpp index 16a14c5dee..d49f678c05 100644 --- a/kicad/cli/command_pcb_export_gerbers.cpp +++ b/kicad/cli/command_pcb_export_gerbers.cpp @@ -39,6 +39,7 @@ CLI::PCB_EXPORT_GERBERS_COMMAND::PCB_EXPORT_GERBERS_COMMAND() : { m_requireLayers = false; addDrawingSheetArg(); + addDefineArg(); m_argParser.add_description( UTF8STDSTR( _( "Plot multiple gerbers for a PCB, including the " "ability to use stored board plot settings" ) ) ); diff --git a/kicad/cli/command_pcb_export_pdf.cpp b/kicad/cli/command_pcb_export_pdf.cpp index 9c636be929..c93f5607eb 100644 --- a/kicad/cli/command_pcb_export_pdf.cpp +++ b/kicad/cli/command_pcb_export_pdf.cpp @@ -37,6 +37,7 @@ CLI::PCB_EXPORT_PDF_COMMAND::PCB_EXPORT_PDF_COMMAND() : PCB_EXPORT_BASE_COMMAND( { addLayerArg( true ); addDrawingSheetArg(); + addDefineArg(); m_argParser.add_argument( "-m", ARG_MIRROR ) .help( UTF8STDSTR( _( "Mirror the board (useful for trying to show bottom layers)" ) ) ) @@ -92,6 +93,7 @@ int CLI::PCB_EXPORT_PDF_COMMAND::doPerform( KIWAY& aKiway ) pdfJob->m_filename = m_argInput; pdfJob->m_outputFile = m_argOutput; pdfJob->m_drawingSheet = m_argDrawingSheet; + pdfJob->SetVarOverrides( m_argDefineVars ); if( !wxFile::Exists( pdfJob->m_filename ) ) { diff --git a/kicad/cli/command_pcb_export_svg.cpp b/kicad/cli/command_pcb_export_svg.cpp index 4028564afc..c60a63f85b 100644 --- a/kicad/cli/command_pcb_export_svg.cpp +++ b/kicad/cli/command_pcb_export_svg.cpp @@ -40,6 +40,7 @@ CLI::PCB_EXPORT_SVG_COMMAND::PCB_EXPORT_SVG_COMMAND() : PCB_EXPORT_BASE_COMMAND( { addLayerArg( true ); addDrawingSheetArg(); + addDefineArg(); m_argParser.add_argument( "-m", ARG_MIRROR ) .help( UTF8STDSTR( _( "Mirror the board (useful for trying to show bottom layers)" ) ) ) @@ -98,6 +99,7 @@ int CLI::PCB_EXPORT_SVG_COMMAND::doPerform( KIWAY& aKiway ) svgJob->m_outputFile = m_argOutput; svgJob->m_colorTheme = FROM_UTF8( m_argParser.get( ARG_THEME ).c_str() ); svgJob->m_plotDrawingSheet = !m_argParser.get( ARG_EXCLUDE_DRAWING_SHEET ); + svgJob->SetVarOverrides( m_argDefineVars ); if( !wxFile::Exists( svgJob->m_filename ) ) { diff --git a/kicad/cli/command_sch_erc.cpp b/kicad/cli/command_sch_erc.cpp index 18c1faad90..8b380cbb32 100644 --- a/kicad/cli/command_sch_erc.cpp +++ b/kicad/cli/command_sch_erc.cpp @@ -39,6 +39,7 @@ CLI::SCH_ERC_COMMAND::SCH_ERC_COMMAND() : COMMAND( "erc" ) { addCommonArgs( true, true, false ); + addDefineArg(); m_argParser.add_description( UTF8STDSTR( _( "Runs the Electrical Rules Check (ERC) on the schematic and creates a report" ) ) ); @@ -75,10 +76,6 @@ CLI::SCH_ERC_COMMAND::SCH_ERC_COMMAND() : COMMAND( "erc" ) .help( UTF8STDSTR( _( "Return a exit code depending on whether or not violations exist" ) ) ) .implicit_value( true ) .default_value( false ); - - m_argParser.add_argument( "-o", ARG_OUTPUT ) - .default_value( std::string() ) - .help( UTF8STDSTR( _( "Output file name" ) ) ); } @@ -89,6 +86,7 @@ int CLI::SCH_ERC_COMMAND::doPerform( KIWAY& aKiway ) ercJob->m_outputFile = m_argOutput; ercJob->m_filename = m_argInput; ercJob->m_exitCodeViolations = m_argParser.get( ARG_EXIT_CODE_VIOLATIONS ); + ercJob->SetVarOverrides( m_argDefineVars ); if( m_argParser.get( ARG_SEVERITY_ALL ) ) { diff --git a/kicad/cli/command_sch_export_plot.cpp b/kicad/cli/command_sch_export_plot.cpp index e4f6604841..c91b48968b 100644 --- a/kicad/cli/command_sch_export_plot.cpp +++ b/kicad/cli/command_sch_export_plot.cpp @@ -48,6 +48,7 @@ CLI::SCH_EXPORT_PLOT_COMMAND::SCH_EXPORT_PLOT_COMMAND( const std::string& aName, { addCommonArgs( true, true, aOutputIsDir ); addDrawingSheetArg(); + addDefineArg(); m_argParser.add_argument( "-t", ARG_THEME ) .default_value( std::string() ) @@ -114,6 +115,7 @@ int CLI::SCH_EXPORT_PLOT_COMMAND::doPerform( KIWAY& aKiway ) settings.m_outputFile = m_argOutput; plotJob->m_drawingSheet = m_argDrawingSheet; + plotJob->SetVarOverrides( m_argDefineVars ); // HPGL local options if( m_plotFormat == PLOT_FORMAT::HPGL ) diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 13e152236d..5e6f1c8498 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -98,6 +98,7 @@ int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob ) m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); BOARD* brd = LoadBoard( aStepJob->m_filename ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( aStepJob->m_format == JOB_EXPORT_PCB_3D::FORMAT::VRML ) { @@ -201,6 +202,7 @@ int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob ) BOARD* brd = LoadBoard( aSvgJob->m_filename ); loadOverrideDrawingSheet( brd, aSvgJob->m_drawingSheet ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( aJob->IsCli() ) { @@ -226,6 +228,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob ) BOARD* brd = LoadBoard( aDxfJob->m_filename ); loadOverrideDrawingSheet( brd, aDxfJob->m_drawingSheet ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( aDxfJob->m_outputFile.IsEmpty() ) { @@ -282,6 +285,7 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob ) BOARD* brd = LoadBoard( aPdfJob->m_filename ); loadOverrideDrawingSheet( brd, aPdfJob->m_drawingSheet ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( aPdfJob->m_outputFile.IsEmpty() ) { @@ -478,6 +482,7 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); BOARD* brd = LoadBoard( aGerberJob->m_filename ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( aGerberJob->m_outputFile.IsEmpty() ) { @@ -854,6 +859,7 @@ int PCBNEW_JOBS_HANDLER::doFpExportSvg( JOB_FP_EXPORT_SVG* aSvgJob, const FOOTPR // until we refactor better plot api later std::unique_ptr brd; brd.reset( CreateEmptyBoard() ); + brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() ); FOOTPRINT* fp = dynamic_cast( aFootprint->Clone() ); @@ -914,6 +920,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob ) m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO ); BOARD* brd = LoadBoard( drcJob->m_filename ); + brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() ); if( drcJob->m_outputFile.IsEmpty() ) {