/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2012-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017 CERN. * * @author Alejandro GarcĂ­a Montoro * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include #include #include #include #include constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT; wxString escapeName( const wxString& aNetName ) { wxString ret( aNetName ); ret.Replace( "!", "~" ); return ConvertToNewOverbarNotation( ret ); } wxString interpretText( const wxString& aText ) { wxString token = aText; if( substituteVariable( &token ) ) return token; wxString text; bool sectionOpen = false; for( wxString::size_type i = 0; i < aText.size(); i++ ) { // Interpret escaped characters if( aText[ i ] == '\\' ) { if( i + 1 != aText.size() ) text.Append( aText[ i + 1 ] ); i++; continue; } // Escape ~ for KiCAD if( aText[i] == '~' ) { text.Append( '~' ); text.Append( '~' ); continue; } if( aText[ i ] == '!' ) { if( sectionOpen ) { text.Append( '~' ); sectionOpen = false; continue; } static wxString escapeChars( wxT( " )]}'\"" ) ); if( i + 1 != aText.size() && escapeChars.Find( aText[i + 1] ) == wxNOT_FOUND ) { sectionOpen = true; text.Append( '~' ); } else { text.Append( aText[ i ] ); } continue; } if( aText[i] == ',' && sectionOpen ) { text.Append( '~' ); sectionOpen = false; } text.Append( aText[ i ] ); } return text; } bool substituteVariable( wxString* aText ) { if( aText->StartsWith( '>' ) && aText->AfterFirst( ' ' ).IsEmpty() ) { wxString token = aText->Upper(); if ( token == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" ); else if( token == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" ); else if( token == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" ); else if( token == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" ); else if( token == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" ); else if( token == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" ); else if( token == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" ); else if( token == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" ); else if( token == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" ); else if( token == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" ); else if( token == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" ); else if( token == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" ); else if( token == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" ); else if( token == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" ); else if( token == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" ); else if( token == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" ); else *aText = wxString::Format( wxS( "${%s}" ), aText->Mid( 1 ).Trim() ); return true; } return false; } wxString convertDescription( wxString aDescr ) { aDescr.Replace( wxS( "\n" ), wxS( " " ) ); aDescr.Replace( wxS( "\r" ), wxEmptyString ); wxRegEx( wxS( "]*?\\s+)?href=\"([^\"]*)\"[^>]*>" ) ) .ReplaceAll( &aDescr, wxS( "\\1 " ) ); aDescr.Replace( wxS( "

" ), wxS( "\n\n" ) ); aDescr.Replace( wxS( "

" ), wxS( "\n\n" ) ); aDescr.Replace( wxS( "
" ), wxS( "\n" ) ); aDescr.Replace( wxS( "
    " ), wxS( "\n" ) ); aDescr.Replace( wxS( "
