Add command-line option to generate netlist and exit

This commit is contained in:
Jon Evans 2020-04-19 14:28:36 -04:00
parent 02bdec1c57
commit b802a3e776
6 changed files with 83 additions and 34 deletions

View File

@ -37,6 +37,7 @@
#include <typeinfo> #include <typeinfo>
#include <macros.h> #include <macros.h>
#include <fctsys.h> #include <fctsys.h>
#include <wx/cmdline.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/snglinst.h> #include <wx/snglinst.h>
@ -316,10 +317,16 @@ bool PGM_SINGLE_TOP::OnPgmInit()
Kiway.set_kiface( KIWAY::KifaceType( TOP_FRAME ), kiface ); Kiway.set_kiface( KIWAY::KifaceType( TOP_FRAME ), kiface );
#endif #endif
// Open project or file specified on the command line: static const wxCmdLineEntryDesc desc[] = {
int argc = App().argc; { wxCMD_LINE_OPTION, "f", "frame", _( "Frame to load" ) },
{ wxCMD_LINE_PARAM, nullptr, nullptr, _( "File to load" ), wxCMD_LINE_VAL_STRING,
wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE }
};
int args_offset = 1; wxCmdLineParser parser( App().argc, App().argv );
parser.SetDesc( desc );
parser.Parse( false );
FRAME_T appType = TOP_FRAME; FRAME_T appType = TOP_FRAME;
@ -333,28 +340,22 @@ bool PGM_SINGLE_TOP::OnPgmInit()
{ wxT( "" ), FRAME_T_COUNT } { wxT( "" ), FRAME_T_COUNT }
}; };
if( argc > 2 ) wxString frameName;
if( parser.Found( "frame", &frameName ) )
{ {
if( App().argv[1] == "--frame" ) appType = FRAME_T_COUNT;
for( const auto& it : frameTypes )
{ {
wxString appName = App().argv[2]; if( it.name == frameName )
appType = FRAME_T_COUNT; appType = it.type;
}
for( int i = 0; frameTypes[i].type != FRAME_T_COUNT; i++ ) if( appType == FRAME_T_COUNT )
{ {
const auto& frame = frameTypes[i]; wxLogError( wxT( "Unknown frame: %s" ), frameName );
if(frame.name == appName) return false;
{
appType = frame.type;
}
}
args_offset += 2;
if( appType == FRAME_T_COUNT )
{
wxLogError( wxT( "Unknown frame: %s" ), appName );
return false;
}
} }
} }
@ -368,8 +369,14 @@ bool PGM_SINGLE_TOP::OnPgmInit()
App().SetTopWindow( frame ); // wxApp gets a face. App().SetTopWindow( frame ); // wxApp gets a face.
// Individual frames may provide additional option/switch processing, but for compatibility,
// any positional arguments are treated as a list of files to pass to OpenProjectFiles
frame->ParseArgs( parser );
if( argc > args_offset ) // Now after the frame processing, the rest of the positional args are files
std::vector<wxString> fileArgs;
if( parser.GetParamCount() )
{ {
/* /*
gerbview handles multiple project data files, i.e. gerber files on gerbview handles multiple project data files, i.e. gerber files on
@ -380,33 +387,29 @@ bool PGM_SINGLE_TOP::OnPgmInit()
launcher. launcher.
*/ */
std::vector<wxString> argSet; for( size_t i = 0; i < parser.GetParamCount(); i++ )
fileArgs.push_back( parser.GetParam( i ) );
for( int i = args_offset; i < argc; ++i )
{
argSet.push_back( App().argv[i] );
}
// special attention to a single argument: argv[1] (==argSet[0]) // special attention to a single argument: argv[1] (==argSet[0])
if( argc == args_offset + 1 ) if( fileArgs.size() == 1 )
{ {
wxFileName argv1( argSet[0] ); wxFileName argv1( fileArgs[0] );
#if defined(PGM_DATA_FILE_EXT) #if defined(PGM_DATA_FILE_EXT)
// PGM_DATA_FILE_EXT, if present, may be different for each compile, // PGM_DATA_FILE_EXT, if present, may be different for each compile,
// it may come from CMake on the compiler command line, but often does not. // it may come from CMake on the compiler command line, but often does not.
// This facillity is mostly useful for those program modules // This facility is mostly useful for those program modules
// supporting a single argv[1]. // supporting a single argv[1].
if( !argv1.GetExt() ) if( !argv1.GetExt() )
argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) ); argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) );
#endif #endif
argv1.MakeAbsolute(); argv1.MakeAbsolute();
argSet[0] = argv1.GetFullPath(); fileArgs[0] = argv1.GetFullPath();
} }
// Use the KIWAY_PLAYER::OpenProjectFiles() API function: // Use the KIWAY_PLAYER::OpenProjectFiles() API function:
if( !frame->OpenProjectFiles( argSet ) ) if( !frame->OpenProjectFiles( fileArgs ) )
{ {
// OpenProjectFiles() API asks that it report failure to the UI. // OpenProjectFiles() API asks that it report failure to the UI.
// Nothing further to say here. // Nothing further to say here.

View File

@ -52,6 +52,7 @@
#include <ws_data_model.h> #include <ws_data_model.h>
#include <connection_graph.h> #include <connection_graph.h>
#include <tool/actions.h> #include <tool/actions.h>
#include <netlist.h>
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName, bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
bool aCreateBackupFile ) bool aCreateBackupFile )
@ -445,6 +446,17 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
UpdateTitle(); UpdateTitle();
// If requested, generate a netlist and exit immediately.
// NOTE: This is intended as a developer-only feature for now, and can be removed in lieu of
// Python scripting once that is possible.
if( m_generateNetlistAndExit )
{
wxLogDebug( wxT( "Writing netlist to %s and exiting..." ), m_netlistFilename );
NETLIST_OBJECT_LIST* netlist = CreateNetlist( false, false );
WriteNetListFile( netlist, NET_TYPE_PCBNEW, m_netlistFilename, 0, nullptr );
Close( false );
}
return true; return true;
} }

