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