KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
25
26#include <base_units.h>
27#include <macros.h>
29#include <progress_reporter.h>
30#include <wx/log.h>
31#include <wx/translation.h>
32
33
35{
37 m_progressReporter->BeginPhase( 0 ); // Read file
38
39 m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
40
42 {
43 m_progressReporter->BeginPhase( 1 ); // Parse File
44
45 std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
46 wxT( "SCHEMATIC" ) };
47
48 long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
49 m_progressReporter->SetMaxProgress( numOfSteps );
50 }
51
52 m_context.CheckPointCallback = [&](){ checkPoint(); };
53
54 XNODE* cNode = m_rootNode->GetChildren();
55
56 if( !cNode )
57 THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARSCM" ) );
58
59 for( ; cNode; cNode = cNode->GetNext() )
60 {
61 if( cNode->GetName() == wxT( "HEADER" ) )
62 {
63 Header.Parse( cNode, &m_context );
64
65 switch( Header.Resolution )
66 {
68 KiCadUnitDivider = (long) 1e5 / (long) SCH_IU_PER_MM;
69 break;
70
71 default:
72 wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
73 break;
74 }
75 }
76 else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
77 {
78 Assignments.Parse( cNode, &m_context );
79 }
80 else if( cNode->GetName() == wxT( "LIBRARY" ) )
81 {
82 Library.Parse( cNode, &m_context );
83 }
84 else if( cNode->GetName() == wxT( "DEFAULTS" ) )
85 {
86 // No design information here (no need to parse)
87 // Only contains CADSTAR configuration data such as default shapes, text and units
88 // In future some of this could be converted to KiCad but limited value
89 }
90 else if( cNode->GetName() == wxT( "PARTS" ) )
91 {
92 Parts.Parse( cNode, &m_context );
93 }
94 else if( cNode->GetName() == wxT( "SHEETS" ) )
95 {
96 Sheets.Parse( cNode, &m_context );
97 }
98 else if( cNode->GetName() == wxT( "SCHEMATIC" ) )
99 {
100 Schematic.Parse( cNode, &m_context );
101 }
102 else if( cNode->GetName() == wxT( "DISPLAY" ) )
103 {
104 // For now only interested in Attribute visibilities, in order to set field visibilities
105 // in the imported design
106 XNODE* subNode = cNode->GetChildren();
107
108 for( ; subNode; subNode = subNode->GetNext() )
109 {
110 if( subNode->GetName() == wxT( "ATTRCOLORS" ) )
111 {
112 AttrColors.Parse( subNode, &m_context );
113 }
114 else if( subNode->GetName() == wxT( "SCMITEMCOLORS" ) )
115 {
116 XNODE* sub2Node = subNode->GetChildren();
117
118 for( ; sub2Node; sub2Node = sub2Node->GetNext() )
119 {
120 if( sub2Node->GetName() == wxT( "SYMCOL" ) )
121 {
122 XNODE* sub3Node = sub2Node->GetChildren();
123
124 for( ; sub3Node; sub3Node = sub3Node->GetNext() )
125 {
126 if( sub3Node->GetName() == wxT( "PARTNAMECOL" ) )
127 SymbolPartNameColor.Parse( sub3Node, &m_context );
128 }
129 }
130 }
131 }
132 else
133 {
134 // No design information here
135 // Contains CADSTAR Display settings such as layer/element colours and visibility.
136 // In the future these settings could be converted to KiCad
137 }
138 }
139
140 }
141 else
142 {
143 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) );
144 }
145
146 checkPoint();
147 }
148
149 delete m_rootNode;
150 m_rootNode = nullptr;
151}
152
153
155 const wxString& aShapeStr )
156{
157 if( aShapeStr == wxT( "ANNULUS" ) )
159 else if( aShapeStr == wxT( "BOX" ) )
161 else if( aShapeStr == wxT( "BULLET" ) )
163 else if( aShapeStr == wxT( "ROUND" ) )
165 else if( aShapeStr == wxT( "CROSS" ) )
167 else if( aShapeStr == wxT( "DIAMOND" ) )
169 else if( aShapeStr == wxT( "FINGER" ) )
171 else if( aShapeStr == wxT( "OCTAGON" ) )
173 else if( aShapeStr == wxT( "PLUS" ) )
175 else if( aShapeStr == wxT( "POINTER" ) )
177 else if( aShapeStr == wxT( "RECTANGLE" ) )
179 else if( aShapeStr == wxT( "ROUNDED" ) )
181 else if( aShapeStr == wxT( "SQUARE" ) )
183 else if( aShapeStr == wxT( "STAR" ) )
185 else if( aShapeStr == wxT( "TRIANGLE" ) )
187 else
189}
190
191
196
197
199{
200 wxCHECK( IsTermShape( aNode ), );
201
202 ShapeType = ParseTermShapeType( aNode->GetName() );
203 Size = GetXmlAttributeIDLong( aNode, 0 );
204
205 switch( ShapeType )
206 {
213 break;
214
218
224 RightLength = GetXmlAttributeIDLong( aNode, 2, false ); // Optional
225 LeftLength = GetXmlAttributeIDLong( aNode, 1 );
226 break;
227
232 //don't do anything
233 break;
234
236 wxASSERT_MSG( false, "Unknown terminal shape type" );
237 break;
238 }
239
240 if( aNode->GetChildren() )
241 {
242 if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
243 {
245 }
246 else
247 {
248 WARN_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
249 }
250
251 CheckNoNextNodes( aNode->GetChildren() );
252 }
253}
254
255
257{
258 wxCHECK( aNode->GetName() == wxT( "TERMINALCODE" ), );
259
260 ID = GetXmlAttributeIDString( aNode, 0 );
261 Name = GetXmlAttributeIDString( aNode, 1 );
262
263 XNODE* cNode = aNode->GetChildren();
264 wxString location = wxString::Format( "TERMINALCODE -> %s", Name );
265
266 for( ; cNode; cNode = cNode->GetNext() )
267 {
268 wxString cNodeName = cNode->GetName();
269
270 if( TERMINAL_SHAPE::IsTermShape( cNode ) )
271 Shape.Parse( cNode, aContext );
272 else if( cNodeName == wxT( "FILLED" ) )
273 Filled = true;
274 else
276 }
277}
278
279
281{
282 wxCHECK( aNode->GetName() == wxT( "CODEDEFS" ), );
283
284 XNODE* cNode = aNode->GetChildren();
285
286 for( ; cNode; cNode = cNode->GetNext() )
287 {
288 wxString nodeName = cNode->GetName();
289
290 if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
291 {
292 continue;
293 }
294 else if( nodeName == wxT( "TERMINALCODE" ) )
295 {
296 TERMINALCODE termcode;
297 termcode.Parse( cNode, aContext );
298 TerminalCodes.insert( std::make_pair( termcode.ID, termcode ) );
299 }
300 else
301 {
302 WARN_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
303 }
304 }
305}
306
307
309{
310 wxCHECK( aNode->GetName() == wxT( "ASSIGNMENTS" ), );
311
312 XNODE* cNode = aNode->GetChildren();
313 bool settingsParsed = false;
314
315 for( ; cNode; cNode = cNode->GetNext() )
316 {
317 if( cNode->GetName() == wxT( "CODEDEFS" ) )
318 {
319 Codedefs.Parse( cNode, aContext );
320 }
321 else if( cNode->GetName() == wxT( "SETTINGS" ) )
322 {
323 settingsParsed = true;
324 Settings.Parse( cNode, aContext );
325 }
326 else if( cNode->GetName() == wxT( "GRIDS" ) )
327 {
328 Grids.Parse( cNode, aContext );
329 }
330 else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
331 {
333 }
334 else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
335 {
337 }
338 else
339 {
340 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
341 }
342 }
343
344 if( !settingsParsed )
345 THROW_MISSING_NODE_IO_ERROR( wxT( "SETTINGS" ), wxT( "ASSIGNMENTS" ) );
346}
347
348
350{
351 wxCHECK( aNode->GetName() == wxT( "TERMINAL" ), );
352
353 ID = GetXmlAttributeIDLong( aNode, 0 );
355
356 XNODE* cNode = aNode->GetChildren();
357 wxString location = wxString::Format( "TERMINAL %ld", ID );
358
359 if( !cNode )
361
362 for( ; cNode; cNode = cNode->GetNext() )
363 {
364 wxString cNodeName = cNode->GetName();
365
366 if( cNodeName == wxT( "ORIENT" ) )
368 else if( cNodeName == wxT( "PT" ) )
369 Position.Parse( cNode, aContext );
370 else
372 }
373}
374
375
377{
378 wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
379 || aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
380
381 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
383
384 //Parse child nodes
385 XNODE* cNode = aNode->GetChildren();
386
387 for( ; cNode; cNode = cNode->GetNext() )
388 {
389 if( ParseSubNode( cNode, aContext ) )
390 continue;
391 else
392 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
393 }
394
396 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
397}
398
399
401{
402 wxCHECK( aNode->GetName() == wxT( "SYMDEF" ), );
403
404 ParseIdentifiers( aNode, aContext );
405
406 XNODE* cNode = aNode->GetChildren();
407
408 for( ; cNode; cNode = cNode->GetNext() )
409 {
410 wxString cNodeName = cNode->GetName();
411
412 if( ParseSubNode( cNode, aContext ) )
413 {
414 continue;
415 }
416 else if( cNodeName == wxT( "TERMINAL" ) )
417 {
418 TERMINAL term;
419 term.Parse( cNode, aContext );
420 Terminals.insert( std::make_pair( term.ID, term ) );
421 }
422 else if( cNodeName == wxT( "PINLABELLOC" ) )
423 {
425 loc.Parse( cNode, aContext );
426 PinLabelLocations.insert( std::make_pair( loc.TerminalID, loc ) );
427 }
428 else if( cNodeName == wxT( "PINNUMNAMELOC" ) )
429 {
431 loc.Parse( cNode, aContext );
432 PinNumberLocations.insert( std::make_pair( loc.TerminalID, loc ) );
433 }
434 else
435 {
436 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
437 }
438 }
439
440 if( !Stub && ( Origin.x == UNDEFINED_VALUE || Origin.y == UNDEFINED_VALUE ) )
441 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
442}
443
444
446{
447 wxCHECK( aNode->GetName() == wxT( "LIBRARY" ), );
448
449 XNODE* cNode = aNode->GetChildren();
450
451 for( ; cNode; cNode = cNode->GetNext() )
452 {
453 wxString cNodeName = cNode->GetName();
454
455 if( cNodeName == wxT( "SYMDEF" ) )
456 {
457 SYMDEF_SCM symdef;
458 symdef.Parse( cNode, aContext );
459 SymbolDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
460 }
461 else if( cNodeName == wxT( "HIERARCHY" ) )
462 {
463 // Ignore for now
464 //
465 // This node doesn't have any equivalent in KiCad so for now we ignore it. In
466 // future, we could parse it in detail, to obtain the tree-structure of
467 // symbols in a cadstar library
468 }
469 else
470 {
471 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
472 }
473
474 aContext->CheckPointCallback();
475 }
476}
477
478
480{
481 wxCHECK( aNode->GetName() == wxT( "SHEETS" ), );
482
483 XNODE* cNode = aNode->GetChildren();
484
485 for( ; cNode; cNode = cNode->GetNext() )
486 {
487 if( cNode->GetName() == wxT( "SHEET" ) )
488 {
489 LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
491 SheetNames.insert( std::make_pair( id, name ) );
492 SheetOrder.push_back( id );
493 }
494 else
495 {
496 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
497 }
498 }
499}
500
501
503{
504 wxCHECK( aNode->GetName() == wxT( "COMP" ), );
505
507
508 XNODE* cNode = aNode->GetChildren();
509
510 for( ; cNode; cNode = cNode->GetNext() )
511 {
512 if( cNode->GetName() == wxT( "READONLY" ) )
513 {
514 ReadOnly = true;
515 }
516 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
517 {
518 AttrLoc.Parse( cNode, aContext );
519 HasLocation = true;
520 }
521 else
522 {
523 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
524 }
525 }
526}
527
528
530{
531 wxCHECK( aNode->GetName() == wxT( "PARTREF" ), );
532
533 RefID = GetXmlAttributeIDString( aNode, 0 );
534
535 XNODE* cNode = aNode->GetChildren();
536
537 for( ; cNode; cNode = cNode->GetNext() )
538 {
539 if( cNode->GetName() == wxT( "READONLY" ) )
540 {
541 ReadOnly = true;
542 }
543 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
544 {
545 AttrLoc.Parse( cNode, aContext );
546 HasLocation = true;
547 }
548 else
549 {
550 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
551 }
552 }
553}
554
555
557{
558 wxCHECK( aNode->GetName() == wxT( "TERMATTR" ), /* void */ );
559
560 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
561
562 XNODE* cNode = aNode->GetChildren();
563
564 for( ; cNode; cNode = cNode->GetNext() )
565 {
566 if( cNode->GetName() == wxT( "ATTR" ) )
567 {
568 ATTRIBUTE_VALUE val;
569 val.Parse( cNode, aContext );
570 Attributes.push_back( val );
571 }
572 else
573 {
574 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
575 }
576 }
577}
578
579
581{
582 wxCHECK( aNode->GetName() == wxT( "SYMPINNAME" ) || aNode->GetName() == wxT( "SYMPINLABEL" ), );
583
584 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
586
587 XNODE* cNode = aNode->GetChildren();
588
589 for( ; cNode; cNode = cNode->GetNext() )
590 {
591 if( cNode->GetName() == wxT( "ATTRLOC" ) )
592 {
593 AttrLoc.Parse( cNode, aContext );
594 HasLocation = true;
595 }
596 else
597 {
598 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
599 }
600 }
601}
602
603
605{
606 wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
607
608 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
609 PinNum = GetXmlAttributeIDLong( aNode, 1 );
610
611 XNODE* cNode = aNode->GetChildren();
612
613 for( ; cNode; cNode = cNode->GetNext() )
614 {
615 if( cNode->GetName() == wxT( "ATTRLOC" ) )
616 {
617 AttrLoc.Parse( cNode, aContext );
618 HasLocation = true;
619 }
620 else
621 {
622 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
623 }
624 }
625}
626
627
629{
630 wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
631
632 XNODE* cNode = aNode->GetChildren();
633
634 for( ; cNode; cNode = cNode->GetNext() )
635 {
636 wxString cNodeName = cNode->GetName();
637
638 if( cNodeName == wxT( "SIGNALREF" ) )
639 {
640 Type = TYPE::SIGNALREF;
641 CheckNoNextNodes( cNode );
642 }
643 else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
644 {
645 Type = TYPE::GLOBALSIGNAL;
647 }
648 else if( cNodeName == wxT( "TESTPOINT" ) )
649 {
650 Type = TYPE::TESTPOINT;
651 CheckNoNextNodes( cNode );
652 }
653 else
654 {
655 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
656 }
657 }
658}
659
660
662{
663 wxCHECK( aNode->GetName() == wxT( "SIGNALREFERENCELINK" ), );
664
666 LayerID = GetXmlAttributeIDString( aNode, 2 );
667
668 //Parse child nodes
669 XNODE* cNode = aNode->GetChildren();
670
671 for( ; cNode; cNode = cNode->GetNext() )
672 {
673 if( ParseSubNode( cNode, aContext ) )
674 continue;
675 else if( cNode->GetName() == wxT( "SIGREFTEXT" ) )
676 Text = GetXmlAttributeIDString( aNode, 0 );
677 else
678 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
679 }
680
682 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
683}
684
685
687{
688 wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
689
690 ID = GetXmlAttributeIDString( aNode, 0 );
691 SymdefID = GetXmlAttributeIDString( aNode, 1 );
692 LayerID = GetXmlAttributeIDString( aNode, 2 );
693
694 XNODE* cNode = aNode->GetChildren();
695 bool originParsed = false;
696 wxString location = wxString::Format( "SYMBOL -> %s", ID );
697
698 for( ; cNode; cNode = cNode->GetNext() )
699 {
700 wxString cNodeName = cNode->GetName();
701
702 if( !originParsed && cNodeName == wxT( "PT" ) )
703 {
704 Origin.Parse( cNode, aContext );
705 originParsed = true;
706 }
707 else if( cNodeName == wxT( "COMP" ) )
708 {
709 ComponentRef.Parse( cNode, aContext );
710 IsComponent = true;
711 }
712 else if( cNodeName == wxT( "PARTREF" ) )
713 {
714 PartRef.Parse( cNode, aContext );
715 HasPartRef = true;
716 }
717 else if( cNodeName == wxT( "PARTNAMENOTVISIBLE" ) )
718 {
719 PartNameVisible = false;
720 }
721 else if( cNodeName == wxT( "VSYMMASTER" ) )
722 {
725 }
726 else if( cNodeName == wxT( "GROUPREF" ) )
727 {
728 GroupID = GetXmlAttributeIDString( cNode, 0 );
729 }
730 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
731 {
732 ReuseBlockRef.Parse( cNode, aContext );
733 }
734 else if( cNodeName == wxT( "SIGNALREFERENCELINK" ) )
735 {
736 SigRefLink.Parse( cNode, aContext );
737 }
738 else if( cNodeName == wxT( "ORIENT" ) )
739 {
741 }
742 else if( cNodeName == wxT( "MIRROR" ) )
743 {
744 Mirror = true;
745 }
746 else if( cNodeName == wxT( "FIX" ) )
747 {
748 Fixed = true;
749 }
750 else if( cNodeName == wxT( "SCALE" ) )
751 {
754 }
755 else if( cNodeName == wxT( "READABILITY" ) )
756 {
757 Readability = ParseReadability( cNode );
758 }
759 else if( cNodeName == wxT( "GATE" ) )
760 {
761 GateID = GetXmlAttributeIDString( cNode, 0 );
762 }
763 else if( cNodeName == wxT( "SYMBOLVARIANT" ) )
764 {
765 IsSymbolVariant = true;
766 SymbolVariant.Parse( cNode, aContext );
767 }
768 else if( cNodeName == wxT( "TERMATTR" ) )
769 {
770 TERMATTR termattr;
771 termattr.Parse( cNode, aContext );
772 TerminalAttributes.insert( std::make_pair( termattr.TerminalID, termattr ) );
773 }
774 else if( cNodeName == wxT( "SYMPINLABEL" ) )
775 {
776 SYMPINNAME_LABEL sympinname;
777 sympinname.Parse( cNode, aContext );
778 PinLabels.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
779 }
780 else if( cNodeName == wxT( "SYMPINNAME" ) )
781 {
782 SYMPINNAME_LABEL sympinname;
783 sympinname.Parse( cNode, aContext );
784 PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
785 }
786 else if( cNodeName == wxT( "PINNUM" ) )
787 {
788 PIN_NUM pinNum;
789 pinNum.Parse( cNode, aContext );
790 PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
791 }
792 else if( cNodeName == wxT( "ATTR" ) )
793 {
794 ATTRIBUTE_VALUE attrVal;
795 attrVal.Parse( cNode, aContext );
796 AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
797 }
798 else
799 {
801 }
802 }
803
804 if( !originParsed )
805 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
806}
807
808
810{
811 wxCHECK( aNode->GetName() == wxT( "SIGLOC" ), );
812
814
815 //Parse child nodes
816 XNODE* cNode = aNode->GetChildren();
817
818 for( ; cNode; cNode = cNode->GetNext() )
819 {
820 if( ParseSubNode( cNode, aContext ) )
821 continue;
822 else
823 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
824 }
825
827 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
828}
829
830
832{
833 wxCHECK( aNode->GetName() == wxT( "BUS" ), );
834
835 ID = GetXmlAttributeIDString( aNode, 0 );
837 LayerID = GetXmlAttributeIDString( aNode, 2 );
838
839 XNODE* cNode = aNode->GetChildren();
840
841 for( ; cNode; cNode = cNode->GetNext() )
842 {
843 wxString cNodeName = cNode->GetName();
844
845 if( SHAPE::IsShape( cNode ) )
846 {
847 Shape.Parse( cNode, aContext );
848 }
849 else if( cNodeName == wxT( "BUSNAME" ) )
850 {
851 Name = GetXmlAttributeIDString( cNode, 0 );
852
853 XNODE* subNode = cNode->GetChildren();
854
855 if( subNode )
856 {
857 if( subNode->GetName() == wxT( "SIGLOC" ) )
858 {
859 BusLabel.Parse( subNode, aContext );
860 HasBusLabel = true;
861 }
862 else
863 {
864 WARN_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
865 }
866 }
867 }
868 else
869 {
870 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
871 }
872 }
873}
874
875
877{
878 wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
879
880 ID = GetXmlAttributeIDString( aNode, 0 );
881 LayerID = GetXmlAttributeIDString( aNode, 2 );
882
883 XNODE* cNode = aNode->GetChildren();
884
885 for( ; cNode; cNode = cNode->GetNext() )
886 {
887 wxString cNodeName = cNode->GetName();
888
889 if( cNodeName == wxT( "CLONE" ) )
890 {
891 Type = TYPE::CLONE;
892 }
893 else if( cNodeName == wxT( "PARENT" ) )
894 {
895 Type = TYPE::PARENT;
897 }
898 else if( cNodeName == wxT( "CHILD" ) )
899 {
900 Type = TYPE::CHILD;
902 }
903 else if( cNodeName == wxT( "BLOCKNAME" ) )
904 {
905 Name = GetXmlAttributeIDString( cNode, 0 );
906 XNODE* subNode = cNode->GetChildren();
907
908 if( subNode )
909 {
910 if( subNode->GetName() == wxT( "ATTRLOC" ) )
911 {
912 BlockLabel.Parse( subNode, aContext );
913 HasBlockLabel = true;
914 }
915 else
916 {
917 WARN_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
918 }
919 }
920 }
921 else if( cNodeName == wxT( "TERMINAL" ) )
922 {
923 TERMINAL term;
924 term.Parse( cNode, aContext );
925 Terminals.insert( std::make_pair( term.ID, term ) );
926 }
927 else if( cNodeName == wxT( "FIGURE" ) )
928 {
929 FIGURE figure;
930 figure.Parse( cNode, aContext );
931 Figures.insert( std::make_pair( figure.ID, figure ) );
932 }
933 else
934 {
935 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
936 }
937 }
938}
939
940
942{
943 wxASSERT( aNode->GetName() == wxT( "TERM" ) );
944
945 ID = GetXmlAttributeIDString( aNode, 0 );
946 SymbolID = GetXmlAttributeIDString( aNode, 1 );
947 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
948
949
950 XNODE* cNode = aNode->GetChildren();
951
952 for( ; cNode; cNode = cNode->GetNext() )
953 {
954 wxString cNodeName = cNode->GetName();
955
956 if( cNodeName == wxT( "SIGLOC" ) )
957 {
958 NetLabel.Parse( cNode, aContext );
959 HasNetLabel = true;
960 }
961 else
962 {
963 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
964 }
965 }
966}
967
968
970{
971 wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
972
973 ID = GetXmlAttributeIDString( aNode, 0 );
974 BusID = GetXmlAttributeIDString( aNode, 1 );
975
976
977 XNODE* cNode = aNode->GetChildren();
978 bool firstPointParsed = false;
979 bool secondPointParsed = false;
980
981 for( ; cNode; cNode = cNode->GetNext() )
982 {
983 wxString cNodeName = cNode->GetName();
984
985 if( cNodeName == wxT( "SIGLOC" ) )
986 {
987 NetLabel.Parse( cNode, aContext );
988 HasNetLabel = true;
989 }
990 else if( cNodeName == wxT( "PT" ) )
991 {
992 if( !firstPointParsed )
993 {
994 FirstPoint.Parse( cNode, aContext );
995 firstPointParsed = true;
996 }
997 else if( !secondPointParsed )
998 {
999 SecondPoint.Parse( cNode, aContext );
1000 secondPointParsed = true;
1001 }
1002 else
1003 {
1004 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1005 }
1006 }
1007 else
1008 {
1009 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1010 }
1011 }
1012
1013 if( !firstPointParsed || !secondPointParsed )
1014 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1015}
1016
1017
1019{
1020 wxASSERT( aNode->GetName() == wxT( "BLOCKTERM" ) );
1021
1022 ID = GetXmlAttributeIDString( aNode, 0 );
1023 BlockID = GetXmlAttributeIDString( aNode, 1 );
1024 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
1025
1026 XNODE* cNode = aNode->GetChildren();
1027
1028 for( ; cNode; cNode = cNode->GetNext() )
1029 {
1030 wxString cNodeName = cNode->GetName();
1031
1032 if( cNodeName == wxT( "SIGLOC" ) )
1033 {
1034 NetLabel.Parse( cNode, aContext );
1035 HasNetLabel = true;
1036 }
1037 else
1038 {
1039 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1040 }
1041 }
1042}
1043
1044
1046{
1047 ParseIdentifiers( aNode, aContext );
1048 LayerID = GetXmlAttributeIDString( aNode, 3 );
1049
1050 XNODE* cNode = aNode->GetChildren();
1051
1052 for( ; cNode; cNode = cNode->GetNext() )
1053 {
1054 wxString cNodeName = cNode->GetName();
1055
1056 if( ParseSubNode( cNode, aContext ) )
1057 {
1058 continue;
1059 }
1060 else if( cNodeName == wxT( "PATH" ) )
1061 {
1062 Path = ParseAllChildVertices( cNode, aContext, true );
1063 }
1064 else if( cNodeName == wxT( "GROUPREF" ) )
1065 {
1066 GroupID = GetXmlAttributeIDString( cNode, 0 );
1067 }
1068 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1069 {
1070 ReuseBlockRef.Parse( cNode, aContext );
1071 }
1072 else if( cNodeName == wxT( "CONLINECODE" ) )
1073 {
1075 }
1076 else
1077 {
1078 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
1079 }
1080 }
1081}
1082
1083
1085{
1086 ParseIdentifiers( aNode, aContext );
1087
1088 //Parse child nodes
1089 XNODE* cNode = aNode->GetChildren();
1090
1091 for( ; cNode; cNode = cNode->GetNext() )
1092 {
1093 wxString cNodeName = cNode->GetName();
1094
1095 if( cNodeName == wxT( "JPT" ) )
1096 {
1097 JUNCTION_SCH jpt;
1098 jpt.Parse( cNode, aContext );
1099 Junctions.insert( std::make_pair( jpt.ID, jpt ) );
1100 }
1101 else if( ParseSubNode( cNode, aContext ) )
1102 {
1103 continue;
1104 }
1105 else if( cNodeName == wxT( "TERM" ) )
1106 {
1107 SYM_TERM pin;
1108 pin.Parse( cNode, aContext );
1109 Terminals.insert( std::make_pair( pin.ID, pin ) );
1110 }
1111 else if( cNodeName == wxT( "BUSTERM" ) )
1112 {
1113 BUS_TERM bt;
1114 bt.Parse( cNode, aContext );
1115 BusTerminals.insert( std::make_pair( bt.ID, bt ) );
1116 }
1117 else if( cNodeName == wxT( "BLOCKTERM" ) )
1118 {
1119 BLOCK_TERM bt;
1120 bt.Parse( cNode, aContext );
1121 BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
1122 }
1123 else if( cNodeName == wxT( "DANGLER" ) )
1124 {
1125 DANGLER dang;
1126 dang.Parse( cNode, aContext );
1127 Danglers.insert( std::make_pair( dang.ID, dang ) );
1128 }
1129 else if( cNodeName == wxT( "CONN" ) )
1130 {
1131 CONNECTION_SCH conn;
1132 conn.Parse( cNode, aContext );
1133 Connections.push_back( conn );
1134 }
1135 else
1136 {
1137 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
1138 }
1139 }
1140}
1141
1142
1144{
1145 wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
1146
1147 XNODE* cNode = aNode->GetChildren();
1148
1149 for( ; cNode; cNode = cNode->GetNext() )
1150 {
1151 wxString cNodeName = cNode->GetName();
1152
1153 if( cNodeName == wxT( "GROUP" ) )
1154 {
1155 GROUP group;
1156 group.Parse( cNode, aContext );
1157 Groups.insert( std::make_pair( group.ID, group ) );
1158 }
1159 else if( cNodeName == wxT( "REUSEBLOCK" ) )
1160 {
1161 REUSEBLOCK reuseblock;
1162 reuseblock.Parse( cNode, aContext );
1163 ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
1164 }
1165 else if( cNodeName == wxT( "FIGURE" ) )
1166 {
1167 FIGURE figure;
1168 figure.Parse( cNode, aContext );
1169 Figures.insert( std::make_pair( figure.ID, figure ) );
1170 }
1171 else if( cNodeName == wxT( "SYMBOL" ) )
1172 {
1173 SYMBOL sym;
1174 sym.Parse( cNode, aContext );
1175 Symbols.insert( std::make_pair( sym.ID, sym ) );
1176 }
1177 else if( cNodeName == wxT( "BUS" ) )
1178 {
1179 BUS bus;
1180 bus.Parse( cNode, aContext );
1181 Buses.insert( std::make_pair( bus.ID, bus ) );
1182 }
1183 else if( cNodeName == wxT( "BLOCK" ) )
1184 {
1185 BLOCK block;
1186 block.Parse( cNode, aContext );
1187 Blocks.insert( std::make_pair( block.ID, block ) );
1188 }
1189 else if( cNodeName == wxT( "NET" ) )
1190 {
1191 NET_SCH net;
1192 net.Parse( cNode, aContext );
1193 Nets.insert( std::make_pair( net.ID, net ) );
1194 }
1195 else if( cNodeName == wxT( "TEXT" ) )
1196 {
1197 TEXT txt;
1198 txt.Parse( cNode, aContext );
1199 Texts.insert( std::make_pair( txt.ID, txt ) );
1200 }
1201 else if( cNodeName == wxT( "DOCSYMBOL" ) )
1202 {
1203 DOCUMENTATION_SYMBOL docsym;
1204 docsym.Parse( cNode, aContext );
1205 DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
1206 }
1207 else if( cNodeName == wxT( "VHIERARCHY" ) )
1208 {
1209 VariantHierarchy.Parse( cNode, aContext );
1210 }
1211 else
1212 {
1213 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1214 }
1215
1216 aContext->CheckPointCallback();
1217 }
1218}
1219
1220
1222{
1223 ParseIdentifiers( aNode, aContext );
1224
1226 LayerID = GetXmlAttributeIDString( aNode, 2 );
1227
1228 XNODE* cNode = aNode->GetChildren();
1229
1230 for( ; cNode; cNode = cNode->GetNext() )
1231 {
1232 if( ParseSubNode( cNode, aContext ) )
1233 {
1234 continue;
1235 }
1236 else if( cNode->GetName() == wxT( "SIGLOC" ) )
1237 {
1238 NetLabel.Parse( cNode, aContext );
1239 HasNetLabel = true;
1240 }
1241 else
1242 {
1243 WARN_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1244 }
1245 }
1246
1247}
1248
1249
1251{
1252 wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
1253
1254 ID = GetXmlAttributeIDString( aNode, 0 );
1256 LayerID = GetXmlAttributeIDString( aNode, 2 );
1257
1258 XNODE* cNode = aNode->GetChildren();
1259 bool positionParsed = false;
1260
1261 for( ; cNode; cNode = cNode->GetNext() )
1262 {
1263 wxString cNodeName = cNode->GetName();
1264
1265 if( cNodeName == wxT( "SIGLOC" ) )
1266 {
1267 NetLabel.Parse( cNode, aContext );
1268 HasNetLabel = true;
1269 }
1270 else if( !positionParsed && cNodeName == wxT( "PT" ) )
1271 {
1272 Position.Parse( cNode, aContext );
1273 positionParsed = true;
1274 }
1275 else
1276 {
1277 WARN_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1278 }
1279 }
1280}
const char * name
constexpr double SCH_IU_PER_MM
Schematic internal units 1=100nm.
Definition base_units.h:70
#define WARN_UNKNOWN_NODE_IO_ERROR(nodename, location)
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
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 std::vector< VERTEX > ParseAllChildVertices(XNODE *aNode, PARSER_CONTEXT *aContext, bool aTestAllChildNodes=false)
If no children are present, it just returns an empty vector (without throwing an exception).
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void checkPoint()
Updates m_progressReporter or throws if user canceled.
static READABILITY ParseReadability(XNODE *aNode)
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)
An extension of wxXmlNode that can format its contents as KiCad-style s-expressions.
Definition xnode.h:67
XNODE * GetChildren() const
Definition xnode.h:97
XNODE * GetNext() const
Definition xnode.h:102
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:79
static wxString nodeName(const wxString &aSymbolPin)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
NETELEMENT_ID ID
First character is "J".
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
std::function< void()> CheckPointCallback
Callback function to report progress.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
POINT Origin
Origin of the component (this is used as the reference point when placing the component in the design...
bool ParseSubNode(XNODE *aChildNode, PARSER_CONTEXT *aContext)
bool Stub
When the CADSTAR Archive file is exported without the component library, if components on the board a...
void ParseIdentifiers(XNODE *aNode, PARSER_CONTEXT *aContext)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
TYPE Type
Determines what the associated layer is, whether parent, child or clone.
LAYER_ID LayerID
The sheet block is on (TODO: verify this is true)
LAYER_ID AssocLayerID
Parent or Child linked sheet.
std::map< TERMINAL_ID, TERMINAL > Terminals
LAYER_ID LayerID
Sheet on which bus is located.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< REUSEBLOCK_ID, REUSEBLOCK > ReuseBlocks
std::map< DOCUMENTATION_SYMBOL_ID, DOCUMENTATION_SYMBOL > DocumentationSymbols
std::map< TERMINALCODE_ID, TERMINALCODE > TerminalCodes
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< SYMDEF_ID, SYMDEF_SCM > SymbolDefinitions
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)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
LAYER_ID LayerID
Sheet on which the connection is drawn.
< "DANGLER" nodename (represents a dangling wire)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
TERMINALCODE_ID TerminalCodeID
Usually a circle, but size can be varied.
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
std::map< NETELEMENT_ID, DANGLER > Danglers
std::map< NETELEMENT_ID, SYM_TERM > Terminals
std::map< NETELEMENT_ID, BUS_TERM > BusTerminals
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< NETELEMENT_ID, BLOCK_TERM > BlockTerminals
std::map< NETELEMENT_ID, JUNCTION_SCH > Junctions
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::vector< LAYER_ID > SheetOrder
A vector to also store the order in which sheets are to be displayed.
std::map< LAYER_ID, SHEET_NAME > SheetNames
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
GROUP_ID GroupID
If not empty, this symbol is part of a group.
LAYER_ID LayerID
Sheet on which symbol is located.
std::map< ATTRIBUTE_ID, ATTRIBUTE_VALUE > AttributeValues
GATE_ID GateID
The gate this symbol represents within the associated Part.
long ScaleRatioNumerator
Symbols can be arbitrarily scaled in CADSTAR.
SIGNALREFERENCELINK SigRefLink
Signal References (a special form of global signal) have annotations showing the location of all the ...
std::map< TERMINAL_ID, SYMPINNAME_LABEL > PinNames
Identifier of the pin in the PCB Equivalent to KiCad's Pin Number.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< TERMINAL_ID, SYMPINNAME_LABEL > PinLabels
Equivalent to KiCad's Pin Name.
std::map< TERMINAL_ID, PIN_NUM > PinNumbers
This seems to only appear in older designs and is similar to PinNames but only allowing numerical val...
std::map< TERMINAL_ID, TERMATTR > TerminalAttributes
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
std::map< TERMINAL_ID, PIN_NUM_LABEL_LOC > PinLabelLocations
std::map< TERMINAL_ID, PIN_NUM_LABEL_LOC > PinNumberLocations
std::map< TERMINAL_ID, TERMINAL > Terminals
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
POINT Position
Pad position within the component's coordinate frame.
KIBIS_PIN * pin
VECTOR2I location