Sim: Fix reading the legacy Spice_Node_Sequence field

This commit is contained in:
Mikolaj Wielgus 2022-08-11 02:42:16 +02:00
parent a1a99b1ec2
commit bd809bf31c
4 changed files with 81 additions and 30 deletions

View File

@ -1192,6 +1192,21 @@ SIM_MODEL::SIM_MODEL( TYPE aType ) : m_baseModel( nullptr ), m_type( aType ),
}
void SIM_MODEL::CreatePins( unsigned aSymbolPinCount )
{
// Default pin sequence: model pins are the same as symbol pins.
// Excess model pins are set as Not Connected.
// Note that intentionally nothing is added if `getPinNames()` returns an empty vector.
for( unsigned i = 0; i < getPinNames().size(); ++i )
{
if( i < aSymbolPinCount )
AddPin( { getPinNames().at( i ), i + 1 } );
else
AddPin( { getPinNames().at( i ), PIN::NOT_CONNECTED } );
}
}
template void SIM_MODEL::WriteInferredDataFields( std::vector<SCH_FIELD>& aFields,
const wxString& aValue ) const;
template void SIM_MODEL::WriteInferredDataFields( std::vector<LIB_FIELD>& aFields,
@ -1314,21 +1329,11 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
void SIM_MODEL::ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsField )
{
// Default pin sequence: model pins are the same as symbol pins.
// Excess model pins are set as Not Connected.
for( unsigned i = 0; i < getPinNames().size(); ++i )
{
if( i < aSymbolPinCount )
AddPin( { getPinNames().at( i ), i + 1 } );
else
AddPin( { getPinNames().at( i ), PIN::NOT_CONNECTED } );
}
CreatePins( aSymbolPinCount );
if( aPinsField == "" )
return;
LOCALE_IO toggle;
tao::pegtl::string_input<> in( aPinsField.ToUTF8(), PINS_FIELD );
std::unique_ptr<tao::pegtl::parse_tree::node> root;

View File

@ -46,8 +46,16 @@ namespace SIM_MODEL_GRAMMAR
struct sep : plus<space> {};
struct legacyPinNumber : digits {};
struct legacyPinSequence : seq<opt<legacyPinNumber>,
star<sep,
legacyPinNumber>> {};
struct legacyPinSequenceGrammar : must<legacyPinSequence, tao::pegtl::eof> {};
struct pinNumber : sor<digits, one<'X'>> {};
struct pinSequence : opt<pinNumber,
struct pinSequence : seq<opt<pinNumber>,
star<sep,
pinNumber>> {};
@ -70,6 +78,7 @@ namespace SIM_MODEL_GRAMMAR
struct fieldFloatValueGrammar : must<fieldFloatValue,
tao::pegtl::eof> {};
struct param : plus<alnum> {};
struct fieldParamValuePair : seq<param,
@ -545,6 +554,8 @@ public:
protected:
SIM_MODEL( TYPE aType );
virtual void CreatePins( unsigned aSymbolPinCount );
template <typename T>
void WriteInferredDataFields( std::vector<T>& aFields, const wxString& aValue ) const;

View File

@ -25,7 +25,15 @@
#include <sim/sim_model_spice.h>
#include <pegtl.hpp>
#include <pegtl/contrib/parse_tree.hpp>
#include <locale_io.h>
namespace SIM_MODEL_SPICE_PARSER
{
using namespace SIM_MODEL_GRAMMAR;
template <typename Rule> struct legacyPinSequenceSelector : std::false_type {};
template <> struct legacyPinSequenceSelector<legacyPinNumber> : std::true_type {};
}
SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType )
@ -38,25 +46,17 @@ SIM_MODEL_SPICE::SIM_MODEL_SPICE( TYPE aType )
}
void SIM_MODEL_SPICE::ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields )
void SIM_MODEL_SPICE::ReadDataSchFields( unsigned aSymbolPinCount,
const std::vector<SCH_FIELD>* aFields )
{
LOCALE_IO toggle;
for( unsigned i = 0; i < aSymbolPinCount; ++i )
AddPin( { wxString::Format( "%d", i + 1 ), i + 1 } );
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
readLegacyDataFields( aSymbolPinCount, aFields );
}
void SIM_MODEL_SPICE::ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields )
void SIM_MODEL_SPICE::ReadDataLibFields( unsigned aSymbolPinCount,
const std::vector<LIB_FIELD>* aFields )
{
LOCALE_IO toggle;
for( unsigned i = 0; i < aSymbolPinCount; ++i )
AddPin( { wxString::Format( "%d", i + 1 ), i + 1 } );
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
readLegacyDataFields( aSymbolPinCount, aFields );
}
@ -121,6 +121,13 @@ wxString SIM_MODEL_SPICE::GenerateSpiceItemLine( const wxString& aRefName,
}
void SIM_MODEL_SPICE::CreatePins( unsigned aSymbolPinCount )
{
for( unsigned i = 0; i < aSymbolPinCount; ++i )
AddPin( { "", PIN::NOT_CONNECTED } );
}
bool SIM_MODEL_SPICE::SetParamFromSpiceCode( const wxString& aParamName,
const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
@ -206,31 +213,55 @@ void SIM_MODEL_SPICE::readLegacyDataFields( unsigned aSymbolPinCount, const std:
{
// Fill in the blanks with the legacy parameters.
if( GetParam( static_cast<int>( SPICE_PARAM::TYPE ) ).value->ToString().IsEmpty() )
if( GetParam( static_cast<int>( SPICE_PARAM::TYPE ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::TYPE ),
GetFieldValue( aFields, LEGACY_TYPE_FIELD ) );
}
if( GetFieldValue( aFields, PINS_FIELD ) == "" )
ParsePinsField( aSymbolPinCount, GetFieldValue( aFields, LEGACY_PINS_FIELD ) );
parseLegacyPinsField( aSymbolPinCount, GetFieldValue( aFields, LEGACY_PINS_FIELD ) );
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString().IsEmpty() )
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::MODEL ),
GetFieldValue( aFields, LEGACY_MODEL_FIELD ) );
}
// If model param is still empty, then use Value field.
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString().IsEmpty() )
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::MODEL ),
GetFieldValue( aFields, SIM_MODEL::VALUE_FIELD ) );
}
if( GetParam( static_cast<int>( SPICE_PARAM::LIB ) ).value->ToString().IsEmpty() )
if( GetParam( static_cast<int>( SPICE_PARAM::LIB ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::LIB ),
GetFieldValue( aFields, LEGACY_LIB_FIELD ) );
}
}
void SIM_MODEL_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount, const wxString& aPinsField )
{
tao::pegtl::string_input<> in( aPinsField.ToUTF8(), PINS_FIELD );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
try
{
root = tao::pegtl::parse_tree::parse<SIM_MODEL_SPICE_PARSER::legacyPinSequenceGrammar,
SIM_MODEL_SPICE_PARSER::legacyPinSequenceSelector>
( in );
}
catch( const tao::pegtl::parse_error& e )
{
THROW_IO_ERROR( e.what() );
}
for( unsigned i = 0; i < root->children.size(); ++i )
{
SetPinSymbolPinNumber( std::stoi( root->children.at( i )->string() ) - 1,
static_cast<int>( i + 1 ) );
}
}

View File

@ -61,6 +61,8 @@ public:
const std::vector<wxString>& aPinNetNames ) const override;
protected:
void CreatePins( unsigned aSymbolPinCount ) override;
bool SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SPICE ) override;
@ -71,6 +73,8 @@ private:
template <typename T>
void readLegacyDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
void parseLegacyPinsField( unsigned aSymbolPinCount, const wxString& aPinsField );
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
};