View File

@ -69,6 +69,7 @@
#include <tools/sch_line_wire_bus_tool.h> #include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h> #include <tools/sch_move_tool.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#include <wx/cmdline.h>
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
@ -226,6 +227,9 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
m_findReplaceDialog = nullptr; m_findReplaceDialog = nullptr;
m_findReplaceStatusPopup = nullptr; m_findReplaceStatusPopup = nullptr;
m_generateNetlistAndExit = false;
m_netlistFilename = wxEmptyString;
SetSpiceAdjustPassiveValues( false ); SetSpiceAdjustPassiveValues( false );
// Give an icon // Give an icon
@ -790,6 +794,16 @@ void SCH_EDIT_FRAME::LoadProject()
} }
void SCH_EDIT_FRAME::ParseArgs( wxCmdLineParser& aParser )
{
aParser.AddOption( "n", "netlist" );
aParser.Parse();
if( aParser.Found( "netlist", &m_netlistFilename ) )
m_generateNetlistAndExit = true;
}
void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event )
{ {
wxFileName kicad_board = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); wxFileName kicad_board = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() );

View File

@ -149,6 +149,11 @@ private:
static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type. static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type.
// NOTE: This is a developer-only feature and can be replaced by appropriate Python
// functionality once that is possible.
bool m_generateNetlistAndExit; ///< For command-line netlist generation
wxString m_netlistFilename;
protected: protected:
/** /**
* Save the schematic files that have been modified and not yet saved. * Save the schematic files that have been modified and not yet saved.
@ -576,6 +581,8 @@ public:
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override; bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override;
void ParseArgs( wxCmdLineParser& aParser ) override;
/** /**
* Import a KiCad schematic into the current sheet. * Import a KiCad schematic into the current sheet.
* *

View File

@ -127,6 +127,19 @@ public:
return false; return false;
} }
/**
* Handles command-line arguments in a frame-specific way.
* The given argument parser has already been initialized with the command line and any
* options/switches that are handled by the top-level launcher before passing control to
* the child frame.
*
* @param aParser is the argument parser created by the top-level launcher.
*/
virtual void ParseArgs( wxCmdLineParser& aParser )
{
WXUNUSED( aParser );
}
/** /**
* Function ShowModal * Function ShowModal

View File