KiCad PCB EDA Suite
eagle_parser.cpp File Reference
#include <plugins/eagle/eagle_parser.h>
#include <string_utils.h>
#include <richio.h>
#include <wx/log.h>
#include <functional>
#include <cstdio>

Go to the source code of this file.

Functions

wxString escapeName (const wxString &aNetName)
 Interprets special characters in Eagle text and converts them to KiCAD notation. More...
 
wxString interpretText (const wxString &aText)
 Translates Eagle special text reference to a KiCad variable reference. More...
 
bool substituteVariable (wxString *aText)
 
template<>
wxString Convert< wxString > (const wxString &aValue)
 
template<>
std::string Convert< std::string > (const wxString &aValue)
 
template<>
double Convert< double > (const wxString &aValue)
 
template<>
int Convert< int > (const wxString &aValue)
 
template<>
bool Convert< bool > (const wxString &aValue)
 
template<>
EROT Convert< EROT > (const wxString &aRot)
 parse an Eagle XML "rot" field. More...
 
template<>
ECOORD Convert< ECOORD > (const wxString &aCoord)
 
template<typename T >
parseRequiredAttribute (wxXmlNode *aNode, const wxString &aAttribute)
 Parse aAttribute of the XML node aNode. More...
 
template<typename T >
OPTIONAL_XML_ATTRIBUTE< T > parseOptionalAttribute (wxXmlNode *aNode, const wxString &aAttribute)
 Parse option aAttribute of the XML node aNode. More...
 
NODE_MAP MapChildren (wxXmlNode *aCurrentNode)
 Provide an easy access to the children of an XML node via their names. More...
 
VECTOR2I ConvertArcCenter (const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
 
static int parseAlignment (const wxString &aAlignment)
 

Variables

constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT
 

Function Documentation

◆ Convert< bool >()

template<>
bool Convert< bool > ( const wxString &  aValue)

Definition at line 264 of file eagle_parser.cpp.

265{
266 if( aValue != "yes" && aValue != "no" )
267 throw XML_PARSER_ERROR( "Conversion to bool failed. Original value, '" +
268 aValue.ToStdString() +
269 "', is neither 'yes' nor 'no'." );
270
271 return aValue == "yes";
272}
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:75

◆ Convert< double >()

template<>
double Convert< double > ( const wxString &  aValue)

Definition at line 241 of file eagle_parser.cpp.

242{
243 double value;
244
245 if( aValue.ToCDouble( &value ) )
246 return value;
247 else
248 throw XML_PARSER_ERROR( "Conversion to double failed. Original value: '" +
249 aValue.ToStdString() + "'." );
250}

◆ Convert< ECOORD >()

template<>
ECOORD Convert< ECOORD > ( const wxString &  aCoord)

Definition at line 295 of file eagle_parser.cpp.

296{
297 // Eagle uses millimeters as the default unit
298 return ECOORD( aCoord, ECOORD::EAGLE_UNIT::EU_MM );
299}

◆ Convert< EROT >()

template<>
EROT Convert< EROT > ( const wxString &  aRot)

parse an Eagle XML "rot" field.

Unfortunately the DTD seems not to explain this format very well. [S][M]R<degrees>. Examples: "R90", "MR180", "SR180"

Definition at line 278 of file eagle_parser.cpp.

279{
280 EROT value;
281
282 value.spin = aRot.find( 'S' ) != aRot.npos;
283 value.mirror = aRot.find( 'M' ) != aRot.npos;
284 value.degrees = strtod( aRot.c_str()
285 + 1 // skip leading 'R'
286 + int( value.spin ) // skip optional leading 'S'
287 + int( value.mirror ), // skip optional leading 'M'
288 nullptr );
289
290 return value;
291}
Eagle rotation.
Definition: eagle_parser.h:477
double degrees
Definition: eagle_parser.h:480
bool spin
Definition: eagle_parser.h:479
bool mirror
Definition: eagle_parser.h:478

References EROT::degrees, EROT::mirror, and EROT::spin.

◆ Convert< int >()

template<>
int Convert< int > ( const wxString &  aValue)

Definition at line 254 of file eagle_parser.cpp.

255{
256 if( aValue.IsEmpty() )
257 throw XML_PARSER_ERROR( "Conversion to int failed. Original value is empty." );
258
259 return wxAtoi( aValue );
260}

◆ Convert< std::string >()

template<>
std::string Convert< std::string > ( const wxString &  aValue)

Definition at line 234 of file eagle_parser.cpp.

235{
236 return std::string( aValue.ToUTF8() );
237}

◆ Convert< wxString >()

template<>
wxString Convert< wxString > ( const wxString &  aValue)

Definition at line 227 of file eagle_parser.cpp.

228{
229 return aValue;
230}

◆ ConvertArcCenter()

VECTOR2I ConvertArcCenter ( const VECTOR2I aStart,
const VECTOR2I aEnd,
double  aAngle 
)

Definition at line 361 of file eagle_parser.cpp.

362{
363 // Eagle give us start and end.
364 // S_ARC wants start to give the center, and end to give the start.
365 double dx = aEnd.x - aStart.x, dy = aEnd.y - aStart.y;
366 VECTOR2I mid = ( aStart + aEnd ) / 2;
367
368 double dlen = sqrt( dx*dx + dy*dy );
369
370 if( !std::isnormal( dlen ) || !std::isnormal( aAngle ) )
371 {
372 THROW_IO_ERROR( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
373 dlen,
374 aAngle ) );
375 }
376
377 double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) );
378
379 VECTOR2I center(
380 mid.x + dist * ( dy / dlen ),
381 mid.y - dist * ( dx / dlen )
382 );
383
384 return center;
385}
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
double DEG2RAD(double deg)
Definition: trigo.h:195

