From e269b5d1b97f5f580801d51959e4ca766da69416 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 31 Aug 2019 15:18:27 +0100 Subject: [PATCH] Workaround an issue where a throw terminates (even when there's a catch for it). You can trigger it before this fix by running Cvpcb when a .kicad_mod file is incorrectly set as "Legacy" in your footprint table. --- common/fp_lib_table.cpp | 5 ++-- cvpcb/readwrite_dlgs.cpp | 2 +- include/fp_lib_table.h | 4 ++- pcbnew/eagle_plugin.cpp | 19 +++++++++++-- pcbnew/eagle_plugin.h | 2 +- pcbnew/footprint_info_impl.cpp | 2 +- pcbnew/github/github_plugin.cpp | 48 +++++++++++++++++--------------- pcbnew/github/github_plugin.h | 14 +++++----- pcbnew/gpcb_plugin.cpp | 32 ++++++++++----------- pcbnew/gpcb_plugin.h | 2 +- pcbnew/io_mgr.h | 4 ++- pcbnew/kicad_plugin.cpp | 22 ++++++--------- pcbnew/kicad_plugin.h | 2 +- pcbnew/legacy_plugin.cpp | 39 ++++++++++++++------------ pcbnew/legacy_plugin.h | 2 +- pcbnew/load_select_footprint.cpp | 2 +- pcbnew/plugin.cpp | 2 +- pcbnew/swig/footprint.i | 13 +-------- 18 files changed, 113 insertions(+), 103 deletions(-) diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index 8966ba5811..406b5bba8a 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -259,11 +259,12 @@ long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname ) } -void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname ) +void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname, + bool aBestEfforts ) { const FP_LIB_TABLE_ROW* row = FindRow( aNickname ); wxASSERT( (PLUGIN*) row->plugin ); - row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), + row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ), aBestEfforts, row->GetProperties() ); } diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index fb9585945d..f6e3f3e2d6 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -54,7 +54,7 @@ static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId ) { wxArrayString fpnames; - aTbl->FootprintEnumerate( fpnames, nicks[libNdx] ); + aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true ); for( unsigned nameNdx = 0; nameNdxfirst.c_str() ) ); + + if( !errorMsg.IsEmpty() && !aBestEfforts ) + THROW_IO_ERROR( errorMsg ); } diff --git a/pcbnew/eagle_plugin.h b/pcbnew/eagle_plugin.h index 01c01d37a3..fbe2901f85 100644 --- a/pcbnew/eagle_plugin.h +++ b/pcbnew/eagle_plugin.h @@ -127,7 +127,7 @@ public: const wxString GetFileExtension() const override; void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL) override; + bool aBestEfforts, const PROPERTIES* aProperties = NULL) override; MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL ) override; diff --git a/pcbnew/footprint_info_impl.cpp b/pcbnew/footprint_info_impl.cpp index ae1ecffad0..89f3fa6be8 100644 --- a/pcbnew/footprint_info_impl.cpp +++ b/pcbnew/footprint_info_impl.cpp @@ -261,7 +261,7 @@ bool FOOTPRINT_LIST_IMPL::JoinWorkers() try { - m_lib_table->FootprintEnumerate( fpnames, nickname ); + m_lib_table->FootprintEnumerate( fpnames, nickname, false ); } catch( const IO_ERROR& ioe ) { diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp index 84438cf854..9800dde6b8 100644 --- a/pcbnew/github/github_plugin.cpp +++ b/pcbnew/github/github_plugin.cpp @@ -138,34 +138,38 @@ const wxString GITHUB_PLUGIN::GetFileExtension() const } -void GITHUB_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, - const wxString& aLibraryPath, const PROPERTIES* aProperties ) +void GITHUB_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibPath, + bool aBestEfforts, const PROPERTIES* aProperties ) { - //D(printf("%s: this:%p aLibraryPath:\"%s\"\n", __func__, this, TO_UTF8(aLibraryPath) );) - cacheLib( aLibraryPath, aProperties ); - - typedef std::set MYSET; - - MYSET unique; - - if( m_pretty_dir.size() ) + try { - wxArrayString locals; + //D(printf("%s: this:%p aLibPath:\"%s\"\n", __func__, this, TO_UTF8(aLibraryPath) );) + cacheLib( aLibPath, aProperties ); - PCB_IO::FootprintEnumerate( locals, m_pretty_dir ); + typedef std::set MYSET; - for( unsigned i=0; ibegin(); it!=m_gh_cache->end(); ++it ) + unique.insert( it->first ); + + for( MYSET::const_iterator it = unique.begin(); it != unique.end(); ++it ) + aFootprintNames.Add( *it ); } - - for( MODULE_ITER it = m_gh_cache->begin(); it!=m_gh_cache->end(); ++it ) + catch( const IO_ERROR& ioe ) { - unique.insert( it->first ); - } - - for( MYSET::const_iterator it = unique.begin(); it != unique.end(); ++it ) - { - aFootprintNames.Add( *it ); + if( !aBestEfforts ) + throw ioe; } } diff --git a/pcbnew/github/github_plugin.h b/pcbnew/github/github_plugin.h index ca633b1a1f..232babdfda 100644 --- a/pcbnew/github/github_plugin.h +++ b/pcbnew/github/github_plugin.h @@ -167,20 +167,20 @@ public: const wxString GetFileExtension() const override; - void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL ) override; + void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibPath, + bool aBestEfforts, const PROPERTIES* aProperties = NULL ) override; void PrefetchLib( const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL ) override; + const PROPERTIES* aProperties = NULL ) override; - MODULE* FootprintLoad( const wxString& aLibraryPath, - const wxString& aFootprintName, const PROPERTIES* aProperties ) override; + MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, + const PROPERTIES* aProperties ) override; void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint, - const PROPERTIES* aProperties = NULL ) override; + const PROPERTIES* aProperties = NULL ) override; void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName, - const PROPERTIES* aProperties = NULL ) override; + const PROPERTIES* aProperties = NULL ) override; bool IsFootprintLibWritable( const wxString& aLibraryPath ) override; diff --git a/pcbnew/gpcb_plugin.cpp b/pcbnew/gpcb_plugin.cpp index abb19672f0..a63dbe625a 100644 --- a/pcbnew/gpcb_plugin.cpp +++ b/pcbnew/gpcb_plugin.cpp @@ -867,25 +867,26 @@ void GPCB_PLUGIN::validateCache( const wxString& aLibraryPath, bool checkModifie } -void GPCB_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, - const wxString& aLibraryPath, - const PROPERTIES* aProperties ) +void GPCB_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, + bool aBestEfforts, const PROPERTIES* aProperties ) { - LOCALE_IO toggle; // toggles on, then off, the C locale. - wxDir dir( aLibraryPath ); + LOCALE_IO toggle; // toggles on, then off, the C locale. + wxDir dir( aLibraryPath ); + wxString errorMsg; if( !dir.IsOpened() ) { - THROW_IO_ERROR( wxString::Format( _( "footprint library path \"%s\" does not exist" ), - GetChars( aLibraryPath ) ) ); + if( aBestEfforts ) + return; + else + { + THROW_IO_ERROR( wxString::Format( _( "footprint library path \"%s\" does not exist" ), + aLibraryPath ) ); + } } init( aProperties ); - wxString errorMsg; - - // Some of the files may have been parsed correctly so we want to add the valid files to - // the library. try { validateCache( aLibraryPath ); @@ -895,14 +896,13 @@ void GPCB_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, errorMsg = ioe.What(); } - const MODULE_MAP& mods = m_cache->GetModules(); + // Some of the files may have been parsed correctly so we want to add the valid files to + // the library. - for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it ) - { + for( MODULE_CITER it = m_cache->GetModules().begin(); it != m_cache->GetModules().end(); ++it ) aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) ); - } - if( !errorMsg.IsEmpty() ) + if( !errorMsg.IsEmpty() && !aBestEfforts ) THROW_IO_ERROR( errorMsg ); } diff --git a/pcbnew/gpcb_plugin.h b/pcbnew/gpcb_plugin.h index 9d15ab51a6..35c3ea06db 100644 --- a/pcbnew/gpcb_plugin.h +++ b/pcbnew/gpcb_plugin.h @@ -63,7 +63,7 @@ public: } void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL) override; + bool aBestEfforts, const PROPERTIES* aProperties = NULL ) override; const MODULE* GetEnumeratedFootprint( const wxString& aLibraryPath, const wxString& aFootprintName, diff --git a/pcbnew/io_mgr.h b/pcbnew/io_mgr.h index f8ae881467..d2362cc3d7 100644 --- a/pcbnew/io_mgr.h +++ b/pcbnew/io_mgr.h @@ -353,10 +353,12 @@ public: * * @param aFootprintNames is the array of available footprint names inside a library. * + * @param aBestEfforts if true, don't throw on errors, just return an empty list. + * * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded. */ virtual void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL ); + bool aBestEfforts, const PROPERTIES* aProperties = NULL ); /** * Generate a timestamp representing all the files in the library (including the library diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index cf4b6c7998..0271f4d5c5 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -2028,20 +2028,18 @@ void PCB_IO::validateCache( const wxString& aLibraryPath, bool checkModified ) } -void PCB_IO::FootprintEnumerate( wxArrayString& aFootprintNames, - const wxString& aLibraryPath, - const PROPERTIES* aProperties ) +void PCB_IO::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibPath, + bool aBestEfforts, const PROPERTIES* aProperties ) { - LOCALE_IO toggle; // toggles on, then off, the C locale. - wxDir dir( aLibraryPath ); + LOCALE_IO toggle; // toggles on, then off, the C locale. + wxDir dir( aLibPath ); + wxString errorMsg; init( aProperties ); - wxString errorMsg; - try { - validateCache( aLibraryPath ); + validateCache( aLibPath ); } catch( const IO_ERROR& ioe ) { @@ -2051,14 +2049,10 @@ void PCB_IO::FootprintEnumerate( wxArrayString& aFootprintNames, // Some of the files may have been parsed correctly so we want to add the valid files to // the library. - const MODULE_MAP& mods = m_cache->GetModules(); - - for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it ) - { + for( MODULE_CITER it = m_cache->GetModules().begin(); it != m_cache->GetModules().end(); ++it ) aFootprintNames.Add( it->first ); - } - if( !errorMsg.IsEmpty() ) + if( !errorMsg.IsEmpty() && !aBestEfforts ) THROW_IO_ERROR( errorMsg ); } diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 287396556b..e2f01c438d 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -121,7 +121,7 @@ public: const PROPERTIES* aProperties = NULL ) override; void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL ) override; + bool aBestEfforts, const PROPERTIES* aProperties = NULL ) override; const MODULE* GetEnumeratedFootprint( const wxString& aLibraryPath, const wxString& aFootprintName, diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 0db263b59a..bdb3762292 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -3269,10 +3269,10 @@ void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader ) char* saveptr; if( !line ) - goto L_bad_library; + THROW_IO_ERROR( wxString::Format( _( "File '%s' is empty." ), m_lib_path ) ); if( !TESTLINE( "PCBNEW-LibModule-V1" ) ) - goto L_bad_library; + THROW_IO_ERROR( wxString::Format( _( "File '%s' is not a legacy library." ), m_lib_path ) ); while( ( line = aReader->ReadLine() ) != NULL ) { @@ -3281,18 +3281,12 @@ void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader ) const char* units = strtok_r( line + SZ( "Units" ), delims, &saveptr ); if( !strcmp( units, "mm" ) ) - { m_owner->diskToBiu = IU_PER_MM; - } } else if( TESTLINE( "$INDEX" ) ) return; } - -L_bad_library: - THROW_IO_ERROR( wxString::Format( _( "File \"%s\" is empty or is not a legacy library" ), - m_lib_path.GetData() ) ); } @@ -3432,22 +3426,31 @@ void LEGACY_PLUGIN::cacheLib( const wxString& aLibraryPath ) } -void LEGACY_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, - const wxString& aLibraryPath, - const PROPERTIES* aProperties ) +void LEGACY_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibPath, + bool aBestEfforts, const PROPERTIES* aProperties ) { - LOCALE_IO toggle; // toggles on, then off, the C locale. + LOCALE_IO toggle; // toggles on, then off, the C locale. + wxString errorMsg; init( aProperties ); - cacheLib( aLibraryPath ); - - const MODULE_MAP& mods = m_cache->m_modules; - - for( MODULE_CITER it = mods.begin(); it != mods.end(); ++it ) + try { - aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) ); + cacheLib( aLibPath ); } + catch( const IO_ERROR& ioe ) + { + errorMsg = ioe.What(); + } + + // Some of the files may have been parsed correctly so we want to add the valid files to + // the library. + + for( MODULE_CITER it = m_cache->m_modules.begin(); it != m_cache->m_modules.end(); ++it ) + aFootprintNames.Add( FROM_UTF8( it->first.c_str() ) ); + + if( !errorMsg.IsEmpty() && !aBestEfforts ) + THROW_IO_ERROR( errorMsg ); } diff --git a/pcbnew/legacy_plugin.h b/pcbnew/legacy_plugin.h index 3844ed47c8..c7a5300891 100644 --- a/pcbnew/legacy_plugin.h +++ b/pcbnew/legacy_plugin.h @@ -84,7 +84,7 @@ public: const PROPERTIES* aProperties = NULL ) override; void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties = NULL ) override; + bool aBestEfforts, const PROPERTIES* aProperties = NULL ) override; MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, const PROPERTIES* aProperties = NULL ) override; diff --git a/pcbnew/load_select_footprint.cpp b/pcbnew/load_select_footprint.cpp index 392ae3ec76..f0e1dd5f41 100644 --- a/pcbnew/load_select_footprint.cpp +++ b/pcbnew/load_select_footprint.cpp @@ -401,7 +401,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath ) wxArrayString footprints; - cur->FootprintEnumerate( footprints, curLibPath ); + cur->FootprintEnumerate( footprints, curLibPath, false ); for( unsigned i = 0; i < footprints.size(); ++i ) { diff --git a/pcbnew/plugin.cpp b/pcbnew/plugin.cpp index 14b6e14f13..6b85411c09 100644 --- a/pcbnew/plugin.cpp +++ b/pcbnew/plugin.cpp @@ -58,7 +58,7 @@ void PLUGIN::Save( const wxString& aFileName, BOARD* aBoard, const PROPERTIES* a void PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aLibraryPath, - const PROPERTIES* aProperties ) + bool aBestEfforts, const PROPERTIES* aProperties ) { // not pure virtual so that plugins only have to implement subset of the PLUGIN interface. not_implemented( this, __FUNCTION__ ); diff --git a/pcbnew/swig/footprint.i b/pcbnew/swig/footprint.i index 15b5214aaf..dee8ddd06e 100644 --- a/pcbnew/swig/footprint.i +++ b/pcbnew/swig/footprint.i @@ -73,18 +73,7 @@ { wxArrayString footprintNames; - if( aExitOnError ) - self->FootprintEnumerate( footprintNames, aLibraryPath ); - else - { - try - { - self->FootprintEnumerate( footprintNames, aLibraryPath ); - } - catch( const IO_ERROR& error ) - { - } - } + self->FootprintEnumerate( footprintNames, aLibraryPath, !aExitOnError ); return footprintNames; }