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;
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 )
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(),
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] );
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)
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)
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)