Add Pcbnew s-expression file parser.

* Add s-expression file parser object and keyword files.
* Fix minor issues with s-expression file formatting.
* Fix a minor bug the zone container fill state parsing in the legacy plugin.
* Move EDA_TEXT visibility definition to eda_text.h.
* Add minor BOARD_ITEM object improvements to support s-expression file
  parser.
This commit is contained in:
Wayne Stambaugh 2012-06-09 13:00:13 -04:00
parent de471744cd
commit 2d0d805014
26 changed files with 4399 additions and 1201 deletions

View File

@ -30,3 +30,5 @@ new/sweet_keywords.cpp
new/sweet_lexer.h
bitmaps_png/png*
bitmaps_png/tmp
common/pcb_keywords.cpp
include/pcb_lexer.h

View File

@ -177,7 +177,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
// because all boards thickness no not match with this setup:
// double epoxy_width = 1.6; // epoxy width in mm
g_Parm_3D_Visu.m_Epoxy_Width = pcb->GetDesignSettings().m_BoardThickness
g_Parm_3D_Visu.m_Epoxy_Width = pcb->GetDesignSettings().GetBoardThickness()
* g_Parm_3D_Visu.m_BoardScale;
// calculate z position for each layer

View File

@ -121,6 +121,8 @@ set(PCB_COMMON_SRCS
../pcbnew/legacy_plugin.cpp
../pcbnew/kicad_plugin.cpp
pcb_plot_params_keywords.cpp
pcb_keywords.cpp
../pcbnew/pcb_parser.cpp
)
@ -148,6 +150,14 @@ make_lexer(
PCBPLOTPARAMS_T
)
# auto-generate pcbnew_sexpr.h and pcbnew_sexpr.cpp
make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/pcb.keywords
${PROJECT_SOURCE_DIR}/include/pcb_lexer.h
${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp
PCB
)
# The dsntest may not build properly using MS Visual Studio.
if(NOT MSVC)
# This one gets made only when testing.

View File

@ -354,7 +354,11 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
// Add font support here at some point in the future.
if( ( m_Size.x != DEFAULT_SIZE_TEXT ) || ( m_Size.y != DEFAULT_SIZE_TEXT ) )
aFormatter->Print( 0, " (size %s)", FMT_IU( m_Size ).c_str() );
aFormatter->Print( 0, " (size %s %s)", FMT_IU( m_Size.GetHeight() ).c_str(),
FMT_IU( m_Size.GetWidth() ).c_str() );
if( m_Thickness != 0 )
aFormatter->Print( 0, " (thickness %s)", FMT_IU( m_Thickness ).c_str() );
if( m_Bold )
aFormatter->Print( 0, " bold" );

195
common/pcb.keywords Normal file
View File

@ -0,0 +1,195 @@
#
# This program source code file is part of KiCad, a free EDA CAD application.
#
# Copyright (C) 2012 CERN.
#
# 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
#
# These are the keywords for the Pcbnew s-expression file format.
add_net
angle
arc
arc_segments
area
arrow1a
arrow1b
arrow2a
arrow2b
at
attr
autoplace_cost90
autoplace_cost180
aux_axis_origin
blind
bold
bottom
center
chamfer
circle
clearance
comment
company
connect
connect_pads
crossbar
date
descr
die_length
dimension
drawings
drill
edge
edge_width
effects
end
feature1
feature2
fill
fill_segments
filled_polygon
fillet
font
fp_arc
fp_circle
fp_curve
fp_line
fp_poly
fp_text
full
general
gr_arc
gr_circle
gr_curve
gr_line
gr_poly
gr_text
hatch
hide
italic
justify
kicad_pcb
last_trace_width
layer
layers
left
links
locked
micro
min_thickness
mirror
mod_edge_width
mod_text_size
mod_text_width
mode
model
module
net
net_class
net_name
nets
no
no_connects
none
np_thru_hole
offset
oval
pad
pad_drill
pad_size
pad_to_mask_clearance
pad_to_paste_clearance
pad_to_paste_clearance_ratio
page
path
pcb_text_size
pcb_text_width
placed
plus
polygon
portrait
priority
pts
radius
rev
rectangle
reference
right
rotate
scale
segment
segment_width
setup
size
smd
smoothing
solder_mask_margin
solder_paste_margin
solder_paste_margin_ratio
solder_paste_ratio
start
status
tags
target
title
title_block
tedit
thermal_width
thermal_gap
thermal_bridge_width
thickness
top
trace_width
tracks
trace_min
trace_clearance
trapezoid
thru
thru_hole
tstamp
use_thermal
user
user_trace_width
user_via
uvia_dia
uvia_drill
uvia_min_drill
uvia_min_size
uvia_size
uvias_allowed
value
version
via
via_dia
via_drill
via_min_drill
via_min_size
via_size
virtual
visible_elements
width
x
xy
xyz
yes
zone
zone_45_only
zone_clearance
zone_connect
zones

