25#include <netlist_lexer.h>   
   48        for( 
unsigned i = 0;  i < 
m_netlist->GetCount();  i++ )
 
   56    NETLIST_LEXER( aReader )
 
   58    m_lineReader = aReader;
 
   68    while( ( 
token = NextTok() ) != T_EOF )
 
   73        if( 
token == T_RIGHT )
 
   88    while( ( 
token = NextTok() ) != T_EOF )
 
  107            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"Parse: entering components section" ) );
 
  108            while( ( 
token = NextTok() ) != T_EOF )
 
  110                if( 
token == T_RIGHT )
 
  112                else if( 
token == T_LEFT )
 
  115                if( 
token == T_comp )       
 
  122            while( ( 
token = NextTok() ) != T_EOF )
 
  124                if( 
token == T_RIGHT )
 
  126                else if( 
token == T_LEFT )
 
  129                if( 
token == T_group )       
 
  136            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"Parse: entering nets section" ) );
 
  137            while( ( 
token = NextTok() ) != T_EOF )
 
  139                if( 
token == T_RIGHT )
 
  141                else if( 
token == T_LEFT )
 
  151            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"Parse: entering libparts section" ) );
 
  152            while( ( 
token = NextTok() ) != T_EOF )
 
  154                if( 
token == T_RIGHT )
 
  156                else if( 
token == T_LEFT )
 
  159                if( 
token == T_libpart )    
 
  191        wxFAIL_MSG( wxString::Format( wxT( 
"KICAD_NETLIST_PARSER::Parse(): bad parenthesis " 
  192                                           "count (count = %d" ),
 
  211    wxString   pin_function;
 
  215    while( (
token = NextTok() ) != T_EOF )
 
  217        if( 
token == T_RIGHT )
 
  219        else if( 
token == T_LEFT )
 
  225            NeedSYMBOLorNUMBER();
 
  231            NeedSYMBOLorNUMBER();
 
  238            pin_function.Clear();
 
  241            while( (
token = NextTok() ) != T_EOF )
 
  243                if( 
token == T_RIGHT )
 
  245                else if( 
token == T_LEFT )
 
  251                    NeedSYMBOLorNUMBER();
 
  257                    NeedSYMBOLorNUMBER();
 
  263                    NeedSYMBOLorNUMBER();
 
  269                    NeedSYMBOLorNUMBER();
 
  283                if( strtol( code.c_str(), 
nullptr, 10 ) >= 1 )
 
  286                        name = wxT(
"N-00000") + code;
 
  288                    component->AddNet( pin_number, 
name, pin_function, pin_type );
 
  324    wxString    humanSheetPath;
 
  327    std::vector<KIID>            uuids;
 
  328    std::map<wxString, wxString> properties;
 
  329    nlohmann::ordered_map<wxString, wxString> fields;
 
  330    std::unordered_set<wxString>              componentClasses;
 
  332    bool duplicatePinsAreJumpers = 
false;
 
  333    std::vector<std::set<wxString>> jumperPinGroups;
 
  335    std::vector<COMPONENT::UNIT_INFO> parsedUnits;
 
  338    while( (
token = NextTok() ) != T_RIGHT )
 
  340        if( 
token == T_LEFT )
 
  346            NeedSYMBOLorNUMBER();
 
  352            NeedSYMBOLorNUMBER();
 
  358            NeedSYMBOLorNUMBER();
 
  359            footprint = FromUTF8();
 
  365            while( ( 
token = NextTok() ) != T_RIGHT )
 
  367                if( 
token == T_LEFT )
 
  372                    NeedSYMBOLorNUMBER();
 
  376                else if( 
token == T_part )
 
  378                    NeedSYMBOLorNUMBER();
 
  382                else if( 
token == T_description )
 
  384                    NeedSYMBOLorNUMBER();
 
  389                    Expecting( 
"part, lib or description" );
 
  392            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"parseComponent: ref='%s' libsource='%s:%s'" ),
 
  401            while( (
token = NextTok() ) != T_RIGHT )
 
  403                if( 
token == T_LEFT )
 
  406                if( 
token == T_name )
 
  408                    NeedSYMBOLorNUMBER();
 
  412                else if( 
token == T_value )
 
  414                    NeedSYMBOLorNUMBER();
 
  420                    Expecting( 
"name or value" );
 
  424            if( !propName.IsEmpty() )
 
  425                properties[propName] = std::move( propValue );
 
  430            while( ( 
token = NextTok() ) != T_RIGHT )
 
  432                if( 
token == T_LEFT )
 
  435                if( 
token == T_field )
 
  440                    while( ( 
token = NextTok() ) != T_RIGHT )
 
  442                        if( 
token == T_LEFT )
 
  445                        if( 
token == T_name )
 
  447                            NeedSYMBOLorNUMBER();
 
  451                        else if( 
token == T_STRING )
 
  457                    if( !fieldName.IsEmpty() )
 
  458                        fields[fieldName] = std::move( fieldValue );
 
  462                    Expecting( 
"field" );
 
  468            while( ( 
token = NextTok() ) != T_EOF )
 
  470                if( 
token == T_names )
 
  472                    NeedSYMBOLorNUMBER();
 
  477                if( 
token == T_tstamps )
 
  479                    NeedSYMBOLorNUMBER();
 
  491            while( ( 
token = NextTok() ) != T_EOF )
 
  493                if( 
token == T_RIGHT )
 
  496                uuids.emplace_back( 
From_UTF8( CurText() ) );
 
  505            while( ( 
token = NextTok() ) != T_RIGHT )
 
  507                if( 
token == T_LEFT )
 
  510                if( 
token == T_unit )
 
  512                    COMPONENT::UNIT_INFO 
info;
 
  514                    while( ( 
token = NextTok() ) != T_RIGHT )
 
  516                        if( 
token == T_LEFT )
 
  522                            NeedSYMBOLorNUMBER();
 
  528                            while( ( 
token = NextTok() ) != T_RIGHT )
 
  530                                if( 
token == T_LEFT )
 
  540                                        if( 
token == T_LEFT )
 
  545                                            NeedSYMBOLorNUMBER();
 
  556                                    if( !pinNum.IsEmpty() )
 
  557                                        info.m_pins.emplace_back( pinNum );
 
  572                    parsedUnits.push_back( 
info );
 
  582        case T_component_classes:
 
  583            while( ( 
token = NextTok() ) != T_RIGHT )
 
  585                if( 
token != T_LEFT )
 
  588                if( ( 
token = NextTok() ) != T_class )
 
  589                    Expecting( T_class );
 
  591                NeedSYMBOLorNUMBER();
 
  592                componentClasses.insert( 
From_UTF8( CurText() ) );
 
  598        case T_duplicate_pin_numbers_are_jumpers:
 
  600            NeedSYMBOLorNUMBER();
 
  601            duplicatePinsAreJumpers = 
From_UTF8( CurText() ) == wxT( 
"1" );
 
  606        case T_jumper_pin_groups:
 
  608            std::set<wxString>* currentGroup = 
nullptr;
 
  610            for( 
token = NextTok(); currentGroup || 
token != T_RIGHT; 
token = NextTok() )
 
  612                if( 
token == T_LEFT )
 
  618                    currentGroup = &jumperPinGroups.emplace_back();
 
  623                    NeedSYMBOLorNUMBER();
 
  624                    wxString padName = 
From_UTF8( CurText() );
 
  626                    wxCHECK2( currentGroup, 
continue );
 
  627                    currentGroup->insert( padName );
 
  632                    currentGroup = 
nullptr;
 
  636                    Expecting( 
"group or pin" );
 
  650    if( !footprint.IsEmpty() && fpid.
Parse( footprint, 
true ) >= 0 )
 
  653        error.Printf( 
_( 
"Invalid footprint ID in\nfile: '%s'\nline: %d\nofff: %d" ),
 
  654                      CurSource(), CurLineNumber(), CurOffset() );
 
  667    std::ranges::copy( jumperPinGroups, std::inserter( component->
JumperPadGroups(),
 
  686    std::vector<KIID> members;
 
  689    while( (
token = NextTok() ) != T_EOF )
 
  691        if( 
token == T_RIGHT )
 
  693        else if( 
token == T_LEFT )
 
  699            NeedSYMBOLorNUMBER();
 
  705            NeedSYMBOLorNUMBER();
 
  711            NeedSYMBOLorNUMBER();
 
  717            while( ( 
token = NextTok() ) != T_RIGHT )
 
  719                if( 
token == T_LEFT )
 
  722                if( 
token == T_member )
 
  726                    while( ( 
token = NextTok() ) != T_RIGHT )
 
  728                        if( 
token == T_LEFT )
 
  731                        if( 
token == T_uuid )
 
  733                            NeedSYMBOLorNUMBER();
 
  743                    members.emplace_back( memberUuid );
 
  747                    Expecting( 
"member" );
 
  761    if( !libId.IsEmpty() && groupLibId.
Parse( libId, 
true ) >= 0 )
 
  764        error.Printf( 
_( 
"Invalid lib_id ID in\nfile: '%s'\nline: %d\nofff: %d" ), CurSource(), CurLineNumber(),
 
  770    NETLIST_GROUP* 
group = 
new NETLIST_GROUP{ std::move( 
name ), std::move( uuid ), std::move( groupLibId ),
 
  771                                              std::move( members ) };
 
  800    wxString          libPartName;
 
  801    wxArrayString     footprintFilters;
 
  802    wxArrayString     aliases;
 
  806    wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"parseLibPartList: begin libpart" ) );
 
  807    while( (
token = NextTok() ) != T_RIGHT )
 
  809        if( 
token == T_LEFT )
 
  815            NeedSYMBOLorNUMBER();
 
  821            NeedSYMBOLorNUMBER();
 
  828            while( (
token = NextTok() ) != T_RIGHT )
 
  830                if( 
token == T_LEFT )
 
  839                if( 
token == T_RIGHT )
 
  843                   Expecting( 
"footprint ID" );
 
  845                footprintFilters.Add( 
From_UTF8( CurText() ) );
 
  851            while( (
token = NextTok() ) != T_RIGHT )
 
  853                if( 
token == T_LEFT )
 
  856                if( 
token != T_alias )
 
  857                    Expecting( T_alias );
 
  859                NeedSYMBOLorNUMBER();
 
  866            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"parseLibPartList: entering pins for '%s:%s'" ),
 
  867                        libName, libPartName );
 
  868            while( (
token = NextTok() ) != T_RIGHT )
 
  870                if( 
token == T_LEFT )
 
  877                wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"parseLibPartList: pin #%d for '%s:%s'" ),
 
  878                            pinCount, libName, libPartName );
 
  882            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"Parsed libpart '%s:%s' pins => pinCount=%d" ),
 
  883                        libName, libPartName, pinCount );
 
  894    wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"parseLibPartList: assigning pinCount=%d for libpart '%s:%s'" ),
 
  895                pinCount, libName, libPartName );
 
  896    for( 
unsigned i = 0;  i < 
m_netlist->GetCount();  i++ )
 
  898        component = 
