Support env variables in spice library paths.
Also removes a bunch of std::string stuff from the file handling in the simulator. All our file handling, env variable expansion, project path, etc. stuff is wxString based, and jumping through std::string in between just makes it more complex and increases the potential bug surface. Also fixes a bug where you'd get two error messages when a spice model library wasn't found. Also fixes a bug where you'd get a spice model library not found error when the text field was empty. Also fixes a bug where we'd try to absolutize a path starting with an unresolved text or environment variable. If the path starts with a variable it's probably absolute, and tacking on the project path in the error message just obfuscates things. Fixes https://gitlab.com/kicad/code/kicad/issues/13082
This commit is contained in:
parent
5aa204e194
commit
b15913bd53
|
@ -264,7 +264,7 @@ wxString KIwxExpandEnvVars( const wxString& str, const PROJECT* aProject )
|
|||
}
|
||||
|
||||
|
||||
const wxString ExpandEnvVarSubstitutions( const wxString& aString, PROJECT* aProject )
|
||||
const wxString ExpandEnvVarSubstitutions( const wxString& aString, const PROJECT* aProject )
|
||||
{
|
||||
// wxGetenv( wchar_t* ) is not re-entrant on linux.
|
||||
// Put a lock on multithreaded use of wxGetenv( wchar_t* ), called from wxEpandEnvVars(),
|
||||
|
|
|
@ -306,6 +306,11 @@ const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const
|
|||
{
|
||||
wxFileName fn = aFileName;
|
||||
|
||||
// Paths which start with an unresolved variable reference are more likely to be
|
||||
// absolute than relative.
|
||||
if( aFileName.StartsWith( wxT( "${" ) ) )
|
||||
return aFileName;
|
||||
|
||||
if( !fn.IsAbsolute() )
|
||||
{
|
||||
wxString pro_dir = wxPathOnly( GetProjectFullName() );
|
||||
|
|
|
@ -55,7 +55,8 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
|
|||
m_scintillaTricks( nullptr ),
|
||||
m_wasCodePreviewUpdated( true ),
|
||||
m_firstCategory( nullptr ),
|
||||
m_prevParamGridSelection( nullptr )
|
||||
m_prevParamGridSelection( nullptr ),
|
||||
m_inKillFocus( false )
|
||||
{
|
||||
m_modelNameCombobox->SetValidator( m_modelNameValidator );
|
||||
m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
|
||||
|
@ -262,7 +263,7 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
|
|||
|
||||
if( ( library() && m_useLibraryModelRadioButton->GetValue() ) || isIbisLoaded() )
|
||||
{
|
||||
path = library()->GetFilePath();
|
||||
path = m_libraryPathText->GetValue();
|
||||
wxFileName fn( path );
|
||||
|
||||
if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) )
|
||||
|
@ -618,23 +619,16 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aLibraryPath, bool aForce
|
|||
if( !aForceReload && libraries.size() >= 1 && libraries.begin()->first == aLibraryPath )
|
||||
return;
|
||||
|
||||
|
||||
DIALOG_IBIS_PARSER_REPORTER dlg( this );
|
||||
dlg.m_messagePanel->Clear();
|
||||
|
||||
bool tryingToLoadIbis = false;
|
||||
|
||||
if( aLibraryPath.EndsWith( ".ibs" ) )
|
||||
tryingToLoadIbis = true;
|
||||
|
||||
try
|
||||
{
|
||||
m_libraryModelsMgr.SetLibrary( std::string( aLibraryPath.ToUTF8() ),
|
||||
&dlg.m_messagePanel->Reporter() );
|
||||
m_libraryModelsMgr.CreateLibrary( aLibraryPath, &dlg.m_messagePanel->Reporter() );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
if( tryingToLoadIbis )
|
||||
if( dlg.m_messagePanel->Reporter().HasMessage() )
|
||||
{
|
||||
dlg.m_messagePanel->Flush();
|
||||
dlg.ShowQuasiModal();
|
||||
|
@ -976,11 +970,9 @@ void DIALOG_SIM_MODEL<T>::onLibraryPathTextEnter( wxCommandEvent& aEvent )
|
|||
if( m_useLibraryModelRadioButton->GetValue() )
|
||||
{
|
||||
wxString path = m_libraryPathText->GetValue();
|
||||
wxFileName fn( path );
|
||||
|
||||
if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( ".." ) )
|
||||
path = fn.GetFullPath();
|
||||
|
||||
if( !path.IsEmpty() )
|
||||
{
|
||||
try
|
||||
{
|
||||
loadLibrary( path );
|
||||
|
@ -992,13 +984,33 @@ void DIALOG_SIM_MODEL<T>::onLibraryPathTextEnter( wxCommandEvent& aEvent )
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SIM_MODEL<T>::onLibraryPathText( wxCommandEvent& aEvent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SIM_MODEL<T>::onLibraryPathTextSetFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void DIALOG_SIM_MODEL<T>::onLibraryPathTextKillFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
if( !m_inKillFocus )
|
||||
{
|
||||
m_inKillFocus = true;
|
||||
|
||||
wxCommandEvent dummy;
|
||||
onLibraryPathTextEnter( dummy );
|
||||
|
||||
m_inKillFocus = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,8 +114,10 @@ private:
|
|||
int getModelPinIndex( const wxString& aModelPinString ) const;
|
||||
|
||||
void onRadioButton( wxCommandEvent& aEvent ) override;
|
||||
void onLibraryPathText( wxCommandEvent& aEvent ) override;
|
||||
void onLibraryPathTextEnter( wxCommandEvent& aEvent ) override;
|
||||
void onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) override;
|
||||
void onLibraryPathTextSetFocus( wxFocusEvent& aEvent ) override;
|
||||
void onBrowseButtonClick( wxCommandEvent& aEvent ) override;
|
||||
void onModelNameCombobox( wxCommandEvent& aEvent ) override;
|
||||
void onModelNameComboboxKillFocus( wxFocusEvent& event ) override;
|
||||
|
@ -157,6 +159,8 @@ private:
|
|||
|
||||
wxPGProperty* m_firstCategory; // Used to add principal parameters to root.
|
||||
wxPGProperty* m_prevParamGridSelection;
|
||||
|
||||
bool m_inKillFocus;
|
||||
};
|
||||
|
||||
#endif /* DIALOG_SIM_MODEL_H */
|
||||
|
|
|
@ -281,8 +281,9 @@ DIALOG_SIM_MODEL_BASE::DIALOG_SIM_MODEL_BASE( wxWindow* parent, wxWindowID id, c
|
|||
m_useLibraryModelRadioButton->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_pathLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
||||
m_libraryPathText->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
||||
m_libraryPathText->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextSetFocus ), NULL, this );
|
||||
m_libraryPathText->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathText ), NULL, this );
|
||||
m_libraryPathText->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this );
|
||||
m_libraryPathText->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this );
|
||||
m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
|
||||
m_browseButton->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
|
||||
m_modelNameLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameLabelUpdate ), NULL, this );
|
||||
|
@ -322,8 +323,9 @@ DIALOG_SIM_MODEL_BASE::~DIALOG_SIM_MODEL_BASE()
|
|||
m_useLibraryModelRadioButton->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onRadioButton ), NULL, this );
|
||||
m_pathLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathLabelUpdate ), NULL, this );
|
||||
m_libraryPathText->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextKillFocus ), NULL, this );
|
||||
m_libraryPathText->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextSetFocus ), NULL, this );
|
||||
m_libraryPathText->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathText ), NULL, this );
|
||||
m_libraryPathText->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathTextEnter ), NULL, this );
|
||||
m_libraryPathText->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onLibraryPathUpdate ), NULL, this );
|
||||
m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonClick ), NULL, this );
|
||||
m_browseButton->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onBrowseButtonUpdate ), NULL, this );
|
||||
m_modelNameLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_SIM_MODEL_BASE::onModelNameLabelUpdate ), NULL, this );
|
||||
|
|
|
@ -407,8 +407,9 @@
|
|||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnKillFocus">onLibraryPathTextKillFocus</event>
|
||||
<event name="OnSetFocus">onLibraryPathTextSetFocus</event>
|
||||
<event name="OnText">onLibraryPathText</event>
|
||||
<event name="OnTextEnter">onLibraryPathTextEnter</event>
|
||||
<event name="OnUpdateUI">onLibraryPathUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
|
|
|
@ -87,8 +87,9 @@ class DIALOG_SIM_MODEL_BASE : public DIALOG_SHIM
|
|||
virtual void onRadioButton( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathTextKillFocus( wxFocusEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathTextSetFocus( wxFocusEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathText( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathTextEnter( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onLibraryPathUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onBrowseButtonUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void onModelNameLabelUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
|
|
@ -359,7 +359,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions, REPORTER&
|
|||
|
||||
try
|
||||
{
|
||||
m_libMgr.CreateLibrary( path );
|
||||
m_libMgr.CreateLibrary( path, &aReporter );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
|
@ -408,36 +408,33 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
|
|||
if( auto rawSpiceModel = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model ) )
|
||||
{
|
||||
int libParamIndex = static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
|
||||
std::string path = rawSpiceModel->GetParam( libParamIndex ).value->ToString();
|
||||
wxString path = rawSpiceModel->GetParam( libParamIndex ).value->ToString();
|
||||
|
||||
if( path != "" )
|
||||
if( !path.IsEmpty() )
|
||||
m_rawIncludes.insert( path );
|
||||
}
|
||||
else if( auto kibisModel = dynamic_cast<const SIM_MODEL_KIBIS*>( aItem.model ) )
|
||||
{
|
||||
wxFileName cacheDir;
|
||||
cacheDir.AssignDir( PATHS::GetUserCachePath() );
|
||||
cacheDir.AppendDir( wxT( "ibis" ) );
|
||||
wxFileName cacheFn;
|
||||
cacheFn.AssignDir( PATHS::GetUserCachePath() );
|
||||
cacheFn.AppendDir( wxT( "ibis" ) );
|
||||
cacheFn.SetFullName( aSymbol.GetRef( &aSheet ) + wxT( ".cache" ) );
|
||||
|
||||
std::string libraryPath = fmt::format( "{}/{}.cache",
|
||||
std::string( cacheDir.GetPath() ),
|
||||
std::string( aSymbol.GetRef( &aSheet ) ) );
|
||||
wxFile cacheFile( libraryPath, wxFile::write );
|
||||
wxFile cacheFile( cacheFn.GetFullPath(), wxFile::write );
|
||||
|
||||
if( !cacheFile.IsOpened() )
|
||||
{
|
||||
DisplayErrorMessage( nullptr,
|
||||
wxString::Format( _( "Could not open file '%s' to write IBIS model" ),
|
||||
libraryPath ) );
|
||||
DisplayErrorMessage( nullptr, wxString::Format( _( "Could not open file '%s' to write "
|
||||
"IBIS model" ),
|
||||
cacheFn.GetFullPath() ) );
|
||||
}
|
||||
|
||||
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
|
||||
std::string modelData = spiceGenerator.IbisDevice(
|
||||
aItem, std::string( m_schematic->Prj().GetProjectPath().c_str() ),
|
||||
std::string( cacheDir.GetPath( wxPATH_GET_SEPARATOR ) ).c_str() );
|
||||
std::string modelData = spiceGenerator.IbisDevice( aItem, m_schematic->Prj(),
|
||||
cacheFn.GetPath( wxPATH_GET_SEPARATOR ) );
|
||||
|
||||
cacheFile.Write( wxString( modelData ) );
|
||||
m_rawIncludes.insert( libraryPath );
|
||||
m_rawIncludes.insert( cacheFn.GetFullPath() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,7 +461,7 @@ void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& a
|
|||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
|
||||
const std::string& aPath )
|
||||
const wxString& aPath )
|
||||
{
|
||||
// First, expand env vars, if any.
|
||||
wxString expandedPath = ExpandEnvVarSubstitutions( aPath, &m_schematic->Prj() );
|
||||
|
@ -495,13 +492,13 @@ void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned
|
|||
|
||||
void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
{
|
||||
for( auto&& [path, library] : m_libMgr.GetLibraries() )
|
||||
for( auto& [path, library] : m_libMgr.GetLibraries() )
|
||||
{
|
||||
if( dynamic_cast<const SIM_LIBRARY_SPICE*>( &library.get() ) )
|
||||
writeInclude( aFormatter, aNetlistOptions, path );
|
||||
}
|
||||
|
||||
for( const std::string& path : m_rawIncludes )
|
||||
for( const wxString& path : m_rawIncludes )
|
||||
writeInclude( aFormatter, aNetlistOptions, path );
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ private:
|
|||
void readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& aNcCounter );
|
||||
|
||||
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
|
||||
const std::string& aPath );
|
||||
const wxString& aPath );
|
||||
|
||||
void writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
|
||||
void writeModels( OUTPUTFORMATTER& aFormatter );
|
||||
|
@ -156,7 +156,7 @@ private:
|
|||
std::string m_title; ///< Spice simulation title found in the schematic sheet
|
||||
std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet
|
||||
//std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
|
||||
std::set<std::string> m_rawIncludes; ///< include directives found in symbols
|
||||
std::set<wxString> m_rawIncludes; ///< include directives found in symbols
|
||||
std::set<std::string> m_nets;
|
||||
std::list<SPICE_ITEM> m_items; ///< Items representing schematic symbols in Spice world
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <pgm_base.h>
|
||||
#include <string>
|
||||
#include <common.h>
|
||||
#include <sch_symbol.h>
|
||||
|
||||
// Include simulator headers after wxWidgets headers to avoid conflicts with Windows headers
|
||||
|
@ -33,7 +34,6 @@
|
|||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_model_ideal.h>
|
||||
|
||||
|
||||
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj )
|
||||
{
|
||||
}
|
||||
|
@ -46,26 +46,18 @@ void SIM_LIB_MGR::Clear()
|
|||
}
|
||||
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const std::string& aLibraryPath, REPORTER* aReporter )
|
||||
SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const wxString& aLibraryPath, REPORTER* aReporter )
|
||||
{
|
||||
std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() );
|
||||
|
||||
auto it =
|
||||
m_libraries.try_emplace( aLibraryPath, SIM_LIBRARY::Create( absolutePath, aReporter ) )
|
||||
.first;
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const std::string& aLibraryPath, REPORTER* aReporter )
|
||||
{
|
||||
std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() );
|
||||
wxString path = ExpandEnvVarSubstitutions( aLibraryPath, &m_project );
|
||||
wxString absolutePath = m_project.AbsolutePath( path );
|
||||
|
||||
// May throw an exception.
|
||||
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( absolutePath, aReporter );
|
||||
std::unique_ptr<SIM_LIBRARY> library = SIM_LIBRARY::Create( m_project.AbsolutePath( path ),
|
||||
aReporter );
|
||||
|
||||
Clear();
|
||||
m_libraries[aLibraryPath] = std::move( library );
|
||||
return *m_libraries.at( aLibraryPath );
|
||||
m_libraries[path] = std::move( library );
|
||||
return *m_libraries.at( path );
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,18 +145,18 @@ template SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<LIB_FIEL
|
|||
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::string& aLibraryPath,
|
||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
||||
const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields,
|
||||
int aSymbolPinCount )
|
||||
{
|
||||
std::string absolutePath = std::string( m_project.AbsolutePath( aLibraryPath ).ToUTF8() );
|
||||
wxString path = ExpandEnvVarSubstitutions( aLibraryPath, &m_project );
|
||||
wxString absolutePath = m_project.AbsolutePath( path );
|
||||
SIM_LIBRARY* library = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
auto it = m_libraries.try_emplace( aLibraryPath,
|
||||
SIM_LIBRARY::Create( absolutePath ) ).first;
|
||||
auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( absolutePath ) ).first;
|
||||
library = &*it->second;
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
|
@ -203,9 +195,9 @@ void SIM_LIB_MGR::SetModel( int aIndex, std::unique_ptr<SIM_MODEL> aModel )
|
|||
}
|
||||
|
||||
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> SIM_LIB_MGR::GetLibraries() const
|
||||
std::map<wxString, std::reference_wrapper<const SIM_LIBRARY>> SIM_LIB_MGR::GetLibraries() const
|
||||
{
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> libraries;
|
||||
std::map<wxString, std::reference_wrapper<const SIM_LIBRARY>> libraries;
|
||||
|
||||
for( auto& [path, library] : m_libraries )
|
||||
libraries.try_emplace( path, *library );
|
||||
|
|
|
@ -45,8 +45,7 @@ public:
|
|||
|
||||
void Clear();
|
||||
|
||||
SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath, REPORTER* aReporter = nullptr );
|
||||
SIM_LIBRARY& SetLibrary( const std::string& aLibraryPath, REPORTER* aReporter = nullptr );
|
||||
SIM_LIBRARY& CreateLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
|
||||
SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount );
|
||||
|
||||
|
@ -63,19 +62,17 @@ public:
|
|||
SIM_LIBRARY::MODEL CreateModel( const std::vector<T>& aFields, int aSymbolPinCount );
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL CreateModel( const std::string& aLibraryPath,
|
||||
const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields,
|
||||
int aSymbolPinCount );
|
||||
SIM_LIBRARY::MODEL CreateModel( const wxString& aLibraryPath, const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields, int aSymbolPinCount );
|
||||
|
||||
void SetModel( int aIndex, std::unique_ptr<SIM_MODEL> aModel );
|
||||
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> GetLibraries() const;
|
||||
std::map<wxString, std::reference_wrapper<const SIM_LIBRARY>> GetLibraries() const;
|
||||
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels() const;
|
||||
|
||||
private:
|
||||
const PROJECT& m_project;
|
||||
std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries;
|
||||
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries;
|
||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,18 +27,17 @@
|
|||
#include <sim/sim_library_spice.h>
|
||||
|
||||
|
||||
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( std::string aFilePath, REPORTER* aReporter )
|
||||
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( const wxString& aFilePath, REPORTER* aReporter )
|
||||
{
|
||||
std::unique_ptr<SIM_LIBRARY> library;
|
||||
wxString wxaFilePath( aFilePath );
|
||||
|
||||
if( wxaFilePath.EndsWith( ".ibs" ) )
|
||||
if( aFilePath.EndsWith( ".ibs" ) )
|
||||
library = std::make_unique<SIM_LIBRARY_KIBIS>();
|
||||
else
|
||||
library = std::make_unique<SIM_LIBRARY_SPICE>();
|
||||
|
||||
library->m_reporter = aReporter;
|
||||
library->ReadFile( aFilePath );
|
||||
library->ReadFile( std::string( aFilePath.c_str() ) );
|
||||
return library;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
* @param aReporter The reporter the library reports to
|
||||
* @return The library loaded in a newly constructed object.
|
||||
*/
|
||||
static std::unique_ptr<SIM_LIBRARY> Create( std::string aFilePath,
|
||||
static std::unique_ptr<SIM_LIBRARY> Create( const wxString& aFilePath,
|
||||
REPORTER* aReporter = nullptr );
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <sim/kibis/kibis.h>
|
||||
#include <sim/sim_model_kibis.h>
|
||||
#include <sim/sim_library_kibis.h>
|
||||
#include <paths.h>
|
||||
#include <common.h>
|
||||
#include <fmt/core.h>
|
||||
#include <wx/filename.h>
|
||||
#include <kiway.h>
|
||||
|
@ -58,8 +58,8 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM&
|
|||
}
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
||||
const std::string aCacheDir ) const
|
||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PROJECT& aProject,
|
||||
const wxString& aCacheDir ) const
|
||||
{
|
||||
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::NAME_FIELD );
|
||||
|
@ -67,13 +67,11 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const st
|
|||
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";
|
||||
|
||||
wxFileName libPath = wxFileName( wxString( ibisLibFilename ) );
|
||||
wxString path = ExpandEnvVarSubstitutions( ibisLibFilename, &aProject );
|
||||
wxString absolutePath = aProject.AbsolutePath( path );
|
||||
|
||||
if( !libPath.IsAbsolute() )
|
||||
libPath.MakeAbsolute( aCwd );
|
||||
|
||||
KIBIS kibis( std::string( libPath.GetFullPath().c_str() ) );
|
||||
kibis.m_cacheDir = aCacheDir;
|
||||
KIBIS kibis( std::string( absolutePath.c_str() ) );
|
||||
kibis.m_cacheDir = std::string( aCacheDir.c_str() );
|
||||
|
||||
if( !kibis.m_valid )
|
||||
{
|
||||
|
|
|
@ -41,8 +41,8 @@ public:
|
|||
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
|
||||
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
|
||||
|
||||
std::string IbisDevice( const SPICE_ITEM& aItem, const std::string aCwd,
|
||||
const std::string aCacheDir ) const;
|
||||
std::string IbisDevice( const SPICE_ITEM& aItem, const PROJECT& aProject,
|
||||
const wxString& aCacheDir ) const;
|
||||
|
||||
protected:
|
||||
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;
|
||||
|
|
|
@ -76,7 +76,7 @@ bool EnsureFileDirectoryExists( wxFileName* aTargetFullFileName,
|
|||
* @param aString a string containing (perhaps) references to env var
|
||||
* @return the expanded environment variable.
|
||||
*/
|
||||
const wxString ExpandEnvVarSubstitutions( const wxString& aString, PROJECT* aProject );
|
||||
const wxString ExpandEnvVarSubstitutions( const wxString& aString, const PROJECT* aProject );
|
||||
|
||||
/**
|
||||
* Expand '${var-name}' templates in text. The LocalResolver is given first crack at it,
|
||||
|
|
Loading…
Reference in New Issue