From b15913bd5309067a14d6e12f4bd17aa812e62c4a Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 7 Dec 2022 15:02:35 +0000 Subject: [PATCH] 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 --- common/common.cpp | 2 +- common/project.cpp | 5 ++ eeschema/dialogs/dialog_sim_model.cpp | 60 +++++++++++-------- eeschema/dialogs/dialog_sim_model.h | 4 ++ eeschema/dialogs/dialog_sim_model_base.cpp | 6 +- eeschema/dialogs/dialog_sim_model_base.fbp | 3 +- eeschema/dialogs/dialog_sim_model_base.h | 3 +- .../netlist_exporter_spice.cpp | 39 ++++++------ .../netlist_exporter_spice.h | 4 +- eeschema/sim/sim_lib_mgr.cpp | 36 +++++------ eeschema/sim/sim_lib_mgr.h | 17 +++--- eeschema/sim/sim_library.cpp | 7 +-- eeschema/sim/sim_library.h | 4 +- eeschema/sim/sim_model_kibis.cpp | 18 +++--- eeschema/sim/sim_model_kibis.h | 4 +- include/common.h | 2 +- 16 files changed, 111 insertions(+), 103 deletions(-) diff --git a/common/common.cpp b/common/common.cpp index 5ea1bcd868..1896233dda 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -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(), diff --git a/common/project.cpp b/common/project.cpp index b40db57164..f14ed69e45 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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() ); diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index 29c60efd18..3d0a52a178 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -55,7 +55,8 @@ DIALOG_SIM_MODEL::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::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::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,29 +970,47 @@ void DIALOG_SIM_MODEL::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(); - - try + if( !path.IsEmpty() ) { - loadLibrary( path ); - updateWidgets(); - } - catch( const IO_ERROR& ) - { - // TODO: Add an infobar to report the error? + try + { + loadLibrary( path ); + updateWidgets(); + } + catch( const IO_ERROR& ) + { + // TODO: Add an infobar to report the error? + } } } } +template +void DIALOG_SIM_MODEL::onLibraryPathText( wxCommandEvent& aEvent ) +{ +} + + +template +void DIALOG_SIM_MODEL::onLibraryPathTextSetFocus( wxFocusEvent& aEvent ) +{ +} + + template void DIALOG_SIM_MODEL::onLibraryPathTextKillFocus( wxFocusEvent& aEvent ) { - wxCommandEvent dummy; - onLibraryPathTextEnter( dummy ); + if( !m_inKillFocus ) + { + m_inKillFocus = true; + + wxCommandEvent dummy; + onLibraryPathTextEnter( dummy ); + + m_inKillFocus = false; + } } diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index cb67f9ffca..b272d4a160 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -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 */ diff --git a/eeschema/dialogs/dialog_sim_model_base.cpp b/eeschema/dialogs/dialog_sim_model_base.cpp index bd3e6b5439..7ec432db01 100644 --- a/eeschema/dialogs/dialog_sim_model_base.cpp +++ b/eeschema/dialogs/dialog_sim_model_base.cpp @@ -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 ); diff --git a/eeschema/dialogs/dialog_sim_model_base.fbp b/eeschema/dialogs/dialog_sim_model_base.fbp index 1023791fd8..7208d290b5 100644 --- a/eeschema/dialogs/dialog_sim_model_base.fbp +++ b/eeschema/dialogs/dialog_sim_model_base.fbp @@ -407,8 +407,9 @@ onLibraryPathTextKillFocus + onLibraryPathTextSetFocus + onLibraryPathText onLibraryPathTextEnter - onLibraryPathUpdate diff --git a/eeschema/dialogs/dialog_sim_model_base.h b/eeschema/dialogs/dialog_sim_model_base.h index 30d2ae0f95..319f0e1806 100644 --- a/eeschema/dialogs/dialog_sim_model_base.h +++ b/eeschema/dialogs/dialog_sim_model_base.h @@ -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(); } diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.cpp b/eeschema/netlist_exporters/netlist_exporter_spice.cpp index 69645a1019..75c71d7d2d 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_spice.cpp @@ -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 ) { @@ -407,37 +407,34 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym // FIXME: Don't have special cases for raw Spice models and KIBIS. if( auto rawSpiceModel = dynamic_cast( aItem.model ) ) { - int libParamIndex = static_cast( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB ); - std::string path = rawSpiceModel->GetParam( libParamIndex ).value->ToString(); + int libParamIndex = static_cast( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB ); + wxString path = rawSpiceModel->GetParam( libParamIndex ).value->ToString(); - if( path != "" ) + if( !path.IsEmpty() ) m_rawIncludes.insert( path ); } else if( auto kibisModel = dynamic_cast( 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( 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( &library.get() ) ) writeInclude( aFormatter, aNetlistOptions, path ); } - for( const std::string& path : m_rawIncludes ) + for( const wxString& path : m_rawIncludes ) writeInclude( aFormatter, aNetlistOptions, path ); } diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.h b/eeschema/netlist_exporters/netlist_exporter_spice.h index 10ae7fff8d..8499045752 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.h +++ b/eeschema/netlist_exporters/netlist_exporter_spice.h @@ -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 m_directives; ///< Spice directives found in the schematic sheet //std::map> m_libraries; ///< Spice libraries - std::set m_rawIncludes; ///< include directives found in symbols + std::set m_rawIncludes; ///< include directives found in symbols std::set m_nets; std::list m_items; ///< Items representing schematic symbols in Spice world }; diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index a133c0c6a4..b4952bda46 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -24,6 +24,7 @@ #include #include +#include #include // Include simulator headers after wxWidgets headers to avoid conflicts with Windows headers @@ -33,7 +34,6 @@ #include #include - 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 library = SIM_LIBRARY::Create( absolutePath, aReporter ); + std::unique_ptr 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 -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& 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 aModel ) } -std::map> SIM_LIB_MGR::GetLibraries() const +std::map> SIM_LIB_MGR::GetLibraries() const { - std::map> libraries; + std::map> libraries; for( auto& [path, library] : m_libraries ) libraries.try_emplace( path, *library ); diff --git a/eeschema/sim/sim_lib_mgr.h b/eeschema/sim/sim_lib_mgr.h index fe5f49ab17..9dc4c6d20e 100644 --- a/eeschema/sim/sim_lib_mgr.h +++ b/eeschema/sim/sim_lib_mgr.h @@ -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,20 +62,18 @@ public: SIM_LIBRARY::MODEL CreateModel( const std::vector& aFields, int aSymbolPinCount ); template - SIM_LIBRARY::MODEL CreateModel( const std::string& aLibraryPath, - const std::string& aBaseModelName, - const std::vector& aFields, - int aSymbolPinCount ); + SIM_LIBRARY::MODEL CreateModel( const wxString& aLibraryPath, const std::string& aBaseModelName, + const std::vector& aFields, int aSymbolPinCount ); void SetModel( int aIndex, std::unique_ptr aModel ); - std::map> GetLibraries() const; + std::map> GetLibraries() const; std::vector> GetModels() const; private: - const PROJECT& m_project; - std::map> m_libraries; - std::vector> m_models; + const PROJECT& m_project; + std::map> m_libraries; + std::vector> m_models; }; diff --git a/eeschema/sim/sim_library.cpp b/eeschema/sim/sim_library.cpp index 37ebfbebdc..9333db4700 100644 --- a/eeschema/sim/sim_library.cpp +++ b/eeschema/sim/sim_library.cpp @@ -27,18 +27,17 @@ #include -std::unique_ptr SIM_LIBRARY::Create( std::string aFilePath, REPORTER* aReporter ) +std::unique_ptr SIM_LIBRARY::Create( const wxString& aFilePath, REPORTER* aReporter ) { std::unique_ptr library; - wxString wxaFilePath( aFilePath ); - if( wxaFilePath.EndsWith( ".ibs" ) ) + if( aFilePath.EndsWith( ".ibs" ) ) library = std::make_unique(); else library = std::make_unique(); library->m_reporter = aReporter; - library->ReadFile( aFilePath ); + library->ReadFile( std::string( aFilePath.c_str() ) ); return library; } diff --git a/eeschema/sim/sim_library.h b/eeschema/sim/sim_library.h index 2e6760297a..341eeff6d6 100644 --- a/eeschema/sim/sim_library.h +++ b/eeschema/sim/sim_library.h @@ -52,8 +52,8 @@ public: * @param aReporter The reporter the library reports to * @return The library loaded in a newly constructed object. */ - static std::unique_ptr Create( std::string aFilePath, - REPORTER* aReporter = nullptr ); + static std::unique_ptr Create( const wxString& aFilePath, + REPORTER* aReporter = nullptr ); /** * Read library from a source file. Must be in the format appropriate to the subclass, e.g. diff --git a/eeschema/sim/sim_model_kibis.cpp b/eeschema/sim/sim_model_kibis.cpp index 008cdf6a58..c46f4cb8be 100644 --- a/eeschema/sim/sim_model_kibis.cpp +++ b/eeschema/sim/sim_model_kibis.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -58,22 +58,20 @@ std::vector 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 ); std::string ibisPinName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD ); 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"; + 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 ) { diff --git a/eeschema/sim/sim_model_kibis.h b/eeschema/sim/sim_model_kibis.h index 729a70e0f6..50b3f4f874 100644 --- a/eeschema/sim/sim_model_kibis.h +++ b/eeschema/sim/sim_model_kibis.h @@ -41,8 +41,8 @@ public: std::string ModelLine( const SPICE_ITEM& aItem ) const override; std::vector 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> GetInstanceParams() const override; diff --git a/include/common.h b/include/common.h index 6c534d29cb..f74f6f468a 100644 --- a/include/common.h +++ b/include/common.h @@ -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,