References _, DEG2RAD(), Format(), THROW_IO_ERROR, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by EAGLE_PLUGIN::loadPlain(), EAGLE_PLUGIN::loadPolygon(), EAGLE_PLUGIN::loadSignals(), SCH_EAGLE_PLUGIN::loadSymbolWire(), SCH_EAGLE_PLUGIN::loadWire(), EAGLE_PLUGIN::packagePolygon(), and EAGLE_PLUGIN::packageWire().

◆ escapeName()

wxString escapeName ( const wxString &  aNetName)

Interprets special characters in Eagle text and converts them to KiCAD notation.

Definition at line 40 of file eagle_parser.cpp.

41{
42 wxString ret( aNetName );
43
44 ret.Replace( "!", "~" );
45
46 return ConvertToNewOverbarNotation( ret );
47}
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.

References ConvertToNewOverbarNotation().

Referenced by SCH_EAGLE_PLUGIN::loadLabel(), SCH_EAGLE_PLUGIN::loadPlainText(), SCH_EAGLE_PLUGIN::loadSegments(), EAGLE_PLUGIN::loadSignals(), and SCH_EAGLE_PLUGIN::loadSymbol().

◆ interpretText()

wxString interpretText ( const wxString &  aText)

Translates Eagle special text reference to a KiCad variable reference.

Definition at line 50 of file eagle_parser.cpp.

51{
52 wxString token = aText.Upper();
53
54 if( substituteVariable( &token ) )
55 return token;
56
57 wxString text;
58 bool sectionOpen = false;
59
60 for( wxString::size_type i = 0; i < aText.size(); i++ )
61 {
62 // Interpret escaped characters
63 if( aText[ i ] == '\\' )
64 {
65 if( i + 1 != aText.size() )
66 text.Append( aText[ i + 1 ] );
67
68 i++;
69 continue;
70 }
71
72 // Escape ~ for KiCAD
73 if( aText[i] == '~' )
74 {
75 text.Append( '~' );
76 text.Append( '~' );
77 continue;
78 }
79
80 if( aText[ i ] == '!' )
81 {
82 if( sectionOpen )
83 {
84 text.Append( '~' );
85 sectionOpen = false;
86 continue;
87 }
88
89 static wxString escapeChars( wxT( " )]}'\"" ) );
90
91 if( i + 1 != aText.size() && escapeChars.Find( aText[i + 1] ) == wxNOT_FOUND )
92 {
93 sectionOpen = true;
94 text.Append( '~' );
95 }
96 else
97 {
98 text.Append( aText[ i ] );
99 }
100
101 continue;
102 }
103
104 if( aText[i] == ',' && sectionOpen )
105 {
106 text.Append( '~' );
107 sectionOpen = false;
108 }
109
110 text.Append( aText[ i ] );
111 }
112
113 return text;
114}
bool substituteVariable(wxString *aText)

References substituteVariable(), and text.

Referenced by EAGLE_PLUGIN::loadPlain(), SCH_EAGLE_PLUGIN::loadPlainText(), SCH_EAGLE_PLUGIN::loadSymbolText(), and EAGLE_PLUGIN::packageText().

◆ MapChildren()

NODE_MAP MapChildren ( wxXmlNode *  aCurrentNode)

Provide an easy access to the children of an XML node via their names.

Parameters
currentNodeis a pointer to a wxXmlNode, whose children will be mapped.
Returns
NODE_MAP is a map linking the name of each children to the children itself (via a wxXmlNode*) Convert an Eagle curve end to a KiCad center for S_ARC

Definition at line 337 of file eagle_parser.cpp.

338{
339 // Map node_name -> node_pointer
340 NODE_MAP nodesMap;
341
342 // Loop through all children mapping them in nodesMap
343 if( aCurrentNode )
344 aCurrentNode = aCurrentNode->GetChildren();
345
346 while( aCurrentNode )
347 {
348 // Create a new pair in the map
349 // key: current node name
350 // value: current node pointer
351 nodesMap[aCurrentNode->GetName()] = aCurrentNode;
352
353 // Get next child
354 aCurrentNode = aCurrentNode->GetNext();
355 }
356
357 return nodesMap;
358}
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:49

