25#include <netlist_lexer.h>
48 for(
unsigned i = 0; i <
m_netlist->GetCount(); i++ )
56 NETLIST_LEXER( 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;
336 while( (
token = NextTok() ) != T_RIGHT )
338 if(
token == T_LEFT )
344 NeedSYMBOLorNUMBER();
350 NeedSYMBOLorNUMBER();
356 NeedSYMBOLorNUMBER();
357 footprint = FromUTF8();
363 while( (
token = NextTok() ) != T_RIGHT )
365 if(
token == T_LEFT )
370 NeedSYMBOLorNUMBER();
374 else if(
token == T_part )
376 NeedSYMBOLorNUMBER();
380 else if(
token == T_description )
382 NeedSYMBOLorNUMBER();
387 Expecting(
"part, lib or description" );
390 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseComponent: ref='%s' libsource='%s:%s'" ),
399 while( (
token = NextTok() ) != T_RIGHT )
401 if(
token == T_LEFT )
404 if(
token == T_name )
406 NeedSYMBOLorNUMBER();
410 else if(
token == T_value )
412 NeedSYMBOLorNUMBER();
418 Expecting(
"name or value" );
422 if( !propName.IsEmpty() )
423 properties[propName] = std::move( propValue );
428 while( (
token = NextTok() ) != T_RIGHT )
430 if(
token == T_LEFT )
433 if(
token == T_field )
438 while( (
token = NextTok() ) != T_RIGHT )
440 if(
token == T_LEFT )
443 if(
token == T_name )
445 NeedSYMBOLorNUMBER();
449 else if(
token == T_STRING )
455 if( !fieldName.IsEmpty() )
456 fields[fieldName] = std::move( fieldValue );
460 Expecting(
"field" );
466 while( (
token = NextTok() ) != T_EOF )
468 if(
token == T_names )
470 NeedSYMBOLorNUMBER();
475 if(
token == T_tstamps )
477 NeedSYMBOLorNUMBER();
489 while( (
token = NextTok() ) != T_EOF )
491 if(
token == T_RIGHT )
494 uuids.emplace_back(
From_UTF8( CurText() ) );
499 case T_component_classes:
500 while( (
token = NextTok() ) != T_RIGHT )
502 if(
token != T_LEFT )
505 if( (
token = NextTok() ) != T_class )
506 Expecting( T_class );
508 NeedSYMBOLorNUMBER();
509 componentClasses.insert(
From_UTF8( CurText() ) );
515 case T_duplicate_pin_numbers_are_jumpers:
517 NeedSYMBOLorNUMBER();
518 duplicatePinsAreJumpers =
From_UTF8( CurText() ) == wxT(
"1" );
523 case T_jumper_pin_groups:
525 std::set<wxString>* currentGroup =
nullptr;
527 for(
token = NextTok(); currentGroup ||
token != T_RIGHT;
token = NextTok() )
529 if(
token == T_LEFT )
535 currentGroup = &jumperPinGroups.emplace_back();
540 NeedSYMBOLorNUMBER();
541 wxString padName =
From_UTF8( CurText() );
543 wxCHECK2( currentGroup,
continue );
544 currentGroup->insert( padName );
549 currentGroup =
nullptr;
553 Expecting(
"group or pin" );
567 if( !footprint.IsEmpty() && fpid.
Parse( footprint,
true ) >= 0 )
570 error.Printf(
_(
"Invalid footprint ID in\nfile: '%s'\nline: %d\nofff: %d" ),
571 CurSource(), CurLineNumber(), CurOffset() );
584 std::ranges::copy( jumperPinGroups, std::inserter( component->
JumperPadGroups(),
602 std::vector<KIID> members;
605 while( (
token = NextTok() ) != T_EOF )
607 if(
token == T_RIGHT )
609 else if(
token == T_LEFT )
615 NeedSYMBOLorNUMBER();
621 NeedSYMBOLorNUMBER();
627 NeedSYMBOLorNUMBER();
633 while( (
token = NextTok() ) != T_RIGHT )
635 if(
token == T_LEFT )
638 if(
token == T_member )
642 while( (
token = NextTok() ) != T_RIGHT )
644 if(
token == T_LEFT )
647 if(
token == T_uuid )
649 NeedSYMBOLorNUMBER();
659 members.emplace_back( memberUuid );
663 Expecting(
"member" );
677 if( !libId.IsEmpty() && groupLibId.
Parse( libId,
true ) >= 0 )
680 error.Printf(
_(
"Invalid lib_id ID in\nfile: '%s'\nline: %d\nofff: %d" ), CurSource(), CurLineNumber(),
687 std::move( members ) };
716 wxString libPartName;
717 wxArrayString footprintFilters;
718 wxArrayString aliases;
722 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: begin libpart" ) );
723 while( (
token = NextTok() ) != T_RIGHT )
725 if(
token == T_LEFT )
731 NeedSYMBOLorNUMBER();
737 NeedSYMBOLorNUMBER();
744 while( (
token = NextTok() ) != T_RIGHT )
746 if(
token == T_LEFT )
755 if(
token == T_RIGHT )
759 Expecting(
"footprint ID" );
761 footprintFilters.Add(
From_UTF8( CurText() ) );
767 while( (
token = NextTok() ) != T_RIGHT )
769 if(
token == T_LEFT )
772 if(
token != T_alias )
773 Expecting( T_alias );
775 NeedSYMBOLorNUMBER();
782 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: entering pins for '%s:%s'" ),
783 libName, libPartName );
784 while( (
token = NextTok() ) != T_RIGHT )
786 if(
token == T_LEFT )
793 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: pin #%d for '%s:%s'" ),
794 pinCount, libName, libPartName );
798 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Parsed libpart '%s:%s' pins => pinCount=%d" ),
799 libName, libPartName, pinCount );
810 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: assigning pinCount=%d for libpart '%s:%s'" ),
811 pinCount, libName, libPartName );
812 for(
unsigned i = 0; i <
m_netlist->GetCount(); i++ )
814 component =
m_netlist->GetComponent( i );
816 if( component->
IsLibSource( libName, libPartName ) )
820 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Assign pinCount=%d to component ref='%s' part='%s:%s'" ),
821 pinCount, component->
GetReference(), libName, libPartName );
824 for(
unsigned jj = 0; jj < aliases.GetCount(); jj++ )
826 if( component->
IsLibSource( libName, aliases[jj] ) )
830 wxLogTrace(
"CVPCB_PINCOUNT",
831 wxT(
"Assign pinCount=%d to component ref='%s' via alias='%s:%s'" ),
832 pinCount, component->
GetReference(), libName, aliases[jj] );
Store all of the related footprint information found in a netlist.
void SetLibrary(const wxString &aLibrary)
const wxString & GetReference() const
void SetProperties(std::map< wxString, wxString > aProps)
void SetPinCount(int aPinCount)
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)
The parser for reading the KiCad s-expression netlist format.
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)) (...
NETLIST * m_netlist
The netlist to parse into. Not owned.
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 "..."))))
LINE_READER * m_lineReader
The line reader used to parse the netlist. Not owned.
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
A logical library item identifier and consists of various portions much like a URI.
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...
NETLIST * m_netlist
The net list to read the file(s) into.
LINE_READER * m_lineReader
The line reader of the netlist.
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.
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)