Commit 9bbff22d authored by Dick Hollenbeck's avatar Dick Hollenbeck

1) Switch to boost hashtable support from wx macros which did not handle std::string.

   This required the additional compiler command line option "-std=c++0x".

2) Switch to unique_ptr from auto_ptr which is C++ deprecated.

3) Change to new English layer names per mailing list discussion, see class_board.cpp.

4) When saving to *.kicad_pcb or *.kicad_mod, identify opportunities to use wildcard
   layer sets, for pads so far.

5) Switch to two std::string hashtables in pcb_parser.cpp, away from one wxString based one
   for layer names and layer sets mapping. One hashtable holds the mask, the other the index.
   Layer sets are only in the mask table.

6) Move "LOCALE_IO toggle" into PCB_IO::Format() since it is a public API function and
   caller should find it as convenient as possible to use.  LOCALE_IO should handle
   nesting OK in the case where public Format() is called from one of the Footprint*()
   functions.

7) Drop support for "export module to new library".  Creating new libraries will have to
   be handled in concert with library table entries, and we've talked recently about
   creating a better footprint library manager, one that resides in a DLL/DSO.  So
   this kind of functionality needs to be handled in there in the near future.

8) Change name of exported PCB_IO module/footprint to *.kicad_mod and not *.emp.
parent 89a40eeb
...@@ -4,13 +4,43 @@ KiCad ChangeLog 2012 ...@@ -4,13 +4,43 @@ KiCad ChangeLog 2012
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2012-Nov-14 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
1) Switch to boost hashtable support from wx macros which did not handle std::string.
This required the additional compiler command line option "-std=c++0x".
2) Switch to unique_ptr from auto_ptr which is C++ deprecated.
3) Change to new English layer names per mailing list discussion, see class_board.cpp.
4) When saving to *.kicad_pcb or *.kicad_mod, identify opportunities to use wildcard
layer sets, for pads so far.
5) Switch to two std::string hashtables in pcb_parser.cpp, away from one wxString based one
for layer names and layer sets mapping. One hashtable holds the mask, the other the index.
Layer sets are only in the mask table.
6) Move "LOCALE_IO toggle" into PCB_IO::Format() since it is a public API function and
caller should find it as convenient as possible to use. LOCALE_IO should handle
nesting OK in the case where public Format() is called from one of the Footprint*()
functions.
7) Drop support for "export module to new library". Creating new libraries will have to
be handled in concert with library table entries, and we've talked recently about
creating a better footprint library manager, one that resides in a DLL/DSO. So
this kind of functionality needs to be handled in there in the near future.
8) Change name of exported PCB_IO module/footprint to *.kicad_mod and not *.emp.
2012-May-5 UPDATE Jerry Jacobs <jerry@xor-gate.org> 2012-May-5 UPDATE Jerry Jacobs <jerry@xor-gate.org>
================================================================================ ================================================================================
++ common ++ common
* Update about dialog to more native size so the notebook is not squeezed * Update about dialog to more native size so the notebook is not squeezed
* Increment copyright year to 2012 * Increment copyright year to 2012
* Fix mousezoom jumping to center for Mac OS X and other platforms * Fix mousezoom jumping to center for Mac OS X and other platforms
* Remove lowercase application name because Mac OS X menubar was inconsitent * Remove lowercase application name because Mac OS X menubar was inconsitent
2012-Mar-11 UPDATE Dick Hollenbeck <dick@softplc.com> 2012-Mar-11 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
......
...@@ -136,6 +136,8 @@ if(CMAKE_COMPILER_IS_GNUCXX) ...@@ -136,6 +136,8 @@ if(CMAKE_COMPILER_IS_GNUCXX)
"Setting GCC version ${GCC_VERSION} build flags \"${KICAD_GCC_RELEASE_BUILD_FLAGS}\"") "Setting GCC version ${GCC_VERSION} build flags \"${KICAD_GCC_RELEASE_BUILD_FLAGS}\"")
endif(CMAKE_BUILD_TYPE STREQUAL Debug) endif(CMAKE_BUILD_TYPE STREQUAL Debug)
# needed when using #include <unordered_map>, or std::unique_ptr which replaces std::auto_ptr
set(CMAKE_CXX_FLAGS "-std=c++0x")
if(WIN32) # under Windows/mingw, -fPIC option is enabled by default if(WIN32) # under Windows/mingw, -fPIC option is enabled by default
# Set default flags for Release build. # Set default flags for Release build.
......
...@@ -70,7 +70,7 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintsLibNames ) ...@@ -70,7 +70,7 @@ bool FOOTPRINT_LIST::ReadFootprintFiles( wxArrayString& aFootprintsLibNames )
for( unsigned i=0; i<fpnames.GetCount(); ++i ) for( unsigned i=0; i<fpnames.GetCount(); ++i )
{ {
std::auto_ptr<MODULE> m( pi->FootprintLoad( libPath, fpnames[i] ) ); std::unique_ptr<MODULE> m( pi->FootprintLoad( libPath, fpnames[i] ) );
// we're loading what we enumerated, all must be there. // we're loading what we enumerated, all must be there.
wxASSERT( m.get() ); wxASSERT( m.get() );
......
...@@ -696,7 +696,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericDesignHeader() ...@@ -696,7 +696,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericDesignHeader()
XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries() XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries()
{ {
XNODE* xlibs = node( wxT( "libraries" ) ); // auto_ptr XNODE* xlibs = node( wxT( "libraries" ) ); // unique_ptr
for( std::set<void*>::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it ) for( std::set<void*>::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it )
{ {
...@@ -716,7 +716,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries() ...@@ -716,7 +716,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries()
XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts() XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts()
{ {
XNODE* xlibparts = node( wxT( "libparts" ) ); // auto_ptr XNODE* xlibparts = node( wxT( "libparts" ) ); // unique_ptr
wxString sLibpart = wxT( "libpart" ); wxString sLibpart = wxT( "libpart" );
wxString sLib = wxT( "lib" ); wxString sLib = wxT( "lib" );
wxString sPart = wxT( "part" ); wxString sPart = wxT( "part" );
...@@ -833,7 +833,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts() ...@@ -833,7 +833,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts()
XNODE* NETLIST_EXPORT_TOOL::makeGenericListOfNets() XNODE* NETLIST_EXPORT_TOOL::makeGenericListOfNets()
{ {
XNODE* xnets = node( wxT( "nets" ) ); // auto_ptr if exceptions ever get used. XNODE* xnets = node( wxT( "nets" ) ); // unique_ptr if exceptions ever get used.
wxString netCodeTxt; wxString netCodeTxt;
wxString netName; wxString netName;
wxString ref; wxString ref;
...@@ -1062,7 +1062,7 @@ bool NETLIST_EXPORT_TOOL::WriteKiCadNetList( const wxString& aOutFileName ) ...@@ -1062,7 +1062,7 @@ bool NETLIST_EXPORT_TOOL::WriteKiCadNetList( const wxString& aOutFileName )
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0; g_NetObjectslist[ii]->m_Flag = 0;
std::auto_ptr<XNODE> xroot( makeGenericRoot() ); std::unique_ptr<XNODE> xroot( makeGenericRoot() );
try try
{ {
......
...@@ -37,17 +37,17 @@ ...@@ -37,17 +37,17 @@
#include <unordered_map> #include <unordered_map>
/// Map a C string to a wxString, used in PLUGINs. /// Map a C string to a wxString, used in PLUGINs.
typedef unordered_map< const char*, wxString > PROPERTIES; typedef std::unordered_map< std::string, wxString > PROPERTIES;
/// Map a C string to an integer. Used in DSNLEXER. /// Map a C string to an integer. Used in DSNLEXER.
typedef unordered_map< const char*, int > KEYWORD_MAP; typedef std::unordered_map< std::string, int > KEYWORD_MAP;
/// Map a C string to an EDA_RECT. /// Map a C string to an EDA_RECT.
/// The key is the classname of the derived wxformbuilder dialog. /// The key is the classname of the derived wxformbuilder dialog.
typedef unordered_map< const char*, EDA_RECT > RECT_MAP; typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP;
#elif 0 // boost::unordered_map #elif 1 // boost::unordered_map
// fix a compile bug at line 97 of boost/detail/container_fwd.hpp // fix a compile bug at line 97 of boost/detail/container_fwd.hpp
#define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD #define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD
...@@ -57,17 +57,17 @@ typedef unordered_map< const char*, EDA_RECT > RECT_MAP; ...@@ -57,17 +57,17 @@ typedef unordered_map< const char*, EDA_RECT > RECT_MAP;
// see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html // see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html
/// Map a C string to a wxString, used in PLUGINs. /// Map a C string to a wxString, used in PLUGINs.
typedef boost::unordered_map< const char*, wxString > PROPERTIES; typedef boost::unordered_map< std::string, wxString > PROPERTIES;
/// Map a C string to an integer. Used in DSNLEXER. /// Map a C string to an integer. Used in DSNLEXER.
typedef boost::unordered_map< const char*, int > KEYWORD_MAP; typedef boost::unordered_map< std::string, int > KEYWORD_MAP;
/// Map a C string to an EDA_RECT. /// Map a C string to an EDA_RECT.
/// The key is the classname of the derived wxformbuilder dialog. /// The key is the classname of the derived wxformbuilder dialog.
typedef boost::unordered_map< const char*, EDA_RECT > RECT_MAP; typedef boost::unordered_map< std::string, EDA_RECT > RECT_MAP;
#elif 1 // wx is inconsistent accross platforms, will soon switch to boost #elif 0 // wx is inconsistent across platforms, will soon switch to boost
// http://docs.wxwidgets.org/trunk/classwx_hash_map.html // http://docs.wxwidgets.org/trunk/classwx_hash_map.html
#include <wx/hashmap.h> #include <wx/hashmap.h>
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <memory> // std::auto_ptr #include <memory> // std::unique_ptr
#include <wx/string.h> #include <wx/string.h>
......
...@@ -79,7 +79,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR ) ...@@ -79,7 +79,7 @@ void LIB_TABLE::Parse( SCH_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR )
in->NeedSYMBOLorNUMBER(); in->NeedSYMBOLorNUMBER();
std::auto_ptr<ROW> row( new ROW( this ) ); std::unique_ptr<ROW> row( new ROW( this ) );
row->SetLogicalName( in->CurText() ); row->SetLogicalName( in->CurText() );
...@@ -244,13 +244,13 @@ void LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR ) ...@@ -244,13 +244,13 @@ void LIB_TABLE::loadLib( ROW* aRow ) throw( IO_ERROR )
if( !libType.compare( "dir" ) ) if( !libType.compare( "dir" ) )
{ {
// autor_ptr wrap source while we create sink, in case sink throws. // autor_ptr wrap source while we create sink, in case sink throws.
std::auto_ptr<LIB_SOURCE> source( std::unique_ptr<LIB_SOURCE> source(
new DIR_LIB_SOURCE( new DIR_LIB_SOURCE(
aRow->GetFullURI(), aRow->GetFullURI(),
aRow->GetOptions() ) ); aRow->GetOptions() ) );
/* @todo load LIB_SINK /* @todo load LIB_SINK
std::auto_ptr<LIB_SINK> sink( std::unique_ptr<LIB_SINK> sink(
new DIR_LIB_SINK( new DIR_LIB_SINK(
aRow->GetFullURI(), aRow->GetFullURI(),
aRow->GetOptions() ) ); aRow->GetOptions() ) );
...@@ -311,7 +311,7 @@ LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const ...@@ -311,7 +311,7 @@ LIB_TABLE::ROW* LIB_TABLE::FindRow( const STRING& aLogicalName ) const
} }
bool LIB_TABLE::InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace ) bool LIB_TABLE::InsertRow( std::unique_ptr<ROW>& aRow, bool doReplace )
{ {
// this does not need to be super fast. // this does not need to be super fast.
......
...@@ -337,7 +337,7 @@ protected: // only a table editor can use these ...@@ -337,7 +337,7 @@ protected: // only a table editor can use these
* exists. If false, then fail if the key already exists. * exists. If false, then fail if the key already exists.
* @return bool - true if the operation succeeded. * @return bool - true if the operation succeeded.
*/ */
bool InsertRow( std::auto_ptr<ROW>& aRow, bool doReplace = false ); bool InsertRow( std::unique_ptr<ROW>& aRow, bool doReplace = false );
/** /**
* Function FindRow * Function FindRow
......
...@@ -86,7 +86,7 @@ bool PCB_CALCULATOR_FRAME::WriteDataFile() ...@@ -86,7 +86,7 @@ bool PCB_CALCULATOR_FRAME::WriteDataFile()
// Switch the locale to standard C (needed to read/write floating point numbers // Switch the locale to standard C (needed to read/write floating point numbers
LOCALE_IO toggle; LOCALE_IO toggle;
std::auto_ptr<PCB_CALCULATOR_DATAFILE> datafile( new PCB_CALCULATOR_DATAFILE( &m_RegulatorList ) ); std::unique_ptr<PCB_CALCULATOR_DATAFILE> datafile( new PCB_CALCULATOR_DATAFILE( &m_RegulatorList ) );
try try
{ {
......
...@@ -379,35 +379,35 @@ wxString BOARD::GetLayerName( int aLayerIndex, bool aTranslate ) const ...@@ -379,35 +379,35 @@ wxString BOARD::GetLayerName( int aLayerIndex, bool aTranslate ) const
// because we want the English name and the translation. // because we want the English name and the translation.
// The English name is stored here, and to get the translation // The English name is stored here, and to get the translation
// wxGetTranslation must be called explicitly. // wxGetTranslation must be called explicitly.
static const wxChar* layer_FRONT_name = _( "Front" ); static const wxChar* layer_FRONT_name = _( "F.Cu" );
static const wxChar* layer_INNER1_name = _( "Inner1" ); static const wxChar* layer_INNER1_name = _( "Inner1.Cu" );
static const wxChar* layer_INNER2_name = _( "Inner2" ); static const wxChar* layer_INNER2_name = _( "Inner2.Cu" );
static const wxChar* layer_INNER3_name = _( "Inner3" ); static const wxChar* layer_INNER3_name = _( "Inner3.Cu" );
static const wxChar* layer_INNER4_name = _( "Inner4" ); static const wxChar* layer_INNER4_name = _( "Inner4.Cu" );
static const wxChar* layer_INNER5_name = _( "Inner5" ); static const wxChar* layer_INNER5_name = _( "Inner5.Cu" );
static const wxChar* layer_INNER6_name = _( "Inner6" ); static const wxChar* layer_INNER6_name = _( "Inner6.Cu" );
static const wxChar* layer_INNER7_name = _( "Inner7" ); static const wxChar* layer_INNER7_name = _( "Inner7.Cu" );
static const wxChar* layer_INNER8_name = _( "Inner8" ); static const wxChar* layer_INNER8_name = _( "Inner8.Cu" );
static const wxChar* layer_INNER9_name = _( "Inner9" ); static const wxChar* layer_INNER9_name = _( "Inner9.Cu" );
static const wxChar* layer_INNER10_name = _( "Inner10" ); static const wxChar* layer_INNER10_name = _( "Inner10.Cu" );
static const wxChar* layer_INNER11_name = _( "Inner11" ); static const wxChar* layer_INNER11_name = _( "Inner11.Cu" );
static const wxChar* layer_INNER12_name = _( "Inner12" ); static const wxChar* layer_INNER12_name = _( "Inner12.Cu" );
static const wxChar* layer_INNER13_name = _( "Inner13" ); static const wxChar* layer_INNER13_name = _( "Inner13.Cu" );
static const wxChar* layer_INNER14_name = _( "Inner14" ); static const wxChar* layer_INNER14_name = _( "Inner14.Cu" );
static const wxChar* layer_BACK_name = _( "Back" ); static const wxChar* layer_BACK_name = _( "B.Cu" );
static const wxChar* layer_ADHESIVE_BACK_name = _( "Adhes_Back" ); static const wxChar* layer_ADHESIVE_BACK_name = _( "B.Adhes" );
static const wxChar* layer_ADHESIVE_FRONT_name = _( "Adhes_Front" ); static const wxChar* layer_ADHESIVE_FRONT_name = _( "F.Adhes" );
static const wxChar* layer_SOLDERPASTE_BACK_name = _( "SoldP_Back" ); static const wxChar* layer_SOLDERPASTE_BACK_name = _( "B.Paste" );
static const wxChar* layer_SOLDERPASTE_FRONT_name = _( "SoldP_Front" ); static const wxChar* layer_SOLDERPASTE_FRONT_name = _( "F.Paste" );
static const wxChar* layer_SILKSCREEN_BACK_name = _( "SilkS_Back" ); static const wxChar* layer_SILKSCREEN_BACK_name = _( "B.SilkS" );
static const wxChar* layer_SILKSCREEN_FRONT_name = _( "SilkS_Front" ); static const wxChar* layer_SILKSCREEN_FRONT_name = _( "F.SilkS" );
static const wxChar* layer_SOLDERMASK_BACK_name = _( "Mask_Back" ); static const wxChar* layer_SOLDERMASK_BACK_name = _( "B.Mask" );
static const wxChar* layer_SOLDERMASK_FRONT_name = _( "Mask_Front" ); static const wxChar* layer_SOLDERMASK_FRONT_name = _( "F.Mask" );
static const wxChar* layer_DRAW_name = _( "Drawings" ); static const wxChar* layer_DRAW_name = _( "Dwgs.User" );
static const wxChar* layer_COMMENT_name = _( "Comments" ); static const wxChar* layer_COMMENT_name = _( "Cmts.User" );
static const wxChar* layer_ECO1_name = _( "Eco1" ); static const wxChar* layer_ECO1_name = _( "Eco1.User" );
static const wxChar* layer_ECO2_name = _( "Eco2" ); static const wxChar* layer_ECO2_name = _( "Eco2.User" );
static const wxChar* layer_EDGE_name = _( "PCB_Edges" ); static const wxChar* layer_EDGE_name = _( "Edge.Cuts" );
wxString BOARD::GetDefaultLayerName( int aLayerNumber, bool aTranslate ) wxString BOARD::GetDefaultLayerName( int aLayerNumber, bool aTranslate )
{ {
......
...@@ -1107,7 +1107,7 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE ...@@ -1107,7 +1107,7 @@ BOARD* EAGLE_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE
m_board->SetFileName( aFileName ); m_board->SetFileName( aFileName );
// delete on exception, iff I own m_board, according to aAppendToMe // delete on exception, iff I own m_board, according to aAppendToMe
auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board ); unique_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
try try
{ {
...@@ -1795,7 +1795,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e, ...@@ -1795,7 +1795,7 @@ void EAGLE_PLUGIN::orientModuleText( MODULE* m, const EELEMENT& e,
MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ) const MODULE* EAGLE_PLUGIN::makeModule( CPTREE& aPackage, const std::string& aPkgName ) const
{ {
std::auto_ptr<MODULE> m( new MODULE( NULL ) ); std::unique_ptr<MODULE> m( new MODULE( NULL ) );
m->SetLibRef( FROM_UTF8( aPkgName.c_str() ) ); m->SetLibRef( FROM_UTF8( aPkgName.c_str() ) );
......
...@@ -74,10 +74,10 @@ static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) ); ...@@ -74,10 +74,10 @@ static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
*/ */
class FP_CACHE_ITEM class FP_CACHE_ITEM
{ {
wxFileName m_file_name; /// The the full file name and path of the footprint to cache. wxFileName m_file_name; ///< The the full file name and path of the footprint to cache.
bool m_writable; /// Writability status of the footprint file. bool m_writable; ///< Writability status of the footprint file.
wxDateTime m_mod_time; /// The last file modified time stamp. wxDateTime m_mod_time; ///< The last file modified time stamp.
auto_ptr< MODULE > m_module; unique_ptr< MODULE > m_module;
public: public:
FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ); FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName );
...@@ -90,11 +90,10 @@ public: ...@@ -90,11 +90,10 @@ public:
}; };
FP_CACHE_ITEM::FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ) FP_CACHE_ITEM::FP_CACHE_ITEM( MODULE* aModule, const wxFileName& aFileName ) :
m_module( aModule )
{ {
m_file_name = aFileName; m_file_name = aFileName;
auto_ptr< MODULE > tmp( aModule );
m_module = tmp;
m_mod_time.Now(); m_mod_time.Now();
} }
...@@ -301,7 +300,7 @@ bool FP_CACHE::IsModified() ...@@ -301,7 +300,7 @@ bool FP_CACHE::IsModified()
void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties ) void PCB_IO::Save( const wxString& aFileName, BOARD* aBoard, PROPERTIES* aProperties )
{ {
LOCALE_IO toggle; // toggles on, then off, the C locale. LOCALE_IO toggle; // toggles on, then off, the C locale.
m_board = aBoard; m_board = aBoard;
...@@ -333,6 +332,8 @@ BOARD_ITEM* PCB_IO::Parse( const wxString& aClipboardSourceInput ) throw( IO_ERR ...@@ -333,6 +332,8 @@ BOARD_ITEM* PCB_IO::Parse( const wxString& aClipboardSourceInput ) throw( IO_ERR
void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
throw( IO_ERROR ) throw( IO_ERROR )
{ {
LOCALE_IO toggle; // public API function, perform anything convenient for caller
switch( aItem->Type() ) switch( aItem->Type() )
{ {
case PCB_T: case PCB_T:
...@@ -822,11 +823,14 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const ...@@ -822,11 +823,14 @@ void PCB_IO::format( EDGE_MODULE* aModuleDrawing, int aNestLevel ) const
if( aModuleDrawing->GetWidth() != 0 ) if( aModuleDrawing->GetWidth() != 0 )
m_out->Print( 0, " (width %s)", FMT_IU( aModuleDrawing->GetWidth() ).c_str() ); m_out->Print( 0, " (width %s)", FMT_IU( aModuleDrawing->GetWidth() ).c_str() );
/* 11-Nov-2021 remove if no one whines after a couple of months. Simple graphic items
perhaps do not need these.
if( aModuleDrawing->GetTimeStamp() ) if( aModuleDrawing->GetTimeStamp() )
m_out->Print( 0, " (tstamp %lX)", aModuleDrawing->GetTimeStamp() ); m_out->Print( 0, " (tstamp %lX)", aModuleDrawing->GetTimeStamp() );
if( aModuleDrawing->GetStatus() ) if( aModuleDrawing->GetStatus() )
m_out->Print( 0, " (status %X)", aModuleDrawing->GetStatus() ); m_out->Print( 0, " (status %X)", aModuleDrawing->GetStatus() );
*/
m_out->Print( 0, ")\n" ); m_out->Print( 0, ")\n" );
} }
...@@ -865,8 +869,13 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const ...@@ -865,8 +869,13 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
formatLayer( aModule ); formatLayer( aModule );
m_out->Print( 0, " (tedit %lX) (tstamp %lX)\n", if( !( m_ctl & CTL_OMIT_TSTAMPS ) )
{
m_out->Print( 0, " (tedit %lX) (tstamp %lX)\n",
aModule->GetLastEditTime(), aModule->GetTimeStamp() ); aModule->GetLastEditTime(), aModule->GetTimeStamp() );
}
else
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+1, "(at %s", FMT_IU( aModule->m_Pos ).c_str() ); m_out->Print( aNestLevel+1, "(at %s", FMT_IU( aModule->m_Pos ).c_str() );
...@@ -976,6 +985,80 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const ...@@ -976,6 +985,80 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
} }
void PCB_IO::formatLayers( int aLayerMask, int aNestLevel ) const
throw( IO_ERROR )
{
m_out->Print( aNestLevel, "(layers" );
int cuMask = ALL_CU_LAYERS;
if( m_board )
cuMask &= m_board->GetEnabledLayers();
// output copper layers first, then non copper
if( ( aLayerMask & cuMask ) == cuMask )
{
m_out->Print( 0, " *.Cu" );
aLayerMask &= ~ALL_CU_LAYERS; // clear bits, so they are not output again below
}
else if( ( aLayerMask & cuMask ) == (LAYER_BACK | LAYER_FRONT) )
{
m_out->Print( 0, " F&B.Cu" );
aLayerMask &= ~(LAYER_BACK | LAYER_FRONT);
}
if( ( aLayerMask & (ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT)) == (ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT) )
{
m_out->Print( 0, " *.Adhes" );
aLayerMask &= ~(ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT);
}
if( ( aLayerMask & (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT)) == (SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT) )
{
m_out->Print( 0, " *.Paste" );
aLayerMask &= ~(SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT);
}
if( ( aLayerMask & (SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT)) == (SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT) )
{
m_out->Print( 0, " *.SilkS" );
aLayerMask &= ~(SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT);
}
if( ( aLayerMask & (SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT)) == (SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT) )
{
m_out->Print( 0, " *.Mask" );
aLayerMask &= ~(SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT);
}
// output any individual layers not handled in wildcard combos above
unsigned layerMask = aLayerMask;
if( m_board )
layerMask &= m_board->GetEnabledLayers();
wxString layerName;
for( int layer = 0; layerMask; ++layer, layerMask >>= 1 )
{
if( layerMask & 1 )
{
if( m_board && !(m_ctl & CTL_UNTRANSLATED_LAYERS) )
layerName = m_board->GetLayerName( layer );
else // I am being called from FootprintSave()
layerName = BOARD::GetDefaultLayerName( layer, false );
m_out->Print( 0, " %s", m_out->Quotew( layerName ).c_str() );
}
}
m_out->Print( 0, ")\n" );
}
void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
throw( IO_ERROR ) throw( IO_ERROR )
{ {
...@@ -1043,30 +1126,7 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const ...@@ -1043,30 +1126,7 @@ void PCB_IO::format( D_PAD* aPad, int aNestLevel ) const
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+1, "(layers" ); formatLayers( aPad->GetLayerMask(), aNestLevel+1 );
unsigned layerMask = aPad->GetLayerMask();
if( m_board )
layerMask &= m_board->GetEnabledLayers();
wxString layerName;
for( int layer = 0; layerMask; ++layer, layerMask >>= 1 )
{
if( layerMask & 1 )
{
if( m_board && !(m_ctl & CTL_UNTRANSLATED_LAYERS) )
layerName = m_board->GetLayerName( layer );
else // from FootprintSave()
layerName = BOARD::GetDefaultLayerName( layer, false );
m_out->Print( 0, " %s", m_out->Quotew( layerName ).c_str() );
}
}
m_out->Print( 0, ")\n" );
// Unconnected pad is default net so don't save it. // Unconnected pad is default net so don't save it.
if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 ) if( !(m_ctl & CTL_OMIT_NETS) && aPad->GetNet() != 0 )
...@@ -1536,7 +1596,7 @@ void PCB_IO::cacheLib( const wxString& aLibraryPath ) ...@@ -1536,7 +1596,7 @@ void PCB_IO::cacheLib( const wxString& aLibraryPath )
wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties ) wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath, PROPERTIES* aProperties )
{ {
LOCALE_IO toggle; // toggles on, then off, the C locale. LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties ); init( aProperties );
...@@ -1558,7 +1618,7 @@ wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath, PROPERTI ...@@ -1558,7 +1618,7 @@ wxArrayString PCB_IO::FootprintEnumerate( const wxString& aLibraryPath, PROPERTI
MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
PROPERTIES* aProperties ) PROPERTIES* aProperties )
{ {
LOCALE_IO toggle; // toggles on, then off, the C locale. LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties ); init( aProperties );
...@@ -1581,10 +1641,14 @@ MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFo ...@@ -1581,10 +1641,14 @@ MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFo
void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
PROPERTIES* aProperties ) PROPERTIES* aProperties )
{ {
LOCALE_IO toggle; // toggles on, then off, the C locale. LOCALE_IO toggle; // toggles on, then off, the C locale.
init( aProperties ); init( aProperties );
// In this public PLUGIN API function, we can safely assume it was
// called for saving into a library path.
m_ctl = CTL_FOR_LIBRARY;
cacheLib( aLibraryPath ); cacheLib( aLibraryPath );
if( !m_cache->IsWritable() ) if( !m_cache->IsWritable() )
...@@ -1667,7 +1731,7 @@ void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProp ...@@ -1667,7 +1731,7 @@ void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, PROPERTIES* aProp
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }
LOCALE_IO toggle; LOCALE_IO toggle;
init( aProperties ); init( aProperties );
......
...@@ -36,14 +36,20 @@ class PCB_PARSER; ...@@ -36,14 +36,20 @@ class PCB_PARSER;
/// Current s-expression file format version. 2 was the last legacy format version. /// Current s-expression file format version. 2 was the last legacy format version.
#define SEXPR_BOARD_FILE_VERSION 3 #define SEXPR_BOARD_FILE_VERSION 3
/// Format output for the clipboard instead of a file. /// Use English default layer names
#define CTL_UNTRANSLATED_LAYERS (1 << 0) #define CTL_UNTRANSLATED_LAYERS (1 << 0)
#define CTL_OMIT_NETS (1 << 1) #define CTL_OMIT_NETS (1 << 1)
/// Format output for the clipboard instead of a file #define CTL_OMIT_TSTAMPS (1 << 2)
#define CTL_CLIPBOARD (CTL_UNTRANSLATED_LAYERS | CTL_OMIT_NETS)
// common combinations of the above:
/// Format output for the clipboard instead of footprint library or BOARD
#define CTL_FOR_CLIPBOARD (CTL_UNTRANSLATED_LAYERS|CTL_OMIT_NETS)
/// Format output for a footprint library instead of clipboard or BOARD
#define CTL_FOR_LIBRARY (CTL_UNTRANSLATED_LAYERS|CTL_OMIT_NETS|CTL_OMIT_TSTAMPS)
/** /**
* Class PCB_IO * Class PCB_IO
...@@ -179,6 +185,9 @@ private: ...@@ -179,6 +185,9 @@ private:
void formatLayer( const BOARD_ITEM* aItem ) const; void formatLayer( const BOARD_ITEM* aItem ) const;
void formatLayers( int aLayerMask, int aNestLevel = 0 ) const
throw( IO_ERROR );
/// we only cache one footprint library for now, this determines which one. /// we only cache one footprint library for now, this determines which one.
void cacheLib( const wxString& aLibraryPath ); void cacheLib( const wxString& aLibraryPath );
......
...@@ -148,7 +148,7 @@ static inline unsigned ReadLine( LINE_READER* rdr, const char* caller ) ...@@ -148,7 +148,7 @@ static inline unsigned ReadLine( LINE_READER* rdr, const char* caller )
#endif #endif
using namespace std; // auto_ptr using namespace std; // unique_ptr
static inline const char* ShowVertJustify( EDA_TEXT_VJUSTIFY_T vertical ) static inline const char* ShowVertJustify( EDA_TEXT_VJUSTIFY_T vertical )
...@@ -237,7 +237,7 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE ...@@ -237,7 +237,7 @@ BOARD* LEGACY_PLUGIN::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPE
m_board->SetFileName( aFileName ); m_board->SetFileName( aFileName );
// delete on exception, iff I own m_board, according to aAppendToMe // delete on exception, iff I own m_board, according to aAppendToMe
auto_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board ); unique_ptr<BOARD> deleter( aAppendToMe ? NULL : m_board );
FILE* fp = wxFopen( aFileName, wxT( "r" ) ); FILE* fp = wxFopen( aFileName, wxT( "r" ) );
if( !fp ) if( !fp )
...@@ -929,7 +929,7 @@ void LEGACY_PLUGIN::loadSETUP() ...@@ -929,7 +929,7 @@ void LEGACY_PLUGIN::loadSETUP()
MODULE* LEGACY_PLUGIN::LoadMODULE() MODULE* LEGACY_PLUGIN::LoadMODULE()
{ {
auto_ptr<MODULE> module( new MODULE( m_board ) ); unique_ptr<MODULE> module( new MODULE( m_board ) );
while( READLINE( m_reader ) ) while( READLINE( m_reader ) )
{ {
...@@ -1139,7 +1139,7 @@ MODULE* LEGACY_PLUGIN::LoadMODULE() ...@@ -1139,7 +1139,7 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
void LEGACY_PLUGIN::loadPAD( MODULE* aModule ) void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
{ {
auto_ptr<D_PAD> pad( new D_PAD( aModule ) ); unique_ptr<D_PAD> pad( new D_PAD( aModule ) );
while( READLINE( m_reader ) ) while( READLINE( m_reader ) )
{ {
...@@ -1382,7 +1382,7 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule ) ...@@ -1382,7 +1382,7 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
auto_ptr<EDGE_MODULE> dwg( new EDGE_MODULE( aModule, shape ) ); // a drawing unique_ptr<EDGE_MODULE> dwg( new EDGE_MODULE( aModule, shape ) ); // a drawing
const char* data; const char* data;
...@@ -1678,7 +1678,7 @@ void LEGACY_PLUGIN::loadPCB_LINE() ...@@ -1678,7 +1678,7 @@ void LEGACY_PLUGIN::loadPCB_LINE()
$EndDRAWSEGMENT $EndDRAWSEGMENT
*/ */
auto_ptr<DRAWSEGMENT> dseg( new DRAWSEGMENT( m_board ) ); unique_ptr<DRAWSEGMENT> dseg( new DRAWSEGMENT( m_board ) );
while( READLINE( m_reader ) ) while( READLINE( m_reader ) )
{ {
...@@ -2069,9 +2069,9 @@ void LEGACY_PLUGIN::loadNETCLASS() ...@@ -2069,9 +2069,9 @@ void LEGACY_PLUGIN::loadNETCLASS()
// create an empty NETCLASS without a name, but do not add it to the BOARD // create an empty NETCLASS without a name, but do not add it to the BOARD
// yet since that would bypass duplicate netclass name checking within the BOARD. // yet since that would bypass duplicate netclass name checking within the BOARD.
// store it temporarily in an auto_ptr until successfully inserted into the BOARD // store it temporarily in an unique_ptr until successfully inserted into the BOARD
// just before returning. // just before returning.
auto_ptr<NETCLASS> nc( new NETCLASS( m_board, wxEmptyString ) ); unique_ptr<NETCLASS> nc( new NETCLASS( m_board, wxEmptyString ) );
while( READLINE( m_reader ) ) while( READLINE( m_reader ) )
{ {
...@@ -2144,7 +2144,7 @@ void LEGACY_PLUGIN::loadNETCLASS() ...@@ -2144,7 +2144,7 @@ void LEGACY_PLUGIN::loadNETCLASS()
// Must have been a name conflict, this is a bad board file. // Must have been a name conflict, this is a bad board file.
// User may have done a hand edit to the file. // User may have done a hand edit to the file.
// auto_ptr will delete nc on this code path // unique_ptr will delete nc on this code path
m_error.Printf( _( "duplicate NETCLASS name '%s'" ), nc->GetName().GetData() ); m_error.Printf( _( "duplicate NETCLASS name '%s'" ), nc->GetName().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
...@@ -2160,7 +2160,7 @@ void LEGACY_PLUGIN::loadNETCLASS() ...@@ -2160,7 +2160,7 @@ void LEGACY_PLUGIN::loadNETCLASS()
void LEGACY_PLUGIN::loadZONE_CONTAINER() void LEGACY_PLUGIN::loadZONE_CONTAINER()
{ {
auto_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) ); unique_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::NO_HATCH; CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::NO_HATCH;
bool sawCorner = false; bool sawCorner = false;
...@@ -2422,7 +2422,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() ...@@ -2422,7 +2422,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
void LEGACY_PLUGIN::loadDIMENSION() void LEGACY_PLUGIN::loadDIMENSION()
{ {
auto_ptr<DIMENSION> dim( new DIMENSION( m_board ) ); unique_ptr<DIMENSION> dim( new DIMENSION( m_board ) );
while( READLINE( m_reader ) ) while( READLINE( m_reader ) )
{ {
......
...@@ -153,7 +153,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -153,7 +153,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
// the s-expression format from clipboard could be done. // the s-expression format from clipboard could be done.
wxString fcontents; wxString fcontents;
PCB_IO pcb_io( CTL_CLIPBOARD ); PCB_IO pcb_io;
wxFFile f( dlg.GetPath() ); wxFFile f( dlg.GetPath() );
if( !f.IsOpened() ) if( !f.IsOpened() )
...@@ -167,7 +167,6 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -167,7 +167,6 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
f.ReadAll( &fcontents ); f.ReadAll( &fcontents );
// @todo Fix this. The layernames are missing, and this fails.
module = dynamic_cast<MODULE*>( pcb_io.Parse( fcontents ) ); module = dynamic_cast<MODULE*>( pcb_io.Parse( fcontents ) );
if( !module ) if( !module )
...@@ -209,16 +208,15 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib ) ...@@ -209,16 +208,15 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
return; return;
fn.SetName( aModule->m_LibRef ); fn.SetName( aModule->m_LibRef );
fn.SetExt( aCreateSysLib ? FootprintLibFileExtension : ModExportFileExtension );
if( aCreateSysLib ) // There is no longer any point to exporting as a new library. Work is planned
path = wxGetApp().ReturnLastVisitedLibraryPath(); // for the library manager to make it easier to use.
else if( config ) title = _( "Export Module" );
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path ); wildcard = FootprintLibFileWildcard;
title = aCreateSysLib ? _( "Create New Library" ) : _( "Export Module" ); fn.SetExt( FootprintFileExtension );
wildcard = aCreateSysLib ? LegacyFootprintLibFileWildcard : ModExportFileWildcard;
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &path );
fn.SetPath( path ); fn.SetPath( path );
wxFileDialog dlg( this, msg, fn.GetPath(), fn.GetFullName(), wxFileDialog dlg( this, msg, fn.GetPath(), fn.GetFullName(),
...@@ -229,27 +227,18 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib ) ...@@ -229,27 +227,18 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
return; return;
fn = dlg.GetPath(); fn = dlg.GetPath();
wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() );
if( !aCreateSysLib && config ) // Save file path if( config ) // Save file path
{ {
config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() ); config->Write( EXPORT_IMPORT_LASTPATH_KEY, fn.GetPath() );
} }
wxString libPath = fn.GetFullPath();
try try
{ {
#if 1 // This *.kicad_mod export works fine. It is the import which is still broken.
// The function PCB_PARSER::Parse() fails with due to the m_layerName[] table
// being empty.
// @todo, enable this code asap.
// Export as *.kicad_pcb format, using a strategy which is specifically chosen // Export as *.kicad_pcb format, using a strategy which is specifically chosen
// as an example on how it could also be used to send it to the system clipboard. // as an example on how it could also be used to send it to the system clipboard.
PCB_IO pcb_io( CTL_CLIPBOARD ); PCB_IO pcb_io( CTL_FOR_LIBRARY );
/* This module should *already* be "normalized" in a way such that /* This module should *already* be "normalized" in a way such that
orientation is zero, etc., since it came from module editor. orientation is zero, etc., since it came from module editor.
...@@ -259,32 +248,11 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib ) ...@@ -259,32 +248,11 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
module->SetOrientation( 0 ); module->SetOrientation( 0 );
*/ */
LOCALE_IO toggle;
pcb_io.Format( aModule ); pcb_io.Format( aModule );
FILE* fp = wxFopen( dlg.GetPath(), wxT( "wt" ) ); FILE* fp = wxFopen( dlg.GetPath(), wxT( "wt" ) );
fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() ); fprintf( fp, "%s", pcb_io.GetStringOutput( false ).c_str() );
fclose( fp ); fclose( fp );
#else
// Use IO_MGR::LEGACY for now, until the IO_MGR::KICAD plugin is ready.
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::LEGACY ) );
try
{
// try to delete the library whether it exists or not, quietly.
pi->FootprintLibDelete( libPath );
}
catch( IO_ERROR ioe )
{
// Ignore this, it will often happen and is not an error because
// the library may not exist. If library was in a read only directory,
// it will still exist as we get to the FootprintLibCreate() below.
}
pi->FootprintLibCreate( libPath );
pi->FootprintSave( libPath, aModule );
#endif
} }
catch( IO_ERROR ioe ) catch( IO_ERROR ioe )
{ {
...@@ -292,7 +260,7 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib ) ...@@ -292,7 +260,7 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule, bool aCreateSysLib )
return; return;
} }
msg.Printf( _( "Module exported in file <%s>" ), libPath.GetData() ); msg.Printf( _( "Module exported to file <%s>" ), GetChars( dlg.GetPath() ) );
DisplayInfoMessage( this, msg ); DisplayInfoMessage( this, msg );
} }
......
...@@ -49,21 +49,32 @@ ...@@ -49,21 +49,32 @@
#include <zones.h> #include <zones.h>
#include <pcb_parser.h> #include <pcb_parser.h>
using namespace std; using namespace std;
void PCB_PARSER::init() void PCB_PARSER::init()
{ {
m_layerMap.clear(); m_layerIndices.clear();
m_layerMasks.clear();
// Add untranslated default (i.e. english) layernames. // Add untranslated default (i.e. english) layernames.
// Some may be overridden later if parsing a board rather than a footprint. // Some may be overridden later if parsing a board rather than a footprint.
// The english name will survive if parsing only a footprint. // The english name will survive if parsing only a footprint.
for( int layerNdx = 0; layerNdx < NB_LAYERS; ++layerNdx ) for( int layerNdx = 0; layerNdx < NB_LAYERS; ++layerNdx )
{ {
wxString untranslated = BOARD::GetDefaultLayerName( layerNdx, false ); std::string untranslated = TO_UTF8( BOARD::GetDefaultLayerName( layerNdx, false ) );
m_layerMap[ untranslated ] = layerNdx;
m_layerIndices[ untranslated ] = layerNdx;
m_layerMasks[ untranslated ] = 1 << layerNdx;
} }
m_layerMasks[ "*.Cu" ] = ALL_CU_LAYERS;
m_layerMasks[ "F&B.Cu" ] = LAYER_BACK | LAYER_FRONT;
m_layerMasks[ "*.Adhes" ] = ADHESIVE_LAYER_BACK | ADHESIVE_LAYER_FRONT;
m_layerMasks[ "*.Paste" ] = SOLDERPASTE_LAYER_BACK | SOLDERPASTE_LAYER_FRONT;
m_layerMasks[ "*.Mask" ] = SOLDERMASK_LAYER_BACK | SILKSCREEN_LAYER_FRONT;
m_layerMasks[ "*.SilkS" ] = SILKSCREEN_LAYER_BACK | SILKSCREEN_LAYER_FRONT;
} }
...@@ -251,7 +262,7 @@ S3D_MASTER* PCB_PARSER::parse3DModel() throw( PARSE_ERROR ) ...@@ -251,7 +262,7 @@ S3D_MASTER* PCB_PARSER::parse3DModel() throw( PARSE_ERROR )
T token; T token;
auto_ptr< S3D_MASTER > n3D( new S3D_MASTER( NULL ) ); unique_ptr< S3D_MASTER > n3D( new S3D_MASTER( NULL ) );
NeedSYMBOL(); NeedSYMBOL();
n3D->m_Shape3DName = FromUTF8(); n3D->m_Shape3DName = FromUTF8();
...@@ -652,7 +663,7 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) ...@@ -652,7 +663,7 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as layers." ) );
T token; T token;
wxString name; std::string name;
std::string type; std::string type;
int layerIndex; int layerIndex;
bool isVisible = true; bool isVisible = true;
...@@ -668,7 +679,7 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) ...@@ -668,7 +679,7 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
layerIndex = parseInt( "layer index" ); layerIndex = parseInt( "layer index" );
NeedSYMBOL(); NeedSYMBOL();
name = FromUTF8(); name = CurText();
NeedSYMBOL(); NeedSYMBOL();
type = CurText(); type = CurText();
...@@ -694,16 +705,17 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) ...@@ -694,16 +705,17 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
if( isVisible ) if( isVisible )
visibleLayers |= 1 << layerIndex; visibleLayers |= 1 << layerIndex;
m_layerIndices[ name ] = layerIndex;
m_layerMasks[ name ] = 1 << layerIndex;
wxString wname = FROM_UTF8( name.c_str() );
enum LAYER_T layerType = LAYER::ParseType( type.c_str() ); enum LAYER_T layerType = LAYER::ParseType( type.c_str() );
LAYER layer( name, layerType, isVisible ); LAYER layer( wname, layerType, isVisible );
layer.SetFixedListIndex( layerIndex ); layer.SetFixedListIndex( layerIndex );
m_board->SetLayer( layerIndex, layer ); m_board->SetLayer( layerIndex, layer );
m_layerMap[ name ] = layerIndex; wxLogDebug( wxT( "Mapping layer %s to index %d" ), GetChars( wname ), layerIndex );
wxLogDebug( wxT( "Mapping layer %s to index %d" ),
GetChars( name ), layerIndex );
if( layerType != LT_UNDEFINED ) if( layerType != LT_UNDEFINED )
copperLayerCount++; copperLayerCount++;
...@@ -724,16 +736,26 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR ) ...@@ -724,16 +736,26 @@ void PCB_PARSER::parseLayers() throw( IO_ERROR, PARSE_ERROR )
} }
int PCB_PARSER::lookUpLayer() throw( PARSE_ERROR, IO_ERROR ) int PCB_PARSER::lookUpLayer( const LAYER_MAP& aMap ) throw( PARSE_ERROR, IO_ERROR )
{ {
wxString name = FromUTF8(); // avoid constructing another std::string, use lexer's directly
const LAYER_HASH_MAP::iterator it = m_layerMap.find( name ); LAYER_MAP::const_iterator it = aMap.find( curText );
if( it == m_layerMap.end() ) if( it == aMap.end() )
{ {
#if 1 && defined(DEBUG)
// dump the whole darn table, there's something wrong with it.
for( it = aMap.begin(); it != aMap.end(); ++it )
{
printf( &aMap == &m_layerIndices ? "lm[%s] = %d\n" : "lm[%s] = %08X\n",
it->first.c_str(), it->second );
}
#endif
wxString error = wxString::Format( wxString error = wxString::Format(
_( "Layer '%s' in file <%s> at line %d, position %d, was not defined in the layers section" ), _( "Layer '%s' in file <%s> at line %d, position %d, was not defined in the layers section" ),
GetChars( name ), GetChars( CurSource() ), CurLineNumber(), CurOffset() ); GetChars( FROM_UTF8( CurText() ) ), GetChars( CurSource() ),
CurLineNumber(), CurOffset() );
THROW_IO_ERROR( error ); THROW_IO_ERROR( error );
} }
...@@ -749,7 +771,7 @@ int PCB_PARSER::parseBoardItemLayer() throw( PARSE_ERROR, IO_ERROR ) ...@@ -749,7 +771,7 @@ int PCB_PARSER::parseBoardItemLayer() throw( PARSE_ERROR, IO_ERROR )
NextTok(); NextTok();
int layerIndex = lookUpLayer(); int layerIndex = lookUpLayer( m_layerIndices );
// Handle closing ) in object parser. // Handle closing ) in object parser.
...@@ -763,14 +785,12 @@ int PCB_PARSER::parseBoardItemLayersAsMask() throw( PARSE_ERROR, IO_ERROR ) ...@@ -763,14 +785,12 @@ int PCB_PARSER::parseBoardItemLayersAsMask() throw( PARSE_ERROR, IO_ERROR )
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
wxT( " as item layer mask." ) ); wxT( " as item layer mask." ) );
int layerIndex;
int layerMask = 0; int layerMask = 0;
T token;
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
layerIndex = lookUpLayer(); int mask = lookUpLayer( m_layerMasks );
layerMask |= ( 1 << layerIndex ); layerMask |= mask;
} }
return layerMask; return layerMask;
...@@ -1042,7 +1062,7 @@ void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1042,7 +1062,7 @@ void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR )
T token; T token;
auto_ptr<NETCLASS> nc( new NETCLASS( m_board, wxEmptyString ) ); unique_ptr<NETCLASS> nc( new NETCLASS( m_board, wxEmptyString ) );
NeedSYMBOL(); NeedSYMBOL();
nc->SetName( FromUTF8() ); nc->SetName( FromUTF8() );
...@@ -1103,7 +1123,7 @@ void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1103,7 +1123,7 @@ void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR )
// Must have been a name conflict, this is a bad board file. // Must have been a name conflict, this is a bad board file.
// User may have done a hand edit to the file. // User may have done a hand edit to the file.
// auto_ptr will delete nc on this code path // unique_ptr will delete nc on this code path
wxString error; wxString error;
error.Printf( _( "duplicate NETCLASS name '%s' in file %s at line %d, offset %d" ), error.Printf( _( "duplicate NETCLASS name '%s' in file %s at line %d, offset %d" ),
...@@ -1121,7 +1141,7 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1121,7 +1141,7 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
T token; T token;
wxPoint pt; wxPoint pt;
auto_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) ); unique_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
switch( CurTok() ) switch( CurTok() )
{ {
...@@ -1282,7 +1302,7 @@ TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1282,7 +1302,7 @@ TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR )
T token; T token;
auto_ptr< TEXTE_PCB > text( new TEXTE_PCB( m_board ) ); unique_ptr< TEXTE_PCB > text( new TEXTE_PCB( m_board ) );
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
text->SetText( FromUTF8() ); text->SetText( FromUTF8() );
...@@ -1350,7 +1370,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1350,7 +1370,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
T token; T token;
auto_ptr< DIMENSION > dimension( new DIMENSION( NULL ) ); unique_ptr< DIMENSION > dimension( new DIMENSION( NULL ) );
dimension->m_Value = parseBoardUnits( "dimension value" ); dimension->m_Value = parseBoardUnits( "dimension value" );
NeedLEFT(); NeedLEFT();
...@@ -1499,7 +1519,7 @@ MODULE* PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1499,7 +1519,7 @@ MODULE* PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
auto_ptr< MODULE > module( new MODULE( m_board ) ); unique_ptr< MODULE > module( new MODULE( m_board ) );
NeedSYMBOL(); NeedSYMBOL();
module->SetLibRef( FromUTF8() ); module->SetLibRef( FromUTF8() );
...@@ -1715,7 +1735,7 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1715,7 +1735,7 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR )
T token = NextTok(); T token = NextTok();
auto_ptr< TEXTE_MODULE > text( new TEXTE_MODULE( NULL ) ); unique_ptr< TEXTE_MODULE > text( new TEXTE_MODULE( NULL ) );
switch( token ) switch( token )
{ {
...@@ -1800,7 +1820,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1800,7 +1820,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
auto_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) ); unique_ptr< EDGE_MODULE > segment( new EDGE_MODULE( NULL ) );
switch( CurTok() ) switch( CurTok() )
{ {
...@@ -1948,7 +1968,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1948,7 +1968,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
break; break;
default: default:
Expecting( "layer, width, tstamp, or status" ); Expecting( "layer or width" );
} }
NeedRIGHT(); NeedRIGHT();
...@@ -1965,7 +1985,7 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR ) ...@@ -1965,7 +1985,7 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR )
wxSize sz; wxSize sz;
wxPoint pt; wxPoint pt;
auto_ptr< D_PAD > pad( new D_PAD( NULL ) ); unique_ptr< D_PAD > pad( new D_PAD( NULL ) );
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
pad->SetPadName( FromUTF8() ); pad->SetPadName( FromUTF8() );
...@@ -2112,18 +2132,20 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2112,18 +2132,20 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR )
} }
case T_layers: case T_layers:
{ {
int layerMask = parseBoardItemLayersAsMask(); int layerMask = parseBoardItemLayersAsMask();
// Only the layers that are used are saved so we need to enable all the copper /*
// layers to prevent any problems with the current design. At some point in // Only the layers that are used are saved so we need to enable all the copper
// the future, the layer handling should be improved. // layers to prevent any problems with the current design. At some point in
if( pad->GetAttribute() == PAD_STANDARD ) // the future, the layer handling should be improved.
layerMask |= ALL_CU_LAYERS; if( pad->GetAttribute() == PAD_STANDARD )
layerMask |= ALL_CU_LAYERS;
*/
pad->SetLayerMask( layerMask ); pad->SetLayerMask( layerMask );
}
break; break;
}
case T_net: case T_net:
pad->SetNet( parseInt( "net number" ) ); pad->SetNet( parseInt( "net number" ) );
...@@ -2191,7 +2213,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2191,7 +2213,7 @@ TRACK* PCB_PARSER::parseTRACK() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
auto_ptr< TRACK > track( new TRACK( m_board ) ); unique_ptr< TRACK > track( new TRACK( m_board ) );
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
...@@ -2253,7 +2275,7 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2253,7 +2275,7 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
auto_ptr< SEGVIA > via( new SEGVIA( m_board ) ); unique_ptr< SEGVIA > via( new SEGVIA( m_board ) );
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
...@@ -2289,15 +2311,15 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2289,15 +2311,15 @@ SEGVIA* PCB_PARSER::parseSEGVIA() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_layers: case T_layers:
{ {
int layer1, layer2; int layer1, layer2;
NextTok(); NextTok();
layer1 = lookUpLayer(); layer1 = lookUpLayer( m_layerIndices );
NextTok(); NextTok();
layer2 = lookUpLayer(); layer2 = lookUpLayer( m_layerIndices );
via->SetLayerPair( layer1, layer2 ); via->SetLayerPair( layer1, layer2 );
NeedRIGHT(); NeedRIGHT();
} }
break; break;
case T_net: case T_net:
...@@ -2338,7 +2360,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2338,7 +2360,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
// bigger scope since each filled_polygon is concatenated in here // bigger scope since each filled_polygon is concatenated in here
std::vector< CPolyPt > pts; std::vector< CPolyPt > pts;
auto_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) ); unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
zone->SetPriority( 0 ); zone->SetPriority( 0 );
...@@ -2643,7 +2665,7 @@ PCB_TARGET* PCB_PARSER::parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR ) ...@@ -2643,7 +2665,7 @@ PCB_TARGET* PCB_PARSER::parsePCB_TARGET() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
auto_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) ); unique_ptr< PCB_TARGET > target( new PCB_TARGET( NULL ) );
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
......
...@@ -30,9 +30,7 @@ ...@@ -30,9 +30,7 @@
#define _PCBNEW_PARSER_H_ #define _PCBNEW_PARSER_H_
#include <pcb_lexer.h> #include <pcb_lexer.h>
#include <hashtables.h>
#include <wx/hashmap.h>
using namespace PCB; using namespace PCB;
...@@ -47,14 +45,11 @@ class TEXTE_MODULE; ...@@ -47,14 +45,11 @@ class TEXTE_MODULE;
class TEXTE_PCB; class TEXTE_PCB;
class MODULE; class MODULE;
class PCB_TARGET; class PCB_TARGET;
class PROPERTIES;
class S3D_MASTER; class S3D_MASTER;
class ZONE_CONTAINER; class ZONE_CONTAINER;
class FPL_CACHE; class FPL_CACHE;
WX_DECLARE_STRING_HASH_MAP( int, LAYER_HASH_MAP );
/** /**
* Class PCB_PARSER * Class PCB_PARSER
...@@ -63,8 +58,11 @@ WX_DECLARE_STRING_HASH_MAP( int, LAYER_HASH_MAP ); ...@@ -63,8 +58,11 @@ WX_DECLARE_STRING_HASH_MAP( int, LAYER_HASH_MAP );
*/ */
class PCB_PARSER : public PCB_LEXER class PCB_PARSER : public PCB_LEXER
{ {
typedef KEYWORD_MAP LAYER_MAP;
BOARD* m_board; BOARD* m_board;
LAYER_HASH_MAP m_layerMap; ///< Map layer name to it's index saved in BOARD::m_Layer. LAYER_MAP m_layerIndices; ///< map layer name to it's index
LAYER_MAP m_layerMasks; ///< map layer names to their masks
/** /**
...@@ -101,11 +99,13 @@ class PCB_PARSER : public PCB_LEXER ...@@ -101,11 +99,13 @@ class PCB_PARSER : public PCB_LEXER
* Function lookUpLayer * Function lookUpLayer
* parses the current token for the layer definition of a #BOARD_ITEM object. * parses the current token for the layer definition of a #BOARD_ITEM object.
* *
* @param aMap is the LAYER_MAP to use for the lookup.
*
* @throw IO_ERROR if the layer is not valid. * @throw IO_ERROR if the layer is not valid.
* @throw PARSE_ERROR if the layer syntax is incorrect. * @throw PARSE_ERROR if the layer syntax is incorrect.
* @return The index the parsed #BOARD_ITEM layer. * @return int - The result of the parsed #BOARD_ITEM layer or set designator.
*/ */
int lookUpLayer() throw( PARSE_ERROR, IO_ERROR ); int lookUpLayer( const LAYER_MAP& aMap ) throw( PARSE_ERROR, IO_ERROR );
/** /**
* Function parseBoardItemLayer * Function parseBoardItemLayer
...@@ -223,9 +223,10 @@ public: ...@@ -223,9 +223,10 @@ public:
init(); init();
} }
// ~PCB_PARSER() {}
/** /**
* Functoin SetLineReader * Function SetLineReader
* sets @a aLineReader into the parser, and returns the previous one, if any. * sets @a aLineReader into the parser, and returns the previous one, if any.
* @param aReader is what to read from for tokens, no ownership is received. * @param aReader is what to read from for tokens, no ownership is received.
* @return LINE_READER* - previous LINE_READER or NULL if none. * @return LINE_READER* - previous LINE_READER or NULL if none.
......
...@@ -77,12 +77,13 @@ static void swigAddBuiltin() ...@@ -77,12 +77,13 @@ static void swigAddBuiltin()
int i = 0; int i = 0;
/* discover the length of the pyimport inittab */ /* discover the length of the pyimport inittab */
while( PyImport_Inittab[i].name ) i++; while( PyImport_Inittab[i].name )
i++;
/* allocate memory for the python module table */ /* allocate memory for the python module table */
SwigImportInittab = (struct _inittab*) malloc( SwigImportInittab = (struct _inittab*) malloc(
sizeof(struct _inittab)*(i+EXTRA_PYTHON_MODULES)); sizeof(struct _inittab)*(i+EXTRA_PYTHON_MODULES));
/* copy all pre-existing python modules into our newly created table */ /* copy all pre-existing python modules into our newly created table */
i=0; i=0;
while( PyImport_Inittab[i].name ) while( PyImport_Inittab[i].name )
...@@ -92,10 +93,11 @@ static void swigAddBuiltin() ...@@ -92,10 +93,11 @@ static void swigAddBuiltin()
} }
} }
/* Function swigAddModules
/* Function swigAddModules
* adds the internal modules we offer to the python scripting, so they will be * adds the internal modules we offer to the python scripting, so they will be
* available to the scripts we run. * available to the scripts we run.
* *
*/ */
static void swigAddModules() static void swigAddModules()
...@@ -110,7 +112,7 @@ static void swigAddModules() ...@@ -110,7 +112,7 @@ static void swigAddModules()
/* Function swigSwitchPythonBuiltin /* Function swigSwitchPythonBuiltin
* switches python module table to our built one . * switches python module table to our built one .
* *
*/ */
static void swigSwitchPythonBuiltin() static void swigSwitchPythonBuiltin()
...@@ -119,35 +121,36 @@ static void swigSwitchPythonBuiltin() ...@@ -119,35 +121,36 @@ static void swigSwitchPythonBuiltin()
} }
/* Function pcbnewInitPythonScripting /* Function pcbnewInitPythonScripting
* Initializes all the python environment and publish our interface inside it * Initializes all the python environment and publish our interface inside it
* initializes all the wxpython interface, and returns the python thread control structure * initializes all the wxpython interface, and returns the python thread control structure
* *
*/ */
PyThreadState *g_PythonMainTState; PyThreadState *g_PythonMainTState;
bool pcbnewInitPythonScripting() bool pcbnewInitPythonScripting()
{ {
swigAddBuiltin(); // add builtin functions swigAddBuiltin(); // add builtin functions
swigAddModules(); // add our own modules swigAddModules(); // add our own modules
swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list swigSwitchPythonBuiltin(); // switch the python builtin modules to our new list
Py_Initialize(); Py_Initialize();
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
PyEval_InitThreads(); PyEval_InitThreads();
// Load the wxPython core API. Imports the wx._core_ module and sets a // Load the wxPython core API. Imports the wx._core_ module and sets a
// local pointer to a function table located there. The pointer is used // local pointer to a function table located there. The pointer is used
// internally by the rest of the API functions. // internally by the rest of the API functions.
if ( ! wxPyCoreAPI_IMPORT() ) { if( ! wxPyCoreAPI_IMPORT() )
{
wxLogError(wxT("***** Error importing the wxPython API! *****")); wxLogError(wxT("***** Error importing the wxPython API! *****"));
PyErr_Print(); PyErr_Print();
Py_Finalize(); Py_Finalize();
return false; return false;
} }
// Save the current Python thread state and release the // Save the current Python thread state and release the
// Global Interpreter Lock. // Global Interpreter Lock.
...@@ -156,7 +159,8 @@ bool pcbnewInitPythonScripting() ...@@ -156,7 +159,8 @@ bool pcbnewInitPythonScripting()
// load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins // load pcbnew inside python, and load all the user plugins, TODO: add system wide plugins
PY_BLOCK_THREADS( blocked ); PY_BLOCK_THREADS( blocked );
#endif #endif
PyRun_SimpleString( "import sys\n" PyRun_SimpleString( "import sys\n"
"sys.path.append(\".\")\n" "sys.path.append(\".\")\n"
"import pcbnew\n" "import pcbnew\n"
...@@ -173,29 +177,28 @@ void pcbnewFinishPythonScripting() ...@@ -173,29 +177,28 @@ void pcbnewFinishPythonScripting()
wxPyEndAllowThreads(g_PythonMainTState); wxPyEndAllowThreads(g_PythonMainTState);
#endif #endif
Py_Finalize(); Py_Finalize();
} }
#ifdef KICAD_SCRIPTING_WXPYTHON #ifdef KICAD_SCRIPTING_WXPYTHON
void RedirectStdio() void RedirectStdio()
{ {
// This is a helpful little tidbit to help debugging and such. It // This is a helpful little tidbit to help debugging and such. It
// redirects Python's stdout and stderr to a window that will popup // redirects Python's stdout and stderr to a window that will popup
// only on demand when something is printed, like a traceback. // only on demand when something is printed, like a traceback.
const char* python_redirect = const char* python_redirect =
"import sys\n\ "import sys\n\
import wx\n\ import wx\n\
output = wx.PyOnDemandOutputWindow()\n\ output = wx.PyOnDemandOutputWindow()\n\
c sys.stderr = output\n"; c sys.stderr = output\n";
PY_BLOCK_THREADS( blocked ); PY_BLOCK_THREADS( blocked );
PyRun_SimpleString( python_redirect ); PyRun_SimpleString( python_redirect );
PY_UNBLOCK_THREADS( blocked ); PY_UNBLOCK_THREADS( blocked );
} }
wxWindow* CreatePythonShellWindow(wxWindow* parent) wxWindow* CreatePythonShellWindow(wxWindow* parent)
{ {
...@@ -228,7 +231,7 @@ def makeWindow(parent):\n\ ...@@ -228,7 +231,7 @@ def makeWindow(parent):\n\
PY_BLOCK_THREADS( blocked ); PY_BLOCK_THREADS( blocked );
// Now make a dictionary to serve as the global namespace when the code is // Now make a dictionary to serve as the global namespace when the code is
// executed. Put a reference to the builtins module in it. // executed. Put a reference to the builtins module in it.
PyObject* globals = PyDict_New(); PyObject* globals = PyDict_New();
PyObject* builtins = PyImport_ImportModule( "__builtin__" ); PyObject* builtins = PyImport_ImportModule( "__builtin__" );
...@@ -239,7 +242,7 @@ def makeWindow(parent):\n\ ...@@ -239,7 +242,7 @@ def makeWindow(parent):\n\
result = PyRun_String( pycrust_panel, Py_file_input, globals, globals ); result = PyRun_String( pycrust_panel, Py_file_input, globals, globals );
// Was there an exception? // Was there an exception?
if ( !result ) if( !result )
{ {
PyErr_Print(); PyErr_Print();
PY_UNBLOCK_THREADS( blocked ); PY_UNBLOCK_THREADS( blocked );
...@@ -258,19 +261,22 @@ def makeWindow(parent):\n\ ...@@ -258,19 +261,22 @@ def makeWindow(parent):\n\
PyObject* arg = wxPyMake_wxObject( parent, false ); PyObject* arg = wxPyMake_wxObject( parent, false );
wxASSERT( arg != NULL ); wxASSERT( arg != NULL );
PyObject* tuple = PyTuple_New( 1 ); PyObject* tuple = PyTuple_New( 1 );
PyTuple_SET_ITEM( tuple, 0, arg ); PyTuple_SET_ITEM( tuple, 0, arg );
result = PyEval_CallObject( func, tuple ); result = PyEval_CallObject( func, tuple );
// Was there an exception? // Was there an exception?
if ( !result ) if( !result )
PyErr_Print(); PyErr_Print();
else else
{ {
// Otherwise, get the returned window out of Python-land and // Otherwise, get the returned window out of Python-land and
// into C++-ville... // into C++-ville...
bool success = wxPyConvertSwigPtr(result, (void**)&window, _T("wxWindow") ); bool success = wxPyConvertSwigPtr(result, (void**)&window, _T("wxWindow") );
(void)success; (void)success;
wxASSERT_MSG(success, _T("Returned object was not a wxWindow!") ); wxASSERT_MSG(success, _T("Returned object was not a wxWindow!") );
Py_DECREF(result); Py_DECREF(result);
} }
...@@ -286,9 +292,3 @@ def makeWindow(parent):\n\ ...@@ -286,9 +292,3 @@ def makeWindow(parent):\n\
} }
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment