Pcbnew s-expression file parser bug fixes and file size improvements.

* Use index when saving layers to handle translated layer names.
* Add LOCALE_IO switcher when loading s-expression format.
* Make SEGVIA default to through hole to improve file size.
* Don't save default orientation of 0 degrees in TEXTE_MODULE and TEXTE_PCB.
* Don't save default zone configuration parameters.
* Save multiple zone corners on a single line.
* Fixed missing ( check in graphic and module arc parsers.
* Consistency improvements for DRAWSEGMENT and EDGE_MODULE objects.
* Minor tweaks to D_PAD formatting.
This commit is contained in:
Wayne Stambaugh 2012-06-16 18:49:24 -04:00
parent d9ed8a3085
commit 8c72db6631
6 changed files with 282 additions and 185 deletions

View File

@ -129,8 +129,8 @@ priority
pts
radius
rev
rect
rect_delta
rectangle
reference
right
rotate
@ -165,7 +165,6 @@ trapezoid
thru
thru_hole
tstamp
use_thermal
user
user_trace_width
user_via

View File

@ -74,10 +74,14 @@ BOARD::BOARD() :
BuildListOfNets(); // prepare pad and netlist containers.
for( int layer = 0; layer < NB_COPPER_LAYERS; ++layer )
for( int layer = 0; layer < LAYER_COUNT; ++layer )
{
m_Layer[layer].m_Name = GetDefaultLayerName( layer );
if( layer <= LAST_COPPER_LAYER )
m_Layer[layer].m_Type = LT_SIGNAL;
else
m_Layer[layer].m_Type = LT_UNDEFINED;
}
m_NetClasses.GetDefault()->SetDescription( _( "This is the default net class." ) );
@ -356,8 +360,8 @@ wxString BOARD::GetLayerName( int aLayerIndex ) const
if( !IsValidLayerIndex( aLayerIndex ) )
return wxEmptyString;
// copper layer names are stored in the BOARD.
if( IsValidCopperLayerIndex( aLayerIndex ) && IsLayerEnabled( aLayerIndex ) )
// All layer names are stored in the BOARD.
if( IsLayerEnabled( aLayerIndex ) )
{
// default names were set in BOARD::BOARD() but they may be
// over-ridden by BOARD::SetLayerName()

View File

@ -199,7 +199,7 @@ private:
/// edge zone descriptors, owned by pointer.
ZONE_CONTAINERS m_ZoneDescriptorList;
LAYER m_Layer[NB_COPPER_LAYERS];
LAYER m_Layer[LAYER_COUNT];
// if true m_highLight_NetCode is used
HIGH_LIGHT_INFO m_highLight; // current high light data
HIGH_LIGHT_INFO m_highLightPrevious; // a previously stored high light data

View File

@ -186,6 +186,7 @@ wxString SEGZONE::GetSelectMenuText() const
SEGVIA::SEGVIA( BOARD_ITEM* aParent ) :
TRACK( aParent, PCB_VIA_T )
{
SetShape( VIA_THROUGH );
}

View File

@ -134,7 +134,7 @@ void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
void PCB_IO::formatLayer( const BOARD_ITEM* aItem ) const
{
#if USE_LAYER_NAMES
#if 1
m_out->Print( 0, " (layer %s)", m_out->Quotew( aItem->GetLayerName() ).c_str() );
#else
m_out->Print( 0, " (layer %d)", aItem->GetLayer() );
@ -182,7 +182,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
if( mask & aBoard->GetEnabledLayers() )
{
#if USE_LAYER_NAMES
m_out->Print( aNestLevel+1, "(%s %s",
m_out->Print( aNestLevel+1, "(%d %s %s", layer,
m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str(),
LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
#else
@ -210,7 +210,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
if( mask & aBoard->GetEnabledLayers() )
{
#if USE_LAYER_NAMES
m_out->Print( aNestLevel+1, "(%s user",
m_out->Print( aNestLevel+1, "(%d %s user", layer,
m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str() );
#else
m_out->Print( aNestLevel+1, "(%d %s user", layer,
@ -454,20 +454,23 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
switch( aSegment->GetShape() )
{
case S_SEGMENT: // Line
m_out->Print( aNestLevel, "(gr_line (pts (xy %s) (xy %s)) (angle %s)",
m_out->Print( aNestLevel, "(gr_line (start %s) (end %s)",
FMT_IU( aSegment->GetStart() ).c_str(),
FMT_IU( aSegment->GetEnd() ).c_str(),
FMT_ANGLE( aSegment->GetAngle() ).c_str() );
FMT_IU( aSegment->GetEnd() ).c_str() );
if( aSegment->GetAngle() != 0.0 )
m_out->Print( 0, " (angle %s)", FMT_ANGLE( aSegment->GetAngle() ).c_str() );
break;
case S_CIRCLE: // Circle
m_out->Print( aNestLevel, "(gr_circle (center (xy %s)) (end (xy %s))",
m_out->Print( aNestLevel, "(gr_circle (center %s) (end %s)",
FMT_IU( aSegment->GetStart() ).c_str(),
FMT_IU( aSegment->GetEnd() ).c_str() );
break;
case S_ARC: // Arc
m_out->Print( aNestLevel, "(gr_arc (start (xy %s)) (end (xy %s)) (angle %s)",
m_out->Print( aNestLevel, "(gr_arc (start %s) (end %s) (angle %s)",
FMT_IU( aSegment->GetStart() ).c_str(),
FMT_IU( aSegment->GetEnd() ).c_str(),
FMT_ANGLE( aSegment->GetAngle() ).c_str() );
@ -515,19 +518,19 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
switch( aModuleDrawing->GetShape() )
{
case S_SEGMENT: // Line
m_out->Print( aNestLevel, "(fp_line (pts (xy %s) (xy %s))",
m_out->Print( aNestLevel, "(fp_line (start %s) (end %s)",
FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
break;
case S_CIRCLE: // Circle
m_out->Print( aNestLevel, "(fp_circle (center (xy %s)) (end (xy %s))",
m_out->Print( aNestLevel, "(fp_circle (center %s) (end %s)",
FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
FMT_IU( aModuleDrawing->GetEnd0() ).c_str() );
break;
case S_ARC: // Arc
m_out->Print( aNestLevel, "(fp_arc (start (xy %s)) (end (xy %s)) (angle %s)",
m_out->Print( aNestLevel, "(fp_arc (start %s) (end %s) (angle %s)",
FMT_IU( aModuleDrawing->GetStart0() ).c_str(),
FMT_IU( aModuleDrawing->GetEnd0() ).c_str(),
FMT_ANGLE( aModuleDrawing->GetAngle() ).c_str() );
@ -722,7 +725,7 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
switch( aPad->GetShape() )
{
case PAD_CIRCLE: shape = "circle"; break;
case PAD_RECT: shape = "rectangle"; break;
case PAD_RECT: shape = "rect"; break;
case PAD_OVAL: shape = "oval"; break;
case PAD_TRAPEZOID: shape = "trapezoid"; break;
@ -744,27 +747,25 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
aPad->GetAttribute() ) );
}
m_out->Print( aNestLevel, "(pad %s %s %s (size %s)",
m_out->Print( aNestLevel, "(pad %s %s %s",
m_out->Quotew( aPad->GetPadName() ).c_str(),
type.c_str(), shape.c_str(),
FMT_IU( aPad->GetSize() ).c_str() );
m_out->Print( aNestLevel+1, " (at %s", FMT_IU( aPad->GetPos0() ).c_str() );
type.c_str(), shape.c_str() );
m_out->Print( 0, " (at %s", FMT_IU( aPad->GetPos0() ).c_str() );
if( aPad->GetOrientation() != 0.0 )
m_out->Print( 0, " %s", FMT_ANGLE( aPad->GetOrientation() ).c_str() );
m_out->Print( 0, ")" );
m_out->Print( 0, " (size %s)", FMT_IU( aPad->GetSize() ).c_str() );
if( (aPad->GetDelta().GetWidth()) != 0 || (aPad->GetDelta().GetHeight() != 0 ) )
m_out->Print( 0, " (rect_delta %s )", FMT_IU( aPad->GetDelta() ).c_str() );
m_out->Print( 0, "\n" );
wxSize sz = aPad->GetDrillSize();
if( (sz.GetWidth() > 0) || (sz.GetHeight() > 0) )
{
m_out->Print( aNestLevel+1, "(drill" );
m_out->Print( 0, " (drill" );
if( aPad->GetDrillShape() == PAD_OVAL )
m_out->Print( 0, " oval" );
@ -775,9 +776,10 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
if( (aPad->GetOffset().x != 0) || (aPad->GetOffset().y != 0) )
m_out->Print( 0, " (offset %s)", FMT_IU( aPad->GetOffset() ).c_str() );
m_out->Print( 0, ")\n" );
m_out->Print( 0, ")" );
}
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+1, "(layers" );
@ -787,7 +789,7 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
{
if( layerMask & 1 )
{
#if USE_LAYER_NAMES
#if 1
m_out->Print( 0, " %s", m_out->Quotew( m_board->GetLayerName( layer ) ).c_str() );
#else
m_out->Print( 0, " %d", layer );
@ -838,10 +840,14 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
void PCB_IO::format( TEXTE_PCB* aText, int aNestLevel ) const
throw( IO_ERROR )
{
m_out->Print( aNestLevel, "(gr_text %s (at %s %s)",
m_out->Print( aNestLevel, "(gr_text %s (at %s",
m_out->Quotew( aText->GetText() ).c_str(),
FMT_IU( aText->GetPosition() ).c_str(),
FMT_ANGLE( aText->GetOrientation() ).c_str() );
FMT_IU( aText->GetPosition() ).c_str() );
if( aText->GetOrientation() != 0.0 )
m_out->Print( 0, " %s", FMT_ANGLE( aText->GetOrientation() ).c_str() );
m_out->Print( 0, ")" );
formatLayer( aText );
@ -875,11 +881,15 @@ void PCB_IO::format( TEXTE_MODULE* aText, int aNestLevel ) const
if( parent )
orient += parent->GetOrientation();
m_out->Print( aNestLevel, "(fp_text %s %s (at %s %s)",
m_out->Print( aNestLevel, "(fp_text %s %s (at %s",
m_out->Quotew( type ).c_str(),
m_out->Quotew( aText->GetText() ).c_str(),
FMT_IU( aText->GetPos0() ).c_str(), FMT_ANGLE( orient ).c_str() );
FMT_IU( aText->GetPos0() ).c_str() );
if( orient != 0.0 )
m_out->Print( 0, " %s", FMT_ANGLE( orient ).c_str() );
m_out->Print( 0, ")" );
formatLayer( aText );
if( !aText->IsVisible() )
@ -898,7 +908,6 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
{
if( aTrack->Type() == PCB_VIA_T )
{
std::string type;
int layer1, layer2;
SEGVIA* via = (SEGVIA*) aTrack;
@ -907,25 +916,35 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
wxCHECK_RET( board != 0, wxT( "Via " ) + via->GetSelectMenuText() +
wxT( " has no parent." ) );
m_out->Print( aNestLevel, "(via" );
via->ReturnLayerPair( &layer1, &layer2 );
switch( aTrack->GetShape() )
{
case VIA_THROUGH: type = "thru"; break;
case VIA_BLIND_BURIED: type = "blind"; break;
case VIA_MICROVIA: type = "micro"; break;
case VIA_THROUGH: // Default shape not saved.
break;
case VIA_BLIND_BURIED:
m_out->Print( 0, " blind" );
break;
case VIA_MICROVIA:
m_out->Print( 0, " micro" );
break;
default:
THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), aTrack->GetShape() ) );
}
m_out->Print( aNestLevel, "(via %s (at %s) (size %s)", type.c_str(),
m_out->Print( 0, " (at %s) (size %s)",
FMT_IU( aTrack->GetStart() ).c_str(),
FMT_IU( aTrack->GetWidth() ).c_str() );
if( aTrack->GetDrill() != UNDEFINED_DRILL_DIAMETER )
m_out->Print( 0, " (drill %s)", FMT_IU( aTrack->GetDrill() ).c_str() );
#if USE_LAYER_NAMES
#if 1
m_out->Print( 0, " (layers %s %s)",
m_out->Quotew( m_board->GetLayerName( layer1 ) ).c_str(),
m_out->Quotew( m_board->GetLayerName( layer2 ) ).c_str() );
@ -939,7 +958,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
FMT_IU( aTrack->GetStart() ).c_str(), FMT_IU( aTrack->GetEnd() ).c_str(),
FMT_IU( aTrack->GetWidth() ).c_str() );
#if USE_LAYER_NAMES
#if 1
m_out->Print( 0, " (layer %s)", m_out->Quotew( aTrack->GetLayerName() ).c_str() );
#else
m_out->Print( 0, " (layer %d)", aTrack->GetLayer() );
@ -985,47 +1004,72 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
if( aZone->GetPriority() > 0 )
m_out->Print( aNestLevel+1, " (priority %d)\n", aZone->GetPriority() );
// Save pad option and clearance
std::string padoption;
m_out->Print( aNestLevel+1, "(connect_pads" );
switch( aZone->GetPadConnection() )
{
default:
case PAD_IN_ZONE: padoption = "yes"; break;
case THERMAL_PAD: padoption = "use_thermal"; break;
case PAD_NOT_IN_ZONE: padoption = "no"; break;
case THERMAL_PAD: // Default option not saved or loaded.
break;
case PAD_IN_ZONE:
m_out->Print( 0, " yes" );
break;
case PAD_NOT_IN_ZONE:
m_out->Print( 0, " no" );
break;
}
m_out->Print( aNestLevel+1, "(connect_pads %s (clearance %s))\n",
padoption.c_str(), FMT_IU( aZone->GetZoneClearance() ).c_str() );
m_out->Print( 0, " (clearance %s))\n",
FMT_IU( aZone->GetZoneClearance() ).c_str() );
m_out->Print( aNestLevel+1, "(min_thickness %s)\n",
FMT_IU( aZone->GetMinThickness() ).c_str() );
m_out->Print( aNestLevel+1,
"(fill %s (mode %s) (arc_segments %d) (thermal_gap %s) (thermal_bridge_width %s)\n",
(aZone->IsFilled()) ? "yes" : "no",
(aZone->GetFillMode()) ? "segment" : "polygon",
m_out->Print( aNestLevel+1, "(fill" );
// Default is not filled.
if( aZone->IsFilled() )
m_out->Print( 0, " yes" );
// Default is polygon filled.
if( aZone->GetFillMode() )
m_out->Print( 0, " (mode polygon)" );
m_out->Print( 0, " (arc_segments %d) (thermal_gap %s) (thermal_bridge_width %s)\n",
aZone->GetArcSegCount(),
FMT_IU( aZone->GetThermalReliefGap() ).c_str(),
FMT_IU( aZone->GetThermalReliefCopperBridge() ).c_str() );
std::string smoothing;
if( aZone->GetCornerSmoothingType() != ZONE_SETTINGS::SMOOTHING_NONE )
{
m_out->Print( aNestLevel+1, "(smoothing" );
switch( aZone->GetCornerSmoothingType() )
{
case ZONE_SETTINGS::SMOOTHING_NONE: smoothing = "none"; break;
case ZONE_SETTINGS::SMOOTHING_CHAMFER: smoothing = "chamfer"; break;
case ZONE_SETTINGS::SMOOTHING_FILLET: smoothing = "fillet"; break;
case ZONE_SETTINGS::SMOOTHING_CHAMFER:
m_out->Print( 0, " chamfer" );
break;
case ZONE_SETTINGS::SMOOTHING_FILLET:
m_out->Print( 0, " fillet" );
break;
default:
THROW_IO_ERROR( wxString::Format( _( "unknown zone corner smoothing type %d" ),
aZone->GetCornerSmoothingType() ) );
}
m_out->Print( aNestLevel+1, "(smoothing %s) (radius %s))\n",
smoothing.c_str(), FMT_IU( aZone->GetCornerRadius() ).c_str() );
if( aZone->GetCornerRadius() != 0 )
m_out->Print( aNestLevel+1, " (radius %s))\n",
FMT_IU( aZone->GetCornerRadius() ).c_str() );
}
m_out->Print( 0, ")\n" );
const std::vector< CPolyPt >& cv = aZone->m_Poly->corner;
int newLine = 0;
if( cv.size() )
{
@ -1034,18 +1078,36 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
for( std::vector< CPolyPt >::const_iterator it = cv.begin(); it != cv.end(); ++it )
{
m_out->Print( aNestLevel+3, "(xy %s %s)\n",
if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)",
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
else
m_out->Print( 0, " (xy %s %s)",
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
if( newLine < 4 )
{
newLine += 1;
}
else
{
newLine = 0;
m_out->Print( 0, "\n" );
}
if( it->end_contour )
{
if( newLine != 0 )
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+2, ")\n" );
if( it+1 != cv.end() )
{
newLine = 0;
m_out->Print( aNestLevel+1, ")\n" );
m_out->Print( aNestLevel+1, "(polygon\n" );
m_out->Print( aNestLevel+2, "(pts\n" );
m_out->Print( aNestLevel+2, "(pts" );
}
}
}
@ -1055,6 +1117,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
// Save the PolysList
const std::vector< CPolyPt >& fv = aZone->GetFilledPolysList();
newLine = 0;
if( fv.size() )
{
@ -1063,15 +1126,33 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
for( std::vector< CPolyPt >::const_iterator it = fv.begin(); it != fv.end(); ++it )
{
m_out->Print( aNestLevel+3, "(xy %s %s)\n",
if( newLine == 0 )
m_out->Print( aNestLevel+3, "(xy %s %s)",
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
else
m_out->Print( 0, " (xy %s %s)",
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
if( newLine < 4 )
{
newLine += 1;
}
else
{
newLine = 0;
m_out->Print( 0, "\n" );
}
if( it->end_contour )
{
if( newLine != 0 )
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+2, ")\n" );
if( it+1 != fv.end() )
{
newLine = 0;
m_out->Print( aNestLevel+1, ")\n" );
m_out->Print( aNestLevel+1, "(filled_polygon\n" );
m_out->Print( aNestLevel+2, "(pts\n" );

View File

@ -301,6 +301,7 @@ BOARD_ITEM* PCB_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
{
T token;
BOARD_ITEM* item;
LOCALE_IO toggle; // toggles on, then off, the C locale.
token = NextTok();
@ -617,19 +618,18 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
T token;
wxString name;
wxString type;
int layerIndex;
bool isVisible = true;
int visibleLayers = 0;
int enabledLayers = 0;
std::vector< LAYER > layers;
int copperLayerCount = 0;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
#if !USE_LAYER_NAMES
NeedNUMBER( "layer index" );
#endif
layerIndex = parseInt( "layer index" );
NeedSYMBOL();
name = FromUTF8();
@ -652,14 +652,20 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
Expecting( "hide or )" );
}
layers.push_back( LAYER( name, LAYER::ParseType( TO_UTF8( type ) ), isVisible ) );
}
enabledLayers |= 1 << layerIndex;
int copperLayerCount = 0;
if( isVisible )
visibleLayers |= 1 << layerIndex;
for( unsigned i = 0; i < layers.size(); i++ )
{
if( layers[i].m_Type != LT_UNDEFINED )
enum LAYER_T layerType = LAYER::ParseType( TO_UTF8( type ) );
LAYER layer( name, layerType, isVisible );
layer.SetFixedListIndex( layerIndex );
m_board->SetLayer( layerIndex, layer );
m_layerMap[ name ] = layerIndex;
wxLogDebug( wxT( "Mapping layer %s index index %d" ),
GetChars( name ), layerIndex );
if( layerType != LT_UNDEFINED )
copperLayerCount++;
}
@ -667,54 +673,11 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
if( (copperLayerCount < 2) || ((copperLayerCount % 2) != 0) )
{
wxString err;
err.Printf( _( "%d is not a valid layer count" ), layers.size() );
err.Printf( _( "%d is not a valid layer count" ), copperLayerCount );
THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
m_board->SetCopperLayerCount( copperLayerCount );
// Copper layers are sequential from front to back in the file but the current layer
// design uses sequential layers from back to front except for the front layer which
// is always vector index 15.
for( unsigned i = 0; i < layers.size(); i++ )
{
int layerIndex = i;
// The copper layers can have different names but they always are at the beginning
// and have a valid layer type. Non-copper layer name cannot be changed so the
// list index can be looked up by name.
if( layers[i].m_Type != LT_UNDEFINED )
{
if( i == 0 )
layerIndex = LAYER_N_FRONT;
else
layerIndex = copperLayerCount - 1 - i;
}
else
{
layerIndex = LAYER::GetDefaultIndex( layers[i].m_Name );
if( layerIndex == UNDEFINED_LAYER )
{
wxString error;
error.Printf( _( "Cannot determine fixed layer list index of layer name \"%s\"" ),
GetChars( layers[i].m_Name ) );
THROW_IO_ERROR( error );
}
}
enabledLayers |= 1 << layerIndex;
if( layers[i].IsVisible() )
visibleLayers |= 1 << layerIndex;
layers[i].SetFixedListIndex( layerIndex );
m_board->SetLayer( layerIndex, layers[i] );
m_layerMap[ layers[i].m_Name ] = layerIndex;
wxLogDebug( wxT( "Mapping layer %s index index %d" ),
GetChars( layers[i].m_Name ), layerIndex );
}
m_board->SetVisibleLayers( visibleLayers );
m_board->SetEnabledLayers( enabledLayers );
}
@ -1119,7 +1082,7 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
T token;
wxPoint pt;
auto_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
switch( CurTok() )
@ -1132,7 +1095,9 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
if( token != T_start )
Expecting( T_start );
segment->SetStart( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
@ -1140,14 +1105,9 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
if( token != T_end )
Expecting( T_end );
segment->SetEnd( parseXY() );
NeedRIGHT();
token = NextTok();
if( token != T_angle )
Expecting( T_angle );
segment->SetAngle( parseDouble( "segment angle" ) );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd( pt );
NeedRIGHT();
break;
@ -1159,15 +1119,20 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
if( token != T_center )
Expecting( T_center );
segment->SetStart( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_end )
Expecting( T_end );
segment->SetEnd( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd( pt );
NeedRIGHT();
break;
@ -1191,19 +1156,22 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
if( token != T_start )
Expecting( T_start );
segment->SetStart( parseXY() );
segment->SetEnd( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_angle )
Expecting( T_angle );
if( token != T_end )
Expecting( T_end );
segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd( pt );
NeedRIGHT();
break;
@ -1238,6 +1206,10 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
switch( token )
{
case T_angle:
segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
break;
case T_layer:
segment->SetLayer( parseBoardItemLayer() );
break;
@ -1287,8 +1259,19 @@ TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR )
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
text->SetPosition( pt );
text->SetOrientation( parseDouble( "angle" ) * 10.0 );
// If there is no orientation defined, then it is the default value of 0 degrees.
token = NextTok();
if( token == T_NUMBER )
{
text->SetOrientation( parseDouble() * 10.0 );
NeedRIGHT();
}
else if( token != T_RIGHT )
{
Unexpected( CurText() );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
@ -1725,8 +1708,18 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR )
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
text->SetPos0( pt );
text->SetOrientation( parseDouble( "angle" ) * 10.0 );
token = NextTok();
// If there is no orientation defined, then it is the default value of 0 degrees.
if( token == T_NUMBER )
{
text->SetOrientation( parseDouble() * 10.0 );
NeedRIGHT();
}
else if( token != T_RIGHT )
{
Unexpected( CurText() );
}
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
@ -1763,6 +1756,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
CurTok() == T_fp_line || CurTok() == T_fp_poly, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as EDGE_MODULE." ) );
wxPoint pt;
T token;
auto_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
@ -1777,15 +1771,20 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
if( token != T_start )
Expecting( T_start );
segment->SetStart0( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart0( pt );
NeedRIGHT();
token = NextTok();
if( token != T_end )
Expecting( T_end );
segment->SetEnd0( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd0( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_angle )
@ -1803,7 +1802,9 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
if( token != T_center )
Expecting( T_center );
segment->SetStart0( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart0( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
@ -1811,7 +1812,9 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
if( token != T_end )
Expecting( T_end );
segment->SetEnd0( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd0( pt );
NeedRIGHT();
break;
@ -1835,11 +1838,23 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
NeedLEFT();
token = NextTok();
if( token != T_pts )
Expecting( T_pts );
if( token != T_start )
Expecting( T_start );
segment->SetStart0( parseXY() );
segment->SetEnd0( parseXY() );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart0( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_end )
Expecting( T_end );
pt.x = parseBoardUnits( "X coordinate" );
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetEnd0( pt );
NeedRIGHT();
break;
@ -1945,7 +1960,7 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR )
pad->SetShape( PAD_CIRCLE );
break;
case T_rectangle:
case T_rect:
pad->SetShape( PAD_RECT );
break;
@ -2203,10 +2218,6 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR )
switch( token )
{
case T_thru:
via->SetShape( VIA_THROUGH );
break;
case T_blind:
via->SetShape( VIA_BLIND_BURIED );
break;
@ -2261,7 +2272,7 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR )
break;
default:
Expecting( "at, size, drill, layers, net, tstamp, or status" );
Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
}
}
@ -2339,25 +2350,31 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
break;
case T_connect_pads:
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_yes: zone->SetPadConnection( PAD_IN_ZONE ); break;
case T_use_thermal: zone->SetPadConnection( THERMAL_PAD ); break;
case T_no: zone->SetPadConnection( PAD_NOT_IN_ZONE ); break;
default: Expecting( "yes, no, or use_thermal" );
}
case T_yes:
zone->SetPadConnection( PAD_IN_ZONE );
break;
NeedLEFT();
token = NextTok();
if( token != T_clearance )
Expecting( T_clearance );
case T_no:
zone->SetPadConnection( PAD_NOT_IN_ZONE );
break;
case T_clearance:
zone->SetZoneClearance( parseBoardUnits( "zone clearance" ) );
NeedRIGHT();
NeedRIGHT();
break;
default:
Expecting( "yes, no, or clearance" );
}
}
break;
case T_min_thickness:
@ -2366,22 +2383,17 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
break;
case T_fill:
token = NextTok();
if( token != T_yes && token != T_no )
Expecting( "yes or no" );
zone->SetIsFilled( token == T_yes );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_yes:
zone->SetIsFilled( true );
break;
case T_mode:
token = NextTok();