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 along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
25
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 );
48 m_progressReporter->SetMaxProgress( numOfSteps );
49 }
50
51 m_context.CheckPointCallback = [&](){ checkPoint(); };
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
195
196
198{
199 wxCHECK( IsTermShape( aNode ), );
200
201 ShapeType = ParseTermShapeType( aNode->GetName() );
202 Size = GetXmlAttributeIDLong( aNode, 0 );
203
204 switch( ShapeType )
205 {
212 break;
213
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 {
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
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 {
332 }
333 else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
334 {
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 );
354
355 XNODE* cNode = aNode->GetChildren();
356 wxString location = wxString::Format( "TERMINAL %ld", ID );
357
358 if( !cNode )
360
361 for( ; cNode; cNode = cNode->GetNext() )
362 {
363 wxString cNodeName = cNode->GetName();
364
365 if( cNodeName == wxT( "ORIENT" ) )
367 else if( cNodeName == wxT( "PT" ) )
368 Position.Parse( cNode, aContext );
369 else
371 }
372}
373
374
376{
377 wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
378 || aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
379
380 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
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
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 if( cNodeName == wxT( "HIERARCHY" ) )
461 {
462 // Ignore for now
463 //
464 // This node doesn't have any equivalent in KiCad so for now we ignore it. In
465 // future, we could parse it in detail, to obtain the tree-structure of
466 // symbols in a cadstar library
467 }
468 else
469 {
470 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
471 }
472
473 aContext->CheckPointCallback();
474 }
475}
476
477
479{
480 wxCHECK( aNode->GetName() == wxT( "SHEETS" ), );
481
482 XNODE* cNode = aNode->GetChildren();
483
484 for( ; cNode; cNode = cNode->GetNext() )
485 {
486 if( cNode->GetName() == wxT( "SHEET" ) )
487 {
488 LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
490 SheetNames.insert( std::make_pair( id, name ) );
491 SheetOrder.push_back( id );
492 }
493 else
494 {
495 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
496 }
497 }
498}
499
500
502{
503 wxCHECK( aNode->GetName() == wxT( "COMP" ), );
504
506
507 XNODE* cNode = aNode->GetChildren();
508
509 for( ; cNode; cNode = cNode->GetNext() )
510 {
511 if( cNode->GetName() == wxT( "READONLY" ) )
512 {
513 ReadOnly = true;
514 }
515 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
516 {
517 AttrLoc.Parse( cNode, aContext );
518 HasLocation = true;
519 }
520 else
521 {
522 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
523 }
524 }
525}
526
527
529{
530 wxCHECK( aNode->GetName() == wxT( "PARTREF" ), );
531
532 RefID = GetXmlAttributeIDString( aNode, 0 );
533
534 XNODE* cNode = aNode->GetChildren();
535
536 for( ; cNode; cNode = cNode->GetNext() )
537 {
538 if( cNode->GetName() == wxT( "READONLY" ) )
539 {
540 ReadOnly = true;
541 }
542 else if( cNode->GetName() == wxT( "ATTRLOC" ) )
543 {
544 AttrLoc.Parse( cNode, aContext );
545 HasLocation = true;
546 }
547 else
548 {
549 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
550 }
551 }
552}
553
554
556{
557 wxCHECK( aNode->GetName() == wxT( "TERMATTR" ), /* void */ );
558
559 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
560
561 XNODE* cNode = aNode->GetChildren();
562
563 for( ; cNode; cNode = cNode->GetNext() )
564 {
565 if( cNode->GetName() == wxT( "ATTR" ) )
566 {
567 ATTRIBUTE_VALUE val;
568 val.Parse( cNode, aContext );
569 Attributes.push_back( val );
570 }
571 else
572 {
573 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
574 }
575 }
576}
577
578
580{
581 wxCHECK( aNode->GetName() == wxT( "SYMPINNAME" ) || aNode->GetName() == wxT( "SYMPINLABEL" ), );
582
583 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
585
586 XNODE* cNode = aNode->GetChildren();
587
588 for( ; cNode; cNode = cNode->GetNext() )
589 {
590 if( cNode->GetName() == wxT( "ATTRLOC" ) )
591 {
592 AttrLoc.Parse( cNode, aContext );
593 HasLocation = true;
594 }
595 else
596 {
597 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
598 }
599 }
600}
601
602
604{
605 wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
606
607 TerminalID = GetXmlAttributeIDLong( aNode, 0 );
608 PinNum = GetXmlAttributeIDLong( aNode, 1 );
609
610 XNODE* cNode = aNode->GetChildren();
611
612 for( ; cNode; cNode = cNode->GetNext() )
613 {
614 if( cNode->GetName() == wxT( "ATTRLOC" ) )
615 {
616 AttrLoc.Parse( cNode, aContext );
617 HasLocation = true;
618 }
619 else
620 {
621 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
622 }
623 }
624}
625
626
628{
629 wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
630
631 XNODE* cNode = aNode->GetChildren();
632
633 for( ; cNode; cNode = cNode->GetNext() )
634 {
635 wxString cNodeName = cNode->GetName();
636
637 if( cNodeName == wxT( "SIGNALREF" ) )
638 {
639 Type = TYPE::SIGNALREF;
640 CheckNoNextNodes( cNode );
641 }
642 else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
643 {
644 Type = TYPE::GLOBALSIGNAL;
646 }
647 else if( cNodeName == wxT( "TESTPOINT" ) )
648 {
649 Type = TYPE::TESTPOINT;
650 CheckNoNextNodes( cNode );
651 }
652 else
653 {
654 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
655 }
656 }
657}
658
659
661{
662 wxCHECK( aNode->GetName() == wxT( "SIGNALREFERENCELINK" ), );
663
665 LayerID = GetXmlAttributeIDString( aNode, 2 );
666
667 //Parse child nodes
668 XNODE* cNode = aNode->GetChildren();
669
670 for( ; cNode; cNode = cNode->GetNext() )
671 {
672 if( ParseSubNode( cNode, aContext ) )
673 continue;
674 else if( cNode->GetName() == wxT( "SIGREFTEXT" ) )
675 Text = GetXmlAttributeIDString( aNode, 0 );
676 else
677 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
678 }
679
681 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
682}
683
684
686{
687 wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
688
689 ID = GetXmlAttributeIDString( aNode, 0 );
690 SymdefID = GetXmlAttributeIDString( aNode, 1 );
691 LayerID = GetXmlAttributeIDString( aNode, 2 );
692
693 XNODE* cNode = aNode->GetChildren();
694 bool originParsed = false;
695 wxString location = wxString::Format( "SYMBOL -> %s", ID );
696
697 for( ; cNode; cNode = cNode->GetNext() )
698 {
699 wxString cNodeName = cNode->GetName();
700
701 if( !originParsed && cNodeName == wxT( "PT" ) )
702 {
703 Origin.Parse( cNode, aContext );
704 originParsed = true;
705 }
706 else if( cNodeName == wxT( "COMP" ) )
707 {
708 ComponentRef.Parse( cNode, aContext );
709 IsComponent = true;
710 }
711 else if( cNodeName == wxT( "PARTREF" ) )
712 {
713 PartRef.Parse( cNode, aContext );
714 HasPartRef = true;
715 }
716 else if( cNodeName == wxT( "PARTNAMENOTVISIBLE" ) )
717 {
718 PartNameVisible = false;
719 }
720 else if( cNodeName == wxT( "VSYMMASTER" ) )
721 {
724 }
725 else if( cNodeName == wxT( "GROUPREF" ) )
726 {
727 GroupID = GetXmlAttributeIDString( cNode, 0 );
728 }
729 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
730 {
731 ReuseBlockRef.Parse( cNode, aContext );
732 }
733 else if( cNodeName == wxT( "SIGNALREFERENCELINK" ) )
734 {
735 SigRefLink.Parse( cNode, aContext );
736 }
737 else if( cNodeName == wxT( "ORIENT" ) )
738 {
740 }
741 else if( cNodeName == wxT( "MIRROR" ) )
742 {
743 Mirror = true;
744 }
745 else if( cNodeName == wxT( "FIX" ) )
746 {
747 Fixed = true;
748 }
749 else if( cNodeName == wxT( "SCALE" ) )
750 {
753 }
754 else if( cNodeName == wxT( "READABILITY" ) )
755 {
756 Readability = ParseReadability( cNode );
757 }
758 else if( cNodeName == wxT( "GATE" ) )
759 {
760 GateID = GetXmlAttributeIDString( cNode, 0 );
761 }
762 else if( cNodeName == wxT( "SYMBOLVARIANT" ) )
763 {
764 IsSymbolVariant = true;
765 SymbolVariant.Parse( cNode, aContext );
766 }
767 else if( cNodeName == wxT( "TERMATTR" ) )
768 {
769 TERMATTR termattr;
770 termattr.Parse( cNode, aContext );
771 TerminalAttributes.insert( std::make_pair( termattr.TerminalID, termattr ) );
772 }
773 else if( cNodeName == wxT( "SYMPINLABEL" ) )
774 {
775 SYMPINNAME_LABEL sympinname;
776 sympinname.Parse( cNode, aContext );
777 PinLabels.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
778 }
779 else if( cNodeName == wxT( "SYMPINNAME" ) )
780 {
781 SYMPINNAME_LABEL sympinname;
782 sympinname.Parse( cNode, aContext );
783 PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
784 }
785 else if( cNodeName == wxT( "PINNUM" ) )
786 {
787 PIN_NUM pinNum;
788 pinNum.Parse( cNode, aContext );
789 PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
790 }
791 else if( cNodeName == wxT( "ATTR" ) )
792 {
793 ATTRIBUTE_VALUE attrVal;
794 attrVal.Parse( cNode, aContext );
795 AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
796 }
797 else
798 {
800 }
801 }
802
803 if( !originParsed )
804 THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
805}
806
807
809{
810 wxCHECK( aNode->GetName() == wxT( "SIGLOC" ), );
811
813
814 //Parse child nodes
815 XNODE* cNode = aNode->GetChildren();
816
817 for( ; cNode; cNode = cNode->GetNext() )
818 {
819 if( ParseSubNode( cNode, aContext ) )
820 continue;
821 else
822 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
823 }
824
826 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
827}
828
829
831{
832 wxCHECK( aNode->GetName() == wxT( "BUS" ), );
833
834 ID = GetXmlAttributeIDString( aNode, 0 );
836 LayerID = GetXmlAttributeIDString( aNode, 2 );
837
838 XNODE* cNode = aNode->GetChildren();
839
840 for( ; cNode; cNode = cNode->GetNext() )
841 {
842 wxString cNodeName = cNode->GetName();
843
844 if( SHAPE::IsShape( cNode ) )
845 {
846 Shape.Parse( cNode, aContext );
847 }
848 else if( cNodeName == wxT( "BUSNAME" ) )
849 {
850 Name = GetXmlAttributeIDString( cNode, 0 );
851
852 XNODE* subNode = cNode->GetChildren();
853
854 if( subNode )
855 {
856 if( subNode->GetName() == wxT( "SIGLOC" ) )
857 {
858 BusLabel.Parse( subNode, aContext );
859 HasBusLabel = true;
860 }
861 else
862 {
863 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
864 }
865 }
866 }
867 else
868 {
869 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
870 }
871 }
872}
873
874
876{
877 wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
878
879 ID = GetXmlAttributeIDString( aNode, 0 );
880 LayerID = GetXmlAttributeIDString( aNode, 2 );
881
882 XNODE* cNode = aNode->GetChildren();
883
884 for( ; cNode; cNode = cNode->GetNext() )
885 {
886 wxString cNodeName = cNode->GetName();
887
888 if( cNodeName == wxT( "CLONE" ) )
889 {
890 Type = TYPE::CLONE;
891 }
892 else if( cNodeName == wxT( "PARENT" ) )
893 {
894 Type = TYPE::PARENT;
896 }
897 else if( cNodeName == wxT( "CHILD" ) )
898 {
899 Type = TYPE::CHILD;
901 }
902 else if( cNodeName == wxT( "BLOCKNAME" ) )
903 {
904 Name = GetXmlAttributeIDString( cNode, 0 );
905 XNODE* subNode = cNode->GetChildren();
906
907 if( subNode )
908 {
909 if( subNode->GetName() == wxT( "ATTRLOC" ) )
910 {
911 BlockLabel.Parse( subNode, aContext );
912 HasBlockLabel = true;
913 }
914 else
915 {
916 THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
917 }
918 }
919 }
920 else if( cNodeName == wxT( "TERMINAL" ) )
921 {
922 TERMINAL term;
923 term.Parse( cNode, aContext );
924 Terminals.insert( std::make_pair( term.ID, term ) );
925 }
926 else if( cNodeName == wxT( "FIGURE" ) )
927 {
928 FIGURE figure;
929 figure.Parse( cNode, aContext );
930 Figures.insert( std::make_pair( figure.ID, figure ) );
931 }
932 else
933 {
934 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
935 }
936 }
937}
938
939
941{
942 wxASSERT( aNode->GetName() == wxT( "TERM" ) );
943
944 ID = GetXmlAttributeIDString( aNode, 0 );
945 SymbolID = GetXmlAttributeIDString( aNode, 1 );
946 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
947
948
949 XNODE* cNode = aNode->GetChildren();
950
951 for( ; cNode; cNode = cNode->GetNext() )
952 {
953 wxString cNodeName = cNode->GetName();
954
955 if( cNodeName == wxT( "SIGLOC" ) )
956 {
957 NetLabel.Parse( cNode, aContext );
958 HasNetLabel = true;
959 }
960 else
961 {
962 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
963 }
964 }
965}
966
967
969{
970 wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
971
972 ID = GetXmlAttributeIDString( aNode, 0 );
973 BusID = GetXmlAttributeIDString( aNode, 1 );
974
975
976 XNODE* cNode = aNode->GetChildren();
977 bool firstPointParsed = false;
978 bool secondPointParsed = false;
979
980 for( ; cNode; cNode = cNode->GetNext() )
981 {
982 wxString cNodeName = cNode->GetName();
983
984 if( cNodeName == wxT( "SIGLOC" ) )
985 {
986 NetLabel.Parse( cNode, aContext );
987 HasNetLabel = true;
988 }
989 else if( cNodeName == wxT( "PT" ) )
990 {
991 if( !firstPointParsed )
992 {
993 FirstPoint.Parse( cNode, aContext );
994 firstPointParsed = true;
995 }
996 else if( !secondPointParsed )
997 {
998 SecondPoint.Parse( cNode, aContext );
999 secondPointParsed = true;
1000 }
1001 else
1002 {
1003 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1004 }
1005 }
1006 else
1007 {
1008 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1009 }
1010 }
1011
1012 if( !firstPointParsed || !secondPointParsed )
1013 THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1014}
1015
1016
1018{
1019 wxASSERT( aNode->GetName() == wxT( "BLOCKTERM" ) );
1020
1021 ID = GetXmlAttributeIDString( aNode, 0 );
1022 BlockID = GetXmlAttributeIDString( aNode, 1 );
1023 TerminalID = GetXmlAttributeIDLong( aNode, 2 );
1024
1025 XNODE* cNode = aNode->GetChildren();
1026
1027 for( ; cNode; cNode = cNode->GetNext() )
1028 {
1029 wxString cNodeName = cNode->GetName();
1030
1031 if( cNodeName == wxT( "SIGLOC" ) )
1032 {
1033 NetLabel.Parse( cNode, aContext );
1034 HasNetLabel = true;
1035 }
1036 else
1037 {
1038 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1039 }
1040 }
1041}
1042
1043
1045{
1046 ParseIdentifiers( aNode, aContext );
1047 LayerID = GetXmlAttributeIDString( aNode, 3 );
1048
1049 XNODE* cNode = aNode->GetChildren();
1050
1051 for( ; cNode; cNode = cNode->GetNext() )
1052 {
1053 wxString cNodeName = cNode->GetName();
1054
1055 if( ParseSubNode( cNode, aContext ) )
1056 {
1057 continue;
1058 }
1059 else if( cNodeName == wxT( "PATH" ) )
1060 {
1061 Path = ParseAllChildPoints( cNode, aContext, true );
1062 }
1063 else if( cNodeName == wxT( "GROUPREF" ) )
1064 {
1065 GroupID = GetXmlAttributeIDString( cNode, 0 );
1066 }
1067 else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1068 {
1069 ReuseBlockRef.Parse( cNode, aContext );
1070 }
1071 else if( cNodeName == wxT( "CONLINECODE" ) )
1072 {
1074 }
1075 else
1076 {
1077 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
1078 }
1079 }
1080}
1081
1082
1084{
1085 ParseIdentifiers( aNode, aContext );
1086
1087 //Parse child nodes
1088 XNODE* cNode = aNode->GetChildren();
1089
1090 for( ; cNode; cNode = cNode->GetNext() )
1091 {
1092 wxString cNodeName = cNode->GetName();
1093
1094 if( cNodeName == wxT( "JPT" ) )
1095 {
1096 JUNCTION_SCH jpt;
1097 jpt.Parse( cNode, aContext );
1098 Junctions.insert( std::make_pair( jpt.ID, jpt ) );
1099 }
1100 else if( ParseSubNode( cNode, aContext ) )
1101 {
1102 continue;
1103 }
1104 else if( cNodeName == wxT( "TERM" ) )
1105 {
1106 SYM_TERM pin;
1107 pin.Parse( cNode, aContext );
1108 Terminals.insert( std::make_pair( pin.ID, pin ) );
1109 }
1110 else if( cNodeName == wxT( "BUSTERM" ) )
1111 {
1112 BUS_TERM bt;
1113 bt.Parse( cNode, aContext );
1114 BusTerminals.insert( std::make_pair( bt.ID, bt ) );
1115 }
1116 else if( cNodeName == wxT( "BLOCKTERM" ) )
1117 {
1118 BLOCK_TERM bt;
1119 bt.Parse( cNode, aContext );
1120 BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
1121 }
1122 else if( cNodeName == wxT( "DANGLER" ) )
1123 {
1124 DANGLER dang;
1125 dang.Parse( cNode, aContext );
1126 Danglers.insert( std::make_pair( dang.ID, dang ) );
1127 }
1128 else if( cNodeName == wxT( "CONN" ) )
1129 {
1130 CONNECTION_SCH conn;
1131 conn.Parse( cNode, aContext );
1132 Connections.push_back( conn );
1133 }
1134 else
1135 {
1136 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
1137 }
1138 }
1139}
1140
1141
1143{
1144 wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
1145
1146 XNODE* cNode = aNode->GetChildren();
1147
1148 for( ; cNode; cNode = cNode->GetNext() )
1149 {
1150 wxString cNodeName = cNode->GetName();
1151
1152 if( cNodeName == wxT( "GROUP" ) )
1153 {
1154 GROUP group;
1155 group.Parse( cNode, aContext );
1156 Groups.insert( std::make_pair( group.ID, group ) );
1157 }
1158 else if( cNodeName == wxT( "REUSEBLOCK" ) )
1159 {
1160 REUSEBLOCK reuseblock;
1161 reuseblock.Parse( cNode, aContext );
1162 ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
1163 }
1164 else if( cNodeName == wxT( "FIGURE" ) )
1165 {
1166 FIGURE figure;
1167 figure.Parse( cNode, aContext );
1168 Figures.insert( std::make_pair( figure.ID, figure ) );
1169 }
1170 else if( cNodeName == wxT( "SYMBOL" ) )
1171 {
1172 SYMBOL sym;
1173 sym.Parse( cNode, aContext );
1174 Symbols.insert( std::make_pair( sym.ID, sym ) );
1175 }
1176 else if( cNodeName == wxT( "BUS" ) )
1177 {
1178 BUS bus;
1179 bus.Parse( cNode, aContext );
1180 Buses.insert( std::make_pair( bus.ID, bus ) );
1181 }
1182 else if( cNodeName == wxT( "BLOCK" ) )
1183 {
1184 BLOCK block;
1185 block.Parse( cNode, aContext );
1186 Blocks.insert( std::make_pair( block.ID, block ) );
1187 }
1188 else if( cNodeName == wxT( "NET" ) )
1189 {
1190 NET_SCH net;
1191 net.Parse( cNode, aContext );
1192 Nets.insert( std::make_pair( net.ID, net ) );
1193 }
1194 else if( cNodeName == wxT( "TEXT" ) )
1195 {
1196 TEXT txt;
1197 txt.Parse( cNode, aContext );
1198 Texts.insert( std::make_pair( txt.ID, txt ) );
1199 }
1200 else if( cNodeName == wxT( "DOCSYMBOL" ) )
1201 {
1202 DOCUMENTATION_SYMBOL docsym;
1203 docsym.Parse( cNode, aContext );
1204 DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
1205 }
1206 else if( cNodeName == wxT( "VHIERARCHY" ) )
1207 {
1208 VariantHierarchy.Parse( cNode, aContext );
1209 }
1210 else
1211 {
1212 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1213 }
1214
1215 aContext->CheckPointCallback();
1216 }
1217}
1218
1219
1221{
1222 ParseIdentifiers( aNode, aContext );
1223
1225 LayerID = GetXmlAttributeIDString( aNode, 2 );
1226
1227 XNODE* cNode = aNode->GetChildren();
1228
1229 for( ; cNode; cNode = cNode->GetNext() )
1230 {
1231 if( ParseSubNode( cNode, aContext ) )
1232 {
1233 continue;
1234 }
1235 else if( cNode->GetName() == wxT( "SIGLOC" ) )
1236 {
1237 NetLabel.Parse( cNode, aContext );
1238 HasNetLabel = true;
1239 }
1240 else
1241 {
1242 THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1243 }
1244 }
1245
1246}
1247
1248
1250{
1251 wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
1252
1253 ID = GetXmlAttributeIDString( aNode, 0 );
1255 LayerID = GetXmlAttributeIDString( aNode, 2 );
1256
1257 XNODE* cNode = aNode->GetChildren();
1258 bool positionParsed = false;
1259
1260 for( ; cNode; cNode = cNode->GetNext() )
1261 {
1262 wxString cNodeName = cNode->GetName();
1263
1264 if( cNodeName == wxT( "SIGLOC" ) )
1265 {
1266 NetLabel.Parse( cNode, aContext );
1267 HasNetLabel = true;
1268 }
1269 else if( !positionParsed && cNodeName == wxT( "PT" ) )
1270 {
1271 Position.Parse( cNode, aContext );
1272 positionParsed = true;
1273 }
1274 else
1275 {
1276 THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1277 }
1278 }
1279}
const char * name
constexpr double SCH_IU_PER_MM
Schematic internal units 1=100nm.
Definition base_units.h:72
#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 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 canceled.
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)
Hold an XML or S-expression element.
Definition xnode.h:43
XNODE * GetChildren() const
Definition xnode.h:61
XNODE * GetNext() const
Definition xnode.h:66
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
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.
VECTOR2I location