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