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