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
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 THROW_IO_ERRORF( _( "Invalid footprint ID in\nfile: '%s'\nline: %d\noffset: %d" ),
650 CurSource(), CurLineNumber(), CurOffset() );
651 }
652
653 COMPONENT* component = new COMPONENT( fpid, ref, value, path, uuids );
654 component->SetName( name );
655 component->SetLibrary( library );
656 component->SetProperties( properties );
657 component->SetFields( fields );
658 component->SetHumanReadablePath( humanSheetPath );
659 component->SetComponentClassNames( componentClasses );
660 component->SetDuplicatePadNumbersAreJumpers( duplicatePinsAreJumpers );
661 std::ranges::copy( jumperPinGroups, std::inserter( component->JumperPadGroups(),
662 component->JumperPadGroups().end() ) );
663 component->SetUnitInfo( parsedUnits );
664 m_netlist->AddComponent( component );
665}
666
667
669{
670 /* Parses a section like
671 * (groups
672 * (group (name "") (lib_id "DesignBlock:Block") (uuid "7b1488be-4c43-4004-94fc-e4a26dda8f5b")
673 * (members
674 * (member (uuid "dfef752d-e203-4feb-91de-483b44bc4062"))
675 */
676
677 wxString name;
678 KIID uuid;
679 wxString libId; // Design block library link
680 std::vector<KIID> members;
681
682 // The token net was read, so the next data is (code <number>)
683 while( (token = NextTok() ) != T_EOF )
684 {
685 if( token == T_RIGHT )
686 break;
687 else if( token == T_LEFT )
688 token = NextTok();
689
690 switch( token )
691 {
692 case T_name:
693 NeedSYMBOLorNUMBER();
694 name = From_UTF8( CurText() );
695 NeedRIGHT();
696 break;
697
698 case T_uuid:
699 NeedSYMBOLorNUMBER();
700 uuid = From_UTF8( CurText() );
701 NeedRIGHT();
702 break;
703
704 case T_lib_id:
705 NeedSYMBOLorNUMBER();
706 libId = FromUTF8();
707 NeedRIGHT();
708 break;
709
710 case T_members:
711 while( ( token = NextTok() ) != T_RIGHT )
712 {
713 if( token == T_LEFT )
714 token = NextTok();
715
716 if( token == T_member )
717 {
718 wxString memberUuid;
719
720 while( ( token = NextTok() ) != T_RIGHT )
721 {
722 if( token == T_LEFT )
723 token = NextTok();
724
725 if( token == T_uuid )
726 {
727 NeedSYMBOLorNUMBER();
728 memberUuid = From_UTF8( CurText() );
729 NeedRIGHT();
730 }
731 else
732 {
733 Expecting( "uuid" );
734 }
735 }
736
737 members.emplace_back( memberUuid );
738 }
739 else
740 {
741 Expecting( "member" );
742 }
743
744 }
745 break;
746
747 default:
748 skipCurrent();
749 break;
750 }
751 }
752
753 LIB_ID groupLibId;
754
755 if( !libId.IsEmpty() && groupLibId.Parse( libId, true ) >= 0 )
756 {
757 THROW_IO_ERRORF( _( "Invalid lib_id ID in\nfile: '%s'\nline: %d\noffset: %d" ),
758 CurSource(), CurLineNumber(), CurOffset() );
759 }
760
761 NETLIST_GROUP* group = new NETLIST_GROUP{ std::move( name ), std::move( uuid ), std::move( groupLibId ),
762 std::move( members ) };
763 m_netlist->AddGroup( group );
764}
765
766
768{
769 /* Parses a section like
770 * (libpart (lib device) (part C)
771 * (aliases
772 * (alias Cxx)
773 * (alias Cyy))
774 * (description "Condensateur non polarise")
775 * (footprints
776 * (fp SM*)
777 * (fp C?)
778 * (fp C1-1))
779 * (fields
780 * (field (name Reference) C)
781 * (field (name Value) C))
782 * (pins
783 * (pin (num 1) (name ~) (type passive))
784 * (pin (num 2) (name ~) (type passive))))
785 *
786 * Currently footprints section/fp are read and data stored
787 * other fields (unused) are skipped
788 */
789 COMPONENT* component = NULL;
790 wxString libName;
791 wxString libPartName;
792 wxArrayString footprintFilters;
793 wxArrayString aliases;
794 int pinCount = 0;
795
796 // The last token read was libpart, so read the next token
797 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: begin libpart" ) );
798 while( (token = NextTok() ) != T_RIGHT )
799 {
800 if( token == T_LEFT )
801 token = NextTok();
802
803 switch( token )
804 {
805 case T_lib:
806 NeedSYMBOLorNUMBER();
807 libName = From_UTF8( CurText() );
808 NeedRIGHT();
809 break;
810
811 case T_part:
812 NeedSYMBOLorNUMBER();
813 libPartName = From_UTF8( CurText() );
814 NeedRIGHT();
815 break;
816
817 case T_footprints:
818 // Read all fp elements (footprint filter item)
819 while( (token = NextTok() ) != T_RIGHT )
820 {
821 if( token == T_LEFT )
822 token = NextTok();
823
824 if( token != T_fp )
825 Expecting( T_fp );
826
827 token = NextTok();
828
829 // Accept an empty (fp) sexpr. We do write them out.
830 if( token == T_RIGHT )
831 continue;
832
833 if( !IsSymbol( token ) && !IsNumber( token ) )
834 Expecting( "footprint ID" );
835
836 footprintFilters.Add( From_UTF8( CurText() ) );
837 NeedRIGHT();
838 }
839 break;
840
841 case T_aliases:
842 while( (token = NextTok() ) != T_RIGHT )
843 {
844 if( token == T_LEFT )
845 token = NextTok();
846
847 if( token != T_alias )
848 Expecting( T_alias );
849
850 NeedSYMBOLorNUMBER();
851 aliases.Add( From_UTF8( CurText() ) );
852 NeedRIGHT();
853 }
854 break;
855
856 case T_pins:
857 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: entering pins for '%s:%s'" ),
858 libName, libPartName );
859 while( (token = NextTok() ) != T_RIGHT )
860 {
861 if( token == T_LEFT )
862 token = NextTok();
863
864 if( token != T_pin )
865 Expecting( T_pin );
866
867 pinCount++;
868 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: pin #%d for '%s:%s'" ),
869 pinCount, libName, libPartName );
870
871 skipCurrent();
872 }
873 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Parsed libpart '%s:%s' pins => pinCount=%d" ),
874 libName, libPartName, pinCount );
875 break;
876
877 default:
878 // Skip not used data (i.e all other tokens)
879 skipCurrent();
880 break;
881 }
882 }
883
884 // Find all of the components that reference this component library part definition.
885 wxLogTrace( "CVPCB_PINCOUNT", wxT( "parseLibPartList: assigning pinCount=%d for libpart '%s:%s'" ),
886 pinCount, libName, libPartName );
887 for( unsigned i = 0; i < m_netlist->GetCount(); i++ )
888 {
889 component = m_netlist->GetComponent( i );
890
891 if( component->IsLibSource( libName, libPartName ) )
892 {
893 component->SetFootprintFilters( footprintFilters );
894 component->SetPinCount( pinCount );
895 wxLogTrace( "CVPCB_PINCOUNT", wxT( "Assign pinCount=%d to component ref='%s' part='%s:%s'" ),
896 pinCount, component->GetReference(), libName, libPartName );
897 }
898
899 for( unsigned jj = 0; jj < aliases.GetCount(); jj++ )
900 {
901 if( component->IsLibSource( libName, aliases[jj] ) )
902 {
903 component->SetFootprintFilters( footprintFilters );
904 component->SetPinCount( pinCount );
905 wxLogTrace( "CVPCB_PINCOUNT",
906 wxT( "Assign pinCount=%d to component ref='%s' via alias='%s:%s'" ),
907 pinCount, component->GetReference(), libName, aliases[jj] );
908 }
909 }
910
911 }
912}
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:46
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:65
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_ERRORF(msg,...)
static bool IsNumber(char x)
wxString From_UTF8(const char *cstring)
std::string path