Abstract out symbol library parser object.
This commit is contained in:
parent
54b20cb049
commit
9260431fe4
|
@ -245,9 +245,11 @@ set( EESCHEMA_SRCS
|
||||||
netlist_exporters/netlist_exporter_xml.cpp
|
netlist_exporters/netlist_exporter_xml.cpp
|
||||||
netlist_exporters/netlist_generator.cpp
|
netlist_exporters/netlist_generator.cpp
|
||||||
|
|
||||||
|
sch_plugins/sch_lib_plugin_cache.cpp
|
||||||
sch_plugins/eagle/sch_eagle_plugin.cpp
|
sch_plugins/eagle/sch_eagle_plugin.cpp
|
||||||
sch_plugins/kicad/sch_sexpr_parser.cpp
|
sch_plugins/kicad/sch_sexpr_parser.cpp
|
||||||
sch_plugins/kicad/sch_sexpr_plugin.cpp
|
sch_plugins/kicad/sch_sexpr_plugin.cpp
|
||||||
|
sch_plugins/legacy/sch_legacy_lib_plugin_cache.cpp
|
||||||
sch_plugins/legacy/sch_legacy_plugin.cpp
|
sch_plugins/legacy/sch_legacy_plugin.cpp
|
||||||
sch_plugins/legacy/sch_legacy_plugin_helpers.cpp
|
sch_plugins/legacy/sch_legacy_plugin_helpers.cpp
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
|
*
|
||||||
|
* 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SCH_LEGACY_LIB_PLUGIN_CACHE_
|
||||||
|
#define _SCH_LEGACY_LIB_PLUGIN_CACHE_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <eda_shape.h> // FILL_T
|
||||||
|
|
||||||
|
#include "../sch_lib_plugin_cache.h"
|
||||||
|
|
||||||
|
class FILE_LINE_READER;
|
||||||
|
class LIB_FIELD;
|
||||||
|
class LIB_PIN;
|
||||||
|
class LIB_SHAPE;
|
||||||
|
class LIB_TEXT;
|
||||||
|
class LINE_READER;
|
||||||
|
class SCH_LEGACY_PLUGIN;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cache assistant for KiCad legacy symbol libraries.
|
||||||
|
*/
|
||||||
|
class SCH_LEGACY_PLUGIN_CACHE : public SCH_LIB_PLUGIN_CACHE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SCH_LEGACY_PLUGIN_CACHE( const wxString& aLibraryPath );
|
||||||
|
virtual ~SCH_LEGACY_PLUGIN_CACHE() {}
|
||||||
|
|
||||||
|
// Most all functions in this class throw IO_ERROR exceptions. There are no
|
||||||
|
// error codes nor user interface calls from here, nor in any SCH_PLUGIN objects.
|
||||||
|
// Catch these exceptions higher up please.
|
||||||
|
|
||||||
|
/// Save the entire library to file m_libFileName;
|
||||||
|
void Save( const std::optional<bool>& aOpt ) override;
|
||||||
|
|
||||||
|
void Load() override;
|
||||||
|
|
||||||
|
void DeleteSymbol( const wxString& aName ) override;
|
||||||
|
|
||||||
|
static LIB_SYMBOL* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion,
|
||||||
|
LIB_SYMBOL_MAP* aMap = nullptr );
|
||||||
|
static void SaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter,
|
||||||
|
LIB_SYMBOL_MAP* aMap = nullptr );
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend SCH_LEGACY_PLUGIN;
|
||||||
|
|
||||||
|
void loadHeader( FILE_LINE_READER& aReader );
|
||||||
|
static void loadAliases( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader,
|
||||||
|
LIB_SYMBOL_MAP* aMap = nullptr );
|
||||||
|
static void loadField( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static void loadDrawEntries( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader,
|
||||||
|
int aMajorVersion, int aMinorVersion );
|
||||||
|
static void loadFootprintFilters( std::unique_ptr<LIB_SYMBOL>& aSymbol,
|
||||||
|
LINE_READER& aReader );
|
||||||
|
void loadDocs();
|
||||||
|
static LIB_SHAPE* loadArc( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static LIB_SHAPE* loadCircle( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static LIB_TEXT* loadText( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader,
|
||||||
|
int aMajorVersion, int aMinorVersion );
|
||||||
|
static LIB_SHAPE* loadRect( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static LIB_PIN* loadPin( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static LIB_SHAPE* loadPolyLine( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
static LIB_SHAPE* loadBezier( std::unique_ptr<LIB_SYMBOL>& aSymbol, LINE_READER& aReader );
|
||||||
|
|
||||||
|
static FILL_T parseFillMode( LINE_READER& aReader, const char* aLine, const char** aOutput );
|
||||||
|
|
||||||
|
void saveDocFile();
|
||||||
|
static void saveArc( LIB_SHAPE* aArc, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void saveBezier( LIB_SHAPE* aBezier, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void saveCircle( LIB_SHAPE* aCircle, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void saveField( const LIB_FIELD* aField, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void savePin( const LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void savePolyLine( LIB_SHAPE* aPolyLine, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void saveRectangle( LIB_SHAPE* aRectangle, OUTPUTFORMATTER& aFormatter );
|
||||||
|
static void saveText( const LIB_TEXT* aText, OUTPUTFORMATTER& aFormatter );
|
||||||
|
|
||||||
|
int m_versionMajor;
|
||||||
|
int m_versionMinor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SCH_LEGACY_LIB_PLUGIN_CACHE_
|
File diff suppressed because it is too large
Load Diff
|
@ -27,6 +27,8 @@
|
||||||
THROW_PARSE_ERROR( text, reader.GetSource(), reader.Line(), \
|
THROW_PARSE_ERROR( text, reader.GetSource(), reader.Line(), \
|
||||||
reader.LineNumber(), pos - reader.Line() )
|
reader.LineNumber(), pos - reader.Line() )
|
||||||
|
|
||||||
|
#define Mils2Iu( x ) Mils2iu( x )
|
||||||
|
|
||||||
|
|
||||||
class LINE_READER;
|
class LINE_READER;
|
||||||
class wxString;
|
class wxString;
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
|
*
|
||||||
|
* 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sch_lib_plugin_cache.h"
|
||||||
|
|
||||||
|
#include <lib_symbol.h>
|
||||||
|
#include <wx_filename.h>
|
||||||
|
|
||||||
|
|
||||||
|
int SCH_LIB_PLUGIN_CACHE::m_modHash = 1; // starts at 1 and goes up
|
||||||
|
std::mutex SCH_LIB_PLUGIN_CACHE::m_modHashMutex;
|
||||||
|
|
||||||
|
|
||||||
|
SCH_LIB_PLUGIN_CACHE::SCH_LIB_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) :
|
||||||
|
m_fileName( aFullPathAndFileName ),
|
||||||
|
m_libFileName( aFullPathAndFileName ),
|
||||||
|
m_isWritable( true ),
|
||||||
|
m_isModified( false )
|
||||||
|
{
|
||||||
|
m_libType = SCH_LIB_TYPE::LT_EESCHEMA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SCH_LIB_PLUGIN_CACHE::~SCH_LIB_PLUGIN_CACHE()
|
||||||
|
{
|
||||||
|
// When the cache is destroyed, all of the alias objects on the heap should be deleted.
|
||||||
|
for( auto& symbol : m_symbols )
|
||||||
|
delete symbol.second;
|
||||||
|
|
||||||
|
m_symbols.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_LIB_PLUGIN_CACHE::Save( const std::optional<bool>& aOpt )
|
||||||
|
{
|
||||||
|
wxCHECK( false, /* void */ );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileName SCH_LIB_PLUGIN_CACHE::GetRealFile() const
|
||||||
|
{
|
||||||
|
wxFileName fn( m_libFileName );
|
||||||
|
|
||||||
|
// If m_libFileName is a symlink follow it to the real source file
|
||||||
|
WX_FILENAME::ResolvePossibleSymlinks( fn );
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxDateTime SCH_LIB_PLUGIN_CACHE::GetLibModificationTime()
|
||||||
|
{
|
||||||
|
wxFileName fn = GetRealFile();
|
||||||
|
|
||||||
|
// update the writable flag while we have a wxFileName, in a network this
|
||||||
|
// is possibly quite dynamic anyway.
|
||||||
|
m_isWritable = fn.IsFileWritable();
|
||||||
|
|
||||||
|
return fn.GetModificationTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_LIB_PLUGIN_CACHE::IsFile( const wxString& aFullPathAndFileName ) const
|
||||||
|
{
|
||||||
|
return m_fileName == aFullPathAndFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_LIB_PLUGIN_CACHE::IsFileChanged() const
|
||||||
|
{
|
||||||
|
wxFileName fn = GetRealFile();
|
||||||
|
|
||||||
|
if( m_fileModTime.IsValid() && fn.IsOk() && fn.FileExists() )
|
||||||
|
return fn.GetModificationTime() != m_fileModTime;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_SYMBOL* SCH_LIB_PLUGIN_CACHE::removeSymbol( LIB_SYMBOL* aSymbol )
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( aSymbol != nullptr, nullptr, "NULL pointer cannot be removed from library." );
|
||||||
|
|
||||||
|
LIB_SYMBOL* firstChild = nullptr;
|
||||||
|
LIB_SYMBOL_MAP::iterator it = m_symbols.find( aSymbol->GetName() );
|
||||||
|
|
||||||
|
if( it == m_symbols.end() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// If the entry pointer doesn't match the name it is mapped to in the library, we
|
||||||
|
// have done something terribly wrong.
|
||||||
|
wxCHECK_MSG( *it->second == aSymbol, nullptr,
|
||||||
|
"Pointer mismatch while attempting to remove alias entry <" + aSymbol->GetName() +
|
||||||
|
"> from library cache <" + m_libFileName.GetName() + ">." );
|
||||||
|
|
||||||
|
// If the symbol is a root symbol used by other symbols find the first alias that uses
|
||||||
|
// the root symbol and make it the new root.
|
||||||
|
if( aSymbol->IsRoot() )
|
||||||
|
{
|
||||||
|
for( auto entry : m_symbols )
|
||||||
|
{
|
||||||
|
if( entry.second->IsAlias()
|
||||||
|
&& entry.second->GetParent().lock() == aSymbol->SharedPtr() )
|
||||||
|
{
|
||||||
|
firstChild = entry.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( firstChild )
|
||||||
|
{
|
||||||
|
for( LIB_ITEM& drawItem : aSymbol->GetDrawItems() )
|
||||||
|
{
|
||||||
|
if( drawItem.Type() == LIB_FIELD_T )
|
||||||
|
{
|
||||||
|
LIB_FIELD& field = static_cast<LIB_FIELD&>( drawItem );
|
||||||
|
|
||||||
|
if( firstChild->FindField( field.GetCanonicalName() ) )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIB_ITEM* newItem = (LIB_ITEM*) drawItem.Clone();
|
||||||
|
drawItem.SetParent( firstChild );
|
||||||
|
firstChild->AddDrawItem( newItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reparent the remaining aliases.
|
||||||
|
for( auto entry : m_symbols )
|
||||||
|
{
|
||||||
|
if( entry.second->IsAlias()
|
||||||
|
&& entry.second->GetParent().lock() == aSymbol->SharedPtr() )
|
||||||
|
entry.second->SetParent( firstChild );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_symbols.erase( it );
|
||||||
|
delete aSymbol;
|
||||||
|
m_isModified = true;
|
||||||
|
SCH_LIB_PLUGIN_CACHE::IncrementModifyHash();
|
||||||
|
return firstChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_LIB_PLUGIN_CACHE::AddSymbol( const LIB_SYMBOL* aSymbol )
|
||||||
|
{
|
||||||
|
// aSymbol is cloned in SYMBOL_LIB::AddSymbol(). The cache takes ownership of aSymbol.
|
||||||
|
wxString name = aSymbol->GetName();
|
||||||
|
LIB_SYMBOL_MAP::iterator it = m_symbols.find( name );
|
||||||
|
|
||||||
|
if( it != m_symbols.end() )
|
||||||
|
{
|
||||||
|
removeSymbol( it->second );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_symbols[ name ] = const_cast< LIB_SYMBOL* >( aSymbol );
|
||||||
|
m_isModified = true;
|
||||||
|
SCH_LIB_PLUGIN_CACHE::IncrementModifyHash();
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
|
*
|
||||||
|
* 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SCH_LIB_PLUGIN_CACHE_H_
|
||||||
|
#define _SCH_LIB_PLUGIN_CACHE_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include <wx/filename.h>
|
||||||
|
|
||||||
|
#include <symbol_library_common.h>
|
||||||
|
|
||||||
|
|
||||||
|
class LIB_SYMBOL;
|
||||||
|
class OUTPUTFORMATTER;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base cache assistant implementation for the symbol library portion of the #SCH_PLUGIN API.
|
||||||
|
*/
|
||||||
|
class SCH_LIB_PLUGIN_CACHE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SCH_LIB_PLUGIN_CACHE( const wxString& aLibraryPath );
|
||||||
|
virtual ~SCH_LIB_PLUGIN_CACHE();
|
||||||
|
|
||||||
|
static void IncrementModifyHash()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> mut( SCH_LIB_PLUGIN_CACHE::m_modHashMutex );
|
||||||
|
SCH_LIB_PLUGIN_CACHE::m_modHash++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetModifyHash()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> mut( SCH_LIB_PLUGIN_CACHE::m_modHashMutex );
|
||||||
|
return SCH_LIB_PLUGIN_CACHE::m_modHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most all functions in this class throw IO_ERROR exceptions. There are no
|
||||||
|
// error codes nor user interface calls from here, nor in any SCH_PLUGIN objects.
|
||||||
|
// Catch these exceptions higher up please.
|
||||||
|
|
||||||
|
/// Save the entire library to file m_libFileName;
|
||||||
|
virtual void Save( const std::optional<bool>& aOpt = std::nullopt );
|
||||||
|
|
||||||
|
virtual void Load() = 0;
|
||||||
|
|
||||||
|
virtual void AddSymbol( const LIB_SYMBOL* aSymbol );
|
||||||
|
|
||||||
|
virtual void DeleteSymbol( const wxString& aName ) = 0;
|
||||||
|
|
||||||
|
// If m_libFileName is a symlink follow it to the real source file
|
||||||
|
wxFileName GetRealFile() const;
|
||||||
|
|
||||||
|
wxDateTime GetLibModificationTime();
|
||||||
|
|
||||||
|
bool IsFile( const wxString& aFullPathAndFileName ) const;
|
||||||
|
|
||||||
|
bool IsFileChanged() const;
|
||||||
|
|
||||||
|
void SetModified( bool aModified = true ) { m_isModified = aModified; }
|
||||||
|
|
||||||
|
wxString GetLogicalName() const { return m_libFileName.GetName(); }
|
||||||
|
|
||||||
|
void SetFileName( const wxString& aFileName ) { m_libFileName = aFileName; }
|
||||||
|
|
||||||
|
wxString GetFileName() const { return m_libFileName.GetFullPath(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LIB_SYMBOL* removeSymbol( LIB_SYMBOL* aAlias );
|
||||||
|
|
||||||
|
static int m_modHash; // Keep track of the modification status of the library.
|
||||||
|
static std::mutex m_modHashMutex;
|
||||||
|
|
||||||
|
wxString m_fileName; // Absolute path and file name.
|
||||||
|
wxFileName m_libFileName; // Absolute path and file name is required here.
|
||||||
|
wxDateTime m_fileModTime;
|
||||||
|
LIB_SYMBOL_MAP m_symbols; // Map of names of #LIB_SYMBOL pointers.
|
||||||
|
bool m_isWritable;
|
||||||
|
bool m_isModified;
|
||||||
|
SCH_LIB_TYPE m_libType; // Is this cache a symbol or symbol library.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SCH_LIB_PLUGIN_CACHE_H_
|
Loading…
Reference in New Issue