m_netlist->GetComponent( i );
 
  900        if( component->
IsLibSource( libName, libPartName ) )
 
  904            wxLogTrace( 
"CVPCB_PINCOUNT", wxT( 
"Assign pinCount=%d to component ref='%s' part='%s:%s'" ),
 
  905                        pinCount, component->
GetReference(), libName, libPartName );
 
  908        for( 
unsigned jj = 0; jj < aliases.GetCount(); jj++ )
 
  910            if( component->
IsLibSource( libName, aliases[jj] ) )
 
  914                wxLogTrace( 
"CVPCB_PINCOUNT",
 
  915                            wxT( 
"Assign pinCount=%d to component ref='%s' via alias='%s:%s'" ),
 
  916                            pinCount, component->
GetReference(), libName, aliases[jj] );
 
void SetLibrary(const wxString &aLibrary)
 
const wxString & GetReference() const
 
void SetProperties(std::map< wxString, wxString > aProps)
 
void SetPinCount(int aPinCount)
 
void SetUnitInfo(const std::vector< UNIT_INFO > &aUnits)
 
bool IsLibSource(const wxString &aLibrary, const wxString &aName) const
 
void SetFootprintFilters(const wxArrayString &aFilters)
 
void SetFields(nlohmann::ordered_map< wxString, wxString > aFields)
 
