diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index 97cb91612f..3af6689324 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -209,7 +209,7 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() { if( strs.first == SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY_KIBIS::PIN_FIELD ) ) { - auto kibisLibrary = static_cast( m_libraryModelsMgr.GetLibrary() ); + auto kibisLibrary = static_cast( library() ); kibismodel->ChangePin( *kibisLibrary, strs.first ); m_ibisPinCombobox->SetSelection( static_cast( i ) ); @@ -309,8 +309,7 @@ bool DIALOG_SIM_MODEL::TransferDataFromWindow() std::string path; - if( ( m_libraryModelsMgr.GetLibrary() && m_useLibraryModelRadioButton->GetValue() ) - || isIbisLoaded() ) + if( ( library() && m_useLibraryModelRadioButton->GetValue() ) || isIbisLoaded() ) { path = m_libraryPathText->GetValue(); wxFileName fn( path ); @@ -697,7 +696,7 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryP std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD ); - for( auto& [baseModelName, baseModel] : m_libraryModelsMgr.GetLibrary()->GetModels() ) + for( auto& [baseModelName, baseModel] : library()->GetModels() ) { if( baseModelName == modelName ) m_libraryModelsMgr.CreateModel( &baseModel, sourcePins, m_fields ); @@ -713,7 +712,7 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aLibraryP wxArrayString modelNames; - for( auto& [name, model] : m_libraryModelsMgr.GetLibrary()->GetModels() ) + for( auto& [name, model] : library()->GetModels() ) modelNames.Add( name ); m_modelNameChoice->Clear(); @@ -922,6 +921,16 @@ SIM_MODEL& DIALOG_SIM_MODEL::curModel() const } +template +const SIM_LIBRARY* DIALOG_SIM_MODEL::library() const +{ + if( m_libraryModelsMgr.GetLibraries().size() == 1 ) + return &m_libraryModelsMgr.GetLibraries().begin()->second.get(); + + return nullptr; +} + + template wxString DIALOG_SIM_MODEL::getSymbolPinString( int symbolPinIndex ) const { @@ -1092,7 +1101,7 @@ void DIALOG_SIM_MODEL::onIbisPinCombobox( wxCommandEvent& aEv std::vector> strs = ibisModel.GetIbisPins(); std::string pinNumber = strs.at( m_ibisPinCombobox->GetSelection() ).first; - auto ibisLibrary = static_cast( m_libraryModelsMgr.GetLibrary() ); + const SIM_LIBRARY_KIBIS* ibisLibrary = dynamic_cast( library() ); ibisModel.ChangePin( *ibisLibrary, pinNumber ); diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index c276c41f13..ebef451d52 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -86,6 +86,7 @@ private: int findSymbolPinRow( const wxString& aSymbolPinNumber ) const; SIM_MODEL& curModel() const; + const SIM_LIBRARY* library() const; wxString getSymbolPinString( int aSymbolPinNumber ) const; wxString getModelPinString( int aModelPinIndex ) const; @@ -113,10 +114,7 @@ private: void adjustParamGridColumns( int aWidth, bool aForce ); - bool isIbisLoaded() - { - return dynamic_cast( m_libraryModelsMgr.GetLibrary() ) != nullptr; - } + bool isIbisLoaded() { return dynamic_cast( library() ); } private: T_symbol& m_symbol; diff --git a/eeschema/netlist_exporters/netlist_exporter_spice.cpp b/eeschema/netlist_exporters/netlist_exporter_spice.cpp index f459b2ed22..44fc5b60eb 100644 --- a/eeschema/netlist_exporters/netlist_exporter_spice.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_spice.cpp @@ -392,9 +392,29 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions ) } catch( const tao::pegtl::parse_error& ) { - // If we couldn't parse it, but it -looks- like SPICE, then send it as raw SPICE - if( text.StartsWith( "." ) || text.StartsWith( "*" ) ) - m_directives.emplace_back( text ); + // Even if we couldn't parse it, send anything that _looks_ like a directive to + // SPICE + wxStringTokenizer tokenizer( text, wxT( "\r\n" ), wxTOKEN_STRTOK ); + bool inDirective = false; + + while( tokenizer.HasMoreTokens() ) + { + wxString line = tokenizer.GetNextToken(); + + if( line.StartsWith( "." ) ) + { + m_directives.emplace_back( line ); + inDirective = true; + } + else if( inDirective && line.StartsWith( "+" ) ) + { + m_directives.emplace_back( line ); + } + else + { + inDirective = false; + } + } continue; } diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index 11714098c2..7b990ced15 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -46,6 +46,13 @@ SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT* aPrj, REPORTER* aReporter ) : } +void SIM_LIB_MGR::Clear() +{ + m_libraries.clear(); + m_models.clear(); +} + + wxString SIM_LIB_MGR::ResolveLibraryPath( const wxString& aLibraryPath, const PROJECT* aProject ) { wxString expandedPath = ExpandEnvVarSubstitutions( aLibraryPath, aProject ); @@ -114,9 +121,6 @@ std::string SIM_LIB_MGR::ResolveEmbeddedLibraryPath( const std::string& aLibPath void SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath ) { - m_models.clear(); - m_library = nullptr; - try { wxString path = ResolveLibraryPath( aLibraryPath, m_project ); @@ -124,7 +128,10 @@ void SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath ) std::function f2 = std::bind( &SIM_LIB_MGR::ResolveEmbeddedLibraryPath, this, _1, _2 ); - m_library = SIM_LIBRARY::Create( path, m_reporter, &f2 ); + std::unique_ptr library = SIM_LIBRARY::Create( path, m_reporter, &f2 ); + + Clear(); + m_libraries[path] = std::move( library ); } catch( const IO_ERROR& e ) { @@ -264,11 +271,10 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath, { wxString path; wxString msg; + SIM_LIBRARY* library = nullptr; SIM_MODEL* baseModel = nullptr; std::string modelName; - wxASSERT( !m_library ); - try { path = ResolveLibraryPath( aLibraryPath, m_project ); @@ -276,7 +282,8 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath, std::function f2 = std::bind( &SIM_LIB_MGR::ResolveEmbeddedLibraryPath, this, _1, _2 ); - m_library = SIM_LIBRARY::Create( path, m_reporter, &f2 ); + auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( path, m_reporter, &f2 ) ).first; + library = &*it->second; } catch( const IO_ERROR& e ) { @@ -302,9 +309,9 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath, modelName = _( "unknown" ).ToStdString(); } - else if( m_library ) + else if( library ) { - baseModel = m_library->FindModel( aBaseModelName ); + baseModel = library->FindModel( aBaseModelName ); modelName = aBaseModelName; if( !baseModel ) @@ -327,18 +334,23 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath, } -const SIM_LIBRARY* SIM_LIB_MGR::GetLibrary() const -{ - return m_library.get(); -} - - void SIM_LIB_MGR::SetModel( int aIndex, std::unique_ptr aModel ) { m_models.at( aIndex ) = std::move( aModel ); } +std::map> SIM_LIB_MGR::GetLibraries() const +{ + std::map> libraries; + + for( auto& [path, library] : m_libraries ) + libraries.try_emplace( path, *library ); + + return libraries; +} + + std::vector> SIM_LIB_MGR::GetModels() const { std::vector> models; diff --git a/eeschema/sim/sim_lib_mgr.h b/eeschema/sim/sim_lib_mgr.h index d1eca311f6..4b8964b7b5 100644 --- a/eeschema/sim/sim_lib_mgr.h +++ b/eeschema/sim/sim_lib_mgr.h @@ -45,8 +45,9 @@ public: void SetReporter( REPORTER* aReporter ) { m_reporter = aReporter; } + void Clear(); + void SetLibrary( const wxString& aLibraryPath ); - const SIM_LIBRARY* GetLibrary() const; SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, const std::vector& aPins ); @@ -71,6 +72,7 @@ public: void SetModel( int aIndex, std::unique_ptr aModel ); + std::map> GetLibraries() const; std::vector> GetModels() const; static wxString ResolveLibraryPath( const wxString& aLibraryPath, const PROJECT* aProject ); @@ -79,10 +81,10 @@ public: const std::string& aRelativeLib ); private: - const PROJECT* m_project; - REPORTER* m_reporter; - std::unique_ptr m_library; - std::vector> m_models; + const PROJECT* m_project; + REPORTER* m_reporter; + std::map> m_libraries; + std::vector> m_models; };