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