Excise wxString from simulation

This commit is contained in:
Mikolaj Wielgus 2022-09-22 07:38:45 +02:00
parent fc10db25ba
commit e4865ce543
41 changed files with 663 additions and 646 deletions

View File

@ -167,14 +167,14 @@ bool DIALOG_SIM_MODEL<T>::TransferDataFromWindow()
if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() ) if( !DIALOG_SIM_MODEL_BASE::TransferDataFromWindow() )
return false; return false;
wxString modelName = ""; std::string modelName;
if( m_useLibraryModelRadioButton->GetValue() ) if( m_useLibraryModelRadioButton->GetValue() )
modelName = m_modelNameCombobox->GetValue(); modelName = m_modelNameCombobox->GetValue();
SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_SPICE::NAME_FIELD, modelName ); SIM_MODEL::SetFieldValue( m_fields, SIM_LIBRARY_SPICE::NAME_FIELD, modelName );
wxString path = ""; std::string path;
if( m_useLibraryModelRadioButton->GetValue() ) if( m_useLibraryModelRadioButton->GetValue() )
{ {
@ -338,7 +338,7 @@ void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
wxTextFile file; wxTextFile file;
wxString text; wxString text;
text << curModel().SpiceGenerator().Preview( modelName ); text << curModel().SpiceGenerator().Preview( std::string( modelName.ToUTF8() ) );
text << "\n"; text << "\n";
text << "--- FILE SOURCE (" << path << ") ---\n"; text << "--- FILE SOURCE (" << path << ") ---\n";
text << "\n"; text << "\n";
@ -356,7 +356,7 @@ void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
} }
} }
else else
m_codePreview->SetText( curModel().SpiceGenerator().Preview( modelName ) ); m_codePreview->SetText( curModel().SpiceGenerator().Preview( std::string( modelName.ToUTF8() ) ) );
m_codePreview->SetEditable( false ); // ??? m_codePreview->SetEditable( false ); // ???
m_wasCodePreviewUpdated = true; m_wasCodePreviewUpdated = true;
@ -453,7 +453,7 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
try try
{ {
m_library->ReadFile( absolutePath ); m_library->ReadFile( std::string( absolutePath.ToUTF8() ) );
} }
catch( const IO_ERROR& e ) catch( const IO_ERROR& e )
{ {
@ -634,9 +634,9 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
// Legacy due to the way we extracted the parameters from Ngspice. // Legacy due to the way we extracted the parameters from Ngspice.
if( param.isOtherVariant ) if( param.isOtherVariant )
prop->SetCell( 3, param.info.defaultValueOfOtherVariant ); prop->SetCell( 3, wxString( param.info.defaultValueOfOtherVariant ) );
else else
prop->SetCell( 3, param.info.defaultValue ); prop->SetCell( 3, wxString( param.info.defaultValue ) );
wxString typeStr; wxString typeStr;
@ -898,7 +898,7 @@ void DIALOG_SIM_MODEL<T>::onPinAssignmentsGridCellChange( wxGridEvent& aEvent )
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED ) if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
{ {
curModel().SetPinSymbolPinNumber( modelPinIndex, curModel().SetPinSymbolPinNumber( modelPinIndex,
m_sortedSymbolPins.at( symbolPinIndex )->GetShownNumber() ); std::string( m_sortedSymbolPins.at( symbolPinIndex )->GetShownNumber().ToUTF8() ) );
} }
updatePinAssignments(); updatePinAssignments();

View File

@ -133,7 +133,7 @@ wxString DIALOG_SIM_SETTINGS::evaluateDCControls( wxChoice* aDcSource, wxTextCtr
{ {
// pick device name from exporter when something different than temperature is selected // pick device name from exporter when something different than temperature is selected
if( dcSource.Cmp( "TEMP" ) ) if( dcSource.Cmp( "TEMP" ) )
dcSource = m_circuitModel->GetItemName( dcSource ); dcSource = m_circuitModel->GetItemName( std::string( dcSource.ToUTF8() ) );
return wxString::Format( "%s %s %s %s", dcSource, return wxString::Format( "%s %s %s %s", dcSource,
SPICE_VALUE( aDcStart->GetValue() ).ToSpiceString(), SPICE_VALUE( aDcStart->GetValue() ).ToSpiceString(),

View File

@ -35,9 +35,12 @@
#include <sch_text.h> #include <sch_text.h>
#include <sch_textbox.h> #include <sch_textbox.h>
#include <string_utils.h> #include <string_utils.h>
#include <boost/algorithm/string/replace.hpp>
#include <fmt/core.h>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
#include <locale_io.h>
namespace NETLIST_EXPORTER_SPICE_PARSER namespace NETLIST_EXPORTER_SPICE_PARSER
@ -74,8 +77,6 @@ bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigne
bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{ {
LOCALE_IO dummy;
// Cleanup list to avoid duplicate if the netlist exporter is run more than once. // Cleanup list to avoid duplicate if the netlist exporter is run more than once.
m_rawIncludes.clear(); m_rawIncludes.clear();
@ -100,7 +101,7 @@ bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsign
void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
{ {
aFormatter.Print( 0, ".title %s\n", TO_UTF8( m_title ) ); aFormatter.Print( 0, ".title %s\n", m_title.c_str() );
} }
@ -112,7 +113,7 @@ void NETLIST_EXPORTER_SPICE::WriteTail( OUTPUTFORMATTER& aFormatter, unsigned aN
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions ) bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
{ {
std::set<wxString> refNames; // Set of reference names to check for duplication. std::set<std::string> refNames; // Set of reference names to check for duplication.
int ncCounter = 1; int ncCounter = 1;
ReadDirectives( aNetlistOptions ); ReadDirectives( aNetlistOptions );
@ -156,15 +157,15 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
} }
void NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( wxString& aNetName ) void NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( std::string& aNetName )
{ {
aNetName.Replace( "(", "_" ); boost::replace_all( aNetName, "(", "_" );
aNetName.Replace( ")", "_" ); boost::replace_all( aNetName, ")", "_" );
aNetName.Replace( " ", "_" ); boost::replace_all( aNetName, " ", "_" );
} }
wxString NETLIST_EXPORTER_SPICE::GetItemName( const wxString& aRefName ) const std::string NETLIST_EXPORTER_SPICE::GetItemName( const std::string& aRefName ) const
{ {
const std::list<ITEM>& spiceItems = GetItems(); const std::list<ITEM>& spiceItems = GetItems();
@ -223,7 +224,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
} }
else if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotInclude>() ) else if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotInclude>() )
{ {
wxString path = node->children.at( 0 )->string(); std::string path = node->children.at( 0 )->string();
try try
{ {
@ -247,19 +248,19 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, ITEM& aItem ) void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, ITEM& aItem )
{ {
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD ); SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
wxString path; std::string path;
if( field ) if( field )
path = field->GetShownText(); path = std::string( field->GetShownText().ToUTF8() );
if( path.IsEmpty() ) if( path == "" )
return; return;
wxString absolutePath = m_schematic->Prj().AbsolutePath( path ); wxString absolutePath = m_schematic->Prj().AbsolutePath( path );
try try
{ {
m_libraries.try_emplace( path, SIM_LIBRARY::Create( absolutePath ) ); m_libraries.try_emplace( path, SIM_LIBRARY::Create( std::string( absolutePath.ToUTF8() ) ) );
} }
catch( const IO_ERROR& e ) catch( const IO_ERROR& e )
{ {
@ -281,7 +282,7 @@ void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem )
if( !field ) if( !field )
return; return;
wxString modelName = field->GetShownText(); std::string modelName = std::string( field->GetShownText().ToUTF8() );
const SIM_LIBRARY& library = *m_libraries.at( aItem.libraryPath ); const SIM_LIBRARY& library = *m_libraries.at( aItem.libraryPath );
const SIM_MODEL* baseModel = library.FindModel( modelName ); const SIM_MODEL* baseModel = library.FindModel( modelName );
@ -312,7 +313,7 @@ void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem )
bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
ITEM& aItem, ITEM& aItem,
std::set<wxString>& aRefNames ) std::set<std::string>& aRefNames )
{ {
aItem.refName = aSymbol.GetRef( &aSheet ); aItem.refName = aSymbol.GetRef( &aSheet );
@ -351,7 +352,7 @@ bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, ITEM& aItem )
if( auto model = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model.get() ) ) if( auto model = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model.get() ) )
{ {
unsigned libParamIndex = static_cast<unsigned>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB ); unsigned libParamIndex = static_cast<unsigned>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
wxString path = model->GetParam( libParamIndex ).value->ToString(); std::string path = model->GetParam( libParamIndex ).value->ToString();
if( path != "" ) if( path != "" )
m_rawIncludes.insert( path ); m_rawIncludes.insert( path );
@ -364,7 +365,7 @@ bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, ITEM& aItem )
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem ) void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem )
{ {
for( const PIN_INFO& pin : m_sortedSymbolPinList ) for( const PIN_INFO& pin : m_sortedSymbolPinList )
aItem.pinNumbers.push_back( pin.num ); aItem.pinNumbers.emplace_back( std::string( pin.num.ToUTF8() ) );
} }
@ -373,7 +374,8 @@ void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem,
{ {
for( const PIN_INFO& pinInfo : m_sortedSymbolPinList ) for( const PIN_INFO& pinInfo : m_sortedSymbolPinList )
{ {
wxString netName = GenerateItemPinNetName( pinInfo.netName, aNcCounter ); std::string netName = GenerateItemPinNetName( std::string( pinInfo.netName.ToUTF8() ),
aNcCounter );
aItem.pinNetNames.push_back( netName ); aItem.pinNetNames.push_back( netName );
m_nets.insert( netName ); m_nets.insert( netName );
@ -382,7 +384,7 @@ void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem,
void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions, void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
const wxString& aPath ) const std::string& aPath )
{ {
// First, expand env vars, if any. // First, expand env vars, if any.
wxString expandedPath = ExpandEnvVarSubstitutions( aPath, &m_schematic->Prj() ); wxString expandedPath = ExpandEnvVarSubstitutions( aPath, &m_schematic->Prj() );
@ -397,8 +399,8 @@ void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned
if( fullPath.IsEmpty() ) if( fullPath.IsEmpty() )
{ {
DisplayErrorMessage( nullptr, DisplayErrorMessage( nullptr,
wxString::Format( _( "Could not find library file '%s'" ), wxString::Format( _( "Could not find library file '%s'" ),
expandedPath ) ); expandedPath ) );
fullPath = expandedPath; fullPath = expandedPath;
} }
} }
@ -414,7 +416,7 @@ void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigne
for( auto&& [path, library] : m_libraries ) for( auto&& [path, library] : m_libraries )
writeInclude( aFormatter, aNetlistOptions, path ); writeInclude( aFormatter, aNetlistOptions, path );
for( const wxString& path : m_rawIncludes ) for( const std::string& path : m_rawIncludes )
writeInclude( aFormatter, aNetlistOptions, path ); writeInclude( aFormatter, aNetlistOptions, path );
} }
@ -426,7 +428,8 @@ void NETLIST_EXPORTER_SPICE::writeModels( OUTPUTFORMATTER& aFormatter )
if( !item.model->IsEnabled() ) if( !item.model->IsEnabled() )
continue; continue;
aFormatter.Print( 0, "%s", TO_UTF8( item.model->SpiceGenerator().ModelLine( item.modelName ) ) ); aFormatter.Print( 0, "%s",
item.model->SpiceGenerator().ModelLine( item.modelName ).c_str() );
} }
} }
@ -439,10 +442,10 @@ void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter )
continue; continue;
aFormatter.Print( 0, "%s", aFormatter.Print( 0, "%s",
TO_UTF8( item.model->SpiceGenerator().ItemLine( item.refName, item.model->SpiceGenerator().ItemLine( item.refName,
item.modelName, item.modelName,
item.pinNumbers, item.pinNumbers,
item.pinNetNames ) ) ); item.pinNetNames ).c_str() );
} }
} }
@ -456,21 +459,21 @@ void NETLIST_EXPORTER_SPICE::WriteDirectives( OUTPUTFORMATTER& aFormatter,
if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS ) if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS )
aFormatter.Print( 0, ".probe alli\n" ); aFormatter.Print( 0, ".probe alli\n" );
for( const wxString& directive : m_directives ) for( const std::string& directive : m_directives )
aFormatter.Print( 0, "%s\n", TO_UTF8( directive ) ); aFormatter.Print( 0, "%s\n", directive.c_str() );
} }
wxString NETLIST_EXPORTER_SPICE::GenerateItemPinNetName( const wxString& aNetName, std::string NETLIST_EXPORTER_SPICE::GenerateItemPinNetName( const std::string& aNetName,
int& aNcCounter ) const int& aNcCounter ) const
{ {
wxString netName = aNetName; std::string netName = aNetName;
ReplaceForbiddenChars( netName ); ReplaceForbiddenChars( netName );
netName = UnescapeString( netName ); netName = std::string( UnescapeString( netName ).ToUTF8() );
if( netName == "" ) if( netName == "" )
netName = wxString::Format( wxT( "NC-%u" ), aNcCounter++ ); netName = fmt::format( "NC-{}", aNcCounter++ );
return netName; return netName;
} }

View File

