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 <roberto.fer.bau@gmail.com>
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 <convert_to_biu.h> // SCH_IU_PER_MM
27 #include <macros.h>
29 #include <progress_reporter.h>
30 #include <wx/translation.h>
31 
32 
34 {
35  if( m_progressReporter )
36  m_progressReporter->BeginPhase( 0 ); // Read file
37 
38  XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
39 
40  if( m_progressReporter )
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( fileRootNode, subNodeChildrenToCount );
48  m_progressReporter->SetMaxProgress( numOfSteps );
49  }
50 
52 
53  XNODE* cNode = fileRootNode->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 fileRootNode;
149 }
150 
151 
153  const wxString& aShapeStr )
154 {
155  if( aShapeStr == wxT( "ANNULUS" ) )
157  else if( aShapeStr == wxT( "BOX" ) )
159  else if( aShapeStr == wxT( "BULLET" ) )
161  else if( aShapeStr == wxT( "ROUND" ) )
163  else if( aShapeStr == wxT( "CROSS" ) )
165  else if( aShapeStr == wxT( "DIAMOND" ) )
167  else if( aShapeStr == wxT( "FINGER" ) )
169  else if( aShapeStr == wxT( "OCTAGON" ) )
171  else if( aShapeStr == wxT( "PLUS" ) )
173  else if( aShapeStr == wxT( "POINTER" ) )
175  else if( aShapeStr == wxT( "RECTANGLE" ) )
177  else if( aShapeStr == wxT( "ROUNDED" ) )
179  else if( aShapeStr == wxT( "SQUARE" ) )
181  else if( aShapeStr == wxT( "STAR" ) )
183  else if( aShapeStr == wxT( "TRIANGLE" ) )
185  else
187 }
188 
189 
191 {
192  return ParseTermShapeType( aNode->GetName() ) != TERMINAL_SHAPE_TYPE::UNDEFINED;
193 }
194 
195 
197 {
198  wxCHECK( IsTermShape( aNode ), );
199 
200  ShapeType = ParseTermShapeType( aNode->GetName() );
201  Size = GetXmlAttributeIDLong( aNode, 0 );
202 
203  switch( ShapeType )
204  {
210  InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
211  break;
212 
214  InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
216 
222  RightLength = GetXmlAttributeIDLong( aNode, 2, false ); // Optional
223  LeftLength = GetXmlAttributeIDLong( aNode, 1 );
224  break;
225 
230  //don't do anything
231  break;
232 
234  wxASSERT_MSG( false, "Unknown terminal shape type" );
235  break;
236  }
237 
238  if( aNode->GetChildren() )
239  {
240  if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
241  {
242  OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
243  }
244  else
245  {
246  THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
247  }
248 
249  CheckNoNextNodes( aNode->GetChildren() );
250  }
251 }
252 
253 
255 {
256  wxCHECK( aNode->GetName() == wxT( "TERMINALCODE" ), );
257 
258  ID = GetXmlAttributeIDString( aNode, 0 );
259  Name = GetXmlAttributeIDString( aNode, 1 );
260 
261  XNODE* cNode = aNode->GetChildren();
262  wxString location = wxString::Format( "TERMINALCODE -> %s", Name );
263 
264  for( ; cNode; cNode = cNode->GetNext() )
265  {
266  wxString cNodeName = cNode->GetName();
267 
268  if( TERMINAL_SHAPE::IsTermShape( cNode ) )
269  Shape.Parse( cNode, aContext );
270  else if( cNodeName == wxT( "FILLED" ) )
271  Filled = true;
272  else
273  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
274  }
275 }
276 
277 
279 {
280  wxCHECK( aNode->GetName() == wxT( "CODEDEFS" ), );
281 
282  XNODE* cNode = aNode->GetChildren();
283 
284  for( ; cNode; cNode = cNode->GetNext() )
285  {
286  wxString nodeName = cNode->GetName();
287 
288  if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
289  {
290  continue;
291  }
292  else if( nodeName == wxT( "TERMINALCODE" ) )
293  {
294  TERMINALCODE termcode;
295  termcode.Parse( cNode, aContext );
296  TerminalCodes.insert( std::make_pair( termcode.ID, termcode ) );
297  }
298  else
299  {
300  THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
301  }
302  }
303 }
304 
305 
307 {
308  wxCHECK( aNode->GetName() == wxT( "ASSIGNMENTS" ), );
309 
310  XNODE* cNode = aNode->GetChildren();
311  bool settingsParsed = false;
312 
313  for( ; cNode; cNode = cNode->GetNext() )
314  {
315  if( cNode->GetName() == wxT( "CODEDEFS" ) )
316  {
317  Codedefs.Parse( cNode, aContext );
318  }
319  else if( cNode->GetName() == wxT( "SETTINGS" ) )
320  {
321  settingsParsed = true;
322  Settings.Parse( cNode, aContext );
323  }
324  else if( cNode->GetName() == wxT( "GRIDS" ) )
325  {
326  Grids.Parse( cNode, aContext );
327  }
328  else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
329  {
330  NetclassEditAttributeSettings = true;
331  }
332  else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
333  {
334  SpacingclassEditAttributeSettings = true;
335  }
336  else
337  {
338  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
339  }
340  }
341 
342  if( !settingsParsed )
343  THROW_MISSING_NODE_IO_ERROR( wxT( "SETTINGS" ), wxT( "ASSIGNMENTS" ) );
344 }
345 
346 
348 {
349  wxCHECK( aNode->GetName() == wxT( "TERMINAL" ), );
350 
351  ID = GetXmlAttributeIDLong( aNode, 0 );
352  TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
353 
354  XNODE* cNode = aNode->GetChildren();
355  wxString location = wxString::Format( "TERMINAL %ld", ID );
356 
357  if( !cNode )
358  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
359 
360  for( ; cNode; cNode = cNode->GetNext() )
361  {
362  wxString cNodeName = cNode->GetName();
363 
364  if( cNodeName == wxT( "ORIENT" ) )
365  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
366  else if( cNodeName == wxT( "PT" ) )
367  Position.Parse( cNode, aContext );
368  else
369  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
370  }
371 }
372 
373 
375 {
376  wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
377  || aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
378 
379  TerminalID = GetXmlAttributeIDLong( aNode, 0 );
380  TextCodeID = GetXmlAttributeIDString( aNode, 1 );
381 
382  //Parse child nodes
383  XNODE* cNode = aNode->GetChildren();
384 
385  for( ; cNode; cNode = cNode->GetNext() )
386  {
387  if( ParseSubNode( cNode, aContext ) )
388  continue;
389  else
390  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
391  }
392 
393  if( !Position.IsFullySpecified() )
394  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
395 }
396 
397 
399 {
400  wxCHECK( aNode->GetName() == wxT( "SYMDEF" ), );
401 
402  ParseIdentifiers( aNode, aContext );
403 
404  XNODE* cNode = aNode->GetChildren();
405 
406  for( ; cNode; cNode = cNode->GetNext() )
407  {
408  wxString cNodeName = cNode->GetName();
409 
410  if( ParseSubNode( cNode, aContext ) )
411  {
412  continue;
413  }
414  else if( cNodeName == wxT( "TERMINAL" ) )
415  {
416  TERMINAL term;
417  term.Parse( cNode, aContext );
418  Terminals.insert( std::make_pair( term.ID, term ) );
419  }
420  else if( cNodeName == wxT( "PINLABELLOC" ) )
421  {
422  PIN_NUM_LABEL_LOC loc;
423  loc.Parse( cNode, aContext );
424  PinLabelLocations.insert( std::make_pair( loc.TerminalID, loc ) );
425  }
426  else if( cNodeName == wxT( "PINNUMNAMELOC" ) )
427  {
428  PIN_NUM_LABEL_LOC loc;
429  loc.Parse( cNode, aContext );
430  PinNumberLocations.insert( std::make_pair( loc.TerminalID, loc ) );
431  }
432  else
433  {
434  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
435  }
436  }
437 
438  if( !Stub && !Origin.IsFullySpecified() )
439  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
440 }
441 
442 
444 {
445  wxCHECK( aNode->GetName() == wxT( "LIBRARY" ), );
446 
447  XNODE* cNode = aNode->GetChildren();
448 
449  for( ; cNode; cNode = cNode->GetNext() )
450  {
451  wxString cNodeName = cNode->GetName();
452 
453  if( cNodeName == wxT( "SYMDEF" ) )
454  {
455  SYMDEF_SCM symdef;
456  symdef.Parse( cNode, aContext );
457  SymbolDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
458  }
459  else
460  {
461  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
462  }
463 
464  aContext->CheckPointCallback();
465  }
466 }
467 
468 
470 {
471  wxCHECK( aNode->GetName() == wxT( "SHEETS" ), );
472 
473  XNODE* cNode = aNode->GetChildren();
474 
475  for( ; cNode; cNode = cNode->GetNext() )
476  {
477  if( cNode->GetName() == wxT( "SHEET" ) )
478  {
479  LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
481  SheetNames.insert( std::make_pair( id, name ) );
482  SheetOrder.push_back( id );
483  }
484  else
485  {
486  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
487  }
488  }
489 }
490 
491 
493 {
494  wxCHECK( aNode->GetName() == wxT( "COMP" ), );
495 
496  Designator = GetXmlAttributeIDString( aNode, 0 );
497 
498  XNODE* cNode = aNode->GetChildren();
499 
500  for( ; cNode; cNode = cNode->GetNext() )
501  {
502  if( cNode->GetName() == wxT( "READONLY" ) )
503  {
504  ReadOnly = true;
505  }
506  else if( cNode->GetName() == wxT( "ATTRLOC" ) )
507  {
508  AttrLoc.Parse( cNode, aContext );
509  HasLocation = true;
510  }
511  else
512  {
513  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
514  }
515  }
516 }
517 
518 
520 {
521  wxCHECK( aNode->GetName() == wxT( "PARTREF" ), );
522 
523  RefID = GetXmlAttributeIDString( aNode, 0 );
524 
525  XNODE* cNode = aNode->GetChildren();
526 
527  for( ; cNode; cNode = cNode->GetNext() )
528  {
529  if( cNode->GetName() == wxT( "READONLY" ) )
530  {
531  ReadOnly = true;
532  }
533  else if( cNode->GetName() == wxT( "ATTRLOC" ) )
534  {
535  AttrLoc.Parse( cNode, aContext );
536  HasLocation = true;
537  }
538  else
539  {
540  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
541  }
542  }
543 }
544 
545 
547 {
548  wxCHECK( aNode->GetName() == wxT( "TERMATTR" ), /* void */ );
549 
550  TerminalID = GetXmlAttributeIDLong( aNode, 0 );
551 
552  XNODE* cNode = aNode->GetChildren();
553  bool attrParsed = false;
554 
555  for( ; cNode; cNode = cNode->GetNext() )
556  {
557  if( !attrParsed && cNode->GetName() == wxT( "ATTR" ) )
558  {
559  Value.Parse( cNode, aContext );
560  attrParsed = true;
561  }
562  else
563  {
564  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
565  }
566  }
567 }
568 
569 
571 {
572  wxCHECK( aNode->GetName() == wxT( "SYMPINNAME" ) || aNode->GetName() == wxT( "SYMPINLABEL" ), );
573 
574  TerminalID = GetXmlAttributeIDLong( aNode, 0 );
575  NameOrLabel = GetXmlAttributeIDString( aNode, 1 );
576 
577  XNODE* cNode = aNode->GetChildren();
578 
579  for( ; cNode; cNode = cNode->GetNext() )
580  {
581  if( cNode->GetName() == wxT( "ATTRLOC" ) )
582  {
583  AttrLoc.Parse( cNode, aContext );
584  HasLocation = true;
585  }
586  else
587  {
588  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
589  }
590  }
591 }
592 
593 
595 {
596  wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
597 
598  TerminalID = GetXmlAttributeIDLong( aNode, 0 );
599  PinNum = GetXmlAttributeIDLong( aNode, 1 );
600 
601  XNODE* cNode = aNode->GetChildren();
602 
603  for( ; cNode; cNode = cNode->GetNext() )
604  {
605  if( cNode->GetName() == wxT( "ATTRLOC" ) )
606  {
607  AttrLoc.Parse( cNode, aContext );
608  HasLocation = true;
609  }
610  else
611  {
612  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
613  }
614  }
615 }
616 
617 
619 {
620  wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
621 
622  XNODE* cNode = aNode->GetChildren();
623 
624  for( ; cNode; cNode = cNode->GetNext() )
625  {
626  wxString cNodeName = cNode->GetName();
627 
628  if( cNodeName == wxT( "SIGNALREF" ) )
629  {
630  Type = TYPE::SIGNALREF;
631  CheckNoNextNodes( cNode );
632  }
633  else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
634  {
635  Type = TYPE::GLOBALSIGNAL;
636  Reference = GetXmlAttributeIDString( cNode, 0 );
637  }
638  else if( cNodeName == wxT( "TESTPOINT" ) )
639  {
640  Type = TYPE::TESTPOINT;
641  CheckNoNextNodes( cNode );
642  }
643  else
644  {
645  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
646  }
647  }
648 }
649 
650 
652 {
653  wxCHECK( aNode->GetName() == wxT( "SIGNALREFERENCELINK" ), );
654 
655  TextCodeID = GetXmlAttributeIDString( aNode, 0 );
656  LayerID = GetXmlAttributeIDString( aNode, 2 );
657 
658  //Parse child nodes
659  XNODE* cNode = aNode->GetChildren();
660 
661  for( ; cNode; cNode = cNode->GetNext() )
662  {
663  if( ParseSubNode( cNode, aContext ) )
664  continue;
665  else if( cNode->GetName() == wxT( "SIGREFTEXT" ) )
666  Text = GetXmlAttributeIDString( aNode, 0 );
667  else
668  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
669  }
670 
671  if( !Position.IsFullySpecified() )
672  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
673 }
674 
675 
677 {
678  wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
679 
680  ID = GetXmlAttributeIDString( aNode, 0 );
681  SymdefID = GetXmlAttributeIDString( aNode, 1 );
682  LayerID = GetXmlAttributeIDString( aNode, 2 );
683 
684  XNODE* cNode = aNode->GetChildren();
685  bool originParsed = false;
686  wxString location = wxString::Format( "SYMBOL -> %s", ID );
687 
688  for( ; cNode; cNode = cNode->GetNext() )
689  {
690  wxString cNodeName = cNode->GetName();
691 
692  if( !originParsed && cNodeName == wxT( "PT" ) )
693  {
694  Origin.Parse( cNode, aContext );
695  originParsed = true;
696  }
697  else if( cNodeName == wxT( "COMP" ) )
698  {
699  ComponentRef.Parse( cNode, aContext );
700  IsComponent = true;
701  }
702  else if( cNodeName == wxT( "PARTREF" ) )
703  {
704  PartRef.Parse( cNode, aContext );
705  HasPartRef = true;
706  }
707  else if( cNodeName == wxT( "PARTNAMENOTVISIBLE" ) )
708  {
709  PartNameVisible = false;
710  }
711  else if( cNodeName == wxT( "VSYMMASTER" ) )
712  {
713  VariantParentSymbolID = GetXmlAttributeIDString( cNode, 0 );
714  VariantID = GetXmlAttributeIDString( cNode, 1 );
715  }
716  else if( cNodeName == wxT( "GROUPREF" ) )
717  {
718  GroupID = GetXmlAttributeIDString( cNode, 0 );
719  }
720  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
721  {
722  ReuseBlockRef.Parse( cNode, aContext );
723  }
724  else if( cNodeName == wxT( "SIGNALREFERENCELINK" ) )
725  {
726  SigRefLink.Parse( cNode, aContext );
727  }
728  else if( cNodeName == wxT( "ORIENT" ) )
729  {
730  OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
731  }
732  else if( cNodeName == wxT( "MIRROR" ) )
733  {
734  Mirror = true;
735  }
736  else if( cNodeName == wxT( "FIX" ) )
737  {
738  Fixed = true;
739  }
740  else if( cNodeName == wxT( "SCALE" ) )
741  {
742  ScaleRatioNumerator = GetXmlAttributeIDLong( cNode, 0 );
743  ScaleRatioDenominator = GetXmlAttributeIDLong( cNode, 1 );
744  }
745  else if( cNodeName == wxT( "READABILITY" ) )
746  {
747  Readability = ParseReadability( cNode );
748  }
749  else if( cNodeName == wxT( "GATE" ) )
750  {
751  GateID = GetXmlAttributeIDString( cNode, 0 );
752  }
753  else if( cNodeName == wxT( "SYMBOLVARIANT" ) )
754  {
755  IsSymbolVariant = true;
756  SymbolVariant.Parse( cNode, aContext );
757  }
758  else if( cNodeName == wxT( "TERMATTR" ) )
759  {
760  TERMATTR termattr;
761  termattr.Parse( cNode, aContext );
762  TerminalAttributes.insert( std::make_pair( termattr.TerminalID, termattr ) );
763  }
764  else if( cNodeName == wxT( "SYMPINLABEL" ) )
765  {
766  SYMPINNAME_LABEL sympinname;
767  sympinname.Parse( cNode, aContext );
768  PinLabels.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
769  }
770  else if( cNodeName == wxT( "SYMPINNAME" ) )
771  {
772  SYMPINNAME_LABEL sympinname;
773  sympinname.Parse( cNode, aContext );
774  PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
775  }
776  else if( cNodeName == wxT( "PINNUM" ) )
777  {
778  PIN_NUM pinNum;
779  pinNum.Parse( cNode, aContext );
780  PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
781  }
782  else if( cNodeName == wxT( "ATTR" ) )
783  {
784  ATTRIBUTE_VALUE attrVal;
785  attrVal.Parse( cNode, aContext );
786  AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
787  }
788  else
789  {
790  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
791  }
792  }
793 
794  if( !originParsed )
795  THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
796 }
797 
798 
800 {
801  wxCHECK( aNode->GetName() == wxT( "SIGLOC" ), );
802 
803  TextCodeID = GetXmlAttributeIDString( aNode, 0 );
804 
805  //Parse child nodes
806  XNODE* cNode = aNode->GetChildren();
807 
808  for( ; cNode; cNode = cNode->GetNext() )
809  {
810  if( ParseSubNode( cNode, aContext ) )
811  continue;
812  else
813  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
814  }
815 
816  if( !Position.IsFullySpecified() )
817  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
818 }
819 
820 
822 {
823  wxCHECK( aNode->GetName() == wxT( "BUS" ), );
824 
825  ID = GetXmlAttributeIDString( aNode, 0 );
826  LineCodeID = GetXmlAttributeIDString( aNode, 1 );
827  LayerID = GetXmlAttributeIDString( aNode, 2 );
828 
829  XNODE* cNode = aNode->GetChildren();
830 
831  for( ; cNode; cNode = cNode->GetNext() )
832  {
833  wxString cNodeName = cNode->GetName();
834 
835  if( SHAPE::IsShape( cNode ) )
836  {
837  Shape.Parse( cNode, aContext );
838  }
839  else if( cNodeName == wxT( "BUSNAME" ) )
840  {
841  Name = GetXmlAttributeIDString( cNode, 0 );
842 
843  XNODE* subNode = cNode->GetChildren();
844 
845  if( subNode )
846  {
847  if( subNode->GetName() == wxT( "SIGLOC" ) )
848  {
849  BusLabel.Parse( subNode, aContext );
850  HasBusLabel = true;
851  }
852  else
853  {
854  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
855  }
856  }
857  }
858  else
859  {
860  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
861  }
862  }
863 }
864 
865 
867 {
868  wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
869 
870  ID = GetXmlAttributeIDString( aNode, 0 );
871  LayerID = GetXmlAttributeIDString( aNode, 2 );
872 
873  XNODE* cNode = aNode->GetChildren();
874 
875  for( ; cNode; cNode = cNode->GetNext() )
876  {
877  wxString cNodeName = cNode->GetName();
878 
879  if( cNodeName == wxT( "CLONE" ) )
880  {
881  Type = TYPE::CLONE;
882  }
883  else if( cNodeName == wxT( "PARENT" ) )
884  {
885  Type = TYPE::PARENT;
886  AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
887  }
888  else if( cNodeName == wxT( "CHILD" ) )
889  {
890  Type = TYPE::CHILD;
891  AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
892  }
893  else if( cNodeName == wxT( "BLOCKNAME" ) )
894  {
895  Name = GetXmlAttributeIDString( cNode, 0 );
896  XNODE* subNode = cNode->GetChildren();
897 
898  if( subNode )
899  {
900  if( subNode->GetName() == wxT( "ATTRLOC" ) )
901  {
902  BlockLabel.Parse( subNode, aContext );
903  HasBlockLabel = true;
904  }
905  else
906  {
907  THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
908  }
909  }
910  }
911  else if( cNodeName == wxT( "TERMINAL" ) )
912  {
913  TERMINAL term;
914  term.Parse( cNode, aContext );
915  Terminals.insert( std::make_pair( term.ID, term ) );
916  }
917  else if( cNodeName == wxT( "FIGURE" ) )
918  {
919  FIGURE figure;
920  figure.Parse( cNode, aContext );
921  Figures.insert( std::make_pair( figure.ID, figure ) );
922  }
923  else
924  {
925  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
926  }
927  }
928 }
929 
930 
932 {
933  wxASSERT( aNode->GetName() == wxT( "TERM" ) );
934 
935  ID = GetXmlAttributeIDString( aNode, 0 );
936  SymbolID = GetXmlAttributeIDString( aNode, 1 );
937  TerminalID = GetXmlAttributeIDLong( aNode, 2 );
938 
939 
940  XNODE* cNode = aNode->GetChildren();
941 
942  for( ; cNode; cNode = cNode->GetNext() )
943  {
944  wxString cNodeName = cNode->GetName();
945 
946  if( cNodeName == wxT( "SIGLOC" ) )
947  {
948  NetLabel.Parse( cNode, aContext );
949  HasNetLabel = true;
950  }
951  else
952  {
953  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
954  }
955  }
956 }
957 
958 
960 {
961  wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
962 
963  ID = GetXmlAttributeIDString( aNode, 0 );
964  BusID = GetXmlAttributeIDString( aNode, 1 );
965 
966 
967  XNODE* cNode = aNode->GetChildren();
968  bool firstPointParsed = false;
969  bool secondPointParsed = false;
970 
971  for( ; cNode; cNode = cNode->GetNext() )
972  {
973  wxString cNodeName = cNode->GetName();
974 
975  if( cNodeName == wxT( "SIGLOC" ) )
976  {
977  NetLabel.Parse( cNode, aContext );
978  HasNetLabel = true;
979  }
980  else if( cNodeName == wxT( "PT" ) )
981  {
982  if( !firstPointParsed )
983  {
984  FirstPoint.Parse( cNode, aContext );
985  firstPointParsed = true;
986  }
987  else if( !secondPointParsed )
988  {
989  SecondPoint.Parse( cNode, aContext );
990  secondPointParsed = true;
991  }
992  else
993  {
994  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
995  }
996  }
997  else
998  {
999  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1000  }
1001  }
1002 
1003  if( !firstPointParsed || !secondPointParsed )
1004  THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
1005 }
1006 
1007 
1009 {
1010  wxASSERT( aNode->GetName() == wxT( "BLOCKTERM" ) );
1011 
1012  ID = GetXmlAttributeIDString( aNode, 0 );
1013  BlockID = GetXmlAttributeIDString( aNode, 1 );
1014  TerminalID = GetXmlAttributeIDLong( aNode, 2 );
1015 
1016  XNODE* cNode = aNode->GetChildren();
1017 
1018  for( ; cNode; cNode = cNode->GetNext() )
1019  {
1020  wxString cNodeName = cNode->GetName();
1021 
1022  if( cNodeName == wxT( "SIGLOC" ) )
1023  {
1024  NetLabel.Parse( cNode, aContext );
1025  HasNetLabel = true;
1026  }
1027  else
1028  {
1029  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1030  }
1031  }
1032 }
1033 
1034 
1036 {
1037  ParseIdentifiers( aNode, aContext );
1038  LayerID = GetXmlAttributeIDString( aNode, 3 );
1039 
1040  XNODE* cNode = aNode->GetChildren();
1041 
1042  for( ; cNode; cNode = cNode->GetNext() )
1043  {
1044  wxString cNodeName = cNode->GetName();
1045 
1046  if( ParseSubNode( cNode, aContext ) )
1047  {
1048  continue;
1049  }
1050  else if( cNodeName == wxT( "PATH" ) )
1051  {
1052  Path = ParseAllChildPoints( cNode, aContext, true );
1053  }
1054  else if( cNodeName == wxT( "GROUPREF" ) )
1055  {
1056  GroupID = GetXmlAttributeIDString( cNode, 0 );
1057  }
1058  else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
1059  {
1060  ReuseBlockRef.Parse( cNode, aContext );
1061  }
1062  else if( cNodeName == wxT( "CONLINECODE" ) )
1063  {
1064  ConnectionLineCode = GetXmlAttributeIDString( cNode, 0 );
1065  }
1066  else
1067  {
1068  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
1069  }
1070  }
1071 }
1072 
1073 
1075 {
1076  ParseIdentifiers( aNode, aContext );
1077 
1078  //Parse child nodes
1079  XNODE* cNode = aNode->GetChildren();
1080 
1081  for( ; cNode; cNode = cNode->GetNext() )
1082  {
1083  wxString cNodeName = cNode->GetName();
1084 
1085  if( cNodeName == wxT( "JPT" ) )
1086  {
1087  JUNCTION_SCH jpt;
1088  jpt.Parse( cNode, aContext );
1089  Junctions.insert( std::make_pair( jpt.ID, jpt ) );
1090  }
1091  else if( ParseSubNode( cNode, aContext ) )
1092  {
1093  continue;
1094  }
1095  else if( cNodeName == wxT( "TERM" ) )
1096  {
1097  SYM_TERM pin;
1098  pin.Parse( cNode, aContext );
1099  Terminals.insert( std::make_pair( pin.ID, pin ) );
1100  }
1101  else if( cNodeName == wxT( "BUSTERM" ) )
1102  {
1103  BUS_TERM bt;
1104  bt.Parse( cNode, aContext );
1105  BusTerminals.insert( std::make_pair( bt.ID, bt ) );
1106  }
1107  else if( cNodeName == wxT( "BLOCKTERM" ) )
1108  {
1109  BLOCK_TERM bt;
1110  bt.Parse( cNode, aContext );
1111  BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
1112  }
1113  else if( cNodeName == wxT( "DANGLER" ) )
1114  {
1115  DANGLER dang;
1116  dang.Parse( cNode, aContext );
1117  Danglers.insert( std::make_pair( dang.ID, dang ) );
1118  }
1119  else if( cNodeName == wxT( "CONN" ) )
1120  {
1121  CONNECTION_SCH conn;
1122  conn.Parse( cNode, aContext );
1123  Connections.push_back( conn );
1124  }
1125  else
1126  {
1127  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
1128  }
1129  }
1130 }
1131 
1132 
1134 {
1135  wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
1136 
1137  XNODE* cNode = aNode->GetChildren();
1138 
1139  for( ; cNode; cNode = cNode->GetNext() )
1140  {
1141  wxString cNodeName = cNode->GetName();
1142 
1143  if( cNodeName == wxT( "GROUP" ) )
1144  {
1145  GROUP group;
1146  group.Parse( cNode, aContext );
1147  Groups.insert( std::make_pair( group.ID, group ) );
1148  }
1149  else if( cNodeName == wxT( "REUSEBLOCK" ) )
1150  {
1151  REUSEBLOCK reuseblock;
1152  reuseblock.Parse( cNode, aContext );
1153  ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
1154  }
1155  else if( cNodeName == wxT( "FIGURE" ) )
1156  {
1157  FIGURE figure;
1158  figure.Parse( cNode, aContext );
1159  Figures.insert( std::make_pair( figure.ID, figure ) );
1160  }
1161  else if( cNodeName == wxT( "SYMBOL" ) )
1162  {
1163  SYMBOL sym;
1164  sym.Parse( cNode, aContext );
1165  Symbols.insert( std::make_pair( sym.ID, sym ) );
1166  }
1167  else if( cNodeName == wxT( "BUS" ) )
1168  {
1169  BUS bus;
1170  bus.Parse( cNode, aContext );
1171  Buses.insert( std::make_pair( bus.ID, bus ) );
1172  }
1173  else if( cNodeName == wxT( "BLOCK" ) )
1174  {
1175  BLOCK block;
1176  block.Parse( cNode, aContext );
1177  Blocks.insert( std::make_pair( block.ID, block ) );
1178  }
1179  else if( cNodeName == wxT( "NET" ) )
1180  {
1181  NET_SCH net;
1182  net.Parse( cNode, aContext );
1183  Nets.insert( std::make_pair( net.ID, net ) );
1184  }
1185  else if( cNodeName == wxT( "TEXT" ) )
1186  {
1187  TEXT txt;
1188  txt.Parse( cNode, aContext );
1189  Texts.insert( std::make_pair( txt.ID, txt ) );
1190  }
1191  else if( cNodeName == wxT( "DOCSYMBOL" ) )
1192  {
1193  DOCUMENTATION_SYMBOL docsym;
1194  docsym.Parse( cNode, aContext );
1195  DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
1196  }
1197  else if( cNodeName == wxT( "VHIERARCHY" ) )
1198  {
1199  VariantHierarchy.Parse( cNode, aContext );
1200  }
1201  else
1202  {
1203  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1204  }
1205 
1206  aContext->CheckPointCallback();
1207  }
1208 }
1209 
1210 
1212 {
1213  ParseIdentifiers( aNode, aContext );
1214 
1215  TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
1216  LayerID = GetXmlAttributeIDString( aNode, 2 );
1217 
1218  XNODE* cNode = aNode->GetChildren();
1219 
1220  for( ; cNode; cNode = cNode->GetNext() )
1221  {
1222  if( ParseSubNode( cNode, aContext ) )
1223  {
1224  continue;
1225  }
1226  else if( cNode->GetName() == wxT( "SIGLOC" ) )
1227  {
1228  NetLabel.Parse( cNode, aContext );
1229  HasNetLabel = true;
1230  }
1231  else
1232  {
1233  THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
1234  }
1235  }
1236 
1237 }
1238 
1239 
1241 {
1242  wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
1243 
1244  ID = GetXmlAttributeIDString( aNode, 0 );
1245  TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
1246  LayerID = GetXmlAttributeIDString( aNode, 2 );
1247 
1248  XNODE* cNode = aNode->GetChildren();
1249  bool positionParsed = false;
1250 
1251  for( ; cNode; cNode = cNode->GetNext() )
1252  {
1253  wxString cNodeName = cNode->GetName();
1254 
1255  if( cNodeName == wxT( "SIGLOC" ) )
1256  {
1257  NetLabel.Parse( cNode, aContext );
1258  HasNetLabel = true;
1259  }
1260  else if( !positionParsed && cNodeName == wxT( "PT" ) )
1261  {
1262  Position.Parse( cNode, aContext );
1263  positionParsed = true;
1264  }
1265  else
1266  {
1267  THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
1268  }
1269  }
1270 }
< "DANGLER" nodename (represents a dangling wire)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First two characters "BT".
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
virtual void BeginPhase(int aPhase)=0
Initialize the aPhase virtual zone of the dialog progress bar.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static XNODE * LoadArchiveFile(const wxString &aFileName, const wxString &aFileTypeIdentifier, PROGRESS_REPORTER *aProgressReporter=nullptr)
Reads a CADSTAR Archive file (S-parameter format)
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 four characters "BLKT".
Only used for error checking (not a real shape)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
#define THROW_MISSING_PARAMETER_IO_ERROR(param, location)
static TERMINAL_SHAPE_TYPE ParseTermShapeType(const wxString &aShapeStr)
This file contains miscellaneous commonly used macros and functions.
< "BUSTERM" nodename (represents a connection to a bus)
std::function< void()> CheckPointCallback
Callback function to report progress.
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
XNODE * GetChildren() const
Definition: xnode.h:62
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
#define THROW_MISSING_NODE_IO_ERROR(nodename, location)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static long GetXmlAttributeIDLong(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
void checkPoint()
Updates m_progressReporter or throws if user cancelled.
Hold an XML or S-expression element.
Definition: xnode.h:43
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
int KiCadUnitDivider
Use this value to convert units in this CSA file to KiCad units.
constexpr double SCH_IU_PER_MM
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
XNODE * GetNext() const
Definition: xnode.h:67
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static READABILITY ParseReadability(XNODE *aNode)
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
static void CheckNoNextNodes(XNODE *aNode)
const char * name
Definition: DXF_plotter.cpp:56
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
PROGRESS_REPORTER * m_progressReporter
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
NETELEMENT_ID ID
First character is "J".
void Parse(XNODE *aNode, PARSER_CONTEXT *aContext) override
wxString LAYER_ID
ID of a Sheet (if schematic) or board Layer (if PCB)
< "BLOCKTERM" nodename (represents a connection to a block)
#define THROW_UNKNOWN_NODE_IO_ERROR(nodename, location)
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)
static wxString GetXmlAttributeIDString(XNODE *aNode, unsigned int aID, bool aIsRequired=true)
static long GetNumberOfStepsForReporting(XNODE *aRootNode, std::vector< wxString > aSubNodeChildrenToCount)
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)
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