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( -1 ),
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( m_fileModTime < 0 )
128 return false;
129
130 if( !fn.IsOk() )
131 return false;
132
133 if( !fn.IsDir() && fn.IsFileReadable() )
134 return fn.GetModificationTime().GetValue().GetValue() != m_fileModTime;
135
136 if( fn.IsDir() && fn.IsDirReadable() )
137 {
138 return KIPLATFORM::IO::TimestampDir( fn.GetPath(),
139 wxS( "*." ) + wxString( FILEEXT::KiCadSymbolLibFileExtension ) )
140 != m_fileModTime;
141 }
142
143 return false;
144}
145
146
148{
149 wxCHECK_MSG( aSymbol != nullptr, nullptr, "NULL pointer cannot be removed from library." );
150
151 LIB_SYMBOL* firstChild = nullptr;
152 LIB_SYMBOL_MAP::iterator it = m_symbols.find( aSymbol->GetName() );
153
154 if( it == m_symbols.end() )
155 return nullptr;
156
157 // If the entry pointer doesn't match the name it is mapped to in the library, we
158 // have done something terribly wrong.
159 wxCHECK_MSG( &*it->second == aSymbol, nullptr,
160 "Pointer mismatch while attempting to remove alias entry <" + aSymbol->GetName() +
161 "> from library cache <" + m_libFileName.GetName() + ">." );
162
163 // If the symbol is a root symbol used by other symbols find the first derived symbol that uses
164 // the root symbol and make it the new root.
165 if( aSymbol->IsRoot() )
166 {
167 for( const std::pair<const wxString, LIB_SYMBOL*>& entry : m_symbols )
168 {
169 if( entry.second->IsDerived()
170 && entry.second->GetParent().lock() == aSymbol->SharedPtr() )
171 {
172 firstChild = entry.second;
173 break;
174 }
175 }
176
177 if( firstChild )
178 {
179 for( SCH_ITEM& drawItem : aSymbol->GetDrawItems() )
180 {
181 if( drawItem.Type() == SCH_FIELD_T )
182 {
183 SCH_FIELD& field = static_cast<SCH_FIELD&>( drawItem );
184
185 if( firstChild->GetField( field.GetCanonicalName() ) )
186 continue;
187 }
188
189 SCH_ITEM* newItem = (SCH_ITEM*) drawItem.Clone();
190 drawItem.SetParent( firstChild );
191 firstChild->AddDrawItem( newItem );
192 }
193
194 // Reparent the remaining derived symbols.
195 for( const std::pair<const wxString, LIB_SYMBOL*>& entry : m_symbols )
196 {
197 if( entry.second->IsDerived()
198 && entry.second->GetParent().lock() == aSymbol->SharedPtr() )
199 {
200 entry.second->SetParent( firstChild );
201 }
202 }
203 }
204 }
205
206 m_symbols.erase( it );
207 delete aSymbol;
208 m_isModified = true;
210 return firstChild;
211}
212
213
215{
216 // aSymbol is cloned in SYMBOL_LIB::AddSymbol(). The cache takes ownership of aSymbol.
217 wxString name = aSymbol->GetName();
218 LIB_SYMBOL_MAP::iterator it = m_symbols.find( name );
219
220 if( it != m_symbols.end() )
221 {
222 removeSymbol( it->second );
223 }
224
225 m_symbols[ name ] = const_cast< LIB_SYMBOL* >( aSymbol );
226 m_isModified = true;
228}
229
230
232{
233 LIB_SYMBOL_MAP::iterator it = m_symbols.find( aName );
234
235 if( it != m_symbols.end() )
236 {
237 return it->second;
238 }
239
240 return nullptr;
241}
const char * name
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition eda_item.cpp:128
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
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:199
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:168
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:123
@ SCH_FIELD_T
Definition typeinfo.h:151