Fix an issue when reading a gpcb footprint library when a .fp file has a problem.
Now the full library loading is not aborted (and the other libraries in list are also loaded). Only the bad .fp file(s) is not loaded. Mainly, a .fp file load error does not throw a library load error, and this is a temporary fix. But throwing a library error when a .fp file cannot be loaded is worst (you even cannot import a good .fp file).
This commit is contained in:
parent
ea855c1abf
commit
1a33efa133
|
@ -287,6 +287,9 @@ wxDateTime GPCB_FPL_CACHE::GetLibModificationTime() const
|
||||||
|
|
||||||
void GPCB_FPL_CACHE::Load()
|
void GPCB_FPL_CACHE::Load()
|
||||||
{
|
{
|
||||||
|
// Note: like our .pretty footprint libraries, the gpcb footprint libraries are folders,
|
||||||
|
// and the footprints are the .fp files inside this folder.
|
||||||
|
|
||||||
wxDir dir( m_lib_path.GetPath() );
|
wxDir dir( m_lib_path.GetPath() );
|
||||||
|
|
||||||
if( !dir.IsOpened() )
|
if( !dir.IsOpened() )
|
||||||
|
@ -301,18 +304,32 @@ void GPCB_FPL_CACHE::Load()
|
||||||
if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
|
if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wxString cacheErrorMsg;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
wxFileName fn( m_lib_path.GetPath(), fpFileName );
|
wxFileName fn( m_lib_path.GetPath(), fpFileName );
|
||||||
|
|
||||||
// reader now owns fp, will close on exception or return
|
// Queue I/O errors so only files that fail to parse don't get loaded.
|
||||||
FILE_LINE_READER reader( fn.GetFullPath() );
|
try
|
||||||
std::string name = TO_UTF8( fn.GetName() );
|
{
|
||||||
MODULE* footprint = parseMODULE( &reader );
|
// reader now owns fp, will close on exception or return
|
||||||
|
FILE_LINE_READER reader( fn.GetFullPath() );
|
||||||
|
|
||||||
// The footprint name is the file name without the extension.
|
std::string name = TO_UTF8( fn.GetName() );
|
||||||
footprint->SetFPID( LIB_ID( fn.GetName() ) );
|
MODULE* footprint = parseMODULE( &reader );
|
||||||
m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) );
|
|
||||||
|
// The footprint name is the file name without the extension.
|
||||||
|
footprint->SetFPID( LIB_ID( fn.GetName() ) );
|
||||||
|
m_modules.insert( name, new GPCB_FPL_CACHE_ITEM( footprint, fn.GetName() ) );
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
if( !cacheErrorMsg.IsEmpty() )
|
||||||
|
cacheErrorMsg += "\n";
|
||||||
|
|
||||||
|
cacheErrorMsg += ioe.What();
|
||||||
|
}
|
||||||
|
|
||||||
} while( dir.GetNext( &fpFileName ) );
|
} while( dir.GetNext( &fpFileName ) );
|
||||||
|
|
||||||
|
@ -320,6 +337,11 @@ void GPCB_FPL_CACHE::Load()
|
||||||
// cache snapshot was made, so that in a networked environment we will
|
// cache snapshot was made, so that in a networked environment we will
|
||||||
// reload the cache as needed.
|
// reload the cache as needed.
|
||||||
m_mod_time = GetLibModificationTime();
|
m_mod_time = GetLibModificationTime();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if( !cacheErrorMsg.IsEmpty() )
|
||||||
|
THROW_IO_ERROR( cacheErrorMsg );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -416,7 +438,10 @@ MODULE* GPCB_FPL_CACHE::parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR,
|
||||||
|
|
||||||
|
|
||||||
if( aLineReader->ReadLine() == NULL )
|
if( aLineReader->ReadLine() == NULL )
|
||||||
THROW_IO_ERROR( "unexpected end of file" );
|
{
|
||||||
|
msg = aLineReader->GetSource() + ": empty file";
|
||||||
|
THROW_IO_ERROR( msg );
|
||||||
|
}
|
||||||
|
|
||||||
parameters.Clear();
|
parameters.Clear();
|
||||||
parseParameters( parameters, aLineReader );
|
parseParameters( parameters, aLineReader );
|
||||||
|
@ -965,6 +990,7 @@ wxArrayString GPCB_PLUGIN::FootprintEnumerate( const wxString& aLibraryPath,
|
||||||
init( aProperties );
|
init( aProperties );
|
||||||
|
|
||||||
#if 1 // Set to 0 to only read directory contents, not load cache.
|
#if 1 // Set to 0 to only read directory contents, not load cache.
|
||||||
|
|
||||||
cacheLib( aLibraryPath );
|
cacheLib( aLibraryPath );
|
||||||
|
|
||||||
const MODULE_MAP& mods = m_cache->GetModules();
|
const MODULE_MAP& mods = m_cache->GetModules();
|
||||||
|
|
|
@ -92,7 +92,6 @@ static const wxString INFO_LEGACY_LIB_WARN_DELETE(
|
||||||
"before deleting a footprint" ) );
|
"before deleting a footprint" ) );
|
||||||
|
|
||||||
static const wxString ModLegacyExportFileWildcard( _( "Legacy foot print export files (*.emp)|*.emp" ) );
|
static const wxString ModLegacyExportFileWildcard( _( "Legacy foot print export files (*.emp)|*.emp" ) );
|
||||||
static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" ) );
|
|
||||||
|
|
||||||
|
|
||||||
#define EXPORT_IMPORT_LASTPATH_KEY wxT( "import_last_path" )
|
#define EXPORT_IMPORT_LASTPATH_KEY wxT( "import_last_path" )
|
||||||
|
@ -103,15 +102,14 @@ static const wxString ModImportFileWildcard( _( "GPcb foot print files (*)|*" )
|
||||||
* @param aParent - parent window for the dialog
|
* @param aParent - parent window for the dialog
|
||||||
* @param aLastPath - last opened path
|
* @param aLastPath - last opened path
|
||||||
*/
|
*/
|
||||||
static wxFileName prompt_for_module( wxWindow* aParent, const wxString& aLastPath )
|
static wxFileName getFootprintFilenameFromUser( wxWindow* aParent, const wxString& aLastPath )
|
||||||
{
|
{
|
||||||
static int lastFilterIndex = 0;
|
static int lastFilterIndex = 0; // To store the last choice during a session.
|
||||||
wxString wildCard;
|
wxString wildCard;
|
||||||
|
|
||||||
wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
|
wildCard << wxGetTranslation( KiCadFootprintLibFileWildcard ) << wxChar( '|' )
|
||||||
<< wxGetTranslation( ModLegacyExportFileWildcard ) << wxChar( '|' )
|
<< wxGetTranslation( ModLegacyExportFileWildcard ) << wxChar( '|' )
|
||||||
<< wxGetTranslation( ModImportFileWildcard ) << wxChar( '|' )
|
<< wxGetTranslation( GedaPcbFootprintLibFileWildcard ) << wxChar( '|' );
|
||||||
<< wxGetTranslation( GedaPcbFootprintLibFileWildcard );
|
|
||||||
|
|
||||||
wxFileDialog dlg( aParent, FMT_IMPORT_MODULE, aLastPath, wxEmptyString, wildCard,
|
wxFileDialog dlg( aParent, FMT_IMPORT_MODULE, aLastPath, wxEmptyString, wildCard,
|
||||||
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
|
||||||
|
@ -263,7 +261,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
|
||||||
if( config )
|
if( config )
|
||||||
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
|
config->Read( EXPORT_IMPORT_LASTPATH_KEY, &lastOpenedPathForLoading );
|
||||||
|
|
||||||
wxFileName fn = prompt_for_module( this, lastOpenedPathForLoading );
|
wxFileName fn = getFootprintFilenameFromUser( this, lastOpenedPathForLoading );
|
||||||
|
|
||||||
if( !fn.IsOk() )
|
if( !fn.IsOk() )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -292,8 +290,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE* module;
|
MODULE* module = NULL;
|
||||||
wxString errMessage;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -310,7 +307,14 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
|
||||||
catch( const IO_ERROR& ioe )
|
catch( const IO_ERROR& ioe )
|
||||||
{
|
{
|
||||||
DisplayError( this, ioe.What() );
|
DisplayError( this, ioe.What() );
|
||||||
return NULL;
|
|
||||||
|
// if the footprint is not loaded, exit.
|
||||||
|
// However, even if an error happens, it can be loaded, because in KICAD and GPCB format,
|
||||||
|
// a fp library is a set of separate files, and the error(s) are not necessary when
|
||||||
|
// reading the selected file
|
||||||
|
|
||||||
|
if( !module )
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert footprint in list
|
// Insert footprint in list
|
||||||
|
|
Loading…
Reference in New Issue