Centralize SPICE lib path resolution and support SPICE_LIB_DIR.
Fixes https://gitlab.com/kicad/code/kicad/issues/13081
This commit is contained in:
parent
bb6544914e
commit
e8980e9024
|
@ -614,17 +614,12 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
|
|||
{
|
||||
auto libraries = m_libraryModelsMgr.GetLibraries();
|
||||
|
||||
// Loading the same library as previously should normally be a no-op except when done using the
|
||||
// library browse button.
|
||||
if( !aForceReload && libraries.size() >= 1 && libraries.begin()->first == aLibraryPath )
|
||||
return;
|
||||
|
||||
DIALOG_IBIS_PARSER_REPORTER dlg( this );
|
||||
dlg.m_messagePanel->Clear();
|
||||
|
||||
try
|
||||
{
|
||||
m_libraryModelsMgr.CreateLibrary( aLibraryPath, &dlg.m_messagePanel->Reporter() );
|
||||
m_libraryModelsMgr.SetLibrary( aLibraryPath, &dlg.m_messagePanel->Reporter() );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
|
|
|
@ -359,7 +359,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions, REPORTER&
|
|||
|
||||
try
|
||||
{
|
||||
m_libMgr.CreateLibrary( path, &aReporter );
|
||||
m_libMgr.AddLibrary( path, &aReporter );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
|
|
|
@ -46,14 +46,51 @@ void SIM_LIB_MGR::Clear()
|
|||
}
|
||||
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const wxString& aLibraryPath, REPORTER* aReporter )
|
||||
wxString SIM_LIB_MGR::ResolveLibraryPath( const wxString& aLibraryPath, const PROJECT& aProject )
|
||||
{
|
||||
wxString path = ExpandEnvVarSubstitutions( aLibraryPath, &m_project );
|
||||
wxString absolutePath = m_project.AbsolutePath( path );
|
||||
wxString expandedPath = ExpandEnvVarSubstitutions( aLibraryPath, &aProject );
|
||||
wxFileName fn( expandedPath );
|
||||
|
||||
if( fn.IsAbsolute() )
|
||||
return fn.GetFullPath();
|
||||
|
||||
wxFileName projectFn( aProject.AbsolutePath( expandedPath ) );
|
||||
|
||||
if( projectFn.Exists() )
|
||||
return projectFn.GetFullPath();
|
||||
|
||||
wxFileName spiceLibFn( expandedPath );
|
||||
wxString spiceLibDir;
|
||||
|
||||
wxGetEnv( wxT( "SPICE_LIB_DIR" ), &spiceLibDir );
|
||||
|
||||
if( !spiceLibDir.IsEmpty() && spiceLibFn.MakeAbsolute( spiceLibDir ) && spiceLibFn.Exists() )
|
||||
return spiceLibFn.GetFullPath();
|
||||
|
||||
THROW_IO_ERROR( wxString::Format( _( "Simulation model library not found at '%s' or '%s'" ),
|
||||
projectFn.GetFullPath(),
|
||||
spiceLibFn.GetFullPath() ) );
|
||||
}
|
||||
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::AddLibrary( const wxString& aLibraryPath, REPORTER* aReporter )
|
||||
{
|
||||
// May throw an exception.
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||
|
||||
// May throw an exception.
|
||||
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( m_project.AbsolutePath( path ),
|
||||
aReporter );
|
||||
auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( path, aReporter ) ) .first;
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath, REPORTER* aReporter )
|
||||
{
|
||||
// May throw an exception.
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||
|
||||
// May throw an exception.
|
||||
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( path, aReporter );
|
||||
|
||||
Clear();
|
||||
m_libraries[path] = std::move( library );
|
||||
|
@ -150,21 +187,19 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
|||
const std::vector<T>& aFields,
|
||||
int aSymbolPinCount )
|
||||
{
|
||||
wxString path = ExpandEnvVarSubstitutions( aLibraryPath, &m_project );
|
||||
wxString absolutePath = m_project.AbsolutePath( path );
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||
SIM_LIBRARY* library = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( absolutePath ) ).first;
|
||||
auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( path ) ).first;
|
||||
library = &*it->second;
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
THROW_IO_ERROR(
|
||||
wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
||||
absolutePath,
|
||||
e.What() ) );
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
||||
path,
|
||||
e.What() ) );
|
||||
}
|
||||
|
||||
if( aBaseModelName == "" )
|
||||
|
@ -180,7 +215,7 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
|||
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: could not find "
|
||||
"base model '%s' in library '%s'" ),
|
||||
aBaseModelName,
|
||||
absolutePath ) );
|
||||
path ) );
|
||||
}
|
||||
|
||||
m_models.push_back( SIM_MODEL::Create( *baseModel, aSymbolPinCount, aFields ) );
|
||||
|
|
|
@ -45,7 +45,8 @@ public:
|
|||
|
||||
void Clear();
|
||||
|
||||
SIM_LIBRARY& CreateLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
SIM_LIBRARY& AddLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
SIM_LIBRARY& SetLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
|
||||
SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount );
|
||||
|
||||
|
@ -70,6 +71,8 @@ public:
|
|||
std::map<wxString, std::reference_wrapper<const SIM_LIBRARY>> GetLibraries() const;
|
||||
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels() const;
|
||||
|
||||
static wxString ResolveLibraryPath( const wxString& aLibraryPath, const PROJECT& aProject );
|
||||
|
||||
private:
|
||||
const PROJECT& m_project;
|
||||
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <fmt/core.h>
|
||||
#include <wx/filename.h>
|
||||
#include <kiway.h>
|
||||
#include "sim_lib_mgr.h"
|
||||
|
||||
std::string SPICE_GENERATOR_KIBIS::ModelName( const SPICE_ITEM& aItem ) const
|
||||
{
|
||||
|
@ -67,16 +68,13 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
|
|||
std::string ibisModelName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
||||
bool diffMode = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
|
||||
wxString path = ExpandEnvVarSubstitutions( ibisLibFilename, &aProject );
|
||||
wxString absolutePath = aProject.AbsolutePath( path );
|
||||
wxString path = SIM_LIB_MGR::ResolveLibraryPath( ibisLibFilename, aProject );
|
||||
|
||||
KIBIS kibis( std::string( absolutePath.c_str() ) );
|
||||
KIBIS kibis( std::string( path.c_str() ) );
|
||||
kibis.m_cacheDir = std::string( aCacheDir.c_str() );
|
||||
|
||||
if( !kibis.m_valid )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS file '%s'" ), ibisLibFilename ) );
|
||||
}
|
||||
|
||||
KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) );
|
||||
|
||||
|
@ -87,10 +85,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
|
|||
|
||||
|
||||
if( !kcomp->m_valid )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS component '%s'" ),
|
||||
ibisCompName ) );
|
||||
}
|
||||
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS component '%s'" ), ibisCompName ) );
|
||||
|
||||
if( !kpin )
|
||||
{
|
||||
|
@ -139,18 +134,15 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
|
|||
|
||||
if( paramValue == "hi-Z" )
|
||||
{
|
||||
kparams.m_waveform =
|
||||
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z( &kibis ) );
|
||||
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z( &kibis ) );
|
||||
}
|
||||
else if( paramValue == "low" )
|
||||
{
|
||||
kparams.m_waveform =
|
||||
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_LOW( &kibis ) );
|
||||
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_LOW( &kibis ) );
|
||||
}
|
||||
else if( paramValue == "high" )
|
||||
{
|
||||
kparams.m_waveform =
|
||||
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH( &kibis ) );
|
||||
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH( &kibis ) );
|
||||
}
|
||||
|
||||
if( diffMode )
|
||||
|
|
|
@ -35,6 +35,16 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const
|
|||
|
||||
m_fileMenu->AppendSeparator();
|
||||
|
||||
wxMenuItem* m_saveImage;
|
||||
m_saveImage = new wxMenuItem( m_fileMenu, ID_SAVE_AS_IMAGE, wxString( _("Export Current Plot as PNG...") ) , wxEmptyString, wxITEM_NORMAL );
|
||||
m_fileMenu->Append( m_saveImage );
|
||||
|
||||
wxMenuItem* m_saveCsv;
|
||||
m_saveCsv = new wxMenuItem( m_fileMenu, ID_SAVE_AS_CSV, wxString( _("Export Current Plot as CSV...") ) , wxEmptyString, wxITEM_NORMAL );
|
||||
m_fileMenu->Append( m_saveCsv );
|
||||
|
||||
m_fileMenu->AppendSeparator();
|
||||
|
||||
wxMenuItem* m_exitSim;
|
||||
m_exitSim = new wxMenuItem( m_fileMenu, wxID_CLOSE, wxString( _("Close") ) + wxT('\t') + wxT("CTRL+W"), wxEmptyString, wxITEM_NORMAL );
|
||||
m_fileMenu->Append( m_exitSim );
|
||||
|
@ -270,6 +280,8 @@ SIM_PLOT_FRAME_BASE::SIM_PLOT_FRAME_BASE( wxWindow* parent, wxWindowID id, const
|
|||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuOpenWorkbook ), this, m_openWorkbook->GetId());
|
||||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveWorkbook ), this, m_saveWorkbook->GetId());
|
||||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveWorkbookAs ), this, m_saveWorkbookAs->GetId());
|
||||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveImage ), this, m_saveImage->GetId());
|
||||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuSaveCsv ), this, m_saveCsv->GetId());
|
||||
m_fileMenu->Bind(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( SIM_PLOT_FRAME_BASE::menuExit ), this, m_exitSim->GetId());
|
||||
this->Connect( m_runSimulation->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuSimulateUpdate ) );
|
||||
this->Connect( m_addSignals->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( SIM_PLOT_FRAME_BASE::menuAddSignalsUpdate ) );
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
<property name="help"></property>
|
||||
<property name="id">wxID_OPEN</property>
|
||||
<property name="kind">wxITEM_NORMAL</property>
|
||||
<property name="label">Open...</property>
|
||||
<property name="label">Open Workbook...</property>
|
||||
<property name="name">m_openWorkbook</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="shortcut"></property>
|
||||
|
@ -121,7 +121,7 @@
|
|||
<property name="help"></property>
|
||||
<property name="id">wxID_SAVE</property>
|
||||
<property name="kind">wxITEM_NORMAL</property>
|
||||
<property name="label">Save</property>
|
||||
<property name="label">Save Workbook</property>
|
||||
<property name="name">m_saveWorkbook</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="shortcut"></property>
|
||||
|
@ -135,7 +135,7 @@
|
|||
<property name="help"></property>
|
||||
<property name="id">wxID_SAVEAS</property>
|
||||
<property name="kind">wxITEM_NORMAL</property>
|
||||
<property name="label">Save As...</property>
|
||||
<property name="label">Save Workbook As...</property>
|
||||
<property name="name">m_saveWorkbookAs</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="shortcut">SHIFT+CTRL+S</property>
|
||||
|
@ -153,7 +153,7 @@
|
|||
<property name="help"></property>
|
||||
<property name="id">ID_SAVE_AS_IMAGE</property>
|
||||
<property name="kind">wxITEM_NORMAL</property>
|
||||
<property name="label">Save as Image</property>
|
||||
<property name="label">Export Current Plot as PNG...</property>
|
||||
<property name="name">m_saveImage</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="shortcut"></property>
|
||||
|
@ -167,7 +167,7 @@
|
|||
<property name="help"></property>
|
||||
<property name="id">ID_SAVE_AS_CSV</property>
|
||||
<property name="kind">wxITEM_NORMAL</property>
|
||||
<property name="label">Save as .csv File</property>
|
||||
<property name="label">Export Current Plot as CSV...</property>
|
||||
<property name="name">m_saveCsv</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="shortcut"></property>
|
||||
|
|
|
@ -35,16 +35,18 @@ class wxListView;
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ID_MENU_RUN_SIM 1000
|
||||
#define ID_MENU_ADD_SIGNAL 1001
|
||||
#define ID_MENU_PROBE_SIGNALS 1002
|
||||
#define ID_MENU_TUNE_SIGNALS 1003
|
||||
#define ID_MENU_SHOW_NETLIST 1004
|
||||
#define ID_MENU_SET_SIMUL 1005
|
||||
#define ID_MENU_SHOW_GRID 1006
|
||||
#define ID_MENU_SHOW_LEGEND 1007
|
||||
#define ID_MENU_DOTTED 1008
|
||||
#define ID_MENU_WHITE_BG 1009
|
||||
#define ID_SAVE_AS_IMAGE 1000
|
||||
#define ID_SAVE_AS_CSV 1001
|
||||
#define ID_MENU_RUN_SIM 1002
|
||||
#define ID_MENU_ADD_SIGNAL 1003
|
||||
#define ID_MENU_PROBE_SIGNALS 1004
|
||||
#define ID_MENU_TUNE_SIGNALS 1005
|
||||
#define ID_MENU_SHOW_NETLIST 1006
|
||||
#define ID_MENU_SET_SIMUL 1007
|
||||
#define ID_MENU_SHOW_GRID 1008
|
||||
#define ID_MENU_SHOW_LEGEND 1009
|
||||
#define ID_MENU_DOTTED 1010
|
||||
#define ID_MENU_WHITE_BG 1011
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class SIM_PLOT_FRAME_BASE
|
||||
|
@ -96,6 +98,8 @@ class SIM_PLOT_FRAME_BASE : public KIWAY_PLAYER
|
|||
virtual void menuOpenWorkbook( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuSaveWorkbook( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuSaveWorkbookAs( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuSaveImage( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuSaveCsv( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuExit( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void menuSimulateUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void menuAddSignalsUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
|
Loading…
Reference in New Issue