1072 lines
23 KiB
C++
1072 lines
23 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
|
* Copyright (C) 2012-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
|
* Copyright (C) 2017 CERN
|
|
*
|
|
* @author Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
|
|
#ifndef _EAGLE_PARSER_H_
|
|
#define _EAGLE_PARSER_H_
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
#include <wx/xml/xml.h>
|
|
#include <wx/string.h>
|
|
#include <wx/filename.h>
|
|
|
|
#include <layer_ids.h>
|
|
#include <trigo.h>
|
|
#include <core/wx_stl_compat.h>
|
|
|
|
class FOOTPRINT;
|
|
struct EINSTANCE;
|
|
struct EPART;
|
|
struct ETEXT;
|
|
|
|
typedef std::unordered_map<wxString, wxXmlNode*> NODE_MAP;
|
|
typedef std::map<wxString, FOOTPRINT*> FOOTPRINT_MAP;
|
|
typedef std::map<wxString, EINSTANCE*> EINSTANCE_MAP;
|
|
typedef std::map<wxString, std::unique_ptr<EPART>> EPART_MAP;
|
|
|
|
///< Translates Eagle special characters to their counterparts in KiCad.
|
|
wxString escapeName( const wxString& aNetName );
|
|
|
|
///< Interprets special characters in Eagle text and converts them to KiCAD notation.
|
|
wxString interpretText( const wxString& aText );
|
|
|
|
///< Translates Eagle special text reference to a KiCad variable reference
|
|
bool substituteVariable( wxString* aText );
|
|
|
|
static inline wxXmlNode* getChildrenNodes( NODE_MAP& aMap, const wxString& aName )
|
|
{
|
|
auto it = aMap.find( aName );
|
|
return it == aMap.end() ? nullptr : it->second->GetChildren();
|
|
}
|
|
|
|
|
|
/**
|
|
* Implement a simple wrapper around runtime_error to isolate the errors thrown by the
|
|
* Eagle XML parser.
|
|
*/
|
|
struct XML_PARSER_ERROR : std::runtime_error
|
|
{
|
|
/**
|
|
* Build an XML error by just calling its parent class constructor, std::runtime_error, with
|
|
* the passed message.
|
|
*
|
|
* @param aMessage is an explanatory error message.
|
|
*/
|
|
XML_PARSER_ERROR( const wxString& aMessage ) noexcept :
|
|
std::runtime_error( "XML parser failed - " + aMessage.ToStdString() )
|
|
{}
|
|
};
|
|
|
|
|
|
/// segment (element) of our XPATH into the Eagle XML document tree in PTREE form.
|
|
struct TRIPLET
|
|
{
|
|
const char* element;
|
|
const char* attribute;
|
|
const char* value;
|
|
|
|
TRIPLET( const char* aElement, const char* aAttribute = "", const char* aValue = "" ) :
|
|
element( aElement ),
|
|
attribute( aAttribute ),
|
|
value( aValue )
|
|
{}
|
|
};
|
|
|
|
|
|
/**
|
|
* Keep track of what we are working on within a PTREE.
|
|
*
|
|
* Then if an exception is thrown, the place within the tree that gave us
|
|
* grief can be reported almost accurately. To minimally impact
|
|
* speed, merely assign const char* pointers during the tree walking
|
|
* expedition. The const char* pointers must be to C strings residing either in
|
|
* the data or code segment (i.e. "compiled in") or within the XML document, but
|
|
* not on the stack, since the stack is unwound during the throwing of the
|
|
* exception. The XML document will not immediately vanish since we capture
|
|
* the xpath (using function Contents()) before the XML document tree (PTREE)
|
|
* is destroyed.
|
|
*/
|
|
class XPATH
|
|
{
|
|
std::vector<TRIPLET> p;
|
|
|
|
public:
|
|
void push( const char* aPathSegment, const char* aAttribute="" )
|
|
{
|
|
p.emplace_back( aPathSegment, aAttribute );
|
|
}
|
|
|
|
void clear() { p.clear(); }
|
|
|
|
void pop() { p.pop_back(); }
|
|
|
|
/// modify the last path node's value
|
|
void Value( const char* aValue )
|
|
{
|
|
p.back().value = aValue;
|
|
}
|
|
|
|
/// modify the last path node's attribute
|
|
void Attribute( const char* aAttribute )
|
|
{
|
|
p.back().attribute = aAttribute;
|
|
}
|
|
|
|
/// return the contents of the XPATH as a single string
|
|
wxString Contents()
|
|
{
|
|
typedef std::vector<TRIPLET>::const_iterator CITER_TRIPLET;
|
|
|
|
wxString ret;
|
|
|
|
for( CITER_TRIPLET it = p.begin(); it != p.end(); ++it )
|
|
{
|
|
if( it != p.begin() )
|
|
ret += '.';
|
|
|
|
ret += it->element;
|
|
|
|
if( it->attribute[0] && it->value[0] )
|
|
{
|
|
ret += '[';
|
|
ret += it->attribute;
|
|
ret += '=';
|
|
ret += it->value;
|
|
ret += ']';
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Convert a wxString to a generic type T.
|
|
*
|
|
* @param aValue is a wxString containing the value that will be converted to type T.
|
|
* @throw XML_PARSER_ERROR - an exception is thrown if the parsing fails or if the conversion to
|
|
* type T is unknown.
|
|
*/
|
|
template<typename T>
|
|
T Convert( const wxString& aValue )
|
|
{
|
|
throw XML_PARSER_ERROR( "Conversion failed. Unknown type." );
|
|
}
|
|
|
|
template <>
|
|
wxString Convert<wxString>( const wxString& aValue );
|
|
|
|
/**
|
|
* Model an optional XML attribute.
|
|
*
|
|
* This was implemented as an alternative to std::optional. This class should be replaced with a
|
|
* simple typedef per type using std::optional when C++17 is published.
|
|
*/
|
|
template <typename T>
|
|
class OPTIONAL_XML_ATTRIBUTE
|
|
{
|
|
private:
|
|
/// A boolean indicating if the data is present or not.
|
|
bool m_isAvailable;
|
|
|
|
/// The actual data if m_isAvailable is true; otherwise, garbage.
|
|
T m_data;
|
|
|
|
public:
|
|
/**
|
|
* Construct a default OPTIONAL_XML_ATTRIBUTE, whose data is not available.
|
|
*/
|
|
OPTIONAL_XML_ATTRIBUTE() :
|
|
m_isAvailable( false ),
|
|
m_data( T() )
|
|
{}
|
|
|
|
/**
|
|
* @param aData is a wxString containing the value that should be converted to type T. If
|
|
* aData is empty, the attribute is understood as unavailable; otherwise, the
|
|
* conversion to T is tried.
|
|
*/
|
|
OPTIONAL_XML_ATTRIBUTE( const wxString& aData )
|
|
{
|
|
m_data = T();
|
|
m_isAvailable = !aData.IsEmpty();
|
|
|
|
if( m_isAvailable )
|
|
Set( aData );
|
|
}
|
|
|
|
/**
|
|
* @param aData is the value of the XML attribute. If this constructor is called, the
|
|
* attribute is available.
|
|
*/
|
|
template<typename V = T>
|
|
OPTIONAL_XML_ATTRIBUTE( T aData ) :
|
|
m_isAvailable( true ),
|
|
m_data( aData )
|
|
{}
|
|
|
|
/**
|
|
* @return bool the availability of the attribute.
|
|
*/
|
|
operator bool() const
|
|
{
|
|
return m_isAvailable;
|
|
}
|
|
|
|
/**
|
|
* Assign to a string (optionally) containing the data.
|
|
*
|
|
* @param aData is a wxString that should be converted to T. If the string is empty, the
|
|
* attribute is set to unavailable.
|
|
*/
|
|
OPTIONAL_XML_ATTRIBUTE<T>& operator =( const wxString& aData )
|
|
{
|
|
m_isAvailable = !aData.IsEmpty();
|
|
|
|
if( m_isAvailable )
|
|
Set( aData );
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Assign to an object of the base type containing the data.
|
|
*
|
|
* @param aData is the actual value of the attribute. Calling this assignment, the attribute
|
|
* is automatically made available.
|
|
*/
|
|
OPTIONAL_XML_ATTRIBUTE<T>& operator =( T aData )
|
|
{
|
|
m_data = aData;
|
|
m_isAvailable = true;
|
|
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* @param aOther is the object of the base type that should be compared with this one.
|
|
*/
|
|
bool operator ==( const T& aOther ) const
|
|
{
|
|
return m_isAvailable && ( aOther == m_data );
|
|
}
|
|
|
|
/**
|
|
* Attempt to convert a string to the base type.
|
|
*
|
|
* @param aString is the string that will be converted to the base type.
|
|
*/
|
|
void Set( const wxString& aString )
|
|
{
|
|
m_data = Convert<T>( aString );
|
|
m_isAvailable = !aString.IsEmpty();
|
|
}
|
|
|
|
/**
|
|
* Return a reference to the value of the attribute assuming it is available.
|
|
*
|
|
* @return T& - the value of the attribute.
|
|
*/
|
|
T& Get()
|
|
{
|
|
assert( m_isAvailable );
|
|
return m_data;
|
|
}
|
|
|
|
/**
|
|
* Return a constant reference to the value of the attribute assuming it is available.
|
|
*
|
|
* @return const T& - the value of the attribute.
|
|
*/
|
|
const T& CGet() const
|
|
{
|
|
assert( m_isAvailable );
|
|
return m_data;
|
|
}
|
|
|
|
/**
|
|
* Return a reference to the value of the attribute assuming it is available.
|
|
*
|
|
* @return T& - the value of the attribute.
|
|
*/
|
|
T& operator*()
|
|
{
|
|
return Get();
|
|
}
|
|
|
|
/**
|
|
* Return a constant reference to the value of the attribute assuming it is available.
|
|
*
|
|
* @return const T& - the value of the attribute.
|
|
*/
|
|
const T& operator*() const
|
|
{
|
|
return CGet();
|
|
}
|
|
|
|
/**
|
|
* Return a pointer to the value of the attribute assuming it is available.
|
|
*
|
|
* @return T* - the value of the attribute.
|
|
*/
|
|
T* operator->()
|
|
{
|
|
return &Get();
|
|
}
|
|
|
|
/**
|
|
* Return a constant pointer to the value of the attribute assuming it is available.
|
|
*
|
|
* @return const T* - the value of the attribute.
|
|
*/
|
|
const T* operator->() const
|
|
{
|
|
return &CGet();
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Provide an easy access to the children of an XML node via their names.
|
|
*
|
|
* @param currentNode is a pointer to a wxXmlNode, whose children will be mapped.
|
|
* @return NODE_MAP is a map linking the name of each children to the children itself (via a
|
|
* wxXmlNode*)
|
|
*/
|
|
NODE_MAP MapChildren( wxXmlNode* aCurrentNode );
|
|
|
|
///< Convert an Eagle curve end to a KiCad center for S_ARC
|
|
VECTOR2I ConvertArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle );
|
|
|
|
// Pre-declare for typedefs
|
|
struct EROT;
|
|
struct ECOORD;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<wxString> opt_wxString;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<int> opt_int;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<double> opt_double;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<bool> opt_bool;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<EROT> opt_erot;
|
|
typedef OPTIONAL_XML_ATTRIBUTE<ECOORD> opt_ecoord;
|
|
|
|
|
|
// All of the 'E'STRUCTS below merely hold Eagle XML information verbatim, in binary.
|
|
// For maintenance and troubleshooting purposes, it was thought that we'd need to
|
|
// separate the conversion process into distinct steps. There is no intent to have KiCad
|
|
// forms of information in these 'E'STRUCTS. They are only binary forms
|
|
// of the Eagle information in the corresponding Eagle XML nodes.
|
|
|
|
// Eagle coordinates
|
|
struct ECOORD
|
|
{
|
|
enum EAGLE_UNIT
|
|
{
|
|
EU_NM, ///< nanometers
|
|
EU_MM, ///< millimeters
|
|
EU_INCH, ///< inches
|
|
EU_MIL, ///< mils/thous
|
|
};
|
|
|
|
///< Value expressed in nanometers
|
|
long long int value;
|
|
|
|
///< Unit used for the value field
|
|
static constexpr EAGLE_UNIT ECOORD_UNIT = EU_NM;
|
|
|
|
ECOORD()
|
|
: value( 0 )
|
|
{
|
|
}
|
|
|
|
ECOORD( int aValue, enum EAGLE_UNIT aUnit )
|
|
: value( ConvertToNm( aValue, aUnit ) )
|
|
{
|
|
}
|
|
|
|
ECOORD( const wxString& aValue, enum EAGLE_UNIT aUnit );
|
|
|
|
int ToMils() const
|
|
{
|
|
return value / 25400;
|
|
}
|
|
|
|
int To100NanoMeters() const
|
|
{
|
|
return value / 100;
|
|
}
|
|
|
|
int ToNanoMeters() const
|
|
{
|
|
return value;
|
|
}
|
|
|
|
float ToMm() const
|
|
{
|
|
return value / 1000000.0;
|
|
}
|
|
|
|
int ToSchUnits() const { return To100NanoMeters(); }
|
|
int ToPcbUnits() const { return ToNanoMeters(); }
|
|
|
|
ECOORD operator+( const ECOORD& aOther ) const
|
|
{
|
|
return ECOORD( value + aOther.value, ECOORD_UNIT );
|
|
}
|
|
|
|
ECOORD operator-( const ECOORD& aOther ) const
|
|
{
|
|
return ECOORD( value - aOther.value, ECOORD_UNIT );
|
|
}
|
|
|
|
bool operator==( const ECOORD& aOther ) const
|
|
{
|
|
return value == aOther.value;
|
|
}
|
|
|
|
///< Converts a size expressed in a certain unit to nanometers.
|
|
static long long int ConvertToNm( int aValue, enum EAGLE_UNIT aUnit );
|
|
};
|
|
|
|
|
|
/// Eagle net
|
|
struct ENET
|
|
{
|
|
int netcode;
|
|
wxString netname;
|
|
|
|
ENET( int aNetCode, const wxString& aNetName ) :
|
|
netcode( aNetCode ),
|
|
netname( aNetName )
|
|
{}
|
|
|
|
ENET() :
|
|
netcode( 0 )
|
|
{}
|
|
};
|
|
|
|
|
|
/// Eagle rotation
|
|
struct EROT
|
|
{
|
|
bool mirror;
|
|
bool spin;
|
|
double degrees;
|
|
|
|
EROT() :
|
|
mirror( false ),
|
|
spin( false ),
|
|
degrees( 0 )
|
|
{}
|
|
|
|
EROT( double aDegrees ) :
|
|
mirror( false ),
|
|
spin( false ),
|
|
degrees( aDegrees )
|
|
{}
|
|
};
|
|
|
|
|
|
/// Eagle wire
|
|
struct EWIRE
|
|
{
|
|
ECOORD x1;
|
|
ECOORD y1;
|
|
ECOORD x2;
|
|
ECOORD y2;
|
|
ECOORD width;
|
|
int layer;
|
|
|
|
// for style: (continuous | longdash | shortdash | dashdot)
|
|
enum { CONTINUOUS,
|
|
LONGDASH,
|
|
SHORTDASH,
|
|
DASHDOT };
|
|
|
|
opt_int style;
|
|
opt_double curve; ///< range is -359.9..359.9
|
|
|
|
// for cap: (flat | round)
|
|
enum { FLAT,
|
|
ROUND };
|
|
|
|
opt_int cap;
|
|
|
|
EWIRE( wxXmlNode* aWire );
|
|
};
|
|
|
|
|
|
/// Eagle Junction
|
|
struct EJUNCTION
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
|
|
EJUNCTION( wxXmlNode* aJunction);
|
|
};
|
|
|
|
|
|
/// Eagle label
|
|
struct ELABEL
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
ECOORD size;
|
|
int layer;
|
|
opt_erot rot;
|
|
opt_wxString xref;
|
|
wxString netname;
|
|
|
|
ELABEL( wxXmlNode* aLabel, const wxString& aNetName );
|
|
};
|
|
|
|
|
|
/// Eagle via
|
|
struct EVIA
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
int layer_front_most; /// < extent
|
|
int layer_back_most; /// < inclusive
|
|
ECOORD drill;
|
|
opt_ecoord diam;
|
|
opt_wxString shape;
|
|
|
|
EVIA( wxXmlNode* aVia );
|
|
};
|
|
|
|
|
|
/// Eagle circle
|
|
struct ECIRCLE
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
ECOORD radius;
|
|
ECOORD width;
|
|
int layer;
|
|
|
|
ECIRCLE( wxXmlNode* aCircle );
|
|
};
|
|
|
|
|
|
/// Eagle XML rectangle in binary
|
|
struct ERECT
|
|
{
|
|
ECOORD x1;
|
|
ECOORD y1;
|
|
ECOORD x2;
|
|
ECOORD y2;
|
|
int layer;
|
|
opt_erot rot;
|
|
|
|
ERECT( wxXmlNode* aRect );
|
|
};
|
|
|
|
|
|
/**
|
|
* Parse an Eagle "attribute" XML element.
|
|
*
|
|
* @note An attribute element is different than an XML element attribute. The attribute element
|
|
* is a full XML node in and of itself, and has attributes of its own. Blame Eagle.
|
|
*/
|
|
struct EATTR
|
|
{
|
|
wxString name;
|
|
opt_wxString value;
|
|
opt_ecoord x;
|
|
opt_ecoord y;
|
|
opt_ecoord size;
|
|
opt_int layer;
|
|
opt_double ratio;
|
|
opt_erot rot;
|
|
|
|
enum { // for 'display'
|
|
Off,
|
|
VALUE,
|
|
NAME,
|
|
BOTH,
|
|
};
|
|
opt_int display;
|
|
opt_int align;
|
|
|
|
EATTR( wxXmlNode* aTree );
|
|
EATTR() {}
|
|
};
|
|
|
|
|
|
/// Eagle dimension element
|
|
struct EDIMENSION
|
|
{
|
|
ECOORD x1;
|
|
ECOORD y1;
|
|
ECOORD x2;
|
|
ECOORD y2;
|
|
ECOORD x3;
|
|
ECOORD y3;
|
|
opt_ecoord textsize;
|
|
int layer;
|
|
opt_wxString dimensionType;
|
|
|
|
EDIMENSION( wxXmlNode* aDimension );
|
|
};
|
|
|
|
|
|
/// Eagle text element
|
|
struct ETEXT
|
|
{
|
|
wxString text;
|
|
ECOORD x;
|
|
ECOORD y;
|
|
ECOORD size;
|
|
int layer;
|
|
opt_wxString font;
|
|
opt_double ratio;
|
|
opt_erot rot;
|
|
|
|
enum { // for align
|
|
CENTER = 0,
|
|
CENTER_LEFT,
|
|
TOP_CENTER,
|
|
TOP_LEFT,
|
|
TOP_RIGHT,
|
|
|
|
// opposites are -1 x above, used by code tricks in here
|
|
CENTER_RIGHT = -CENTER_LEFT,
|
|
BOTTOM_CENTER = -TOP_CENTER,
|
|
BOTTOM_LEFT = -TOP_RIGHT,
|
|
BOTTOM_RIGHT = -TOP_LEFT,
|
|
};
|
|
|
|
opt_int align;
|
|
|
|
ETEXT( wxXmlNode* aText );
|
|
|
|
/// Calculate text size based on font type and size
|
|
VECTOR2I ConvertSize() const;
|
|
};
|
|
|
|
|
|
/**
|
|
* Parse an Eagle frame element.
|
|
*/
|
|
struct EFRAME
|
|
{
|
|
ECOORD x1;
|
|
ECOORD y1;
|
|
ECOORD x2;
|
|
ECOORD y2;
|
|
int columns;
|
|
int rows;
|
|
int layer;
|
|
opt_bool border_left;
|
|
opt_bool border_top;
|
|
opt_bool border_right;
|
|
opt_bool border_bottom;
|
|
|
|
EFRAME( wxXmlNode* aFrameNode );
|
|
};
|
|
|
|
|
|
/// Structure holding common properties for through-hole and SMD pads
|
|
struct EPAD_COMMON
|
|
{
|
|
wxString name;
|
|
ECOORD x, y;
|
|
opt_erot rot;
|
|
opt_bool stop;
|
|
opt_bool thermals;
|
|
|
|
EPAD_COMMON( wxXmlNode* aPad );
|
|
};
|
|
|
|
|
|
/// Eagle thru hole pad
|
|
struct EPAD : public EPAD_COMMON
|
|
{
|
|
ECOORD drill;
|
|
opt_ecoord diameter;
|
|
|
|
// for shape: (square | round | octagon | long | offset)
|
|
enum {
|
|
UNDEF = -1,
|
|
SQUARE,
|
|
ROUND,
|
|
OCTAGON,
|
|
LONG,
|
|
OFFSET,
|
|
};
|
|
opt_int shape;
|
|
opt_bool first;
|
|
|
|
EPAD( wxXmlNode* aPad );
|
|
};
|
|
|
|
|
|
/// Eagle SMD pad
|
|
struct ESMD : public EPAD_COMMON
|
|
{
|
|
ECOORD dx;
|
|
ECOORD dy;
|
|
int layer;
|
|
opt_int roundness;
|
|
opt_bool cream;
|
|
|
|
ESMD( wxXmlNode* aSMD );
|
|
};
|
|
|
|
|
|
/// Eagle pin element
|
|
struct EPIN
|
|
{
|
|
wxString name;
|
|
ECOORD x;
|
|
ECOORD y;
|
|
|
|
opt_wxString visible;
|
|
opt_wxString length;
|
|
opt_wxString direction;
|
|
opt_wxString function;
|
|
opt_int swaplevel;
|
|
opt_erot rot;
|
|
|
|
EPIN( wxXmlNode* aPin );
|
|
};
|
|
|
|
|
|
/// Eagle vertex
|
|
struct EVERTEX
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
opt_double curve; ///< range is -359.9..359.9
|
|
|
|
EVERTEX( wxXmlNode* aVertex );
|
|
};
|
|
|
|
|
|
/// Eagle polygon, without vertices which are parsed as needed
|
|
struct EPOLYGON
|
|
{
|
|
ECOORD width;
|
|
int layer;
|
|
opt_ecoord spacing;
|
|
|
|
// KiCad priority is opposite of Eagle rank, that is:
|
|
// - Eagle Low rank drawn first
|
|
// - KiCad high priority drawn first
|
|
// So since Eagle has an upper limit we define this, used for the cases
|
|
// where no rank is specified.
|
|
static const int max_priority = 6;
|
|
|
|
enum { // for pour
|
|
SOLID,
|
|
HATCH,
|
|
CUTOUT,
|
|
};
|
|
int pour;
|
|
opt_ecoord isolate;
|
|
opt_bool orphans;
|
|
opt_bool thermals;
|
|
opt_int rank;
|
|
|
|
EPOLYGON( wxXmlNode* aPolygon );
|
|
};
|
|
|
|
|
|
/// Eagle hole element
|
|
struct EHOLE
|
|
{
|
|
ECOORD x;
|
|
ECOORD y;
|
|
ECOORD drill;
|
|
|
|
EHOLE( wxXmlNode* aHole );
|
|
};
|
|
|
|
|
|
/// Eagle element element
|
|
struct EELEMENT
|
|
{
|
|
wxString name;
|
|
wxString library;
|
|
wxString package;
|
|
wxString value;
|
|
ECOORD x;
|
|
ECOORD y;
|
|
opt_bool locked;
|
|
opt_bool smashed;
|
|
opt_erot rot;
|
|
|
|
EELEMENT( wxXmlNode* aElement );
|
|
};
|
|
|
|
|
|
struct ELAYER
|
|
{
|
|
int number;
|
|
wxString name;
|
|
int color;
|
|
int fill;
|
|
opt_bool visible;
|
|
opt_bool active;
|
|
|
|
ELAYER( wxXmlNode* aLayer );
|
|
};
|
|
|
|
|
|
struct EAGLE_LAYER
|
|
{
|
|
enum
|
|
{
|
|
TOP = 1,
|
|
ROUTE2 = 2,
|
|
ROUTE3 = 3,
|
|
ROUTE4 = 4,
|
|
ROUTE5 = 5,
|
|
ROUTE6 = 6,
|
|
ROUTE7 = 7,
|
|
ROUTE8 = 8,
|
|
ROUTE9 = 9,
|
|
ROUTE10 = 10,
|
|
ROUTE11 = 11,
|
|
ROUTE12 = 12,
|
|
ROUTE13 = 13,
|
|
ROUTE14 = 14,
|
|
ROUTE15 = 15,
|
|
BOTTOM = 16,
|
|
PADS = 17,
|
|
VIAS = 18,
|
|
UNROUTED = 19,
|
|
DIMENSION = 20,
|
|
TPLACE = 21,
|
|
BPLACE = 22,
|
|
TORIGINS = 23,
|
|
BORIGINS = 24,
|
|
TNAMES = 25,
|
|
BNAMES = 26,
|
|
TVALUES = 27,
|
|
BVALUES = 28,
|
|
TSTOP = 29,
|
|
BSTOP = 30,
|
|
TCREAM = 31,
|
|
BCREAM = 32,
|
|
TFINISH = 33,
|
|
BFINISH = 34,
|
|
TGLUE = 35,
|
|
BGLUE = 36,
|
|
TTEST = 37,
|
|
BTEST = 38,
|
|
TKEEPOUT = 39,
|
|
BKEEPOUT = 40,
|
|
TRESTRICT = 41,
|
|
BRESTRICT = 42,
|
|
VRESTRICT = 43,
|
|
DRILLS = 44,
|
|
HOLES = 45,
|
|
MILLING = 46,
|
|
MEASURES = 47,
|
|
DOCUMENT = 48,
|
|
REFERENCELC = 49,
|
|
REFERENCELS = 50,
|
|
TDOCU = 51,
|
|
BDOCU = 52,
|
|
NETS = 91,
|
|
BUSSES = 92,
|
|
PINS = 93,
|
|
SYMBOLS = 94,
|
|
NAMES = 95,
|
|
VALUES = 96,
|
|
INFO = 97,
|
|
GUIDE = 98,
|
|
USERLAYER1 = 160,
|
|
USERLAYER2 = 161
|
|
};
|
|
};
|
|
|
|
|
|
struct EPART
|
|
{
|
|
/*
|
|
* <!ELEMENT part (attribute*, variant*)>
|
|
* <!ATTLIST part
|
|
* name %String; #REQUIRED
|
|
* library %String; #REQUIRED
|
|
* deviceset %String; #REQUIRED
|
|
* device %String; #REQUIRED
|
|
* technology %String; ""
|
|
* value %String; #IMPLIED
|
|
* >
|
|
*/
|
|
|
|
wxString name;
|
|
wxString library;
|
|
wxString deviceset;
|
|
wxString device;
|
|
opt_wxString technology;
|
|
opt_wxString value;
|
|
std::map<std::string,std::string> attribute;
|
|
std::map<std::string,std::string> variant;
|
|
|
|
EPART( wxXmlNode* aPart );
|
|
};
|
|
|
|
|
|
struct EINSTANCE
|
|
{
|
|
/*
|
|
* <!ELEMENT instance (attribute)*>
|
|
* <!ATTLIST instance
|
|
* part %String; #REQUIRED
|
|
* gate %String; #REQUIRED
|
|
* x %Coord; #REQUIRED
|
|
* y %Coord; #REQUIRED
|
|
* smashed %Bool; "no"
|
|
* rot %Rotation; "R0"
|
|
* >
|
|
*/
|
|
|
|
wxString part;
|
|
wxString gate;
|
|
ECOORD x;
|
|
ECOORD y;
|
|
opt_bool smashed;
|
|
opt_erot rot;
|
|
|
|
EINSTANCE( wxXmlNode* aInstance );
|
|
};
|
|
|
|
|
|
struct EGATE
|
|
{
|
|
/*
|
|
* <!ELEMENT gate EMPTY>
|
|
* <!ATTLIST gate
|
|
* name %String; #REQUIRED
|
|
* symbol %String; #REQUIRED
|
|
* x %Coord; #REQUIRED
|
|
* y %Coord; #REQUIRED
|
|
* addlevel %GateAddLevel; "next"
|
|
* swaplevel %Int; "0"
|
|
* >
|
|
*/
|
|
|
|
wxString name;
|
|
wxString symbol;
|
|
|
|
ECOORD x;
|
|
ECOORD y;
|
|
|
|
opt_int addlevel;
|
|
opt_int swaplevel;
|
|
|
|
enum
|
|
{
|
|
MUST,
|
|
CAN,
|
|
NEXT,
|
|
REQUEST,
|
|
ALWAYS
|
|
};
|
|
|
|
EGATE( wxXmlNode* aGate );
|
|
};
|
|
|
|
|
|
struct ECONNECT
|
|
{
|
|
/*
|
|
* <!ELEMENT connect EMPTY>
|
|
* <!ATTLIST connect
|
|
* gate %String; #REQUIRED
|
|
* pin %String; #REQUIRED
|
|
* pad %String; #REQUIRED
|
|
* route %ContactRoute; "all"
|
|
* >
|
|
*/
|
|
wxString gate;
|
|
wxString pin;
|
|
wxString pad;
|
|
//int contactroute; // TODO
|
|
|
|
ECONNECT( wxXmlNode* aConnect );
|
|
};
|
|
|
|
|
|
struct EDEVICE
|
|
{
|
|
/*
|
|
* <!ELEMENT device (connects?, technologies?)>
|
|
* <!ATTLIST device
|
|
* name %String; ""
|
|
* package %String; #IMPLIED
|
|
* >
|
|
*/
|
|
wxString name;
|
|
opt_wxString package;
|
|
|
|
std::vector<ECONNECT> connects;
|
|
|
|
EDEVICE( wxXmlNode* aDevice );
|
|
};
|
|
|
|
|
|
struct EDEVICE_SET
|
|
{
|
|
/*
|
|
<!ELEMENT deviceset (description?, gates, devices)>
|
|
<!ATTLIST deviceset
|
|
name %String; #REQUIRED
|
|
prefix %String; ""
|
|
uservalue %Bool; "no"
|
|
>
|
|
*/
|
|
|
|
wxString name;
|
|
opt_wxString prefix;
|
|
opt_bool uservalue;
|
|
//std::vector<EDEVICE> devices;
|
|
//std::vector<EGATE> gates;
|
|
|
|
|
|
EDEVICE_SET( wxXmlNode* aDeviceSet );
|
|
};
|
|
|
|
|
|
struct ECLASS
|
|
{
|
|
wxString number;
|
|
wxString name;
|
|
std::map<wxString, ECOORD> clearanceMap;
|
|
|
|
ECLASS( wxXmlNode* aClass );
|
|
};
|
|
|
|
|
|
#endif // _EAGLE_PARSER_H_
|