From 43f039ef5f2d0cbec583cb1189cab15f81cb1cc9 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Wed, 9 Nov 2022 22:37:47 -0500 Subject: [PATCH] Add netlist export cli --- common/jobs/job_export_sch_netlist.h | 53 ++++++++++++ common/wildcards_and_files_ext.cpp | 2 + eeschema/dialogs/dialog_netlist.cpp | 4 +- eeschema/eeschema_jobs_handler.cpp | 105 ++++++++++++++++++++++- eeschema/eeschema_jobs_handler.h | 1 + include/wildcards_and_files_ext.h | 2 + kicad/CMakeLists.txt | 1 + kicad/cli/command_export_sch_netlist.cpp | 87 +++++++++++++++++++ kicad/cli/command_export_sch_netlist.h | 37 ++++++++ kicad/kicad_cli.cpp | 29 ++++--- 10 files changed, 304 insertions(+), 17 deletions(-) create mode 100644 common/jobs/job_export_sch_netlist.h create mode 100644 kicad/cli/command_export_sch_netlist.cpp create mode 100644 kicad/cli/command_export_sch_netlist.h diff --git a/common/jobs/job_export_sch_netlist.h b/common/jobs/job_export_sch_netlist.h new file mode 100644 index 0000000000..e1376e6fe7 --- /dev/null +++ b/common/jobs/job_export_sch_netlist.h @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef JOB_EXPORT_SCH_NETLIST_H +#define JOB_EXPORT_SCH_NETLIST_H + +#include +#include "job.h" + +class JOB_EXPORT_SCH_NETLIST : public JOB +{ +public: + JOB_EXPORT_SCH_NETLIST( bool aIsCli ) : + JOB( "netlist", aIsCli ), + m_filename(), + m_outputFile() + { + } + + wxString m_filename; + wxString m_outputFile; + + enum class FORMAT + { + KICADXML, + KICADSEXPR, + ORCADPCB2, + CADSTAR, + SPICE, + SPICEMODEL + }; + + FORMAT format; +}; + +#endif \ No newline at end of file diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index 6e5b91121e..9e68ca5086 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -138,6 +138,8 @@ const std::string LegacySchematicFileExtension( "sch" ); const std::string EagleSchematicFileExtension( "sch" ); const std::string CadstarSchematicFileExtension( "csa" ); const std::string KiCadSchematicFileExtension( "kicad_sch" ); +const std::string SpiceFileExtension( "cir" ); +const std::string CadstarNetlistFileExtension( "frp" ); const std::string OrCadPcb2NetlistFileExtension( "net" ); const std::string NetlistFileExtension( "net" ); const std::string FootprintAssignmentFileExtension( "cmp" ); diff --git a/eeschema/dialogs/dialog_netlist.cpp b/eeschema/dialogs/dialog_netlist.cpp index 83bfae125b..d2150db12b 100644 --- a/eeschema/dialogs/dialog_netlist.cpp +++ b/eeschema/dialogs/dialog_netlist.cpp @@ -579,12 +579,12 @@ bool NETLIST_DIALOG::FilenamePrms( NETLIST_TYPE_ID aType, wxString * aExt, wxStr switch( aType ) { case NET_TYPE_SPICE: - fileExt = wxT( "cir" ); + fileExt = SpiceFileExtension; fileWildcard = SpiceNetlistFileWildcard(); break; case NET_TYPE_CADSTAR: - fileExt = wxT( "frp" ); + fileExt = CadstarNetlistFileExtension; fileWildcard = CadstarNetlistFileWildcard(); break; diff --git a/eeschema/eeschema_jobs_handler.cpp b/eeschema/eeschema_jobs_handler.cpp index 46b93d0b9c..87199ca29d 100644 --- a/eeschema/eeschema_jobs_handler.cpp +++ b/eeschema/eeschema_jobs_handler.cpp @@ -20,6 +20,7 @@ #include "eeschema_jobs_handler.h" #include +#include #include #include #include @@ -30,12 +31,25 @@ #include #include "eeschema_helpers.h" #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include + EESCHEMA_JOBS_HANDLER::EESCHEMA_JOBS_HANDLER() { + Register( "netlist", + std::bind( &EESCHEMA_JOBS_HANDLER::JobExportNetlist, this, std::placeholders::_1 ) ); Register( "pdf", std::bind( &EESCHEMA_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) ); Register( "svg", @@ -81,7 +95,7 @@ int EESCHEMA_JOBS_HANDLER::JobExportPdf( JOB* aJob ) schPlotter->Plot( PLOT_FORMAT::PDF, settings, renderSettings.get(), nullptr ); - return 0; + return CLI::EXIT_CODES::OK; } @@ -107,5 +121,92 @@ int EESCHEMA_JOBS_HANDLER::JobExportSvg( JOB* aJob ) schPlotter->Plot( PLOT_FORMAT::SVG, settings, renderSettings.get(), nullptr ); - return 0; + return CLI::EXIT_CODES::OK; +} + + +int EESCHEMA_JOBS_HANDLER::JobExportNetlist( JOB* aJob ) +{ + JOB_EXPORT_SCH_NETLIST* aNetJob = dynamic_cast( aJob ); + + SCHEMATIC* sch = EESCHEMA_HELPERS::LoadSchematic( aNetJob->m_filename, SCH_IO_MGR::SCH_KICAD ); + + // Annotation warning check + SCH_REFERENCE_LIST referenceList; + sch->GetSheets().GetSymbols( referenceList ); + if( referenceList.GetCount() > 0 ) + { + if( referenceList.CheckAnnotation( []( ERCE_T, const wxString&, SCH_REFERENCE*, SCH_REFERENCE* ) {} ) > 0 ) + { + wxPrintf( _( "Warning: schematic has annotation errors, please use the schematic editor to fix them\n" ) ); + } + } + + // Test duplicate sheet names: + ERC_TESTER erc( sch ); + + if( erc.TestDuplicateSheetNames( false ) > 0 ) + { + wxPrintf( _( "Warning: duplicate sheet names.\n" ) ); + } + + + std::unique_ptr helper; + + wxString fileExt; + + switch( aNetJob->format ) + { + case JOB_EXPORT_SCH_NETLIST::FORMAT::KICADSEXPR: + fileExt = NetlistFileExtension; + helper = std::make_unique( sch ); + break; + + case JOB_EXPORT_SCH_NETLIST::FORMAT::ORCADPCB2: + fileExt = OrCadPcb2NetlistFileExtension; + helper = std::make_unique( sch ); + break; + + case JOB_EXPORT_SCH_NETLIST::FORMAT::CADSTAR: + fileExt = CadstarNetlistFileExtension; + helper = std::make_unique( sch ); + break; + + case JOB_EXPORT_SCH_NETLIST::FORMAT::SPICE: + fileExt = SpiceFileExtension; + helper = std::make_unique( sch ); + break; + + case JOB_EXPORT_SCH_NETLIST::FORMAT::SPICEMODEL: + fileExt = SpiceFileExtension; + helper = std::make_unique( sch ); + break; + + case JOB_EXPORT_SCH_NETLIST::FORMAT::KICADXML: + fileExt = wxS( "xml" ); + helper = std::make_unique( sch ); + break; + default: + wxFprintf( stderr, _( "Unknown netlist format.\n" ) ); + return CLI::EXIT_CODES::ERR_UNKNOWN; + } + + + if( aNetJob->m_outputFile.IsEmpty() ) + { + wxFileName fn = sch->GetFileName(); + fn.SetName( fn.GetName() ); + fn.SetExt( fileExt ); + + aNetJob->m_outputFile = fn.GetFullName(); + } + + bool res = helper->WriteNetlist( aNetJob->m_outputFile, 0 ); + + if(!res) + { + return CLI::EXIT_CODES::ERR_UNKNOWN; + } + + return CLI::EXIT_CODES::OK; } \ No newline at end of file diff --git a/eeschema/eeschema_jobs_handler.h b/eeschema/eeschema_jobs_handler.h index cb3c318e13..c42c940e34 100644 --- a/eeschema/eeschema_jobs_handler.h +++ b/eeschema/eeschema_jobs_handler.h @@ -38,6 +38,7 @@ class EESCHEMA_JOBS_HANDLER : public JOB_DISPATCHER { public: EESCHEMA_JOBS_HANDLER(); + int JobExportNetlist( JOB* aJob ); int JobExportPdf( JOB* aJob ); int JobExportSvg( JOB* aJob ); diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h index 033bcd2e5d..734dda9aac 100644 --- a/include/wildcards_and_files_ext.h +++ b/include/wildcards_and_files_ext.h @@ -123,6 +123,8 @@ extern const std::string LegacySchematicFileExtension; extern const std::string EagleSchematicFileExtension; extern const std::string CadstarSchematicFileExtension; extern const std::string KiCadSchematicFileExtension; +extern const std::string SpiceFileExtension; +extern const std::string CadstarNetlistFileExtension; extern const std::string OrCadPcb2NetlistFileExtension; extern const std::string NetlistFileExtension; extern const std::string GerberFileExtension; diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 6fe6d60211..c125d1f02d 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -26,6 +26,7 @@ set( KICAD_SRCS cli/command_export_pcb_svg.cpp cli/command_pcb.cpp cli/command_pcb_export.cpp + cli/command_export_sch_netlist.cpp cli/command_export_sch_pdf.cpp cli/command_export_sch_svg.cpp cli/command_sch.cpp diff --git a/kicad/cli/command_export_sch_netlist.cpp b/kicad/cli/command_export_sch_netlist.cpp new file mode 100644 index 0000000000..3600c5dd65 --- /dev/null +++ b/kicad/cli/command_export_sch_netlist.cpp @@ -0,0 +1,87 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "command_export_sch_netlist.h" +#include +#include "jobs/job_export_sch_netlist.h" +#include +#include +#include + +#include + +#define ARG_FORMAT "--format" + +CLI::EXPORT_SCH_NETLIST_COMMAND::EXPORT_SCH_NETLIST_COMMAND() : EXPORT_PCB_BASE_COMMAND( "netlist" ) +{ + m_argParser.add_argument( ARG_FORMAT ) + .default_value( std::string( "kicadsexpr" ) ) + .help( "Netlist output format, valid options: kicadsexpr, kicadxml, cadstar, orcadpcb2, spice, spicemodel" ); +} + + +int CLI::EXPORT_SCH_NETLIST_COMMAND::Perform( KIWAY& aKiway ) +{ + JOB_EXPORT_SCH_NETLIST* netJob = new JOB_EXPORT_SCH_NETLIST( true ); + + netJob->m_filename = FROM_UTF8( m_argParser.get( ARG_INPUT ).c_str() ); + netJob->m_outputFile = FROM_UTF8( m_argParser.get( ARG_OUTPUT ).c_str() ); + + if( !wxFile::Exists( netJob->m_filename ) ) + { + wxFprintf( stderr, _( "Schematic file does not exist or is not accessible\n" ) ); + return EXIT_CODES::ERR_INVALID_INPUT_FILE; + } + + wxString format = FROM_UTF8( m_argParser.get( ARG_FORMAT ).c_str() ); + if( format == "kicadsexpr" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::KICADSEXPR; + } + else if( format == "kicadxml" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::KICADXML; + } + else if( format == "cadstar" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::CADSTAR; + } + else if( format == "orcadpcb2" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::ORCADPCB2; + } + else if( format == "spice" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::SPICE; + } + else if( format == "spicemodel" ) + { + netJob->format = JOB_EXPORT_SCH_NETLIST::FORMAT::SPICEMODEL; + } + else + { + wxFprintf( stderr, _( "Invalid format\n" ) ); + return EXIT_CODES::ERR_ARGS; + } + + int exitCode = aKiway.ProcessJob( KIWAY::FACE_SCH, netJob ); + + return exitCode; +} \ No newline at end of file diff --git a/kicad/cli/command_export_sch_netlist.h b/kicad/cli/command_export_sch_netlist.h new file mode 100644 index 0000000000..7287bd4603 --- /dev/null +++ b/kicad/cli/command_export_sch_netlist.h @@ -0,0 +1,37 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef COMMAND_EXPORT_SCH_NETLIST_H +#define COMMAND_EXPORT_SCH_NETLIST_H + +#include "command_export_pcb_base.h" + +namespace CLI +{ +class EXPORT_SCH_NETLIST_COMMAND : public EXPORT_PCB_BASE_COMMAND +{ +public: + EXPORT_SCH_NETLIST_COMMAND(); + + int Perform( KIWAY& aKiway ) override; +}; +} // namespace CLI + +#endif \ No newline at end of file diff --git a/kicad/kicad_cli.cpp b/kicad/kicad_cli.cpp index 2ee5efcc08..adbd578e4d 100644 --- a/kicad/kicad_cli.cpp +++ b/kicad/kicad_cli.cpp @@ -55,6 +55,7 @@ #include "cli/command_export_pcb_pos.h" #include "cli/command_export_pcb_svg.h" #include "cli/command_export_pcb_step.h" +#include "cli/command_export_sch_netlist.h" #include "cli/command_export_sch_pdf.h" #include "cli/command_export_sch_svg.h" #include "cli/command_sch.h" @@ -106,19 +107,20 @@ struct COMMAND_ENTRY handler( aHandler ), subCommands( aSub ){}; }; -static CLI::EXPORT_PCB_DRILL_COMMAND exportPcbDrillCmd{}; -static CLI::EXPORT_PCB_DXF_COMMAND exportPcbDxfCmd{}; -static CLI::EXPORT_PCB_STEP_COMMAND exportPcbStepCmd{}; -static CLI::EXPORT_PCB_SVG_COMMAND exportPcbSvgCmd{}; -static CLI::EXPORT_PCB_PDF_COMMAND exportPcbPdfCmd{}; -static CLI::EXPORT_PCB_POS_COMMAND exportPcbPosCmd{}; -static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{}; -static CLI::EXPORT_PCB_COMMAND exportPcbCmd{}; -static CLI::PCB_COMMAND pcbCmd{}; -static CLI::EXPORT_SCH_COMMAND exportSchCmd{}; -static CLI::SCH_COMMAND schCmd{}; -static CLI::EXPORT_SCH_PDF_COMMAND exportSchPdfCmd{}; -static CLI::EXPORT_SCH_SVG_COMMAND exportSchSvgCmd{}; +static CLI::EXPORT_PCB_DRILL_COMMAND exportPcbDrillCmd{}; +static CLI::EXPORT_PCB_DXF_COMMAND exportPcbDxfCmd{}; +static CLI::EXPORT_PCB_STEP_COMMAND exportPcbStepCmd{}; +static CLI::EXPORT_PCB_SVG_COMMAND exportPcbSvgCmd{}; +static CLI::EXPORT_PCB_PDF_COMMAND exportPcbPdfCmd{}; +static CLI::EXPORT_PCB_POS_COMMAND exportPcbPosCmd{}; +static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{}; +static CLI::EXPORT_PCB_COMMAND exportPcbCmd{}; +static CLI::PCB_COMMAND pcbCmd{}; +static CLI::EXPORT_SCH_COMMAND exportSchCmd{}; +static CLI::SCH_COMMAND schCmd{}; +static CLI::EXPORT_SCH_NETLIST_COMMAND exportSchNetlistCmd{}; +static CLI::EXPORT_SCH_PDF_COMMAND exportSchPdfCmd{}; +static CLI::EXPORT_SCH_SVG_COMMAND exportSchSvgCmd{}; static std::vector commandStack = { { @@ -142,6 +144,7 @@ static std::vector commandStack = { { { &exportSchCmd, { + &exportSchNetlistCmd, &exportSchPdfCmd, &exportSchSvgCmd }