KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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 <core/profile.h>
31#include <io/io_base.h>
32
33#include <string_utils.h>
34#include <richio.h>
35#include <trace_helpers.h>
36#include <wx/log.h>
37#include <wx/regex.h>
38#include <wx/tokenzr.h>
39
40#include <functional>
41#include <cstdio>
42#include <array>
43
45
46
47wxString escapeName( const wxString& aNetName )
48{
49 wxString ret( aNetName );
50
51 ret.Replace( "!", "~" );
52
53 return ConvertToNewOverbarNotation( ret );
54}
55
56
57wxString interpretText( const wxString& aText )
58{
59 wxString token = aText;
60
61 if( substituteVariable( &token ) )
62 return token;
63
64 wxString text;
65 bool sectionOpen = false;
66
67 for( wxString::size_type i = 0; i < aText.size(); i++ )
68 {
69 // Interpret escaped characters
70 if( aText[ i ] == '\\' )
71 {
72 if( i + 1 != aText.size() )
73 text.Append( aText[ i + 1 ] );
74
75 i++;
76 continue;
77 }
78
79 // Escape ~ for KiCAD
80 if( aText[i] == '~' )
81 {
82 text.Append( '~' );
83 text.Append( '~' );
84 continue;
85 }
86
87 if( aText[ i ] == '!' )
88 {
89 if( sectionOpen )
90 {
91 text.Append( '~' );
92 sectionOpen = false;
93 continue;
94 }
95
96 static wxString escapeChars( wxT( " )]}'\"" ) );
97
98 if( i + 1 != aText.size() && escapeChars.Find( aText[i + 1] ) == wxNOT_FOUND )
99 {
100 sectionOpen = true;
101 text.Append( '~' );
102 }
103 else
104 {
105 text.Append( aText[ i ] );
106 }
107
108 continue;
109 }
110
111 if( aText[i] == ',' && sectionOpen )
112 {
113 text.Append( '~' );
114 sectionOpen = false;
115 }
116
117 text.Append( aText[ i ] );
118 }
119
120 return text;
121}
122
123
124bool substituteVariable( wxString* aText )
125{
126 if( aText->StartsWith( '>' ) && aText->AfterFirst( ' ' ).IsEmpty() )
127 {
128 wxString token = aText->Upper();
129
130 if ( token == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
131 else if( token == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
132 else if( token == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
133 else if( token == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
134 else if( token == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
135 else if( token == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
136 else if( token == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
137 else if( token == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
138 else if( token == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
139 else if( token == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
140 else if( token == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
141 else if( token == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
142 else if( token == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
143 else if( token == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
144 else if( token == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
145 else if( token == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
146 else *aText = wxString::Format( wxS( "${%s}" ), aText->Mid( 1 ).Trim() );
147
148 return true;
149 }
150
151 return false;
152}
153
154
155wxString convertDescription( wxString aDescr )
156{
157 aDescr.Replace( wxS( "\n" ), wxS( " " ) );
158 aDescr.Replace( wxS( "\r" ), wxEmptyString );
159
160 wxRegEx( wxS( "<a\\s+(?:[^>]*?\\s+)?href=\"([^\"]*)\"[^>]*>" ) )
161 .ReplaceAll( &aDescr, wxS( "\\1 " ) );
162
163 aDescr.Replace( wxS( "<p>" ), wxS( "\n\n" ) );
164 aDescr.Replace( wxS( "</p>" ), wxS( "\n\n" ) );
165
166 aDescr.Replace( wxS( "<br>" ), wxS( "\n" ) );
167 aDescr.Replace( wxS( "<ul>" ), wxS( "\n" ) );
168 aDescr.Replace( wxS( "</ul>" ), wxS( "\n\n" ) );
169 aDescr.Replace( wxS( "<li></li>" ), wxS( "\n" ) );
170 aDescr.Replace( wxS( "<li>" ), wxS( "\n \u2022 " ) ); // Bullet point
171
172 aDescr = RemoveHTMLTags( aDescr );
173
174 wxRegEx( wxS( "\n +" ) ).ReplaceAll( &aDescr, wxS( "\n" ) );
175 wxRegEx( wxS( " +\n" ) ).ReplaceAll( &aDescr, wxS( "\n" ) );
176
177 wxRegEx( wxS( "\n{3,}" ) ).ReplaceAll( &aDescr, wxS( "\n\n" ) );
178 wxRegEx( wxS( "^\n+" ) ).ReplaceAll( &aDescr, wxEmptyString );
179 wxRegEx( wxS( "\n+$" ) ).ReplaceAll( &aDescr, wxEmptyString );
180
181 return aDescr;
182}
183
184
185size_t GetNodeCount( const wxXmlNode* aNode )
186{
187 size_t cnt = 0;
188
189 PROF_TIMER timer;
190
191 std::function<size_t( const wxXmlNode* )> countNodes =
192 [&]( const wxXmlNode* node )
193 {
194 size_t count = 0;
195
196 while( node )
197 {
198 if( const wxXmlNode* child = node->GetChildren() )
199 count += countNodes( child );
200 else
201 count++;
202
203 node = node->GetNext();
204 }
205
206 return count;
207 };
208
209 cnt = countNodes( aNode );
210
211 timer.Stop();
212
213 wxLogTrace( traceEagleIo, wxS( "XML node '%s' count = %zu took %0.4f ms." ),
214 aNode->GetName(), cnt, timer.msecs() );
215
216 return cnt;
217}
218template<> template<>
220{
221 m_isAvailable = !aData.IsEmpty();
222
223 if( m_isAvailable )
224 Set( aData );
225}
226
227
228ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
229{
230 // This array is used to adjust the fraction part value basing on the number of digits
231 // in the fraction.
232 static std::array<int, 9> DIVIDERS = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
233
234 int integer, pre_fraction, post_fraction;
235 long long unsigned fraction;
236
237 // The following check is needed to handle correctly negative fractions where the integer
238 // part == 0.
239 bool negative = ( aValue[0] == '-' );
240
241 // %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3
242 // digits.
243 int ret = sscanf( aValue.c_str(), "%d.%n%llu%n", &integer, &pre_fraction, &fraction,
244 &post_fraction );
245
246 if( ret == 0 )
247 throw XML_PARSER_ERROR( "Invalid coordinate" );
248
249 // process the integer part
250 value = ConvertToNm( integer, aUnit );
251
252 // process the fraction part
253 if( ret == 2 )
254 {
255 int digits = post_fraction - pre_fraction;
256
257 // adjust the number of digits if necessary as we cannot handle anything smaller than
258 // nanometers (rounding).
259 if( digits >= static_cast<int>( DIVIDERS.size() ) )
260 {
261 long long unsigned denom = pow( 10, digits - DIVIDERS.size() + 1 );
262 digits = DIVIDERS.size() - 1;
263 fraction /= denom;
264 }
265
266 int frac_value = ConvertToNm( fraction, aUnit ) / DIVIDERS[digits];
267
268 // keep the sign in mind
269 value = negative ? value - frac_value : value + frac_value;
270 }
271}
272
273
274long long int ECOORD::ConvertToNm( int aValue, enum EAGLE_UNIT aUnit )
275{
276 long long int ret;
277
278 switch( aUnit )
279 {
280 default:
281 case EU_NM: ret = aValue; break;
282 case EU_MM: ret = (long long) aValue * 1000000; break;
283 case EU_INCH: ret = (long long) aValue * 25400000; break;
284 case EU_MIL: ret = (long long) aValue * 25400; break;
285 }
286
287 if( ( ret > 0 ) != ( aValue > 0 ) )
288 wxLogError( _( "Invalid size %lld: too large" ), aValue );
289
290 return ret;
291}
292
293
294EURN::EURN( const wxString& aUrn )
295{
296 Parse( aUrn );
297}
298
299
300void EURN::Parse( const wxString& aUrn )
301{
302 wxStringTokenizer tokens( aUrn, ":" );
303
304 host = tokens.GetNextToken();
305 path = tokens.GetNextToken();
306 assetType = tokens.GetNextToken();
307
308 // Split off the version if there is one.
309 wxString tmp = tokens.GetNextToken();
310
311 assetId = tmp.BeforeFirst( '/' );
312 assetVersion = tmp.AfterLast( '/' );
313}
314
315
316bool EURN::IsValid() const
317{
318 if( host != "urn" )
319 return false;
320
321 if( path.IsEmpty() )
322 return false;
323
324 static std::set<wxString> validAssetTypes =
325 {
326 "component",
327 "footprint",
328 "library",
329 "package",
330 "symbol"
331 };
332
333 if( validAssetTypes.count( assetType ) == 0 )
334 return false;
335
336 if( assetId.IsEmpty() )
337 return false;
338
339 return true;
340}
341
342
343// Template specializations below parse wxString to the used types:
344// - wxString (preferred)
345// - string
346// - double
347// - int
348// - bool
349// - EROT
350// - ECOORD
351
352template <>
353wxString Convert<wxString>( const wxString& aValue )
354{
355 return aValue;
356}
357
358
359template <>
360std::string Convert<std::string>( const wxString& aValue )
361{
362 return std::string( aValue.ToUTF8() );
363}
364
365
366template <>
367double Convert<double>( const wxString& aValue )
368{
369 double value;
370
371 if( aValue.ToCDouble( &value ) )
372 return value;
373 else
374 throw XML_PARSER_ERROR( "Conversion to double failed. Original value: '" +
375 aValue.ToStdString() + "'." );
376}
377
378
379template <>
380int Convert<int>( const wxString& aValue )
381{
382 if( aValue.IsEmpty() )
383 throw XML_PARSER_ERROR( "Conversion to int failed. Original value is empty." );
384
385 return wxAtoi( aValue );
386}
387
388
389template <>
390bool Convert<bool>( const wxString& aValue )
391{
392 if( aValue != "yes" && aValue != "no" )
393 throw XML_PARSER_ERROR( "Conversion to bool failed. Original value, '" +
394 aValue.ToStdString() +
395 "', is neither 'yes' nor 'no'." );
396
397 return aValue == "yes";
398}
399
400
403template<>
404EROT Convert<EROT>( const wxString& aRot )
405{
406 EROT value;
407
408 value.spin = aRot.find( 'S' ) != aRot.npos;
409 value.mirror = aRot.find( 'M' ) != aRot.npos;
410 value.degrees = strtod( aRot.c_str()
411 + 1 // skip leading 'R'
412 + int( value.spin ) // skip optional leading 'S'
413 + int( value.mirror ), // skip optional leading 'M'
414 nullptr );
415
416 return value;
417}
418
419
420template<>
421ECOORD Convert<ECOORD>( const wxString& aCoord )
422{
423 // Eagle uses millimeters as the default unit
424 return ECOORD( aCoord, ECOORD::EAGLE_UNIT::EU_MM );
425}
426
427
428template<>
429EURN Convert<EURN>( const wxString& aUrn )
430{
431 return EURN( aUrn );
432}
433
434
443template<typename T>
444T parseRequiredAttribute( wxXmlNode* aNode, const wxString& aAttribute )
445{
446 wxString value;
447
448 if( aNode->GetAttribute( aAttribute, &value ) )
449 return Convert<T>( value );
450 else
451 throw XML_PARSER_ERROR( "The required attribute " + aAttribute + " is missing at "
452 "line " + wxString::Format( "%d", aNode->GetLineNumber() ) +
453 "." );
454}
455
456
465template<typename T>
466OPTIONAL_XML_ATTRIBUTE<T> parseOptionalAttribute( wxXmlNode* aNode, const wxString& aAttribute )
467{
468 return OPTIONAL_XML_ATTRIBUTE<T>( aNode->GetAttribute( aAttribute ) );
469}
470
471
472NODE_MAP MapChildren( wxXmlNode* aCurrentNode )
473{
474 // Map node_name -> node_pointer
475 NODE_MAP nodesMap;
476
477 // Loop through all children mapping them in nodesMap
478 if( aCurrentNode )
479 aCurrentNode = aCurrentNode->GetChildren();
480
481 while( aCurrentNode )
482 {
483 // Create a new pair in the map
484 // key: current node name
485 // value: current node pointer
486 nodesMap[aCurrentNode->GetName()] = aCurrentNode;
487
488 // Get next child
489 aCurrentNode = aCurrentNode->GetNext();
490 }
491
492 return nodesMap;
493}
494
495
496VECTOR2I ConvertArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle )
497{
498 // Eagle give us start and end.
499 // S_ARC wants start to give the center, and end to give the start.
500 double dx = aEnd.x - aStart.x, dy = aEnd.y - aStart.y;
501 VECTOR2I mid = ( aStart + aEnd ) / 2;
502
503 double dlen = sqrt( dx*dx + dy*dy );
504
505 if( !std::isnormal( dlen ) || !std::isnormal( aAngle ) )
506 {
507 THROW_IO_ERROR( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
508 dlen,
509 aAngle ) );
510 }
511
512 double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) );
513
515 mid.x + dist * ( dy / dlen ),
516 mid.y - dist * ( dx / dlen )
517 );
518
519 return center;
520}
521
522
523static int parseAlignment( const wxString& aAlignment )
524{
525 // (bottom-left | bottom-center | bottom-right | center-left |
526 // center | center-right | top-left | top-center | top-right)
527 if( aAlignment == "center" )
528 return ETEXT::CENTER;
529 else if( aAlignment == "center-right" )
530 return ETEXT::CENTER_RIGHT;
531 else if( aAlignment == "top-left" )
532 return ETEXT::TOP_LEFT;
533 else if( aAlignment == "top-center" )
534 return ETEXT::TOP_CENTER;
535 else if( aAlignment == "top-right" )
536 return ETEXT::TOP_RIGHT;
537 else if( aAlignment == "bottom-left" )
538 return ETEXT::BOTTOM_LEFT;
539 else if( aAlignment == "bottom-center" )
541 else if( aAlignment == "bottom-right" )
542 return ETEXT::BOTTOM_RIGHT;
543 else if( aAlignment == "center-left" )
544 return ETEXT::CENTER_LEFT;
545
546 return DEFAULT_ALIGNMENT;
547}
548
549
550void EAGLE_BASE::Report( const wxString& aMsg, SEVERITY aSeverity )
551{
552 if( !io )
553 return;
554
555 io->Report( aMsg, aSeverity );
556}
557
558
560{
561 if( !io )
562 return;
563
565}
566
567
568EWIRE::EWIRE( wxXmlNode* aWire, IO_BASE* aIo ) :
569 EAGLE_BASE( aIo )
570{
571 /*
572 * <!ELEMENT wire EMPTY>
573 * <!ATTLIST wire
574 * x1 %Coord; #REQUIRED
575 * y1 %Coord; #REQUIRED
576 * x2 %Coord; #REQUIRED
577 * y2 %Coord; #REQUIRED
578 * width %Dimension; #REQUIRED
579 * layer %Layer; #REQUIRED
580 * extent %Extent; #IMPLIED -- only applicable for airwires --
581 * style %WireStyle; "continuous"
582 * curve %WireCurve; "0"
583 * cap %WireCap; "round" -- only applicable if 'curve' is not zero --
584 * >
585 */
586
587 x1 = parseRequiredAttribute<ECOORD>( aWire, "x1" );
588 y1 = parseRequiredAttribute<ECOORD>( aWire, "y1" );
589 x2 = parseRequiredAttribute<ECOORD>( aWire, "x2" );
590 y2 = parseRequiredAttribute<ECOORD>( aWire, "y2" );
591 width = parseRequiredAttribute<ECOORD>( aWire, "width" );
592 layer = parseRequiredAttribute<int>( aWire, "layer" );
593 curve = parseOptionalAttribute<double>( aWire, "curve" );
594
595 opt_wxString s = parseOptionalAttribute<wxString>( aWire, "style" );
596
597 if( s == "continuous" )
599 else if( s == "longdash" )
601 else if( s == "shortdash" )
603 else if( s == "dashdot" )
605
606 s = parseOptionalAttribute<wxString>( aWire, "cap" );
607
608 if( s == "round" )
610 else if( s == "flat" )
612
614}
615
616
617ESEGMENT::ESEGMENT( wxXmlNode* aSegment, IO_BASE* aIo ) :
618 EAGLE_BASE( aIo )
619{
620 /*
621 * <!ELEMENT segment (pinref | portref | wire | junction | label | probe)*>
622 * <!-- 'pinref' and 'junction' are only valid in a <net> context -->
623 */
624 for( wxXmlNode* child = aSegment->GetChildren(); child; child = child->GetNext() )
625 {
626 if( child->GetName() == "pinref" )
627 pinRefs.emplace_back( std::make_unique<EPINREF>( child, aIo ) );
628 else if( child->GetName() == "portref" )
629 portRefs.emplace_back( std::make_unique<EPORTREF>( child, aIo ) );
630 else if( child->GetName() == "wire" )
631 wires.emplace_back( std::make_unique<EWIRE>( child, aIo ) );
632 else if( child->GetName() == "junction" )
633 junctions.emplace_back( std::make_unique<EJUNCTION>( child, aIo ) );
634 else if( child->GetName() == "label" )
635 labels.emplace_back( std::make_unique<ELABEL>( child, aIo ) );
636 else if( child->GetName() == "probe" )
637 probes.emplace_back( std::make_unique<EPROBE>( child, aIo ) );
638 }
639
641}
642
643
644EBUS::EBUS( wxXmlNode* aBus, IO_BASE* aIo ) :
645 EAGLE_BASE( aIo )
646{
647 /*
648 * <!ELEMENT bus (segment)*>
649 * <!ATTLIST bus
650 * name %String; #REQUIRED
651 * >
652 */
653 name = parseRequiredAttribute<wxString>( aBus, "name" );
654
655 for( wxXmlNode* child = aBus->GetChildren(); child; child = child->GetNext() )
656 {
657 if( child->GetName() == "segment" )
658 segments.emplace_back( std::make_unique<ESEGMENT>( child, aIo ) );
659 }
660
662}
663
664
665EJUNCTION::EJUNCTION( wxXmlNode* aJunction, IO_BASE* aIo ) :
666 EAGLE_BASE( aIo )
667{
668 /*
669 * <!ELEMENT junction EMPTY>
670 * <!ATTLIST junction
671 * x %Coord; #REQUIRED
672 * y %Coord; #REQUIRED
673 * >
674 */
675
676 x = parseRequiredAttribute<ECOORD>( aJunction, "x" );
677 y = parseRequiredAttribute<ECOORD>( aJunction, "y" );
678
680}
681
682
683ELABEL::ELABEL( wxXmlNode* aLabel, IO_BASE* aIo ) :
684 EAGLE_BASE( aIo )
685{
686 /*
687 * <!ELEMENT label EMPTY>
688 * <!ATTLIST label
689 * x %Coord; #REQUIRED
690 * y %Coord; #REQUIRED
691 * size %Dimension; #REQUIRED
692 * layer %Layer; #REQUIRED
693 * font %TextFont; "proportional"
694 * ratio %Int; "8"
695 * rot %Rotation; "R0"
696 * xref %Bool; "no"
697 * align %Align; "bottom-left"
698 * grouprefs IDREFS #IMPLIED
699 * >
700 * <!-- rot: Only 0, 90, 180 or 270 -->
701 * <!-- xref: Only in <net> context -->
702 */
703 x = parseRequiredAttribute<ECOORD>( aLabel, "x" );
704 y = parseRequiredAttribute<ECOORD>( aLabel, "y" );
705 size = parseRequiredAttribute<ECOORD>( aLabel, "size" );
706 layer = parseRequiredAttribute<int>( aLabel, "layer" );
707 font = parseOptionalAttribute<wxString>( aLabel, "font" );
708 ratio = parseOptionalAttribute<int>( aLabel, "ratio" );
709 rot = parseOptionalAttribute<EROT>( aLabel, "rot" );
710 xref = parseOptionalAttribute<wxString>( aLabel, "xref" );
711 align = parseOptionalAttribute<wxString>( aLabel, "align" );
712
714}
715
716
717ENET::ENET( wxXmlNode* aNet, IO_BASE* aIo ) :
718 EAGLE_BASE( aIo )
719{
720 /*
721 * <!ELEMENT net (segment)*>
722 * <!ATTLIST net
723 * name %String; #REQUIRED
724 * class %Class; "0"
725 * >
726 */
727 netname = parseRequiredAttribute<wxString>( aNet, "name" );
728 netcode = parseRequiredAttribute<int>( aNet, "class" );
729
730 for( wxXmlNode* segment = aNet->GetChildren(); segment; segment = segment->GetNext() )
731 segments.emplace_back( std::make_unique<ESEGMENT>( segment ) );
732
734}
735
736
737EVIA::EVIA( wxXmlNode* aVia, IO_BASE* aIo ) :
738 EAGLE_BASE( aIo )
739{
740 /*
741 * <!ELEMENT via EMPTY>
742 * <!ATTLIST via
743 * x %Coord; #REQUIRED
744 * y %Coord; #REQUIRED
745 * extent %Extent; #REQUIRED
746 * drill %Dimension; #REQUIRED
747 * diameter %Dimension; "0"
748 * shape %ViaShape; "round"
749 * alwaysstop %Bool; "no"
750 * >
751 */
752
753 x = parseRequiredAttribute<ECOORD>( aVia, "x" );
754 y = parseRequiredAttribute<ECOORD>( aVia, "y" );
755
756 wxString ext = parseRequiredAttribute<wxString>( aVia, "extent" );
757 sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most );
758
759 drill = parseRequiredAttribute<ECOORD>( aVia, "drill" );
760 diam = parseOptionalAttribute<ECOORD>( aVia, "diameter" );
761 shape = parseOptionalAttribute<wxString>( aVia, "shape" );
762
764}
765
766
767ECIRCLE::ECIRCLE( wxXmlNode* aCircle, IO_BASE* aIo ) :
768 EAGLE_BASE( aIo )
769{
770 /*
771 * <!ELEMENT circle EMPTY>
772 * <!ATTLIST circle
773 * x %Coord; #REQUIRED
774 * y %Coord; #REQUIRED
775 * radius %Coord; #REQUIRED
776 * width %Dimension; #REQUIRED
777 * layer %Layer; #REQUIRED
778 * >
779 */
780
781 x = parseRequiredAttribute<ECOORD>( aCircle, "x" );
782 y = parseRequiredAttribute<ECOORD>( aCircle, "y" );
783 radius = parseRequiredAttribute<ECOORD>( aCircle, "radius" );
784 width = parseRequiredAttribute<ECOORD>( aCircle, "width" );
785 layer = parseRequiredAttribute<int>( aCircle, "layer" );
786
788}
789
790
791ERECT::ERECT( wxXmlNode* aRect, IO_BASE* aIo ) :
792 EAGLE_BASE( aIo )
793{
794 /*
795 * <!ELEMENT rectangle EMPTY>
796 * <!ATTLIST rectangle
797 * x1 %Coord; #REQUIRED
798 * y1 %Coord; #REQUIRED
799 * x2 %Coord; #REQUIRED
800 * y2 %Coord; #REQUIRED
801 * layer %Layer; #REQUIRED
802 * rot %Rotation; "R0"
803 * >
804 */
805
806 x1 = parseRequiredAttribute<ECOORD>( aRect, "x1" );
807 y1 = parseRequiredAttribute<ECOORD>( aRect, "y1" );
808 x2 = parseRequiredAttribute<ECOORD>( aRect, "x2" );
809 y2 = parseRequiredAttribute<ECOORD>( aRect, "y2" );
810 layer = parseRequiredAttribute<int>( aRect, "layer" );
811 rot = parseOptionalAttribute<EROT>( aRect, "rot" );
812
814}
815
816
817EDESCRIPTION::EDESCRIPTION( wxXmlNode* aDescription, IO_BASE* aIo ) :
818 EAGLE_BASE( aIo )
819{
820 /*
821 * <!ELEMENT description (#PCDATA)>
822 * <!ATTLIST description
823 * language %String; "en"
824 * >
825 */
826
827 text = aDescription->GetNodeContent();
828 language = parseOptionalAttribute<wxString>( aDescription, "language" );
829
831}
832
833
834EATTR::EATTR( wxXmlNode* aTree, IO_BASE* aIo ) :
835 EAGLE_BASE( aIo )
836{
837 /*
838 * <!ELEMENT attribute EMPTY>
839 * <!ATTLIST attribute
840 * name %String; #REQUIRED
841 * value %String; #IMPLIED
842 * x %Coord; #IMPLIED
843 * y %Coord; #IMPLIED
844 * size %Dimension; #IMPLIED
845 * layer %Layer; #IMPLIED
846 * font %TextFont; #IMPLIED
847 * ratio %Int; #IMPLIED
848 * rot %Rotation; "R0"
849 * display %AttributeDisplay; "value" -- only in <element> or <instance> context --
850 * constant %Bool; "no" -- only in <device> context --
851 * >
852 */
853
854 name = parseRequiredAttribute<wxString>( aTree, "name" );
855 value = parseOptionalAttribute<wxString>( aTree, "value" );
856
857 x = parseOptionalAttribute<ECOORD>( aTree, "x" );
858 y = parseOptionalAttribute<ECOORD>( aTree, "y" );
859 size = parseOptionalAttribute<ECOORD>( aTree, "size" );
860
861 layer = parseOptionalAttribute<int>( aTree, "layer" );
862 ratio = parseOptionalAttribute<double>( aTree, "ratio" );
863 rot = parseOptionalAttribute<EROT>( aTree, "rot" );
864
865 opt_wxString stemp = parseOptionalAttribute<wxString>( aTree, "display" );
866
867 // (off | value | name | both)
868 if( stemp == "off" )
870 else if( stemp == "name" )
872 else if( stemp == "both" )
874 else // "value" is the default
876
877 stemp = parseOptionalAttribute<wxString>( aTree, "align" );
878
879 align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
880
882}
883
884
885EPINREF::EPINREF( wxXmlNode* aPinRef, IO_BASE* aIo ) :
886 EAGLE_BASE( aIo )
887{
888 /*
889 * <!ELEMENT pinref EMPTY>
890 * <!ATTLIST pinref
891 * part %String; #REQUIRED
892 * gate %String; #REQUIRED
893 * pin %String; #REQUIRED
894 * >
895 */
896 part = parseRequiredAttribute<wxString>( aPinRef, "part" );
897 gate = parseRequiredAttribute<wxString>( aPinRef, "gate" );
898 pin = parseRequiredAttribute<wxString>( aPinRef, "pin" );
899
901}
902
903
904EPORTREF::EPORTREF( wxXmlNode* aPortRef, IO_BASE* aIo ) :
905 EAGLE_BASE( aIo )
906{
907 /*
908 * <!ELEMENT portref EMPTY>
909 * <!ATTLIST portref
910 * moduleinst %String; #REQUIRED
911 * port %String; #REQUIRED
912 * >
913 */
914 moduleinst = parseRequiredAttribute<wxString>( aPortRef, "moduleinst" );
915 port = parseRequiredAttribute<wxString>( aPortRef, "port" );
916
918}
919
920
921EPROBE::EPROBE( wxXmlNode* aProbe, IO_BASE* aIo ) :
922 EAGLE_BASE( aIo )
923{
924 /*
925 * <!ELEMENT probe EMPTY>
926 * <!ATTLIST probe
927 * x %Coord; #REQUIRED
928 * y %Coord; #REQUIRED
929 * size %Dimension; #REQUIRED
930 * layer %Layer; #REQUIRED
931 * font %TextFont; "proportional"
932 * ratio %Int; "8"
933 * rot %Rotation; "R0"
934 * xref %Bool; "no"
935 * grouprefs IDREFS #IMPLIED
936 * >
937 * <!-- rot: Only 0, 90, 180 or 270 -->
938 * <!-- xref: Only in <net> context -->
939 */
940 x = parseRequiredAttribute<ECOORD>( aProbe, "x" );
941 y = parseRequiredAttribute<ECOORD>( aProbe, "y" );
942 size = parseRequiredAttribute<double>( aProbe, "size" );
943 layer = parseRequiredAttribute<int>( aProbe, "layer" );
944 font = parseOptionalAttribute<wxString>( aProbe, "font" );
945 ratio = parseOptionalAttribute<int>( aProbe, "ratio" );
946 rot = parseOptionalAttribute<EROT>( aProbe, "rot" );
947 xref = parseOptionalAttribute<bool>( aProbe, "xref" );
948
950}
951
952
953EDIMENSION::EDIMENSION( wxXmlNode* aDimension, IO_BASE* aIo ) :
954 EAGLE_BASE( aIo )
955{
956 /*
957 * <!ELEMENT dimension EMPTY>
958 * <!ATTLIST dimension
959 * x1 %Coord; #REQUIRED
960 * y1 %Coord; #REQUIRED
961 * x2 %Coord; #REQUIRED
962 * y2 %Coord; #REQUIRED
963 * x3 %Coord; #REQUIRED
964 * y3 %Coord; #REQUIRED
965 * textsize %Coord;
966 * layer %Layer; #REQUIRED
967 * dtype %DimensionType; "parallel"
968 * >
969 */
970
971 x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
972 y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
973 x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
974 y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
975 x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
976 y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
977 textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
978 layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
979 dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
980
982}
983
984
985ETEXT::ETEXT( wxXmlNode* aText, IO_BASE* aIo ) :
986 EAGLE_BASE( aIo )
987{
988 /*
989 <!ELEMENT text (#PCDATA)>
990 <!ATTLIST text
991 x %Coord; #REQUIRED
992 y %Coord; #REQUIRED
993 size %Dimension; #REQUIRED
994 layer %Layer; #REQUIRED
995 font %TextFont; "proportional"
996 ratio %Int; "8"
997 rot %Rotation; "R0"
998 align %Align; "bottom-left"
999 >
1000 */
1001
1002 text = aText->GetNodeContent();
1003 x = parseRequiredAttribute<ECOORD>( aText, "x" );
1004 y = parseRequiredAttribute<ECOORD>( aText, "y" );
1005 size = parseRequiredAttribute<ECOORD>( aText, "size" );
1006 layer = parseRequiredAttribute<int>( aText, "layer" );
1007
1008 font = parseOptionalAttribute<wxString>( aText, "font" );
1009 ratio = parseOptionalAttribute<double>( aText, "ratio" );
1010 rot = parseOptionalAttribute<EROT>( aText, "rot" );
1011
1012 opt_wxString stemp = parseOptionalAttribute<wxString>( aText, "align" );
1013
1014 align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
1015
1017}
1018
1019
1021{
1022 VECTOR2I textsize;
1023
1024 if( font )
1025 {
1026 const wxString& fontName = font.CGet();
1027
1028 if( fontName == "vector" )
1029 {
1030 textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() );
1031 }
1032 else if( fontName == "fixed" )
1033 {
1034 textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() * 0.80 );
1035 }
1036 else
1037 {
1038 textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() );
1039 }
1040 }
1041 else
1042 {
1043 textsize = VECTOR2I( size.ToSchUnits() * 0.85, size.ToSchUnits() );
1044 }
1045
1046 return textsize;
1047}
1048
1049
1050EFRAME::EFRAME( wxXmlNode* aFrameNode, IO_BASE* aIo ) :
1051 EAGLE_BASE( aIo )
1052{
1053 /*
1054 * <!ELEMENT frame EMPTY>
1055 * <!ATTLIST frame
1056 * x1 %Coord; #REQUIRED
1057 * y1 %Coord; #REQUIRED
1058 * x2 %Coord; #REQUIRED
1059 * y2 %Coord; #REQUIRED
1060 * columns %Int; #REQUIRED
1061 * rows %Int; #REQUIRED
1062 * layer %Layer; #REQUIRED
1063 * border-left %Bool; "yes"
1064 * border-top %Bool; "yes"
1065 * border-right %Bool; "yes"
1066 * border-bottom %Bool; "yes"
1067 * >
1068 */
1069 border_left = true;
1070 border_top = true;
1071 border_right = true;
1072 border_bottom = true;
1073
1074 x1 = parseRequiredAttribute<ECOORD>( aFrameNode, "x1" );
1075 y1 = parseRequiredAttribute<ECOORD>( aFrameNode, "y1" );
1076 x2 = parseRequiredAttribute<ECOORD>( aFrameNode, "x2" );
1077 y2 = parseRequiredAttribute<ECOORD>( aFrameNode, "y2" );
1078 columns = parseRequiredAttribute<int>( aFrameNode, "columns" );
1079 rows = parseRequiredAttribute<int>( aFrameNode, "rows" );
1080 layer = parseRequiredAttribute<int>( aFrameNode, "layer" );
1081 border_left = parseOptionalAttribute<bool>( aFrameNode, "border-left" );
1082 border_top = parseOptionalAttribute<bool>( aFrameNode, "border-top" );
1083 border_right = parseOptionalAttribute<bool>( aFrameNode, "border-right" );
1084 border_bottom = parseOptionalAttribute<bool>( aFrameNode, "border-bottom" );
1085
1087}
1088
1089
1090EPAD_COMMON::EPAD_COMMON( wxXmlNode* aPad, IO_BASE* aIo ) :
1091 EAGLE_BASE( aIo )
1092{
1093 // #REQUIRED says DTD, throw exception if not found
1094 name = parseRequiredAttribute<wxString>( aPad, "name" );
1095 x = parseRequiredAttribute<ECOORD>( aPad, "x" );
1096 y = parseRequiredAttribute<ECOORD>( aPad, "y" );
1097 rot = parseOptionalAttribute<EROT>( aPad, "rot" );
1098 stop = parseOptionalAttribute<bool>( aPad, "stop" );
1099 thermals = parseOptionalAttribute<bool>( aPad, "thermals" );
1100}
1101
1102
1103EPAD::EPAD( wxXmlNode* aPad, IO_BASE* aIo ) :
1104 EPAD_COMMON( aPad, aIo )
1105{
1106 /*
1107 <!ELEMENT pad EMPTY>
1108 <!ATTLIST pad
1109 name %String; #REQUIRED
1110 x %Coord; #REQUIRED
1111 y %Coord; #REQUIRED
1112 drill %Dimension; #REQUIRED
1113 diameter %Dimension; "0"
1114 shape %PadShape; "round"
1115 rot %Rotation; "R0"
1116 stop %Bool; "yes"
1117 thermals %Bool; "yes"
1118 first %Bool; "no"
1119 >
1120 */
1121
1122 // #REQUIRED says DTD, but DipTrace doesn't write it sometimes
1123 drill = parseOptionalAttribute<ECOORD>( aPad, "drill" );
1124
1125 // Optional attributes
1126 diameter = parseOptionalAttribute<ECOORD>( aPad, "diameter" );
1127
1128 opt_wxString s = parseOptionalAttribute<wxString>( aPad, "shape" );
1129
1130 // (square | round | octagon | long | offset)
1131 if( s == "square" )
1133 else if( s == "round" )
1135 else if( s == "octagon" )
1137 else if( s == "long" )
1138 shape = EPAD::LONG;
1139 else if( s == "offset" )
1141
1142 first = parseOptionalAttribute<bool>( aPad, "first" );
1143
1145}
1146
1147
1148ESMD::ESMD( wxXmlNode* aSMD, IO_BASE* aIo ) :
1149 EPAD_COMMON( aSMD, aIo )
1150{
1151 /*
1152 <!ATTLIST smd
1153 name %String; #REQUIRED
1154 x %Coord; #REQUIRED
1155 y %Coord; #REQUIRED
1156 dx %Dimension; #REQUIRED
1157 dy %Dimension; #REQUIRED
1158 layer %Layer; #REQUIRED
1159 roundness %Int; "0"
1160 rot %Rotation; "R0"
1161 stop %Bool; "yes"
1162 thermals %Bool; "yes"
1163 cream %Bool; "yes"
1164 >
1165 */
1166
1167 // DTD #REQUIRED, throw exception if not found
1168 dx = parseRequiredAttribute<ECOORD>( aSMD, "dx" );
1169 dy = parseRequiredAttribute<ECOORD>( aSMD, "dy" );
1170 layer = parseRequiredAttribute<int>( aSMD, "layer" );
1171
1172 roundness = parseOptionalAttribute<int>( aSMD, "roundness" );
1173 cream = parseOptionalAttribute<bool>( aSMD, "cream" );
1174
1176}
1177
1178
1179EPIN::EPIN( wxXmlNode* aPin, IO_BASE* aIo ) :
1180 EAGLE_BASE( aIo )
1181{
1182 /*
1183 <!ELEMENT pin EMPTY>
1184 <!ATTLIST pin
1185 name %String; #REQUIRED
1186 x %Coord; #REQUIRED
1187 y %Coord; #REQUIRED
1188 visible %PinVisible; "both"
1189 length %PinLength; "long"
1190 direction %PinDirection; "io"
1191 function %PinFunction; "none"
1192 swaplevel %Int; "0"
1193 rot %Rotation; "R0"
1194 >
1195 */
1196
1197 // DTD #REQUIRED, throw exception if not found
1198 name = parseRequiredAttribute<wxString>( aPin, "name" );
1199 x = parseRequiredAttribute<ECOORD>( aPin, "x" );
1200 y = parseRequiredAttribute<ECOORD>( aPin, "y" );
1201
1202 visible = parseOptionalAttribute<wxString>( aPin, "visible" );
1203 length = parseOptionalAttribute<wxString>( aPin, "length" );
1204 direction = parseOptionalAttribute<wxString>( aPin, "direction" );
1205 function = parseOptionalAttribute<wxString>( aPin, "function" );
1206 swaplevel = parseOptionalAttribute<int>( aPin, "swaplevel" );
1207 rot = parseOptionalAttribute<EROT>( aPin, "rot" );
1208
1210}
1211
1212
1213EVERTEX::EVERTEX( wxXmlNode* aVertex, IO_BASE* aIo ) :
1214 EAGLE_BASE( aIo )
1215{
1216 /*
1217 * <!ELEMENT vertex EMPTY>
1218 * <!ATTLIST vertex
1219 * x %Coord; #REQUIRED
1220 * y %Coord; #REQUIRED
1221 * curve %WireCurve; "0" -- the curvature from this vertex to the next one --
1222 * >
1223 */
1224
1225 x = parseRequiredAttribute<ECOORD>( aVertex, "x" );
1226 y = parseRequiredAttribute<ECOORD>( aVertex, "y" );
1227 curve = parseOptionalAttribute<double>( aVertex, "curve" );
1228
1230}
1231
1232
1233EPOLYGON::EPOLYGON( wxXmlNode* aPolygon, IO_BASE* aIo ) :
1234 EAGLE_BASE( aIo )
1235{
1236 /*
1237 * <!ELEMENT polygon (vertex)*>
1238 * <!-- the vertices must define a valid polygon; if the last vertex is the same
1239 * as the first one, it is ignored -->
1240 * <!ATTLIST polygon
1241 * width %Dimension; #REQUIRED
1242 * layer %Layer; #REQUIRED
1243 * spacing %Dimension; #IMPLIED
1244 * pour %PolygonPour; "solid"
1245 * isolate %Dimension; #IMPLIED
1246 * orphans %Bool; "no"
1247 * thermals %Bool; "yes"
1248 * rank %Int; "0"
1249 * grouprefs IDREFS #IMPLIED
1250 * >
1251 * <!-- isolate: Only in <signal> or <package> context -->
1252 * <!-- orphans: Only in <signal> context -->
1253 * <!-- thermals:Only in <signal> context -->
1254 * <!-- rank: 1..6 in <signal> context, 0 or 7 in <package> context -->
1255 */
1256
1257 width = parseRequiredAttribute<ECOORD>( aPolygon, "width" );
1258 layer = parseRequiredAttribute<int>( aPolygon, "layer" );
1259
1260 spacing = parseOptionalAttribute<ECOORD>( aPolygon, "spacing" );
1261 isolate = parseOptionalAttribute<ECOORD>( aPolygon, "isolate" );
1262 opt_wxString s = parseOptionalAttribute<wxString>( aPolygon, "pour" );
1263
1264 // default pour to solid fill
1266
1267 // (solid | hatch | cutout)
1268 if( s == "hatch" )
1270 else if( s == "cutout" )
1272
1273 orphans = parseOptionalAttribute<bool>( aPolygon, "orphans" );
1274 thermals = parseOptionalAttribute<bool>( aPolygon, "thermals" );
1275 rank = parseOptionalAttribute<int>( aPolygon, "rank" );
1276
1277 for( wxXmlNode* child = aPolygon->GetChildren(); child; child = child->GetNext() )
1278 {
1279 if( child->GetName() == "vertex" )
1280 vertices.emplace_back( std::make_unique<EVERTEX>( child, aIo ) );
1281 }
1282
1284}
1285
1286
1287ESPLINE::ESPLINE( wxXmlNode* aSpline, IO_BASE* aIo ) :
1288 EAGLE_BASE( aIo )
1289{
1290 /*
1291 * <!ELEMENT spline (vertex)*>
1292 * <!-- Four simple (non-curve) vertices define the control points of a degree-3 spline
1293 * curve -->
1294 * <!ATTLIST spline
1295 * width %Dimension; #REQUIRED
1296 * >
1297 */
1298 width = parseRequiredAttribute<double>( aSpline, "width" );
1299
1300 for( wxXmlNode* child = aSpline->GetChildren(); child; child = child->GetNext() )
1301 {
1302 if( child->GetName() == "vertex" )
1303 vertices.emplace_back( std::make_unique<EVERTEX>( child, aIo ) );
1304 }
1305
1307}
1308
1309
1310EVARIANT::EVARIANT( wxXmlNode* aVariant, IO_BASE* aIo ) :
1311 EAGLE_BASE( aIo )
1312{
1313 /*
1314 * <!ELEMENT variant EMPTY>
1315 * <!ATTLIST variant
1316 * name %String; #REQUIRED
1317 * populate %Bool; "yes"
1318 * value %String; #IMPLIED
1319 * technology %String; #IMPLIED
1320 * >
1321 * <!-- technology: Only in part context -->
1322 */
1323 name = parseRequiredAttribute<wxString>( aVariant, "name" );
1324 populate = parseOptionalAttribute<bool>( aVariant, "populate" );
1325 value = parseOptionalAttribute<wxString>( aVariant, "value" );
1326 technology = parseOptionalAttribute<wxString>( aVariant, "technology" );
1327
1329}
1330
1331
1332EMODEL::EMODEL( wxXmlNode* aModel, IO_BASE* aIo ) :
1333 EAGLE_BASE( aIo )
1334{
1335 /*
1336 * <!ELEMENT model (#PCDATA)>
1337 * <!ATTLIST model
1338 * name %String; #REQUIRED
1339 * >
1340 */
1341 name = parseRequiredAttribute<wxString>( aModel, "name" );
1342 model = aModel->GetNodeContent();
1343
1345}
1346
1347
1348EPINMAP::EPINMAP( wxXmlNode* aPinMap, IO_BASE* aIo ) :
1349 EAGLE_BASE( aIo )
1350{
1351 /*
1352 * <!ELEMENT pinmap EMPTY>
1353 * <!ATTLIST pinmap
1354 * gate %String; #REQUIRED
1355 * pin %String; #REQUIRED
1356 * pinorder %String; #REQUIRED
1357 * >
1358 */
1359 gate = parseRequiredAttribute<wxString>( aPinMap, "gate" );
1360 pin = parseRequiredAttribute<wxString>( aPinMap, "pin" );
1361 pinorder = parseRequiredAttribute<wxString>( aPinMap, "pinorder" );
1362
1364}
1365
1366
1367EPINMAPPING::EPINMAPPING( wxXmlNode* aPinMapping, IO_BASE* aIo ) :
1368 EAGLE_BASE( aIo )
1369{
1370 /*
1371 * <!ELEMENT pinmapping (pinmap+)>
1372 * <!ATTLIST pinmapping
1373 * isusermap %Bool; "no"
1374 * iddevicewide %Bool; "yes"
1375 * spiceprefix %String; ""
1376 * >
1377 */
1378 isusermap = parseOptionalAttribute<bool>( aPinMapping, "isusermap" );
1379 iddevicewide = parseOptionalAttribute<bool>( aPinMapping, "iddevicewide" );
1380 spiceprefix = parseOptionalAttribute<wxString>( aPinMapping, "spiceprefix" );
1381
1382 for( wxXmlNode* child = aPinMapping->GetChildren(); child; child = child->GetNext() )
1383 {
1384 if( child->GetName() == "pinmap" )
1385 pinmaps.emplace_back( std::make_unique<EPINMAP>( child, aIo ) );
1386 }
1387
1389}
1390
1391
1392ESPICE::ESPICE( wxXmlNode* aSpice, IO_BASE* aIo ) :
1393 EAGLE_BASE( aIo )
1394{
1395 /*
1396 * <!ELEMENT spice (pinmapping, model)>
1397 */
1398 pinmapping = std::make_unique<EPINMAPPING>( aSpice );
1399
1400 if( aSpice->GetName() == "model" )
1401 model = std::make_unique<EMODEL>( aSpice );
1402
1404}
1405
1406
1407EHOLE::EHOLE( wxXmlNode* aHole, IO_BASE* aIo ) :
1408 EAGLE_BASE( aIo )
1409{
1410 /*
1411 <!ELEMENT hole EMPTY>
1412 <!ATTLIST hole
1413 x %Coord; #REQUIRED
1414 y %Coord; #REQUIRED
1415 drill %Dimension; #REQUIRED
1416 >
1417 */
1418
1419 // #REQUIRED:
1420 x = parseRequiredAttribute<ECOORD>( aHole, "x" );
1421 y = parseRequiredAttribute<ECOORD>( aHole, "y" );
1422 drill = parseRequiredAttribute<ECOORD>( aHole, "drill" );
1423
1425}
1426
1427
1428EELEMENT::EELEMENT( wxXmlNode* aElement, IO_BASE* aIo ) :
1429 EAGLE_BASE( aIo )
1430{
1431 /*
1432 <!ELEMENT element (attribute*, variant*)>
1433 <!ATTLIST element
1434 name %String; #REQUIRED
1435 library %String; #REQUIRED
1436 library_urn %Urn; ""
1437 package %String; #REQUIRED
1438 package3d_urn %Urn; ""
1439 override_package3d_urn %Urn; ""
1440 override_package_urn %Urn; ""
1441 override_locally_modified %Bool; "no"
1442 value %String; #REQUIRED
1443 x %Coord; #REQUIRED
1444 y %Coord; #REQUIRED
1445 locked %Bool; "no"
1446 populate %Bool; "yes"
1447 smashed %Bool; "no"
1448 rot %Rotation; "R0"
1449 grouprefs IDREFS #IMPLIED
1450 >
1451 */
1452
1453 // #REQUIRED
1454 name = parseRequiredAttribute<wxString>( aElement, "name" );
1455 library = parseRequiredAttribute<wxString>( aElement, "library" );
1456 value = parseRequiredAttribute<wxString>( aElement, "value" );
1457 std::string p = parseRequiredAttribute<std::string>( aElement, "package" );
1458 ReplaceIllegalFileNameChars( &p, '_' );
1459 package = wxString::FromUTF8( p.c_str() );
1460
1461 x = parseRequiredAttribute<ECOORD>( aElement, "x" );
1462 y = parseRequiredAttribute<ECOORD>( aElement, "y" );
1463
1464 // optional
1465 library_urn = parseOptionalAttribute<EURN>( aElement, "library_urn" );
1466 locked = parseOptionalAttribute<bool>( aElement, "locked" );
1467 smashed = parseOptionalAttribute<bool>( aElement, "smashed" );
1468 rot = parseOptionalAttribute<EROT>( aElement, "rot" );
1469
1470 for( wxXmlNode* child = aElement->GetChildren(); child; child = child->GetNext() )
1471 {
1472 if( child->GetName() == "attribute" )
1473 {
1474 std::unique_ptr<EATTR> attr = std::make_unique<EATTR>( child, aIo );
1475 attributes[ attr->name ] = std::move( attr );
1476 }
1477 else if( child->GetName() == "variant" )
1478 {
1479 std::unique_ptr<EVARIANT> variant = std::make_unique<EVARIANT>( child, aIo );
1480 variants[ variant->name ] = std::move( variant );
1481 }
1482 }
1483
1484 AdvanceProgressPhase();
1485}
1486
1487
1488ELAYER::ELAYER( wxXmlNode* aLayer, IO_BASE* aIo ) :
1489 EAGLE_BASE( aIo )
1490{
1491 /*
1492 <!ELEMENT layer EMPTY>
1493 <!ATTLIST layer
1494 number %Layer; #REQUIRED
1495 name %String; #REQUIRED
1496 color %Int; #REQUIRED
1497 fill %Int; #REQUIRED
1498 visible %Bool; "yes"
1499 active %Bool; "yes"
1500 >
1501 */
1502
1503 number = parseRequiredAttribute<int>( aLayer, "number" );
1504 name = parseRequiredAttribute<wxString>( aLayer, "name" );
1505 color = parseRequiredAttribute<int>( aLayer, "color" );
1506 fill = parseRequiredAttribute<int>( aLayer, "fill" );
1507 visible = parseOptionalAttribute<bool>( aLayer, "visible" );
1508 active = parseOptionalAttribute<bool>( aLayer, "active" );
1509
1511}
1512
1513
1514EPART::EPART( wxXmlNode* aPart, IO_BASE* aIo ) :
1515 EAGLE_BASE( aIo )
1516{
1517 /*
1518 * <!ELEMENT part (attribute*, variant*)>
1519 * <!ATTLIST part
1520 * name %String; #REQUIRED
1521 * library %String; #REQUIRED
1522 * deviceset %String; #REQUIRED
1523 * device %String; #REQUIRED
1524 * technology %String; ""
1525 * value %String; #IMPLIED
1526 * >
1527 */
1528 name = parseRequiredAttribute<wxString>( aPart, "name" );
1529 library = parseRequiredAttribute<wxString>( aPart, "library" );
1530 libraryUrn = parseOptionalAttribute<EURN>( aPart, "library_urn" );
1531 deviceset = parseRequiredAttribute<wxString>( aPart, "deviceset" );
1532 device = parseRequiredAttribute<wxString>( aPart, "device" );
1533 package3d_urn = parseOptionalAttribute<wxString>( aPart, "package3d_urn" );
1534 override_package3d_urn = parseOptionalAttribute<wxString>( aPart, "override_package3d_urn" );
1535 override_package_urn = parseOptionalAttribute<wxString>( aPart, "override_package_urn" );
1536 override_locally_modified = parseOptionalAttribute<bool>( aPart, "override_locally_modified" );
1537 technology = parseOptionalAttribute<wxString>( aPart, "technology" );
1538 value = parseOptionalAttribute<wxString>( aPart, "value" );
1539
1540 for( wxXmlNode* child = aPart->GetChildren(); child; child = child->GetNext() )
1541 {
1542 if( child->GetName() == "attribute" )
1543 {
1544 std::unique_ptr<EATTR> attr = std::make_unique<EATTR>( child, aIo );
1545 attributes[ attr->name ] = std::move( attr );
1546 }
1547 else if( child->GetName() == "variant" )
1548 {
1549 std::unique_ptr<EVARIANT> variant = std::make_unique<EVARIANT>( child, aIo );
1550 variants[ variant->name ] = std::move( variant );
1551 }
1552 else if( child->GetName() == "spice" )
1553 {
1554 spice = std::make_unique<ESPICE>( child, aIo );
1555 }
1556 }
1557
1559}
1560
1561
1562EINSTANCE::EINSTANCE( wxXmlNode* aInstance, IO_BASE* aIo ) :
1563 EAGLE_BASE( aIo )
1564{
1565 /*
1566 * <!ELEMENT instance (attribute)*>
1567 * <!ATTLIST instance
1568 * part %String; #REQUIRED
1569 * gate %String; #REQUIRED
1570 * x %Coord; #REQUIRED
1571 * y %Coord; #REQUIRED
1572 * smashed %Bool; "no"
1573 * rot %Rotation; "R0"
1574 * >
1575 */
1576 part = parseRequiredAttribute<wxString>( aInstance, "part" );
1577 gate = parseRequiredAttribute<wxString>( aInstance, "gate" );
1578
1579 x = parseRequiredAttribute<ECOORD>( aInstance, "x" );
1580 y = parseRequiredAttribute<ECOORD>( aInstance, "y" );
1581
1582 // optional
1583 smashed = parseOptionalAttribute<bool>( aInstance, "smashed" );
1584 rot = parseOptionalAttribute<EROT>( aInstance, "rot" );
1585
1586 for( wxXmlNode* child = aInstance->GetChildren(); child; child = child->GetNext() )
1587 {
1588 if( child->GetName() == "attribute" )
1589 {
1590 std::unique_ptr<EATTR> attr = std::make_unique<EATTR>( child, aIo );
1591 attributes[ attr->name ] = std::move( attr );
1592 }
1593 }
1594
1596}
1597
1598
1599EGATE::EGATE( wxXmlNode* aGate, IO_BASE* aIo ) :
1600 EAGLE_BASE( aIo )
1601{
1602 /*
1603 * <!ELEMENT gate EMPTY>
1604 * <!ATTLIST gate
1605 * name %String; #REQUIRED
1606 * symbol %String; #REQUIRED
1607 * x %Coord; #REQUIRED
1608 * y %Coord; #REQUIRED
1609 * addlevel %GateAddLevel; "next"
1610 * swaplevel %Int; "0"
1611 * >
1612 */
1613
1614 name = parseRequiredAttribute<wxString>( aGate, "name" );
1615 symbol = parseRequiredAttribute<wxString>( aGate, "symbol" );
1616
1617 x = parseRequiredAttribute<ECOORD>( aGate, "x" );
1618 y = parseRequiredAttribute<ECOORD>( aGate, "y" );
1619
1620 opt_wxString stemp = parseOptionalAttribute<wxString>( aGate, "addlevel" );
1621
1622 // (off | value | name | both)
1623 if( stemp == "must" )
1625 else if( stemp == "can" )
1627 else if( stemp == "next" )
1629 else if( stemp == "request" )
1631 else if( stemp == "always" )
1633 else
1635
1636 swaplevel = parseOptionalAttribute<int>( aGate, "swaplevel" );
1637
1639}
1640
1641
1642ECONNECT::ECONNECT( wxXmlNode* aConnect, IO_BASE* aIo ) :
1643 EAGLE_BASE( aIo )
1644{
1645 /*
1646 * <!ELEMENT connect EMPTY>
1647 * <!ATTLIST connect
1648 * gate %String; #REQUIRED
1649 * pin %String; #REQUIRED
1650 * pad %String; #REQUIRED
1651 * route %ContactRoute; "all"
1652 * >
1653 */
1654 gate = parseRequiredAttribute<wxString>( aConnect, "gate" );
1655 pin = parseRequiredAttribute<wxString>( aConnect, "pin" );
1656 pad = parseRequiredAttribute<wxString>( aConnect, "pad" );
1657 contactroute = parseOptionalAttribute<wxString>( aConnect, "contactroute" );
1658
1660}
1661
1662
1663ETECHNOLOGY::ETECHNOLOGY( wxXmlNode* aTechnology, IO_BASE* aIo ) :
1664 EAGLE_BASE( aIo )
1665{
1666 /*
1667 * <!ELEMENT technology (attribute)*>
1668 * <!ATTLIST technology
1669 * name %String; #REQUIRED
1670 * >
1671 */
1672 name = parseRequiredAttribute<wxString>( aTechnology, "name" );
1673
1674 for( wxXmlNode* child = aTechnology->GetChildren(); child; child = child->GetNext() )
1675 {
1676 if( child->GetName() == "attribute" )
1677 attributes.emplace_back( std::make_unique<EATTR>( child, aIo ) );
1678 }
1679
1681}
1682
1683
1684EPACKAGE3DINST::EPACKAGE3DINST( wxXmlNode* aPackage3dInst, IO_BASE* aIo ) :
1685 EAGLE_BASE( aIo )
1686{
1687 /*
1688 * <!ELEMENT package3dinstance EMPTY>
1689 * <!ATTLIST package3dinstance
1690 * package3d_urn %Urn; #REQUIRED
1691 * >
1692 */
1693 package3d_urn = parseRequiredAttribute<wxString>( aPackage3dInst, "package3d_urn" );
1694
1696}
1697
1698
1699EDEVICE::EDEVICE( wxXmlNode* aDevice, IO_BASE* aIo ) :
1700 EAGLE_BASE( aIo )
1701{
1702 /*
1703 * <!ELEMENT device (connects?, package3dinstances?, technologies?)>
1704 * <!ATTLIST device
1705 * name %String; ""
1706 * package %String; #IMPLIED
1707 */
1708 name = parseRequiredAttribute<wxString>( aDevice, "name" );
1709 opt_wxString pack = parseOptionalAttribute<wxString>( aDevice, "package" );
1710
1711 if( pack )
1712 {
1713 std::string p( pack->c_str() );
1714 ReplaceIllegalFileNameChars( &p, '_' );
1715 package.Set( wxString::FromUTF8( p.c_str() ) );
1716 }
1717
1718 for( wxXmlNode* child = aDevice->GetChildren(); child; child = child->GetNext() )
1719 {
1720 if( child->GetName() == "connects" )
1721 {
1722 for( wxXmlNode* connect = child->GetChildren(); connect; connect = connect->GetNext() )
1723 {
1724 if( connect->GetName() == "connect" )
1725 connects.emplace_back( std::make_unique<ECONNECT>( connect, aIo ) );
1726 }
1727
1729 }
1730 else if( child->GetName() == "packages3dinstances" )
1731 {
1732 for( wxXmlNode* package3dinst = child->GetChildren(); package3dinst;
1733 package3dinst = package3dinst->GetNext() )
1734 {
1735 if( package3dinst->GetName() == "package3dinstance" )
1736 package3dinstances.emplace_back( std::make_unique<EPACKAGE3DINST>( package3dinst, aIo ) );
1737 }
1738
1740 }
1741 else if( child->GetName() == "technologies" )
1742 {
1743 for( wxXmlNode* technology = child->GetChildren(); technology;
1744 technology = technology->GetNext() )
1745 {
1746 if( technology->GetName() == "technology" )
1747 technologies.emplace_back( std::make_unique<ETECHNOLOGY>( technology, aIo ) );
1748 }
1749
1751 }
1752 }
1753
1755}
1756
1757
1758EDEVICE_SET::EDEVICE_SET( wxXmlNode* aDeviceSet, IO_BASE* aIo ) :
1759 EAGLE_BASE( aIo )
1760{
1761 /*
1762 * <!ELEMENT deviceset (description?, gates, devices, spice?)>
1763 * <!ATTLIST deviceset
1764 * name %String; #REQUIRED
1765 * urn %Urn; ""
1766 * locally_modified %Bool; "no"
1767 * prefix %String; ""
1768 * uservalue %Bool; "no"
1769 * library_version %Int; ""
1770 * library_locally_modified %Bool; "no"
1771 * >
1772 * <!-- library_version and library_locally_modified: Only in managed libraries
1773 * inside boards or schematics -->
1774 */
1775 name = parseRequiredAttribute<wxString>( aDeviceSet, "name" );
1776 urn = parseOptionalAttribute<EURN>( aDeviceSet, "urn" );
1777 locally_modified = parseOptionalAttribute<bool>( aDeviceSet, "locally_modified" );
1778 prefix = parseOptionalAttribute<wxString>( aDeviceSet, "prefix" );
1779 uservalue = parseOptionalAttribute<bool>( aDeviceSet, "uservalue" );
1780 library_version = parseOptionalAttribute<int>( aDeviceSet, "library_version" );
1782 parseOptionalAttribute<bool>( aDeviceSet, "library_locally_modified" );
1783
1784 for( wxXmlNode* child = aDeviceSet->GetChildren(); child; child = child->GetNext() )
1785 {
1786 if( child->GetName() == "description" )
1787 {
1788 description = std::make_optional<EDESCRIPTION>( child, aIo );
1789 }
1790 else if( child->GetName() == "gates" )
1791 {
1792 for( wxXmlNode* gate = child->GetChildren(); gate; gate = gate->GetNext() )
1793 {
1794 std::unique_ptr<EGATE> tmp = std::make_unique<EGATE>( gate, aIo );
1795 gates[tmp->name] = std::move( tmp );
1796 }
1797
1799 }
1800 else if( child->GetName() == "devices" )
1801 {
1802 for( wxXmlNode* device = child->GetChildren(); device; device = device->GetNext() )
1803 devices.emplace_back( std::make_unique<EDEVICE>( device, aIo ) );
1804
1806 }
1807 else if( child->GetName() == "spice" )
1808 {
1809 spice = std::make_optional<ESPICE>( child, aIo );
1810 }
1811 }
1812
1814}
1815
1816
1817ECLASS::ECLASS( wxXmlNode* aClass, IO_BASE* aIo ) :
1818 EAGLE_BASE( aIo )
1819{
1820 /*
1821 * <!ELEMENT class (clearance)*>
1822 * <!ATTLIST class
1823 * number %Class; #REQUIRED
1824 * name %String; #REQUIRED
1825 * width %Dimension; "0"
1826 * drill %Dimension; "0"
1827 * >
1828 */
1829 number = parseRequiredAttribute<wxString>( aClass, "number" );
1830 name = parseRequiredAttribute<wxString>( aClass, "name" );
1831 width = parseOptionalAttribute<ECOORD>( aClass, "width" );
1832 drill = parseOptionalAttribute<ECOORD>( aClass, "drill" );
1833
1834 for( wxXmlNode* child = aClass->GetChildren(); child; child = child->GetNext() )
1835 {
1836 if( child->GetName() == "clearance" )
1837 {
1838 wxString to = parseRequiredAttribute<wxString>( child, "class" );
1839 ECOORD value = parseRequiredAttribute<ECOORD>( child, "value" );
1840
1841 clearanceMap[to] = value;
1842
1844 }
1845 }
1846
1848}
1849
1850
1851EPLAIN::EPLAIN( wxXmlNode* aPlain, IO_BASE* aIo ) :
1852 EAGLE_BASE( aIo )
1853{
1854 /*
1855 * <!ELEMENT plain (polygon | wire | text | dimension | circle | spline | rectangle |
1856 * frame | hole)*>
1857 */
1858 for( wxXmlNode* child = aPlain->GetChildren(); child; child = child->GetNext() )
1859 {
1860 if( child->GetName() == "polygon" )
1861 polygons.emplace_back( std::make_unique<EPOLYGON>( child, aIo ) );
1862 else if( child->GetName() == "wire" )
1863 wires.emplace_back( std::make_unique<EWIRE>( child, aIo ) );
1864 else if( child->GetName() == "text" )
1865 texts.emplace_back( std::make_unique<ETEXT>( child, aIo ) );
1866 else if( child->GetName() == "dimension" )
1867 dimensions.emplace_back( std::make_unique<EDIMENSION>( child, aIo ) );
1868 else if( child->GetName() == "circle" )
1869 circles.emplace_back( std::make_unique<ECIRCLE>( child, aIo ) );
1870 else if( child->GetName() == "spline" )
1871 splines.emplace_back( std::make_unique<ESPLINE>( child, aIo ) );
1872 else if( child->GetName() == "rectangle" )
1873 rectangles.emplace_back( std::make_unique<ERECT>( child, aIo ) );
1874 else if( child->GetName() == "frame" )
1875 frames.emplace_back( std::make_unique<EFRAME>( child, aIo ) );
1876 else if( child->GetName() == "hole" )
1877 holes.emplace_back( std::make_unique<EHOLE>( child, aIo ) );
1878 }
1879
1881}
1882
1883
1884EMODULEINST::EMODULEINST( wxXmlNode* aModuleInst, IO_BASE* aIo ) :
1885 EAGLE_BASE( aIo )
1886{
1887 /*
1888 * <!ELEMENT moduleinst (attribute)*>
1889 * <!ATTLIST moduleinst
1890 * name %String; #REQUIRED
1891 * module %String; #REQUIRED
1892 * modulevariant %String; ""
1893 * x %Coord; #REQUIRED
1894 * y %Coord; #REQUIRED
1895 * offset %Int; "0"
1896 * smashed %Bool; "no"
1897 * rot %Rotation; "R0"
1898 * >
1899 * <!-- rot: Only 0, 90, 180 or 270 -->
1900 */
1901 name = parseRequiredAttribute<wxString>( aModuleInst, "name" );
1902 moduleinst = parseRequiredAttribute<wxString>( aModuleInst, "module" );
1903 moduleVariant = parseOptionalAttribute<wxString>( aModuleInst, "modulevariant" );
1904 x = parseRequiredAttribute<ECOORD>( aModuleInst, "x" );
1905 y = parseRequiredAttribute<ECOORD>( aModuleInst, "y" );
1906 offset = parseOptionalAttribute<int>( aModuleInst, "offset" );
1907 smashed = parseOptionalAttribute<bool>( aModuleInst, "smashed" );
1908 rotation = parseOptionalAttribute<EROT>( aModuleInst, "rot" );
1909
1911}
1912
1913
1914ESHEET::ESHEET( wxXmlNode* aSheet, IO_BASE* aIo ) :
1915 EAGLE_BASE( aIo )
1916{
1917 /*
1918 * <!ELEMENT sheet (description?, plain?, moduleinsts?, instances?, busses?, nets?)>
1919 */
1920 description = parseOptionalAttribute<wxString>( aSheet, "description" );
1921
1922 for( wxXmlNode* child = aSheet->GetChildren(); child; child = child->GetNext() )
1923 {
1924 if( child->GetName() == "plain" )
1925 {
1926 plain = std::make_unique<EPLAIN>( child, aIo );
1927 }
1928 else if( child->GetName() == "moduleinsts" )
1929 {
1930 for( wxXmlNode* moduleinst = child->GetChildren(); moduleinst;
1931 moduleinst = moduleinst->GetNext() )
1932 {
1933 if( moduleinst->GetName() == "moduleinst" )
1934 {
1935 std::unique_ptr<EMODULEINST> inst = std::make_unique<EMODULEINST>( moduleinst,
1936 aIo );
1937 moduleinsts[ inst->name ] = std::move( inst );
1938 }
1939 }
1940
1942 }
1943 else if( child->GetName() == "instances" )
1944 {
1945 for( wxXmlNode* instance = child->GetChildren(); instance;
1946 instance = instance->GetNext() )
1947 {
1948 if( instance->GetName() == "instance" )
1949 instances.emplace_back( std::make_unique<EINSTANCE>( instance, aIo ) );
1950 }
1951
1953 }
1954 else if( child->GetName() == "busses" )
1955 {
1956 for( wxXmlNode* bus = child->GetChildren(); bus; bus = bus->GetNext() )
1957 {
1958 if( bus->GetName() == "bus" )
1959 busses.emplace_back( std::make_unique<EBUS>( bus, aIo ) );
1960 }
1961
1963 }
1964 else if( child->GetName() == "nets" )
1965 {
1966 for( wxXmlNode* net = child->GetChildren(); net; net = net->GetNext() )
1967 {
1968 if( net->GetName() == "net" )
1969 nets.emplace_back( std::make_unique<ENET>( net, aIo ) );
1970 }
1971
1973 }
1974 }
1975
1977}
1978
1979
1980ESCHEMATIC_GROUP::ESCHEMATIC_GROUP( wxXmlNode* aSchematicGroup, IO_BASE* aIo ) :
1981 EAGLE_BASE( aIo )
1982{
1983 /*
1984 * <!ELEMENT schematic_group (attribute*, description?)>
1985 * <!ATTLIST schematic_group
1986 * name ID #REQUIRED
1987 * selectable %Bool; #IMPLIED
1988 * width %Dimension; #IMPLIED
1989 * titleSize %Dimension; #IMPLIED
1990 * titleFont %TextFont; #IMPLIED
1991 * style %WireStyle; #IMPLIED
1992 * showAnnotations %Bool; #IMPLIED
1993 * layer %Layer; #IMPLIED
1994 * grouprefs IDREFS #IMPLIED
1995 * >
1996 */
1997 name = parseRequiredAttribute<wxString>( aSchematicGroup, "name" );
1998 selectable = parseOptionalAttribute<bool>( aSchematicGroup, "selectable" );
1999 width = parseOptionalAttribute<ECOORD>( aSchematicGroup, "width" );
2000 titleSize = parseOptionalAttribute<ECOORD>( aSchematicGroup, "titleSize" );
2001 titleFont = parseOptionalAttribute<wxString>( aSchematicGroup, "font" );
2002 wireStyle = parseOptionalAttribute<wxString>( aSchematicGroup, "style" );
2003 showAnnotations = parseOptionalAttribute<bool>( aSchematicGroup, "showAnnotations" );
2004 layer = parseOptionalAttribute<int>( aSchematicGroup, "layer" );
2005 grouprefs = parseOptionalAttribute<wxString>( aSchematicGroup, "grouprefs" );
2006
2007 for( wxXmlNode* child = aSchematicGroup->GetChildren(); child; child = child->GetNext() )
2008 {
2009 if( child->GetName() == "description" )
2010 {
2011 description = std::make_optional<EDESCRIPTION>( child, aIo );
2012 }
2013 else if( child->GetName() == "attribute" )
2014 {
2015 attributes.emplace_back( std::make_unique<EATTR>( child, aIo ) );
2016 }
2017 }
2018
2020}
2021
2022
2023EMODULE::EMODULE( wxXmlNode* aModule, IO_BASE* aIo ) :
2024 EAGLE_BASE( aIo )
2025{
2026 /*
2027 * <!ELEMENT module (description?, ports?, variantdefs?, groups?, parts?, sheets?)>
2028 * <!ATTLIST module
2029 * name %String; #REQUIRED
2030 * prefix %String; ""
2031 * dx %Coord; #REQUIRED
2032 * dy %Coord; #REQUIRED
2033 * >
2034 */
2035 name = parseRequiredAttribute<wxString>( aModule, "name" );
2036 prefix = parseOptionalAttribute<wxString>( aModule, "prefix" );
2037 dx = parseRequiredAttribute<ECOORD>( aModule, "dx" );
2038 dy = parseRequiredAttribute<ECOORD>( aModule, "dy" );
2039
2040 for( wxXmlNode* child = aModule->GetChildren(); child; child = child->GetNext() )
2041 {
2042 if( child->GetName() == "description" )
2043 {
2044 description = std::make_optional<EDESCRIPTION>( child, aIo );
2045 }
2046 else if( child->GetName() == "ports" )
2047 {
2048 for( wxXmlNode* port = child->GetChildren(); port; port = port->GetNext() )
2049 {
2050 if( port->GetName() == "port" )
2051 {
2052 std::unique_ptr<EPORT> tmp = std::make_unique<EPORT>( port, aIo );
2053 ports[ tmp->name ] = std::move( tmp );
2054 }
2055 }
2056
2058 }
2059 else if( child->GetName() == "variantdefs" )
2060 {
2061 for( wxXmlNode* variantdef = child->GetChildren(); variantdef;
2062 variantdef = variantdef->GetNext() )
2063 {
2064 if( variantdef->GetName() == "variantdef" )
2065 {
2066 std::unique_ptr<EVARIANTDEF> tmp = std::make_unique<EVARIANTDEF>( variantdef,
2067 aIo );
2068 variantdefs[ tmp->name ] = std::move( tmp );
2069 }
2070 }
2071
2073 }
2074 else if( child->GetName() == "groups" )
2075 {
2076 for( wxXmlNode* group = child->GetChildren(); group; group = group->GetNext() )
2077 {
2078 if( group->GetName() == "schematic_group" )
2079 {
2080 std::unique_ptr<ESCHEMATIC_GROUP> tmp =
2081 std::make_unique<ESCHEMATIC_GROUP>( group, aIo );
2082 groups[ tmp->name ] = std::move( tmp );
2083 }
2084 }
2085
2087 }
2088 else if( child->GetName() == "parts" )
2089 {
2090 for( wxXmlNode* part = child->GetChildren(); part; part = part->GetNext() )
2091 {
2092 if( part->GetName() == "part" )
2093 {
2094 std::unique_ptr<EPART> tmp = std::make_unique<EPART>( part, aIo );
2095 parts[ tmp->name ] = std::move( tmp );
2096 }
2097 }
2098
2100 }
2101 else if( child->GetName() == "sheets" )
2102 {
2103 for( wxXmlNode* sheet = child->GetChildren(); sheet; sheet = sheet->GetNext() )
2104 {
2105 if( sheet->GetName() == "sheet" )
2106 sheets.emplace_back( std::make_unique<ESHEET>( sheet, aIo ) );
2107 }
2108
2110 }
2111 }
2112
2114}
2115
2116
2117EPORT::EPORT( wxXmlNode* aPort, IO_BASE* aIo ) :
2118 EAGLE_BASE( aIo )
2119{
2120 /*
2121 * <!ELEMENT port EMPTY>
2122 * <!ATTLIST port
2123 * name %String; #REQUIRED
2124 * side %Int; #REQUIRED
2125 * coord %Coord; #REQUIRED
2126 * direction %PortDirection; "io"
2127 * >
2128 */
2129 name = parseRequiredAttribute<wxString>( aPort, "name" );
2130 side = parseRequiredAttribute<wxString>( aPort, "side" );
2131 coord = parseRequiredAttribute<ECOORD>( aPort, "coord" );
2132 direction = parseOptionalAttribute<wxString>( aPort, "direction" );
2133
2135}
2136
2137
2138EVARIANTDEF::EVARIANTDEF( wxXmlNode* aVariantDef, IO_BASE* aIo ) :
2139 EAGLE_BASE( aIo )
2140{
2141 /*
2142 * <!ELEMENT variantdef EMPTY>
2143 * <!ATTLIST variantdef
2144 * name %String; #REQUIRED
2145 * current %Bool; "no"
2146 * >
2147 */
2148 name = parseRequiredAttribute<wxString>( aVariantDef, "name" );
2149 current = parseOptionalAttribute<bool>( aVariantDef, "current" );
2150
2152}
2153
2154
2155ENOTE::ENOTE( wxXmlNode* aNote, IO_BASE* aIo ) :
2156 EAGLE_BASE( aIo )
2157{
2158 /*
2159 * <!ELEMENT note (#PCDATA)>
2160 * <!ATTLIST note
2161 * version %Real; #REQUIRED
2162 * severity %Severity; #REQUIRED
2163 * >
2164 * <!-- version: The EAGLE program version that introduced this compatibility note -->
2165 */
2166 version = parseRequiredAttribute<double>( aNote, "version" );
2167 severity = parseRequiredAttribute<wxString>( aNote, "severity" );
2168
2169 note = aNote->GetNodeContent();
2170
2172}
2173
2174
2175ECOMPATIBILITY::ECOMPATIBILITY( wxXmlNode* aCompatibility, IO_BASE* aIo ) :
2176 EAGLE_BASE( aIo )
2177{
2178 /*
2179 * <!ELEMENT compatibility (note)*>
2180 */
2181 for( wxXmlNode* child = aCompatibility->GetNext(); child; child = child->GetNext() )
2182 {
2183 if( child->GetName() == "note" )
2184 notes.emplace_back( std::make_unique<ENOTE>( child ) );
2185 }
2186
2188}
2189
2190
2191ESETTING::ESETTING( wxXmlNode* aSetting, IO_BASE* aIo ) :
2192 EAGLE_BASE( aIo )
2193{
2194 /*
2195 * <!ELEMENT setting EMPTY>
2196 * <!ATTLIST setting
2197 * alwaysvectorfont %Bool; #IMPLIED
2198 * verticaltext %VerticalText; "up"
2199 * keepoldvectorfont %Bool; "no"
2200 * >
2201 */
2202 alwaysvectorfont = parseOptionalAttribute<bool>( aSetting, "alwaysvectorfont" );
2203 verticaltext = parseOptionalAttribute<wxString>( aSetting, "verticaltext" );
2204 keepoldvectorfont = parseOptionalAttribute<bool>( aSetting, "keepoldvectorfont" );
2205
2207}
2208
2209
2210EGRID::EGRID( wxXmlNode* aGrid, IO_BASE* aIo ) :
2211 EAGLE_BASE( aIo )
2212{
2213 /*
2214 * <!ELEMENT grid EMPTY>
2215 * <!ATTLIST grid
2216 * distance %Real; #IMPLIED
2217 * unitdist %GridUnit; #IMPLIED
2218 * unit %GridUnit; #IMPLIED
2219 * style %GridStyle; "lines"
2220 * multiple %Int; "1"
2221 * display %Bool; "no"
2222 * altdistance %Real; #IMPLIED
2223 * altunitdist %GridUnit; #IMPLIED
2224 * altunit %GridUnit; #IMPLIED
2225 * >
2226 */
2227 distance = parseOptionalAttribute<double>( aGrid, "distance" );
2228 unitdist = parseOptionalAttribute<wxString>( aGrid, "unitdist" );
2229 unit = parseOptionalAttribute<wxString>( aGrid, "unit" );
2230 style = parseOptionalAttribute<wxString>( aGrid, "style" );
2231 multiple = parseOptionalAttribute<int>( aGrid, "multiple" );
2232 display = parseOptionalAttribute<bool>( aGrid, "display" );
2233 altdistance = parseOptionalAttribute<double>( aGrid, "altdistance" );
2234 altunitdist = parseOptionalAttribute<wxString>( aGrid, "altunitdist" );
2235 altunit = parseOptionalAttribute<wxString>( aGrid, "altunit" );
2236
2238}
2239
2240
2241EFILTER::EFILTER( wxXmlNode* aFilter, IO_BASE* aIo ) :
2242 EAGLE_BASE( aIo )
2243{
2244 /*
2245 * <!ELEMENT filter EMPTY>
2246 * <!ATTLIST filter
2247 * name %String; #REQUIRED
2248 * expression %String; #REQUIRED
2249 * >
2250 */
2251 name = parseRequiredAttribute<wxString>( aFilter, "name" );
2252 expression = parseRequiredAttribute<wxString>( aFilter, "expression" );
2253
2255};
2256
2257
2258EPACKAGE::EPACKAGE( wxXmlNode* aPackage, IO_BASE* aIo ) :
2259 EAGLE_BASE( aIo )
2260{
2261 /*
2262 * <!ELEMENT package (description?, (polygon | wire | text | dimension | circle |
2263 * rectangle | frame | hole | pad | smd)*)>
2264 * <!ATTLIST package
2265 * name %String; #REQUIRED
2266 * urn %Urn; ""
2267 * locally_modified %Bool; "no"
2268 * library_version %Int; ""
2269 * library_locally_modified %Bool; "no"
2270 * >
2271 * <!-- library_version and library_locally_modified: Only in managed libraries
2272 * inside boards or schematics -->
2273 */
2274 name = parseRequiredAttribute<wxString>( aPackage, "name" );
2275 urn = parseOptionalAttribute<EURN>( aPackage, "urn" );
2276 locally_modified = parseOptionalAttribute<bool>( aPackage, "locally_modified" );
2277 library_version = parseOptionalAttribute<int>( aPackage, "library_version" );
2278 library_locally_modified = parseOptionalAttribute<bool>( aPackage, "library_locally_modified" );
2279
2280 for( wxXmlNode* child = aPackage->GetChildren(); child; child = child->GetNext() )
2281 {
2282 if( child->GetName() == "description" )
2283 {
2284 description = std::make_optional<EDESCRIPTION>( child, aIo );
2285 }
2286 else if( child->GetName() == "polygon" )
2287 {
2288 polygons.emplace_back( std::make_unique<EPOLYGON>( child, aIo ) );
2289 }
2290 else if( child->GetName() == "wire" )
2291 {
2292 wires.emplace_back( std::make_unique<EWIRE>( child, aIo ) );
2293 }
2294 else if( child->GetName() == "text" )
2295 {
2296 texts.emplace_back( std::make_unique<ETEXT>( child, aIo ) );
2297 }
2298 else if( child->GetName() == "dimension" )
2299 {
2300 dimensions.emplace_back( std::make_unique<EDIMENSION>( child, aIo ) );
2301 }
2302 else if( child->GetName() == "circle" )
2303 {
2304 circles.emplace_back( std::make_unique<ECIRCLE>( child, aIo ) );
2305 }
2306 else if( child->GetName() == "rectangle" )
2307 {
2308 rectangles.emplace_back( std::make_unique<ERECT>( child, aIo ) );
2309 }
2310 else if( child->GetName() == "frame" )
2311 {
2312 frames.emplace_back( std::make_unique<EFRAME>( child, aIo ) );
2313 }
2314 else if( child->GetName() == "hole" )
2315 {
2316 holes.emplace_back( std::make_unique<EHOLE>( child, aIo ) );
2317 }
2318 else if( child->GetName() == "pad" )
2319 {
2320 thtpads.emplace_back( std::make_unique<EPAD>( child, aIo ) );
2321 }
2322 else if( child->GetName() == "smd" )
2323 {
2324 smdpads.emplace_back( std::make_unique<ESMD>( child, aIo ) );
2325 }
2326 }
2327
2329}
2330
2331
2332EPACKAGEINSTANCE::EPACKAGEINSTANCE( wxXmlNode* aPackageInstance, IO_BASE* aIo ) :
2333 EAGLE_BASE( aIo )
2334{
2335 /*
2336 * <!ELEMENT packageinstance EMPTY>
2337 * <!ATTLIST packageinstance
2338 * name %String; #REQUIRED
2339 * >
2340 */
2341 name = parseRequiredAttribute<wxString>( aPackageInstance, "name" );
2342
2344}
2345
2346
2347EPACKAGE3D::EPACKAGE3D( wxXmlNode* aPackage3d, IO_BASE* aIo ) :
2348 EAGLE_BASE( aIo )
2349{
2350 /*
2351 * <!ELEMENT package3d (description?, packageinstances?)>
2352 * <!ATTLIST package3d
2353 * name %String; ""
2354 * urn %Urn; #REQUIRED
2355 * type %Package3dType; #REQUIRED
2356 * library_version %Int; ""
2357 * library_locally_modified %Bool; "no"
2358 * >
2359 * <!-- library_version and library_locally_modified: Only in managed libraries
2360 * inside boards or schematics -->
2361 */
2362 name = parseRequiredAttribute<wxString>( aPackage3d, "name" );
2363 urn = parseRequiredAttribute<wxString>( aPackage3d, "urn" );
2364 type = parseRequiredAttribute<wxString>( aPackage3d, "type" );
2365 library_version = parseOptionalAttribute<int>( aPackage3d, "library_version" );
2366 library_locally_modified = parseOptionalAttribute<bool>( aPackage3d,
2367 "library_locally_modified" );
2368
2369 for( wxXmlNode* child = aPackage3d->GetChildren(); child; child = child->GetNext() )
2370 {
2371 if( child->GetName() == "description" )
2372 {
2373 description = std::make_optional<EDESCRIPTION>( child, aIo );
2374 }
2375 else if( child->GetName() == "packageinstances" )
2376 {
2377 for( wxXmlNode* instance = child->GetChildren(); instance;
2378 instance = instance->GetNext() )
2379 packageinstances.emplace_back( std::make_unique<EPACKAGEINSTANCE>( instance,
2380 aIo ) );
2381
2383 }
2384 }
2385
2387}
2388
2389
2390ESYMBOL::ESYMBOL( wxXmlNode* aSymbol, IO_BASE* aIo ) :
2391 EAGLE_BASE( aIo )
2392{
2393 /*
2394 * <!ELEMENT symbol (description?, (polygon | wire | text | dimension | pin | circle |
2395 * rectangle | frame)*)>
2396 * <!ATTLIST symbol
2397 * name %String; #REQUIRED
2398 * urn %Urn; ""
2399 * locally_modified %Bool; "no"
2400 * library_version %Int; ""
2401 * library_locally_modified %Bool; "no"
2402 * >
2403 * <!-- library_version and library_locally_modified: Only in managed libraries
2404 * inside boards or schematics -->
2405 */
2406
2407 name = parseRequiredAttribute<wxString>( aSymbol, "name" );
2408 urn = parseOptionalAttribute<EURN>( aSymbol, "urn" );
2409 locally_modified = parseOptionalAttribute<bool>( aSymbol, "locally_modified" );
2410 library_version = parseOptionalAttribute<int>( aSymbol, "library_version" );
2411 library_locally_modified = parseOptionalAttribute<bool>( aSymbol, "library_locally_modified" );
2412
2413 for( wxXmlNode* child = aSymbol->GetChildren(); child; child = child->GetNext() )
2414 {
2415 if( child->GetName() == "description" )
2416 {
2417 description = std::make_optional<EDESCRIPTION>( child, aIo );
2418 }
2419 else if( child->GetName() == "polygon" )
2420 {
2421 polygons.emplace_back( std::make_unique<EPOLYGON>( child, aIo ) );
2422 }
2423 else if( child->GetName() == "wire" )
2424 {
2425 wires.emplace_back( std::make_unique<EWIRE>( child, aIo ) );
2426 }
2427 else if( child->GetName() == "text" )
2428 {
2429 texts.emplace_back( std::make_unique<ETEXT>( child, aIo ) );
2430 }
2431 else if( child->GetName() == "dimension" )
2432 {
2433 dimensions.emplace_back( std::make_unique<EDIMENSION>( child, aIo ) );
2434 }
2435 else if( child->GetName() == "pin" )
2436 {
2437 pins.emplace_back( std::make_unique<EPIN>( child, aIo ) );
2438 }
2439 else if( child->GetName() == "circle" )
2440 {
2441 circles.emplace_back( std::make_unique<ECIRCLE>( child, aIo ) );
2442 }
2443 else if( child->GetName() == "rectangle" )
2444 {
2445 rectangles.emplace_back( std::make_unique<ERECT>( child, aIo ) );
2446 }
2447 else if( child->GetName() == "frame" )
2448 {
2449 frames.emplace_back( std::make_unique<EFRAME>( child, aIo ) );
2450 }
2451 }
2452
2454}
2455
2456
2457ELIBRARY::ELIBRARY( wxXmlNode* aLibrary, IO_BASE* aIo ) :
2458 EAGLE_BASE( aIo )
2459{
2460 /*
2461 * <!ELEMENT library (description?, packages?, packages3d?, symbols?, devicesets?)>
2462 * <!ATTLIST library
2463 * name %String; #REQUIRED
2464 * urn %Urn; ""
2465 * >
2466 * <!-- name: Only in libraries used inside boards or schematics -->
2467 * <!-- urn: Only in online libraries used inside boards or schematics -->
2468 */
2469
2470 // The name and urn attributes are only valid in schematic and board files.
2471 wxString parentNodeName;
2472
2473 if( aLibrary->GetParent() )
2474 parentNodeName = aLibrary->GetParent()->GetName();
2475
2476 if( parentNodeName == "libraries" )
2477 {
2478 name = parseRequiredAttribute<wxString>( aLibrary, "name" );
2479 urn = parseOptionalAttribute<EURN>( aLibrary, "urn" );
2480 }
2481
2482 for( wxXmlNode* child = aLibrary->GetChildren(); child; child = child->GetNext() )
2483 {
2484 if( child->GetName() == "description" )
2485 {
2486 description = std::make_optional<EDESCRIPTION>( child, aIo );
2487 }
2488 else if( child->GetName() == "packages" )
2489 {
2490 for( wxXmlNode* package = child->GetChildren(); package; package = package->GetNext() )
2491 {
2492 if( package->GetName() == "package" )
2493 {
2494 std::unique_ptr<EPACKAGE> tmp = std::make_unique<EPACKAGE>( package, aIo );
2495 packages[ tmp->name ] = std::move( tmp );
2496 }
2497 }
2498
2500 }
2501 else if( child->GetName() == "packages3d" )
2502 {
2503 for( wxXmlNode* package3d = child->GetChildren(); package3d;
2504 package3d = package3d->GetNext() )
2505 {
2506 if( package3d->GetName() == "package3d" )
2507 {
2508 std::unique_ptr<EPACKAGE3D> tmp = std::make_unique<EPACKAGE3D>( package3d,
2509 aIo );
2510 packages3d[ tmp->name ] = std::move( tmp );
2511 }
2512 }
2513
2515 }
2516 else if( child->GetName() == "symbols" )
2517 {
2518 for( wxXmlNode* symbol = child->GetChildren(); symbol; symbol = symbol->GetNext() )
2519 {
2520 if( symbol->GetName() == "symbol" )
2521 {
2522 std::unique_ptr<ESYMBOL> tmp = std::make_unique<ESYMBOL>( symbol, aIo );
2523 symbols[ tmp->name ] = std::move( tmp );
2524 }
2525 }
2526
2528 }
2529 else if( child->GetName() == "devicesets" )
2530 {
2531 for( wxXmlNode* deviceset = child->GetChildren(); deviceset;
2532 deviceset = deviceset->GetNext() )
2533 {
2534 if( deviceset->GetName() == "deviceset" )
2535 {
2536 std::unique_ptr<EDEVICE_SET> tmp = std::make_unique<EDEVICE_SET>( deviceset,
2537 aIo );
2538 devicesets[ tmp->name ] = std::move( tmp );
2539 }
2540 }
2541
2543 }
2544 }
2545
2547}
2548
2549
2550wxString ELIBRARY::GetName() const
2551{
2552 wxString libName = name;
2553
2554 // Use the name when no library urn exists.
2555 if( !urn )
2556 return libName;
2557
2558 // Suffix the library name with the urn library identifier. Eagle schematics can have
2559 // mulitple libraries with the same name. The urn library identifier is used to prevent
2560 // library name clashes.
2561 if( urn->IsValid() )
2562 libName += wxS( "_" ) + urn->assetId;
2563
2564 return libName;
2565}
2566
2567
2568EAPPROVED::EAPPROVED( wxXmlNode* aApproved, IO_BASE* aIo ) :
2569 EAGLE_BASE( aIo )
2570{
2571 /*
2572 * <!ELEMENT approved EMPTY>
2573 * <!ATTLIST approved
2574 * hash %String; #REQUIRED
2575 * >
2576 */
2577 hash = parseRequiredAttribute<wxString>( aApproved, "hash" );
2578
2580}
2581
2582
2583ESCHEMATIC::ESCHEMATIC( wxXmlNode* aSchematic, IO_BASE* aIo ) :
2584 EAGLE_BASE( aIo )
2585{
2586 /*
2587 * <!ELEMENT schematic (description?, libraries?, attributes?, variantdefs?, classes?,
2588 * modules?, groups?, parts?, sheets?, errors?)>
2589 * <!ATTLIST schematic
2590 * xreflabel %String; #IMPLIED
2591 * xrefpart %String; #IMPLIED
2592 * >
2593 */
2594 xreflabel = parseOptionalAttribute<wxString>( aSchematic, "xreflabel" );
2595 xrefpart = parseOptionalAttribute<wxString>( aSchematic, "xrefpart" );
2596
2597 for( wxXmlNode* child = aSchematic->GetChildren(); child; child = child->GetNext() )
2598 {
2599 if( child->GetName() == "description" )
2600 {
2601 description = std::make_optional<EDESCRIPTION>( child, aIo );
2602 }
2603 else if( child->GetName() == "libraries" )
2604 {
2605 for( wxXmlNode* library = child->GetChildren(); library; library = library->GetNext() )
2606 {
2607 if( library->GetName() == "library" )
2608 {
2609 std::unique_ptr<ELIBRARY> tmp = std::make_unique<ELIBRARY>( library, aIo );
2610
2611 wxString libName = tmp->GetName();
2612
2613 // Prevent duplicate library names. This should only happen if the Eagle
2614 // file has an invalid format.
2615 if( libraries.find( libName ) != libraries.end() )
2616 {
2617 wxString uniqueName;
2618 std::set<wxString> usedNames;
2619
2620 for( const auto& [setName, setLibrary] : libraries )
2621 usedNames.emplace( setName );
2622
2623 if( usedNames.find( libName ) != usedNames.end() )
2624 {
2625 int i = 1;
2626
2627 do
2628 {
2629 uniqueName.Format( wxS( "%s_%d" ), libName, i );
2630 i += 1;
2631 } while( usedNames.find( uniqueName ) != usedNames.end() );
2632 }
2633
2634 libName = uniqueName;
2635 }
2636
2637 libraries[ libName ] = std::move( tmp );
2638 }
2639 }
2640
2642 }
2643 else if( child->GetName() == "attributes" )
2644 {
2645 for( wxXmlNode* attribute = child->GetChildren(); attribute;
2646 attribute = attribute->GetNext() )
2647 {
2648 if( attribute->GetName() == "attribute" )
2649 {
2650 std::unique_ptr<EATTR> tmp = std::make_unique<EATTR>( attribute, aIo );
2651 attributes[ tmp->name ] = std::move( tmp );
2652 }
2653 }
2654
2656 }
2657 else if( child->GetName() == "variantdefs" )
2658 {
2659 for( wxXmlNode* variantdef = child->GetChildren(); variantdef;
2660 variantdef = variantdef->GetNext() )
2661 {
2662 if( variantdef->GetName() == "variantdef" )
2663 {
2664 std::unique_ptr<EVARIANTDEF> tmp = std::make_unique<EVARIANTDEF>( variantdef,
2665 aIo );
2666 variantdefs[ tmp->name ] = std::move( tmp );
2667 }
2668 }
2669
2671 }
2672 else if( child->GetName() == "classes" )
2673 {
2674 for( wxXmlNode* eclass = child->GetChildren(); eclass; eclass = eclass->GetNext() )
2675 {
2676 if( eclass->GetName() == "class" )
2677 {
2678 std::unique_ptr<ECLASS> tmp = std::make_unique<ECLASS>( eclass, aIo );
2679 classes[ tmp->number ] = std::move( tmp );
2680 }
2681 }
2682
2684 }
2685 else if( child->GetName() == "modules" )
2686 {
2687 for( wxXmlNode* mod = child->GetChildren(); mod; mod = mod->GetNext() )
2688 {
2689 if( mod->GetName() == "module" )
2690 {
2691 std::unique_ptr<EMODULE> tmp = std::make_unique<EMODULE>( mod, aIo );
2692 modules[ tmp->name ] = std::move( tmp );
2693 }
2694 }
2695
2697 }
2698 else if( child->GetName() == "groups" )
2699 {
2700 for( wxXmlNode* group = child->GetChildren(); group; group = group->GetNext() )
2701 {
2702 if( group->GetName() == "schematic_group" )
2703 {
2704 std::unique_ptr<ESCHEMATIC_GROUP> tmp =
2705 std::make_unique<ESCHEMATIC_GROUP>( group, aIo );
2706 groups[ tmp->name ] = std::move( tmp );
2707 }
2708 }
2709
2711 }
2712 else if( child->GetName() == "parts" )
2713 {
2714 for( wxXmlNode* part = child->GetChildren(); part; part = part->GetNext() )
2715 {
2716 if( part->GetName() == "part" )
2717 {
2718 std::unique_ptr<EPART> tmp = std::make_unique<EPART>( part, aIo );
2719 parts[ tmp->name ] = std::move( tmp );
2720 }
2721 }
2722
2724 }
2725 else if( child->GetName() == "sheets" )
2726 {
2727 for( wxXmlNode* sheet = child->GetChildren(); sheet; sheet = sheet->GetNext() )
2728 {
2729 if( sheet->GetName() == "sheet" )
2730 sheets.emplace_back( std::make_unique<ESHEET>( sheet, aIo ) );
2731 }
2732
2734 }
2735 else if( child->GetName() == "errors" )
2736 {
2737 for( wxXmlNode* error = child->GetChildren(); error; error = error->GetNext() )
2738 {
2739 if( error->GetName() == "approved" )
2740 errors.emplace_back( std::make_unique<EAPPROVED>( error, aIo ) );
2741 }
2742
2744 }
2745 }
2746
2748}
2749
2750
2751EDRAWING::EDRAWING( wxXmlNode* aDrawing, IO_BASE* aIo ) :
2752 EAGLE_BASE( aIo )
2753{
2754 /*
2755 * <!ELEMENT drawing (settings?, grid?, filters?, layers, (library | schematic | board))>
2756 */
2757 for( wxXmlNode* child = aDrawing->GetChildren(); child; child = child->GetNext() )
2758 {
2759 if( child->GetName() == "settings" )
2760 {
2761 for( wxXmlNode* setting = child->GetChildren(); setting; setting = setting->GetNext() )
2762 settings.emplace_back( std::make_unique<ESETTING>( setting, aIo ) );
2763
2765 }
2766 else if( child->GetName() == "grid" )
2767 {
2768 grid = std::make_optional<EGRID>( child, aIo );
2769 }
2770 else if( child->GetName() == "filters" )
2771 {
2772 for( wxXmlNode* filter = child->GetChildren(); filter; filter = filter->GetNext() )
2773 {
2774 if( filter->GetName() == "filter" )
2775 filters.emplace_back( std::make_unique<EFILTER>( filter, aIo ) );
2776 }
2777
2779 }
2780 else if( child->GetName() == "layers" )
2781 {
2782 for( wxXmlNode* layer = child->GetChildren(); layer; layer = layer->GetNext() )
2783 {
2784 if( layer->GetName() == "layer" )
2785 layers.emplace_back( std::make_unique<ELAYER>( layer, aIo ) );
2786 }
2787
2789 }
2790 else if( child->GetName() == "schematic" )
2791 {
2792 schematic = std::make_optional<ESCHEMATIC>( child, aIo );
2793 }
2794 else if( child->GetName() == "library" )
2795 {
2796 library = std::make_optional<ELIBRARY>( child, aIo );
2797 }
2798 }
2799
2800 // std::optional<std::unique_ptr<EBOARD>> board;
2801
2803}
2804
2805
2806EAGLE_DOC::EAGLE_DOC( wxXmlNode* aEagleDoc, IO_BASE* aIo ) :
2807 EAGLE_BASE( aIo )
2808{
2809 /*
2810 * <!ELEMENT eagle (compatibility?, drawing, compatibility?)>
2811 * <!ATTLIST eagle
2812 * version %Real; #REQUIRED
2813 * >
2814 * <!-- version: The EAGLE program version that generated this file, in the
2815 * form V.RR -->
2816 */
2817
2818 version = parseRequiredAttribute<wxString>( aEagleDoc, "version" );
2819
2820 for( wxXmlNode* child = aEagleDoc->GetChildren(); child; child = child->GetNext() )
2821 {
2822 if( child->GetName() == "compitibility" )
2823 compatibility = std::make_optional<ECOMPATIBILITY>( child, aIo );
2824 else if( child->GetName() == "drawing" )
2825 drawing = std::make_unique<EDRAWING>( child, aIo );
2826 }
2827
2829}
virtual void AdvanceProgressPhase()
Definition: io_base.cpp:133
virtual void Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Definition: io_base.cpp:124
Model an optional XML attribute.
Definition: eagle_parser.h:202
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:316
void Set(const wxString &aString)
Attempt to convert a string to the base type.
Definition: eagle_parser.h:294
OPTIONAL_XML_ATTRIBUTE()
Construct a default OPTIONAL_XML_ATTRIBUTE, whose data is not available.
Definition: eagle_parser.h:214
A small class to help profiling.
Definition: profile.h:49
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:88
double msecs(bool aSinceLast=false)
Definition: profile.h:149
EURN Convert< EURN >(const wxString &aUrn)
std::string Convert< std::string >(const wxString &aValue)
static int parseAlignment(const wxString &aAlignment)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
double Convert< double >(const wxString &aValue)
wxString escapeName(const wxString &aNetName)
Translates Eagle special characters to their counterparts in KiCad.
wxString interpretText(const wxString &aText)
Interprets special characters in Eagle text and converts them to KiCAD notation.
bool substituteVariable(wxString *aText)
Translates Eagle special text reference to a KiCad variable reference.
constexpr auto DEFAULT_ALIGNMENT
int Convert< int >(const wxString &aValue)
wxString Convert< wxString >(const wxString &aValue)
size_t GetNodeCount(const wxXmlNode *aNode)
Fetch the number of XML nodes within aNode.
EROT Convert< EROT >(const wxString &aRot)
parse an Eagle XML "rot" field.
T parseRequiredAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse aAttribute of the XML node aNode.
bool Convert< bool >(const wxString &aValue)
ECOORD Convert< ECOORD >(const wxString &aCoord)
OPTIONAL_XML_ATTRIBUTE< T > parseOptionalAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse option aAttribute of the XML node aNode.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
Convert an Eagle curve end to a KiCad center for S_ARC.
wxString convertDescription(wxString aDescr)
Converts Eagle's HTML description into KiCad description format.
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:54
#define _(s)
const wxChar *const traceEagleIo
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
SEVERITY
wxString RemoveHTMLTags(const wxString &aInput)
Removes HTML tags from a string.
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
IO_BASE * io
Definition: eagle_parser.h:405
void AdvanceProgressPhase()
void Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Send a message to the IO_BASE REPORTER object if one exists.
EAGLE_DOC(wxXmlNode *aEagleDoc, IO_BASE *aIo=nullptr)
std::optional< ECOMPATIBILITY > compatibility
wxString version
The Eagle XML file version.
std::unique_ptr< EDRAWING > drawing
EAPPROVED(wxXmlNode *aApproved, IO_BASE *aIo=nullptr)
wxString hash
opt_double ratio
Definition: eagle_parser.h:862
opt_wxString value
Definition: eagle_parser.h:856
opt_ecoord size
Definition: eagle_parser.h:859
opt_ecoord y
Definition: eagle_parser.h:858
wxString name
Definition: eagle_parser.h:855
opt_erot rot
Definition: eagle_parser.h:863
opt_int align
Definition: eagle_parser.h:874
opt_int display
Definition: eagle_parser.h:873
opt_ecoord x
Definition: eagle_parser.h:857
opt_int layer
Definition: eagle_parser.h:860
EBUS(wxXmlNode *aBus, IO_BASE *aIo=nullptr)
wxString name
std::vector< std::unique_ptr< ESEGMENT > > segments
ECOORD x
Definition: eagle_parser.h:772
ECOORD radius
Definition: eagle_parser.h:774
ECOORD y
Definition: eagle_parser.h:773
ECIRCLE(wxXmlNode *aCircle, IO_BASE *aIo=nullptr)
ECOORD width
Definition: eagle_parser.h:775
wxString number
opt_ecoord drill
std::map< wxString, ECOORD > clearanceMap
opt_ecoord width
ECLASS(wxXmlNode *aClass, IO_BASE *aIo=nullptr)
wxString name
std::vector< std::unique_ptr< ENOTE > > notes
ECOMPATIBILITY(wxXmlNode *aCompatibility, IO_BASE *aIo=nullptr)
opt_wxString contactroute
wxString pad
ECONNECT(wxXmlNode *aConnect, IO_BASE *aIo=nullptr)
wxString gate
wxString pin
@ EU_NM
nanometers
Definition: eagle_parser.h:485
@ EU_MM
millimeters
Definition: eagle_parser.h:486
@ EU_MIL
mils/thous
Definition: eagle_parser.h:488
@ EU_INCH
inches
Definition: eagle_parser.h:487
int ToSchUnits() const
Definition: eagle_parser.h:529
long long int value
Value expressed in nanometers.
Definition: eagle_parser.h:492
static long long int ConvertToNm(int aValue, enum EAGLE_UNIT aUnit)
Converts a size expressed in a certain unit to nanometers.
opt_wxString language
Definition: eagle_parser.h:474
wxString text
Definition: eagle_parser.h:473
EDESCRIPTION(wxXmlNode *aDescription, IO_BASE *aIo=nullptr)
opt_eurn urn
opt_bool uservalue
opt_bool library_locally_modified
std::vector< std::unique_ptr< EDEVICE > > devices
opt_bool locally_modified
std::optional< EDESCRIPTION > description
opt_int library_version
opt_wxString prefix
EDEVICE_SET(wxXmlNode *aDeviceSet, IO_BASE *aIo=nullptr)
std::map< wxString, std::unique_ptr< EGATE > > gates
std::optional< ESPICE > spice
wxString name
std::vector< std::unique_ptr< EPACKAGE3DINST > > package3dinstances
wxString name
std::vector< std::unique_ptr< ECONNECT > > connects
EDEVICE(wxXmlNode *aDevice, IO_BASE *aIo=nullptr)
opt_wxString package
std::vector< std::unique_ptr< ETECHNOLOGY > > technologies
opt_wxString dimensionType
Definition: eagle_parser.h:917
opt_ecoord textsize
Definition: eagle_parser.h:915
EDIMENSION(wxXmlNode *aDimension, IO_BASE *aIo=nullptr)
std::optional< ESCHEMATIC > schematic
std::optional< ELIBRARY > library
EDRAWING(wxXmlNode *aDrawing, IO_BASE *aIo=nullptr)
std::vector< std::unique_ptr< ESETTING > > settings
std::vector< std::unique_ptr< ELAYER > > layers
std::optional< EGRID > grid
std::vector< std::unique_ptr< EFILTER > > filters
EELEMENT(wxXmlNode *aElement, IO_BASE *aIo=nullptr)
wxString name
wxString library
wxString value
wxString expression
EFILTER(wxXmlNode *aGrid, IO_BASE *aIo=nullptr)
wxString name
ECOORD x1
opt_bool border_bottom
opt_bool border_left
opt_bool border_right
ECOORD y1
opt_bool border_top
int columns
ECOORD y2
EFRAME(wxXmlNode *aFrameNode, IO_BASE *aIo=nullptr)
ECOORD x2
opt_int swaplevel
ECOORD x
ECOORD y
wxString symbol
EGATE(wxXmlNode *aGate, IO_BASE *aIo=nullptr)
wxString name
opt_int addlevel
opt_wxString style
opt_int multiple
opt_wxString unit
opt_bool display
EGRID(wxXmlNode *aGrid, IO_BASE *aIo=nullptr)
opt_wxString altunit
opt_wxString unitdist
opt_wxString altunitdist
opt_double altdistance
opt_double distance
ECOORD y
ECOORD drill
ECOORD x
EHOLE(wxXmlNode *aHole, IO_BASE *aIo=nullptr)
wxString part
std::map< wxString, std::unique_ptr< EATTR > > attributes
opt_erot rot
wxString gate
opt_bool smashed
EINSTANCE(wxXmlNode *aInstance, IO_BASE *aIo=nullptr)
ECOORD y
Definition: eagle_parser.h:684
ECOORD x
Definition: eagle_parser.h:683
EJUNCTION(wxXmlNode *aJunction, IO_BASE *aIo=nullptr)
opt_erot rot
Definition: eagle_parser.h:717
opt_wxString font
Definition: eagle_parser.h:715
opt_int ratio
Definition: eagle_parser.h:716
ELABEL(wxXmlNode *aLabel, IO_BASE *aIo=nullptr)
ECOORD size
Definition: eagle_parser.h:713
opt_wxString align
Definition: eagle_parser.h:719
opt_bool xref
Definition: eagle_parser.h:718
int layer
Definition: eagle_parser.h:714
ECOORD y
Definition: eagle_parser.h:712
ECOORD x
Definition: eagle_parser.h:711
wxString name
opt_bool visible
opt_bool active
int number
ELAYER(wxXmlNode *aLayer, IO_BASE *aIo=nullptr)
std::map< wxString, std::unique_ptr< EDEVICE_SET > > devicesets
wxString GetName() const
Fetch the fully unique library name.
std::map< wxString, std::unique_ptr< EPACKAGE3D > > packages3d
std::map< wxString, std::unique_ptr< EPACKAGE > > packages
wxString name
std::optional< EDESCRIPTION > description
std::map< wxString, std::unique_ptr< ESYMBOL > > symbols
opt_eurn urn
ELIBRARY(wxXmlNode *aLibrary, IO_BASE *aIo=nullptr)
wxString name
wxString model
EMODEL(wxXmlNode *aModel, IO_BASE *aIo=nullptr)
opt_bool smashed
wxString name
EMODULEINST(wxXmlNode *aModuleInst, IO_BASE *aIo=nullptr)
opt_erot rotation
opt_int offset
opt_wxString moduleVariant
wxString moduleinst
std::map< wxString, std::unique_ptr< EPART > > parts
ECOORD dy
std::map< wxString, std::unique_ptr< ESCHEMATIC_GROUP > > groups
std::vector< std::unique_ptr< ESHEET > > sheets
std::optional< EDESCRIPTION > description
EMODULE(wxXmlNode *aModule, IO_BASE *aIo=nullptr)
opt_wxString prefix
std::map< wxString, std::unique_ptr< EVARIANTDEF > > variantdefs
ECOORD dx
wxString name
std::map< wxString, std::unique_ptr< EPORT > > ports
int netcode
Definition: eagle_parser.h:563
wxString netname
Definition: eagle_parser.h:562
std::vector< std::unique_ptr< ESEGMENT > > segments
Definition: eagle_parser.h:565
ENOTE(wxXmlNode *aNote, IO_BASE *aIo=nullptr)
wxString note
double version
wxString severity
EPACKAGE3DINST(wxXmlNode *aPackage3dInst, IO_BASE *aIo=nullptr)
wxString package3d_urn
opt_bool library_locally_modified
wxString name
std::optional< EDESCRIPTION > description
opt_int library_version
std::vector< std::unique_ptr< EPACKAGEINSTANCE > > packageinstances
wxString type
EPACKAGE3D(wxXmlNode *aPackage3d, IO_BASE *aIo=nullptr)
EPACKAGEINSTANCE(wxXmlNode *aPackageInstance, IO_BASE *aIo=nullptr)
std::vector< std::unique_ptr< EPOLYGON > > polygons
std::vector< std::unique_ptr< EPAD > > thtpads
std::vector< std::unique_ptr< ECIRCLE > > circles
std::vector< std::unique_ptr< ESMD > > smdpads
std::vector< std::unique_ptr< EDIMENSION > > dimensions
opt_bool library_locally_modified
std::vector< std::unique_ptr< EHOLE > > holes
opt_int library_version
wxString name
std::vector< std::unique_ptr< EFRAME > > frames
std::vector< std::unique_ptr< ERECT > > rectangles
std::vector< std::unique_ptr< ETEXT > > texts
std::vector< std::unique_ptr< EWIRE > > wires
std::optional< EDESCRIPTION > description
EPACKAGE(wxXmlNode *aPackage, IO_BASE *aIo=nullptr)
opt_eurn urn
opt_bool locally_modified
Structure holding common properties for through-hole and SMD pads.
opt_bool thermals
EPAD_COMMON(wxXmlNode *aPad, IO_BASE *aIo=nullptr)
opt_bool stop
wxString name
opt_erot rot
opt_ecoord diameter
opt_bool first
opt_ecoord drill
opt_int shape
EPAD(wxXmlNode *aPad, IO_BASE *aIo=nullptr)
wxString device
std::unique_ptr< ESPICE > spice
opt_bool override_locally_modified
wxString library
opt_wxString override_package_urn
opt_wxString technology
std::map< wxString, std::unique_ptr< EATTR > > attributes
opt_eurn libraryUrn
opt_wxString override_package3d_urn
EPART(wxXmlNode *aPart, IO_BASE *aIo=nullptr)
wxString deviceset
opt_wxString package3d_urn
opt_wxString value
std::map< wxString, std::unique_ptr< EVARIANT > > variants
wxString name
EPINMAPPING(wxXmlNode *aPinMap, IO_BASE *aIo=nullptr)
opt_bool iddevicewide
opt_wxString spiceprefix
opt_bool isusermap
std::vector< std::unique_ptr< EPINMAP > > pinmaps
wxString pinorder
wxString gate
wxString pin
EPINMAP(wxXmlNode *aPinMap, IO_BASE *aIo=nullptr)
wxString gate
EPINREF(wxXmlNode *aPinRef, IO_BASE *aIo=nullptr)
wxString pin
wxString part
EPIN(wxXmlNode *aPin, IO_BASE *aIo=nullptr)
ECOORD x
wxString name
opt_int swaplevel
opt_wxString visible
opt_wxString direction
opt_wxString length
opt_wxString function
opt_erot rot
ECOORD y
std::vector< std::unique_ptr< EWIRE > > wires
std::vector< std::unique_ptr< EPOLYGON > > polygons
std::vector< std::unique_ptr< ETEXT > > texts
std::vector< std::unique_ptr< ECIRCLE > > circles
EPLAIN(wxXmlNode *aPlain, IO_BASE *aIo=nullptr)
std::vector< std::unique_ptr< EFRAME > > frames
std::vector< std::unique_ptr< ESPLINE > > splines
std::vector< std::unique_ptr< ERECT > > rectangles
std::vector< std::unique_ptr< EDIMENSION > > dimensions
std::vector< std::unique_ptr< EHOLE > > holes
opt_bool orphans
opt_int rank
opt_bool thermals
opt_ecoord spacing
std::vector< std::unique_ptr< EVERTEX > > vertices
EPOLYGON(wxXmlNode *aPolygon, IO_BASE *aIo=nullptr)
ECOORD width
opt_ecoord isolate
wxString port
EPORTREF(wxXmlNode *aPortRef, IO_BASE *aIo=nullptr)
wxString moduleinst
opt_wxString direction
wxString name
EPORT(wxXmlNode *aPort, IO_BASE *aIo=nullptr)
wxString side
ECOORD coord
double size
ECOORD y
opt_erot rot
opt_wxString font
ECOORD x
EPROBE(wxXmlNode *aProbe, IO_BASE *aIo=nullptr)
opt_bool xref
ECOORD x2
Definition: eagle_parser.h:801
ECOORD y1
Definition: eagle_parser.h:800
opt_erot rot
Definition: eagle_parser.h:804
int layer
Definition: eagle_parser.h:803
ERECT(wxXmlNode *aRect, IO_BASE *aIo=nullptr)
ECOORD y2
Definition: eagle_parser.h:802
ECOORD x1
Definition: eagle_parser.h:799
Eagle rotation.
Definition: eagle_parser.h:582
double degrees
Definition: eagle_parser.h:585
bool spin
Definition: eagle_parser.h:584
bool mirror
Definition: eagle_parser.h:583
std::vector< std::unique_ptr< EATTR > > attributes
ESCHEMATIC_GROUP(wxXmlNode *aSchematicGroup, IO_BASE *aIo=nullptr)
opt_bool showAnnotations
std::optional< EDESCRIPTION > description
opt_wxString titleFont
opt_wxString grouprefs
opt_wxString wireStyle
opt_ecoord titleSize
opt_ecoord width
std::map< wxString, std::unique_ptr< EMODULE > > modules
opt_wxString xreflabel
opt_wxString xrefpart
std::map< wxString, std::unique_ptr< EATTR > > attributes
std::vector< std::unique_ptr< EAPPROVED > > errors
std::optional< EDESCRIPTION > description
std::map< wxString, std::unique_ptr< ECLASS > > classes
std::vector< std::unique_ptr< ESHEET > > sheets
std::map< wxString, std::unique_ptr< EPART > > parts
ESCHEMATIC(wxXmlNode *aSchematic, IO_BASE *aIo=nullptr)
std::map< wxString, std::unique_ptr< ELIBRARY > > libraries
std::map< wxString, std::unique_ptr< EVARIANTDEF > > variantdefs
std::map< wxString, std::unique_ptr< ESCHEMATIC_GROUP > > groups
std::vector< std::unique_ptr< EPORTREF > > portRefs
std::vector< std::unique_ptr< EPROBE > > probes
std::vector< std::unique_ptr< EPINREF > > pinRefs
ESEGMENT(wxXmlNode *aSegment, IO_BASE *aIo=nullptr)
std::vector< std::unique_ptr< EWIRE > > wires
std::vector< std::unique_ptr< EJUNCTION > > junctions
std::vector< std::unique_ptr< ELABEL > > labels
opt_bool alwaysvectorfont
opt_bool keepoldvectorfont
opt_wxString verticaltext
ESETTING(wxXmlNode *aSetting, IO_BASE *aIo=nullptr)
ESHEET(wxXmlNode *aSheet, IO_BASE *aIo=nullptr)
std::unique_ptr< EPLAIN > plain
std::vector< std::unique_ptr< ENET > > nets
std::vector< std::unique_ptr< EBUS > > busses
opt_wxString description
std::vector< std::unique_ptr< EINSTANCE > > instances
std::map< wxString, std::unique_ptr< EMODULEINST > > moduleinsts
opt_int roundness
ECOORD dx
int layer
opt_bool cream
ECOORD dy
ESMD(wxXmlNode *aSMD, IO_BASE *aIo=nullptr)
ESPICE(wxXmlNode *aSpice, IO_BASE *aIo=nullptr)
std::unique_ptr< EMODEL > model
std::unique_ptr< EPINMAPPING > pinmapping
std::vector< std::unique_ptr< EVERTEX > > vertices
Definition: eagle_parser.h:820
double width
Definition: eagle_parser.h:821
ESPLINE(wxXmlNode *aSpline, IO_BASE *aIo=nullptr)
std::vector< std::unique_ptr< EFRAME > > frames
opt_int library_version
std::optional< EDESCRIPTION > description
std::vector< std::unique_ptr< EPIN > > pins
std::vector< std::unique_ptr< ECIRCLE > > circles
opt_bool library_locally_modified
std::vector< std::unique_ptr< ETEXT > > texts
std::vector< std::unique_ptr< EPOLYGON > > polygons
opt_eurn urn
std::vector< std::unique_ptr< ERECT > > rectangles
std::vector< std::unique_ptr< EWIRE > > wires
ESYMBOL(wxXmlNode *aSymbol, IO_BASE *aIo=nullptr)
opt_bool locally_modified
wxString name
std::vector< std::unique_ptr< EDIMENSION > > dimensions
wxString name
std::vector< std::unique_ptr< EATTR > > attributes
ETECHNOLOGY(wxXmlNode *aTechnology, IO_BASE *aIo=nullptr)
opt_double ratio
Definition: eagle_parser.h:957
wxString text
Definition: eagle_parser.h:951
ECOORD y
Definition: eagle_parser.h:953
ECOORD size
Definition: eagle_parser.h:954
ETEXT(wxXmlNode *aText, IO_BASE *aIo=nullptr)
opt_erot rot
Definition: eagle_parser.h:958
opt_int align
Definition: eagle_parser.h:974
ECOORD x
Definition: eagle_parser.h:952
VECTOR2I ConvertSize() const
Calculate text size based on font type and size.
opt_wxString font
Definition: eagle_parser.h:956
@ BOTTOM_CENTER
Definition: eagle_parser.h:969
@ BOTTOM_RIGHT
Definition: eagle_parser.h:971
@ TOP_CENTER
Definition: eagle_parser.h:963
@ TOP_LEFT
Definition: eagle_parser.h:964
@ TOP_RIGHT
Definition: eagle_parser.h:965
@ CENTER_RIGHT
Definition: eagle_parser.h:968
@ CENTER_LEFT
Definition: eagle_parser.h:962
@ BOTTOM_LEFT
Definition: eagle_parser.h:970
int layer
Definition: eagle_parser.h:955
Container that parses Eagle library file "urn" definitions.
Definition: eagle_parser.h:433
bool IsValid() const
Check if the string passed to the ctor was a valid Eagle urn.
wxString host
Should always be "urn".
Definition: eagle_parser.h:449
void Parse(const wxString &aUrn)
wxString assetVersion
May be empty depending on the asset type.
Definition: eagle_parser.h:453
wxString assetId
The unique asset identifier for the asset type.
Definition: eagle_parser.h:452
wxString assetType
Must be "symbol", "footprint", "package", "component", or "library".
Definition: eagle_parser.h:451
wxString path
Path to the asset type below.
Definition: eagle_parser.h:450
EVARIANTDEF(wxXmlNode *aVariantDef, IO_BASE *aIo=nullptr)
opt_bool current
wxString name
opt_bool populate
opt_wxString technology
EVARIANT(wxXmlNode *aVariant, IO_BASE *aIo=nullptr)
wxString name
opt_wxString value
EVERTEX(wxXmlNode *aVertex, IO_BASE *aIo=nullptr)
ECOORD y
Definition: eagle_parser.h:614
ECOORD x
Definition: eagle_parser.h:613
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:615
opt_ecoord diam
Definition: eagle_parser.h:748
ECOORD drill
< inclusive
Definition: eagle_parser.h:747
ECOORD y
Definition: eagle_parser.h:744
EVIA(wxXmlNode *aVia, IO_BASE *aIo=nullptr)
opt_wxString shape
Definition: eagle_parser.h:749
int layer_front_most
Definition: eagle_parser.h:745
int layer_back_most
< extent
Definition: eagle_parser.h:746
ECOORD x
Definition: eagle_parser.h:743
ECOORD width
Definition: eagle_parser.h:646
int layer
Definition: eagle_parser.h:647
EWIRE(wxXmlNode *aWire, IO_BASE *aIo=nullptr)
ECOORD x2
Definition: eagle_parser.h:644
opt_int cap
Definition: eagle_parser.h:663
opt_int style
Definition: eagle_parser.h:656
ECOORD y2
Definition: eagle_parser.h:645
ECOORD x1
Definition: eagle_parser.h:642
@ LONGDASH
Definition: eagle_parser.h:651
@ CONTINUOUS
Definition: eagle_parser.h:650
@ SHORTDASH
Definition: eagle_parser.h:652
ECOORD y1
Definition: eagle_parser.h:643
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:657
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:82
VECTOR2I center
wxLogTrace helper definitions.
double DEG2RAD(double deg)
Definition: trigo.h:166
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695