void SetHumanReadablePath(const wxString &aPath)
 
void SetDuplicatePadNumbersAreJumpers(bool aEnabled)
 
void SetComponentClassNames(const std::unordered_set< wxString > &aClassNames)
 
std::vector< std::set< wxString > > & JumperPadGroups()
 
void SetName(const wxString &aName)
 
KICAD_NETLIST_PARSER(LINE_READER *aReader, NETLIST *aNetlist)
 
void parseComponent()
Parse a component description: (comp (ref P1) (value DB25FEMELLE) (footprint DB25FC) (libsource (lib ...
 
void Parse()
Function Parse parse the full netlist.
 
void parseNet()
Parse a net section (net (code 20) (name /PC-A0) (node (ref BUS1) (pin 62)) (node (ref U3) (pin 3)) (...
 
void parseLibPartList()
Read the section "libparts" in the netlist: (libparts (libpart (lib device) (part C) (description "Co...
 
void parseGroup()
Parse a group section (group (name "GroupName") (member (uuid "..."))))
 
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
 
NETLIST * m_netlist
The netlist to parse into. Not owned.
 
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
 
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
 
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
 
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.
 
LINE_READER * m_lineReader
The line reader of the netlist.
 
NETLIST * m_netlist
The net list to read the file(s) into.
 
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
 
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
 
static bool IsNumber(char x)
 
wxString From_UTF8(const char *cstring)