@ -49,12 +49,12 @@ public:
struct ITEM struct ITEM
{ {
wxString refName; std::string refName;
wxString libraryPath; std::string libraryPath;
std::vector<wxString> pinNumbers; std::vector<std::string> pinNumbers;
std::vector<wxString> pinNetNames; std::vector<std::string> pinNetNames;
std::unique_ptr<const SIM_MODEL> model; std::unique_ptr<const SIM_MODEL> model;
wxString modelName; std::string modelName;
}; };
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) : NETLIST_EXPORTER_BASE( aSchematic ) {} NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) : NETLIST_EXPORTER_BASE( aSchematic ) {}
@ -90,12 +90,12 @@ public:
/** /**
* Replace illegal spice net name characters with underscores. * Replace illegal spice net name characters with underscores.
*/ */
static void ReplaceForbiddenChars( wxString& aNetName ); static void ReplaceForbiddenChars( std::string& aNetName );
/** /**
* Return the list of nets. * Return the list of nets.
*/ */
std::set<wxString> GetNets() const { return m_nets; } std::set<std::string> GetNets() const { return m_nets; }
/** /**
@ -107,20 +107,20 @@ public:
* to the assigned device model type or it is the reference prefixed with a character defining * to the assigned device model type or it is the reference prefixed with a character defining
* the device model type. * the device model type.
*/ */
wxString GetItemName( const wxString& aRefName ) const; std::string GetItemName( const std::string& aRefName ) const;
/** /**
* Return the list of items representing schematic components in the Spice world. * Return the list of items representing schematic components in the Spice world.
*/ */
const std::list<ITEM>& GetItems() const { return m_items; } const std::list<ITEM>& GetItems() const { return m_items; }
const std::vector<wxString>& GetDirectives() { return m_directives; } const std::vector<std::string>& GetDirectives() { return m_directives; }
protected: protected:
void ReadDirectives( unsigned aNetlistOptions = 0 ); void ReadDirectives( unsigned aNetlistOptions = 0 );
virtual void WriteDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) const; virtual void WriteDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) const;
virtual wxString GenerateItemPinNetName( const wxString& aNetName, int& aNcCounter ) const; virtual std::string GenerateItemPinNetName( const std::string& aNetName, int& aNcCounter ) const;
/** /**
* Return the paths of exported sheets (either all or the current one). * Return the paths of exported sheets (either all or the current one).
@ -132,23 +132,23 @@ private:
void readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem ); void readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem );
void readEnabledField( SCH_SYMBOL& aSymbol, ITEM& aItem ); void readEnabledField( SCH_SYMBOL& aSymbol, ITEM& aItem );
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem, bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem,
std::set<wxString>& aRefNames ); std::set<std::string>& aRefNames );
bool readModel( SCH_SYMBOL& aSymbol, ITEM& aItem ); bool readModel( SCH_SYMBOL& aSymbol, ITEM& aItem );
void readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem ); void readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem );
void readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem, int& aNcCounter ); void readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem, int& aNcCounter );
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions, void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
const wxString& aPath ); const std::string& aPath );
void writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ); void writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
void writeModels( OUTPUTFORMATTER& aFormatter ); void writeModels( OUTPUTFORMATTER& aFormatter );
void writeItems( OUTPUTFORMATTER& aFormatter ); void writeItems( OUTPUTFORMATTER& aFormatter );
wxString m_title; ///< Spice simulation title found in the schematic sheet std::string m_title; ///< Spice simulation title found in the schematic sheet
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
std::set<wxString> m_rawIncludes; ///< include directives found in symbols std::set<std::string> m_rawIncludes; ///< include directives found in symbols
std::set<wxString> m_nets; std::set<std::string> m_nets;
std::list<ITEM> m_items; ///< Items representing schematic symbols in Spice world std::list<ITEM> m_items; ///< Items representing schematic symbols in Spice world
}; };

View File

@ -35,7 +35,7 @@ void NETLIST_EXPORTER_SPICE_MODEL::WriteHead( OUTPUTFORMATTER& aFormatter,
for( auto const& [key, port] : m_ports ) for( auto const& [key, port] : m_ports )
{ {
wxString portDir; std::string portDir;
switch( port.dir ) switch( port.dir )
{ {
@ -49,7 +49,7 @@ void NETLIST_EXPORTER_SPICE_MODEL::WriteHead( OUTPUTFORMATTER& aFormatter,
break; break;
} }
aFormatter.Print( 0, "+ %s ; %s\n", TO_UTF8( port.name ), TO_UTF8( portDir ) ); aFormatter.Print( 0, "+ %s ; %s\n", port.name.c_str(), portDir.c_str() );
} }
aFormatter.Print( 0, "\n\n" ); aFormatter.Print( 0, "\n\n" );
@ -71,10 +71,10 @@ bool NETLIST_EXPORTER_SPICE_MODEL::ReadSchematicAndLibraries( unsigned aNetlistO
} }
wxString NETLIST_EXPORTER_SPICE_MODEL::GenerateItemPinNetName( const wxString& aNetName, std::string NETLIST_EXPORTER_SPICE_MODEL::GenerateItemPinNetName( const std::string& aNetName,
int& aNcCounter ) const int& aNcCounter ) const
{ {
wxString netName = aNetName; std::string netName = aNetName;
if( m_ports.count( netName ) ) if( m_ports.count( netName ) )
netName = m_ports.at( netName ).name; netName = m_ports.at( netName ).name;
@ -92,10 +92,9 @@ void NETLIST_EXPORTER_SPICE_MODEL::readPorts( unsigned aNetlistOptions )
auto label = static_cast<SCH_LABEL_BASE*>( item ); auto label = static_cast<SCH_LABEL_BASE*>( item );
if( SCH_CONNECTION* conn = label->Connection( &sheet ) ) if( SCH_CONNECTION* conn = label->Connection( &sheet ) )
{ m_ports.insert( { std::string( conn->Name().ToUTF8() ),
m_ports.insert( { conn->Name(), PORT_INFO{ label->GetText(), PORT_INFO{ std::string( label->GetText().ToUTF8() ),
label->GetShape() } } ); label->GetShape() } } );
}
} }
} }
} }

View File

@ -40,18 +40,18 @@ public:
bool ReadSchematicAndLibraries( unsigned aNetlistOptions ) override; bool ReadSchematicAndLibraries( unsigned aNetlistOptions ) override;
protected: protected:
wxString GenerateItemPinNetName( const wxString& aNetName, int& aNcCounter ) const override; std::string GenerateItemPinNetName( const std::string& aNetName, int& aNcCounter ) const override;
private: private:
struct PORT_INFO struct PORT_INFO
{ {
wxString name; std::string name;
LABEL_FLAG_SHAPE dir; LABEL_FLAG_SHAPE dir;
}; };
void readPorts( unsigned aNetlistOptions ); void readPorts( unsigned aNetlistOptions );
std::map<wxString, PORT_INFO> m_ports; std::map<std::string, PORT_INFO> m_ports;
}; };
#endif // NETLIST_EXPORTER_SPICE_MODEL_H #endif // NETLIST_EXPORTER_SPICE_MODEL_H

View File

@ -26,7 +26,7 @@
#include <sim/sim_library_spice.h> #include <sim/sim_library_spice.h>
std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( wxString aFilePath ) std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( std::string aFilePath )
{ {
std::unique_ptr<SIM_LIBRARY> library = std::make_unique<SIM_LIBRARY_SPICE>(); std::unique_ptr<SIM_LIBRARY> library = std::make_unique<SIM_LIBRARY_SPICE>();
@ -35,17 +35,17 @@ std::unique_ptr<SIM_LIBRARY> SIM_LIBRARY::Create( wxString aFilePath )
} }
void SIM_LIBRARY::ReadFile( const wxString& aFilePath ) void SIM_LIBRARY::ReadFile( const std::string& aFilePath )
{ {
m_filePath = aFilePath; m_filePath = aFilePath;
} }
SIM_MODEL* SIM_LIBRARY::FindModel( const wxString& aModelName ) const SIM_MODEL* SIM_LIBRARY::FindModel( const std::string& aModelName ) const
{ {
for( unsigned i = 0; i < GetModelNames().size(); ++i ) for( unsigned i = 0; i < GetModelNames().size(); ++i )
{ {
wxString curModelName = GetModelNames().at( i ); std::string curModelName = GetModelNames().at( i );
if( curModelName == aModelName ) if( curModelName == aModelName )
return m_models.at( i ).get(); return m_models.at( i ).get();

View File

@ -44,7 +44,7 @@ public:
* @param aFilePath Path to the file. * @param aFilePath Path to the file.
* @return The library loaded in a newly constructed object. * @return The library loaded in a newly constructed object.
*/ */
static std::unique_ptr<SIM_LIBRARY> Create( wxString aFilePath ); static std::unique_ptr<SIM_LIBRARY> Create( std::string aFilePath );
/** /**
* Read library from a source file. Must be in the format appropriate to the subclass, e.g. * Read library from a source file. Must be in the format appropriate to the subclass, e.g.
@ -53,7 +53,7 @@ public:
* @param aFilePath Path to the file. * @param aFilePath Path to the file.
* @throw IO_ERROR on read or parsing error. * @throw IO_ERROR on read or parsing error.
*/ */
virtual void ReadFile( const wxString& aFilePath ) = 0; virtual void ReadFile( const std::string& aFilePath ) = 0;
/** /**
* Write library to a source file (e.g. in Spice format). * Write library to a source file (e.g. in Spice format).
@ -61,22 +61,22 @@ public:
* @param aFilePath Path to the file. * @param aFilePath Path to the file.
* @throw IO_ERROR on write error. * @throw IO_ERROR on write error.
*/ */
virtual void WriteFile( const wxString& aFilePath ) = 0; virtual void WriteFile( const std::string& aFilePath ) = 0;
SIM_MODEL* FindModel( const wxString& aModelName ) const; SIM_MODEL* FindModel( const std::string& aModelName ) const;
std::vector<std::reference_wrapper<SIM_MODEL>> GetModels() const; std::vector<std::reference_wrapper<SIM_MODEL>> GetModels() const;
const std::vector<wxString>& GetModelNames() const { return m_modelNames; } const std::vector<std::string>& GetModelNames() const { return m_modelNames; }
wxString GetFilePath() const { return m_filePath; } std::string GetFilePath() const { return m_filePath; }
wxString GetError() const { return m_error; } std::string GetError() const { return m_error; }
protected: protected:
std::vector<std::unique_ptr<SIM_MODEL>> m_models; std::vector<std::unique_ptr<SIM_MODEL>> m_models;
std::vector<wxString> m_modelNames; std::vector<std::string> m_modelNames;
wxString m_filePath; std::string m_filePath;
wxString m_error; std::string m_error;
}; };

View File

@ -33,14 +33,14 @@ SIM_LIBRARY_SPICE::SIM_LIBRARY_SPICE() :
} }
void SIM_LIBRARY_SPICE::ReadFile( const wxString& aFilePath ) void SIM_LIBRARY_SPICE::ReadFile( const std::string& aFilePath )
{ {
SIM_LIBRARY::ReadFile( aFilePath ); SIM_LIBRARY::ReadFile( aFilePath );
m_spiceLibraryParser->ReadFile( aFilePath ); m_spiceLibraryParser->ReadFile( aFilePath );
} }
void SIM_LIBRARY_SPICE::WriteFile( const wxString& aFilePath ) void SIM_LIBRARY_SPICE::WriteFile( const std::string& aFilePath )
{ {
// Not implemented yet. // Not implemented yet.
} }

View File

@ -37,10 +37,10 @@ public:
SIM_LIBRARY_SPICE(); SIM_LIBRARY_SPICE();
// @copydoc SIM_LIBRARY::ReadFile() // @copydoc SIM_LIBRARY::ReadFile()
void ReadFile( const wxString& aFilePath ) override; void ReadFile( const std::string& aFilePath ) override;
// @copydoc SIM_LIBRARY::WriteFile() // @copydoc SIM_LIBRARY::WriteFile()
void WriteFile( const wxString& aFilePath ) override; void WriteFile( const std::string& aFilePath ) override;
private: private:
std::unique_ptr<SPICE_LIBRARY_PARSER> m_spiceLibraryParser; std::unique_ptr<SPICE_LIBRARY_PARSER> m_spiceLibraryParser;

View File

