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