KiCad PCB EDA Suite
eagle_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) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5  * Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  * Copyright (C) 2017 CERN.
7  *
8  * @author Alejandro GarcĂ­a Montoro <[email protected]>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
29 
30 #include <string_utils.h>
31 #include <richio.h>
32 #include <wx/log.h>
33 
34 #include <functional>
35 #include <cstdio>
36 
38 
39 
40 wxString escapeName( const wxString& aNetName )
41 {
42  wxString ret( aNetName );
43 
44  ret.Replace( wxT( "!" ), wxT( "~" ) );
45 
46  return ConvertToNewOverbarNotation( ret );
47 }
48 
49 
50 template<> template<>
52 {
53  m_isAvailable = !aData.IsEmpty();
54 
55  if( m_isAvailable )
56  Set( aData );
57 }
58 
59 
60 ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
61 {
62  // This array is used to adjust the fraction part value basing on the number of digits
63  // in the fraction.
64  constexpr int DIVIDERS[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
65  constexpr unsigned int DIVIDERS_MAX_IDX = sizeof( DIVIDERS ) / sizeof( DIVIDERS[0] ) - 1;
66 
67  int integer, fraction, pre_fraction, post_fraction;
68 
69  // The following check is needed to handle correctly negative fractions where the integer
70  // part == 0.
71  bool negative = ( aValue[0] == '-' );
72 
73  // %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3
74  // digits.
75  int ret = sscanf( aValue.c_str(), "%d.%n%d%n", &integer, &pre_fraction, &fraction,
76  &post_fraction );
77 
78  if( ret == 0 )
79  throw XML_PARSER_ERROR( "Invalid coordinate" );
80 
81  // process the integer part
82  value = ConvertToNm( integer, aUnit );
83 
84  // process the fraction part
85  if( ret == 2 )
86  {
87  int digits = post_fraction - pre_fraction;
88 
89  // adjust the number of digits if necessary as we cannot handle anything smaller than
90  // nanometers (rounding).
91  if( (unsigned) digits > DIVIDERS_MAX_IDX )
92  {
93  int diff = digits - DIVIDERS_MAX_IDX;
94  digits = DIVIDERS_MAX_IDX;
95  fraction /= DIVIDERS[diff];
96  }
97 
98  int frac_value = ConvertToNm( fraction, aUnit ) / DIVIDERS[digits];
99 
100  // keep the sign in mind
101  value = negative ? value - frac_value : value + frac_value;
102  }
103 }
104 
105 
106 long long int ECOORD::ConvertToNm( int aValue, enum EAGLE_UNIT aUnit )
107 {
108  long long int ret;
109 
110  switch( aUnit )
111  {
112  default:
113  case EU_NM: ret = aValue; break;
114  case EU_MM: ret = (long long) aValue * 1000000; break;
115  case EU_INCH: ret = (long long) aValue * 25400000; break;
116  case EU_MIL: ret = (long long) aValue * 25400; break;
117  }
118 
119  if( ( ret > 0 ) != ( aValue > 0 ) )
120  wxLogError( _( "Invalid size %lld: too large" ), aValue );
121 
122  return ret;
123 }
124 
125 
126 // Template specializations below parse wxString to the used types:
127 // - wxString (preferred)
128 // - string
129 // - double
130 // - int
131 // - bool
132 // - EROT
133 // - ECOORD
134 
135 template <>
136 wxString Convert<wxString>( const wxString& aValue )
137 {
138  return aValue;
139 }
140 
141 
142 template <>
143 std::string Convert<std::string>( const wxString& aValue )
144 {
145  return std::string( aValue.ToUTF8() );
146 }
147 
148 
149 template <>
150 double Convert<double>( const wxString& aValue )
151 {
152  double value;
153 
154  if( aValue.ToCDouble( &value ) )
155  return value;
156  else
157  throw XML_PARSER_ERROR( "Conversion to double failed. Original value: '" +
158  aValue.ToStdString() + "'." );
159 }
160 
161 
162 template <>
163 int Convert<int>( const wxString& aValue )
164 {
165  if( aValue.IsEmpty() )
166  throw XML_PARSER_ERROR( "Conversion to int failed. Original value is empty." );
167 
168  return wxAtoi( aValue );
169 }
170 
171 
172 template <>
173 bool Convert<bool>( const wxString& aValue )
174 {
175  if( aValue != wxT( "yes" ) && aValue != wxT( "no" ) )
176  throw XML_PARSER_ERROR( "Conversion to bool failed. Original value, '" +
177  aValue.ToStdString() +
178  "', is neither 'yes' nor 'no'." );
179 
180  return aValue == wxT( "yes" );
181 }
182 
183 
186 template<>
187 EROT Convert<EROT>( const wxString& aRot )
188 {
189  EROT value;
190 
191  value.spin = aRot.find( 'S' ) != aRot.npos;
192  value.mirror = aRot.find( 'M' ) != aRot.npos;
193  value.degrees = strtod( aRot.c_str()
194  + 1 // skip leading 'R'
195  + int( value.spin ) // skip optional leading 'S'
196  + int( value.mirror ), // skip optional leading 'M'
197  nullptr );
198 
199  return value;
200 }
201 
202 
203 template<>
204 ECOORD Convert<ECOORD>( const wxString& aCoord )
205 {
206  // Eagle uses millimeters as the default unit
207  return ECOORD( aCoord, ECOORD::EAGLE_UNIT::EU_MM );
208 }
209 
210 
219 template<typename T>
220 T parseRequiredAttribute( wxXmlNode* aNode, const wxString& aAttribute )
221 {
222  wxString value;
223 
224  if( aNode->GetAttribute( aAttribute, &value ) )
225  return Convert<T>( value );
226  else
227  throw XML_PARSER_ERROR( "The required attribute " + aAttribute + " is missing." );
228 }
229 
230 
239 template<typename T>
240 OPTIONAL_XML_ATTRIBUTE<T> parseOptionalAttribute( wxXmlNode* aNode, const wxString& aAttribute )
241 {
242  return OPTIONAL_XML_ATTRIBUTE<T>( aNode->GetAttribute( aAttribute ) );
243 }
244 
245 
246 NODE_MAP MapChildren( wxXmlNode* aCurrentNode )
247 {
248  // Map node_name -> node_pointer
249  NODE_MAP nodesMap;
250 
251  // Loop through all children mapping them in nodesMap
252  if( aCurrentNode )
253  aCurrentNode = aCurrentNode->GetChildren();
254 
255  while( aCurrentNode )
256  {
257  // Create a new pair in the map
258  // key: current node name
259  // value: current node pointer
260  nodesMap[aCurrentNode->GetName()] = aCurrentNode;
261 
262  // Get next child
263  aCurrentNode = aCurrentNode->GetNext();
264  }
265 
266  return nodesMap;
267 }
268 
269 
270 wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAngle )
271 {
272  // Eagle give us start and end.
273  // S_ARC wants start to give the center, and end to give the start.
274  double dx = aEnd.x - aStart.x, dy = aEnd.y - aStart.y;
275  wxPoint mid = ( aStart + aEnd ) / 2;
276 
277  double dlen = sqrt( dx*dx + dy*dy );
278 
279  if( !std::isnormal( dlen ) || !std::isnormal( aAngle ) )
280  {
281  THROW_IO_ERROR( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
282  dlen,
283  aAngle ) );
284  }
285 
286  double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) );
287 
288  wxPoint center(
289  mid.x + dist * ( dy / dlen ),
290  mid.y - dist * ( dx / dlen )
291  );
292 
293  return center;
294 }
295 
296 
297 static int parseAlignment( const wxString& aAlignment )
298 {
299  // (bottom-left | bottom-center | bottom-right | center-left |
300  // center | center-right | top-left | top-center | top-right)
301  if( aAlignment == wxT( "center" ) )
302  return ETEXT::CENTER;
303  else if( aAlignment == wxT( "center-right" ) )
304  return ETEXT::CENTER_RIGHT;
305  else if( aAlignment == wxT( "top-left" ) )
306  return ETEXT::TOP_LEFT;
307  else if( aAlignment == wxT( "top-center" ) )
308  return ETEXT::TOP_CENTER;
309  else if( aAlignment == wxT( "top-right" ) )
310  return ETEXT::TOP_RIGHT;
311  else if( aAlignment == wxT( "bottom-left" ) )
312  return ETEXT::BOTTOM_LEFT;
313  else if( aAlignment == wxT( "bottom-center" ) )
314  return ETEXT::BOTTOM_CENTER;
315  else if( aAlignment == wxT( "bottom-right" ) )
316  return ETEXT::BOTTOM_RIGHT;
317  else if( aAlignment == wxT( "center-left" ) )
318  return ETEXT::CENTER_LEFT;
319 
320  return DEFAULT_ALIGNMENT;
321 }
322 
323 
324 EWIRE::EWIRE( wxXmlNode* aWire )
325 {
326  /*
327  <!ELEMENT wire EMPTY>
328  <!ATTLIST wire
329  x1 %Coord; #REQUIRED
330  y1 %Coord; #REQUIRED
331  x2 %Coord; #REQUIRED
332  y2 %Coord; #REQUIRED
333  width %Dimension; #REQUIRED
334  layer %Layer; #REQUIRED
335  extent %Extent; #IMPLIED -- only applicable for airwires --
336  style %WireStyle; "continuous"
337  curve %WireCurve; "0"
338  cap %WireCap; "round" -- only applicable if 'curve' is not zero --
339  >
340  */
341 
342  x1 = parseRequiredAttribute<ECOORD>( aWire, wxT( "x1" ) );
343  y1 = parseRequiredAttribute<ECOORD>( aWire, wxT( "y1" ) );
344  x2 = parseRequiredAttribute<ECOORD>( aWire, wxT( "x2" ) );
345  y2 = parseRequiredAttribute<ECOORD>( aWire, wxT( "y2" ) );
346  width = parseRequiredAttribute<ECOORD>( aWire, wxT( "width" ) );
347  layer = parseRequiredAttribute<int>( aWire, wxT( "layer" ) );
348  curve = parseOptionalAttribute<double>( aWire, wxT( "curve" ) );
349 
350  opt_wxString s = parseOptionalAttribute<wxString>( aWire, wxT( "style" ) );
351 
352  if( s == wxT( "continuous" ) )
354  else if( s == wxT( "longdash" ) )
356  else if( s == wxT( "shortdash" ) )
358  else if( s == wxT( "dashdot" ) )
360 
361  s = parseOptionalAttribute<wxString>( aWire, wxT( "cap" ) );
362 
363  if( s == wxT( "round" ) )
364  cap = EWIRE::ROUND;
365  else if( s == wxT( "flat" ) )
366  cap = EWIRE::FLAT;
367 }
368 
369 
370 EJUNCTION::EJUNCTION( wxXmlNode* aJunction )
371 {
372  /*
373  <!ELEMENT junction EMPTY>
374  <!ATTLIST junction
375  x %Coord; #REQUIRED
376  y %Coord; #REQUIRED
377  >
378  */
379 
380  x = parseRequiredAttribute<ECOORD>( aJunction, wxT( "x" ) );
381  y = parseRequiredAttribute<ECOORD>( aJunction, wxT( "y" ) );
382 }
383 
384 
385 ELABEL::ELABEL( wxXmlNode* aLabel, const wxString& aNetName )
386 {
387  /*
388  <!ELEMENT label EMPTY>
389  <!ATTLIST label
390  x %Coord; #REQUIRED
391  y %Coord; #REQUIRED
392  size %Dimension; #REQUIRED
393  layer %Layer; #REQUIRED
394  font %TextFont; "proportional"
395  ratio %Int; "8"
396  rot %Rotation; "R0"
397  xref %Bool; "no"
398  >
399  */
400 
401  x = parseRequiredAttribute<ECOORD>( aLabel, wxT( "x" ) );
402  y = parseRequiredAttribute<ECOORD>( aLabel, wxT( "y" ) );
403  size = parseRequiredAttribute<ECOORD>( aLabel, wxT( "size" ) );
404  layer = parseRequiredAttribute<int>( aLabel, wxT( "layer" ) );
405  rot = parseOptionalAttribute<EROT>( aLabel, wxT( "rot" ) );
406  xref = parseOptionalAttribute<wxString>( aLabel, wxT( "xref" ) );
407  netname = aNetName;
408 }
409 
410 
411 EVIA::EVIA( wxXmlNode* aVia )
412 {
413  /*
414  <!ELEMENT via EMPTY>
415  <!ATTLIST via
416  x %Coord; #REQUIRED
417  y %Coord; #REQUIRED
418  extent %Extent; #REQUIRED
419  drill %Dimension; #REQUIRED
420  diameter %Dimension; "0"
421  shape %ViaShape; "round"
422  alwaysstop %Bool; "no"
423  >
424  */
425 
426  x = parseRequiredAttribute<ECOORD>( aVia, wxT( "x" ) );
427  y = parseRequiredAttribute<ECOORD>( aVia, wxT( "y" ) );
428 
429  wxString ext = parseRequiredAttribute<wxString>( aVia, wxT( "extent" ) );
430  sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most );
431 
432  drill = parseRequiredAttribute<ECOORD>( aVia, wxT( "drill" ) );
433  diam = parseOptionalAttribute<ECOORD>( aVia, wxT( "diameter" ) );
434  shape = parseOptionalAttribute<wxString>( aVia, wxT( "shape" ) );
435 }
436 
437 
438 ECIRCLE::ECIRCLE( wxXmlNode* aCircle )
439 {
440  /*
441  <!ELEMENT circle EMPTY>
442  <!ATTLIST circle
443  x %Coord; #REQUIRED
444  y %Coord; #REQUIRED
445  radius %Coord; #REQUIRED
446  width %Dimension; #REQUIRED
447  layer %Layer; #REQUIRED
448  >
449  */
450 
451  x = parseRequiredAttribute<ECOORD>( aCircle, wxT( "x" ) );
452  y = parseRequiredAttribute<ECOORD>( aCircle, wxT( "y" ) );
453  radius = parseRequiredAttribute<ECOORD>( aCircle, wxT( "radius" ) );
454  width = parseRequiredAttribute<ECOORD>( aCircle, wxT( "width" ) );
455  layer = parseRequiredAttribute<int>( aCircle, wxT( "layer" ) );
456 }
457 
458 
459 ERECT::ERECT( wxXmlNode* aRect )
460 {
461  /*
462  <!ELEMENT rectangle EMPTY>
463  <!ATTLIST rectangle
464  x1 %Coord; #REQUIRED
465  y1 %Coord; #REQUIRED
466  x2 %Coord; #REQUIRED
467  y2 %Coord; #REQUIRED
468  layer %Layer; #REQUIRED
469  rot %Rotation; "R0"
470  >
471  */
472 
473  x1 = parseRequiredAttribute<ECOORD>( aRect, wxT( "x1" ) );
474  y1 = parseRequiredAttribute<ECOORD>( aRect, wxT( "y1" ) );
475  x2 = parseRequiredAttribute<ECOORD>( aRect, wxT( "x2" ) );
476  y2 = parseRequiredAttribute<ECOORD>( aRect, wxT( "y2" ) );
477  layer = parseRequiredAttribute<int>( aRect, wxT( "layer" ) );
478  rot = parseOptionalAttribute<EROT>( aRect, wxT( "rot" ) );
479 }
480 
481 
482 EATTR::EATTR( wxXmlNode* aTree )
483 {
484  /*
485  <!ELEMENT attribute EMPTY>
486  <!ATTLIST attribute
487  name %String; #REQUIRED
488  value %String; #IMPLIED
489  x %Coord; #IMPLIED
490  y %Coord; #IMPLIED
491  size %Dimension; #IMPLIED
492  layer %Layer; #IMPLIED
493  font %TextFont; #IMPLIED
494  ratio %Int; #IMPLIED
495  rot %Rotation; "R0"
496  display %AttributeDisplay; "value" -- only in <element> or <instance> context --
497  constant %Bool; "no" -- only in <device> context --
498  >
499  */
500 
501  name = parseRequiredAttribute<wxString>( aTree, wxT( "name" ) );
502  value = parseOptionalAttribute<wxString>( aTree, wxT( "value" ) );
503 
504  x = parseOptionalAttribute<ECOORD>( aTree, wxT( "x" ) );
505  y = parseOptionalAttribute<ECOORD>( aTree, wxT( "y" ) );
506  size = parseOptionalAttribute<ECOORD>( aTree, wxT( "size" ) );
507 
508  layer = parseOptionalAttribute<int>( aTree, wxT( "layer" ) );
509  ratio = parseOptionalAttribute<double>( aTree, wxT( "ratio" ) );
510  rot = parseOptionalAttribute<EROT>( aTree, wxT( "rot" ) );
511 
512  opt_wxString stemp = parseOptionalAttribute<wxString>( aTree, wxT( "display" ) );
513 
514  // (off | value | name | both)
515  if( stemp == wxT( "off" ) )
517  else if( stemp == wxT( "name" ) )
519  else if( stemp == wxT( "both" ) )
521  else // "value" is the default
523 
524  stemp = parseOptionalAttribute<wxString>( aTree, wxT( "align" ) );
525 
526  align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
527 }
528 
529 
530 EDIMENSION::EDIMENSION( wxXmlNode* aDimension )
531 {
532  /*
533  <!ELEMENT dimension EMPTY>
534  <!ATTLIST dimension
535  x1 %Coord; #REQUIRED
536  y1 %Coord; #REQUIRED
537  x2 %Coord; #REQUIRED
538  y2 %Coord; #REQUIRED
539  x3 %Coord; #REQUIRED
540  y3 %Coord; #REQUIRED
541  textsize %Coord;
542  layer %Layer; #REQUIRED
543  dtype %DimensionType; "parallel"
544  >
545  */
546 
547  x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
548  y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
549  x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
550  y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
551  x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
552  y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
553  textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
554  layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
555  dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
556 }
557 
558 
559 ETEXT::ETEXT( wxXmlNode* aText )
560 {
561  /*
562  <!ELEMENT text (#PCDATA)>
563  <!ATTLIST text
564  x %Coord; #REQUIRED
565  y %Coord; #REQUIRED
566  size %Dimension; #REQUIRED
567  layer %Layer; #REQUIRED
568  font %TextFont; "proportional"
569  ratio %Int; "8"
570  rot %Rotation; "R0"
571  align %Align; "bottom-left"
572  >
573  */
574 
575  text = aText->GetNodeContent();
576  x = parseRequiredAttribute<ECOORD>( aText, wxT( "x" ) );
577  y = parseRequiredAttribute<ECOORD>( aText, wxT( "y" ) );
578  size = parseRequiredAttribute<ECOORD>( aText, wxT( "size" ) );
579  layer = parseRequiredAttribute<int>( aText, wxT( "layer" ) );
580 
581  font = parseOptionalAttribute<wxString>( aText, wxT( "font" ) );
582  ratio = parseOptionalAttribute<double>( aText, wxT( "ratio" ) );
583  rot = parseOptionalAttribute<EROT>( aText, wxT( "rot" ) );
584 
585  opt_wxString stemp = parseOptionalAttribute<wxString>( aText, wxT( "align" ) );
586 
587  align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
588 }
589 
590 
591 wxSize ETEXT::ConvertSize() const
592 {
593  wxSize textsize;
594 
595  if( font )
596  {
597  const wxString& fontName = font.CGet();
598 
599  if( fontName == wxT( "vector" ) )
600  {
601  textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() );
602  }
603  else if( fontName == wxT( "fixed" ) )
604  {
605  textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() * 0.80 );
606  }
607  else
608  {
609  textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() );
610  }
611  }
612  else
613  {
614  textsize = wxSize( size.ToSchUnits() * 0.85, size.ToSchUnits() );
615  }
616 
617  return textsize;
618 }
619 
620 
621 EFRAME::EFRAME( wxXmlNode* aFrameNode )
622 {
623  /*
624  * <!ELEMENT frame EMPTY>
625  * <!ATTLIST frame
626  * x1 %Coord; #REQUIRED
627  * y1 %Coord; #REQUIRED
628  * x2 %Coord; #REQUIRED
629  * y2 %Coord; #REQUIRED
630  * columns %Int; #REQUIRED
631  * rows %Int; #REQUIRED
632  * layer %Layer; #REQUIRED
633  * border-left %Bool; "yes"
634  * border-top %Bool; "yes"
635  * border-right %Bool; "yes"
636  * border-bottom %Bool; "yes"
637  * >
638  */
639  border_left = true;
640  border_top = true;
641  border_right = true;
642  border_bottom = true;
643 
644  x1 = parseRequiredAttribute<ECOORD>( aFrameNode, wxT( "x1" ) );
645  y1 = parseRequiredAttribute<ECOORD>( aFrameNode, wxT( "y1" ) );
646  x2 = parseRequiredAttribute<ECOORD>( aFrameNode, wxT( "x2" ) );
647  y2 = parseRequiredAttribute<ECOORD>( aFrameNode, wxT( "y2" ) );
648  columns = parseRequiredAttribute<int>( aFrameNode, wxT( "columns" ) );
649  rows = parseRequiredAttribute<int>( aFrameNode, wxT( "rows" ) );
650  layer = parseRequiredAttribute<int>( aFrameNode, wxT( "layer" ) );
651  border_left = parseOptionalAttribute<bool>( aFrameNode, wxT( "border-left" ) );
652  border_top = parseOptionalAttribute<bool>( aFrameNode, wxT( "border-top" ) );
653  border_right = parseOptionalAttribute<bool>( aFrameNode, wxT( "border-right" ) );
654  border_bottom = parseOptionalAttribute<bool>( aFrameNode, wxT( "border-bottom" ) );
655 }
656 
657 
658 EPAD_COMMON::EPAD_COMMON( wxXmlNode* aPad )
659 {
660  // #REQUIRED says DTD, throw exception if not found
661  name = parseRequiredAttribute<wxString>( aPad, wxT( "name" ) );
662  x = parseRequiredAttribute<ECOORD>( aPad, wxT( "x" ) );
663  y = parseRequiredAttribute<ECOORD>( aPad, wxT( "y" ) );
664  rot = parseOptionalAttribute<EROT>( aPad, wxT( "rot" ) );
665  stop = parseOptionalAttribute<bool>( aPad, wxT( "stop" ) );
666  thermals = parseOptionalAttribute<bool>( aPad, wxT( "thermals" ) );
667 }
668 
669 
670 EPAD::EPAD( wxXmlNode* aPad )
671  : EPAD_COMMON( aPad )
672 {
673  /*
674  <!ELEMENT pad EMPTY>
675  <!ATTLIST pad
676  name %String; #REQUIRED
677  x %Coord; #REQUIRED
678  y %Coord; #REQUIRED
679  drill %Dimension; #REQUIRED
680  diameter %Dimension; "0"
681  shape %PadShape; "round"
682  rot %Rotation; "R0"
683  stop %Bool; "yes"
684  thermals %Bool; "yes"
685  first %Bool; "no"
686  >
687  */
688 
689  // #REQUIRED says DTD, throw exception if not found
690  drill = parseRequiredAttribute<ECOORD>( aPad, wxT( "drill" ) );
691 
692  // Optional attributes
693  diameter = parseOptionalAttribute<ECOORD>( aPad, wxT( "diameter" ) );
694 
695  opt_wxString s = parseOptionalAttribute<wxString>( aPad, wxT( "shape" ) );
696 
697  // (square | round | octagon | long | offset)
698  if( s == wxT( "square" ) )
700  else if( s == wxT( "round" ) )
701  shape = EPAD::ROUND;
702  else if( s == wxT( "octagon" ) )
704  else if( s == wxT( "long" ) )
705  shape = EPAD::LONG;
706  else if( s == wxT( "offset" ) )
708 
709  first = parseOptionalAttribute<bool>( aPad, wxT( "first" ) );
710 }
711 
712 
713 ESMD::ESMD( wxXmlNode* aSMD )
714  : EPAD_COMMON( aSMD )
715 {
716  /*
717  <!ATTLIST smd
718  name %String; #REQUIRED
719  x %Coord; #REQUIRED
720  y %Coord; #REQUIRED
721  dx %Dimension; #REQUIRED
722  dy %Dimension; #REQUIRED
723  layer %Layer; #REQUIRED
724  roundness %Int; "0"
725  rot %Rotation; "R0"
726  stop %Bool; "yes"
727  thermals %Bool; "yes"
728  cream %Bool; "yes"
729  >
730  */
731 
732  // DTD #REQUIRED, throw exception if not found
733  dx = parseRequiredAttribute<ECOORD>( aSMD, wxT( "dx" ) );
734  dy = parseRequiredAttribute<ECOORD>( aSMD, wxT( "dy" ) );
735  layer = parseRequiredAttribute<int>( aSMD, wxT( "layer" ) );
736 
737  roundness = parseOptionalAttribute<int>( aSMD, wxT( "roundness" ) );
738  cream = parseOptionalAttribute<bool>( aSMD, wxT( "cream" ) );
739 }
740 
741 
742 EPIN::EPIN( wxXmlNode* aPin )
743 {
744  /*
745  <!ELEMENT pin EMPTY>
746  <!ATTLIST pin
747  name %String; #REQUIRED
748  x %Coord; #REQUIRED
749  y %Coord; #REQUIRED
750  visible %PinVisible; "both"
751  length %PinLength; "long"
752  direction %PinDirection; "io"
753  function %PinFunction; "none"
754  swaplevel %Int; "0"
755  rot %Rotation; "R0"
756  >
757  */
758 
759  // DTD #REQUIRED, throw exception if not found
760  name = parseRequiredAttribute<wxString>( aPin, wxT( "name" ) );
761  x = parseRequiredAttribute<ECOORD>( aPin, wxT( "x" ) );
762  y = parseRequiredAttribute<ECOORD>( aPin, wxT( "y" ) );
763 
764  visible = parseOptionalAttribute<wxString>( aPin, wxT( "visible" ) );
765  length = parseOptionalAttribute<wxString>( aPin, wxT( "length" ) );
766  direction = parseOptionalAttribute<wxString>( aPin, wxT( "direction" ) );
767  function = parseOptionalAttribute<wxString>( aPin, wxT( "function" ) );
768  swaplevel = parseOptionalAttribute<int>( aPin, wxT( "swaplevel" ) );
769  rot = parseOptionalAttribute<EROT>( aPin, wxT( "rot" ) );
770 }
771 
772 
773 EVERTEX::EVERTEX( wxXmlNode* aVertex )
774 {
775  /*
776  <!ELEMENT vertex EMPTY>
777  <!ATTLIST vertex
778  x %Coord; #REQUIRED
779  y %Coord; #REQUIRED
780  curve %WireCurve; "0" -- the curvature from this vertex to the next one --
781  >
782  */
783 
784  x = parseRequiredAttribute<ECOORD>( aVertex, wxT( "x" ) );
785  y = parseRequiredAttribute<ECOORD>( aVertex, wxT( "y" ) );
786  curve = parseOptionalAttribute<double>( aVertex, wxT( "curve" ) );
787 }
788 
789 
790 EPOLYGON::EPOLYGON( wxXmlNode* aPolygon )
791 {
792  /*
793  <!ATTLIST polygon
794  width %Dimension; #REQUIRED
795  layer %Layer; #REQUIRED
796  spacing %Dimension; #IMPLIED
797  pour %PolygonPour; "solid"
798  isolate %Dimension; #IMPLIED -- only in <signal> or <package> context --
799  orphans %Bool; "no" -- only in <signal> context --
800  thermals %Bool; "yes" -- only in <signal> context --
801  rank %Int; "0" -- 1..6 in <signal> context, 0 or 7 in
802  <package> context --
803  >
804  */
805 
806  width = parseRequiredAttribute<ECOORD>( aPolygon, wxT( "width" ) );
807  layer = parseRequiredAttribute<int>( aPolygon, wxT( "layer" ) );
808 
809  spacing = parseOptionalAttribute<ECOORD>( aPolygon, wxT( "spacing" ) );
810  isolate = parseOptionalAttribute<ECOORD>( aPolygon, wxT( "isolate" ) );
811  opt_wxString s = parseOptionalAttribute<wxString>( aPolygon, wxT( "pour" ) );
812 
813  // default pour to solid fill
815 
816  // (solid | hatch | cutout)
817  if( s == wxT( "hatch" ) )
819  else if( s == wxT( "cutout" ) )
821 
822  orphans = parseOptionalAttribute<bool>( aPolygon, wxT( "orphans" ) );
823  thermals = parseOptionalAttribute<bool>( aPolygon, wxT( "thermals" ) );
824  rank = parseOptionalAttribute<int>( aPolygon, wxT( "rank" ) );
825 }
826 
827 
828 EHOLE::EHOLE( wxXmlNode* aHole )
829 {
830  /*
831  <!ELEMENT hole EMPTY>
832  <!ATTLIST hole
833  x %Coord; #REQUIRED
834  y %Coord; #REQUIRED
835  drill %Dimension; #REQUIRED
836  >
837  */
838 
839  // #REQUIRED:
840  x = parseRequiredAttribute<ECOORD>( aHole, wxT( "x" ) );
841  y = parseRequiredAttribute<ECOORD>( aHole, wxT( "y" ) );
842  drill = parseRequiredAttribute<ECOORD>( aHole, wxT( "drill" ) );
843 }
844 
845 
846 EELEMENT::EELEMENT( wxXmlNode* aElement )
847 {
848  /*
849  <!ELEMENT element (attribute*, variant*)>
850  <!ATTLIST element
851  name %String; #REQUIRED
852  library %String; #REQUIRED
853  package %String; #REQUIRED
854  value %String; #REQUIRED
855  x %Coord; #REQUIRED
856  y %Coord; #REQUIRED
857  locked %Bool; "no"
858  smashed %Bool; "no"
859  rot %Rotation; "R0"
860  >
861  */
862 
863  // #REQUIRED
864  name = parseRequiredAttribute<wxString>( aElement, wxT( "name" ) );
865  library = parseRequiredAttribute<wxString>( aElement, wxT( "library" ) );
866  value = parseRequiredAttribute<wxString>( aElement, wxT( "value" ) );
867  std::string p = parseRequiredAttribute<std::string>( aElement, wxT( "package" ) );
868  ReplaceIllegalFileNameChars( &p, '_' );
869  package = wxString::FromUTF8( p.c_str() );
870 
871  x = parseRequiredAttribute<ECOORD>( aElement, wxT( "x" ) );
872  y = parseRequiredAttribute<ECOORD>( aElement, wxT( "y" ) );
873 
874  // optional
875  locked = parseOptionalAttribute<bool>( aElement, wxT( "locked" ) );
876  smashed = parseOptionalAttribute<bool>( aElement, wxT( "smashed" ) );
877  rot = parseOptionalAttribute<EROT>( aElement, wxT( "rot" ) );
878 }
879 
880 
881 ELAYER::ELAYER( wxXmlNode* aLayer )
882 {
883  /*
884  <!ELEMENT layer EMPTY>
885  <!ATTLIST layer
886  number %Layer; #REQUIRED
887  name %String; #REQUIRED
888  color %Int; #REQUIRED
889  fill %Int; #REQUIRED
890  visible %Bool; "yes"
891  active %Bool; "yes"
892  >
893  */
894 
895  number = parseRequiredAttribute<int>( aLayer, wxT( "number" ) );
896  name = parseRequiredAttribute<wxString>( aLayer, wxT( "name" ) );
897  color = parseRequiredAttribute<int>( aLayer, wxT( "color" ) );
898  fill = 1; // Temporary value.
899  visible = parseOptionalAttribute<bool>( aLayer, wxT( "visible" ) );
900  active = parseOptionalAttribute<bool>( aLayer, wxT( "active" ) );
901 }
902 
903 
904 EPART::EPART( wxXmlNode* aPart )
905 {
906  /*
907  * <!ELEMENT part (attribute*, variant*)>
908  * <!ATTLIST part
909  * name %String; #REQUIRED
910  * library %String; #REQUIRED
911  * deviceset %String; #REQUIRED
912  * device %String; #REQUIRED
913  * technology %String; ""
914  * value %String; #IMPLIED
915  * >
916  */
917  // #REQUIRED
918  name = parseRequiredAttribute<wxString>( aPart, wxT( "name" ) );
919  library = parseRequiredAttribute<wxString>( aPart, wxT( "library" ) );
920  deviceset = parseRequiredAttribute<wxString>( aPart, wxT( "deviceset" ) );
921  device = parseRequiredAttribute<wxString>( aPart, wxT( "device" ) );
922  technology = parseOptionalAttribute<wxString>( aPart, wxT( "technology" ) );
923  value = parseOptionalAttribute<wxString>( aPart, wxT( "value" ) );
924 
925  for( wxXmlNode* child = aPart->GetChildren(); child; child = child->GetNext() )
926  {
927  if( child->GetName() == wxT( "attribute" ) )
928  {
929  std::string aname, avalue;
930 
931  for( wxXmlAttribute* x = child->GetAttributes(); x; x = x->GetNext() )
932  {
933  if( x->GetName() == wxT( "name" ) )
934  aname = x->GetValue();
935  else if( x->GetName() == wxT( "value" ) )
936  avalue = x->GetValue();
937  }
938 
939  if( aname.size() && avalue.size() )
940  attribute[aname] = avalue;
941  }
942  else if( child->GetName() == wxT( "variant" ) )
943  {
944  std::string aname, avalue;
945 
946  for( wxXmlAttribute* x = child->GetAttributes(); x; x = x->GetNext() )
947  {
948  if( x->GetName() == wxT( "name" ) )
949  aname = x->GetValue();
950  else if( x->GetName() == wxT( "value" ) )
951  avalue = x->GetValue();
952  }
953 
954  if( aname.size() && avalue.size() )
955  variant[aname] = avalue;
956  }
957  }
958 }
959 
960 
961 EINSTANCE::EINSTANCE( wxXmlNode* aInstance )
962 {
963  /*
964  * <!ELEMENT instance (attribute)*>
965  * <!ATTLIST instance
966  * part %String; #REQUIRED
967  * gate %String; #REQUIRED
968  * x %Coord; #REQUIRED
969  * y %Coord; #REQUIRED
970  * smashed %Bool; "no"
971  * rot %Rotation; "R0"
972  * >
973  */
974  part = parseRequiredAttribute<wxString>( aInstance, wxT( "part" ) );
975  gate = parseRequiredAttribute<wxString>( aInstance, wxT( "gate" ) );
976 
977  x = parseRequiredAttribute<ECOORD>( aInstance, wxT( "x" ) );
978  y = parseRequiredAttribute<ECOORD>( aInstance, wxT( "y" ) );
979 
980  // optional
981  smashed = parseOptionalAttribute<bool>( aInstance, wxT( "smashed" ) );
982  rot = parseOptionalAttribute<EROT>( aInstance, wxT( "rot" ) );
983 }
984 
985 
986 EGATE::EGATE( wxXmlNode* aGate )
987 {
988  /*
989  * <!ELEMENT gate EMPTY>
990  * <!ATTLIST gate
991  * name %String; #REQUIRED
992  * symbol %String; #REQUIRED
993  * x %Coord; #REQUIRED
994  * y %Coord; #REQUIRED
995  * addlevel %GateAddLevel; "next"
996  * swaplevel %Int; "0"
997  * >
998  */
999 
1000  name = parseRequiredAttribute<wxString>( aGate, wxT( "name" ) );
1001  symbol = parseRequiredAttribute<wxString>( aGate, wxT( "symbol" ) );
1002 
1003  x = parseRequiredAttribute<ECOORD>( aGate, wxT( "x" ) );
1004  y = parseRequiredAttribute<ECOORD>( aGate, wxT( "y" ) );
1005 
1006  opt_wxString stemp = parseOptionalAttribute<wxString>( aGate, wxT( "addlevel" ) );
1007 
1008  // (off | value | name | both)
1009  if( stemp == wxT( "must" ) )
1010  addlevel = EGATE::MUST;
1011  else if( stemp == wxT( "can" ) )
1012  addlevel = EGATE::CAN;
1013  else if( stemp == wxT( "next" ) )
1014  addlevel = EGATE::NEXT;
1015  else if( stemp == wxT( "request" ) )
1016  addlevel = EGATE::REQUEST;
1017  else if( stemp == wxT( "always" ) )
1018  addlevel = EGATE::ALWAYS;
1019  else
1020  addlevel = EGATE::NEXT;
1021 }
1022 
1023 
1024 ECONNECT::ECONNECT( wxXmlNode* aConnect )
1025 {
1026  /*
1027  * <!ELEMENT connect EMPTY>
1028  * <!ATTLIST connect
1029  * gate %String; #REQUIRED
1030  * pin %String; #REQUIRED
1031  * pad %String; #REQUIRED
1032  * route %ContactRoute; "all"
1033  * >
1034  */
1035  gate = parseRequiredAttribute<wxString>( aConnect, wxT( "gate" ) );
1036  pin = parseRequiredAttribute<wxString>( aConnect, wxT( "pin" ) );
1037  pad = parseRequiredAttribute<wxString>( aConnect, wxT( "pad" ) );
1038 }
1039 
1040 
1041 EDEVICE::EDEVICE( wxXmlNode* aDevice )
1042 {
1043  /*
1044  <!ELEMENT device (connects?, technologies?)>
1045  <!ATTLIST device
1046  name %String; ""
1047  package %String; #IMPLIED
1048  >
1049  */
1050  name = parseRequiredAttribute<wxString>( aDevice, wxT( "name" ) );
1051  opt_wxString pack = parseOptionalAttribute<wxString>( aDevice, wxT( "package" ) );
1052 
1053  if( pack )
1054  {
1055  std::string p( pack->c_str() );
1056  ReplaceIllegalFileNameChars( &p, '_' );
1057  package.Set( wxString::FromUTF8( p.c_str() ) );
1058  }
1059 
1060  NODE_MAP aDeviceChildren = MapChildren( aDevice );
1061  wxXmlNode* connectNode = getChildrenNodes( aDeviceChildren, wxT( "connects" ) );
1062 
1063  while( connectNode )
1064  {
1065  connects.emplace_back( connectNode );
1066  connectNode = connectNode->GetNext();
1067  }
1068 }
1069 
1070 
1071 EDEVICE_SET::EDEVICE_SET( wxXmlNode* aDeviceSet )
1072 {
1073  /*
1074  <!ELEMENT deviceset (description?, gates, devices)>
1075  <!ATTLIST deviceset
1076  name %String; #REQUIRED
1077  prefix %String; ""
1078  uservalue %Bool; "no"
1079  >
1080  */
1081 
1082  name = parseRequiredAttribute<wxString>( aDeviceSet, wxT( "name" ) );
1083  prefix = parseOptionalAttribute<wxString>( aDeviceSet, wxT( "prefix" ) );
1084  uservalue = parseOptionalAttribute<bool>( aDeviceSet, wxT( "uservalue" ) );
1085 
1086  /* Russell: Parsing of devices and gates moved to sch_eagle_plugin.cpp
1087  *
1088  //TODO: description
1089 
1090  NODE_MAP aDeviceSetChildren = MapChildren(aDeviceSet);
1091  wxXmlNode* deviceNode = getChildrenNodes(aDeviceSetChildren, wxT( "device" ));
1092 
1093  while(deviceNode){
1094  devices.push_back(EDEVICE(deviceNode));
1095  deviceNode->GetNext();
1096  }
1097 
1098  wxXmlNode* gateNode = getChildrenNodes(aDeviceSetChildren, wxT( "gate" ));
1099 
1100  while(gateNode){
1101  gates.push_back(EGATE(gateNode));
1102  gateNode->GetNext();
1103  }
1104  */
1105 
1106 }
1107 
1108 
1109 ECLASS::ECLASS( wxXmlNode* aClass )
1110 {
1111  number = parseRequiredAttribute<wxString>( aClass, wxT( "number" ) );
1112  name = parseRequiredAttribute<wxString>( aClass, wxT( "name" ) );
1113 
1114  for( wxXmlNode* child = aClass->GetChildren(); child; child = child->GetNext() )
1115  {
1116  if( child->GetName() == wxT( "clearance" ) )
1117  {
1118  wxString to = parseRequiredAttribute<wxString>( child, wxT( "class" ) );
1119  ECOORD value = parseRequiredAttribute<ECOORD>( child, wxT( "value" ) );
1120 
1121  clearanceMap[to] = value;
1122  }
1123  }
1124 }
void Set(const wxString &aString)
Attempt to convert a string to the base type.
Definition: eagle_parser.h:281
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
Eagle rotation.
Definition: eagle_parser.h:470
ECOORD Convert< ECOORD >(const wxString &aCoord)
bool mirror
Definition: eagle_parser.h:472
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:508
ECOORD x
Definition: eagle_parser.h:744
opt_int rank
Definition: eagle_parser.h:792
int ToSchUnits() const
Definition: eagle_parser.h:429
ECOORD x
Definition: eagle_parser.h:534
opt_ecoord diam
Definition: eagle_parser.h:554
opt_wxString direction
Definition: eagle_parser.h:749
opt_erot rot
Definition: eagle_parser.h:538
opt_int cap
Definition: eagle_parser.h:515
opt_bool border_bottom
Definition: eagle_parser.h:686
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:303
ECLASS(wxXmlNode *aClass)
ECOORD drill
< inclusive
Definition: eagle_parser.h:553
opt_wxString shape
Definition: eagle_parser.h:555
ECOORD y
Definition: eagle_parser.h:762
opt_bool border_left
Definition: eagle_parser.h:683
int color
Definition: DXF_plotter.cpp:57
ECOORD x2
Definition: eagle_parser.h:579
opt_double ratio
Definition: eagle_parser.h:645
OPTIONAL_XML_ATTRIBUTE()
Construct a default OPTIONAL_XML_ATTRIBUTE, whose data is not available.
Definition: eagle_parser.h:201
opt_wxString xref
Definition: eagle_parser.h:539
opt_erot rot
Definition: eagle_parser.h:820
ECOORD width
Definition: eagle_parser.h:497
opt_bool thermals
Definition: eagle_parser.h:791
opt_bool smashed
Definition: eagle_parser.h:819
wxString name
Definition: eagle_parser.h:695
EROT Convert< EROT >(const wxString &aRot)
parse an Eagle XML "rot" field.
opt_erot rot
Definition: eagle_parser.h:582
double degrees
Definition: eagle_parser.h:474
ECOORD width
Definition: eagle_parser.h:772
ECOORD y
Definition: eagle_parser.h:565
ECOORD x1
Definition: eagle_parser.h:676
T parseRequiredAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse aAttribute of the XML node aNode.
ECOORD y1
Definition: eagle_parser.h:677
ECOORD y
Definition: eagle_parser.h:817
ECOORD y
Definition: eagle_parser.h:525
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:68
wxString netname
Definition: eagle_parser.h:540
int layer
Definition: eagle_parser.h:682
opt_erot rot
Definition: eagle_parser.h:603
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
ELAYER(wxXmlNode *aLayer)
opt_bool thermals
Definition: eagle_parser.h:699
ECOORD width
Definition: eagle_parser.h:567
opt_int swaplevel
Definition: eagle_parser.h:751
ECOORD x
Definition: eagle_parser.h:564
EPIN(wxXmlNode *aPin)
nanometers
Definition: eagle_parser.h:385
EDEVICE(wxXmlNode *aDevice)
ECOORD y
Definition: eagle_parser.h:535
EPART(wxXmlNode *aPart)
int layer_back_most
< extent
Definition: eagle_parser.h:552
ECONNECT(wxXmlNode *aConnect)
EVERTEX(wxXmlNode *aVertex)
opt_int align
Definition: eagle_parser.h:612
ECOORD dy
Definition: eagle_parser.h:731
ESMD(wxXmlNode *aSMD)
opt_ecoord isolate
Definition: eagle_parser.h:789
wxString name
Definition: eagle_parser.h:596
ECOORD y1
Definition: eagle_parser.h:494
EJUNCTION(wxXmlNode *aJunction)
wxString value
Definition: eagle_parser.h:815
wxString escapeName(const wxString &aNetName)
opt_int style
Definition: eagle_parser.h:507
wxString Convert< wxString >(const wxString &aValue)
ECOORD x
Definition: eagle_parser.h:801
EDIMENSION(wxXmlNode *aDimension)
LAYER_NUM layer
Definition: eagle_parser.h:498
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
opt_ecoord y
Definition: eagle_parser.h:599
ELABEL(wxXmlNode *aLabel, const wxString &aNetName)
opt_ecoord textsize
Definition: eagle_parser.h:628
int layer
Definition: eagle_parser.h:581
opt_ecoord spacing
Definition: eagle_parser.h:774
wxString name
Definition: eagle_parser.h:812
ECOORD size
Definition: eagle_parser.h:536
EWIRE(wxXmlNode *aWire)
EHOLE(wxXmlNode *aHole)
ECOORD y1
Definition: eagle_parser.h:578
ECOORD x2
Definition: eagle_parser.h:678
ECOORD dx
Definition: eagle_parser.h:730
EPOLYGON(wxXmlNode *aPolygon)
ECOORD x
Definition: eagle_parser.h:640
int columns
Definition: eagle_parser.h:680
#define _(s)
bool m_isAvailable
A boolean indicating if the data is present or not.
Definition: eagle_parser.h:192
wxSize ConvertSize() const
Calculate text size based on font type and size.
Model an optional XML attribute.
Definition: eagle_parser.h:188
ECOORD size
Definition: eagle_parser.h:642
EDEVICE_SET(wxXmlNode *aDeviceSet)
int layer
Definition: eagle_parser.h:732
opt_wxString value
Definition: eagle_parser.h:597
wxString text
Definition: eagle_parser.h:639
EVIA(wxXmlNode *aVia)
EGATE(wxXmlNode *aGate)
ECOORD x
Definition: eagle_parser.h:816
opt_int roundness
Definition: eagle_parser.h:733
mils/thous
Definition: eagle_parser.h:388
LAYER_NUM layer
Definition: eagle_parser.h:568
opt_int align
Definition: eagle_parser.h:662
ECOORD y2
Definition: eagle_parser.h:679
static int parseAlignment(const wxString &aAlignment)
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:763
millimeters
Definition: eagle_parser.h:386
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 rows
Definition: eagle_parser.h:681
int Convert< int >(const wxString &aValue)
ECOORD y2
Definition: eagle_parser.h:496
OPTIONAL_XML_ATTRIBUTE< T > parseOptionalAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse option aAttribute of the XML node aNode.
opt_bool border_right
Definition: eagle_parser.h:685
opt_ecoord x
Definition: eagle_parser.h:598
opt_int layer
Definition: eagle_parser.h:601
ECOORD x1
Definition: eagle_parser.h:577
opt_wxString dimensionType
Definition: eagle_parser.h:630
EPAD_COMMON(wxXmlNode *aPad)
opt_erot rot
Definition: eagle_parser.h:646
opt_wxString font
Definition: eagle_parser.h:644
ECOORD x
Definition: eagle_parser.h:761
constexpr auto DEFAULT_ALIGNMENT
opt_ecoord diameter
Definition: eagle_parser.h:709
double DEG2RAD(double deg)
Definition: trigo.h:229
Structure holding common properties for through-hole and SMD pads.
Definition: eagle_parser.h:693
wxPoint ConvertArcCenter(const wxPoint &aStart, const wxPoint &aEnd, double aAngle)
ECOORD radius
Definition: eagle_parser.h:566
EFRAME(wxXmlNode *aFrameNode)
opt_double ratio
Definition: eagle_parser.h:602
opt_erot rot
Definition: eagle_parser.h:697
ECOORD y
Definition: eagle_parser.h:550
ECOORD x
Definition: eagle_parser.h:524
LAYER_NUM layer
Definition: eagle_parser.h:537
opt_bool first
Definition: eagle_parser.h:721
opt_bool orphans
Definition: eagle_parser.h:790
ECOORD x
Definition: eagle_parser.h:549
ECOORD y
Definition: eagle_parser.h:745
ERECT(wxXmlNode *aRect)
wxString name
Definition: eagle_parser.h:743
opt_int shape
Definition: eagle_parser.h:720
wxString package
Definition: eagle_parser.h:814
double Convert< double >(const wxString &aValue)
bool spin
Definition: eagle_parser.h:473
ECOORD y2
Definition: eagle_parser.h:580
ECOORD y
Definition: eagle_parser.h:641
opt_int display
Definition: eagle_parser.h:611
ECOORD drill
Definition: eagle_parser.h:708
ECOORD y
Definition: eagle_parser.h:802
opt_bool stop
Definition: eagle_parser.h:698
int layer
Definition: eagle_parser.h:643
ECOORD x1
Definition: eagle_parser.h:493
wxString library
Definition: eagle_parser.h:813
ECIRCLE(wxXmlNode *aCircle)
opt_wxString visible
Definition: eagle_parser.h:747
ECOORD drill
Definition: eagle_parser.h:803
ETEXT(wxXmlNode *aText)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
EELEMENT(wxXmlNode *aElement)
opt_wxString length
Definition: eagle_parser.h:748
static long long int ConvertToNm(int aValue, enum EAGLE_UNIT aUnit)
opt_bool border_top
Definition: eagle_parser.h:684
ECOORD x2
Definition: eagle_parser.h:495
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:47
long long int value
Unit used for the value field.
Definition: eagle_parser.h:392
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:57
EINSTANCE(wxXmlNode *aInstance)
opt_ecoord size
Definition: eagle_parser.h:600
EPAD(wxXmlNode *aPad)
int layer_front_most
Definition: eagle_parser.h:551
opt_bool cream
Definition: eagle_parser.h:734
opt_bool locked
Definition: eagle_parser.h:818
bool Convert< bool >(const wxString &aValue)
opt_erot rot
Definition: eagle_parser.h:752