@ -34,9 +34,13 @@
#include <sim/sim_model_tline.h> #include <sim/sim_model_tline.h>
#include <sim/sim_model_xspice.h> #include <sim/sim_model_xspice.h>
#include <locale_io.h>
#include <lib_symbol.h> #include <lib_symbol.h>
#include <confirm.h> #include <confirm.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string.hpp>
#include <fmt/core.h>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
@ -373,8 +377,8 @@ template TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<LIB_FIELD>& aFiel
template <typename T> template <typename T>
TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields ) TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields )
{ {
wxString deviceTypeFieldValue = GetFieldValue( &aFields, DEVICE_TYPE_FIELD ); std::string deviceTypeFieldValue = GetFieldValue( &aFields, DEVICE_TYPE_FIELD );
wxString typeFieldValue = GetFieldValue( &aFields, TYPE_FIELD ); std::string typeFieldValue = GetFieldValue( &aFields, TYPE_FIELD );
if( deviceTypeFieldValue != "" ) if( deviceTypeFieldValue != "" )
{ {
@ -404,9 +408,9 @@ TYPE SIM_MODEL::ReadTypeFromFields( const std::vector<T>& aFields )
} }
TYPE SIM_MODEL::InferTypeFromRefAndValue( const wxString& aRef, const wxString& aValue ) TYPE SIM_MODEL::InferTypeFromRefAndValue( const std::string& aRef, const std::string& aValue )
{ {
static std::map<wxString, TYPE> refPrefixToType = { static std::map<std::string, TYPE> refPrefixToType = {
{ "R", TYPE::R }, { "R", TYPE::R },
{ "C", TYPE::C }, { "C", TYPE::C },
{ "L", TYPE::L }, { "L", TYPE::L },
@ -443,7 +447,7 @@ TYPE SIM_MODEL::InferTypeFromRefAndValue( const wxString& aRef, const wxString&
for( auto&& [curPrefix, curType] : refPrefixToType ) for( auto&& [curPrefix, curType] : refPrefixToType )
{ {
if( aRef.StartsWith( curPrefix ) ) if( boost::starts_with( aRef, curPrefix ) )
{ {
type = curType; type = curType;
break; break;
@ -452,46 +456,46 @@ TYPE SIM_MODEL::InferTypeFromRefAndValue( const wxString& aRef, const wxString&
// We handle "V" and "I" later because it collides and std::map is unordered. // We handle "V" and "I" later because it collides and std::map is unordered.
if( type == TYPE::NONE && aRef.StartsWith( "V" ) ) if( type == TYPE::NONE && boost::starts_with( aRef, "V" ) )
type = TYPE::V; type = TYPE::V;
if( type == TYPE::NONE && aRef.StartsWith( "I" ) ) if( type == TYPE::NONE && boost::starts_with( aRef, "I" ) )
type = TYPE::I; type = TYPE::I;
wxString value = aValue; std::string value = aValue;
// Some types have to be inferred from Value field. // Some types have to be inferred from Value field.
switch( type ) switch( type )
{ {
case TYPE::R: case TYPE::R:
if( value.Trim( false ).StartsWith( "=" ) ) if( boost::starts_with( boost::trim_left_copy( value ), "=" ) )
type = TYPE::R_BEHAVIORAL; type = TYPE::R_BEHAVIORAL;
break; break;
case TYPE::C: case TYPE::C:
if( value.Trim( false ).StartsWith( "=" ) ) if( boost::starts_with( boost::trim_left_copy( value ), "=" ) )
type = TYPE::C_BEHAVIORAL; type = TYPE::C_BEHAVIORAL;
break; break;
case TYPE::L: case TYPE::L:
if( value.Trim( false ).StartsWith( "=" ) ) if( boost::starts_with( boost::trim_left_copy( value ), "=" ) )
type = TYPE::L_BEHAVIORAL; type = TYPE::L_BEHAVIORAL;
break; break;
case TYPE::V: case TYPE::V:
if( value.Trim( false ).StartsWith( "=" ) ) if( boost::starts_with( boost::trim_left_copy( value ), "=" ) )
type = TYPE::V_BEHAVIORAL; type = TYPE::V_BEHAVIORAL;
break; break;
case TYPE::I: case TYPE::I:
if( value.Trim( false ).StartsWith( "=" ) ) if( boost::starts_with( boost::trim_left_copy( value ), "=" ) )
type = TYPE::I_BEHAVIORAL; type = TYPE::I_BEHAVIORAL;
break; break;
case TYPE::TLINE_Z0: case TYPE::TLINE_Z0:
try try
{ {
tao::pegtl::string_input<> in( aValue.ToUTF8(), "Value" ); tao::pegtl::string_input<> in( aValue, "Value" );
auto root = tao::pegtl::parse_tree::parse< auto root = tao::pegtl::parse_tree::parse<
SIM_MODEL_PARSER::fieldParamValuePairsGrammar, SIM_MODEL_PARSER::fieldParamValuePairsGrammar,
SIM_MODEL_PARSER::fieldParamValuePairsSelector> SIM_MODEL_PARSER::fieldParamValuePairsSelector>
@ -655,12 +659,12 @@ template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
template <typename T> template <typename T>
wxString SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const wxString& aFieldName ) std::string SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName )
{ {
static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value ); static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
if( !aFields ) if( !aFields )
return wxEmptyString; // Should not happen, T=void specialization will be called instead. return ""; // Should not happen, T=void specialization will be called instead.
auto fieldIt = std::find_if( aFields->begin(), aFields->end(), auto fieldIt = std::find_if( aFields->begin(), aFields->end(),
[aFieldName]( const T& field ) [aFieldName]( const T& field )
@ -669,23 +673,23 @@ wxString SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const wxString
} ); } );
if( fieldIt != aFields->end() ) if( fieldIt != aFields->end() )
return fieldIt->GetText(); return std::string( fieldIt->GetText().ToUTF8() );
return wxEmptyString; return "";
} }
// This specialization is used when no fields are passed. // This specialization is used when no fields are passed.
template <> template <>
wxString SIM_MODEL::GetFieldValue( const std::vector<void>* aFields, const wxString& aFieldName ) std::string SIM_MODEL::GetFieldValue( const std::vector<void>* aFields, const std::string& aFieldName )
{ {
return wxEmptyString; return "";
} }
template <typename T> template <typename T>
void SIM_MODEL::SetFieldValue( std::vector<T>& aFields, const wxString& aFieldName, void SIM_MODEL::SetFieldValue( std::vector<T>& aFields, const std::string& aFieldName,
const wxString& aValue ) const std::string& aValue )
{ {
static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value ); static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
@ -697,7 +701,7 @@ void SIM_MODEL::SetFieldValue( std::vector<T>& aFields, const wxString& aFieldNa
if( fieldIt != aFields.end() ) if( fieldIt != aFields.end() )
{ {
if( aValue.IsEmpty() ) if( aValue == "" )
aFields.erase( fieldIt ); aFields.erase( fieldIt );
else else
fieldIt->SetText( aValue ); fieldIt->SetText( aValue );
@ -705,7 +709,7 @@ void SIM_MODEL::SetFieldValue( std::vector<T>& aFields, const wxString& aFieldNa
return; return;
} }
if( aValue.IsEmpty() ) if( aValue == "" )
return; return;
if constexpr( std::is_same<T, SCH_FIELD>::value ) if constexpr( std::is_same<T, SCH_FIELD>::value )
@ -731,7 +735,7 @@ void SIM_MODEL::AddPin( const PIN& aPin )
} }
int SIM_MODEL::FindModelPinIndex( const wxString& aSymbolPinNumber ) int SIM_MODEL::FindModelPinIndex( const std::string& aSymbolPinNumber )
{ {
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex ) for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
{ {
@ -769,14 +773,14 @@ const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const
} }
const SIM_MODEL::PARAM* SIM_MODEL::FindParam( const wxString& aParamName ) const const SIM_MODEL::PARAM* SIM_MODEL::FindParam( const std::string& aParamName ) const
{ {
std::vector<std::reference_wrapper<const PARAM>> params = GetParams(); std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
auto it = std::find_if( params.begin(), params.end(), auto it = std::find_if( params.begin(), params.end(),
[aParamName]( const PARAM& param ) [aParamName]( const PARAM& param )
{ {
return param.info.name == aParamName.Lower(); return param.info.name == boost::to_lower_copy( aParamName );
} ); } );
if( it == params.end() ) if( it == params.end() )
@ -812,14 +816,14 @@ const SIM_MODEL::PARAM& SIM_MODEL::GetBaseParam( unsigned aParamIndex ) const
} }
bool SIM_MODEL::SetParamValue( unsigned aParamIndex, const wxString& aValue, bool SIM_MODEL::SetParamValue( unsigned aParamIndex, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
return m_params.at( aParamIndex ).value->FromString( aValue.ToStdString(), aNotation ); return m_params.at( aParamIndex ).value->FromString( aValue, aNotation );
} }
bool SIM_MODEL::SetParamValue( const wxString& aParamName, const wxString& aValue, bool SIM_MODEL::SetParamValue( const std::string& aParamName, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
std::vector<std::reference_wrapper<const PARAM>> params = GetParams(); std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
@ -827,7 +831,7 @@ bool SIM_MODEL::SetParamValue( const wxString& aParamName, const wxString& aValu
auto it = std::find_if( params.begin(), params.end(), auto it = std::find_if( params.begin(), params.end(),
[aParamName]( const PARAM& param ) [aParamName]( const PARAM& param )
{ {
return param.info.name == aParamName.Lower(); return param.info.name == boost::to_lower_copy( aParamName );
} ); } );
if( it == params.end() ) if( it == params.end() )
@ -967,13 +971,13 @@ void SIM_MODEL::CreatePins( unsigned aSymbolPinCount )
// Excess model pins are set as Not Connected. // Excess model pins are set as Not Connected.
// Note that intentionally nothing is added if `getPinNames()` returns an empty vector. // Note that intentionally nothing is added if `getPinNames()` returns an empty vector.
// SIM_MODEL pins must be ordered by symbol pin numbers -- this is assumed by code that // SIM_MODEL pins must be ordered by symbol pin numbers -- this is assumed by the code that
// accesses them. // accesses them.
for( unsigned modelPinIndex = 0; modelPinIndex < getPinNames().size(); ++modelPinIndex ) for( unsigned modelPinIndex = 0; modelPinIndex < getPinNames().size(); ++modelPinIndex )
{ {
if( modelPinIndex < aSymbolPinCount ) if( modelPinIndex < aSymbolPinCount )
AddPin( { getPinNames().at( modelPinIndex ), wxString::FromCDouble( modelPinIndex + 1 ) } ); AddPin( { getPinNames().at( modelPinIndex ), fmt::format( "{}", modelPinIndex + 1 ) } );
else else
AddPin( { getPinNames().at( modelPinIndex ), "" } ); AddPin( { getPinNames().at( modelPinIndex ), "" } );
} }
@ -981,12 +985,12 @@ void SIM_MODEL::CreatePins( unsigned aSymbolPinCount )
template void SIM_MODEL::WriteInferredDataFields( std::vector<SCH_FIELD>& aFields, template void SIM_MODEL::WriteInferredDataFields( std::vector<SCH_FIELD>& aFields,
const wxString& aValue ) const; const std::string& aValue ) const;
template void SIM_MODEL::WriteInferredDataFields( std::vector<LIB_FIELD>& aFields, template void SIM_MODEL::WriteInferredDataFields( std::vector<LIB_FIELD>& aFields,
const wxString& aValue ) const; const std::string& aValue ) const;
template <typename T> template <typename T>
void SIM_MODEL::WriteInferredDataFields( std::vector<T>& aFields, const wxString& aValue ) const void SIM_MODEL::WriteInferredDataFields( std::vector<T>& aFields, const std::string& aValue ) const
{ {
if( GetPinCount() == 2 if( GetPinCount() == 2
&& GetPin( 0 ).symbolPinNumber == "1" && GetPin( 0 ).symbolPinNumber == "1"
@ -1003,33 +1007,33 @@ void SIM_MODEL::WriteInferredDataFields( std::vector<T>& aFields, const wxString
} }
wxString SIM_MODEL::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const std::string SIM_MODEL::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const
{ {
wxString result; std::string result;
if( aIsFirst ) if( aIsFirst )
aIsFirst = false; aIsFirst = false;
else else
result << " "; result.append( " " );
wxString name = aParam.info.name; std::string name = aParam.info.name;
// Because of collisions with instance parameters, we append some model parameters with "_". // Because of collisions with instance parameters, we append some model parameters with "_".
if( aParam.info.name.EndsWith( "_" ) ) if( boost::ends_with( aParam.info.name, "_" ) )
name = aParam.info.name.BeforeLast( '_' ); name = aParam.info.name.substr( 0, aParam.info.name.length() - 1);
wxString value = aParam.value->ToString(); std::string value = aParam.value->ToString();
if( value.Contains( " " ) ) if( value.find( " " ) != std::string::npos )
value = "\"" + value + "\""; value = "\"" + value + "\"";
result << aParam.info.name + "=" + value; result.append( fmt::format( "{}={}", aParam.info.name, value ) );
return result; return result;
} }
wxString SIM_MODEL::GenerateParamsField( const wxString& aPairSeparator ) const std::string SIM_MODEL::GenerateParamsField( const std::string& aPairSeparator ) const
{ {
wxString result; std::string result;
bool isFirst = true; bool isFirst = true;
for( const PARAM& param : m_params ) for( const PARAM& param : m_params )
@ -1037,18 +1041,16 @@ wxString SIM_MODEL::GenerateParamsField( const wxString& aPairSeparator ) const
if( param.value->ToString() == "" ) if( param.value->ToString() == "" )
continue; continue;
result << GenerateParamValuePair( param, isFirst ); result.append( GenerateParamValuePair( param, isFirst ) );
} }
return result; return result;
} }
void SIM_MODEL::ParseParamsField( const wxString& aParamsField ) void SIM_MODEL::ParseParamsField( const std::string& aParamsField )
{ {
LOCALE_IO toggle; tao::pegtl::string_input<> in( aParamsField, "Sim_Params" );
tao::pegtl::string_input<> in( aParamsField.ToUTF8(), "Sim_Params" );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -1065,7 +1067,7 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
THROW_IO_ERROR( e.what() ); THROW_IO_ERROR( e.what() );
} }
wxString paramName; std::string paramName;
for( const auto& node : root->children ) for( const auto& node : root->children )
{ {
@ -1083,12 +1085,10 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
} }
else if( node->is_type<SIM_MODEL_PARSER::quotedString>() ) else if( node->is_type<SIM_MODEL_PARSER::quotedString>() )
{ {
wxASSERT( !paramName.IsEmpty() ); std::string str = node->string();
wxString str = node->string();
// Unescape quotes. // Unescape quotes.
str.Replace( "\\\"", "\"" ); boost::replace_all( str, "\\\"", "\"" );
SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI ); SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI );
} }
@ -1100,14 +1100,14 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
} }
void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsField ) void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const std::string& aPinsField )
{ {
CreatePins( aSymbolPinCount ); CreatePins( aSymbolPinCount );
if( aPinsField == "" ) if( aPinsField == "" )
return; return;
tao::pegtl::string_input<> in( aPinsField.ToUTF8(), PINS_FIELD ); tao::pegtl::string_input<> in( aPinsField, PINS_FIELD );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -1138,12 +1138,12 @@ void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsF
} }
void SIM_MODEL::ParseDisabledField( const wxString& aDisabledField ) void SIM_MODEL::ParseDisabledField( const std::string& aDisabledField )
{ {
if( aDisabledField == "" ) if( aDisabledField == "" )
return; return;
char c = aDisabledField.Lower()[0]; char c = boost::to_lower_copy( aDisabledField )[0];
if( c == 'y' || c == 't' || c == '1' ) if( c == 'y' || c == 't' || c == '1' )
m_isEnabled = false; m_isEnabled = false;
@ -1179,7 +1179,7 @@ void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount, const std::vec
return; return;
} }
wxString valueField = GetFieldValue( aFields, VALUE_FIELD ); std::string valueField = GetFieldValue( aFields, VALUE_FIELD );
if( aAllowParamValuePairs ) // The usual param-value pairs have precedence. if( aAllowParamValuePairs ) // The usual param-value pairs have precedence.
{ {
@ -1228,21 +1228,21 @@ void SIM_MODEL::doWriteFields( std::vector<T>& aFields ) const
} }
wxString SIM_MODEL::generateDeviceTypeField() const std::string SIM_MODEL::generateDeviceTypeField() const
{ {
return DeviceTypeInfo( TypeInfo( m_type ).deviceType ).fieldValue; return DeviceTypeInfo( TypeInfo( m_type ).deviceType ).fieldValue;
} }
wxString SIM_MODEL::generateTypeField() const std::string SIM_MODEL::generateTypeField() const
{ {
return TypeInfo( m_type ).fieldValue; return TypeInfo( m_type ).fieldValue;
} }
wxString SIM_MODEL::generatePinsField() const std::string SIM_MODEL::generatePinsField() const
{ {
wxString result = ""; std::string result = "";
bool isFirst = true; bool isFirst = true;
for( const PIN& pin : GetPins() ) for( const PIN& pin : GetPins() )
@ -1250,29 +1250,29 @@ wxString SIM_MODEL::generatePinsField() const
if( isFirst ) if( isFirst )
isFirst = false; isFirst = false;
else else
result << " "; result.append( " " );
if( pin.symbolPinNumber == "" ) if( pin.symbolPinNumber == "" )
result << "~"; result.append( "~" );
else else
result << pin.symbolPinNumber; // Note that it's numbered from 1. result.append( pin.symbolPinNumber ); // Note that it's numbered from 1.
} }
return result; return result;
} }
wxString SIM_MODEL::generateDisabledField() const std::string SIM_MODEL::generateDisabledField() const
{ {
return m_isEnabled ? "" : "1"; return m_isEnabled ? "" : "1";
} }
wxString SIM_MODEL::parseFieldFloatValue( wxString aFieldFloatValue ) std::string SIM_MODEL::parseFieldFloatValue( std::string aFieldFloatValue )
{ {
try try
{ {
tao::pegtl::string_input<> in( aFieldFloatValue.ToUTF8(), "Value" ); tao::pegtl::string_input<> in( aFieldFloatValue, "Value" );
auto root = tao::pegtl::parse_tree::parse< auto root = tao::pegtl::parse_tree::parse<
SIM_MODEL_PARSER::fieldFloatValueGrammar, SIM_MODEL_PARSER::fieldFloatValueGrammar,
SIM_MODEL_PARSER::fieldFloatValueSelector> SIM_MODEL_PARSER::fieldFloatValueSelector>

View File

@ -146,8 +146,8 @@ public:
struct DEVICE_INFO struct DEVICE_INFO
{ {
wxString fieldValue; std::string fieldValue;
wxString description; std::string description;
}; };
@ -302,27 +302,27 @@ public:
struct INFO struct INFO
{ {
DEVICE_TYPE_ deviceType; DEVICE_TYPE_ deviceType;
wxString fieldValue; std::string fieldValue;
wxString description; std::string description;
}; };
struct SPICE_INFO struct SPICE_INFO
{ {
wxString itemType; std::string itemType;
wxString modelType = ""; std::string modelType = "";
wxString inlineTypeString = ""; std::string inlineTypeString = "";
wxString level = ""; std::string level = "";
bool isDefaultLevel = false; bool isDefaultLevel = false;
bool hasExpression = false; bool hasExpression = false;
wxString version = ""; std::string version = "";
}; };
struct PIN struct PIN
{ {
const wxString name; const std::string name;
wxString symbolPinNumber; std::string symbolPinNumber;
static constexpr auto NOT_CONNECTED = -1; static constexpr auto NOT_CONNECTED = -1;
}; };
@ -359,38 +359,38 @@ public:
struct INFO struct INFO
{ {
wxString name = ""; std::string name = "";
unsigned id = 0; // Legacy (don't remove). unsigned id = 0; // Legacy (don't remove).
DIR dir = DIR_INOUT; DIR dir = DIR_INOUT;
SIM_VALUE::TYPE type = SIM_VALUE::TYPE_FLOAT; SIM_VALUE::TYPE type = SIM_VALUE::TYPE_FLOAT;
FLAGS flags = {}; // Legacy (don't remove). FLAGS flags = {}; // Legacy (don't remove).
wxString unit = ""; std::string unit = "";
CATEGORY category = CATEGORY::PRINCIPAL; CATEGORY category = CATEGORY::PRINCIPAL;
wxString defaultValue = ""; std::string defaultValue = "";
wxString defaultValueOfOtherVariant = ""; // Legacy (don't remove). std::string defaultValueOfOtherVariant = ""; // Legacy (don't remove).
wxString description = ""; std::string description = "";
bool isSpiceInstanceParam = false; bool isSpiceInstanceParam = false;
bool isInstanceParam = false; bool isInstanceParam = false;
wxString spiceModelName = ""; std::string spiceModelName = "";
wxString spiceInstanceName = ""; std::string spiceInstanceName = "";
std::vector<wxString> enumValues = {}; std::vector<std::string> enumValues = {};
// TODO: Stop using brace-initializers, use this constructor for all info structs. // TODO: Stop using brace-initializers, use this constructor for all info structs.
INFO( wxString aName = "", INFO( std::string aName = "",
unsigned aId = 0, unsigned aId = 0,
DIR aDir = DIR_INOUT, DIR aDir = DIR_INOUT,
SIM_VALUE::TYPE aType = SIM_VALUE::TYPE_FLOAT, SIM_VALUE::TYPE aType = SIM_VALUE::TYPE_FLOAT,
FLAGS aFlags = {}, FLAGS aFlags = {},
const wxString& aUnit = "", const std::string& aUnit = "",
CATEGORY aCategory = CATEGORY::PRINCIPAL, CATEGORY aCategory = CATEGORY::PRINCIPAL,
const wxString& aDefaultValue = "", const std::string& aDefaultValue = "",
const wxString& aDefaultValueOfOtherVariant = "", const std::string& aDefaultValueOfOtherVariant = "",
const wxString& aDescription = "", const std::string& aDescription = "",
bool aIsSpiceInstanceParam = false, bool aIsSpiceInstanceParam = false,
bool aIsInstanceParam = false, bool aIsInstanceParam = false,
const wxString& aSpiceModelName = "", const std::string& aSpiceModelName = "",
const wxString& aSpiceInstanceName = "", const std::string& aSpiceInstanceName = "",
std::vector<wxString> aEnumValues = {} ) : std::vector<std::string> aEnumValues = {} ) :
name( aName ), name( aName ),
id( aId ), id( aId ),
dir( aDir ), dir( aDir ),
@ -430,7 +430,7 @@ public:
template <typename T> template <typename T>
static TYPE ReadTypeFromFields( const std::vector<T>& aFields ); static TYPE ReadTypeFromFields( const std::vector<T>& aFields );
static TYPE InferTypeFromRefAndValue( const wxString& aRef, const wxString& aValue ); static TYPE InferTypeFromRefAndValue( const std::string& aRef, const std::string& aValue );
template <typename T> template <typename T>
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields ); static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
@ -449,11 +449,11 @@ public:
const std::vector<T>& aFields ); const std::vector<T>& aFields );
template <typename T> template <typename T>
static wxString GetFieldValue( const std::vector<T>* aFields, const wxString& aFieldName ); static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName );
template <typename T> template <typename T>
static void SetFieldValue( std::vector<T>& aFields, const wxString& aFieldName, static void SetFieldValue( std::vector<T>& aFields, const std::string& aFieldName,
const wxString& aValue ); const std::string& aValue );
const SPICE_GENERATOR& SpiceGenerator() const { return *m_spiceGenerator; } const SPICE_GENERATOR& SpiceGenerator() const { return *m_spiceGenerator; }
@ -487,7 +487,7 @@ public:
SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); } SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); }
void AddPin( const PIN& aPin ); void AddPin( const PIN& aPin );
int FindModelPinIndex( const wxString& aSymbolPinNumber ); int FindModelPinIndex( const std::string& aSymbolPinNumber );
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false ); void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
DEVICE_INFO GetDeviceTypeInfo() const { return DeviceTypeInfo( GetDeviceType() ); } DEVICE_INFO GetDeviceTypeInfo() const { return DeviceTypeInfo( GetDeviceType() ); }
@ -504,7 +504,7 @@ public:
std::vector<std::reference_wrapper<const PIN>> GetPins() const; std::vector<std::reference_wrapper<const PIN>> GetPins() const;
void SetPinSymbolPinNumber( int aPinIndex, const wxString& aSymbolPinNumber ) void SetPinSymbolPinNumber( int aPinIndex, const std::string& aSymbolPinNumber )
{ {
m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber; m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
} }
@ -513,18 +513,18 @@ public:
int GetParamCount() const { return static_cast<int>( m_params.size() ); } int GetParamCount() const { return static_cast<int>( m_params.size() ); }
const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden. const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden.
const PARAM* FindParam( const wxString& aParamName ) const; const PARAM* FindParam( const std::string& aParamName ) const;
std::vector<std::reference_wrapper<const PARAM>> GetParams() const; std::vector<std::reference_wrapper<const PARAM>> GetParams() const;
const PARAM& GetUnderlyingParam( unsigned aParamIndex ) const; // Return the actual parameter. const PARAM& GetUnderlyingParam( unsigned aParamIndex ) const; // Return the actual parameter.
const PARAM& GetBaseParam( unsigned aParamIndex ) const; // Always return base parameter if it exists. const PARAM& GetBaseParam( unsigned aParamIndex ) const; // Always return base parameter if it exists.
virtual bool SetParamValue( unsigned aParamIndex, const wxString& aValue, virtual bool SetParamValue( unsigned aParamIndex, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SI ); = SIM_VALUE_GRAMMAR::NOTATION::SI );
bool SetParamValue( const wxString& aParamName, const wxString& aValue, bool SetParamValue( const std::string& aParamName, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI ); SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
bool HasOverrides() const; bool HasOverrides() const;
@ -546,15 +546,15 @@ protected:
virtual void CreatePins( unsigned aSymbolPinCount ); virtual void CreatePins( unsigned aSymbolPinCount );
template <typename T> template <typename T>
void WriteInferredDataFields( std::vector<T>& aFields, const wxString& aValue ) const; void WriteInferredDataFields( std::vector<T>& aFields, const std::string& aValue ) const;
virtual wxString GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const; virtual std::string GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const;
wxString GenerateParamsField( const wxString& aPairSeparator ) const; std::string GenerateParamsField( const std::string& aPairSeparator ) const;
void ParseParamsField( const wxString& aParamsField ); void ParseParamsField( const std::string& aParamsField );
void ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsField ); void ParsePinsField( unsigned aSymbolPinCount, const std::string& aPinsField );
void ParseDisabledField( const wxString& aDisabledField ); void ParseDisabledField( const std::string& aDisabledField );
template <typename T> template <typename T>
void InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields, void InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields,
@ -562,9 +562,9 @@ protected:
bool aAllowParamValuePairs = true ); bool aAllowParamValuePairs = true );
private: private:
static TYPE readTypeFromSpiceStrings( const wxString& aTypeString, static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
const wxString& aLevel = "", const std::string& aLevel = "",
const wxString& aVersion = "", const std::string& aVersion = "",
bool aSkipDefaultLevel = true ); bool aSkipDefaultLevel = true );
@ -574,17 +574,17 @@ private:
template <typename T> template <typename T>
void doWriteFields( std::vector<T>& aFields ) const; void doWriteFields( std::vector<T>& aFields ) const;
wxString generateDeviceTypeField() const; std::string generateDeviceTypeField() const;
wxString generateTypeField() const; std::string generateTypeField() const;
wxString generatePinsField() const; std::string generatePinsField() const;
wxString generateDisabledField() const; std::string generateDisabledField() const;
wxString parseFieldFloatValue( wxString aFieldFloatValue ); std::string parseFieldFloatValue( std::string aFieldFloatValue );
virtual bool requiresSpiceModelLine() const; virtual bool requiresSpiceModelLine() const;
virtual std::vector<wxString> getPinNames() const { return {}; } virtual std::vector<std::string> getPinNames() const { return {}; }
std::unique_ptr<SPICE_GENERATOR> m_spiceGenerator; std::unique_ptr<SPICE_GENERATOR> m_spiceGenerator;

View File

@ -23,22 +23,23 @@
*/ */
#include <sim/sim_model_behavioral.h> #include <sim/sim_model_behavioral.h>
#include <locale_io.h>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <fmt/core.h>
wxString SPICE_GENERATOR_BEHAVIORAL::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_BEHAVIORAL::ModelLine( const std::string& aModelName ) const
{ {
return ""; return "";
} }
wxString SPICE_GENERATOR_BEHAVIORAL::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR_BEHAVIORAL::ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
LOCALE_IO toggle;
switch( m_model.GetType() ) switch( m_model.GetType() )
{ {
case SIM_MODEL::TYPE::R_BEHAVIORAL: case SIM_MODEL::TYPE::R_BEHAVIORAL:
@ -51,13 +52,15 @@ wxString SPICE_GENERATOR_BEHAVIORAL::ItemLine( const wxString& aRefName,
case SIM_MODEL::TYPE::V_BEHAVIORAL: case SIM_MODEL::TYPE::V_BEHAVIORAL:
return SPICE_GENERATOR::ItemLine( aRefName, return SPICE_GENERATOR::ItemLine( aRefName,
wxString::Format( "V=%s", m_model.GetParam( 0 ).value->ToString() ), fmt::format( "V={0}",
m_model.GetParam( 0 ).value->ToString() ),
aSymbolPinNumbers, aSymbolPinNumbers,
aPinNetNames ); aPinNetNames );
case SIM_MODEL::TYPE::I_BEHAVIORAL: case SIM_MODEL::TYPE::I_BEHAVIORAL:
return SPICE_GENERATOR::ItemLine( aRefName, return SPICE_GENERATOR::ItemLine( aRefName,
wxString::Format( "I=%s", m_model.GetParam( 0 ).value->ToString() ), fmt::format( "I={0}",
m_model.GetParam( 0 ).value->ToString() ),
aSymbolPinNumbers, aSymbolPinNumbers,
aPinNetNames ); aPinNetNames );
@ -129,14 +132,16 @@ void SIM_MODEL_BEHAVIORAL::WriteDataLibFields( std::vector<LIB_FIELD>& aFields )
} }
bool SIM_MODEL_BEHAVIORAL::parseValueField( const wxString& aValueField ) bool SIM_MODEL_BEHAVIORAL::parseValueField( const std::string& aValueField )
{ {
wxString expr = aValueField; std::string expr = aValueField;
if( !expr.Replace( "=", "", false ) )
return false;
SetParamValue( 0, expr.Trim( false ).Trim( true ) ); if( expr.find( "=" ) == std::string::npos )
return false;
boost::replace_first( expr, "=", "" );
SetParamValue( 0, boost::trim_copy( expr ) );
return true; return true;
} }
@ -161,7 +166,7 @@ void SIM_MODEL_BEHAVIORAL::inferredReadDataFields( unsigned aSymbolPinCount,
template <typename T> template <typename T>
void SIM_MODEL_BEHAVIORAL::inferredWriteDataFields( std::vector<T>& aFields ) const void SIM_MODEL_BEHAVIORAL::inferredWriteDataFields( std::vector<T>& aFields ) const
{ {
wxString value = GetParam( 0 ).value->ToString(); std::string value = GetParam( 0 ).value->ToString();
if( value == "" ) if( value == "" )
value = GetDeviceTypeInfo().fieldValue; value = GetDeviceTypeInfo().fieldValue;
@ -170,8 +175,8 @@ void SIM_MODEL_BEHAVIORAL::inferredWriteDataFields( std::vector<T>& aFields ) co
} }
SIM_MODEL::PARAM::INFO SIM_MODEL_BEHAVIORAL::makeParams( wxString aName, wxString aDescription, SIM_MODEL::PARAM::INFO SIM_MODEL_BEHAVIORAL::makeParams( std::string aName, std::string aDescription,
wxString aUnit ) std::string aUnit )
{ {
PARAM::INFO paramInfo = {}; PARAM::INFO paramInfo = {};

View File

@ -34,11 +34,11 @@ class SPICE_GENERATOR_BEHAVIORAL : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
wxString ItemLine( const wxString& aRefName, std::string ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override; const std::vector<std::string>& aPinNetNames ) const override;
}; };
@ -57,7 +57,7 @@ public:
private: private:
bool parseValueField( const wxString& aValueField ); bool parseValueField( const std::string& aValueField );
template <typename T> template <typename T>
void inferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields ); void inferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
@ -65,9 +65,9 @@ private:
template <typename T> template <typename T>
void inferredWriteDataFields( std::vector<T>& aFields ) const; void inferredWriteDataFields( std::vector<T>& aFields ) const;
std::vector<wxString> getPinNames() const override { return { "+", "-" }; } std::vector<std::string> getPinNames() const override { return { "+", "-" }; }
static PARAM::INFO makeParams( wxString aName, wxString aDescription, wxString aUnit ); static PARAM::INFO makeParams( std::string aName, std::string aDescription, std::string aUnit );
bool m_isInferred; bool m_isInferred;

View File

@ -27,18 +27,18 @@
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
wxString SPICE_GENERATOR_IDEAL::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_IDEAL::ModelLine( const std::string& aModelName ) const
{ {
return ""; return "";
} }
wxString SPICE_GENERATOR_IDEAL::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR_IDEAL::ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
wxString valueStr = m_model.GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE ); std::string valueStr = m_model.GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE );
if( valueStr != "" ) if( valueStr != "" )
return SPICE_GENERATOR::ItemLine( aRefName, valueStr, aSymbolPinNumbers, return SPICE_GENERATOR::ItemLine( aRefName, valueStr, aSymbolPinNumbers,
@ -108,17 +108,17 @@ void SIM_MODEL_IDEAL::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) cons
template <typename T> template <typename T>
void SIM_MODEL_IDEAL::inferredWriteDataFields( std::vector<T>& aFields ) const void SIM_MODEL_IDEAL::inferredWriteDataFields( std::vector<T>& aFields ) const
{ {
wxString value = GetParam( 0 ).value->ToString(); std::string value = GetParam( 0 ).value->ToString();
if( value.IsEmpty() ) if( value == "" )
value = DeviceTypeInfo( GetDeviceType() ).fieldValue; value = DeviceTypeInfo( GetDeviceType() ).fieldValue;
WriteInferredDataFields( aFields, value ); WriteInferredDataFields( aFields, value );
} }
SIM_MODEL::PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( wxString aName, wxString aDescription, SIM_MODEL::PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( std::string aName, std::string aDescription,
wxString aUnit ) std::string aUnit )
{ {
SIM_MODEL::PARAM::INFO paramInfo = {}; SIM_MODEL::PARAM::INFO paramInfo = {};

View File

@ -34,11 +34,11 @@ class SPICE_GENERATOR_IDEAL : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
wxString ItemLine( const wxString& aRefName, std::string ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override; const std::vector<std::string>& aPinNetNames ) const override;
}; };
@ -57,9 +57,9 @@ private:
template <typename T> template <typename T>
void inferredWriteDataFields( std::vector<T>& aFields ) const; void inferredWriteDataFields( std::vector<T>& aFields ) const;
std::vector<wxString> getPinNames() const override { return { "+", "-" }; } std::vector<std::string> getPinNames() const override { return { "+", "-" }; }
static PARAM::INFO makeParamInfo( wxString aName, wxString aDescription, wxString aUnit ); static PARAM::INFO makeParamInfo( std::string aName, std::string aDescription, std::string aUnit );
bool m_isInferred; bool m_isInferred;
}; };

View File

@ -25,12 +25,12 @@
#include <sim/sim_model_mutual_inductor.h> #include <sim/sim_model_mutual_inductor.h>
wxString SPICE_GENERATOR_MUTUAL_INDUCTOR::ItemParams() const std::string SPICE_GENERATOR_MUTUAL_INDUCTOR::ItemParams() const
{ {
wxString result; std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() ) for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
result << " " << param.value->ToSpiceString(); result.append( " " + param.value->ToSpiceString() );
return result; return result;
} }