View File

@ -1673,28 +1673,36 @@ void TITLE_BLOCK::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aCont
aFormatter->Print( aNestLevel, "(title_block\n" );
if( !m_title.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(title %s)\n", EscapedUTF8( m_title ).c_str() );
aFormatter->Print( aNestLevel+1, "(title %s)\n",
aFormatter->Quotew( m_title ).c_str() );
if( !m_date.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(date %s)\n", EscapedUTF8( m_date ).c_str() );
aFormatter->Print( aNestLevel+1, "(date %s)\n",
aFormatter->Quotew( m_date ).c_str() );
if( !m_revision.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(rev %s)\n", EscapedUTF8( m_revision ).c_str() );
aFormatter->Print( aNestLevel+1, "(rev %s)\n",
aFormatter->Quotew( m_revision ).c_str() );
if( !m_company.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(company %s)\n", EscapedUTF8( m_company ).c_str() );
aFormatter->Print( aNestLevel+1, "(company %s)\n",
aFormatter->Quotew( m_company ).c_str() );
if( !m_comment1.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment1 %s)\n", EscapedUTF8( m_comment1 ).c_str() );
aFormatter->Print( aNestLevel+1, "(comment 1 %s)\n",
aFormatter->Quotew( m_comment1 ).c_str() );
if( !m_comment2.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment2 %s)\n", EscapedUTF8( m_comment2 ).c_str() );
aFormatter->Print( aNestLevel+1, "(comment 2 %s)\n",
aFormatter->Quotew( m_comment2 ).c_str() );
if( !m_comment3.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment3 %s)\n", EscapedUTF8( m_comment3 ).c_str() );
aFormatter->Print( aNestLevel+1, "(comment 3 %s)\n",
aFormatter->Quotew( m_comment3 ).c_str() );
if( !m_comment4.IsEmpty() )
aFormatter->Print( aNestLevel+1, "(comment4 %s)\n", EscapedUTF8( m_comment4 ).c_str() );
aFormatter->Print( aNestLevel+1, "(comment 4 %s)\n",
aFormatter->Quotew( m_comment4 ).c_str() );
aFormatter->Print( aNestLevel, ")\n\n" );
}

View File

@ -33,8 +33,6 @@ class TRANSFORM;
#define HIGHLIGHT_COLOR WHITE
#define TEXT_NO_VISIBLE 1
//#define GR_DEFAULT_DRAWMODE GR_COPY
#define GR_DEFAULT_DRAWMODE GR_COPY

View File

@ -37,7 +37,6 @@ public:
int m_SolderPasteMargin; ///< Solder paste margin absolute value
double m_SolderPasteMarginRatio; ///< Solder pask margin ratio value of pad size
///< The final margin is the sum of these 2 values
int m_BoardThickness; ///< Board Thickness for 3D viewer
// Variables used in footprint handling
wxSize m_ModuleTextSize; ///< Default footprint texts size
@ -188,11 +187,15 @@ public:
*/
void AppendConfigs( PARAM_CFG_ARRAY* aResult );
int GetBoardThickness() const { return m_boardThickness; }
void SetBoardThickness( int aThickness ) { m_boardThickness = aThickness; }
private:
int m_CopperLayerCount; ///< Number of copper layers for this design
int m_EnabledLayers; ///< Bit-mask for layer enabling
int m_VisibleLayers; ///< Bit-mask for layer visibility
int m_VisibleElements; ///< Bit-mask for element category visibility
int m_boardThickness; ///< Board thickness for 3D viewer
};
#endif // BOARD_DESIGN_SETTINGS_H_

View File

@ -57,7 +57,10 @@ enum EDA_DRAW_MODE_T {
SKETCH // sketch mode: segments have thickness, but are not filled
};
#define DEFAULT_SIZE_TEXT 60 /* default text height (in mils or 1/1000") */
#define TEXT_NO_VISIBLE 1 //< EDA_TEXT::m_Attribut(e?) visibility flag.
/**
* Class EDA_TEXT
@ -110,6 +113,15 @@ public:
void SetItalic( bool isItalic ) { m_Italic = isItalic; }
bool IsItalic() const { return m_Italic; }
void SetBold( bool aBold ) { m_Bold = aBold; }
bool IsBold() const { return m_Bold; }
void SetVisible( bool aVisible )
{
( aVisible ) ? m_Attributs &= ~TEXT_NO_VISIBLE : m_Attributs |= TEXT_NO_VISIBLE;
}
bool IsVisible() const { return !( m_Attributs & TEXT_NO_VISIBLE ); }
void SetMirrored( bool isMirrored ) { m_Mirror = isMirrored; }
bool IsMirrored() const { return m_Mirror; }

View File

@ -7,6 +7,7 @@
#define _LAYERS_ID_AND_VISIBILITY_H_
/* Layer identification (layer number) */
#define UNDEFINED_LAYER -1
#define FIRST_COPPER_LAYER 0
#define LAYER_N_BACK 0
#define LAYER_N_2 1

View File

@ -539,7 +539,10 @@ bool TREE_PROJECT_FRAME::AddFileToTree( const wxString& aName,
bool addFile = false;
for( unsigned i = 0; i < m_Filters.size(); i++ )
{
reg.Compile( m_Filters[i], wxRE_ICASE );
wxCHECK2_MSG( reg.Compile( m_Filters[i], wxRE_ICASE ), continue,
wxT( "Regular expression " ) + m_Filters[i] +
wxT( " failed to compile." ) );
if( reg.Matches( aName ) )
{
addFile = true;

View File

@ -339,6 +339,18 @@ int BOARD::GetCurrentMicroViaDrill()
}
bool BOARD::SetLayer( int aIndex, const LAYER& aLayer )
{
if( aIndex < NB_COPPER_LAYERS )
{
m_Layer[ aIndex ] = aLayer;
return true;
}
return false;
}
wxString BOARD::GetLayerName( int aLayerIndex ) const
{
if( !IsValidLayerIndex( aLayerIndex ) )
@ -407,7 +419,7 @@ bool BOARD::SetLayerName( int aLayerIndex, const wxString& aLayerName )
if( !IsValidCopperLayerIndex( aLayerIndex ) )
return false;
if( aLayerName == wxEmptyString || aLayerName.Len() > 20 )
if( aLayerName == wxEmptyString || aLayerName.Len() > 20 )
return false;
// no quote chars in the name allowed
@ -506,14 +518,65 @@ LAYER_T LAYER::ParseType( const char* aType )
else if( strcmp( aType, "jumper" ) == 0 )
return LT_JUMPER;
else
return LAYER_T( -1 );
return LT_UNDEFINED;
}
int LAYER::GetDefaultIndex( const wxString& aName )
{
static LAYER_INDEX_HASH_MAP layerIndices;
if( layerIndices.empty() )
{
// These are only default layer names. The copper names may be over-ridden in
// the BOARD (*.brd) file.
layerIndices[ _( "Front" ) ] = LAYER_N_FRONT;
layerIndices[ _( "Inner2" ) ] = LAYER_N_2;
layerIndices[ _( "Inner3" ) ] = LAYER_N_3;
layerIndices[ _( "Inner4" ) ] = LAYER_N_4;
layerIndices[ _( "Inner5" ) ] = LAYER_N_5;
layerIndices[ _( "Inner6" ) ] = LAYER_N_6;
layerIndices[ _( "Inner7" ) ] = LAYER_N_7;
layerIndices[ _( "Inner8" ) ] = LAYER_N_8;
layerIndices[ _( "Inner9" ) ] = LAYER_N_9;
layerIndices[ _( "Inner10" ) ] = LAYER_N_10;
layerIndices[ _( "Inner11" ) ] = LAYER_N_11;
layerIndices[ _( "Inner12" ) ] = LAYER_N_12;
layerIndices[ _( "Inner13" ) ] = LAYER_N_13;
layerIndices[ _( "Inner14" ) ] = LAYER_N_14;
layerIndices[ _( "Inner15" ) ] = LAYER_N_15;
layerIndices[ _( "Back" ) ] = LAYER_N_BACK;
layerIndices[ _( "Adhes_Back" ) ] = ADHESIVE_N_BACK;
layerIndices[ _( "Adhes_Front" ) ] = ADHESIVE_N_FRONT;
layerIndices[ _( "SoldP_Back" ) ] = SOLDERPASTE_N_BACK;
layerIndices[ _( "SoldP_Front" ) ] = SOLDERPASTE_N_FRONT;
layerIndices[ _( "SilkS_Back" ) ] = SILKSCREEN_N_BACK;
layerIndices[ _( "SilkS_Front" ) ] = SILKSCREEN_N_FRONT;
layerIndices[ _( "Mask_Back" ) ] = SOLDERMASK_N_BACK;
layerIndices[ _( "Mask_Front" ) ] = SOLDERMASK_N_FRONT;
layerIndices[ _( "Drawings" ) ] = DRAW_N;
layerIndices[ _( "Comments" ) ] = COMMENT_N;
layerIndices[ _( "Eco1" ) ] = ECO1_N;
layerIndices[ _( "Eco2" ) ] = ECO2_N;
layerIndices[ _( "PCB_Edges" ) ] = EDGE_N;
}
const LAYER_INDEX_HASH_MAP::iterator it = layerIndices.find( aName );
if( it == layerIndices.end() )
return UNDEFINED_LAYER;
return layerIndices[ aName ];
}
int BOARD::GetCopperLayerCount() const
{
return m_designSettings.GetCopperLayerCount();
}
void BOARD::SetCopperLayerCount( int aCount )
{
m_designSettings.SetCopperLayerCount( aCount );

View File

@ -19,6 +19,9 @@
#include <class_zone_settings.h>
#include <pcb_plot_params.h>
#include <wx/hashmap.h>
class PCB_BASE_FRAME;
class PCB_EDIT_FRAME;
class PICKED_ITEMS_LIST;
@ -43,6 +46,7 @@ typedef std::vector< TRACK* > TRACK_PTRS;
*/
enum LAYER_T
{
LT_UNDEFINED = -1,
LT_SIGNAL,
LT_POWER,
LT_MIXED,
@ -51,11 +55,27 @@ enum LAYER_T
/**
* Struct LAYER
* Class LAYER
* holds information pertinent to a layer of a BOARD.
*/
struct LAYER
class LAYER
{
public:
LAYER( const wxString& aName = wxEmptyString, LAYER_T aType = LT_SIGNAL,
bool aVisible = true ) :
m_Name( aName ),
m_Type( aType ),
m_visible( aVisible ),
m_fixedListIndex( UNDEFINED_LAYER )
{
}
void SetVisible( bool aEnable ) { m_visible = aEnable; }
bool IsVisible() const { return m_visible; }
void SetFixedListIndex( int aIndex ) { m_fixedListIndex = aIndex; }
int GetFixedListIndex() const { return m_fixedListIndex; }
/** The name of the layer, there should be no spaces in this name. */
wxString m_Name;
@ -63,7 +83,6 @@ struct LAYER
LAYER_T m_Type;
// int m_Color;
// bool m_Visible; // ? use flags in m_Color instead ?
/**
* Function ShowType
@ -81,9 +100,25 @@ struct LAYER
* LAYER_T(-1) if the string is invalid
*/
static LAYER_T ParseType( const char* aType );
/**
* Function GetDefaultIndex
* returns the layer index of the layer \a aName.
*
* @param aName A reference to a wxString object containing the default layer name.
* @return The index of the layer \a aName if found otherwise #UNDEFINED_LAYER_INDEX.
*/
static int GetDefaultIndex( const wxString& aName );
private:
bool m_visible;
int m_fixedListIndex;
};
WX_DECLARE_STRING_HASH_MAP( int, LAYER_INDEX_HASH_MAP );
/**
* Struct VIA_DIMENSION
* is a small helper container to handle a stock of specific vias each with
@ -600,6 +635,8 @@ public:
*/
bool SetLayerName( int aLayerIndex, const wxString& aLayerName );
bool SetLayer( int aIndex, const LAYER& aLayer );
/**
* Function GetLayerType
* returns the type of the copper layer given by aLayerIndex.

View File

@ -62,7 +62,7 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS() :
m_ModuleSegmentWidth = DMils2iu( 100 );
// Layer thickness for 3D viewer
m_BoardThickness = DMils2iu( DEFAULT_BOARD_THICKNESS_DMILS );
m_boardThickness = DMils2iu( DEFAULT_BOARD_THICKNESS_DMILS );
}
@ -70,7 +70,7 @@ void BOARD_DESIGN_SETTINGS::AppendConfigs( PARAM_CFG_ARRAY* aResult )
{
m_Pad_Master.AppendConfigs( aResult );
aResult->push_back( new PARAM_CFG_INT( wxT( "BoardThickness" ), &m_BoardThickness,
aResult->push_back( new PARAM_CFG_INT( wxT( "BoardThickness" ), &m_boardThickness,
DMils2iu( DEFAULT_BOARD_THICKNESS_DMILS ), 0, 0xFFFF ) );
aResult->push_back( new PARAM_CFG_INT( wxT( "TxtPcbV" ), &m_PcbTextSize.y,

View File

@ -91,31 +91,15 @@ wxString BOARD_ITEM::GetLayerName() const
std::string BOARD_ITEM::FormatInternalUnits( int aValue )
{
char buf[50];
char buf[50];
#if defined( USE_PCBNEW_NANOMETRES )
double engUnits = aValue / 1000000.0;
int nm = aValue;
#else
double engUnits = ( aValue * 10000.0 ) / 25.4 / 1000000.0;
int nm = KIROUND( ( aValue / 10000.0 ) * 25.4 * 1e6 );
#endif
int len;
if( engUnits != 0.0 && fabs( engUnits ) <= 0.0001 )
{
// printf( "f: " );
len = snprintf( buf, 49, "%.10f", engUnits );
while( --len > 0 && buf[len] == '0' )
buf[len] = '\0';
++len;
}
else
{
// printf( "g: " );
len = snprintf( buf, 49, "%.10g", engUnits );
}
int len = snprintf( buf, 49, "%g", nm / 1e6 );
return std::string( buf, len );
}

View File

@ -32,6 +32,7 @@
#include <class_board_item.h>
#include <class_pcb_text.h>
class LINE_READER;

View File

@ -572,6 +572,20 @@ D_PAD* MODULE::GetPad( const wxPoint& aPosition, int aLayerMask )
}
void MODULE::Add3DModel( S3D_MASTER* a3DModel )
{
a3DModel->SetParent( this );
m_3D_Drawings.PushBack( a3DModel );
}
void MODULE::AddPad( D_PAD* aPad )
{
aPad->SetParent( this );
m_Pads.PushBack( aPad );
}
// see class_module.h
SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] )

View File

@ -325,6 +325,22 @@ public:
*/
unsigned GetPadCount() const { return m_Pads.GetCount() ; }
/**
* Function Add3DModel
* adds \a a3DModel definition to the end of the 3D model list.
*
* @param a3DModel A pointer to a #S3D_MASTER to add to the list.
*/
void Add3DModel( S3D_MASTER* a3DModel );
/**
* Function AddPad
* adds \a aPad to the end of the pad list.
*
* @param aPad A pointer to a #D_PAD to add to the list.
*/
void AddPad( D_PAD* aPad );
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );

View File

@ -916,6 +916,24 @@ ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const
}
void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
{
if( aPolygon.empty() )
return;
for( unsigned i = 0; i < aPolygon.size(); i++ )
{
if( i == 0 )
m_Poly->Start( GetLayer(), aPolygon[i].x, aPolygon[i].y, GetHatchStyle() );
else
AppendCorner( aPolygon[i] );
}
m_Poly->Close();
}
wxString ZONE_CONTAINER::GetSelectMenuText() const
{
wxString text;

View File

@ -429,6 +429,11 @@ public:
return m_Poly->GetHatchStyle();
}
void SetHatchStyle( CPolyLine::hatch_style aStyle )
{
m_Poly->SetHatchStyle( aStyle );
}
/**
* Function TransformShapeWithClearanceToPolygon
* Convert the track shape to a closed polygon
@ -515,6 +520,18 @@ public:
unsigned int GetCornerRadius() const { return cornerRadius; };
void AddPolygon( std::vector< wxPoint >& aPolygon );
void AddFilledPolygon( std::vector< CPolyPt >& aPolygon )
{
m_FilledPolysList.insert( m_FilledPolysList.end(), aPolygon.begin(), aPolygon.end() );
}
void AddFillSegments( std::vector< SEGMENT >& aSegments )
{
m_FillSegmList.insert( m_FillSegmList.end(), aSegments.begin(), aSegments.end() );
}
virtual wxString GetSelectMenuText() const;
virtual BITMAP_DEF GetMenuImage() const { return add_zone_xpm; }

View File

@ -369,7 +369,7 @@ static void compute_layer_Zs( BOARD* pcb ) //{{{
int copper_layers = pcb->GetCopperLayerCount( );
// We call it 'layer' thickness, but it's the whole board thickness!
double board_thickness = pcb->GetDesignSettings().m_BoardThickness;
double board_thickness = pcb->GetDesignSettings().GetBoardThickness();
double half_thickness = board_thickness / 2;
// Compute each layer's Z value, more or less like the 3d view

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +1,149 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) CERN.
*
* 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 KICAD_PLUGIN_H_
#define KICAD_PLUGIN_H_
#include <io_mgr.h>
#include <string>
class BOARD;
class BOARD_ITEM;
/** Current s-expression file format version. 2 was the last legacy format version. */
#define SEXPR_BOARD_FILE_VERSION 3
/** Format output for the clipboard instead of a file. */
#define CTL_CLIPBOARD (1 << 0)
/**
* Class PCB_IO
* is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
*
* @note This class is not thread safe, but it is re-entrant multiple times in sequence.
*/
class PCB_IO : public PLUGIN
{
public:
const wxString& PluginName() const
{
static const wxString name = wxT( "KiCad" );
return name;
}
const wxString& GetFileExtension() const
{
static const wxString extension = wxT( "kicad_pcb" );
return extension;
}
void Save( const wxString& aFileName, BOARD* aBoard,
PROPERTIES* aProperties = NULL ); // overload
/**
* Function Format
* outputs \a aItem to \a aFormatter in s-expression format.
*
* @param aItem A pointer the an #BOARD_ITEM object to format.
* @param aFormatter The #OUTPUTFORMATTER object to write to.
* @param aNestLevel The indentation nest level.
* @param aControlBits The control bit definition for object specific formatting.
* @throw IO_ERROR on write error.
*/
void Format( BOARD_ITEM* aItem, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
protected:
wxString m_error; ///< for throwing exceptions
BOARD* m_board; ///< which BOARD, no ownership here
PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
LINE_READER* m_reader; ///< no ownership here.
wxString m_filename; ///< for saves only, name is in m_reader for loads
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
private:
void format( BOARD* aBoard, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( DIMENSION* aDimension, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( EDGE_MODULE* aModuleDrawing, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( DRAWSEGMENT* aSegment, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( PCB_TARGET* aTarget, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( MODULE* aModule, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( D_PAD* aPad, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( TEXTE_PCB* aText, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( TEXTE_MODULE* aText, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( TRACK* aTrack, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
void format( ZONE_CONTAINER* aZone, OUTPUTFORMATTER* aFormatter, int aNestLevel,
int aControlBits ) const
throw( IO_ERROR );
};
#endif // KICAD_PLUGIN_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 CERN.
*
* 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 KICAD_PLUGIN_H_
#define KICAD_PLUGIN_H_
#include <io_mgr.h>
#include <string>
class BOARD;
class BOARD_ITEM;
/** Current s-expression file format version. 2 was the last legacy format version. */
#define SEXPR_BOARD_FILE_VERSION 3
/** Format output for the clipboard instead of a file. */
#define CTL_CLIPBOARD (1 << 0)
/**
* Class PCB_IO
* is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
*
* @note This class is not thread safe, but it is re-entrant multiple times in sequence.
*/
class PCB_IO : public PLUGIN
{
public:
//-----<PLUGIN API>---------------------------------------------------------
const wxString& PluginName() const
{
static const wxString name = wxT( "KiCad" );
return name;
}
const wxString& GetFileExtension() const
{
static const wxString extension = wxT( "kicad_pcb" );
return extension;
}
void Save( const wxString& aFileName, BOARD* aBoard,
PROPERTIES* aProperties = NULL ); // overload
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES* aProperties = NULL );
//-----</PLUGIN API>--------------------------------------------------------
PCB_IO();
/**
* Function Format
* outputs \a aItem to \a aFormatter in s-expression format.
*
* @param aItem A pointer the an #BOARD_ITEM object to format.
* @param aNestLevel The indentation nest level.
* @throw IO_ERROR on write error.
*/
void Format( BOARD_ITEM* aItem, int aNestLevel = 0 ) const
throw( IO_ERROR );
std::string GetStringOutput( bool doClear )
{
std::string ret = m_sf.GetString();
if( doClear )
m_sf.Clear();
return ret;
}
protected:
wxString m_error; ///< for throwing exceptions
BOARD* m_board; ///< which BOARD, no ownership here
PROPERTIES* m_props; ///< passed via Save() or Load(), no ownership, may be NULL.
LINE_READER* m_reader; ///< no ownership here.
wxString m_filename; ///< for saves only, name is in m_reader for loads
int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing?
STRING_FORMATTER m_sf;
OUTPUTFORMATTER* m_out; ///< output any Format()s to this, no ownership
int m_ctl;
private:
void format( BOARD* aBoard, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( DIMENSION* aDimension, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( EDGE_MODULE* aModuleDrawing, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( DRAWSEGMENT* aSegment, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( PCB_TARGET* aTarget, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( MODULE* aModule, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( D_PAD* aPad, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( TEXTE_PCB* aText, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( TEXTE_MODULE* aText, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( TRACK* aTrack, int aNestLevel = 0 ) const
throw( IO_ERROR );
void format( ZONE_CONTAINER* aZone, int aNestLevel = 0 ) const
throw( IO_ERROR );
void formatLayer( const BOARD_ITEM* aItem ) const;
};
#endif // KICAD_PLUGIN_H_

View File

@ -403,7 +403,7 @@ void LEGACY_PLUGIN::loadGENERAL()
else if( TESTLINE( "BoardThickness" ) )
{
BIU thickn = biuParse( line + SZ( "BoardThickness" ) );
m_board->GetDesignSettings().m_BoardThickness = thickn;
m_board->GetDesignSettings().SetBoardThickness( thickn );
}
/*
@ -2215,7 +2215,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
arcsegcount = 32;
zc->SetArcSegCount( arcsegcount );
zc->SetIsFilled( fillstate == 'S' ? true : false );
zc->SetIsFilled( fillstate == 'F' ? true : false );
zc->SetThermalReliefGap( thermalReliefGap );
zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge );
}
@ -2825,7 +2825,7 @@ void LEGACY_PLUGIN::saveGENERAL( const BOARD* aBoard ) const
fprintf( m_fp, "Ndraw %d\n", aBoard->m_Drawings.GetCount() );
fprintf( m_fp, "Ntrack %d\n", aBoard->GetNumSegmTrack() );
fprintf( m_fp, "Nzone %d\n", aBoard->GetNumSegmZone() );
fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().m_BoardThickness ).c_str() );
fprintf( m_fp, "BoardThickness %s\n", fmtBIU( aBoard->GetDesignSettings().GetBoardThickness() ).c_str() );
fprintf( m_fp, "Nmodule %d\n", aBoard->m_Modules.GetCount() );
fprintf( m_fp, "Nnets %d\n", aBoard->GetNetCount() );
fprintf( m_fp, "$EndGENERAL\n\n" );

2499
pcbnew/pcb_parser.cpp Normal file

File diff suppressed because it is too large Load Diff

214
pcbnew/pcb_parser.h Normal file
View File

@ -0,0 +1,214 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 CERN
*
* 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
*/
/**
* @file pcb_parser.h
* @brief Pcbnew s-expression file format parser definition.
*/
#ifndef _PCBNEW_PARSER_H_
#define _PCBNEW_PARSER_H_
#include <pcb_lexer.h>
#include <wx/hashmap.h>
using namespace PCB;
class BOARD;
class BOARD_ITEM;
class D_PAD;
class EDGE_MODULE;
class TEXTE_MODULE;
class TEXTE_PCB;
class MODULE;
class PCB_TARGET;
class S3D_MASTER;
class ZONE_CONTAINER;
WX_DECLARE_STRING_HASH_MAP( int, LAYER_HASH_MAP );
#define USE_LAYER_NAMES 1 // Set to 0 to format and parse layers by index number.
/**
* Class PCB_PARSER
* reads a Pcbnew s-expression fromatted #LINE_READER object and returns the appropriate
* #BOARD_ITEM object.
*/
class PCB_PARSER : public PCB_LEXER
{
BOARD* m_board;
LAYER_HASH_MAP m_layerMap; //< Map layer name to it's index saved in BOARD::m_Layer.
void parseHeader() throw( IO_ERROR, PARSE_ERROR );
void parseGeneralSection() throw( IO_ERROR, PARSE_ERROR );
void parsePAGE_INFO() throw( IO_ERROR, PARSE_ERROR );
void parseTITLE_BLOCK() throw( IO_ERROR, PARSE_ERROR );
void parseLayers() throw( IO_ERROR, PARSE_ERROR );
void parseSetup() throw( IO_ERROR, PARSE_ERROR );
void parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR );
void parseNETCLASS() throw( IO_ERROR, PARSE_ERROR );
void parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR );
void parseTEXTE_PCB( TEXTE_PCB* aText = NULL ) throw( IO_ERROR, PARSE_ERROR );
void parseDIMENSION() throw( IO_ERROR, PARSE_ERROR );
void parseMODULE() throw( IO_ERROR, PARSE_ERROR );
TEXTE_MODULE* parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR );
EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR );
D_PAD* parseD_PAD() throw( IO_ERROR, PARSE_ERROR );
TRACK* parseTRACK() throw( IO_ERROR, PARSE_ERROR );
SEGVIA* parseSEGVIA() throw( IO_ERROR, PARSE_ERROR );
ZONE_CONTAINER* parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR );
PCB_TARGET* parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR );
BOARD* parseBOARD() throw( IO_ERROR, PARSE_ERROR );
/**
* Function lookUpLayer
* parses the current token for the layer definition of a #BOARD_ITEM object.
*
* @throw IO_ERROR if the layer is not valid.
* @throw PARSE_ERROR if the layer syntax is incorrect.
* @return The index the parsed #BOARD_ITEM layer.
*/
int lookUpLayer() throw( PARSE_ERROR, IO_ERROR );
/**
* Function parseBoardItemLayer
* parses the layer definition of a #BOARD_ITEM object.
*
* @throw IO_ERROR if the layer is not valid.
* @throw PARSE_ERROR if the layer syntax is incorrect.
* @return The index the parsed #BOARD_ITEM layer.
*/
int parseBoardItemLayer() throw( IO_ERROR, PARSE_ERROR );
/**
* Function parseBoardItemLayersAsMask
* parses the layers definition of a #BOARD_ITEM object.
*
* @throw IO_ERROR if any of the layers is not valid.
* @throw PARSE_ERROR if the layers syntax is incorrect.
* @return The mask of layers the parsed #BOARD_ITEM is on.
*/
int parseBoardItemLayersAsMask() throw( PARSE_ERROR, IO_ERROR );
/**
* Function parseXY
* parses a coordinate pair (xy X Y) in board units (mm).
*
* The parser checks if the previous token was T_LEFT and parses the remainder of
* the token syntax. This is used when parsing a list of coorinate points. This
* way the parser can be used in either case.
*
* @throw PARSE_ERROR if the coordinate pair syntax is incorrect.
* @return A wxPoint object containing the coordinate pair.
*/
wxPoint parseXY() throw( PARSE_ERROR );
void parseXY( int* aX, int* aY ) throw( PARSE_ERROR );
/**
* Function parseEDA_TEXT
* parses the common settings for any object derived from #EDA_TEXT.
*
* @throw PARSE_ERROR if the text syntax is not valid.
* @param aText A point to the #EDA_TEXT object to save the parsed settings into.
*/
void parseEDA_TEXT( EDA_TEXT* aText ) throw( PARSE_ERROR );
S3D_MASTER* parse3DModel() throw( PARSE_ERROR );
/**
* Function parseDouble
* parses the current token as an ASCII numeric string with possible leading whitespace into
* a double precision floating point number.
*
* @throw IO_ERROR if an error occurs attempting to convert the current token.
* @return The result of the parsed token.
*/
double parseDouble() throw( IO_ERROR );
inline double parseDouble( const char* aExpected ) throw( IO_ERROR )
{
NeedNUMBER( aExpected );
return parseDouble();
}
inline double parseDouble( T aToken ) throw( IO_ERROR )
{
return parseDouble( GetTokenText( aToken ) );
}
inline int parseBoardUnits() throw( IO_ERROR )
{
// There should be no rounding issues here, since the values in the file are in mm
// and get converted to nano-meters. This product should be an integer, exactly.
return int( parseDouble() * 1e6 );
}
inline int parseBoardUnits( const char* aExpected ) throw( PARSE_ERROR )
{
return KIROUND( parseDouble( aExpected ) * 1e6 );
}
inline int parseBoardUnits( T aToken ) throw( PARSE_ERROR )
{
return parseBoardUnits( GetTokenText( aToken ) );
}
inline int parseInt() throw( PARSE_ERROR )
{
return (int)strtol( CurText(), NULL, 10 );
}
inline int parseInt( const char* aExpected ) throw( PARSE_ERROR )
{
NeedNUMBER( aExpected );
return parseInt();
}
inline int parseHex() throw( PARSE_ERROR )
{
NeedSYMBOLorNUMBER();
return (int)strtol( CurText(), NULL, 16 );
}
bool parseBool() throw( PARSE_ERROR );
public:
PCB_PARSER( LINE_READER* aReader, BOARD* aBoard = NULL ) :
PCB_LEXER( aReader ),
m_board( aBoard )
{
}
BOARD_ITEM* Parse() throw( IO_ERROR, PARSE_ERROR );
};
#endif // _PCBNEW_PARSER_H_