From c135158364879d25be087899651ebfccb1740336 Mon Sep 17 00:00:00 2001 From: John Beard Date: Mon, 15 Apr 2019 09:56:01 +0100 Subject: [PATCH] Kicad2Step: handle quoted layers More recent Kicad_pcb files have quoted layer names (i.e. strings, not symbols). The importer in K2S doesn't handle that, so it chokes on elements like (layer "Edge.Cuts"). Fixes: lp:1824750 * https://bugs.launchpad.net/kicad/+bug/1824750 --- utils/kicad2step/pcb/kicadcurve.cpp | 45 +++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/utils/kicad2step/pcb/kicadcurve.cpp b/utils/kicad2step/pcb/kicadcurve.cpp index 991e15820b..d635ec2cb5 100644 --- a/utils/kicad2step/pcb/kicadcurve.cpp +++ b/utils/kicad2step/pcb/kicadcurve.cpp @@ -28,6 +28,40 @@ #include "sexpr/sexpr.h" #include "kicadcurve.h" +#include + +/** + * Get the layer name from a layer element, if the layer is syntactically + * valid + * + * E.g. (layer "Edge.Cuts") -> "Edge.Cuts" + * + * @param aLayerElem the s-expr element to get the name from + * @return the layer name if valid, else empty + */ +static OPT getLayerName( const SEXPR::SEXPR& aLayerElem ) +{ + OPT layer; + + if( aLayerElem.GetNumberOfChildren() == 2 ) + { + const auto& layerChild = *aLayerElem.GetChild( 1 ); + + // The layer child can be quoted (string) or unquoted (symbol) + // depending on PCB version. + if( layerChild.IsString() ) + { + layer = layerChild.GetString(); + } + else if( layerChild.IsSymbol() ) + { + layer = layerChild.GetSymbol(); + } + } + + return layer; +} + KICADCURVE::KICADCURVE() { @@ -115,19 +149,18 @@ bool KICADCURVE::Read( SEXPR::SEXPR* aEntry, CURVE_TYPE aCurveType ) } else if( text == "layer" ) { - if( child->GetNumberOfChildren() < 2 - || !child->GetChild( 1 )->IsSymbol() ) + const OPT layer = getLayerName( *child ); + + if( !layer ) { std::ostringstream ostr; - ostr << "* bad layer data"; + ostr << "* bad layer data: " << child->AsString(); wxLogMessage( "%s\n", ostr.str().c_str() ); return false; } - text = child->GetChild( 1 )->GetSymbol(); - // NOTE: for the moment we only process Edge.Cuts - if( text == "Edge.Cuts" ) + if( *layer == "Edge.Cuts" ) m_layer = LAYER_EDGE; } }