View File

@ -34,7 +34,7 @@ class SPICE_GENERATOR_MUTUAL_INDUCTOR : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ItemParams() const override; std::string ItemParams() const override;
}; };

View File

@ -23,20 +23,20 @@
*/ */
#include <sim/sim_model_ngspice.h> #include <sim/sim_model_ngspice.h>
#include <locale_io.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <fmt/core.h>
std::vector<wxString> SPICE_GENERATOR_NGSPICE::CurrentNames( const wxString& aRefName ) const std::vector<std::string> SPICE_GENERATOR_NGSPICE::CurrentNames( const std::string& aRefName ) const
{ {
LOCALE_IO toggle;
switch( m_model.GetTypeInfo().deviceType ) switch( m_model.GetTypeInfo().deviceType )
{ {
case SIM_MODEL::DEVICE_TYPE_::NPN: case SIM_MODEL::DEVICE_TYPE_::NPN:
case SIM_MODEL::DEVICE_TYPE_::PNP: case SIM_MODEL::DEVICE_TYPE_::PNP:
return { wxString::Format( "I(%s:c)", aRefName ), return { fmt::format( "I({}:c)", aRefName ),
wxString::Format( "I(%s:b)", aRefName ), fmt::format( "I({}:b)", aRefName ),
wxString::Format( "I(%s:e)", aRefName ) }; fmt::format( "I({}:e)", aRefName ) };
case SIM_MODEL::DEVICE_TYPE_::NJFET: case SIM_MODEL::DEVICE_TYPE_::NJFET:
case SIM_MODEL::DEVICE_TYPE_::PJFET: case SIM_MODEL::DEVICE_TYPE_::PJFET:
@ -44,9 +44,9 @@ std::vector<wxString> SPICE_GENERATOR_NGSPICE::CurrentNames( const wxString& aRe
case SIM_MODEL::DEVICE_TYPE_::PMES: case SIM_MODEL::DEVICE_TYPE_::PMES:
case SIM_MODEL::DEVICE_TYPE_::NMOS: case SIM_MODEL::DEVICE_TYPE_::NMOS:
case SIM_MODEL::DEVICE_TYPE_::PMOS: case SIM_MODEL::DEVICE_TYPE_::PMOS:
return { wxString::Format( "I(%s:d)", aRefName ), return { fmt::format( "I({}:d)", aRefName ),
wxString::Format( "I(%s:g)", aRefName ), fmt::format( "I({}:g)", aRefName ),
wxString::Format( "I(%s:s)", aRefName ) }; fmt::format( "I({}:s)", aRefName ) };
case SIM_MODEL::DEVICE_TYPE_::R: case SIM_MODEL::DEVICE_TYPE_::R:
case SIM_MODEL::DEVICE_TYPE_::C: case SIM_MODEL::DEVICE_TYPE_::C:
@ -81,7 +81,7 @@ SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType ) :
} }
bool SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue, bool SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const std::string& aParamName, const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
// "level" and "version" are not really parameters - they're part of the type - so silently // "level" and "version" are not really parameters - they're part of the type - so silently
@ -107,8 +107,8 @@ bool SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const wxString& aParamName, const
{ {
return !param.info.isSpiceInstanceParam return !param.info.isSpiceInstanceParam
&& param.info.category != PARAM::CATEGORY::SUPERFLUOUS && param.info.category != PARAM::CATEGORY::SUPERFLUOUS
&& ( param.info.name == aParamName.Lower() && ( param.info.name == boost::to_lower_copy( aParamName )
|| param.info.name == aParamName.Lower() + "_" ); || param.info.name == boost::to_lower_copy( aParamName ) + "_" );
} ); } );
if( paramIt != params.end() ) if( paramIt != params.end() )
@ -122,7 +122,7 @@ bool SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const wxString& aParamName, const
auto ngspiceParamIt = std::find_if( ngspiceParams.begin(), ngspiceParams.end(), auto ngspiceParamIt = std::find_if( ngspiceParams.begin(), ngspiceParams.end(),
[aParamName]( const PARAM& param ) [aParamName]( const PARAM& param )
{ {
return param.info.name == aParamName.Lower(); return param.info.name == boost::to_lower_copy( aParamName );
} ); } );
if( ngspiceParamIt == ngspiceParams.end() ) if( ngspiceParamIt == ngspiceParams.end() )
@ -146,7 +146,7 @@ bool SIM_MODEL_NGSPICE::SetParamFromSpiceCode( const wxString& aParamName, const
} }
std::vector<wxString> SIM_MODEL_NGSPICE::getPinNames() const std::vector<std::string> SIM_MODEL_NGSPICE::getPinNames() const
{ {
return ModelInfo( getModelType() ).pinNames; return ModelInfo( getModelType() ).pinNames;
} }

View File

@ -34,7 +34,7 @@ class SPICE_GENERATOR_NGSPICE : public SPICE_GENERATOR_SPICE
public: public:
using SPICE_GENERATOR_SPICE::SPICE_GENERATOR_SPICE; using SPICE_GENERATOR_SPICE::SPICE_GENERATOR_SPICE;
std::vector<wxString> CurrentNames( const wxString& aRefName ) const override; std::vector<std::string> CurrentNames( const std::string& aRefName ) const override;
}; };
@ -46,7 +46,7 @@ public:
SIM_MODEL_NGSPICE( TYPE aType ); SIM_MODEL_NGSPICE( TYPE aType );
bool SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue, bool SetParamFromSpiceCode( const std::string& aParamName, const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) override; SIM_VALUE_GRAMMAR::NOTATION aNotation ) override;
// Protected because it's accessed by QA tests. // Protected because it's accessed by QA tests.
@ -92,11 +92,11 @@ protected:
struct MODEL_INFO struct MODEL_INFO
{ {
wxString name; std::string name;
wxString variant1; std::string variant1;
wxString variant2; std::string variant2;
std::vector<wxString> pinNames; std::vector<std::string> pinNames;
wxString description; std::string description;
std::vector<SIM_MODEL::PARAM::INFO> modelParams; std::vector<SIM_MODEL::PARAM::INFO> modelParams;
std::vector<SIM_MODEL::PARAM::INFO> instanceParams; std::vector<SIM_MODEL::PARAM::INFO> instanceParams;
}; };
@ -106,7 +106,7 @@ protected:
private: private:
bool requiresSpiceModelLine() const override { return false; } bool requiresSpiceModelLine() const override { return false; }
std::vector<wxString> getPinNames() const override; std::vector<std::string> getPinNames() const override;
MODEL_TYPE getModelType() const; MODEL_TYPE getModelType() const;
bool getIsOtherVariant(); bool getIsOtherVariant();

