Don't attempt to read simulation model if symbol isn't included.

Also collect up all errors for one dialog when preparing simulation.
Also translate error messages.

Fixes https://gitlab.com/kicad/code/kicad/issues/12686
This commit is contained in:
Jeff Young 2022-10-26 00:31:48 +01:00
parent 5f0ebfbfbd
commit 445657022b
3 changed files with 47 additions and 37 deletions

View File

@ -41,7 +41,7 @@
#include <sch_textbox.h>
#include <string_utils.h>
#include <dialogs/html_message_box.h>
#include <boost/algorithm/string/replace.hpp>
#include <fmt/core.h>
#include <paths.h>
@ -148,10 +148,11 @@ void NETLIST_EXPORTER_SPICE::WriteTail( OUTPUTFORMATTER& aFormatter, unsigned aN
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
{
wxArrayString error_msgs;
std::set<std::string> refNames; // Set of reference names to check for duplication.
int ncCounter = 1;
int ncCounter = 1;
ReadDirectives( aNetlistOptions );
ReadDirectives( aNetlistOptions, error_msgs );
m_nets.clear();
m_items.clear();
@ -167,9 +168,9 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
if( !cacheDir.DirExists() )
{
wxLogTrace(
"IBIS_CACHE:", wxT( "%s:%s:%d\n * failed to create ibis cache directory '%s'" ),
__FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
wxLogTrace( wxT( "IBIS_CACHE:" ),
wxT( "%s:%s:%d\n * failed to create ibis cache directory '%s'" ),
__FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
return false;
}
@ -202,7 +203,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
{
SCH_SYMBOL* symbol = findNextSymbol( item, &sheet );
if( !symbol )
if( !symbol || symbol->GetFieldText( SIM_MODEL::ENABLE_FIELD ) == wxT( "0" ) )
continue;
CreatePinList( symbol, &sheet, true );
@ -231,14 +232,22 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
}
catch( const IO_ERROR& e )
{
DisplayErrorMessage( nullptr,
wxString::Format( "Failed reading simulation model from symbol '%s':\n%s",
symbol->GetRef( &sheet ),
e.What() ) );
error_msgs.Add( wxString::Format( _( "Error reading simulation model from symbol "
"'%s':\n%s" ),
symbol->GetRef( &sheet ),
e.What() ) );
}
}
}
if( error_msgs.GetCount() )
{
HTML_MESSAGE_BOX dlg( nullptr, _( "Errors" ) );
dlg.ListSet( error_msgs );
dlg.ShowModal();
}
return true;
}
@ -279,7 +288,7 @@ const SPICE_ITEM* NETLIST_EXPORTER_SPICE::FindItem( const std::string& aRefName
}
void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions, wxArrayString& aErrors )
{
m_directives.clear();
@ -330,9 +339,10 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
}
catch( const IO_ERROR& e )
{
DisplayErrorMessage( nullptr,
wxString::Format( "Failed reading model library '%s'.", path ),
e.What() );
aErrors.Add( wxString::Format( _( "Error reading simulation model library "
"'%s':\n%s" ),
path,
e.What() ) );
}
}
else

View File

@ -123,7 +123,7 @@ public:
const std::vector<std::string>& GetDirectives() { return m_directives; }
protected:
void ReadDirectives( unsigned aNetlistOptions = 0 );
void ReadDirectives( unsigned aNetlistOptions, wxArrayString& aErrors );
virtual void WriteDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) const;
virtual std::string GenerateItemPinNetName( const std::string& aNetName, int& aNcCounter ) const;

View File

@ -4,7 +4,7 @@
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -25,15 +25,14 @@
*/
#include "ngspice_helpers.h"
#include <string_utils.h>
#include <macros.h> // for TO_UTF8 def
#include <wx/regex.h>
#include <wx/tokenzr.h>
#include <locale_io.h>
SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
const std::string& aVector, wxString& aSignal ) const
SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal( const std::string& aVector,
wxString& aSignal ) const
{
using namespace std;
@ -44,7 +43,7 @@ SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
if( !internalDevParameter.Matches( vector ) )
{
// any text is a node name, which returns voltage
aSignal = "V(" + aVector + ")";
aSignal = wxT( "V(" ) + aVector + wxT( ")" );
return SPT_VOLTAGE;
}
else
@ -55,8 +54,8 @@ SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
{
// this is a branch current
paramType[0] = 'I';
aSignal = paramType + "(";
aSignal += internalDevParameter.GetMatch( vector, 1 ).Upper() + ")";
aSignal = paramType + wxT( "(" );
aSignal += internalDevParameter.GetMatch( vector, 1 ).Upper() + wxT( ")" );
return SPT_CURRENT;
}
else
@ -69,14 +68,15 @@ SIM_PLOT_TYPE NGSPICE_CIRCUIT_MODEL::VectorToSignal(
wxString NGSPICE_CIRCUIT_MODEL::GetSheetSimCommand()
{
wxString simCmd;
wxArrayString error_msgs;
wxString simCmd;
ReadDirectives();
ReadDirectives( 0, error_msgs );
for( const auto& directive : GetDirectives() )
for( const std::string& directive : GetDirectives() )
{
if( IsSimCommand( directive ) )
simCmd += wxString::Format( "%s\r\n", directive );
simCmd += wxString::Format( wxT( "%s\r\n" ), directive );
}
return simCmd;
@ -92,18 +92,18 @@ SIM_TYPE NGSPICE_CIRCUIT_MODEL::GetSimType()
SIM_TYPE NGSPICE_CIRCUIT_MODEL::CommandToSimType( const wxString& aCmd )
{
const std::vector<std::pair<wxString, SIM_TYPE>> simCmds = {
{ "^.ac\\M.*", ST_AC },
{ "^.dc\\M.*", ST_DC },
{ "^.tran\\M.*", ST_TRANSIENT },
{ "^.op\\M.*", ST_OP },
{ "^.disto\\M.*", ST_DISTORTION },
{ "^.noise\\M.*", ST_NOISE },
{ "^.pz\\M.*", ST_POLE_ZERO },
{ "^.sens\\M.*", ST_SENSITIVITY },
{ "^.tf\\M.*", ST_TRANS_FUNC } };
{ wxT( "^.ac\\M.*" ), ST_AC },
{ wxT( "^.dc\\M.*" ), ST_DC },
{ wxT( "^.tran\\M.*" ), ST_TRANSIENT },
{ wxT( "^.op\\M.*" ), ST_OP },
{ wxT( "^.disto\\M.*" ), ST_DISTORTION },
{ wxT( "^.noise\\M.*" ), ST_NOISE },
{ wxT( "^.pz\\M.*" ), ST_POLE_ZERO },
{ wxT( "^.sens\\M.*" ), ST_SENSITIVITY },
{ wxT( "^.tf\\M.*" ), ST_TRANS_FUNC } };
wxRegEx simCmd;
for( const auto& c : simCmds )
for( const std::pair<wxString, SIM_TYPE>& c : simCmds )
{
simCmd.Compile( c.first, wxRE_ADVANCED | wxRE_NOSUB | wxRE_ICASE );