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)