View File

@ -23,6 +23,9 @@
*/ */
#include <sim/sim_model_raw_spice.h> #include <sim/sim_model_raw_spice.h>
#include <boost/algorithm/string/predicate.hpp>
#include <fmt/core.h>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
@ -36,30 +39,30 @@ namespace SIM_MODEL_RAW_SPICE_PARSER
} }
wxString SPICE_GENERATOR_RAW_SPICE::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_RAW_SPICE::ModelLine( const std::string& aModelName ) const
{ {
return ""; return "";
} }
wxString SPICE_GENERATOR_RAW_SPICE::ItemName( const wxString& aRefName ) const std::string SPICE_GENERATOR_RAW_SPICE::ItemName( const std::string& aRefName ) const
{ {
wxString elementType = m_model.GetParam( std::string elementType = m_model.GetParam(
static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::TYPE ) ).value->ToString(); static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::TYPE ) ).value->ToString();
if( aRefName != "" && aRefName.StartsWith( elementType ) ) if( aRefName != "" && boost::starts_with( aRefName, elementType ) )
return aRefName; return aRefName;
else else
return elementType + aRefName; return elementType + aRefName;
} }
wxString SPICE_GENERATOR_RAW_SPICE::ItemPins( const wxString& aRefName, std::string SPICE_GENERATOR_RAW_SPICE::ItemPins( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
wxString result; std::string result;
for( const SIM_MODEL::PIN& pin : GetPins() ) for( const SIM_MODEL::PIN& pin : GetPins() )
{ {
@ -69,7 +72,7 @@ wxString SPICE_GENERATOR_RAW_SPICE::ItemPins( const wxString& aRefName,
if( it != aSymbolPinNumbers.end() ) if( it != aSymbolPinNumbers.end() )
{ {
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it ); long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
result << " " << aPinNetNames.at( symbolPinIndex ); result.append( " " + aPinNetNames.at( symbolPinIndex ) );
} }
} }
@ -77,37 +80,35 @@ wxString SPICE_GENERATOR_RAW_SPICE::ItemPins( const wxString& aRefName,
} }
wxString SPICE_GENERATOR_RAW_SPICE::ItemModelName( const wxString& aModelName ) const std::string SPICE_GENERATOR_RAW_SPICE::ItemModelName( const std::string& aModelName ) const
{ {
return ""; return "";
} }
wxString SPICE_GENERATOR_RAW_SPICE::ItemParams() const std::string SPICE_GENERATOR_RAW_SPICE::ItemParams() const
{ {
wxString result; std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() ) for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
{ {
if( param.info.name != "model" ) if( param.info.name == "model" )
result << ""; result.append( " " + param.value->ToString() );
else
result << " " << param.value->ToString();
} }
return result; return result;
} }
wxString SPICE_GENERATOR_RAW_SPICE::Preview( const wxString& aModelName ) const std::string SPICE_GENERATOR_RAW_SPICE::Preview( const std::string& aModelName ) const
{ {
std::vector<wxString> pinNumbers; std::vector<std::string> pinNumbers;
std::vector<wxString> pinNetNames; std::vector<std::string> pinNetNames;
for( int i = 0; i < m_model.GetPinCount(); ++i ) for( int i = 0; i < m_model.GetPinCount(); ++i )
{ {
pinNumbers.push_back( wxString::FromCDouble( i + 1 ) ); pinNumbers.push_back( fmt::format( "{0}", i + 1 ) );
pinNetNames.push_back( wxString::FromCDouble( i + 1 ) ); pinNetNames.push_back( fmt::format( "{0}", i + 1 ) );
} }
return ItemLine( "", aModelName, pinNumbers, pinNetNames ); return ItemLine( "", aModelName, pinNumbers, pinNetNames );
@ -162,7 +163,7 @@ void SIM_MODEL_RAW_SPICE::WriteDataLibFields( std::vector<LIB_FIELD>& aFields )
void SIM_MODEL_RAW_SPICE::CreatePins( unsigned aSymbolPinCount ) void SIM_MODEL_RAW_SPICE::CreatePins( unsigned aSymbolPinCount )
{ {
for( unsigned symbolPinIndex = 0; symbolPinIndex < aSymbolPinCount; ++symbolPinIndex ) for( unsigned symbolPinIndex = 0; symbolPinIndex < aSymbolPinCount; ++symbolPinIndex )
AddPin( { "", wxString::FromCDouble( symbolPinIndex + 1 ) } ); AddPin( { "", fmt::format( "{}", symbolPinIndex + 1 ) } );
} }
@ -258,7 +259,7 @@ void SIM_MODEL_RAW_SPICE::readLegacyDataFields( unsigned aSymbolPinCount,
void SIM_MODEL_RAW_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount, void SIM_MODEL_RAW_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
const wxString& aLegacyPinsField ) const std::string& aLegacyPinsField )
{ {
if( aLegacyPinsField == "" ) if( aLegacyPinsField == "" )
return; return;
@ -267,7 +268,7 @@ void SIM_MODEL_RAW_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex ) for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
SetPinSymbolPinNumber( static_cast<int>( modelPinIndex ), "" ); SetPinSymbolPinNumber( static_cast<int>( modelPinIndex ), "" );
tao::pegtl::string_input<> in( aLegacyPinsField.ToUTF8(), PINS_FIELD ); tao::pegtl::string_input<> in( aLegacyPinsField, PINS_FIELD );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -287,12 +288,8 @@ void SIM_MODEL_RAW_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
int symbolPinIndex = std::stoi( symbolPinStr ) - 1; int symbolPinIndex = std::stoi( symbolPinStr ) - 1;
if( symbolPinIndex < 0 || symbolPinIndex >= static_cast<int>( aSymbolPinCount ) ) if( symbolPinIndex < 0 || symbolPinIndex >= static_cast<int>( aSymbolPinCount ) )
{ THROW_IO_ERROR( wxString::Format( _( "Invalid symbol pin index: '%s'" ), symbolPinStr ) );
THROW_IO_ERROR( wxString::Format( _( "Invalid symbol pin index: '%s'" ),
symbolPinStr ) );
}
SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() ); SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() );
} }
} }

View File

@ -34,17 +34,17 @@ class SPICE_GENERATOR_RAW_SPICE : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
wxString ItemName( const wxString& aRefName ) const override; std::string ItemName( const std::string& aRefName ) const override;
wxString ItemPins( const wxString& aRefName, std::string ItemPins( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override; const std::vector<std::string>& aPinNetNames ) const override;
wxString ItemModelName( const wxString& aModelName ) const override; std::string ItemModelName( const std::string& aModelName ) const override;
wxString ItemParams() const override; std::string ItemParams() const override;
wxString Preview( const wxString& aModelName ) const override; std::string Preview( const std::string& aModelName ) const override;
}; };
@ -84,7 +84,7 @@ private:
template <typename T> template <typename T>
void readLegacyDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields ); void readLegacyDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
void parseLegacyPinsField( unsigned aSymbolPinCount, const wxString& aLegacyPinsField ); void parseLegacyPinsField( unsigned aSymbolPinCount, const std::string& aLegacyPinsField );
bool requiresSpiceModelLine() const override { return false; } bool requiresSpiceModelLine() const override { return false; }

View File

