KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_io_lib_cache.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * @author Wayne Stambaugh <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "sch_io_lib_cache.h"
23
24#include <common.h>
25#include <kiplatform/io.h>
26#include <lib_symbol.h>
27#include <wx_filename.h>
28
29
30SCH_IO_LIB_CACHE::SCH_IO_LIB_CACHE( const wxString& aFullPathAndFileName ) :
31 m_modHash( 1 ),
32 m_fileName( aFullPathAndFileName ),
34 m_fileModTime( 0 ),
35 m_isWritable( true ),
36 m_isModified( false ),
37 m_hasParseError( false )
38{
40
41 // Normalize the path: if it's a directory on the filesystem, ensure m_libFileName is marked
42 // as a directory so that IsDir() checks work correctly.
43 if( wxFileName::DirExists( aFullPathAndFileName ) )
44 m_libFileName.AssignDir( aFullPathAndFileName );
45 else
46 m_libFileName = aFullPathAndFileName;
47}
48
49
51{
52 // When the cache is destroyed, all of the alias objects on the heap should be deleted.
53 for( auto& symbol : m_symbols )
54 delete symbol.second;
55
56 m_symbols.clear();
57}
58
59
60void SCH_IO_LIB_CACHE::Save( const std::optional<bool>& aOpt )
61{
62 wxCHECK( false, /* void */ );
63}
64
65
67{
68 wxFileName fn( m_libFileName );
69
70 // If m_libFileName is a symlink follow it to the real source file
72
73 // Normalize the path: if it's a directory on the filesystem, ensure fn is marked as a
74 // directory so that IsDir() checks work correctly. wxFileName::IsDir() only checks if
75 // the path string ends with a separator, not if the path is actually a directory.
76 if( !fn.IsDir() && wxFileName::DirExists( fn.GetFullPath() ) )
77 fn.AssignDir( fn.GetFullPath() );
78
79 return fn;
80}
81
82
84{
85 wxFileName fn = GetRealFile();
86 wxString wildcard = fn.GetFullName();
87
88 // Update the writable flag while we have a wxFileName, in a network this is possibly quite dynamic anyway.
89 if( !fn.IsDir() )
90 {
91 m_isWritable = fn.IsFileWritable();
92 return fn.GetModificationTime().GetValue().GetValue();
93 }
94 else
95 {
96 m_isWritable = fn.IsDirWritable();
97 wildcard = wxS( "*." ) + wxString( FILEEXT::KiCadSymbolLibFileExtension );
98 return KIPLATFORM::IO::TimestampDir( fn.GetPath(), wildcard );
99 }
100}
101
102
103bool SCH_IO_LIB_CACHE::IsFile( const wxString& aFullPathAndFileName ) const
104{
105 return m_fileName == aFullPathAndFileName;
106}
107
108
109void SCH_IO_LIB_CACHE::SetFileName( const wxString& aFileName )
110{
111 // Update both m_fileName and m_libFileName to keep them in sync
112 m_fileName = aFileName;
113
114 // Normalize the path: if it's a directory on the filesystem, ensure m_libFileName is marked
115 // as a directory so that IsDir() checks work correctly.
116 if( wxFileName::DirExists( aFileName ) )
117 m_libFileName.AssignDir( aFileName );
118 else
119 m_libFileName = aFileName;
120}
121
122
124{
125 wxFileName fn = GetRealFile();
126
127 if( !fn.IsOk() )
128 return false;
129
130 if( !fn.IsDir() && fn.IsFileReadable() )
131 return fn.GetModificationTime().GetValue().GetValue() != m_fileModTime;
132
133 if( fn.IsDir() && fn.IsDirReadable() )
134 {
135 return KIPLATFORM::IO::TimestampDir( fn.GetPath(),
136 wxS( "*." ) + wxString( FILEEXT::KiCadSymbolLibFileExtension ) )
137 != m_fileModTime;
138 }
139
140 return false;
141}
142
143
145{
146 wxCHECK_MSG( aSymbol != nullptr, nullptr, "NULL pointer cannot be removed from library." );
147
148 LIB_SYMBOL* firstChild = nullptr;
149 LIB_SYMBOL_MAP::iterator it = m_symbols.find( aSymbol->GetName() );
150
151 if( it == m_symbols.end() )
152 return nullptr;
153
154 // If the entry pointer doesn't match the name it is mapped to in the library, we
155 // have done something terribly wrong.
156 wxCHECK_MSG( &*it->second == aSymbol, nullptr,
157 "Pointer mismatch while attempting to remove alias entry <" + aSymbol->GetName() +
158 "> from library cache <" + m_libFileName.GetName() + ">." );
159
160 // If the symbol is a root symbol used by other symbols find the first derived symbol that uses
161 // the root symbol and make it the new root.
162 if( aSymbol->IsRoot() )
163 {
164 for( const std::pair<const wxString, LIB_SYMBOL*>& entry : m_symbols )
165 {
166 if( entry.second->IsDerived()
167 && entry.second->GetParent().lock() == aSymbol->SharedPtr() )
168 {
169 firstChild = entry.second;
170 break;
171 }
172 }
173
174 if( firstChild )
175 {
176 for( SCH_ITEM& drawItem : aSymbol->GetDrawItems() )
177 {
178 if( drawItem.Type() == SCH_FIELD_T )
179 {
180 SCH_FIELD& field = static_cast<SCH_FIELD&>( drawItem );
181
182 if( firstChild->GetField( field.GetCanonicalName() ) )
183 continue;
184 }
185
186 SCH_ITEM* newItem = (SCH_ITEM*) drawItem.Clone();
187 drawItem.SetParent( firstChild );
188 firstChild->AddDrawItem( newItem );
189 }
190
191 // Reparent the remaining derived symbols.
192 for( const std::pair<const wxString, LIB_SYMBOL*>& entry : m_symbols )
193 {
194 if( entry.second->IsDerived()
195 && entry.second->GetParent().lock() == aSymbol->SharedPtr() )
196 {
197 entry.second->SetParent( firstChild );
198 }
199 }
200 }
201 }
202
203 m_symbols.erase( it );
204 delete aSymbol;
205 m_isModified = true;
207 return firstChild;
208}
209
210
212{
213 // aSymbol is cloned in SYMBOL_LIB::AddSymbol(). The cache takes ownership of aSymbol.
214 wxString name = aSymbol->GetName();
215 LIB_SYMBOL_MAP::iterator it = m_symbols.find( name );
216
217 if( it != m_symbols.end() )
218 {
219 removeSymbol( it->second );
220 }
221
222 m_symbols[ name ] = const_cast< LIB_SYMBOL* >( aSymbol );
223 m_isModified = true;
225}
226
227
229{
230 LIB_SYMBOL_MAP::iterator it = m_symbols.find( aName );
231
232 if( it != m_symbols.end() )
233 {
234 return it->second;
235 }
236
237 return nullptr;
238}
const char * name
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.h:113
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition eda_item.cpp:118
Define a library symbol object.
Definition lib_symbol.h:83
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition lib_symbol.h:202
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Definition lib_symbol.h:712
wxString GetName() const override
Definition lib_symbol.h:145
std::shared_ptr< LIB_SYMBOL > SharedPtr() const
http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared.
Definition lib_symbol.h:92
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
wxString GetCanonicalName() const
Get a non-language-specific name for a field which can be used for storage, variable look-up,...
bool IsFile(const wxString &aFullPathAndFileName) const
virtual LIB_SYMBOL * GetSymbol(const wxString &aName)
void SetFileName(const wxString &aFileName)
virtual void AddSymbol(const LIB_SYMBOL *aSymbol)
SCH_LIB_TYPE m_libType
LIB_SYMBOL_MAP m_symbols
wxFileName GetRealFile() const
bool IsFileChanged() const
long long GetLibModificationTime()
virtual void Save(const std::optional< bool > &aOpt=std::nullopt)
Save the entire library to file m_libFileName;.
SCH_IO_LIB_CACHE(const wxString &aLibraryPath)
LIB_SYMBOL * removeSymbol(LIB_SYMBOL *aAlias)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
static void ResolvePossibleSymlinks(wxFileName &aFilename)
The common library.
static const std::string KiCadSymbolLibFileExtension
long long TimestampDir(const wxString &aDirPath, const wxString &aFilespec)
Computes a hash of modification times and sizes for files matching a pattern.
Definition unix/io.cpp:103
@ SCH_FIELD_T
Definition typeinfo.h:154