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" ) );
109 while( (
token = NextTok() ) != T_EOF )
111 if(
token == T_RIGHT )
113 else if(
token == T_LEFT )
116 if(
token == T_comp )
123 while( (
token = NextTok() ) != T_EOF )
125 if(
token == T_RIGHT )
127 else if(
token == T_LEFT )
130 if(
token == T_group )
137 while( (
token = NextTok() ) != T_EOF )
139 if(
token == T_RIGHT )
141 else if(
token == T_LEFT )
144 if(
token == T_variant )
151 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Parse: entering nets section" ) );
153 while( (
token = NextTok() ) != T_EOF )
155 if(
token == T_RIGHT )
157 else if(
token == T_LEFT )
167 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Parse: entering libparts section" ) );
169 while( (
token = NextTok() ) != T_EOF )
171 if(
token == T_RIGHT )
173 else if(
token == T_LEFT )
176 if(
token == T_libpart )
208 wxFAIL_MSG( wxString::Format( wxT(
"KICAD_NETLIST_PARSER::Parse(): bad parenthesis "
209 "count (count = %d" ),
228 wxString pin_function;
232 while( (
token = NextTok() ) != T_EOF )
234 if(
token == T_RIGHT )
236 else if(
token == T_LEFT )
242 NeedSYMBOLorNUMBER();
248 NeedSYMBOLorNUMBER();
255 pin_function.Clear();
258 while( (
token = NextTok() ) != T_EOF )
260 if(
token == T_RIGHT )
262 else if(
token == T_LEFT )
268 NeedSYMBOLorNUMBER();
274 NeedSYMBOLorNUMBER();
280 NeedSYMBOLorNUMBER();
286 NeedSYMBOLorNUMBER();
300 if( strtol( code.c_str(),
nullptr, 10 ) >= 1 )
303 name = wxT(
"N-00000") + code;
305 component->AddNet( pin_number,
name, pin_function, pin_type );
341 wxString humanSheetPath;
344 std::vector<KIID> uuids;
345 std::map<wxString, wxString> properties;
346 nlohmann::ordered_map<wxString, wxString> fields;
347 std::unordered_set<wxString> componentClasses;
349 bool duplicatePinsAreJumpers =
false;
350 std::vector<std::set<wxString>> jumperPinGroups;
352 std::vector<COMPONENT::UNIT_INFO> parsedUnits;
353 std::vector<COMPONENT_VARIANT> parsedVariants;
356 while( (
token = NextTok() ) != T_RIGHT )
358 if(
token == T_LEFT )
364 NeedSYMBOLorNUMBER();
370 NeedSYMBOLorNUMBER();
376 NeedSYMBOLorNUMBER();
377 footprint = FromUTF8();
383 while( (
token = NextTok() ) != T_RIGHT )
385 if(
token == T_LEFT )
390 NeedSYMBOLorNUMBER();
394 else if(
token == T_part )
396 NeedSYMBOLorNUMBER();
400 else if(
token == T_description )
402 NeedSYMBOLorNUMBER();
407 Expecting(
"part, lib or description" );
410 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseComponent: ref='%s' libsource='%s:%s'" ),
419 while( (
token = NextTok() ) != T_RIGHT )
421 if(
token == T_LEFT )
424 if(
token == T_name )
426 NeedSYMBOLorNUMBER();
430 else if(
token == T_value )
432 NeedSYMBOLorNUMBER();
438 Expecting(
"name or value" );
442 if( !propName.IsEmpty() )
443 properties[propName] = std::move( propValue );
448 while( (
token = NextTok() ) != T_RIGHT )
450 if(
token == T_LEFT )
453 if(
token == T_field )
458 while( (
token = NextTok() ) != T_RIGHT )
460 if(
token == T_LEFT )
463 if(
token == T_name )
465 NeedSYMBOLorNUMBER();
469 else if(
token == T_STRING )
475 if( !fieldName.IsEmpty() )
476 fields[fieldName] = std::move( fieldValue );
480 Expecting(
"field" );
486 while( (
token = NextTok() ) != T_EOF )
488 if(
token == T_names )
490 NeedSYMBOLorNUMBER();
495 if(
token == T_tstamps )
497 NeedSYMBOLorNUMBER();
509 while( (
token = NextTok() ) != T_EOF )
511 if(
token == T_RIGHT )
514 uuids.emplace_back(
From_UTF8( CurText() ) );
523 while( (
token = NextTok() ) != T_RIGHT )
525 if(
token == T_LEFT )
528 if(
token == T_unit )
530 COMPONENT::UNIT_INFO
info;
532 while( (
token = NextTok() ) != T_RIGHT )
534 if(
token == T_LEFT )
540 NeedSYMBOLorNUMBER();
546 while( (
token = NextTok() ) != T_RIGHT )
548 if(
token == T_LEFT )
558 if(
token == T_LEFT )
563 NeedSYMBOLorNUMBER();
574 if( !pinNum.IsEmpty() )
575 info.m_pins.emplace_back( pinNum );
590 parsedUnits.push_back(
info );
601 case T_component_classes:
602 while( (
token = NextTok() ) != T_RIGHT )
604 if(
token != T_LEFT )
607 if( (
token = NextTok() ) != T_class )
608 Expecting( T_class );
610 NeedSYMBOLorNUMBER();
611 componentClasses.insert(
From_UTF8( CurText() ) );
617 case T_duplicate_pin_numbers_are_jumpers:
619 NeedSYMBOLorNUMBER();
620 duplicatePinsAreJumpers =
From_UTF8( CurText() ) == wxT(
"1" );
625 case T_jumper_pin_groups:
627 std::set<wxString>* currentGroup =
nullptr;
629 for(
token = NextTok(); currentGroup ||
token != T_RIGHT;
token = NextTok() )
631 if(
token == T_LEFT )
637 currentGroup = &jumperPinGroups.emplace_back();
642 NeedSYMBOLorNUMBER();
643 wxString padName =
From_UTF8( CurText() );
645 wxCHECK2( currentGroup,
continue );
646 currentGroup->insert( padName );
651 currentGroup =
nullptr;
655 Expecting(
"group or pin" );
664 while( (
token = NextTok() ) != T_RIGHT )
666 if(
token == T_LEFT )
669 if(
token != T_variant )
675 COMPONENT_VARIANT variant;
679 if(
token == T_LEFT )
685 NeedSYMBOLorNUMBER();
694 bool hasValue =
false;
696 while( (
token = NextTok() ) != T_RIGHT )
698 if(
token == T_LEFT )
701 if(
token == T_name )
703 NeedSYMBOLorNUMBER();
707 else if(
token == T_value )
709 NeedSYMBOLorNUMBER();
716 Expecting(
"name or value" );
720 if( propName.IsEmpty() )
723 bool propBool =
true;
727 wxString normalized = propValue;
728 normalized.MakeLower();
730 if( normalized == wxT(
"0" ) || normalized == wxT(
"false" ) )
732 else if( normalized == wxT(
"1" ) || normalized == wxT(
"true" ) )
735 propBool = !propValue.IsEmpty();
738 if( propName.CmpNoCase( wxT(
"dnp" ) ) == 0 )
740 variant.
m_dnp = propBool;
743 else if( propName.CmpNoCase( wxT(
"exclude_from_bom" ) ) == 0 )
748 else if( propName.CmpNoCase( wxT(
"exclude_from_sim" ) ) == 0 )
753 else if( propName.CmpNoCase( wxT(
"exclude_from_pos_files" ) ) == 0 )
763 while( (
token = NextTok() ) != T_RIGHT )
765 if(
token == T_LEFT )
768 if(
token == T_field )
773 while( (
token = NextTok() ) != T_RIGHT )
775 if(
token == T_LEFT )
778 if(
token == T_name )
780 NeedSYMBOLorNUMBER();
784 else if(
token == T_value )
786 NeedSYMBOLorNUMBER();
790 else if(
token == T_STRING )
796 if( !fieldName.IsEmpty() )
797 variant.
m_fields[fieldName] = std::move( fieldValue );
801 Expecting(
"field" );
812 if( !variant.
m_name.IsEmpty() )
813 parsedVariants.push_back( std::move( variant ) );
826 if( !footprint.IsEmpty() && fpid.
Parse( footprint,
true ) >= 0 )
829 error.Printf(
_(
"Invalid footprint ID in\nfile: '%s'\nline: %d\nofff: %d" ),
830 CurSource(), CurLineNumber(), CurOffset() );
843 std::ranges::copy( jumperPinGroups, std::inserter( component->
JumperPadGroups(),
847 for(
const COMPONENT_VARIANT& variant : parsedVariants )
866 std::vector<KIID> members;
869 while( (
token = NextTok() ) != T_EOF )
871 if(
token == T_RIGHT )
873 else if(
token == T_LEFT )
879 NeedSYMBOLorNUMBER();
885 NeedSYMBOLorNUMBER();
891 NeedSYMBOLorNUMBER();
897 while( (
token = NextTok() ) != T_RIGHT )
899 if(
token == T_LEFT )
902 if(
token == T_member )
906 while( (
token = NextTok() ) != T_RIGHT )
908 if(
token == T_LEFT )
911 if(
token == T_uuid )
913 NeedSYMBOLorNUMBER();
923 members.emplace_back( memberUuid );
927 Expecting(
"member" );
941 if( !libId.IsEmpty() && groupLibId.
Parse( libId,
true ) >= 0 )
944 error.Printf(
_(
"Invalid lib_id ID in\nfile: '%s'\nline: %d\nofff: %d" ), CurSource(), CurLineNumber(),
950 NETLIST_GROUP*
group =
new NETLIST_GROUP{ std::move(
name ), std::move( uuid ), std::move( groupLibId ),
951 std::move( members ) };
962 wxString description;
966 if(
token == T_LEFT )
972 NeedSYMBOLorNUMBER();
978 NeedSYMBOLorNUMBER();
989 if( !
name.IsEmpty() )
1018 wxString libPartName;
1019 wxArrayString footprintFilters;
1020 wxArrayString aliases;
1024 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: begin libpart" ) );
1025 while( (
token = NextTok() ) != T_RIGHT )
1027 if(
token == T_LEFT )
1033 NeedSYMBOLorNUMBER();
1039 NeedSYMBOLorNUMBER();
1046 while( (
token = NextTok() ) != T_RIGHT )
1048 if(
token == T_LEFT )
1057 if(
token == T_RIGHT )
1061 Expecting(
"footprint ID" );
1063 footprintFilters.Add(
From_UTF8( CurText() ) );
1069 while( (
token = NextTok() ) != T_RIGHT )
1071 if(
token == T_LEFT )
1074 if(
token != T_alias )
1075 Expecting( T_alias );
1077 NeedSYMBOLorNUMBER();
1084 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: entering pins for '%s:%s'" ),
1085 libName, libPartName );
1086 while( (
token = NextTok() ) != T_RIGHT )
1088 if(
token == T_LEFT )
1091 if(
token != T_pin )
1095 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: pin #%d for '%s:%s'" ),
1096 pinCount, libName, libPartName );
1100 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Parsed libpart '%s:%s' pins => pinCount=%d" ),
1101 libName, libPartName, pinCount );
1112 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"parseLibPartList: assigning pinCount=%d for libpart '%s:%s'" ),
1113 pinCount, libName, libPartName );
1114 for(
unsigned i = 0; i <
m_netlist->GetCount(); i++ )
1116 component =
m_netlist->GetComponent( i );
1118 if( component->
IsLibSource( libName, libPartName ) )
1122 wxLogTrace(
"CVPCB_PINCOUNT", wxT(
"Assign pinCount=%d to component ref='%s' part='%s:%s'" ),
1123 pinCount, component->
GetReference(), libName, libPartName );
1126 for(
unsigned jj = 0; jj < aliases.GetCount(); jj++ )
1128 if( component->
IsLibSource( libName, aliases[jj] ) )
1132 wxLogTrace(
"CVPCB_PINCOUNT",
1133 wxT(
"Assign pinCount=%d to component ref='%s' via alias='%s:%s'" ),
1134 pinCount, component->
GetReference(), libName, aliases[jj] );
Store all of the related component information found in a netlist.
void SetLibrary(const wxString &aLibrary)
const wxString & GetReference() const
void AddVariant(const COMPONENT_VARIANT &aVariant)
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 parseVariant()
Parse a variant section (variant (name "VariantName") (description "Description"))
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)
bool m_excludedFromPosFiles
bool m_hasExcludedFromBOM
bool m_hasExcludedFromSim
bool m_hasExcludedFromPosFiles
nlohmann::ordered_map< wxString, wxString > m_fields