@ -23,9 +23,10 @@
*/ */
#include <sim/sim_model_source.h> #include <sim/sim_model_source.h>
#include <fmt/core.h>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
#include <locale_io.h>
namespace SIM_MODEL_SOURCE_PARSER namespace SIM_MODEL_SOURCE_PARSER
@ -38,29 +39,28 @@ namespace SIM_MODEL_SOURCE_PARSER
} }
wxString SPICE_GENERATOR_SOURCE::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_SOURCE::ModelLine( const std::string& aModelName ) const
{ {
return ""; return "";
} }
wxString SPICE_GENERATOR_SOURCE::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR_SOURCE::ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
LOCALE_IO toggle; std::string model;
wxString model;
wxString ac = m_model.FindParam( "ac" )->value->ToSpiceString(); std::string ac = m_model.FindParam( "ac" )->value->ToSpiceString();
wxString ph = m_model.FindParam( "ph" )->value->ToSpiceString(); std::string ph = m_model.FindParam( "ph" )->value->ToSpiceString();
if( ac != "" ) if( ac != "" )
model << wxString::Format( "AC %s %s ", ac, ph ); model.append( fmt::format( "AC {} {} ", ac, ph ) );
if( m_model.GetSpiceInfo().inlineTypeString != "" ) if( m_model.GetSpiceInfo().inlineTypeString != "" )
{ {
wxString args = ""; std::string args = "";
switch( m_model.GetType() ) switch( m_model.GetType() )
{ {
@ -91,7 +91,7 @@ wxString SPICE_GENERATOR_SOURCE::ItemLine( const wxString& aRefName,
{ {
std::unique_ptr<SIM_VALUE> value = SIM_VALUE::Create( SIM_VALUE::TYPE_FLOAT, std::unique_ptr<SIM_VALUE> value = SIM_VALUE::Create( SIM_VALUE::TYPE_FLOAT,
node->string() ); node->string() );
args << value->ToString( SIM_VALUE::NOTATION::SPICE ) << " "; args.append( value->ToString( SIM_VALUE::NOTATION::SPICE ) + " " );
} }
} }
} }
@ -102,96 +102,96 @@ wxString SPICE_GENERATOR_SOURCE::ItemLine( const wxString& aRefName,
case SIM_MODEL::TYPE::V_WHITENOISE: case SIM_MODEL::TYPE::V_WHITENOISE:
case SIM_MODEL::TYPE::I_WHITENOISE: case SIM_MODEL::TYPE::I_WHITENOISE:
args << getParamValueString( "rms", "0" ) << " "; args.append( getParamValueString( "rms", "0" ) + " " );
args << getParamValueString( "dt", "0" ) << " "; args.append( getParamValueString( "dt", "0" ) + " " );
args << "0 0 0 0 0 "; args.append( "0 0 0 0 0 " );
break; break;
case SIM_MODEL::TYPE::V_PINKNOISE: case SIM_MODEL::TYPE::V_PINKNOISE:
case SIM_MODEL::TYPE::I_PINKNOISE: case SIM_MODEL::TYPE::I_PINKNOISE:
args << "0 "; args.append( "0 " );
args << getParamValueString( "dt", "0" ) << " "; args.append( getParamValueString( "dt", "0" ) + " " );
args << getParamValueString( "slope", "0" ) << " "; args.append( getParamValueString( "slope", "0" ) + " " );
args << getParamValueString( "rms", "0" ) << " "; args.append( getParamValueString( "rms", "0" ) + " " );
args << "0 0 0 "; args.append( "0 0 0 " );
break; break;
case SIM_MODEL::TYPE::V_BURSTNOISE: case SIM_MODEL::TYPE::V_BURSTNOISE:
case SIM_MODEL::TYPE::I_BURSTNOISE: case SIM_MODEL::TYPE::I_BURSTNOISE:
args << "0 0 0 0 "; args.append( "0 0 0 0 " );
args << getParamValueString( "ampl", "0" ) << " "; args.append( getParamValueString( "ampl", "0" ) + " " );
args << getParamValueString( "tcapt", "0" ) << " "; args.append( getParamValueString( "tcapt", "0" ) + " " );
args << getParamValueString( "temit", "0" ) << " "; args.append( getParamValueString( "temit", "0" ) + " " );
break; break;
case SIM_MODEL::TYPE::V_RANDUNIFORM: case SIM_MODEL::TYPE::V_RANDUNIFORM:
case SIM_MODEL::TYPE::I_RANDUNIFORM: case SIM_MODEL::TYPE::I_RANDUNIFORM:
{ {
args << "1 "; args.append( "1 " );
args << getParamValueString( "dt", "0" ) << " "; args.append( getParamValueString( "dt", "0" ) + " " );
args << getParamValueString( "td", "0" ) << " "; args.append( getParamValueString( "td", "0" ) + " " );
auto min = dynamic_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "max" )->value ); auto min = dynamic_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "max" )->value );
auto max = dynamic_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "min" )->value ); auto max = dynamic_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "min" )->value );
SIM_VALUE_FLOAT range = max - min; SIM_VALUE_FLOAT range = max - min;
SIM_VALUE_FLOAT offset = ( max + min ) / SIM_VALUE_FLOAT( 2 ); SIM_VALUE_FLOAT offset = ( max + min ) / SIM_VALUE_FLOAT( 2 );
args << range.ToSpiceString() << " "; args.append( range.ToSpiceString() + " " );
args << offset.ToSpiceString() << " "; args.append( offset.ToSpiceString() + " " );
} }
break; break;
case SIM_MODEL::TYPE::V_RANDNORMAL: case SIM_MODEL::TYPE::V_RANDNORMAL:
case SIM_MODEL::TYPE::I_RANDNORMAL: case SIM_MODEL::TYPE::I_RANDNORMAL:
args << "2 "; args.append( "2 " );
args << getParamValueString( "dt", "0" ) << " "; args.append( getParamValueString( "dt", "0" ) + " " );
args << getParamValueString( "td", "0" ) << " "; args.append( getParamValueString( "td", "0" ) + " " );
args << getParamValueString( "stddev", "0" ) << " "; args.append( getParamValueString( "stddev", "0" ) + " " );
args << getParamValueString( "mean", "0" ) << " "; args.append( getParamValueString( "mean", "0" ) + " " );
break; break;
case SIM_MODEL::TYPE::V_RANDEXP: case SIM_MODEL::TYPE::V_RANDEXP:
case SIM_MODEL::TYPE::I_RANDEXP: case SIM_MODEL::TYPE::I_RANDEXP:
args << "3 "; args.append( "3 " );
args << getParamValueString( "dt", "0" ) << " "; args.append( getParamValueString( "dt", "0" ) + " " );
args << getParamValueString( "td", "0" ) << " "; args.append( getParamValueString( "td", "0" ) + " " );
args << getParamValueString( "mean", "0" ) << " "; args.append( getParamValueString( "mean", "0" ) + " " );
args << getParamValueString( "offset", "0" ) << " "; args.append( getParamValueString( "offset", "0" ) + " " );
break; break;
/*case SIM_MODEL::TYPE::V_RANDPOISSON: /*case SIM_MODEL::TYPE::V_RANDPOISSON:
case SIM_MODEL::TYPE::I_RANDPOISSON: case SIM_MODEL::TYPE::I_RANDPOISSON:
args << "4 "; args.append( "4 " );
args << FindParam( "dt" )->value->ToSpiceString() << " "; args.append( FindParam( "dt" )->value->ToSpiceString() + " " );
args << FindParam( "td" )->value->ToSpiceString() << " "; args.append( FindParam( "td" )->value->ToSpiceString() + " " );
args << FindParam( "lambda" )->value->ToSpiceString() << " "; args.append( FindParam( "lambda" )->value->ToSpiceString() + " " );
args << FindParam( "offset" )->value->ToSpiceString() << " "; args.append( FindParam( "offset" )->value->ToSpiceString() + " " );
break;*/ break;*/
default: default:
for( const SIM_MODEL::PARAM& param : m_model.GetParams() ) for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
{ {
wxString argStr = param.value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE ); std::string argStr = param.value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE );
if( argStr != "" ) if( argStr != "" )
args << argStr << " "; args.append( argStr + " " );
} }
break; break;
} }
model << wxString::Format( "%s( %s)", m_model.GetSpiceInfo().inlineTypeString, args ); model.append( fmt::format( "{}( {})", m_model.GetSpiceInfo().inlineTypeString, args ) );
} }
else else
model << m_model.GetParam( 0 ).value->ToSpiceString(); model.append( m_model.GetParam( 0 ).value->ToSpiceString() );
return SPICE_GENERATOR::ItemLine( aRefName, model, aSymbolPinNumbers, aPinNetNames ); return SPICE_GENERATOR::ItemLine( aRefName, model, aSymbolPinNumbers, aPinNetNames );
} }
wxString SPICE_GENERATOR_SOURCE::getParamValueString( const wxString& aParamName, std::string SPICE_GENERATOR_SOURCE::getParamValueString( const std::string& aParamName,
const wxString& aDefaultValue ) const const std::string& aDefaultValue ) const
{ {
wxString result = m_model.FindParam( aParamName )->value->ToSpiceString(); std::string result = m_model.FindParam( aParamName )->value->ToSpiceString();
if( result == "" ) if( result == "" )
result = aDefaultValue; result = aDefaultValue;
@ -227,7 +227,7 @@ void SIM_MODEL_SOURCE::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) con
} }
bool SIM_MODEL_SOURCE::SetParamValue( unsigned aParamIndex, const wxString& aValue, bool SIM_MODEL_SOURCE::SetParamValue( unsigned aParamIndex, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
// Sources are special. All preceding parameter values must be filled. If they are not, fill // Sources are special. All preceding parameter values must be filled. If they are not, fill
@ -254,7 +254,7 @@ bool SIM_MODEL_SOURCE::SetParamValue( unsigned aParamIndex, const wxString& aVal
} }
wxString SIM_MODEL_SOURCE::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const std::string SIM_MODEL_SOURCE::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const
{ {
if( aParam.value->ToString() == "0" ) if( aParam.value->ToString() == "0" )
return ""; return "";
@ -266,7 +266,7 @@ wxString SIM_MODEL_SOURCE::GenerateParamValuePair( const PARAM& aParam, bool& aI
template <typename T> template <typename T>
void SIM_MODEL_SOURCE::inferredWriteDataFields( std::vector<T>& aFields ) const void SIM_MODEL_SOURCE::inferredWriteDataFields( std::vector<T>& aFields ) const
{ {
wxString value = GetFieldValue( &aFields, PARAMS_FIELD ); std::string value = GetFieldValue( &aFields, PARAMS_FIELD );
if( value == "" ) if( value == "" )
value = GetDeviceTypeInfo().fieldValue; value = GetDeviceTypeInfo().fieldValue;
@ -357,8 +357,8 @@ const std::vector<SIM_MODEL::PARAM::INFO>& SIM_MODEL_SOURCE::makeParamInfos( TYP
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeDcParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeDcParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -376,8 +376,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeDcParamInfos( wxString
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSinParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSinParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -437,8 +437,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSinParamInfos( wxStrin
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePulseParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePulseParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -514,8 +514,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePulseParamInfos( wxStr
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeExpParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeExpParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -573,7 +573,7 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeExpParamInfos( wxStrin
} }
/*std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSfamParamInfos( wxString aPrefix, wxString aUnit ) /*std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSfamParamInfos( std::string aPrefix, std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -622,7 +622,7 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeExpParamInfos( wxStrin
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSffmParamInfos( wxString aPrefix, wxString aUnit ) std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSffmParamInfos( std::string aPrefix, std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -688,9 +688,9 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSffmParamInfos( wxStri
}*/ }*/
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePwlParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePwlParamInfos( std::string aPrefix,
wxString aQuantity, std::string aQuantity,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -762,8 +762,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePwlParamInfos( wxStrin
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -789,8 +789,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos(
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoiseParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoiseParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -824,8 +824,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoiseParamInfos( w
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -859,8 +859,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoiseParamInfos(
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniformParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniformParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -902,8 +902,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniformParamInfo
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormalParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormalParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -945,8 +945,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormalParamInfos
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExpParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExpParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -988,8 +988,8 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExpParamInfos( w
} }
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoissonParamInfos( wxString aPrefix, std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoissonParamInfos( std::string aPrefix,
wxString aUnit ) std::string aUnit )
{ {
std::vector<PARAM::INFO> paramInfos; std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo; PARAM::INFO paramInfo;
@ -1030,7 +1030,7 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoissonParamInfo
return paramInfos; return paramInfos;
} }
void SIM_MODEL_SOURCE::appendAcParamInfos( std::vector<PARAM::INFO>& aParamInfos, wxString aUnit ) void SIM_MODEL_SOURCE::appendAcParamInfos( std::vector<PARAM::INFO>& aParamInfos, std::string aUnit )
{ {
PARAM::INFO paramInfo; PARAM::INFO paramInfo;

View File

@ -49,15 +49,15 @@ class SPICE_GENERATOR_SOURCE : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
wxString ItemLine( const wxString& aRefName, std::string ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override; const std::vector<std::string>& aPinNetNames ) const override;
private: private:
wxString getParamValueString( const wxString& aParamName, std::string getParamValueString( const std::string& aParamName,
const wxString& aDefaultValue ) const; const std::string& aDefaultValue ) const;
}; };
@ -69,40 +69,40 @@ public:
void WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const override; void WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const override;
void WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const override; void WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const override;
bool SetParamValue( unsigned aParamIndex, const wxString& aValue, bool SetParamValue( unsigned aParamIndex, const std::string& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI ) SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI )
override; override;
bool HasAutofill() const override { return true; } bool HasAutofill() const override { return true; }
protected: protected:
wxString GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override; std::string GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override;
private: private:
template <typename T> template <typename T>
void inferredWriteDataFields( std::vector<T>& aFields ) const; void inferredWriteDataFields( std::vector<T>& aFields ) const;
std::vector<wxString> getPinNames() const override { return { "+", "-" }; } std::vector<std::string> getPinNames() const override { return { "+", "-" }; }
static const std::vector<PARAM::INFO>& makeParamInfos( TYPE aType ); static const std::vector<PARAM::INFO>& makeParamInfos( TYPE aType );
static std::vector<PARAM::INFO> makeDcParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeDcParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeSinParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeSinParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makePulseParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makePulseParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeExpParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeExpParamInfos( std::string aPrefix, std::string aUnit );
//static std::vector<PARAM::INFO> makeSfamParamInfos( wxString aPrefix, wxString aUnit ); //static std::vector<PARAM::INFO> makeSfamParamInfos( std::string aPrefix, std::string aUnit );
//static std::vector<PARAM::INFO> makeSffmParamInfos( wxString aPrefix, wxString aUnit ); //static std::vector<PARAM::INFO> makeSffmParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makePwlParamInfos( wxString aPrefix, wxString aQuantity, static std::vector<PARAM::INFO> makePwlParamInfos( std::string aPrefix, std::string aQuantity,
wxString aUnit ); std::string aUnit );
static std::vector<PARAM::INFO> makeWhiteNoiseParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeWhiteNoiseParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makePinkNoiseParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makePinkNoiseParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeBurstNoiseParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeBurstNoiseParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeRandomUniformParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeRandomUniformParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeRandomNormalParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeRandomNormalParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeRandomExpParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeRandomExpParamInfos( std::string aPrefix, std::string aUnit );
static std::vector<PARAM::INFO> makeRandomPoissonParamInfos( wxString aPrefix, wxString aUnit ); static std::vector<PARAM::INFO> makeRandomPoissonParamInfos( std::string aPrefix, std::string aUnit );
static void appendAcParamInfos( std::vector<PARAM::INFO>& aParamInfos, wxString aUnit ); static void appendAcParamInfos( std::vector<PARAM::INFO>& aParamInfos, std::string aUnit );
bool m_isInferred; bool m_isInferred;

View File

@ -25,13 +25,14 @@
#include <sim/sim_model_spice.h> #include <sim/sim_model_spice.h>
#include <sim/sim_model_raw_spice.h> #include <sim/sim_model_raw_spice.h>
#include <sim/spice_model_parser.h> #include <sim/spice_model_parser.h>
#include <confirm.h> #include <confirm.h>
#include <boost/algorithm/string/trim.hpp>
wxString SPICE_GENERATOR_SPICE::Preview( const wxString& aModelName ) const
std::string SPICE_GENERATOR_SPICE::Preview( const std::string& aModelName ) const
{ {
wxString spiceCode = ModelLine( aModelName ); std::string spiceCode = ModelLine( aModelName );
if( spiceCode == "" ) if( spiceCode == "" )
spiceCode = static_cast<const SIM_MODEL_SPICE&>( m_model ).m_spiceCode; spiceCode = static_cast<const SIM_MODEL_SPICE&>( m_model ).m_spiceCode;
@ -39,16 +40,17 @@ wxString SPICE_GENERATOR_SPICE::Preview( const wxString& aModelName ) const
if( spiceCode == "" && m_model.GetBaseModel() ) if( spiceCode == "" && m_model.GetBaseModel() )
spiceCode = static_cast<const SIM_MODEL_SPICE*>( m_model.GetBaseModel() )->m_spiceCode; spiceCode = static_cast<const SIM_MODEL_SPICE*>( m_model.GetBaseModel() )->m_spiceCode;
wxString itemLine = ItemLine( "", aModelName ); std::string itemLine = ItemLine( "", aModelName );
if( spiceCode != "" )
spiceCode << "\n";
spiceCode << itemLine; if( spiceCode != "" )
return spiceCode.Trim(); spiceCode.append( "\n" );
spiceCode.append( itemLine );
return boost::trim_copy( spiceCode );
} }
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const wxString& aSpiceCode ) std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const std::string& aSpiceCode )
{ {
auto model = static_cast<SIM_MODEL_SPICE*>( auto model = static_cast<SIM_MODEL_SPICE*>(
SIM_MODEL::Create( SPICE_MODEL_PARSER::ReadType( aSpiceCode ) ).release() ); SIM_MODEL::Create( SPICE_MODEL_PARSER::ReadType( aSpiceCode ) ).release() );
@ -83,7 +85,7 @@ SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType,
} }
bool SIM_MODEL_SPICE::SetParamValue( unsigned aParamIndex, const wxString& aParamValue, bool SIM_MODEL_SPICE::SetParamValue( unsigned aParamIndex, const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
// Models sourced from a library are immutable. // Models sourced from a library are immutable.
@ -94,8 +96,8 @@ bool SIM_MODEL_SPICE::SetParamValue( unsigned aParamIndex, const wxString& aPara
} }
bool SIM_MODEL_SPICE::SetParamFromSpiceCode( const wxString& aParamName, bool SIM_MODEL_SPICE::SetParamFromSpiceCode( const std::string& aParamName,
const wxString& aParamValue, const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
{ {
return SIM_MODEL::SetParamValue( aParamName, aParamValue, aNotation ); return SIM_MODEL::SetParamValue( aParamName, aParamValue, aNotation );

View File

@ -35,7 +35,7 @@ class SPICE_GENERATOR_SPICE : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString Preview( const wxString& aModelName ) const override; std::string Preview( const std::string& aModelName ) const override;
}; };
@ -45,7 +45,7 @@ public:
friend class SPICE_GENERATOR_SPICE; friend class SPICE_GENERATOR_SPICE;
friend class SPICE_MODEL_PARSER; friend class SPICE_MODEL_PARSER;
static std::unique_ptr<SIM_MODEL_SPICE> Create( const wxString& aSpiceCode ); static std::unique_ptr<SIM_MODEL_SPICE> Create( const std::string& aSpiceCode );
SIM_MODEL_SPICE( TYPE aType, SIM_MODEL_SPICE( TYPE aType,
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ); std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator );
@ -55,15 +55,16 @@ public:
std::unique_ptr<SPICE_MODEL_PARSER> aSpiceModelParser ); std::unique_ptr<SPICE_MODEL_PARSER> aSpiceModelParser );
protected: protected:
bool SetParamValue( unsigned aParamIndex, const wxString& aParamValue, bool SetParamValue( unsigned aParamIndex, const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SI ) override; = SIM_VALUE_GRAMMAR::NOTATION::SI ) override;
virtual bool SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue, virtual bool SetParamFromSpiceCode( const std::string& aParamName,
const std::string& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SPICE ); = SIM_VALUE_GRAMMAR::NOTATION::SPICE );
wxString m_spiceCode; std::string m_spiceCode;
private: private:
std::unique_ptr<SPICE_MODEL_PARSER> m_spiceModelParser; std::unique_ptr<SPICE_MODEL_PARSER> m_spiceModelParser;

View File

@ -24,6 +24,8 @@
#include <sim/sim_model_subckt.h> #include <sim/sim_model_subckt.h>
#include <sim/spice_grammar.h> #include <sim/spice_grammar.h>
#include <fmt/core.h>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
@ -46,30 +48,26 @@ namespace SIM_MODEL_SUBCKT_SPICE_PARSER
} }
wxString SPICE_GENERATOR_SUBCKT::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_SUBCKT::ModelLine( const std::string& aModelName ) const
{ {
return ""; return "";
} }
std::vector<wxString> SPICE_GENERATOR_SUBCKT::CurrentNames( const wxString& aRefName ) const std::vector<std::string> SPICE_GENERATOR_SUBCKT::CurrentNames( const std::string& aRefName ) const
{ {
std::vector<wxString> currentNames; std::vector<std::string> currentNames;
for( const SIM_MODEL::PIN& pin : GetPins() ) for( const SIM_MODEL::PIN& pin : GetPins() )
{ currentNames.push_back( fmt::format( "I({:s}:{:s})", ItemName( aRefName ), pin.name ) );
currentNames.push_back( wxString::Format( "I(%s:%s)",
ItemName( aRefName ),
pin.name ) );
}
return currentNames; return currentNames;
} }
void SPICE_MODEL_PARSER_SUBCKT::ReadModel( const wxString& aSpiceCode ) void SPICE_MODEL_PARSER_SUBCKT::ReadModel( const std::string& aSpiceCode )
{ {
tao::pegtl::string_input<> in( aSpiceCode.ToUTF8(), "from_content" ); tao::pegtl::string_input<> in( aSpiceCode, "from_content" );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -98,7 +96,7 @@ void SPICE_MODEL_PARSER_SUBCKT::ReadModel( const wxString& aSpiceCode )
} }
else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktPinName>() ) else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktPinName>() )
{ {
model.AddPin( { subnode->string(), wxString::FromCDouble( model.GetPinCount() + 1 ) } ); model.AddPin( { subnode->string(), fmt::format( "{:d}", model.GetPinCount() + 1 ) } );
} }
else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktParams>() ) else if( subnode->is_type<SIM_MODEL_SUBCKT_SPICE_PARSER::dotSubcktParams>() )
{ {

View File

@ -34,8 +34,8 @@ class SPICE_GENERATOR_SUBCKT : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
std::vector<wxString> CurrentNames( const wxString& aRefName ) const override; std::vector<std::string> CurrentNames( const std::string& aRefName ) const override;
}; };
@ -44,7 +44,7 @@ class SPICE_MODEL_PARSER_SUBCKT : public SPICE_MODEL_PARSER
public: public:
using SPICE_MODEL_PARSER::SPICE_MODEL_PARSER; using SPICE_MODEL_PARSER::SPICE_MODEL_PARSER;
void ReadModel( const wxString& aSpiceCode ) override; void ReadModel( const std::string& aSpiceCode ) override;
}; };

View File

@ -1,5 +1,4 @@
/* /* This program source code file is part of KiCad, a free EDA CAD application.
* This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2022 Mikolaj Wielgus * Copyright (C) 2022 Mikolaj Wielgus
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
@ -24,32 +23,33 @@
#include <sim/sim_model_switch.h> #include <sim/sim_model_switch.h>
#include <fmt/core.h>
wxString SPICE_GENERATOR_SWITCH::ItemLine( const wxString& aRefName,
const wxString& aModelName, std::string SPICE_GENERATOR_SWITCH::ItemLine( const std::string& aRefName,
const std::vector<wxString>& aSymbolPinNumbers, const std::string& aModelName,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
{ {
wxString result; std::string result;
switch( m_model.GetType() ) switch( m_model.GetType() )
{ {
case SIM_MODEL::TYPE::SW_V: case SIM_MODEL::TYPE::SW_V:
{ {
result << SPICE_GENERATOR::ItemLine( aRefName, aModelName, aSymbolPinNumbers, result = SPICE_GENERATOR::ItemLine( aRefName, aModelName, aSymbolPinNumbers, aPinNetNames );
aPinNetNames );
break; break;
} }
case SIM_MODEL::TYPE::SW_I: case SIM_MODEL::TYPE::SW_I:
{ {
wxString vsourceName = "V__" + aRefName; std::string vsourceName = "V__" + aRefName;
// Current switches measure input current through a voltage source. // Current switches measure input current through a voltage source.
result << vsourceName << " " << aPinNetNames[0] << " " << aPinNetNames[1] << " 0\n"; result.append( fmt::format( "{0} {1} 0\n", aPinNetNames[0], aPinNetNames[1] ) );
result.append( SPICE_GENERATOR::ItemLine( aRefName, fmt::format( "{0} {1}",
result << SPICE_GENERATOR::ItemLine( aRefName, vsourceName + " " + aModelName, vsourceName, aModelName ),
aSymbolPinNumbers, aPinNetNames ); aSymbolPinNumbers, aPinNetNames ) );
break; break;
} }
@ -62,19 +62,17 @@ wxString SPICE_GENERATOR_SWITCH::ItemLine( const wxString& aRefName,
} }
wxString SPICE_GENERATOR_SWITCH::ItemParams() const std::string SPICE_GENERATOR_SWITCH::ItemParams() const
{ {
wxString result; std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() ) for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
{ {
// The only instance param is "ic", which is positional. // The only instance param is "ic", which is positional.
wxString value = param.value->ToSpiceString(); std::string value = param.value->ToSpiceString();
if( value == "none" ) if( value != "none" )
result << ""; result.append( value );
else
result << value;
} }
return result; return result;
@ -125,7 +123,7 @@ SIM_MODEL_SWITCH::SIM_MODEL_SWITCH( TYPE aType ) :
} }
wxString SIM_MODEL_SWITCH::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const std::string SIM_MODEL_SWITCH::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const
{ {
if( aParam.info.name == "ic" && aParam.value->ToString() == "none" ) if( aParam.info.name == "ic" && aParam.value->ToString() == "none" )
{ {

View File

@ -34,10 +34,10 @@ class SPICE_GENERATOR_SWITCH : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ItemLine( const wxString& aRefName, const wxString& aModelName, std::string ItemLine( const std::string& aRefName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override; const std::vector<std::string>& aPinNetNames ) const override;
wxString ItemParams() const override; std::string ItemParams() const override;
std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const override; std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const override;
}; };
@ -48,10 +48,10 @@ public:
SIM_MODEL_SWITCH( TYPE aType ); SIM_MODEL_SWITCH( TYPE aType );
protected: protected:
wxString GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override; std::string GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override;
private: private:
std::vector<wxString> getPinNames() const override std::vector<std::string> getPinNames() const override
{ {
return { "ctrl+", "ctrl-", "no+", "no-" }; return { "ctrl+", "ctrl-", "no+", "no-" };
} }

View File

@ -23,14 +23,15 @@
*/ */
#include <sim/sim_model_tline.h> #include <sim/sim_model_tline.h>
#include <locale_io.h>
#include <fmt/core.h>
using PARAM = SIM_MODEL::PARAM; using PARAM = SIM_MODEL::PARAM;
wxString SPICE_GENERATOR_TLINE::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR_TLINE::ModelLine( const std::string& aModelName ) const
{ {
wxString r, l, g, c, len; std::string r, l, g, c, len;
switch( m_model.GetType() ) switch( m_model.GetType() )
{ {
@ -40,7 +41,7 @@ wxString SPICE_GENERATOR_TLINE::ModelLine( const wxString& aModelName ) const
auto td = static_cast<const SIM_VALUE_FLOAT&>( *m_model.FindParam( "td" )->value ); auto td = static_cast<const SIM_VALUE_FLOAT&>( *m_model.FindParam( "td" )->value );
if( !z0.HasValue() || !td.HasValue() ) if( !z0.HasValue() || !td.HasValue() )
return wxString::Format( ".model %s LTRA()\n", aModelName ); return fmt::format( ".model {} LTRA()\n", aModelName );
r = SIM_VALUE_FLOAT( 0 ).ToSpiceString(); r = SIM_VALUE_FLOAT( 0 ).ToSpiceString();
l = ( td * z0 ).ToSpiceString(); l = ( td * z0 ).ToSpiceString();
@ -63,8 +64,8 @@ wxString SPICE_GENERATOR_TLINE::ModelLine( const wxString& aModelName ) const
return ""; return "";
} }
return wxString::Format( ".model %s LTRA( r=%s l=%s g=%s c=%s len=%s )\n", return fmt::format( ".model {} LTRA( r={} l={} g={} c={} len={} )\n",
aModelName, r, l, g, c, len ); aModelName, r, l, g, c, len );
} }
@ -116,7 +117,7 @@ void SIM_MODEL_TLINE::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) cons
template <typename T> template <typename T>
void SIM_MODEL_TLINE::inferredWriteDataFields( std::vector<T>& aFields ) const void SIM_MODEL_TLINE::inferredWriteDataFields( std::vector<T>& aFields ) const
{ {
wxString value = GetFieldValue( &aFields, PARAMS_FIELD ); std::string value = GetFieldValue( &aFields, PARAMS_FIELD );
if( value == "" ) if( value == "" )
value = GetDeviceTypeInfo().fieldValue; value = GetDeviceTypeInfo().fieldValue;

View File

@ -34,7 +34,7 @@ class SPICE_GENERATOR_TLINE : public SPICE_GENERATOR
public: public:
using SPICE_GENERATOR::SPICE_GENERATOR; using SPICE_GENERATOR::SPICE_GENERATOR;
wxString ModelLine( const wxString& aModelName ) const override; std::string ModelLine( const std::string& aModelName ) const override;
}; };
@ -53,7 +53,7 @@ private:
template <typename T> template <typename T>
void inferredWriteDataFields( std::vector<T>& aFields ) const; void inferredWriteDataFields( std::vector<T>& aFields ) const;
std::vector<wxString> getPinNames() const override { return { "1+", "1-", "2+", "2-" }; } std::vector<std::string> getPinNames() const override { return { "1+", "1-", "2+", "2-" }; }
static std::vector<PARAM::INFO> makeZ0ParamInfos(); static std::vector<PARAM::INFO> makeZ0ParamInfos();
static std::vector<PARAM::INFO> makeRlgcParamInfos(); static std::vector<PARAM::INFO> makeRlgcParamInfos();

