KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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{
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;
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 {
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
Store all of the related footprint 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)) (...
NETLIST * m_netlist
The netlist to parse into. Not owned.
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 "..."))))
LINE_READER * m_lineReader
The line reader used to parse the netlist. Not owned.
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
Definition kiid.h:49
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
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:93
NETLIST * m_netlist
The net list to read the file(s) into.
LINE_READER * m_lineReader
The line reader of the netlist.
CMP_READER * m_footprintReader
The reader used to load the footprint links. If NULL, footprint links are not read.
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)