KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/netlist_reader/kicad_netlist_reader.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 1992-2011 Jean-Pierre Charras.
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <netlist_lexer.h> // netlist_lexer is common to Eeschema and Pcbnew
26#include <string_utils.h>
27#include <json_common.h>
28
29#include "pcb_netlist.h"
30#include "netlist_reader.h"
32
33using namespace NL_T;
34
35
37{
38 KICAD_NETLIST_PARSER parser( m_lineReader, m_netlist );
39
40 parser.Parse();
41
43 {
45
46 // Sort the component pins so they are in the same order as the legacy format. This
47 // is useful for comparing legacy and s-expression netlist dumps.
48 for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
49 m_netlist->GetComponent( i )->SortPins();
50 }
51}
52
53
54// KICAD_NETLIST_PARSER
56 NETLIST_LEXER( aReader )
57{
58 m_lineReader = aReader;
59 m_netlist = aNetlist;
60 token = T_NONE;
61}
62
63
65{
66 int curr_level = 0;
67
68 while( ( token = NextTok() ) != T_EOF )
69 {
70 if( token == T_LEFT )
71 curr_level--;
72
73 if( token == T_RIGHT )
74 {
75 curr_level++;
76
77 if( curr_level > 0 )
78 return;
79 }
80 }
81}
82
83
85{
86 int plevel = 0; // the count of ')' to read at end of file after parsing all sections
87
88 while( ( token = NextTok() ) != T_EOF )
89 {
90 if( token == T_LEFT )
91 token = NextTok();
92
93 switch( token )
94 {
95 case T_export: // The netlist starts here.
96 // nothing to do here, just increment the count of ')' to read at end of file
97 plevel++;
98 break;
99
100 case T_version: // The netlist starts here.
101 // version id not yet used: read it but does not use it
102 NextTok();
103 NeedRIGHT();
104 break;
105
106 case T_components: // The section comp starts here.
107 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Parse: entering components section" ) );
108
109 while( ( token = NextTok() ) != T_EOF )
110 {
111 if( token == T_RIGHT )
112 break;
113 else if( token == T_LEFT )
114 token = NextTok();
115
116 if( token == T_comp ) // A component section found. Read it
118 }
119
120 break;
121
122 case T_groups: // The section groups starts here.
123 while( ( token = NextTok() ) != T_EOF )
124 {
125 if( token == T_RIGHT )
126 break;
127 else if( token == T_LEFT )
128 token = NextTok();
129
130 if( token == T_group ) // A group section found. Read it
131 parseGroup();
132 }
133
134 break;
135
136 case T_nets: // The section nets starts here.
137 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Parse: entering nets section" ) );
138
139 while( ( token = NextTok() ) != T_EOF )
140 {
141 if( token == T_RIGHT )
142 break;
143 else if( token == T_LEFT )
144 token = NextTok();
145
146 if( token == T_net ) // A net section if found. Read it
147 parseNet();
148 }
149
150 break;
151
152 case T_libparts: // The section libparts starts here.
153 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Parse: entering libparts section" ) );
154
155 while( ( token = NextTok() ) != T_EOF )
156 {
157 if( token == T_RIGHT )
158 break;
159 else if( token == T_LEFT )
160 token = NextTok();
161
162 if( token == T_libpart ) // A libpart section if found. Read it
164 }
165
166 break;
167
168 case T_libraries: // The section libraries starts here.
169 // List of libraries in use.
170 // Not used here, just skip it
171 skipCurrent();
172 break;
173
174 case T_design: // The section design starts here.
175 // Not used (mainly they are comments), just skip it
176 skipCurrent();
177 break;
178
179 case T_RIGHT: // The closing parenthesis of the file.
180 plevel--;
181 break;
182
183 default:
184 skipCurrent();
185 break;
186 }
187 }
188
189 // Go back and apply group information to the components
190 m_netlist->ApplyGroupMembership();
191
192 if( plevel != 0 )
193 {
194 wxFAIL_MSG( wxString::Format( wxT( "KICAD_NETLIST_PARSER::Parse(): bad parenthesis "
195 "count (count = %d" ),
196 plevel ) );
197 }
198}
199
200
202{
203 /* Parses a section like
204 * (net (code 20) (name /PC-A0)
205 * (node (ref "BUS1") (pin "62)")
206 * (node (ref "U3") ("pin 3") (pin_function "clock"))
207 * (node (ref "U9") (pin "M6") (pin_function "reset")))
208 */
209
210 wxString code;
211 wxString name;
212 wxString reference;
213 wxString pin_number;
214 wxString pin_function;
215 wxString pin_type;
216
217 // The token net was read, so the next data is (code <number>)
218 while( (token = NextTok() ) != T_EOF )
219 {
220 if( token == T_RIGHT )
221 break;
222 else if( token == T_LEFT )
223 token = NextTok();
224
225 switch( token )
226 {
227 case T_code:
228 NeedSYMBOLorNUMBER();
229 code = From_UTF8( CurText() );
230 NeedRIGHT();
231 break;
232
233 case T_name:
234 NeedSYMBOLorNUMBER();
235 name = From_UTF8( CurText() );
236 NeedRIGHT();
237 break;
238
239 case T_node:
240 // By default: no pin function or type.
241 pin_function.Clear();
242 pin_type.Clear();
243
244 while( (token = NextTok() ) != T_EOF )
245 {
246 if( token == T_RIGHT )
247 break;
248 else if( token == T_LEFT )
249 token = NextTok();
250
251 switch( token )
252 {
253 case T_ref:
254 NeedSYMBOLorNUMBER();
255 reference = From_UTF8( CurText() );
256 NeedRIGHT();
257 break;
258
259 case T_pin:
260 NeedSYMBOLorNUMBER();
261 pin_number = From_UTF8( CurText() );
262 NeedRIGHT();
263 break;
264
265 case T_pinfunction:
266 NeedSYMBOLorNUMBER();
267 pin_function = From_UTF8( CurText() );
268 NeedRIGHT();
269 break;
270
271 case T_pintype:
272 NeedSYMBOLorNUMBER();
273 pin_type = From_UTF8( CurText() );
274 NeedRIGHT();
275 break;
276
277 default:
278 skipCurrent();
279 break;
280 }
281 }
282
283 // Don't assume component will be found; it might be "DNP" or "Exclude from board".
284 if( COMPONENT* component = m_netlist->GetComponentByReference( reference ) )
285 {
286 if( strtol( code.c_str(), nullptr, 10 ) >= 1 )
287 {
288 if( name.IsEmpty() ) // Give a dummy net name like N-000009
289 name = wxT("N-00000") + code;
290
291 component->AddNet( pin_number, name, pin_function, pin_type );
292 }
293 }
294
295 break;
296
297 default:
298 skipCurrent();
299 break;
300 }
301 }
302}
303
304
306{
307 /* Parses a section like
308 * (comp (ref P1)
309 * (value DB25FEMALE)
310 * (footprint DB25FC)
311 * (libsource (lib conn) (part DB25))
312 * (property (name PINCOUNT) (value 25))
313 * (sheetpath (names /) (tstamps /))
314 * (component_classes (class (name "CLASS")))
315 * (tstamp 68183921-93a5-49ac-91b0-49d05a0e1647))
316 *
317 * other fields (unused) are skipped
318 * A component need a reference, value, footprint name and a full time stamp
319 * The full time stamp is the sheetpath time stamp + the component time stamp
320 */
321 LIB_ID fpid;
322 wxString footprint;
323 wxString ref;
324 wxString value;
325 wxString library;
326 wxString name;
327 wxString humanSheetPath;
328 KIID_PATH path;
329
330 std::vector<KIID> uuids;
331 std::map<wxString, wxString> properties;
332 nlohmann::ordered_map<wxString, wxString> fields;
333 std::unordered_set<wxString> componentClasses;
334
335 bool duplicatePinsAreJumpers = false;
336 std::vector<std::set<wxString>> jumperPinGroups;
337
338 std::vector<COMPONENT::UNIT_INFO> parsedUnits;
339
340 // The token comp was read, so the next data is (ref P1)
341 while( (token = NextTok() ) != T_RIGHT )
342 {
343 if( token == T_LEFT )
344 token = NextTok();
345
346 switch( token )
347 {
348 case T_ref:
349 NeedSYMBOLorNUMBER();
350 ref = From_UTF8( CurText() );
351 NeedRIGHT();
352 break;
353
354 case T_value:
355 NeedSYMBOLorNUMBER();
356 value = From_UTF8( CurText() );
357 NeedRIGHT();
358 break;
359
360 case T_footprint:
361 NeedSYMBOLorNUMBER();
362 footprint = FromUTF8();
363 NeedRIGHT();
364 break;
365
366 case T_libsource:
367 // Read libsource
368 while( ( token = NextTok() ) != T_RIGHT )
369 {
370 if( token == T_LEFT )
371 token = NextTok();
372
373 if( token == T_lib )
374 {
375 NeedSYMBOLorNUMBER();
376 library = From_UTF8( CurText() );
377 NeedRIGHT();
378 }
379 else if( token == T_part )
380 {
381 NeedSYMBOLorNUMBER();
382 name = From_UTF8( CurText() );
383 NeedRIGHT();
384 }
385 else if( token == T_description )
386 {
387 NeedSYMBOLorNUMBER();
388 NeedRIGHT();
389 }
390 else
391 {
392 Expecting( "part, lib or description" );
393 }
394 }
395 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseComponent: ref='%s' libsource='%s:%s'" ),
396 ref, library, name );
397 break;
398
399 case T_property:
400 {
401 wxString propName;
402 wxString propValue;
403
404 while( (token = NextTok() ) != T_RIGHT )
405 {
406 if( token == T_LEFT )
407 token = NextTok();
408
409 if( token == T_name )
410 {
411 NeedSYMBOLorNUMBER();
412 propName = From_UTF8( CurText() );
413 NeedRIGHT();
414 }
415 else if( token == T_value )
416 {
417 NeedSYMBOLorNUMBER();
418 propValue = From_UTF8( CurText() );
419 NeedRIGHT();
420 }
421 else
422 {
423 Expecting( "name or value" );
424 }
425 }
426
427 if( !propName.IsEmpty() )
428 properties[propName] = std::move( propValue );
429 break;
430 }
431
432 case T_fields:
433 while( ( token = NextTok() ) != T_RIGHT )
434 {
435 if( token == T_LEFT )
436 token = NextTok();
437
438 if( token == T_field )
439 {
440 wxString fieldName;
441 wxString fieldValue;
442
443 while( ( token = NextTok() ) != T_RIGHT )
444 {
445 if( token == T_LEFT )
446 token = NextTok();
447
448 if( token == T_name )
449 {
450 NeedSYMBOLorNUMBER();
451 fieldName = From_UTF8( CurText() );
452 NeedRIGHT();
453 }
454 else if( token == T_STRING )
455 {
456 fieldValue = From_UTF8( CurText() );
457 }
458 }
459
460 if( !fieldName.IsEmpty() )
461 fields[fieldName] = std::move( fieldValue );
462 }
463 else
464 {
465 Expecting( "field" );
466 }
467 }
468 break;
469
470 case T_sheetpath:
471 while( ( token = NextTok() ) != T_EOF )
472 {
473 if( token == T_names )
474 {
475 NeedSYMBOLorNUMBER();
476 humanSheetPath = From_UTF8( CurText() );
477 NeedRIGHT();
478 }
479
480 if( token == T_tstamps )
481 {
482 NeedSYMBOLorNUMBER();
483 path = KIID_PATH( From_UTF8( CurText() ) );
484 NeedRIGHT();
485 break;
486 }
487 }
488
489 NeedRIGHT();
490
491 break;
492
493 case T_tstamps:
494 while( ( token = NextTok() ) != T_EOF )
495 {
496 if( token == T_RIGHT )
497 break;
498
499 uuids.emplace_back( From_UTF8( CurText() ) );
500 }
501
502 break;
503
504 case T_units:
505 {
506 // Parse a section like:
507 // (units (unit (ref "U1A") (name "A") (pins (pin "1") (pin "2"))))
508 while( ( token = NextTok() ) != T_RIGHT )
509 {
510 if( token == T_LEFT )
511 token = NextTok();
512
513 if( token == T_unit )
514 {
515 COMPONENT::UNIT_INFO info;
516
517 while( ( token = NextTok() ) != T_RIGHT )
518 {
519 if( token == T_LEFT )
520 token = NextTok();
521
522 switch( token )
523 {
524 case T_name:
525 NeedSYMBOLorNUMBER();
526 info.m_unitName = From_UTF8( CurText() );
527 NeedRIGHT();
528 break;
529
530 case T_pins:
531 while( ( token = NextTok() ) != T_RIGHT )
532 {
533 if( token == T_LEFT )
534 token = NextTok();
535
536 if( token == T_pin )
537 {
538 wxString pinNum;
539
540 // Parse pins in attribute style: (pin (num "1"))
541 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
542 {
543 if( token == T_LEFT )
544 token = NextTok();
545
546 if( token == T_num )
547 {
548 NeedSYMBOLorNUMBER();
549 pinNum = From_UTF8( CurText() );
550 NeedRIGHT();
551 }
552 else
553 {
554 // ignore other subfields of pin
555 // leave bare tokens untouched; they are not supported in this context
556 }
557 }
558
559 if( !pinNum.IsEmpty() )
560 info.m_pins.emplace_back( pinNum );
561 }
562 else
563 {
564 skipCurrent();
565 }
566 }
567 break;
568
569 default:
570 skipCurrent();
571 break;
572 }
573 }
574
575 parsedUnits.push_back( info );
576 }
577 else
578 {
579 skipCurrent();
580 }
581 }
582
583 break;
584 }
585
586 case T_component_classes:
587 while( ( token = NextTok() ) != T_RIGHT )
588 {
589 if( token != T_LEFT )
590 Expecting( T_LEFT );
591
592 if( ( token = NextTok() ) != T_class )
593 Expecting( T_class );
594
595 NeedSYMBOLorNUMBER();
596 componentClasses.insert( From_UTF8( CurText() ) );
597 NeedRIGHT();
598 }
599
600 break;
601
602 case T_duplicate_pin_numbers_are_jumpers:
603 {
604 NeedSYMBOLorNUMBER();
605 duplicatePinsAreJumpers = From_UTF8( CurText() ) == wxT( "1" );
606 NeedRIGHT();
607 break;
608 }
609
610 case T_jumper_pin_groups:
611 {
612 std::set<wxString>* currentGroup = nullptr;
613
614 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
615 {
616 if( token == T_LEFT )
617 token = NextTok();
618
619 switch( token )
620 {
621 case T_group:
622 currentGroup = &jumperPinGroups.emplace_back();
623 break;
624
625 case T_pin:
626 {
627 NeedSYMBOLorNUMBER();
628 wxString padName = From_UTF8( CurText() );
629 NeedRIGHT();
630 wxCHECK2( currentGroup, continue );
631 currentGroup->insert( padName );
632 break;
633 }
634
635 case T_RIGHT:
636 currentGroup = nullptr;
637 break;
638
639 default:
640 Expecting( "group or pin" );
641 }
642 }
643
644 break;
645 }
646
647 default:
648 // Skip not used data (i.e all other tokens)
649 skipCurrent();
650 break;
651 }
652 }
653
654 if( !footprint.IsEmpty() && fpid.Parse( footprint, true ) >= 0 )
655 {
656 wxString error;
657 error.Printf( _( "Invalid footprint ID in\nfile: '%s'\nline: %d\nofff: %d" ),
658 CurSource(), CurLineNumber(), CurOffset() );
659
660 THROW_IO_ERROR( error );
661 }
662
663 COMPONENT* component = new COMPONENT( fpid, ref, value, path, uuids );
664 component->SetName( name );
665 component->SetLibrary( library );
666 component->SetProperties( properties );
667 component->SetFields( fields );
668 component->SetHumanReadablePath( humanSheetPath );
669 component->SetComponentClassNames( componentClasses );
670 component->SetDuplicatePadNumbersAreJumpers( duplicatePinsAreJumpers );
671 std::ranges::copy( jumperPinGroups, std::inserter( component->JumperPadGroups(),
672 component->JumperPadGroups().end() ) );
673 component->SetUnitInfo( parsedUnits );
674 m_netlist->AddComponent( component );
675}
676
677
679{
680 /* Parses a section like
681 * (groups
682 * (group (name "") (lib_id "DesignBlock:Block") (uuid "7b1488be-4c43-4004-94fc-e4a26dda8f5b")
683 * (members
684 * (member (uuid "dfef752d-e203-4feb-91de-483b44bc4062"))
685 */
686
687 wxString name;
688 KIID uuid;
689 wxString libId; // Design block library link
690 std::vector<KIID> members;
691
692 // The token net was read, so the next data is (code <number>)
693 while( (token = NextTok() ) != T_EOF )
694 {
695 if( token == T_RIGHT )
696 break;
697 else if( token == T_LEFT )
698 token = NextTok();
699
700 switch( token )
701 {
702 case T_name:
703 NeedSYMBOLorNUMBER();
704 name = From_UTF8( CurText() );
705 NeedRIGHT();
706 break;
707
708 case T_uuid:
709 NeedSYMBOLorNUMBER();
710 uuid = From_UTF8( CurText() );
711 NeedRIGHT();
712 break;
713
714 case T_lib_id:
715 NeedSYMBOLorNUMBER();
716 libId = FromUTF8();
717 NeedRIGHT();
718 break;
719
720 case T_members:
721 while( ( token = NextTok() ) != T_RIGHT )
722 {
723 if( token == T_LEFT )
724 token = NextTok();
725
726 if( token == T_member )
727 {
728 wxString memberUuid;
729
730 while( ( token = NextTok() ) != T_RIGHT )
731 {
732 if( token == T_LEFT )
733 token = NextTok();
734
735 if( token == T_uuid )
736 {
737 NeedSYMBOLorNUMBER();
738 memberUuid = From_UTF8( CurText() );
739 NeedRIGHT();
740 }
741 else
742 {
743 Expecting( "uuid" );
744 }
745 }
746
747 members.emplace_back( memberUuid );
748 }
749 else
750 {
751 Expecting( "member" );
752 }
753
754 }
755 break;
756
757 default:
758 skipCurrent();
759 break;
760 }
761 }
762
763 LIB_ID groupLibId;
764
765 if( !libId.IsEmpty() && groupLibId.Parse( libId, true ) >= 0 )
766 {
767 wxString error;
768 error.Printf( _( "Invalid lib_id ID in\nfile: '%s'\nline: %d\nofff: %d" ), CurSource(), CurLineNumber(),
769 CurOffset() );
770
771 THROW_IO_ERROR( error );
772 }
773
774 NETLIST_GROUP* group = new NETLIST_GROUP{ std::move( name ), std::move( uuid ), std::move( groupLibId ),
775 std::move( members ) };
776 m_netlist->AddGroup( group );
777}
778
779
781{
782 /* Parses a section like
783 * (libpart (lib device) (part C)
784 * (aliases
785 * (alias Cxx)
786 * (alias Cyy))
787 * (description "Condensateur non polarise")
788 * (footprints
789 * (fp SM*)
790 * (fp C?)
791 * (fp C1-1))
792 * (fields
793 * (field (name Reference) C)
794 * (field (name Value) C))
795 * (pins
796 * (pin (num 1) (name ~) (type passive))
797 * (pin (num 2) (name ~) (type passive))))
798 *
799 * Currently footprints section/fp are read and data stored
800 * other fields (unused) are skipped
801 */
802 COMPONENT* component = NULL;
803 wxString libName;
804 wxString libPartName;
805 wxArrayString footprintFilters;
806 wxArrayString aliases;
807 int pinCount = 0;
808
809 // The last token read was libpart, so read the next token
810 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: begin libpart" ) );
811 while( (token = NextTok() ) != T_RIGHT )
812 {
813 if( token == T_LEFT )
814 token = NextTok();
815
816 switch( token )
817 {
818 case T_lib:
819 NeedSYMBOLorNUMBER();
820 libName = From_UTF8( CurText() );
821 NeedRIGHT();
822 break;
823
824 case T_part:
825 NeedSYMBOLorNUMBER();
826 libPartName = From_UTF8( CurText() );
827 NeedRIGHT();
828 break;
829
830 case T_footprints:
831 // Read all fp elements (footprint filter item)
832 while( (token = NextTok() ) != T_RIGHT )
833 {
834 if( token == T_LEFT )
835 token = NextTok();
836
837 if( token != T_fp )
838 Expecting( T_fp );
839
840 token = NextTok();
841
842 // Accept an empty (fp) sexpr. We do write them out.
843 if( token == T_RIGHT )
844 continue;
845
846 if( !IsSymbol( token ) && !IsNumber( token ) )
847 Expecting( "footprint ID" );
848
849 footprintFilters.Add( From_UTF8( CurText() ) );
850 NeedRIGHT();
851 }
852 break;
853
854 case T_aliases:
855 while( (token = NextTok() ) != T_RIGHT )
856 {
857 if( token == T_LEFT )
858 token = NextTok();
859
860 if( token != T_alias )
861 Expecting( T_alias );
862
863 NeedSYMBOLorNUMBER();
864 aliases.Add( From_UTF8( CurText() ) );
865 NeedRIGHT();
866 }
867 break;
868
869 case T_pins:
870 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: entering pins for '%s:%s'" ),
871 libName, libPartName );
872 while( (token = NextTok() ) != T_RIGHT )
873 {
874 if( token == T_LEFT )
875 token = NextTok();
876
877 if( token != T_pin )
878 Expecting( T_pin );
879
880 pinCount++;
881 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: pin #%d for '%s:%s'" ),
882 pinCount, libName, libPartName );
883
884 skipCurrent();
885 }
886 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Parsed libpart '%s:%s' pins => pinCount=%d" ),
887 libName, libPartName, pinCount );
888 break;
889
890 default:
891 // Skip not used data (i.e all other tokens)
892 skipCurrent();
893 break;
894 }
895 }
896
897 // Find all of the components that reference this component library part definition.
898 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: assigning pinCount=%d for libpart '%s:%s'" ),
899 pinCount, libName, libPartName );
900 for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
901 {
902 component = m_netlist->GetComponent( i );
903
904 if( component->IsLibSource( libName, libPartName ) )
905 {
906 component->SetFootprintFilters( footprintFilters );
907 component->SetPinCount( pinCount );
908 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Assign pinCount=%d to component ref='%s' part='%s:%s'" ),
909 pinCount, component->GetReference(), libName, libPartName );
910 }
911
912 for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
913 {
914 if( component->IsLibSource( libName, aliases[jj] ) )
915 {
916 component->SetFootprintFilters( footprintFilters );
917 component->SetPinCount( pinCount );
918 wxLogTrace( "CVPCB_PINCOUNT",
919 wxT( "Assign pinCount=%d to component ref='%s' via alias='%s:%s'" ),
920 pinCount, component->GetReference(), libName, aliases[jj] );
921 }
922 }
923
924 }
925}
const char * name
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.
Definition lib_id.cpp:52
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition richio.h:66
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 _(s)
#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)
std::string path