View File

@ -391,7 +391,7 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
} }
else else
{ {
m_model->SetParamValue( m_paramIndex, aText ); m_model->SetParamValue( m_paramIndex, std::string( aText.ToUTF8() ) );
aVariant = GetParam().value->ToString(); aVariant = GetParam().value->ToString();
} }
@ -399,6 +399,17 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
} }
static wxArrayString convertStringsToWx( const std::vector<std::string>& aStrings )
{
wxArrayString result;
for( const std::string& string : aStrings )
result.Add( string );
return result;
}
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName, SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
std::shared_ptr<SIM_LIBRARY> aLibrary, std::shared_ptr<SIM_LIBRARY> aLibrary,
std::shared_ptr<SIM_MODEL> aModel, std::shared_ptr<SIM_MODEL> aModel,
@ -406,8 +417,7 @@ SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aN
SIM_VALUE::TYPE aValueType, SIM_VALUE::TYPE aValueType,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) SIM_VALUE_GRAMMAR::NOTATION aNotation )
: wxEnumProperty( aLabel, aName, : wxEnumProperty( aLabel, aName,
wxArrayString( aModel->GetParam( aParamIndex ).info.enumValues.size(), convertStringsToWx( aModel->GetParam( aParamIndex ).info.enumValues ) ),
&aModel->GetParam( aParamIndex ).info.enumValues[0] ) ),
SIM_PROPERTY( aLibrary, aModel, aParamIndex ) SIM_PROPERTY( aLibrary, aModel, aParamIndex )
{ {
auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(), auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(),

View File

@ -69,7 +69,7 @@ private:
SIM_VALUE_GRAMMAR::NOTATION m_notation; SIM_VALUE_GRAMMAR::NOTATION m_notation;
wxString m_prevText; wxString m_prevText;
long m_prevInsertionPoint; long m_prevInsertionPoint;
wxDECLARE_EVENT_TABLE(); wxDECLARE_EVENT_TABLE();
}; };
@ -112,7 +112,7 @@ public:
int aParamIndex ); int aParamIndex );
wxValidator* DoGetValidator() const override; wxValidator* DoGetValidator() const override;
void OnSetValue() override; void OnSetValue() override;
}; };

View File

@ -23,61 +23,63 @@
*/ */
#include <sim/spice_generator.h> #include <sim/spice_generator.h>
#include <locale_io.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <fmt/core.h>
wxString SPICE_GENERATOR::ModelLine( const wxString& aModelName ) const std::string SPICE_GENERATOR::ModelLine( const std::string& aModelName ) const
{ {
LOCALE_IO toggle;
if( !m_model.HasSpiceNonInstanceOverrides() && !m_model.requiresSpiceModelLine() ) if( !m_model.HasSpiceNonInstanceOverrides() && !m_model.requiresSpiceModelLine() )
return ""; return "";
wxString result = ""; std::string result = "";
result << wxString::Format( ".model %s ", aModelName ); result.append( fmt::format( ".model {} ", aModelName ) );
size_t indentLength = result.Length(); size_t indentLength = result.length();
result << wxString::Format( "%s \n", m_model.GetSpiceInfo().modelType ); result.append( fmt::format( "{}\n", m_model.GetSpiceInfo().modelType ) );
for( const SIM_MODEL::PARAM& param : m_model.GetParams() ) for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
{ {
if( param.info.isSpiceInstanceParam ) if( param.info.isSpiceInstanceParam )
continue; continue;
wxString name = ( param.info.spiceModelName == "" ) ? std::string name = ( param.info.spiceModelName == "" ) ?
param.info.name : param.info.spiceModelName; param.info.name : param.info.spiceModelName;
wxString value = param.value->ToSpiceString(); std::string value = param.value->ToSpiceString();
if( value == "" ) if( value == "" )
continue; continue;
result << wxString::Format( "+%s%s=%s\n", wxString( ' ', indentLength - 1 ), name, value ); result.append( fmt::format( "+{}{}={}\n", std::string( indentLength - 1, ' ' ),
name, value ) );
} }
return result; return result;
} }
wxString SPICE_GENERATOR::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const wxString& aModelName ) const const std::string& aModelName ) const
{ {
// Use linear symbol pin numbers enumeration. Used in model preview. // Use linear symbol pin numbers enumeration. Used in model preview.
std::vector<wxString> pinNumbers; std::vector<std::string> pinNumbers;
for( int i = 0; i < m_model.GetPinCount(); ++i ) for( int i = 0; i < m_model.GetPinCount(); ++i )
pinNumbers.push_back( wxString::FromCDouble( i + 1 ) ); pinNumbers.push_back( fmt::format( "{}", i + 1 ) );
return ItemLine( aRefName, aModelName, pinNumbers ); return ItemLine( aRefName, aModelName, pinNumbers );
} }
wxString SPICE_GENERATOR::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers ) const const std::vector<std::string>& aSymbolPinNumbers ) const
{ {
std::vector<wxString> pinNetNames; std::vector<std::string> pinNetNames;
for( const SIM_MODEL::PIN& pin : GetPins() ) for( const SIM_MODEL::PIN& pin : GetPins() )
pinNetNames.push_back( pin.name ); pinNetNames.push_back( pin.name );
@ -86,36 +88,36 @@ wxString SPICE_GENERATOR::ItemLine( const wxString& aRefName,
} }
wxString SPICE_GENERATOR::ItemLine( const wxString& aRefName, std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
wxString result; std::string result;
result << ItemName( aRefName ); result.append( ItemName( aRefName ) );
result << ItemPins( aRefName, aModelName, aSymbolPinNumbers, aPinNetNames ); result.append( ItemPins( aRefName, aModelName, aSymbolPinNumbers, aPinNetNames ) );
result << ItemModelName( aModelName ); result.append( ItemModelName( aModelName ) );
result << ItemParams(); result.append( ItemParams() );
result << "\n"; result.append( "\n" );
return result; return result;
} }
wxString SPICE_GENERATOR::ItemName( const wxString& aRefName ) const std::string SPICE_GENERATOR::ItemName( const std::string& aRefName ) const
{ {
if( aRefName != "" && aRefName.StartsWith( m_model.GetSpiceInfo().itemType ) ) if( aRefName != "" && boost::starts_with( aRefName, m_model.GetSpiceInfo().itemType ) )
return aRefName; return aRefName;
else else
return m_model.GetSpiceInfo().itemType + aRefName; return m_model.GetSpiceInfo().itemType + aRefName;
} }
wxString SPICE_GENERATOR::ItemPins( const wxString& aRefName, std::string SPICE_GENERATOR::ItemPins( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const const std::vector<std::string>& aPinNetNames ) const
{ {
wxString result; std::string result;
int ncCounter = 0; int ncCounter = 0;
for( const SIM_MODEL::PIN& pin : GetPins() ) for( const SIM_MODEL::PIN& pin : GetPins() )
@ -124,14 +126,11 @@ wxString SPICE_GENERATOR::ItemPins( const wxString& aRefName,
pin.symbolPinNumber ); pin.symbolPinNumber );
if( it == aSymbolPinNumbers.end() ) if( it == aSymbolPinNumbers.end() )
{ result.append( fmt::format( " NC-{}-{}", aRefName, ncCounter++ ) );
LOCALE_IO toggle;
result << wxString::Format( " NC-%s-%u", aRefName, ncCounter++ );
}
else else
{ {
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it ); long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
result << " " << aPinNetNames.at( symbolPinIndex ); result.append( " " + aPinNetNames.at( symbolPinIndex ) );
} }
} }
@ -139,54 +138,53 @@ wxString SPICE_GENERATOR::ItemPins( const wxString& aRefName,
} }
wxString SPICE_GENERATOR::ItemModelName( const wxString& aModelName ) const std::string SPICE_GENERATOR::ItemModelName( const std::string& aModelName ) const
{ {
return " " + aModelName; return " " + aModelName;
} }
wxString SPICE_GENERATOR::ItemParams() const std::string SPICE_GENERATOR::ItemParams() const
{ {
wxString result; std::string result;
for( const SIM_MODEL::PARAM& param : GetInstanceParams() ) for( const SIM_MODEL::PARAM& param : GetInstanceParams() )
{ {
wxString name = ( param.info.spiceInstanceName == "" ) ? std::string name = ( param.info.spiceInstanceName == "" ) ?
param.info.name : param.info.spiceInstanceName; param.info.name : param.info.spiceInstanceName;
wxString value = param.value->ToSpiceString(); std::string value = param.value->ToSpiceString();
if( value != "" ) if( value != "" )
result << " " << name << "=" << value; result.append( fmt::format( " {}={}", name, value ) );
} }
return result; return result;
} }
wxString SPICE_GENERATOR::TuningLine( const wxString& aSymbol ) const std::string SPICE_GENERATOR::TuningLine( const std::string& aSymbol ) const
{ {
// TODO. // TODO.
return ""; return "";
} }
std::vector<wxString> SPICE_GENERATOR::CurrentNames( const wxString& aRefName ) const std::vector<std::string> SPICE_GENERATOR::CurrentNames( const std::string& aRefName ) const
{ {
LOCALE_IO toggle; return { fmt::format( "I({})", ItemName( aRefName ) ) };
return { wxString::Format( "I(%s)", ItemName( aRefName ) ) };
} }
wxString SPICE_GENERATOR::Preview( const wxString& aModelName ) const std::string SPICE_GENERATOR::Preview( const std::string& aModelName ) const
{ {
wxString spiceCode = ModelLine( aModelName ); std::string spiceCode = ModelLine( aModelName );
wxString itemLine = ItemLine( "", aModelName ); std::string itemLine = ItemLine( "", aModelName );
if( spiceCode != "" ) if( spiceCode != "" )
spiceCode << "\n"; spiceCode.append( "\n" );
spiceCode << itemLine; spiceCode.append( itemLine );
return spiceCode.Trim(); return boost::trim_copy( spiceCode );
} }

View File

