Mostly coding standards, but also quote codemodel names before passing to spice.

Fixes https://gitlab.com/kicad/code/kicad/issues/12687
This commit is contained in:
Jeff Young 2022-12-11 18:41:01 +00:00
parent 65538ccad4
commit 5c53daadb0
1 changed files with 56 additions and 61 deletions

View File

@ -26,27 +26,23 @@
*/ */
#include <config.h> // Needed for MSW compilation #include <config.h> // Needed for MSW compilation
#include <wx/log.h> #include <common.h>
#include <locale_io.h>
#include <fmt/core.h>
#include <paths.h>
#include "ngspice_circuit_model.h" #include "ngspice_circuit_model.h"
#include "ngspice.h" #include "ngspice.h"
#include "spice_reporter.h" #include "spice_reporter.h"
#include "spice_settings.h" #include "spice_settings.h"
#include <common.h>
#include <locale_io.h>
#include <paths.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/dir.h> #include <wx/dir.h>
#include <wx/log.h>
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
using namespace std;
/** /**
* Flag to enable debug output of Ngspice simulator. * Flag to enable debug output of Ngspice simulator.
@ -88,14 +84,14 @@ void NGSPICE::Init( const SPICE_SIMULATOR_SETTINGS* aSettings )
} }
vector<string> NGSPICE::AllPlots() const std::vector<std::string> NGSPICE::AllPlots() const
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
char* currentPlot = m_ngSpice_CurPlot(); char* currentPlot = m_ngSpice_CurPlot();
char** allPlots = m_ngSpice_AllVecs( currentPlot ); char** allPlots = m_ngSpice_AllVecs( currentPlot );
int noOfPlots = 0; int noOfPlots = 0;
vector<string> retVal; std::vector<std::string> retVal;
if( allPlots != nullptr ) if( allPlots != nullptr )
{ {
@ -106,7 +102,7 @@ vector<string> NGSPICE::AllPlots() const
for( int i = 0; i < noOfPlots; i++, allPlots++ ) for( int i = 0; i < noOfPlots; i++, allPlots++ )
{ {
string vec = *allPlots; std::string vec = *allPlots;
retVal.push_back( vec ); retVal.push_back( vec );
} }
} }
@ -116,11 +112,11 @@ vector<string> NGSPICE::AllPlots() const
} }
vector<COMPLEX> NGSPICE::GetPlot( const string& aName, int aMaxLen ) std::vector<COMPLEX> NGSPICE::GetPlot( const std::string& aName, int aMaxLen )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<COMPLEX> data; std::vector<COMPLEX> data;
vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ); vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
if( vi ) if( vi )
{ {
@ -143,11 +139,11 @@ vector<COMPLEX> NGSPICE::GetPlot( const string& aName, int aMaxLen )
} }
vector<double> NGSPICE::GetRealPlot( const string& aName, int aMaxLen ) std::vector<double> NGSPICE::GetRealPlot( const std::string& aName, int aMaxLen )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<double> data; std::vector<double> data;
vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ); vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
if( vi ) if( vi )
{ {
@ -157,9 +153,7 @@ vector<double> NGSPICE::GetRealPlot( const string& aName, int aMaxLen )
if( vi->v_realdata ) if( vi->v_realdata )
{ {
for( int i = 0; i < length; i++ ) for( int i = 0; i < length; i++ )
{
data.push_back( vi->v_realdata[i] ); data.push_back( vi->v_realdata[i] );
}
} }
else if( vi->v_compdata ) else if( vi->v_compdata )
{ {
@ -175,11 +169,11 @@ vector<double> NGSPICE::GetRealPlot( const string& aName, int aMaxLen )
} }
vector<double> NGSPICE::GetImagPlot( const string& aName, int aMaxLen ) std::vector<double> NGSPICE::GetImagPlot( const std::string& aName, int aMaxLen )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<double> data; std::vector<double> data;
vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ); vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
if( vi ) if( vi )
{ {
@ -189,9 +183,7 @@ vector<double> NGSPICE::GetImagPlot( const string& aName, int aMaxLen )
if( vi->v_compdata ) if( vi->v_compdata )
{ {
for( int i = 0; i < length; i++ ) for( int i = 0; i < length; i++ )
{
data.push_back( vi->v_compdata[i].cx_imag ); data.push_back( vi->v_compdata[i].cx_imag );
}
} }
} }
@ -199,11 +191,11 @@ vector<double> NGSPICE::GetImagPlot( const string& aName, int aMaxLen )
} }
vector<double> NGSPICE::GetMagPlot( const string& aName, int aMaxLen ) std::vector<double> NGSPICE::GetMagPlot( const std::string& aName, int aMaxLen )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<double> data; std::vector<double> data;
vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ); vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
if( vi ) if( vi )
{ {
@ -226,10 +218,10 @@ vector<double> NGSPICE::GetMagPlot( const string& aName, int aMaxLen )
} }
vector<double> NGSPICE::GetPhasePlot( const string& aName, int aMaxLen ) std::vector<double> NGSPICE::GetPhasePlot( const std::string& aName, int aMaxLen )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<double> data; std::vector<double> data;
vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ); vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
if( vi ) if( vi )
@ -275,11 +267,11 @@ bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, REPORTER&
} }
bool NGSPICE::LoadNetlist( const string& aNetlist ) bool NGSPICE::LoadNetlist( const std::string& aNetlist )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
vector<char*> lines; std::vector<char*> lines;
stringstream ss( aNetlist ); std::stringstream ss( aNetlist );
m_netlist = ""; m_netlist = "";
@ -339,7 +331,7 @@ bool NGSPICE::IsRunning()
} }
bool NGSPICE::Command( const string& aCmd ) bool NGSPICE::Command( const std::string& aCmd )
{ {
LOCALE_IO c_locale; // ngspice works correctly only with C locale LOCALE_IO c_locale; // ngspice works correctly only with C locale
validate(); validate();
@ -347,37 +339,37 @@ bool NGSPICE::Command( const string& aCmd )
} }
string NGSPICE::GetXAxis( SIM_TYPE aType ) const std::string NGSPICE::GetXAxis( SIM_TYPE aType ) const
{ {
switch( aType ) switch( aType )
{ {
case ST_AC: case ST_AC:
case ST_NOISE: case ST_NOISE:
return string( "frequency" ); return std::string( "frequency" );
case ST_DC: case ST_DC:
// find plot, which ends with "-sweep" // find plot, which ends with "-sweep"
for( auto& plot : AllPlots() ) for( auto& plot : AllPlots() )
{ {
const string sweepEnding = "-sweep"; const std::string sweepEnding = "-sweep";
unsigned int len = sweepEnding.length(); unsigned int len = sweepEnding.length();
if( plot.length() > len if( plot.length() > len
&& plot.substr( plot.length() - len, len ).compare( sweepEnding ) == 0 ) && plot.substr( plot.length() - len, len ).compare( sweepEnding ) == 0 )
{ {
return string( plot ); return std::string( plot );
} }
} }
break; break;
case ST_TRANSIENT: case ST_TRANSIENT:
return string( "time" ); return std::string( "time" );
default: default:
break; break;
} }
return string( "" ); return std::string( "" );
} }
@ -447,12 +439,12 @@ void NGSPICE::init_dll()
wxFileName dllFile( "", NGSPICE_DLL_FILE ); wxFileName dllFile( "", NGSPICE_DLL_FILE );
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
#if defined( _MSC_VER ) #if defined( _MSC_VER )
const vector<string> dllPaths = { "" }; const std::vector<string> dllPaths = { "" };
#else #else
const vector<string> dllPaths = { "", "/mingw64/bin", "/mingw32/bin" }; const std::vector<string> dllPaths = { "", "/mingw64/bin", "/mingw32/bin" };
#endif #endif
#elif defined(__WXMAC__) #elif defined(__WXMAC__)
const vector<string> dllPaths = { const std::vector<std::string> dllPaths = {
PATHS::GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice", PATHS::GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice",
PATHS::GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice", PATHS::GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice",
@ -464,7 +456,7 @@ void NGSPICE::init_dll()
"/../../../../../Contents/PlugIns/sim" "/../../../../../Contents/PlugIns/sim"
}; };
#else // Unix systems #else // Unix systems
const vector<string> dllPaths = { "/usr/local/lib" }; const std::vector<string> dllPaths = { "/usr/local/lib" };
#endif #endif
#if defined(__WINDOWS__) || (__WXMAC__) #if defined(__WINDOWS__) || (__WXMAC__)
@ -520,7 +512,7 @@ void NGSPICE::init_dll()
m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" ); m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" );
m_ngSpice_Running = (ngSpice_Running) m_dll.GetSymbol( "ngSpice_running" ); // it is not a typo m_ngSpice_Running = (ngSpice_Running) m_dll.GetSymbol( "ngSpice_running" ); // it is not a typo
m_ngSpice_Init( &cbSendChar, &cbSendStat, &cbControlledExit, NULL, NULL, m_ngSpice_Init( &cbSendChar, &cbSendStat, &cbControlledExit, nullptr, nullptr,
&cbBGThreadRunning, this ); &cbBGThreadRunning, this );
// Load a custom spinit file, to fix the problem with loading .cm files // Load a custom spinit file, to fix the problem with loading .cm files
@ -530,14 +522,14 @@ void NGSPICE::init_dll()
wxSetWorkingDirectory( exeDir.GetPath() ); wxSetWorkingDirectory( exeDir.GetPath() );
// Find *.cm files // Find *.cm files
string cmPath = findCmPath(); std::string cmPath = findCmPath();
// __CMPATH is used in custom spinit file to point to the codemodels directory // __CMPATH is used in custom spinit file to point to the codemodels directory
if( !cmPath.empty() ) if( !cmPath.empty() )
Command( "set __CMPATH=\"" + cmPath + "\"" ); Command( "set __CMPATH=\"" + cmPath + "\"" );
// Possible relative locations for spinit file // Possible relative locations for spinit file
const vector<string> spiceinitPaths = const std::vector<std::string> spiceinitPaths =
{ {
".", ".",
#ifdef __WXMAC__ #ifdef __WXMAC__
@ -582,7 +574,7 @@ void NGSPICE::init_dll()
// reset and remcirc give an error if no circuit is loaded, so load an empty circuit at the // reset and remcirc give an error if no circuit is loaded, so load an empty circuit at the
// start. // start.
vector<char*> lines; std::vector<char*> lines;
lines.push_back( strdup( "*" ) ); lines.push_back( strdup( "*" ) );
lines.push_back( strdup( ".end" ) ); lines.push_back( strdup( ".end" ) );
lines.push_back( nullptr ); // Sentinel. lines.push_back( nullptr ); // Sentinel.
@ -596,7 +588,7 @@ void NGSPICE::init_dll()
} }
bool NGSPICE::loadSpinit( const string& aFileName ) bool NGSPICE::loadSpinit( const std::string& aFileName )
{ {
if( !wxFileName::FileExists( aFileName ) ) if( !wxFileName::FileExists( aFileName ) )
return false; return false;
@ -613,9 +605,9 @@ bool NGSPICE::loadSpinit( const string& aFileName )
} }
string NGSPICE::findCmPath() const std::string NGSPICE::findCmPath() const
{ {
const vector<string> cmPaths = const std::vector<std::string> cmPaths =
{ {
#ifdef __WXMAC__ #ifdef __WXMAC__
"/Applications/ngspice/lib/ngspice", "/Applications/ngspice/lib/ngspice",
@ -642,17 +634,17 @@ string NGSPICE::findCmPath() const
} }
} }
return string(); return std::string();
} }
bool NGSPICE::loadCodemodels( const string& aPath ) bool NGSPICE::loadCodemodels( const std::string& aPath )
{ {
wxArrayString cmFiles; wxArrayString cmFiles;
size_t count = wxDir::GetAllFiles( aPath, &cmFiles ); size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
for( const auto& cm : cmFiles ) for( const auto& cm : cmFiles )
Command( "codemodel " + cm.ToStdString() ); Command( fmt::format( "codemodel '{}'", cm.ToStdString() ) );
return count != 0; return count != 0;
} }
@ -667,7 +659,9 @@ int NGSPICE::cbSendChar( char* aWhat, int aId, void* aUser )
// strip stdout/stderr from the line // strip stdout/stderr from the line
if( ( strncasecmp( aWhat, "stdout ", 7 ) == 0 ) if( ( strncasecmp( aWhat, "stdout ", 7 ) == 0 )
|| ( strncasecmp( aWhat, "stderr ", 7 ) == 0 ) ) || ( strncasecmp( aWhat, "stderr ", 7 ) == 0 ) )
{
aWhat += 7; aWhat += 7;
}
sim->m_reporter->Report( aWhat ); sim->m_reporter->Report( aWhat );
} }
@ -693,7 +687,8 @@ int NGSPICE::cbBGThreadRunning( NG_BOOL aFinished, int aId, void* aUser )
} }
int NGSPICE::cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void* aUser ) int NGSPICE::cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId,
void* aUser )
{ {
// Something went wrong, reload the dll // Something went wrong, reload the dll
NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser ); NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );