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