KiCad PCB EDA Suite
cadstar_sch_archive_parser.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) 2020-2021 Roberto Fernandez Bautista <[email protected]>
5 * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
26#include <base_units.h>
27#include <macros.h>
29#include <progress_reporter.h>
30#include <wx/translation.h>
31
32
34{
36 m_progressReporter->BeginPhase( 0 ); // Read file
37
38 m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
39
41 {
42 m_progressReporter->BeginPhase( 1 ); // Parse File
43
44 std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
45 wxT( "SCHEMATIC" ) };
46
47 long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
49 }
50
52
53 XNODE* cNode = m_rootNode->GetChildren();
54
55 if( !cNode )
56 THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARSCM" ) );
57
58 for( ; cNode; cNode = cNode->GetNext() )
59 {
60 if( cNode->GetName() == wxT( "HEADER" ) )
61 {
62 Header.Parse( cNode, &m_context );
63
64 switch( Header.Resolution )
65 {
67 KiCadUnitDivider = (long) 1e5 / (long) SCH_IU_PER_MM;
68 break;
69
70 default:
71 wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
72 break;
73 }
74 }
75 else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
76 {
77 Assignments.Parse( cNode, &m_context );
78 }
79 else if( cNode->GetName() == wxT( "LIBRARY" ) )
80 {
81 Library.Parse( cNode, &m_context );
82 }
83 else if( cNode->GetName() == wxT( "DEFAULTS" ) )
84 {
85 // No design information here (no need to parse)
86 // Only contains CADSTAR configuration data such as default shapes, text and units
87 // In future some of this could be converted to KiCad but limited value
88 }
89 else if( cNode->GetName() == wxT( "PARTS" ) )
90 {
91 Parts.Parse( cNode, &m_context );
92 }
93 else if( cNode->GetName() == wxT( "SHEETS" ) )
94 {
95 Sheets.Parse( cNode, &m_context );
96 }
97 else if( cNode->GetName() == wxT( "SCHEMATIC" ) )
98 {
99 Schematic.Parse( cNode, &m_context );
100 }
101 else if( cNode->GetName() == wxT( "DISPLAY" ) )
102 {
103 // For now only interested in Attribute visibilities, in order to set field visibilities
104 // in the imported design
105 XNODE* subNode = cNode->GetChildren();
106
107 for( ; subNode; subNode = subNode->GetNext() )
108 {
109 if( subNode->GetName() == wxT( "ATTRCOLORS" ) )
110 {
111 AttrColors.Parse( subNode, &m_context );
112 }
113 else if( subNode->GetName() == wxT( "SCMITEMCOLORS" ) )
114 {
115 XNODE* sub2Node = subNode->GetChildren();
116
117 for( ; sub2Node; sub2Node = sub2Node->GetNext() )
118 {
119 if( sub2Node->GetName() == wxT( "SYMCOL" ) )
120 {
121 XNODE* sub3Node = sub2Node->GetChildren();
122
123 for( ; sub3Node; sub3Node = sub3Node->GetNext() )
124 {
125 if( sub3Node->GetName() == wxT( "PARTNAMECOL" ) )
126 SymbolPartNameColor.Parse( sub3Node, &m_context );
127 }
128 }
129 }
130 }
131 else
132 {
133 // No design information here
134 // Contains CADSTAR Display settings such as layer/element colours and visibility.
135 // In the future these settings could be converted to KiCad
136 }
137 }
138
139 }
140 else
141 {
142 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) );
143 }
144
145 checkPoint();
146 }
147
148 delete m_rootNode;
149 m_rootNode = nullptr;
150}
151
152
154 const wxString& aShapeStr )
155{
156 if( aShapeStr == wxT( "ANNULUS" ) )
158 else if( aShapeStr == wxT( "BOX" ) )
160 else if( aShapeStr == wxT( "BULLET" ) )
162 else if( aShapeStr == wxT( "ROUND" ) )
164 else if( aShapeStr == wxT( "CROSS" ) )
166 else if( aShapeStr == wxT( "DIAMOND" ) )
168 else if( aShapeStr == wxT( "FINGER" ) )
170 else if( aShapeStr == wxT( "OCTAGON" ) )
172 else if( aShapeStr == wxT( "PLUS" ) )
174 else if( aShapeStr == wxT( "POINTER" ) )
176 else if( aShapeStr == wxT( "RECTANGLE" ) )
178 else if( aShapeStr == wxT( "ROUNDED" ) )
180 else if( aShapeStr == wxT( "SQUARE" ) )
182 else if( aShapeStr == wxT( "STAR" ) )
184 else if( aShapeStr == wxT( "TRIANGLE" ) )
186 else
188}
189
190
192{
193 return ParseTermShapeType( aNode->GetName() ) != TERMINAL_SHAPE_TYPE::UNDEFINED;
194}
195
196
198{
199 wxCHECK( IsTermShape( aNode ), );
200
201 ShapeType = ParseTermShapeType( aNode->GetName() );
202 Size = GetXmlAttributeIDLong( aNode, 0 );
203
204 switch( ShapeType )
205 {
211 InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
212 break;
213
215 InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
217
223 RightLength = GetXmlAttributeIDLong( aNode, 2, false ); // Optional
224 LeftLength = GetXmlAttributeIDLong( aNode, 1 );
225 break;
226
231 //don't do anything
232 break;
233
235 wxASSERT_MSG( false, "Unknown terminal shape type" );
236 break;
237 }
238
239 if( aNode->GetChildren() )
240 {
241 if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
242 {
243 OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
244 }
245 else
246 {
247 THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
248 }
249
250 CheckNoNextNodes( aNode->GetChildren() );
251 }
252}
253
254
256{
257 wxCHECK( aNode->GetName() == wxT( "TERMINALCODE" ), );
258
259 ID = GetXmlAttributeIDString( aNode, 0 );
260 Name = GetXmlAttributeIDString( aNode, 1 );
261
262 XNODE* cNode = aNode->GetChildren();
263 wxString location = wxString::Format( "TERMINALCODE -> %s", Name );
264
265 for( ; cNode; cNode = cNode->GetNext() )
266 {
267 wxString cNodeName = cNode->GetName();
268
269 if( TERMINAL_SHAPE::IsTermShape( cNode ) )
270 Shape.Parse( cNode, aContext );
271 else if( cNodeName == wxT( "FILLED" ) )
272 Filled = true;
273 else
274 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
275 }
276}
277
278
280{
281 wxCHECK( aNode->GetName() == wxT( "CODEDEFS" ), );
282
283 XNODE* cNode = aNode->GetChildren();
284
285 for( ; cNode; cNode = cNode->GetNext() )
286 {
287 wxString nodeName = cNode->GetName();
288
289 if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
290 {
291 continue;
292 }
293 else if( nodeName == wxT( "TERMINALCODE" ) )
294 {
295 TERMINALCODE termcode;
296 termcode.Parse( cNode, aContext );
297 TerminalCodes.insert( std::make_pair( termcode.ID, termcode ) );
298 }
299 else
300 {
301 THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
302 }
303 }
304}
305
306
308{
309 wxCHECK( aNode->GetName() == wxT( "ASSIGNMENTS" ), );
310
311 XNODE* cNode = aNode->GetChildren();
312 bool settingsParsed = false;
313
314 for( ; cNode; cNode = cNode->GetNext() )
315 {
316 if( cNode->GetName() == wxT( "CODEDEFS" ) )
317 {
318 Codedefs.Parse( cNode, aContext );
319 }
320 else if( cNode->GetName() == wxT( "SETTINGS" ) )
321 {
322 settingsParsed = true;
323 Settings.Parse( cNode, aContext );
324 }
325 else if( cNode->GetName() == wxT( "GRIDS" ) )
326 {
327 Grids.Parse( cNode, aContext );
328 }
329 else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
330 {
331 NetclassEditAttributeSettings = true;
332 }
333 else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
334 {
335 SpacingclassEditAttributeSettings = true;
336 }
337 else
338 {
339 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
340 }
341 }
342
343 if( !settingsParsed )
344 THROW_MISSING_NODE_IO_ERROR( wxT( "SETTINGS" ), wxT( "ASSIGNMENTS" ) );
345}
346
347
349{
350 wxCHECK( aNode->GetName() == wxT( "TERMINAL" ), );
351
352 ID = GetXmlAttributeIDLong( aNode, 0 );
353 TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
354
355 XNODE* cNode = aNode->GetChildren();
356 wxString location = wxString::Format( "TERMINAL %ld", ID );
357
358 if( !cNode )
359 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
360
361 for( ; cNode; cNode = cNode->GetNext() )
362 {
363 wxString cNodeName = cNode->GetName();
364
365 if( cNodeName == wxT( "ORIENT" ) )
366 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
367 else if( cNodeName == wxT( "PT" ) )
368 Position.Parse( cNode, aContext );
369 else
370 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
371 }
372}
373
374
376{
377 wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
378 || aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
379
380 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
381 TextCodeID = GetXmlAttributeIDString( aNode, 1 );
382
383 //Parse child nodes
384 XNODE* cNode = aNode->GetChildren();
385
386 for( ; cNode; cNode = cNode->GetNext() )
387 {
388 if( ParseSubNode( cNode, aContext ) )
389 continue;
390 else
391 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
392 }
393
394 if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
395 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
396}
397
398
400{
401 wxCHECK( aNode->GetName() == wxT( "SYMDEF" ), );
402
403 ParseIdentifiers( aNode, aContext );
404
405 XNODE* cNode = aNode->GetChildren();
406
407 for( ; cNode; cNode = cNode->GetNext() )
408 {
409 wxString cNodeName = cNode->GetName();
410
411 if( ParseSubNode( cNode, aContext ) )
412 {
413 continue;
414 }
415 else if( cNodeName == wxT( "TERMINAL" ) )
416 {
417 TERMINAL term;
418 term.Parse( cNode, aContext );
419 Terminals.insert( std::make_pair( term.ID, term ) );
420 }
421 else if( cNodeName == wxT( "PINLABELLOC" ) )
422 {
424 loc.Parse( cNode, aContext );
425 PinLabelLocations.insert( std::make_pair( loc.TerminalID, loc ) );
426 }
427 else if( cNodeName == wxT( "PINNUMNAMELOC" ) )
428 {
430 loc.Parse( cNode, aContext );
431 PinNumberLocations.insert( std::make_pair( loc.TerminalID, loc ) );
432 }
433 else
434 {
435 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
436 }
437 }
438
439 if( !Stub && ( Origin.x == UNDEFINED_VALUE || Origin.y == UNDEFINED_VALUE ) )
440 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
441}
442
443
445{
446 wxCHECK( aNode->GetName() == wxT( "LIBRARY" ), );
447
448 XNODE* cNode = aNode->GetChildren();
449
450 for( ; cNode; cNode = cNode->GetNext() )
451 {
452 wxString cNodeName = cNode->GetName();
453
454 if( cNodeName == wxT( "SYMDEF" ) )
455 {
456 SYMDEF_SCM symdef;
457 symdef.Parse( cNode, aContext );
458 SymbolDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
459 }
460 else
461 {
462 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
463 }
464
465 aContext->CheckPointCallback();
466 }
467}
468
469
471{
472 wxCHECK( aNode->GetName() == wxT( "SHEETS" ), );
473
474 XNODE* cNode = aNode->GetChildren();
475
476 for( ; cNode; cNode = cNode->GetNext() )
477 {
478 if( cNode->GetName() == wxT( "SHEET" ) )
479 {
480 LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
482 SheetNames.insert( std::make_pair( id, name ) );
483 SheetOrder.push_back( id );
484 }
485 else
486 {
487 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
488 }
489 }
490}
491
492
494{
495 wxCHECK( aNode->GetName() == wxT( "COMP" ), );
496
497 Designator = GetXmlAttributeIDString( aNode, 0 );
498
499 XNODE* cNode = aNode->GetChildren();
500
501 for( ; cNode; cNode = cNode->GetNext() )
502 {
503 if( cNode->GetName() == wxT( "READONLY" ) )
504 {
505 ReadOnly = true;
506 }
507 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
508 {
509 AttrLoc.Parse( cNode, aContext );
510 HasLocation = true;
511 }
512 else
513 {
514 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
515 }
516 }
517}
518
519
521{
522 wxCHECK( aNode->GetName() == wxT( "PARTREF" ), );
523
524 RefID = GetXmlAttributeIDString( aNode, 0 );
525
526 XNODE* cNode = aNode->GetChildren();
527
528 for( ; cNode; cNode = cNode->GetNext() )
529 {
530 if( cNode->GetName() == wxT( "READONLY" ) )
531 {
532 ReadOnly = true;
533 }
534 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
535 {
536 AttrLoc.Parse( cNode, aContext );
537 HasLocation = true;
538 }
539 else
540 {
541 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
542 }
543 }
544}
545
546
548{
549 wxCHECK( aNode->GetName() == wxT( "TERMATTR" ), /* void */ );
550
551 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
552
553 XNODE* cNode = aNode->GetChildren();
554 bool attrParsed = false;
555
556 for( ; cNode; cNode = cNode->GetNext() )
557 {
558 if( !attrParsed && cNode->GetName() == wxT( "ATTR" ) )
559 {
560 Value.Parse( cNode, aContext );
561 attrParsed = true;
562 }
563 else
564 {
565 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
566 }
567 }
568}
569
570
572{
573 wxCHECK( aNode->GetName() == wxT( "SYMPINNAME" ) || aNode->GetName() == wxT( "SYMPINLABEL" ), );
574
575 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
576 NameOrLabel = GetXmlAttributeIDString( aNode, 1 );
577
578 XNODE* cNode = aNode->GetChildren();
579
580 for( ; cNode; cNode = cNode->GetNext() )
581 {
582 if( cNode->GetName() == wxT( "ATTRLOC" ) )
583 {
584 AttrLoc.Parse( cNode, aContext );
585 HasLocation = true;
586 }
587 else
588 {
589 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
590 }
591 }
592}
593
594
596{
597 wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
598
599 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
600 PinNum = GetXmlAttributeIDLong( aNode, 1 );
601
602 XNODE* cNode = aNode->GetChildren();
603
604 for( ; cNode; cNode = cNode->GetNext() )
605 {
606 if( cNode->GetName() == wxT( "ATTRLOC" ) )
607 {
608 AttrLoc.Parse( cNode, aContext );
609 HasLocation = true;
610 }
611 else
612 {
613 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
614 }
615 }
616}
617
618
620{
621 wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
622
623 XNODE* cNode = aNode->GetChildren();
624
625 for( ; cNode; cNode = cNode->GetNext() )
626 {
627 wxString cNodeName = cNode->GetName();
628
629 if( cNodeName == wxT( "SIGNALREF" ) )
630 {
631 Type = TYPE::SIGNALREF;
632 CheckNoNextNodes( cNode );
633 }
634 else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
635 {
636 Type = TYPE::GLOBALSIGNAL;
637 Reference = GetXmlAttributeIDString( cNode, 0 );
638 }
639 else if( cNodeName == wxT( "TESTPOINT" ) )
640 {
641 Type = TYPE::TESTPOINT;
642 CheckNoNextNodes( cNode );
643 }
644 else
645 {
646 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
647 }
648 }
649}
650
651
653{
654 wxCHECK( aNode->GetName() == wxT( "SIGNALREFERENCELINK" ), );
655
656 TextCodeID = GetXmlAttributeIDString( aNode, 0 );
657 LayerID = GetXmlAttributeIDString( aNode, 2 );
658
659 //Parse child nodes
660 XNODE* cNode = aNode->GetChildren();
661
662 for( ; cNode; cNode = cNode->GetNext() )
663 {
664 if( ParseSubNode( cNode, aContext ) )
665 continue;
666 else if( cNode->GetName() == wxT( "SIGREFTEXT" ) )
667 Text = GetXmlAttributeIDString( aNode, 0 );
668 else
669 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
670 }
671
672 if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
673 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
674}
675
676
678{
679 wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
680
681 ID = GetXmlAttributeIDString( aNode, 0 );
682 SymdefID = GetXmlAttributeIDString( aNode, 1 );
683 LayerID = GetXmlAttributeIDString( aNode, 2 );
684
685 XNODE* cNode = aNode->GetChildren();
686 bool originParsed = false;
687 wxString location = wxString::Format( "SYMBOL -> %s", ID );
688
689 for( ; cNode; cNode = cNode->GetNext() )
690 {
691 wxString cNodeName = cNode->GetName();
692
693 if( !originParsed && cNodeName == wxT( "PT" ) )
694 {
695 Origin.Parse( cNode, aContext );
696 originParsed = true;
697 }
698 else if( cNodeName == wxT( "COMP" ) )
699 {
700 ComponentRef.Parse( cNode, aContext );
701 IsComponent = true;
702 }
703 else if( cNodeName == wxT( "PARTREF" ) )
704 {
705 PartRef.Parse( cNode, aContext );
706 HasPartRef = true;
707 }
708 else if( cNodeName == wxT( "PARTNAMENOTVISIBLE" ) )
709 {
710 PartNameVisible = false;
711 }
712 else if( cNodeName == wxT( "VSYMMASTER" ) )
713 {
714 VariantParentSymbolID = GetXmlAttributeIDString( cNode, 0 );
715 VariantID = GetXmlAttributeIDString( cNode, 1 );
716 }
717 else if( cNodeName == wxT( "GROUPREF" ) )
718 {
719 GroupID = GetXmlAttributeIDString( cNode, 0 );
720 }
721 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
722 {
723 ReuseBlockRef.Parse( cNode, aContext );
724 }
725 else if( cNodeName == wxT( "SIGNALREFERENCELINK" ) )
726 {
727 SigRefLink.Parse( cNode, aContext );
728 }
729 else if( cNodeName == wxT( "ORIENT" ) )
730 {
731 OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
732 }
733 else if( cNodeName == wxT( "MIRROR" ) )
734 {
735 Mirror = true;
736 }
737 else if( cNodeName == wxT( "FIX" ) )
738 {
739 Fixed = true;
740 }
741 else if( cNodeName == wxT( "SCALE" ) )
742 {
743 ScaleRatioNumerator = GetXmlAttributeIDLong( cNode, 0 );
744 ScaleRatioDenominator = GetXmlAttributeIDLong( cNode, 1 );
745 }
746 else if( cNodeName == wxT( "READABILITY" ) )
747 {
748 Readability = ParseReadability( cNode );
749 }
750 else if( cNodeName == wxT( "GATE" ) )
751 {
752 GateID = GetXmlAttributeIDString( cNode, 0 );
753 }
754 else if( cNodeName == wxT( "SYMBOLVARIANT" ) )
755 {
756 IsSymbolVariant = true;
757 SymbolVariant.Parse( cNode, aContext );
758 }
759 else if( cNodeName == wxT( "TERMATTR" ) )
760 {
761 TERMATTR termattr;
762 termattr.Parse( cNode, aContext );
763 TerminalAttributes.insert( std::make_pair( termattr.TerminalID, termattr ) );
764 }
765 else if( cNodeName == wxT( "SYMPINLABEL" ) )
766 {
767 SYMPINNAME_LABEL sympinname;
768 sympinname.Parse( cNode, aContext );
769 PinLabels.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
770 }
771 else if( cNodeName == wxT( "SYMPINNAME" ) )
772 {
773 SYMPINNAME_LABEL sympinname;
774 sympinname.Parse( cNode, aContext );
775 PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
776 }
777 else if( cNodeName == wxT( "PINNUM" ) )
778 {
779 PIN_NUM pinNum;
780 pinNum.Parse( cNode, aContext );
781 PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
782 }
783 else if( cNodeName == wxT( "ATTR" ) )
784 {
785 ATTRIBUTE_VALUE attrVal;
786 attrVal.Parse( cNode, aContext );
787 AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
788 }
789 else
790 {
791 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
792 }
793 }
794
795 if( !originParsed )
796 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
797}
798
799
801{
802 wxCHECK( aNode->GetName() == wxT( "SIGLOC" ), );
803
804 TextCodeID = GetXmlAttributeIDString( aNode, 0 );
805
806 //Parse child nodes
807 XNODE* cNode = aNode->GetChildren();
808
809 for( ; cNode; cNode = cNode->GetNext() )
810 {
811 if( ParseSubNode( cNode, aContext ) )
812 continue;
813 else
814 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
815 }
816
817 if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
818 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
819}
820
821
823{
824 wxCHECK( aNode->GetName() == wxT( "BUS" ), );
825
826 ID = GetXmlAttributeIDString( aNode, 0 );
827 LineCodeID = GetXmlAttributeIDString( aNode, 1 );
828 LayerID = GetXmlAttributeIDString( aNode, 2 );
829
830 XNODE* cNode = aNode->GetChildren();
831
832 for( ; cNode; cNode = cNode->GetNext() )
833 {
834 wxString cNodeName = cNode->GetName();
835
836 if( SHAPE::IsShape( cNode ) )
837 {
838 Shape.Parse( cNode, aContext );
839 }
840 else if( cNodeName == wxT( "BUSNAME" ) )
841 {
842 Name = GetXmlAttributeIDString( cNode, 0 );
843
844 XNODE* subNode = cNode->GetChildren();
845
846 if( subNode )
847 {
848 if( subNode->GetName() == wxT( "SIGLOC" ) )
849 {
850 BusLabel.Parse( subNode, aContext );
851 HasBusLabel = true;
852 }
853 else
854 {
855 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
856 }
857 }
858 }
859 else
860 {
861 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
862 }
863 }
864}
865
866
868{
869 wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
870
871 ID = GetXmlAttributeIDString( aNode, 0 );
872 LayerID = GetXmlAttributeIDString( aNode, 2 );
873
874 XNODE* cNode = aNode->GetChildren();
875
876 for( ; cNode; cNode = cNode->GetNext() )
877 {
878 wxString cNodeName = cNode->GetName();
879
880 if( cNodeName == wxT( "CLONE" ) )
881 {
882 Type = TYPE::CLONE;
883 }
884 else if( cNodeName == wxT( "PARENT" ) )
885 {
886 Type = TYPE::PARENT;
887 AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
888 }
889 else if( cNodeName == wxT( "CHILD" ) )
890 {
891 Type = TYPE::CHILD;
892 AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
893 }
894 else if( cNodeName == wxT( "BLOCKNAME" ) )
895 {
896 Name = GetXmlAttributeIDString( cNode, 0 );
897 XNODE* subNode = cNode->GetChildren();
898
899 if( subNode )
900 {
901 if( subNode->GetName() == wxT( "ATTRLOC" ) )
902 {
903 BlockLabel.Parse( subNode, aContext );
904 HasBlockLabel = true;
905 }
906 else
907 {
908 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
909 }
910 }
911 }
912 else if( cNodeName == wxT( "TERMINAL" ) )
913 {
914 TERMINAL term;
915 term.Parse( cNode, aContext );
916 Terminals.insert( std::make_pair( term.ID, term ) );
917 }
918 else if( cNodeName == wxT( "FIGURE" ) )
919 {
920 FIGURE figure;
921 figure.Parse( cNode, aContext );
922 Figures.insert( std::make_pair( figure.ID, figure ) );
923 }
924 else
925 {
926 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
927 }
928 }
929}
930
931
933{
934 wxASSERT( aNode->GetName() == wxT( "TERM" ) );
935
936 ID = GetXmlAttributeIDString( aNode, 0 );
937 SymbolID = GetXmlAttributeIDString( aNode, 1 );
938 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
939
940
941 XNODE* cNode = aNode->GetChildren();
942
943 for( ; cNode; cNode = cNode->GetNext() )
944 {
945 wxString cNodeName = cNode->GetName();
946
947 if( cNodeName == wxT( "SIGLOC" ) )
948 {
949 NetLabel.Parse( cNode, aContext );
950 HasNetLabel = true;
951 }
952 else
953 {
954 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
955 }
956 }
957}
958
959
961{
962 wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
963
964 ID = GetXmlAttributeIDString( aNode, 0 );
965 BusID = GetXmlAttributeIDString( aNode, 1 );
966
967
968 XNODE* cNode = aNode->GetChildren();
969 bool firstPointParsed = false;
970 bool secondPointParsed = false;
971
972 for( ; cNode; cNode = cNode->GetNext() )
973 {
974 wxString cNodeName = cNode->GetName();
975
976 if( cNodeName == wxT( "SIGLOC" ) )
977 {
978 NetLabel.Parse( cNode, aContext );
979 HasNetLabel = true;
980 }
981 else if( cNodeName == wxT( "PT" ) )
982 {
983 if( !firstPointParsed )
984 {
985 FirstPoint.Parse( cNode, aContext );
986 firstPointParsed = true;
987 }
988 else if( !secondPointParsed )
989 {
990 SecondPoint.Parse( cNode, aContext );
991 secondPointParsed = true;
992 }
993 else
994 {
995 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
996 }
997 }
998 else
999 {
1000 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1001 }
1002 }
1003
1004 if( !firstPointParsed || !secondPointParsed )
1005 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1006}
1007
1008
1010{
1011 wxASSERT( aNode->GetName() == wxT( "BLOCKTERM" ) );
1012
1013 ID = GetXmlAttributeIDString( aNode, 0 );
1014 BlockID = GetXmlAttributeIDString( aNode, 1 );
1015 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
1016
1017 XNODE* cNode = aNode->GetChildren();
1018
1019 for( ; cNode; cNode = cNode->GetNext() )
1020 {
1021 wxString cNodeName = cNode->GetName();
1022
1023 if( cNodeName == wxT( "SIGLOC" ) )
1024 {
1025 NetLabel.Parse( cNode, aContext );
1026 HasNetLabel = true;
1027 }
1028 else
1029 {
1030 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1031 }
1032 }
1033}
1034
1035
1037{
1038 ParseIdentifiers( aNode, aContext );
1039 LayerID = GetXmlAttributeIDString( aNode, 3 );
1040
1041 XNODE* cNode = aNode->GetChildren();
1042
1043 for( ; cNode; cNode = cNode->GetNext() )
1044 {
1045 wxString cNodeName = cNode->GetName();
1046
1047 if( ParseSubNode( cNode, aContext ) )
1048 {
1049 continue;
1050 }
1051 else if( cNodeName == wxT( "PATH" ) )
1052 {
1053 Path = ParseAllChildPoints( cNode, aContext, true );
1054 }
1055 else if( cNodeName == wxT( "GROUPREF" ) )
1056 {
1057 GroupID = GetXmlAttributeIDString( cNode, 0 );
1058 }
1059 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1060 {
1061 ReuseBlockRef.Parse( cNode, aContext );
1062 }
1063 else if( cNodeName == wxT( "CONLINECODE" ) )
1064 {
1065 ConnectionLineCode = GetXmlAttributeIDString( cNode, 0 );
1066 }
1067 else
1068 {
1069 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
1070 }
1071 }
1072}
1073
1074
1076{
1077 ParseIdentifiers( aNode, aContext );
1078
1079 //Parse child nodes
1080 XNODE* cNode = aNode->GetChildren();
1081
1082 for( ; cNode; cNode = cNode->GetNext() )
1083 {
1084 wxString cNodeName = cNode->GetName();
1085
1086 if( cNodeName == wxT( "JPT" ) )
1087 {
1088 JUNCTION_SCH jpt;
1089 jpt.Parse( cNode, aContext );
1090 Junctions.insert( std::make_pair( jpt.ID, jpt ) );
1091 }
1092 else if( ParseSubNode( cNode, aContext ) )
1093 {
1094 continue;
1095 }
1096 else if( cNodeName == wxT( "TERM" ) )
1097 {
1098 SYM_TERM pin;
1099 pin.Parse( cNode, aContext );
1100 Terminals.insert( std::make_pair( pin.ID, pin ) );
1101 }
1102 else if( cNodeName == wxT( "BUSTERM" ) )
1103 {
1104 BUS_TERM bt;
1105 bt.Parse( cNode, aContext );
1106 BusTerminals.insert( std::make_pair( bt.ID, bt ) );
1107 }
1108 else if( cNodeName == wxT( "BLOCKTERM" ) )
1109 {
1110 BLOCK_TERM bt;
1111 bt.Parse( cNode, aContext );
1112 BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
1113 }
1114 else if( cNodeName == wxT( "DANGLER" ) )
1115 {
1116 DANGLER dang;
1117 dang.Parse( cNode, aContext );
1118 Danglers.insert( std::make_pair( dang.ID, dang ) );
1119 }
1120 else if( cNodeName == wxT( "CONN" ) )
1121 {
1122 CONNECTION_SCH conn;
1123 conn.Parse( cNode, aContext );
1124 Connections.push_back( conn );
1125 }
1126 else
1127 {
1128 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
1129 }
1130 }
1131}
1132
1133
1135{
1136 wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
1137
1138 XNODE* cNode = aNode->GetChildren();
1139
1140 for( ; cNode; cNode = cNode->GetNext() )
1141 {
1142 wxString cNodeName = cNode->GetName();
1143
1144 if( cNodeName == wxT( "GROUP" ) )
1145 {
1146 GROUP group;
1147 group.Parse( cNode, aContext );
1148 Groups.insert( std::make_pair( group.ID, group ) );
1149 }
1150 else if( cNodeName == wxT( "REUSEBLOCK" ) )
1151 {
1152 REUSEBLOCK reuseblock;
1153 reuseblock.Parse( cNode, aContext );
1154 ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
1155 }
1156 else if( cNodeName == wxT( "FIGURE" ) )
1157 {
1158 FIGURE figure;
1159 figure.Parse( cNode, aContext );
1160 Figures.insert( std::make_pair( figure.ID, figure ) );
1161 }
1162 else if( cNodeName == wxT( "SYMBOL" ) )
1163 {
1164 SYMBOL sym;
1165 sym.Parse( cNode, aContext );
1166 Symbols.insert( std::make_pair( sym.ID, sym ) );
1167 }
1168 else if( cNodeName == wxT( "BUS" ) )
1169 {
1170 BUS bus;
1171 bus.Parse( cNode, aContext );
1172 Buses.insert( std::make_pair( bus.ID, bus ) );
1173 }
1174 else if( cNodeName == wxT( "BLOCK" ) )
1175 {
1176 BLOCK block;
1177 block.Parse( cNode, aContext );
1178 Blocks.insert( std::make_pair( block.ID, block ) );
1179 }
1180 else if( cNodeName == wxT( "NET" ) )
1181 {
1182 NET_SCH net;
1183 net.Parse( cNode, aContext );
1184 Nets.insert( std::make_pair( net.ID, net ) );
1185 }
1186 else if( cNodeName == wxT( "TEXT" ) )
1187 {
1188 TEXT txt;
1189 txt.Parse( cNode, aContext );
1190 Texts.insert( std::make_pair( txt.ID, txt ) );
1191 }
1192 else if( cNodeName == wxT( "DOCSYMBOL" ) )
1193 {
1194 DOCUMENTATION_SYMBOL docsym;
1195 docsym.Parse( cNode, aContext );
1196 DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
1197 }
1198 else if( cNodeName == wxT( "VHIERARCHY" ) )
1199 {
1200 VariantHierarchy.Parse( cNode, aContext );
1201 }
1202 else
1203 {
1204 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1205 }
1206
1207 aContext->CheckPointCallback();
1208 }
1209}
1210
1211
1213{
1214 ParseIdentifiers( aNode, aContext );
1215
1216 TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
1217 LayerID = GetXmlAttributeIDString( aNode, 2 );
1218
1219 XNODE* cNode = aNode->GetChildren();
1220
1221 for( ; cNode; cNode = cNode->GetNext() )
1222 {
1223 if( ParseSubNode( cNode, aContext ) )
1224 {
1225 continue;
1226 }
1227 else if( cNode->GetName() == wxT( "SIGLOC" ) )
1228 {
1229 NetLabel.Parse( cNode, aContext );
1230 HasNetLabel = true;
1231 }
1232 else
1233 {
1234 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1235 }
1236 }
1237
1238}
1239
1240
1242{
1243 wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
1244
1245 ID = GetXmlAttributeIDString( aNode, 0 );
1246 TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
1247 LayerID = GetXmlAttributeIDString( aNode, 2 );
1248
1249 XNODE* cNode = aNode->GetChildren();
1250 bool positionParsed = false;
1251
1252 for( ; cNode; cNode = cNode->GetNext() )
1253 {
1254 wxString cNodeName = cNode->GetName();
1255
1256 if( cNodeName == wxT( "SIGLOC" ) )
1257 {
1258 NetLabel.Parse( cNode, aContext );
1259 HasNetLabel = true;
1260 }
1261 else if( !positionParsed && cNodeName == wxT( "PT" ) )
1262 {
1263 Position.Parse( cNode, aContext );
1264 positionParsed = true;
1265 }
1266 else
1267 {
1268 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1269 }
1270 }
1271}
const char * name
Definition: DXF_plotter.cpp:56
constexpr double SCH_IU_PER_MM
Definition: base_units.h:73
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
static const long UNDEFINED_VALUE
static void CheckNoNextNodes(XNODE *aNode)
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format)
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void checkPoint()
Updates m_progressReporter or throws if user cancelled.
static READABILITY ParseReadability(XNODE *aNode)
static std::vector< POINT > ParseAllChildPoints(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false, int aExpectedNumPoints=UNDEFINED_VALUE)
if no children are present, it just returns an empty vector (without throwing an exception)
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
PROGRESS_REPORTER * m_progressReporter
@ UNDEFINED
Only used for error checking (not a real shape)
int KiCadUnitDivider
Use this value to convert units in this CSA file to KiCad units.
static TERMINAL_SHAPE_TYPE ParseTermShapeType(const wxString &aShapeStr)
virtual void BeginPhase(int aPhase)=0
Initialize the aPhase virtual zone of the dialog progress bar.
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
Hold an XML or S-expression element.
Definition: xnode.h:44
XNODE * GetChildren() const
Definition: xnode.h:62
XNODE * GetNext() const
Definition: xnode.h:67
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First character is "J".
std::function< void()> CheckPointCallback
Callback function to report progress.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "BLOCKTERM" nodename (represents a connection to a block)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First four characters "BLKT".
< "BUSTERM" nodename (represents a connection to a bus)
NETELEMENT_ID ID
First two characters "BT".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "DANGLER" nodename (represents a dangling wire)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
< "TERM" nodename (represents a pin in a SCH symbol)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override