Referenced by EAGLE_PLUGIN::cacheLib(), SCH_EAGLE_PLUGIN::countNets(), EDEVICE::EDEVICE(), SCH_EAGLE_PLUGIN::Load(), EAGLE_PLUGIN::loadAllSections(), SCH_EAGLE_PLUGIN::loadDrawing(), EAGLE_PLUGIN::loadLibrary(), SCH_EAGLE_PLUGIN::loadLibrary(), SCH_EAGLE_PLUGIN::loadSchematic(), SCH_EAGLE_PLUGIN::loadSegments(), and SCH_EAGLE_PLUGIN::loadSheet().

◆ parseAlignment()

static int parseAlignment ( const wxString &  aAlignment)
static

Definition at line 388 of file eagle_parser.cpp.

389{
390 // (bottom-left | bottom-center | bottom-right | center-left |
391 // center | center-right | top-left | top-center | top-right)
392 if( aAlignment == "center" )
393 return ETEXT::CENTER;
394 else if( aAlignment == "center-right" )
395 return ETEXT::CENTER_RIGHT;
396 else if( aAlignment == "top-left" )
397 return ETEXT::TOP_LEFT;
398 else if( aAlignment == "top-center" )
399 return ETEXT::TOP_CENTER;
400 else if( aAlignment == "top-right" )
401 return ETEXT::TOP_RIGHT;
402 else if( aAlignment == "bottom-left" )
403 return ETEXT::BOTTOM_LEFT;
404 else if( aAlignment == "bottom-center" )
406 else if( aAlignment == "bottom-right" )
407 return ETEXT::BOTTOM_RIGHT;
408 else if( aAlignment == "center-left" )
409 return ETEXT::CENTER_LEFT;
410
411 return DEFAULT_ALIGNMENT;
412}
constexpr auto DEFAULT_ALIGNMENT
@ BOTTOM_CENTER
Definition: eagle_parser.h:661
@ BOTTOM_RIGHT
Definition: eagle_parser.h:663
@ TOP_CENTER
Definition: eagle_parser.h:655
@ TOP_LEFT
Definition: eagle_parser.h:656
@ TOP_RIGHT
Definition: eagle_parser.h:657
@ CENTER_RIGHT
Definition: eagle_parser.h:660
@ CENTER_LEFT
Definition: eagle_parser.h:654
@ BOTTOM_LEFT
Definition: eagle_parser.h:662

References ETEXT::BOTTOM_CENTER, ETEXT::BOTTOM_LEFT, ETEXT::BOTTOM_RIGHT, ETEXT::CENTER, ETEXT::CENTER_LEFT, ETEXT::CENTER_RIGHT, DEFAULT_ALIGNMENT, ETEXT::TOP_CENTER, ETEXT::TOP_LEFT, and ETEXT::TOP_RIGHT.

Referenced by EATTR::EATTR(), and ETEXT::ETEXT().

◆ parseOptionalAttribute()

template<typename T >
OPTIONAL_XML_ATTRIBUTE< T > parseOptionalAttribute ( wxXmlNode *  aNode,
const wxString &  aAttribute 
)

Parse option aAttribute of the XML node aNode.

Parameters
aNodeis the node whose attribute will be parsed.
aAttributeis the attribute that will be parsed.
Returns
OPTIONAL_XML_ATTRIBUTE<T> - an optional XML attribute, parsed as the specified type if found.

Definition at line 331 of file eagle_parser.cpp.

332{
333 return OPTIONAL_XML_ATTRIBUTE<T>( aNode->GetAttribute( aAttribute ) );
334}
Model an optional XML attribute.
Definition: eagle_parser.h:195

◆ parseRequiredAttribute()

template<typename T >
T parseRequiredAttribute ( wxXmlNode *  aNode,
const wxString &  aAttribute 
)

Parse aAttribute of the XML node aNode.

Parameters
aNodeis the node whose attribute will be parsed.
aAttributeis the attribute that will be parsed.
Exceptions
XML_PARSER_ERROR- exception thrown if the required attribute is missing
Returns
T - the attributed parsed as the specified type.

Definition at line 311 of file eagle_parser.cpp.

312{
313 wxString value;
314
315 if( aNode->GetAttribute( aAttribute, &value ) )
316 return Convert<T>( value );
317 else
318 throw XML_PARSER_ERROR( "The required attribute " + aAttribute + " is missing." );
319}

◆ substituteVariable()

bool substituteVariable ( wxString *  aText)

Definition at line 117 of file eagle_parser.cpp.

118{
119 if ( *aText == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
120 else if( *aText == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
121 else if( *aText == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
122 else if( *aText == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
123 else if( *aText == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
124 else if( *aText == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
125 else if( *aText == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
126 else if( *aText == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
127 else if( *aText == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
128 else if( *aText == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
129 else if( *aText == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
130 else if( *aText == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
131 else if( *aText == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
132 else if( *aText == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
133 else if( *aText == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
134 else if( *aText == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
135 else return false;
136
137 return true;
138}

Referenced by interpretText().

Variable Documentation

◆ DEFAULT_ALIGNMENT

constexpr auto DEFAULT_ALIGNMENT = ETEXT::BOTTOM_LEFT
constexpr

Definition at line 37 of file eagle_parser.cpp.

Referenced by EATTR::EATTR(), ETEXT::ETEXT(), and parseAlignment().