" ), wxS( "\n\n" ) ); aDescr.Replace( wxS( "
  • " ), wxS( "\n" ) ); aDescr.Replace( wxS( "
  • " ), wxS( "\n \u2022 " ) ); // Bullet point aDescr = RemoveHTMLTags( aDescr ); wxRegEx( wxS( "\n +" ) ).ReplaceAll( &aDescr, wxS( "\n" ) ); wxRegEx( wxS( " +\n" ) ).ReplaceAll( &aDescr, wxS( "\n" ) ); wxRegEx( wxS( "\n{3,}" ) ).ReplaceAll( &aDescr, wxS( "\n\n" ) ); wxRegEx( wxS( "^\n+" ) ).ReplaceAll( &aDescr, wxEmptyString ); wxRegEx( wxS( "\n+$" ) ).ReplaceAll( &aDescr, wxEmptyString ); return aDescr; } size_t GetNodeCount( const wxXmlNode* aNode ) { size_t cnt = 0; PROF_TIMER timer; std::function countNodes = [&]( const wxXmlNode* node ) { size_t count = 0; while( node ) { if( const wxXmlNode* child = node->GetChildren() ) count += countNodes( child ); else count++; node = node->GetNext(); } return count; }; cnt = countNodes( aNode ); timer.Stop(); wxLogTrace( traceEagleIo, wxS( "XML node '%s' count = %zu took %0.4f ms." ), aNode->GetName(), cnt, timer.msecs() ); return cnt; } template<> template<> OPTIONAL_XML_ATTRIBUTE::OPTIONAL_XML_ATTRIBUTE( wxString aData ) { m_isAvailable = !aData.IsEmpty(); if( m_isAvailable ) Set( aData ); } ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit ) { // This array is used to adjust the fraction part value basing on the number of digits // in the fraction. constexpr int DIVIDERS[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; constexpr unsigned int DIVIDERS_MAX_IDX = sizeof( DIVIDERS ) / sizeof( DIVIDERS[0] ) - 1; int integer, fraction, pre_fraction, post_fraction; // The following check is needed to handle correctly negative fractions where the integer // part == 0. bool negative = ( aValue[0] == '-' ); // %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3 // digits. int ret = sscanf( aValue.c_str(), "%d.%n%d%n", &integer, &pre_fraction, &fraction, &post_fraction ); if( ret == 0 ) throw XML_PARSER_ERROR( "Invalid coordinate" ); // process the integer part value = ConvertToNm( integer, aUnit ); // process the fraction part if( ret == 2 ) { int digits = post_fraction - pre_fraction; // adjust the number of digits if necessary as we cannot handle anything smaller than // nanometers (rounding). if( (unsigned) digits > DIVIDERS_MAX_IDX ) { int diff = digits - DIVIDERS_MAX_IDX; digits = DIVIDERS_MAX_IDX; fraction /= DIVIDERS[diff]; } int frac_value = ConvertToNm( fraction, aUnit ) / DIVIDERS[digits]; // keep the sign in mind value = negative ? value - frac_value : value + frac_value; } } long long int ECOORD::ConvertToNm( int aValue, enum EAGLE_UNIT aUnit ) { long long int ret; switch( aUnit ) { default: case EU_NM: ret = aValue; break; case EU_MM: ret = (long long) aValue * 1000000; break; case EU_INCH: ret = (long long) aValue * 25400000; break; case EU_MIL: ret = (long long) aValue * 25400; break; } if( ( ret > 0 ) != ( aValue > 0 ) ) wxLogError( _( "Invalid size %lld: too large" ), aValue ); return ret; } // Template specializations below parse wxString to the used types: // - wxString (preferred) // - string // - double // - int // - bool // - EROT // - ECOORD template <> wxString Convert( const wxString& aValue ) { return aValue; } template <> std::string Convert( const wxString& aValue ) { return std::string( aValue.ToUTF8() ); } template <> double Convert( const wxString& aValue ) { double value; if( aValue.ToCDouble( &value ) ) return value; else throw XML_PARSER_ERROR( "Conversion to double failed. Original value: '" + aValue.ToStdString() + "'." ); } template <> int Convert( const wxString& aValue ) { if( aValue.IsEmpty() ) throw XML_PARSER_ERROR( "Conversion to int failed. Original value is empty." ); return wxAtoi( aValue ); } template <> bool Convert( const wxString& aValue ) { if( aValue != "yes" && aValue != "no" ) throw XML_PARSER_ERROR( "Conversion to bool failed. Original value, '" + aValue.ToStdString() + "', is neither 'yes' nor 'no'." ); return aValue == "yes"; } /// parse an Eagle XML "rot" field. Unfortunately the DTD seems not to explain /// this format very well. [S][M]R. Examples: "R90", "MR180", "SR180" template<> EROT Convert( const wxString& aRot ) { EROT value; value.spin = aRot.find( 'S' ) != aRot.npos; value.mirror = aRot.find( 'M' ) != aRot.npos; value.degrees = strtod( aRot.c_str() + 1 // skip leading 'R' + int( value.spin ) // skip optional leading 'S' + int( value.mirror ), // skip optional leading 'M' nullptr ); return value; } template<> ECOORD Convert( const wxString& aCoord ) { // Eagle uses millimeters as the default unit return ECOORD( aCoord, ECOORD::EAGLE_UNIT::EU_MM ); } /** * Parse \a aAttribute of the XML node \a aNode. * * @param aNode is the node whose attribute will be parsed. * @param aAttribute is the attribute that will be parsed. * @throw XML_PARSER_ERROR - exception thrown if the required attribute is missing * @return T - the attributed parsed as the specified type. */ template T parseRequiredAttribute( wxXmlNode* aNode, const wxString& aAttribute ) { wxString value; if( aNode->GetAttribute( aAttribute, &value ) ) return Convert( value ); else throw XML_PARSER_ERROR( "The required attribute " + aAttribute + " is missing at " "line " + wxString::Format( "%d", aNode->GetLineNumber() ) + "." ); } /** * Parse option \a aAttribute of the XML node \a aNode. * * @param aNode is the node whose attribute will be parsed. * @param aAttribute is the attribute that will be parsed. * @return OPTIONAL_XML_ATTRIBUTE - an optional XML attribute, parsed as the specified type if * found. */ template OPTIONAL_XML_ATTRIBUTE parseOptionalAttribute( wxXmlNode* aNode, const wxString& aAttribute ) { return OPTIONAL_XML_ATTRIBUTE( aNode->GetAttribute( aAttribute ) ); } NODE_MAP MapChildren( wxXmlNode* aCurrentNode ) { // Map node_name -> node_pointer NODE_MAP nodesMap; // Loop through all children mapping them in nodesMap if( aCurrentNode ) aCurrentNode = aCurrentNode->GetChildren(); while( aCurrentNode ) { // Create a new pair in the map // key: current node name // value: current node pointer nodesMap[aCurrentNode->GetName()] = aCurrentNode; // Get next child aCurrentNode = aCurrentNode->GetNext(); } return nodesMap; } VECTOR2I ConvertArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle ) { // Eagle give us start and end. // S_ARC wants start to give the center, and end to give the start. double dx = aEnd.x - aStart.x, dy = aEnd.y - aStart.y; VECTOR2I mid = ( aStart + aEnd ) / 2; double dlen = sqrt( dx*dx + dy*dy ); if( !std::isnormal( dlen ) || !std::isnormal( aAngle ) ) { THROW_IO_ERROR( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ), dlen, aAngle ) ); } double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) ); VECTOR2I center( mid.x + dist * ( dy / dlen ), mid.y - dist * ( dx / dlen ) ); return center; } static int parseAlignment( const wxString& aAlignment ) { // (bottom-left | bottom-center | bottom-right | center-left | // center | center-right | top-left | top-center | top-right) if( aAlignment == "center" ) return ETEXT::CENTER; else if( aAlignment == "center-right" ) return ETEXT::CENTER_RIGHT; else if( aAlignment == "top-left" ) return ETEXT::TOP_LEFT; else if( aAlignment == "top-center" ) return ETEXT::TOP_CENTER; else if( aAlignment == "top-right" ) return ETEXT::TOP_RIGHT; else if( aAlignment == "bottom-left" ) return ETEXT::BOTTOM_LEFT; else if( aAlignment == "bottom-center" ) return ETEXT::BOTTOM_CENTER; else if( aAlignment == "bottom-right" ) return ETEXT::BOTTOM_RIGHT; else if( aAlignment == "center-left" ) return ETEXT::CENTER_LEFT; return DEFAULT_ALIGNMENT; } void EAGLE_BASE::Report( const wxString& aMsg, SEVERITY aSeverity ) { if( !io ) return; io->Report( aMsg, aSeverity ); } void EAGLE_BASE::AdvanceProgressPhase() { if( !io ) return; io->AdvanceProgressPhase(); } EWIRE::EWIRE( wxXmlNode* aWire, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x1 = parseRequiredAttribute( aWire, "x1" ); y1 = parseRequiredAttribute( aWire, "y1" ); x2 = parseRequiredAttribute( aWire, "x2" ); y2 = parseRequiredAttribute( aWire, "y2" ); width = parseRequiredAttribute( aWire, "width" ); layer = parseRequiredAttribute( aWire, "layer" ); curve = parseOptionalAttribute( aWire, "curve" ); opt_wxString s = parseOptionalAttribute( aWire, "style" ); if( s == "continuous" ) style = EWIRE::CONTINUOUS; else if( s == "longdash" ) style = EWIRE::LONGDASH; else if( s == "shortdash" ) style = EWIRE::SHORTDASH; else if( s == "dashdot" ) style = EWIRE::DASHDOT; s = parseOptionalAttribute( aWire, "cap" ); if( s == "round" ) cap = EWIRE::ROUND; else if( s == "flat" ) cap = EWIRE::FLAT; AdvanceProgressPhase(); } ESEGMENT::ESEGMENT( wxXmlNode* aSegment, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ for( wxXmlNode* child = aSegment->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "pinref" ) pinRefs.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "portref" ) portRefs.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "wire" ) wires.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "junction" ) junctions.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "label" ) labels.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "probe" ) probes.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } EBUS::EBUS( wxXmlNode* aBus, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aBus, "name" ); for( wxXmlNode* child = aBus->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "segment" ) segments.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } EJUNCTION::EJUNCTION( wxXmlNode* aJunction, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x = parseRequiredAttribute( aJunction, "x" ); y = parseRequiredAttribute( aJunction, "y" ); AdvanceProgressPhase(); } ELABEL::ELABEL( wxXmlNode* aLabel, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * * */ x = parseRequiredAttribute( aLabel, "x" ); y = parseRequiredAttribute( aLabel, "y" ); size = parseRequiredAttribute( aLabel, "size" ); layer = parseRequiredAttribute( aLabel, "layer" ); font = parseOptionalAttribute( aLabel, "font" ); ratio = parseOptionalAttribute( aLabel, "ratio" ); rot = parseOptionalAttribute( aLabel, "rot" ); xref = parseOptionalAttribute( aLabel, "xref" ); align = parseOptionalAttribute( aLabel, "align" ); AdvanceProgressPhase(); } ENET::ENET( wxXmlNode* aNet, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ netname = parseRequiredAttribute( aNet, "name" ); netcode = parseRequiredAttribute( aNet, "class" ); for( wxXmlNode* segment = aNet->GetChildren(); segment; segment = segment->GetNext() ) segments.emplace_back( std::make_unique( segment ) ); AdvanceProgressPhase(); } EVIA::EVIA( wxXmlNode* aVia, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x = parseRequiredAttribute( aVia, "x" ); y = parseRequiredAttribute( aVia, "y" ); wxString ext = parseRequiredAttribute( aVia, "extent" ); sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most ); drill = parseRequiredAttribute( aVia, "drill" ); diam = parseOptionalAttribute( aVia, "diameter" ); shape = parseOptionalAttribute( aVia, "shape" ); AdvanceProgressPhase(); } ECIRCLE::ECIRCLE( wxXmlNode* aCircle, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x = parseRequiredAttribute( aCircle, "x" ); y = parseRequiredAttribute( aCircle, "y" ); radius = parseRequiredAttribute( aCircle, "radius" ); width = parseRequiredAttribute( aCircle, "width" ); layer = parseRequiredAttribute( aCircle, "layer" ); AdvanceProgressPhase(); } ERECT::ERECT( wxXmlNode* aRect, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x1 = parseRequiredAttribute( aRect, "x1" ); y1 = parseRequiredAttribute( aRect, "y1" ); x2 = parseRequiredAttribute( aRect, "x2" ); y2 = parseRequiredAttribute( aRect, "y2" ); layer = parseRequiredAttribute( aRect, "layer" ); rot = parseOptionalAttribute( aRect, "rot" ); AdvanceProgressPhase(); } EDESCRIPTION::EDESCRIPTION( wxXmlNode* aDescription, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ text = aDescription->GetNodeContent(); language = parseOptionalAttribute( aDescription, "language" ); AdvanceProgressPhase(); } EATTR::EATTR( wxXmlNode* aTree, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * or context -- * constant %Bool; "no" -- only in context -- * > */ name = parseRequiredAttribute( aTree, "name" ); value = parseOptionalAttribute( aTree, "value" ); x = parseOptionalAttribute( aTree, "x" ); y = parseOptionalAttribute( aTree, "y" ); size = parseOptionalAttribute( aTree, "size" ); layer = parseOptionalAttribute( aTree, "layer" ); ratio = parseOptionalAttribute( aTree, "ratio" ); rot = parseOptionalAttribute( aTree, "rot" ); opt_wxString stemp = parseOptionalAttribute( aTree, "display" ); // (off | value | name | both) if( stemp == "off" ) display = EATTR::Off; else if( stemp == "name" ) display = EATTR::NAME; else if( stemp == "both" ) display = EATTR::BOTH; else // "value" is the default display = EATTR::VALUE; stemp = parseOptionalAttribute( aTree, "align" ); align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT; AdvanceProgressPhase(); } EPINREF::EPINREF( wxXmlNode* aPinRef, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ part = parseRequiredAttribute( aPinRef, "part" ); gate = parseRequiredAttribute( aPinRef, "gate" ); pin = parseRequiredAttribute( aPinRef, "pin" ); AdvanceProgressPhase(); } EPORTREF::EPORTREF( wxXmlNode* aPortRef, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ moduleinst = parseRequiredAttribute( aPortRef, "moduleinst" ); port = parseRequiredAttribute( aPortRef, "port" ); AdvanceProgressPhase(); } EPROBE::EPROBE( wxXmlNode* aProbe, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * * */ x = parseRequiredAttribute( aProbe, "x" ); y = parseRequiredAttribute( aProbe, "y" ); size = parseRequiredAttribute( aProbe, "size" ); layer = parseRequiredAttribute( aProbe, "layer" ); font = parseOptionalAttribute( aProbe, "font" ); ratio = parseOptionalAttribute( aProbe, "ratio" ); rot = parseOptionalAttribute( aProbe, "rot" ); xref = parseOptionalAttribute( aProbe, "xref" ); AdvanceProgressPhase(); } EDIMENSION::EDIMENSION( wxXmlNode* aDimension, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x1 = parseRequiredAttribute( aDimension, wxT( "x1" ) ); y1 = parseRequiredAttribute( aDimension, wxT( "y1" ) ); x2 = parseRequiredAttribute( aDimension, wxT( "x2" ) ); y2 = parseRequiredAttribute( aDimension, wxT( "y2" ) ); x3 = parseRequiredAttribute( aDimension, wxT( "x3" ) ); y3 = parseRequiredAttribute( aDimension, wxT( "y3" ) ); textsize = parseOptionalAttribute( aDimension, wxT( "textsize" ) ); layer = parseRequiredAttribute( aDimension, wxT( "layer" ) ); dimensionType = parseOptionalAttribute( aDimension, wxT( "dtype" ) ); AdvanceProgressPhase(); } ETEXT::ETEXT( wxXmlNode* aText, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* */ text = aText->GetNodeContent(); x = parseRequiredAttribute( aText, "x" ); y = parseRequiredAttribute( aText, "y" ); size = parseRequiredAttribute( aText, "size" ); layer = parseRequiredAttribute( aText, "layer" ); font = parseOptionalAttribute( aText, "font" ); ratio = parseOptionalAttribute( aText, "ratio" ); rot = parseOptionalAttribute( aText, "rot" ); opt_wxString stemp = parseOptionalAttribute( aText, "align" ); align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT; AdvanceProgressPhase(); } VECTOR2I ETEXT::ConvertSize() const { VECTOR2I textsize; if( font ) { const wxString& fontName = font.CGet(); if( fontName == "vector" ) { textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() ); } else if( fontName == "fixed" ) { textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() * 0.80 ); } else { textsize = VECTOR2I( size.ToSchUnits(), size.ToSchUnits() ); } } else { textsize = VECTOR2I( size.ToSchUnits() * 0.85, size.ToSchUnits() ); } return textsize; } EFRAME::EFRAME( wxXmlNode* aFrameNode, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ border_left = true; border_top = true; border_right = true; border_bottom = true; x1 = parseRequiredAttribute( aFrameNode, "x1" ); y1 = parseRequiredAttribute( aFrameNode, "y1" ); x2 = parseRequiredAttribute( aFrameNode, "x2" ); y2 = parseRequiredAttribute( aFrameNode, "y2" ); columns = parseRequiredAttribute( aFrameNode, "columns" ); rows = parseRequiredAttribute( aFrameNode, "rows" ); layer = parseRequiredAttribute( aFrameNode, "layer" ); border_left = parseOptionalAttribute( aFrameNode, "border-left" ); border_top = parseOptionalAttribute( aFrameNode, "border-top" ); border_right = parseOptionalAttribute( aFrameNode, "border-right" ); border_bottom = parseOptionalAttribute( aFrameNode, "border-bottom" ); AdvanceProgressPhase(); } EPAD_COMMON::EPAD_COMMON( wxXmlNode* aPad, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { // #REQUIRED says DTD, throw exception if not found name = parseRequiredAttribute( aPad, "name" ); x = parseRequiredAttribute( aPad, "x" ); y = parseRequiredAttribute( aPad, "y" ); rot = parseOptionalAttribute( aPad, "rot" ); stop = parseOptionalAttribute( aPad, "stop" ); thermals = parseOptionalAttribute( aPad, "thermals" ); } EPAD::EPAD( wxXmlNode* aPad, IO_BASE* aIo ) : EPAD_COMMON( aPad, aIo ) { /* */ // #REQUIRED says DTD, throw exception if not found drill = parseRequiredAttribute( aPad, "drill" ); // Optional attributes diameter = parseOptionalAttribute( aPad, "diameter" ); opt_wxString s = parseOptionalAttribute( aPad, "shape" ); // (square | round | octagon | long | offset) if( s == "square" ) shape = EPAD::SQUARE; else if( s == "round" ) shape = EPAD::ROUND; else if( s == "octagon" ) shape = EPAD::OCTAGON; else if( s == "long" ) shape = EPAD::LONG; else if( s == "offset" ) shape = EPAD::OFFSET; first = parseOptionalAttribute( aPad, "first" ); AdvanceProgressPhase(); } ESMD::ESMD( wxXmlNode* aSMD, IO_BASE* aIo ) : EPAD_COMMON( aSMD, aIo ) { /* */ // DTD #REQUIRED, throw exception if not found dx = parseRequiredAttribute( aSMD, "dx" ); dy = parseRequiredAttribute( aSMD, "dy" ); layer = parseRequiredAttribute( aSMD, "layer" ); roundness = parseOptionalAttribute( aSMD, "roundness" ); cream = parseOptionalAttribute( aSMD, "cream" ); AdvanceProgressPhase(); } EPIN::EPIN( wxXmlNode* aPin, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* */ // DTD #REQUIRED, throw exception if not found name = parseRequiredAttribute( aPin, "name" ); x = parseRequiredAttribute( aPin, "x" ); y = parseRequiredAttribute( aPin, "y" ); visible = parseOptionalAttribute( aPin, "visible" ); length = parseOptionalAttribute( aPin, "length" ); direction = parseOptionalAttribute( aPin, "direction" ); function = parseOptionalAttribute( aPin, "function" ); swaplevel = parseOptionalAttribute( aPin, "swaplevel" ); rot = parseOptionalAttribute( aPin, "rot" ); AdvanceProgressPhase(); } EVERTEX::EVERTEX( wxXmlNode* aVertex, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ x = parseRequiredAttribute( aVertex, "x" ); y = parseRequiredAttribute( aVertex, "y" ); curve = parseOptionalAttribute( aVertex, "curve" ); AdvanceProgressPhase(); } EPOLYGON::EPOLYGON( wxXmlNode* aPolygon, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * * * * * */ width = parseRequiredAttribute( aPolygon, "width" ); layer = parseRequiredAttribute( aPolygon, "layer" ); spacing = parseOptionalAttribute( aPolygon, "spacing" ); isolate = parseOptionalAttribute( aPolygon, "isolate" ); opt_wxString s = parseOptionalAttribute( aPolygon, "pour" ); // default pour to solid fill pour = EPOLYGON::SOLID; // (solid | hatch | cutout) if( s == "hatch" ) pour = EPOLYGON::HATCH; else if( s == "cutout" ) pour = EPOLYGON::CUTOUT; orphans = parseOptionalAttribute( aPolygon, "orphans" ); thermals = parseOptionalAttribute( aPolygon, "thermals" ); rank = parseOptionalAttribute( aPolygon, "rank" ); for( wxXmlNode* child = aPolygon->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "vertex" ) vertices.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } ESPLINE::ESPLINE( wxXmlNode* aSpline, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ width = parseRequiredAttribute( aSpline, "width" ); for( wxXmlNode* child = aSpline->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "vertex" ) vertices.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } EVARIANT::EVARIANT( wxXmlNode* aVariant, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aVariant, "name" ); populate = parseOptionalAttribute( aVariant, "populate" ); value = parseOptionalAttribute( aVariant, "value" ); technology = parseOptionalAttribute( aVariant, "technology" ); AdvanceProgressPhase(); } EMODEL::EMODEL( wxXmlNode* aModel, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aModel, "name" ); model = aModel->GetNodeContent(); AdvanceProgressPhase(); } EPINMAP::EPINMAP( wxXmlNode* aPinMap, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ gate = parseRequiredAttribute( aPinMap, "gate" ); pin = parseRequiredAttribute( aPinMap, "pin" ); pinorder = parseRequiredAttribute( aPinMap, "pinorder" ); AdvanceProgressPhase(); } EPINMAPPING::EPINMAPPING( wxXmlNode* aPinMapping, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ isusermap = parseOptionalAttribute( aPinMapping, "isusermap" ); iddevicewide = parseOptionalAttribute( aPinMapping, "iddevicewide" ); spiceprefix = parseOptionalAttribute( aPinMapping, "spiceprefix" ); for( wxXmlNode* child = aPinMapping->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "pinmap" ) pinmaps.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } ESPICE::ESPICE( wxXmlNode* aSpice, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * */ pinmapping = std::make_unique( aSpice ); if( aSpice->GetName() == "model" ) model = std::make_unique( aSpice ); AdvanceProgressPhase(); } EHOLE::EHOLE( wxXmlNode* aHole, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* */ // #REQUIRED: x = parseRequiredAttribute( aHole, "x" ); y = parseRequiredAttribute( aHole, "y" ); drill = parseRequiredAttribute( aHole, "drill" ); AdvanceProgressPhase(); } EELEMENT::EELEMENT( wxXmlNode* aElement, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* */ // #REQUIRED name = parseRequiredAttribute( aElement, "name" ); library = parseRequiredAttribute( aElement, "library" ); value = parseRequiredAttribute( aElement, "value" ); std::string p = parseRequiredAttribute( aElement, "package" ); ReplaceIllegalFileNameChars( &p, '_' ); package = wxString::FromUTF8( p.c_str() ); x = parseRequiredAttribute( aElement, "x" ); y = parseRequiredAttribute( aElement, "y" ); // optional library_urn = parseOptionalAttribute( aElement, "library_urn" ); locked = parseOptionalAttribute( aElement, "locked" ); smashed = parseOptionalAttribute( aElement, "smashed" ); rot = parseOptionalAttribute( aElement, "rot" ); for( wxXmlNode* child = aElement->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "attribute" ) { std::unique_ptr attr = std::make_unique( child, aIo ); attributes[ attr->name ] = std::move( attr ); } else if( child->GetName() == "variant" ) { std::unique_ptr variant = std::make_unique( child, aIo ); variants[ variant->name ] = std::move( variant ); } } AdvanceProgressPhase(); } ELAYER::ELAYER( wxXmlNode* aLayer, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* */ number = parseRequiredAttribute( aLayer, "number" ); name = parseRequiredAttribute( aLayer, "name" ); color = parseRequiredAttribute( aLayer, "color" ); fill = parseRequiredAttribute( aLayer, "fill" ); visible = parseOptionalAttribute( aLayer, "visible" ); active = parseOptionalAttribute( aLayer, "active" ); AdvanceProgressPhase(); } EPART::EPART( wxXmlNode* aPart, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aPart, "name" ); library = parseRequiredAttribute( aPart, "library" ); libraryUrn = parseOptionalAttribute( aPart, "library_urn" ); deviceset = parseRequiredAttribute( aPart, "deviceset" ); device = parseRequiredAttribute( aPart, "device" ); package3d_urn = parseOptionalAttribute( aPart, "package3d_urn" ); override_package3d_urn = parseOptionalAttribute( aPart, "override_package3d_urn" ); override_package_urn = parseOptionalAttribute( aPart, "override_package_urn" ); override_locally_modified = parseOptionalAttribute( aPart, "override_locally_modified" ); technology = parseOptionalAttribute( aPart, "technology" ); value = parseOptionalAttribute( aPart, "value" ); for( wxXmlNode* child = aPart->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "attribute" ) { std::unique_ptr attr = std::make_unique( child, aIo ); attributes[ attr->name ] = std::move( attr ); } else if( child->GetName() == "variant" ) { std::unique_ptr variant = std::make_unique( child, aIo ); variants[ variant->name ] = std::move( variant ); } else if( child->GetName() == "spice" ) { spice = std::make_unique( child, aIo ); } } AdvanceProgressPhase(); } EINSTANCE::EINSTANCE( wxXmlNode* aInstance, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ part = parseRequiredAttribute( aInstance, "part" ); gate = parseRequiredAttribute( aInstance, "gate" ); x = parseRequiredAttribute( aInstance, "x" ); y = parseRequiredAttribute( aInstance, "y" ); // optional smashed = parseOptionalAttribute( aInstance, "smashed" ); rot = parseOptionalAttribute( aInstance, "rot" ); for( wxXmlNode* child = aInstance->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "attribute" ) { std::unique_ptr attr = std::make_unique( child, aIo ); attributes[ attr->name ] = std::move( attr ); } } AdvanceProgressPhase(); } EGATE::EGATE( wxXmlNode* aGate, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aGate, "name" ); symbol = parseRequiredAttribute( aGate, "symbol" ); x = parseRequiredAttribute( aGate, "x" ); y = parseRequiredAttribute( aGate, "y" ); opt_wxString stemp = parseOptionalAttribute( aGate, "addlevel" ); // (off | value | name | both) if( stemp == "must" ) addlevel = EGATE::MUST; else if( stemp == "can" ) addlevel = EGATE::CAN; else if( stemp == "next" ) addlevel = EGATE::NEXT; else if( stemp == "request" ) addlevel = EGATE::REQUEST; else if( stemp == "always" ) addlevel = EGATE::ALWAYS; else addlevel = EGATE::NEXT; swaplevel = parseOptionalAttribute( aGate, "swaplevel" ); AdvanceProgressPhase(); } ECONNECT::ECONNECT( wxXmlNode* aConnect, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ gate = parseRequiredAttribute( aConnect, "gate" ); pin = parseRequiredAttribute( aConnect, "pin" ); pad = parseRequiredAttribute( aConnect, "pad" ); contactroute = parseOptionalAttribute( aConnect, "contactroute" ); AdvanceProgressPhase(); } ETECHNOLOGY::ETECHNOLOGY( wxXmlNode* aTechnology, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aTechnology, "name" ); for( wxXmlNode* child = aTechnology->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "attribute" ) attributes.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } EPACKAGE3DINST::EPACKAGE3DINST( wxXmlNode* aPackage3dInst, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ package3d_urn = parseRequiredAttribute( aPackage3dInst, "package3d_urn" ); AdvanceProgressPhase(); } EDEVICE::EDEVICE( wxXmlNode* aDevice, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * ( aDevice, "name" ); opt_wxString pack = parseOptionalAttribute( aDevice, "package" ); if( pack ) { std::string p( pack->c_str() ); ReplaceIllegalFileNameChars( &p, '_' ); package.Set( wxString::FromUTF8( p.c_str() ) ); } for( wxXmlNode* child = aDevice->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "connects" ) { for( wxXmlNode* connect = child->GetChildren(); connect; connect = connect->GetNext() ) { if( connect->GetName() == "connect" ) connects.emplace_back( std::make_unique( connect, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "packages3dinstances" ) { for( wxXmlNode* package3dinst = child->GetChildren(); package3dinst; package3dinst = package3dinst->GetNext() ) { if( package3dinst->GetName() == "package3dinstance" ) package3dinstances.emplace_back( std::make_unique( package3dinst, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "technologies" ) { for( wxXmlNode* technology = child->GetChildren(); technology; technology = technology->GetNext() ) { if( technology->GetName() == "technology" ) technologies.emplace_back( std::make_unique( technology, aIo ) ); } AdvanceProgressPhase(); } } AdvanceProgressPhase(); } EDEVICE_SET::EDEVICE_SET( wxXmlNode* aDeviceSet, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aDeviceSet, "name" ); urn = parseOptionalAttribute( aDeviceSet, "urn" ); locally_modified = parseOptionalAttribute( aDeviceSet, "locally_modified" ); prefix = parseOptionalAttribute( aDeviceSet, "prefix" ); uservalue = parseOptionalAttribute( aDeviceSet, "uservalue" ); library_version = parseOptionalAttribute( aDeviceSet, "library_version" ); library_locally_modified = parseOptionalAttribute( aDeviceSet, "library_locally_modified" ); for( wxXmlNode* child = aDeviceSet->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "gates" ) { for( wxXmlNode* gate = child->GetChildren(); gate; gate = gate->GetNext() ) { std::unique_ptr tmp = std::make_unique( gate, aIo ); gates[tmp->name] = std::move( tmp ); } AdvanceProgressPhase(); } else if( child->GetName() == "devices" ) { for( wxXmlNode* device = child->GetChildren(); device; device = device->GetNext() ) devices.emplace_back( std::make_unique( device, aIo ) ); AdvanceProgressPhase(); } else if( child->GetName() == "spice" ) { spice = std::make_optional( child, aIo ); } } AdvanceProgressPhase(); } ECLASS::ECLASS( wxXmlNode* aClass, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ number = parseRequiredAttribute( aClass, "number" ); name = parseRequiredAttribute( aClass, "name" ); width = parseOptionalAttribute( aClass, "width" ); drill = parseOptionalAttribute( aClass, "drill" ); for( wxXmlNode* child = aClass->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "clearance" ) { wxString to = parseRequiredAttribute( child, "class" ); ECOORD value = parseRequiredAttribute( child, "value" ); clearanceMap[to] = value; AdvanceProgressPhase(); } } AdvanceProgressPhase(); } EPLAIN::EPLAIN( wxXmlNode* aPlain, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * */ for( wxXmlNode* child = aPlain->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "polygon" ) polygons.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "wire" ) wires.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "text" ) texts.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "dimension" ) dimensions.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "circle" ) circles.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "spline" ) splines.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "rectangle" ) rectangles.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "frame" ) frames.emplace_back( std::make_unique( child, aIo ) ); else if( child->GetName() == "hole" ) holes.emplace_back( std::make_unique( child, aIo ) ); } AdvanceProgressPhase(); } EMODULEINST::EMODULEINST( wxXmlNode* aModuleInst, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aModuleInst, "name" ); moduleinst = parseRequiredAttribute( aModuleInst, "module" ); moduleVariant = parseOptionalAttribute( aModuleInst, "modulevariant" ); x = parseRequiredAttribute( aModuleInst, "x" ); y = parseRequiredAttribute( aModuleInst, "y" ); offset = parseOptionalAttribute( aModuleInst, "offset" ); smashed = parseOptionalAttribute( aModuleInst, "smashed" ); rotation = parseOptionalAttribute( aModuleInst, "rot" ); AdvanceProgressPhase(); } ESHEET::ESHEET( wxXmlNode* aSheet, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * */ description = parseOptionalAttribute( aSheet, "description" ); for( wxXmlNode* child = aSheet->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "plain" ) { plain = std::make_unique( child, aIo ); } else if( child->GetName() == "moduleinsts" ) { for( wxXmlNode* moduleinst = child->GetChildren(); moduleinst; moduleinst = moduleinst->GetNext() ) { if( moduleinst->GetName() == "moduleinst" ) { std::unique_ptr inst = std::make_unique( moduleinst, aIo ); moduleinsts[ inst->name ] = std::move( inst ); } } AdvanceProgressPhase(); } else if( child->GetName() == "instances" ) { for( wxXmlNode* instance = child->GetChildren(); instance; instance = instance->GetNext() ) { if( instance->GetName() == "instance" ) instances.emplace_back( std::make_unique( instance, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "busses" ) { for( wxXmlNode* bus = child->GetChildren(); bus; bus = bus->GetNext() ) { if( bus->GetName() == "bus" ) busses.emplace_back( std::make_unique( bus, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "nets" ) { for( wxXmlNode* net = child->GetChildren(); net; net = net->GetNext() ) { if( net->GetName() == "net" ) nets.emplace_back( std::make_unique( net, aIo ) ); } AdvanceProgressPhase(); } } AdvanceProgressPhase(); } ESCHEMATIC_GROUP::ESCHEMATIC_GROUP( wxXmlNode* aSchematicGroup, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aSchematicGroup, "name" ); selectable = parseOptionalAttribute( aSchematicGroup, "selectable" ); width = parseOptionalAttribute( aSchematicGroup, "width" ); titleSize = parseOptionalAttribute( aSchematicGroup, "titleSize" ); titleFont = parseOptionalAttribute( aSchematicGroup, "font" ); wireStyle = parseOptionalAttribute( aSchematicGroup, "style" ); showAnnotations = parseOptionalAttribute( aSchematicGroup, "showAnnotations" ); layer = parseOptionalAttribute( aSchematicGroup, "layer" ); grouprefs = parseOptionalAttribute( aSchematicGroup, "grouprefs" ); for( wxXmlNode* child = aSchematicGroup->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "attribute" ) { attributes.emplace_back( std::make_unique( child, aIo ) ); } } AdvanceProgressPhase(); } EMODULE::EMODULE( wxXmlNode* aModule, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aModule, "name" ); prefix = parseOptionalAttribute( aModule, "prefix" ); dx = parseRequiredAttribute( aModule, "dx" ); dy = parseRequiredAttribute( aModule, "dy" ); for( wxXmlNode* child = aModule->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "ports" ) { for( wxXmlNode* port = child->GetChildren(); port; port = port->GetNext() ) { if( port->GetName() == "port" ) { std::unique_ptr tmp = std::make_unique( port, aIo ); ports[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "variantdefs" ) { for( wxXmlNode* variantdef = child->GetChildren(); variantdef; variantdef = variantdef->GetNext() ) { if( variantdef->GetName() == "variantdef" ) { std::unique_ptr tmp = std::make_unique( variantdef, aIo ); variantdefs[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "groups" ) { for( wxXmlNode* group = child->GetChildren(); group; group = group->GetNext() ) { if( group->GetName() == "schematic_group" ) { std::unique_ptr tmp = std::make_unique( group, aIo ); groups[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "parts" ) { for( wxXmlNode* part = child->GetChildren(); part; part = part->GetNext() ) { if( part->GetName() == "part" ) { std::unique_ptr tmp = std::make_unique( part, aIo ); parts[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "sheets" ) { for( wxXmlNode* sheet = child->GetChildren(); sheet; sheet = sheet->GetNext() ) { if( sheet->GetName() == "sheet" ) sheets.emplace_back( std::make_unique( sheet, aIo ) ); } AdvanceProgressPhase(); } } AdvanceProgressPhase(); } EPORT::EPORT( wxXmlNode* aPort, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aPort, "name" ); side = parseRequiredAttribute( aPort, "side" ); coord = parseRequiredAttribute( aPort, "coord" ); direction = parseOptionalAttribute( aPort, "direction" ); AdvanceProgressPhase(); } EVARIANTDEF::EVARIANTDEF( wxXmlNode* aVariantDef, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aVariantDef, "name" ); current = parseOptionalAttribute( aVariantDef, "current" ); AdvanceProgressPhase(); } ENOTE::ENOTE( wxXmlNode* aNote, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ version = parseRequiredAttribute( aNote, "version" ); severity = parseRequiredAttribute( aNote, "severity" ); note = aNote->GetNodeContent(); AdvanceProgressPhase(); } ECOMPATIBILITY::ECOMPATIBILITY( wxXmlNode* aCompatibility, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * */ for( wxXmlNode* child = aCompatibility->GetNext(); child; child = child->GetNext() ) { if( child->GetName() == "note" ) notes.emplace_back( std::make_unique( child ) ); } AdvanceProgressPhase(); } ESETTING::ESETTING( wxXmlNode* aSetting, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ alwaysvectorfont = parseOptionalAttribute( aSetting, "alwaysvectorfont" ); verticaltext = parseOptionalAttribute( aSetting, "verticaltext" ); keepoldvectorfont = parseOptionalAttribute( aSetting, "keepoldvectorfont" ); AdvanceProgressPhase(); } EGRID::EGRID( wxXmlNode* aGrid, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ distance = parseOptionalAttribute( aGrid, "distance" ); unitdist = parseOptionalAttribute( aGrid, "unitdist" ); unit = parseOptionalAttribute( aGrid, "unit" ); style = parseOptionalAttribute( aGrid, "style" ); multiple = parseOptionalAttribute( aGrid, "multiple" ); display = parseOptionalAttribute( aGrid, "display" ); altdistance = parseOptionalAttribute( aGrid, "altdistance" ); altunitdist = parseOptionalAttribute( aGrid, "altunitdist" ); altunit = parseOptionalAttribute( aGrid, "altunit" ); AdvanceProgressPhase(); } EFILTER::EFILTER( wxXmlNode* aFilter, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aFilter, "name" ); expression = parseRequiredAttribute( aFilter, "expression" ); AdvanceProgressPhase(); }; EPACKAGE::EPACKAGE( wxXmlNode* aPackage, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aPackage, "name" ); urn = parseOptionalAttribute( aPackage, "urn" ); locally_modified = parseOptionalAttribute( aPackage, "locally_modified" ); library_version = parseOptionalAttribute( aPackage, "library_version" ); library_locally_modified = parseOptionalAttribute( aPackage, "library_locally_modified" ); for( wxXmlNode* child = aPackage->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "polygon" ) { polygons.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "wire" ) { wires.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "text" ) { texts.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "dimension" ) { dimensions.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "circle" ) { circles.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "rectangle" ) { rectangles.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "frame" ) { frames.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "hole" ) { holes.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "pad" ) { thtpads.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "smd" ) { smdpads.emplace_back( std::make_unique( child, aIo ) ); } } AdvanceProgressPhase(); } EPACKAGEINSTANCE::EPACKAGEINSTANCE( wxXmlNode* aPackageInstance, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ name = parseRequiredAttribute( aPackageInstance, "name" ); AdvanceProgressPhase(); } EPACKAGE3D::EPACKAGE3D( wxXmlNode* aPackage3d, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aPackage3d, "name" ); urn = parseRequiredAttribute( aPackage3d, "urn" ); type = parseRequiredAttribute( aPackage3d, "type" ); library_version = parseOptionalAttribute( aPackage3d, "library_version" ); library_locally_modified = parseOptionalAttribute( aPackage3d, "library_locally_modified" ); for( wxXmlNode* child = aPackage3d->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "packageinstances" ) { for( wxXmlNode* instance = child->GetChildren(); instance; instance = instance->GetNext() ) packageinstances.emplace_back( std::make_unique( instance, aIo ) ); AdvanceProgressPhase(); } } AdvanceProgressPhase(); } ESYMBOL::ESYMBOL( wxXmlNode* aSymbol, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ name = parseRequiredAttribute( aSymbol, "name" ); urn = parseOptionalAttribute( aSymbol, "urn" ); locally_modified = parseOptionalAttribute( aSymbol, "locally_modified" ); library_version = parseOptionalAttribute( aSymbol, "library_version" ); library_locally_modified = parseOptionalAttribute( aSymbol, "library_locally_modified" ); for( wxXmlNode* child = aSymbol->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "polygon" ) { polygons.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "wire" ) { wires.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "text" ) { texts.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "dimension" ) { dimensions.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "pin" ) { pins.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "circle" ) { circles.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "rectangle" ) { rectangles.emplace_back( std::make_unique( child, aIo ) ); } else if( child->GetName() == "frame" ) { frames.emplace_back( std::make_unique( child, aIo ) ); } } AdvanceProgressPhase(); } ELIBRARY::ELIBRARY( wxXmlNode* aLibrary, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * * */ // The name and urn attributes are only valid in schematic and board files. wxString parentNodeName; if( aLibrary->GetParent() ) parentNodeName = aLibrary->GetParent()->GetName(); if( parentNodeName == "libraries" ) { name = parseRequiredAttribute( aLibrary, "name" ); urn = parseOptionalAttribute( aLibrary, "urn" ); } for( wxXmlNode* child = aLibrary->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "packages" ) { for( wxXmlNode* package = child->GetChildren(); package; package = package->GetNext() ) { if( package->GetName() == "package" ) { std::unique_ptr tmp = std::make_unique( package, aIo ); packages[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "packages3d" ) { for( wxXmlNode* package3d = child->GetChildren(); package3d; package3d = package3d->GetNext() ) { if( package3d->GetName() == "package3d" ) { std::unique_ptr tmp = std::make_unique( package3d, aIo ); packages3d[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "symbols" ) { for( wxXmlNode* symbol = child->GetChildren(); symbol; symbol = symbol->GetNext() ) { if( symbol->GetName() == "symbol" ) { std::unique_ptr tmp = std::make_unique( symbol, aIo ); symbols[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "devicesets" ) { for( wxXmlNode* deviceset = child->GetChildren(); deviceset; deviceset = deviceset->GetNext() ) { if( deviceset->GetName() == "deviceset" ) { std::unique_ptr tmp = std::make_unique( deviceset, aIo ); devicesets[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } } AdvanceProgressPhase(); } EAPPROVED::EAPPROVED( wxXmlNode* aApproved, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ hash = parseRequiredAttribute( aApproved, "hash" ); AdvanceProgressPhase(); } ESCHEMATIC::ESCHEMATIC( wxXmlNode* aSchematic, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * */ xreflabel = parseOptionalAttribute( aSchematic, "xreflabel" ); xrefpart = parseOptionalAttribute( aSchematic, "xrefpart" ); for( wxXmlNode* child = aSchematic->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "description" ) { description = std::make_optional( child, aIo ); } else if( child->GetName() == "libraries" ) { for( wxXmlNode* library = child->GetChildren(); library; library = library->GetNext() ) { if( library->GetName() == "library" ) { std::unique_ptr tmp = std::make_unique( library, aIo ); libraries[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "attributes" ) { for( wxXmlNode* attribute = child->GetChildren(); attribute; attribute = attribute->GetNext() ) { if( attribute->GetName() == "attribute" ) { std::unique_ptr tmp = std::make_unique( attribute, aIo ); attributes[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "variantdefs" ) { for( wxXmlNode* variantdef = child->GetChildren(); variantdef; variantdef = variantdef->GetNext() ) { if( variantdef->GetName() == "variantdef" ) { std::unique_ptr tmp = std::make_unique( variantdef, aIo ); variantdefs[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "classes" ) { for( wxXmlNode* eclass = child->GetChildren(); eclass; eclass = eclass->GetNext() ) { if( eclass->GetName() == "class" ) { std::unique_ptr tmp = std::make_unique( eclass, aIo ); classes[ tmp->number ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "modules" ) { for( wxXmlNode* mod = child->GetChildren(); mod; mod = mod->GetNext() ) { if( mod->GetName() == "module" ) { std::unique_ptr tmp = std::make_unique( mod, aIo ); modules[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "groups" ) { for( wxXmlNode* group = child->GetChildren(); group; group = group->GetNext() ) { if( group->GetName() == "schematic_group" ) { std::unique_ptr tmp = std::make_unique( group, aIo ); groups[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "parts" ) { for( wxXmlNode* part = child->GetChildren(); part; part = part->GetNext() ) { if( part->GetName() == "part" ) { std::unique_ptr tmp = std::make_unique( part, aIo ); parts[ tmp->name ] = std::move( tmp ); } } AdvanceProgressPhase(); } else if( child->GetName() == "sheets" ) { for( wxXmlNode* sheet = child->GetChildren(); sheet; sheet = sheet->GetNext() ) { if( sheet->GetName() == "sheet" ) sheets.emplace_back( std::make_unique( sheet, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "errors" ) { for( wxXmlNode* error = child->GetChildren(); error; error = error->GetNext() ) { if( error->GetName() == "approved" ) errors.emplace_back( std::make_unique( error, aIo ) ); } AdvanceProgressPhase(); } } AdvanceProgressPhase(); } EDRAWING::EDRAWING( wxXmlNode* aDrawing, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * */ for( wxXmlNode* child = aDrawing->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "settings" ) { for( wxXmlNode* setting = child->GetChildren(); setting; setting = setting->GetNext() ) settings.emplace_back( std::make_unique( setting, aIo ) ); AdvanceProgressPhase(); } else if( child->GetName() == "grid" ) { grid = std::make_optional( child, aIo ); } else if( child->GetName() == "filters" ) { for( wxXmlNode* filter = child->GetChildren(); filter; filter = filter->GetNext() ) { if( filter->GetName() == "filter" ) filters.emplace_back( std::make_unique( filter, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "layers" ) { for( wxXmlNode* layer = child->GetChildren(); layer; layer = layer->GetNext() ) { if( layer->GetName() == "layer" ) layers.emplace_back( std::make_unique( layer, aIo ) ); } AdvanceProgressPhase(); } else if( child->GetName() == "schematic" ) { schematic = std::make_optional( child, aIo ); } else if( child->GetName() == "library" ) { library = std::make_optional( child, aIo ); } } // std::optional> board; AdvanceProgressPhase(); } EAGLE_DOC::EAGLE_DOC( wxXmlNode* aEagleDoc, IO_BASE* aIo ) : EAGLE_BASE( aIo ) { /* * * * */ version = parseRequiredAttribute( aEagleDoc, "version" ); for( wxXmlNode* child = aEagleDoc->GetChildren(); child; child = child->GetNext() ) { if( child->GetName() == "compitibility" ) compatibility = std::make_optional( child, aIo ); else if( child->GetName() == "drawing" ) drawing = std::make_unique( child, aIo ); } AdvanceProgressPhase(); }