@ -33,30 +33,30 @@ class SPICE_GENERATOR
public: public:
SPICE_GENERATOR( const SIM_MODEL& aModel ) : m_model( aModel ) {} SPICE_GENERATOR( const SIM_MODEL& aModel ) : m_model( aModel ) {}
virtual wxString ModelLine( const wxString& aModelName ) const; virtual std::string ModelLine( const std::string& aModelName ) const;
wxString ItemLine( const wxString& aRefName, std::string ItemLine( const std::string& aRefName,
const wxString& aModelName ) const; const std::string& aModelName ) const;
wxString ItemLine( const wxString& aRefName, std::string ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers ) const; const std::vector<std::string>& aSymbolPinNumbers ) const;
virtual wxString ItemLine( const wxString& aRefName, virtual std::string ItemLine( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const; const std::vector<std::string>& aPinNetNames ) const;
virtual wxString ItemName( const wxString& aRefName ) const; virtual std::string ItemName( const std::string& aRefName ) const;
virtual wxString ItemPins( const wxString& aRefName, virtual std::string ItemPins( const std::string& aRefName,
const wxString& aModelName, const std::string& aModelName,
const std::vector<wxString>& aSymbolPinNumbers, const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const; const std::vector<std::string>& aPinNetNames ) const;
virtual wxString ItemModelName( const wxString& aModelName ) const; virtual std::string ItemModelName( const std::string& aModelName ) const;
virtual wxString ItemParams() const; virtual std::string ItemParams() const;
virtual wxString TuningLine( const wxString& aSymbol ) const; virtual std::string TuningLine( const std::string& aSymbol ) const;
virtual std::vector<wxString> CurrentNames( const wxString& aRefName ) const;
virtual wxString Preview( const wxString& aModelName ) const; virtual std::vector<std::string> CurrentNames( const std::string& aRefName ) const;
virtual std::string Preview( const std::string& aModelName ) const;
protected: protected:
virtual std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const virtual std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const

View File

@ -26,6 +26,8 @@
#include <sim/spice_grammar.h> #include <sim/spice_grammar.h>
#include <sim/sim_model_spice.h> #include <sim/sim_model_spice.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <pegtl.hpp> #include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree.hpp>
@ -46,9 +48,9 @@ namespace SIM_MODEL_SPICE_PARSER
} }
SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const wxString& aSpiceCode ) SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const std::string& aSpiceCode )
{ {
tao::pegtl::string_input<> in( aSpiceCode.ToUTF8(), "Spice_Code" ); tao::pegtl::string_input<> in( aSpiceCode, "Spice_Code" );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -69,10 +71,10 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const wxString& aSpiceCode )
{ {
if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() ) if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() )
{ {
wxString paramName; std::string paramName;
wxString typeString; std::string typeString;
wxString level; std::string level;
wxString version; std::string version;
for( const auto& subnode : node->children ) for( const auto& subnode : node->children )
{ {
@ -128,12 +130,12 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const wxString& aSpiceCode )
} }
void SPICE_MODEL_PARSER::ReadModel( const wxString& aSpiceCode ) void SPICE_MODEL_PARSER::ReadModel( const std::string& aSpiceCode )
{ {
// The default behavior is to treat the Spice param=value pairs as the model parameters and // The default behavior is to treat the Spice param=value pairs as the model parameters and
// values (for many models the correspondence is not exact, so this function is overridden). // values (for many models the correspondence is not exact, so this function is overridden).
tao::pegtl::string_input<> in( aSpiceCode.ToUTF8(), "Spice_Code" ); tao::pegtl::string_input<> in( aSpiceCode, "Spice_Code" );
std::unique_ptr<tao::pegtl::parse_tree::node> root; std::unique_ptr<tao::pegtl::parse_tree::node> root;
try try
@ -153,7 +155,7 @@ void SPICE_MODEL_PARSER::ReadModel( const wxString& aSpiceCode )
{ {
if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() ) if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() )
{ {
wxString paramName = ""; std::string paramName = "";
for( const auto& subnode : node->children ) for( const auto& subnode : node->children )
{ {
@ -171,7 +173,7 @@ void SPICE_MODEL_PARSER::ReadModel( const wxString& aSpiceCode )
} }
else if( subnode->is_type<SIM_MODEL_SPICE_PARSER::paramValue>() ) else if( subnode->is_type<SIM_MODEL_SPICE_PARSER::paramValue>() )
{ {
wxASSERT( !paramName.IsEmpty() ); wxASSERT( paramName != "" );
if( !m_model.SetParamFromSpiceCode( paramName, subnode->string() ) ) if( !m_model.SetParamFromSpiceCode( paramName, subnode->string() ) )
{ {
@ -197,26 +199,25 @@ void SPICE_MODEL_PARSER::ReadModel( const wxString& aSpiceCode )
} }
SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const wxString& aTypeString, SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const std::string& aTypeString,
const wxString& aLevel, const std::string& aLevel,
const wxString& aVersion, const std::string& aVersion,
bool aSkipDefaultLevel ) bool aSkipDefaultLevel )
{ {
std::unique_ptr<SIM_VALUE> readLevel = SIM_VALUE::Create( SIM_VALUE::TYPE_INT, std::unique_ptr<SIM_VALUE> readLevel = SIM_VALUE::Create( SIM_VALUE::TYPE_INT, aLevel );
aLevel.ToStdString() );
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() ) for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
{ {
wxString typePrefix = SIM_MODEL::SpiceInfo( type ).modelType; std::string typePrefix = SIM_MODEL::SpiceInfo( type ).modelType;
wxString level = SIM_MODEL::SpiceInfo( type ).level; std::string level = SIM_MODEL::SpiceInfo( type ).level;
wxString version = SIM_MODEL::SpiceInfo( type ).version; std::string version = SIM_MODEL::SpiceInfo( type ).version;
bool isDefaultLevel = SIM_MODEL::SpiceInfo( type ).isDefaultLevel; bool isDefaultLevel = SIM_MODEL::SpiceInfo( type ).isDefaultLevel;
if( typePrefix == "" ) if( typePrefix == "" )
continue; continue;
// Check if `aTypeString` starts with `typePrefix`. // Check if `aTypeString` starts with `typePrefix`.
if( aTypeString.Upper().StartsWith( typePrefix ) if( boost::starts_with( boost::to_upper_copy( aTypeString ), typePrefix )
&& ( level == readLevel->ToString() && ( level == readLevel->ToString()
|| ( !aSkipDefaultLevel && isDefaultLevel && aLevel == "" ) ) || ( !aSkipDefaultLevel && isDefaultLevel && aLevel == "" ) )
&& version == aVersion ) && version == aVersion )

View File

@ -33,16 +33,16 @@ class SIM_MODEL_SPICE;
class SPICE_MODEL_PARSER class SPICE_MODEL_PARSER
{ {
public: public:
static SIM_MODEL::TYPE ReadType( const wxString& aSpiceCode ); static SIM_MODEL::TYPE ReadType( const std::string& aSpiceCode );
SPICE_MODEL_PARSER( SIM_MODEL_SPICE& aModel ) : m_model( aModel ) {} SPICE_MODEL_PARSER( SIM_MODEL_SPICE& aModel ) : m_model( aModel ) {}
virtual void ReadModel( const wxString& aSpiceCode ); virtual void ReadModel( const std::string& aSpiceCode );
protected: protected:
static SIM_MODEL::TYPE ReadTypeFromSpiceStrings( const wxString& aTypeString, static SIM_MODEL::TYPE ReadTypeFromSpiceStrings( const std::string& aTypeString,
const wxString& aLevel = "", const std::string& aLevel = "",
const wxString& aVersion = "", const std::string& aVersion = "",
bool aSkipDefaultLevel = true ); bool aSkipDefaultLevel = true );
SIM_MODEL_SPICE& m_model; SIM_MODEL_SPICE& m_model;

View File

@ -797,7 +797,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
try try
{ {
library = SIM_LIBRARY::Create( path ); library = SIM_LIBRARY::Create( std::string( path.ToUTF8() ) );
} }
catch( const IO_ERROR& e ) catch( const IO_ERROR& e )
{ {
@ -810,7 +810,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( !nameField ) if( !nameField )
return true; return true;
SIM_MODEL* baseModel = library->FindModel( nameField->GetShownText() ); SIM_MODEL* baseModel = library->FindModel( std::string( nameField->GetShownText().ToUTF8() ) );
if( !baseModel ) if( !baseModel )
return true; return true;
@ -823,8 +823,8 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
model = SIM_MODEL::Create( static_cast<int>( pins.size() ), model = SIM_MODEL::Create( static_cast<int>( pins.size() ),
symbol->GetFields() ); symbol->GetFields() );
wxString ref = symbol->GetRef( &m_frame->GetCurrentSheet() ); auto ref = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
std::vector<wxString> currentNames = model->SpiceGenerator().CurrentNames( ref ); std::vector<std::string> currentNames = model->SpiceGenerator().CurrentNames( ref );
if( currentNames.size() == 0 ) if( currentNames.size() == 0 )
return true; return true;
@ -834,7 +834,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
return true; return true;
} }
int modelPinIndex = model->FindModelPinIndex( pin->GetNumber() ); int modelPinIndex = model->FindModelPinIndex( std::string( pin->GetNumber().ToUTF8() ) );
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED ) if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
{ {
@ -846,7 +846,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
{ {
if( SCH_CONNECTION* conn = static_cast<SCH_ITEM*>( item )->Connection() ) if( SCH_CONNECTION* conn = static_cast<SCH_ITEM*>( item )->Connection() )
{ {
wxString spiceNet = UnescapeString( conn->Name() ); std::string spiceNet = std::string( UnescapeString( conn->Name() ).ToUTF8() );
NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( spiceNet ); NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( spiceNet );
simFrame->AddVoltagePlot( wxString::Format( "V(%s)", spiceNet ) ); simFrame->AddVoltagePlot( wxString::Format( "V(%s)", spiceNet ) );

View File

@ -25,11 +25,14 @@
#include <eeschema_test_utils.h> #include <eeschema_test_utils.h>
#include <sim/sim_library_spice.h> #include <sim/sim_library_spice.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <fmt/core.h>
class TEST_SIM_LIBRARY_SPICE_FIXTURE class TEST_SIM_LIBRARY_SPICE_FIXTURE
{ {
public: public:
wxString GetLibraryPath( const wxString& aBaseName ) std::string GetLibraryPath( const std::string& aBaseName )
{ {
wxFileName fn = KI_TEST::GetEeschemaTestDataDir(); wxFileName fn = KI_TEST::GetEeschemaTestDataDir();
fn.AppendDir( "spice_netlists" ); fn.AppendDir( "spice_netlists" );
@ -37,22 +40,23 @@ public:
fn.SetName( aBaseName ); fn.SetName( aBaseName );
fn.SetExt( "lib.spice" ); fn.SetExt( "lib.spice" );
return fn.GetFullPath(); return std::string( fn.GetFullPath().ToUTF8() );
} }
void LoadLibrary( const wxString& aBaseName ) void LoadLibrary( const std::string& aBaseName )
{ {
wxString path = GetLibraryPath( aBaseName ); std::string path = GetLibraryPath( aBaseName );
m_library = std::make_unique<SIM_LIBRARY_SPICE>(); m_library = std::make_unique<SIM_LIBRARY_SPICE>();
m_library->ReadFile( path ); m_library->ReadFile( path );
} }
void CompareToUsualDiodeModel( const SIM_MODEL& aModel, const wxString& aModelName, int aModelIndex ) void CompareToUsualDiodeModel( const SIM_MODEL& aModel, const std::string& aModelName, int aModelIndex )
{ {
BOOST_CHECK( aModel.GetType() == SIM_MODEL::TYPE::D ); BOOST_CHECK( aModel.GetType() == SIM_MODEL::TYPE::D );
BOOST_CHECK_EQUAL( aModelName, aModel.GetSpiceInfo().modelType.Upper() BOOST_CHECK_EQUAL( aModelName,
+ wxString::FromCDouble( aModelIndex ) fmt::format( "{}{}_Usual",
+ "_Usual" ); boost::to_upper_copy( aModel.GetSpiceInfo().modelType ),
aModelIndex ) );
BOOST_CHECK_EQUAL( aModel.FindParam( "bv" )->value->ToString(), "1.1u" ); BOOST_CHECK_EQUAL( aModel.FindParam( "bv" )->value->ToString(), "1.1u" );
BOOST_CHECK_EQUAL( aModel.FindParam( "cjo" )->value->ToString(), "2.2m" ); BOOST_CHECK_EQUAL( aModel.FindParam( "cjo" )->value->ToString(), "2.2m" );
BOOST_CHECK_EQUAL( aModel.FindParam( "ibv" )->value->ToString(), "3.3" ); BOOST_CHECK_EQUAL( aModel.FindParam( "ibv" )->value->ToString(), "3.3" );
@ -61,13 +65,14 @@ public:
BOOST_CHECK_EQUAL( aModel.FindParam( "n" )->value->ToString(), "6.6G" ); BOOST_CHECK_EQUAL( aModel.FindParam( "n" )->value->ToString(), "6.6G" );
} }
void CompareToEmptyModel( const SIM_MODEL& aModel, const wxString& aModelName, int aModelIndex ) void CompareToEmptyModel( const SIM_MODEL& aModel, const std::string& aModelName, int aModelIndex )
{ {
BOOST_TEST_CONTEXT( "Model index: " << aModelIndex ) BOOST_TEST_CONTEXT( "Model index: " << aModelIndex )
{ {
BOOST_CHECK_EQUAL( aModelName, aModel.GetSpiceInfo().modelType.Upper() BOOST_CHECK_EQUAL( aModelName,
+ wxString::FromCDouble( aModelIndex ) fmt::format( "{}{}_Empty",
+ "_Empty" ); boost::to_upper_copy( aModel.GetSpiceInfo().modelType ),
aModelIndex ) );
for( unsigned i = 0; i < aModel.GetParamCount(); ++i ) for( unsigned i = 0; i < aModel.GetParamCount(); ++i )
{ {
@ -79,8 +84,8 @@ public:
} }
} }
void TestTransistor( const SIM_MODEL& aModel, const wxString& aModelName, int aModelIndex, void TestTransistor( const SIM_MODEL& aModel, const std::string& aModelName, int aModelIndex,
SIM_MODEL::TYPE aType, const std::vector<wxString>& aParamNames ) SIM_MODEL::TYPE aType, const std::vector<std::string>& aParamNames )
{ {
BOOST_TEST_CONTEXT( "Model index: " << aModelIndex BOOST_TEST_CONTEXT( "Model index: " << aModelIndex
<< ", Model name: " << aModelName << ", Model name: " << aModelName
@ -88,25 +93,24 @@ public:
<< ", Model type: " << aModel.GetTypeInfo().fieldValue ) << ", Model type: " << aModel.GetTypeInfo().fieldValue )
{ {
BOOST_CHECK( aModel.GetType() == aType ); BOOST_CHECK( aModel.GetType() == aType );
BOOST_CHECK_EQUAL( aModelName, "_" + wxString::FromCDouble( aModelIndex ) BOOST_CHECK_EQUAL( aModelName,
+ "_" + aModel.GetSpiceInfo().modelType.Upper() fmt::format( "_{}_{}_{}",
+ "_" + aModel.GetTypeInfo().fieldValue ); aModelIndex,
boost::to_upper_copy( aModel.GetSpiceInfo().modelType ),
aModel.GetTypeInfo().fieldValue ) );
for( int i = 0; i < aParamNames.size(); ++i ) for( int i = 0; i < aParamNames.size(); ++i )
{ {
wxString paramName = aParamNames.at( i ); std::string paramName = aParamNames.at( i );
BOOST_TEST_CONTEXT( "Param name: " << paramName ) BOOST_TEST_CONTEXT( "Param name: " << paramName )
{ {
if( i == 0 ) if( i == 0 )
{
BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value->ToString(), "0" ); BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value->ToString(), "0" );
}
else else
{ {
BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value->ToString(), BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value->ToString(),
wxString::FromCDouble( i ) + ".0000" fmt::format( "{}.0000{}G", i, i ) );
+ wxString::FromCDouble( i ) + "G" );
} }
} }
} }
@ -125,14 +129,14 @@ BOOST_AUTO_TEST_CASE( Diodes )
LoadLibrary( "diodes" ); LoadLibrary( "diodes" );
const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels(); const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels();
const std::vector<wxString>& modelNames = m_library->GetModelNames(); const std::vector<std::string>& modelNames = m_library->GetModelNames();
BOOST_CHECK_EQUAL( models.size(), 22 ); BOOST_CHECK_EQUAL( models.size(), 22 );
for( int i = 0; i < models.size(); ++i ) for( int i = 0; i < models.size(); ++i )
{ {
const SIM_MODEL& model = models.at( i ); const SIM_MODEL& model = models.at( i );
const wxString& modelName = modelNames.at( i ); const std::string& modelName = modelNames.at( i );
switch( i ) switch( i )
{ {
@ -230,14 +234,14 @@ BOOST_AUTO_TEST_CASE( Bjts )
LoadLibrary( "bjts" ); LoadLibrary( "bjts" );
const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels(); const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels();
const std::vector<wxString>& modelNames = m_library->GetModelNames(); const std::vector<std::string>& modelNames = m_library->GetModelNames();
BOOST_CHECK_EQUAL( models.size(), 6 ); BOOST_CHECK_EQUAL( models.size(), 6 );
for( int i = 0; i < models.size(); ++i ) for( int i = 0; i < models.size(); ++i )
{ {
const SIM_MODEL& model = models.at( i ); const SIM_MODEL& model = models.at( i );
const wxString& modelName = modelNames.at( i ); const std::string& modelName = modelNames.at( i );
switch( i ) switch( i )
{ {
@ -284,14 +288,14 @@ BOOST_AUTO_TEST_CASE( Fets )
LoadLibrary( "fets" ); LoadLibrary( "fets" );
const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels(); const std::vector<std::reference_wrapper<SIM_MODEL>> models = m_library->GetModels();
const std::vector<wxString>& modelNames = m_library->GetModelNames(); const std::vector<std::string>& modelNames = m_library->GetModelNames();
BOOST_CHECK_EQUAL( models.size(), 44 ); BOOST_CHECK_EQUAL( models.size(), 44 );
for( int i = 0; i < models.size(); ++i ) for( int i = 0; i < models.size(); ++i )
{ {
const SIM_MODEL& model = models.at( i ); const SIM_MODEL& model = models.at( i );
const wxString& modelName = modelNames.at( i ); const std::string& modelName = modelNames.at( i );
switch( i ) switch( i )
{ {

View File

@ -120,7 +120,7 @@ public:
//ngspice->Init(); //ngspice->Init();
ngspice->Command( "set ngbehavior=ps" ); ngspice->Command( "set ngbehavior=ps" );
ngspice->Command( "setseed 1" ); ngspice->Command( "setseed 1" );
BOOST_REQUIRE( ngspice->LoadNetlist( netlist.ToStdString() ) ); BOOST_REQUIRE( ngspice->LoadNetlist( std::string( netlist.ToUTF8() ) ) );
BOOST_REQUIRE( ngspice->Run() ); BOOST_REQUIRE( ngspice->Run() );
// Test if ngspice cannot run a simulation (missing code models). // Test if ngspice cannot run a simulation (missing code models).