KiCad PCB EDA Suite
fp_lib_table.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 (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2012-2016 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2012-2017 KiCad Developers, see AUTHORS.txt for contributors.
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
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <fctsys.h>
28 #include <common.h>
29 #include <kiface_i.h>
30 #include <footprint_info.h>
31 #include <lib_id.h>
32 #include <lib_table_lexer.h>
33 #include <fp_lib_table.h>
34 #include <class_module.h>
35 
36 #define OPT_SEP '|'
37 
38 using namespace LIB_TABLE_T;
39 
40 
41 static const wxChar global_tbl_name[] = wxT( "fp-lib-table" );
42 
43 
45 {
46  return LIB_TABLE_ROW::operator == ( aRow ) && type == aRow.type;
47 }
48 
49 
50 void FP_LIB_TABLE_ROW::SetType( const wxString& aType )
51 {
52  type = IO_MGR::EnumFromStr( aType );
53 
54  if( IO_MGR::PCB_FILE_T( -1 ) == type )
55  type = IO_MGR::KICAD_SEXP;
56 }
57 
58 
60  LIB_TABLE( aFallBackTable )
61 {
62  // not copying fall back, simply search aFallBackTable separately
63  // if "nickName not found".
64 }
65 
66 
67 void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
68 {
69  T tok;
70  wxString errMsg; // to collect error messages
71 
72  // This table may be nested within a larger s-expression, or not.
73  // Allow for parser of that optional containing s-epression to have looked ahead.
74  if( in->CurTok() != T_fp_lib_table )
75  {
76  in->NeedLEFT();
77 
78  if( ( tok = in->NextTok() ) != T_fp_lib_table )
79  in->Expecting( T_fp_lib_table );
80  }
81 
82  while( ( tok = in->NextTok() ) != T_RIGHT )
83  {
84  std::unique_ptr< FP_LIB_TABLE_ROW > row( new FP_LIB_TABLE_ROW );
85 
86  if( tok == T_EOF )
87  in->Expecting( T_RIGHT );
88 
89  if( tok != T_LEFT )
90  in->Expecting( T_LEFT );
91 
92  // in case there is a "row integrity" error, tell where later.
93  int lineNum = in->CurLineNumber();
94 
95  if( ( tok = in->NextTok() ) != T_lib )
96  in->Expecting( T_lib );
97 
98  // (name NICKNAME)
99  in->NeedLEFT();
100 
101  if( ( tok = in->NextTok() ) != T_name )
102  in->Expecting( T_name );
103 
104  in->NeedSYMBOLorNUMBER();
105 
106  row->SetNickName( in->FromUTF8() );
107 
108  in->NeedRIGHT();
109 
110  // After (name), remaining (lib) elements are order independent, and in
111  // some cases optional.
112  bool sawType = false;
113  bool sawOpts = false;
114  bool sawDesc = false;
115  bool sawUri = false;
116  bool sawDisabled = false;
117 
118  while( ( tok = in->NextTok() ) != T_RIGHT )
119  {
120  if( tok == T_EOF )
121  in->Unexpected( T_EOF );
122 
123  if( tok != T_LEFT )
124  in->Expecting( T_LEFT );
125 
126  tok = in->NeedSYMBOLorNUMBER();
127 
128  switch( tok )
129  {
130  case T_uri:
131  if( sawUri )
132  in->Duplicate( tok );
133  sawUri = true;
134  in->NeedSYMBOLorNUMBER();
135  row->SetFullURI( in->FromUTF8() );
136  break;
137 
138  case T_type:
139  if( sawType )
140  in->Duplicate( tok );
141  sawType = true;
142  in->NeedSYMBOLorNUMBER();
143  row->SetType( in->FromUTF8() );
144  break;
145 
146  case T_options:
147  if( sawOpts )
148  in->Duplicate( tok );
149  sawOpts = true;
150  in->NeedSYMBOLorNUMBER();
151  row->SetOptions( in->FromUTF8() );
152  break;
153 
154  case T_descr:
155  if( sawDesc )
156  in->Duplicate( tok );
157  sawDesc = true;
158  in->NeedSYMBOLorNUMBER();
159  row->SetDescr( in->FromUTF8() );
160  break;
161 
162  case T_disabled:
163  if( sawDisabled )
164  in->Duplicate( tok );
165  sawDisabled = true;
166  row->SetEnabled( false );
167  break;
168 
169  default:
170  in->Unexpected( tok );
171  }
172 
173  in->NeedRIGHT();
174  }
175 
176  if( !sawType )
177  in->Expecting( T_type );
178 
179  if( !sawUri )
180  in->Expecting( T_uri );
181 
182  // all nickNames within this table fragment must be unique, so we do not
183  // use doReplace in InsertRow(). (However a fallBack table can have a
184  // conflicting nickName and ours will supercede that one since in
185  // FindLib() we search this table before any fall back.)
186  wxString nickname = row->GetNickName(); // store it to be able to used it
187  // after row deletion if an error occurs
188  LIB_TABLE_ROW* tmp = row.release();
189 
190  if( !InsertRow( tmp ) )
191  {
192  delete tmp; // The table did not take ownership of the row.
193 
194  wxString msg = wxString::Format(
195  _( "Duplicate library nickname \"%s\" found in footprint library "
196  "table file line %d" ), GetChars( nickname ), lineNum );
197 
198  if( !errMsg.IsEmpty() )
199  errMsg << '\n';
200 
201  errMsg << msg;
202  }
203  }
204 
205  if( !errMsg.IsEmpty() )
206  THROW_IO_ERROR( errMsg );
207 }
208 
209 
210 bool FP_LIB_TABLE::operator==( const FP_LIB_TABLE& aFpTable ) const
211 {
212  if( rows.size() == aFpTable.rows.size() )
213  {
214  for( unsigned i = 0; i < rows.size(); ++i )
215  {
216  if( (FP_LIB_TABLE_ROW&)rows[i] != (FP_LIB_TABLE_ROW&)aFpTable.rows[i] )
217  return false;
218  }
219 
220  return true;
221  }
222 
223  return false;
224 }
225 
226 
227 void FP_LIB_TABLE::Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const
228 {
229  aOutput->Print( aIndentLevel, "(fp_lib_table\n" );
230 
231  for( LIB_TABLE_ROWS_CITER it = rows.begin(); it != rows.end(); ++it )
232  it->Format( aOutput, aIndentLevel+1 );
233 
234  aOutput->Print( aIndentLevel, ")\n" );
235 }
236 
237 
238 long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname )
239 {
240  if( aNickname )
241  {
242  const FP_LIB_TABLE_ROW* row = FindRow( *aNickname );
243  wxASSERT( (PLUGIN*) row->plugin );
244  return row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) );
245  }
246 
247  long long hash = 0;
248  for( wxString const& nickname : GetLogicalLibs() )
249  {
250  const FP_LIB_TABLE_ROW* row = FindRow( nickname );
251  wxASSERT( (PLUGIN*) row->plugin );
252  hash += row->plugin->GetLibraryTimestamp( row->GetFullURI( true ) );
253  }
254 
255  return hash;
256 }
257 
258 
259 void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname )
260 {
261  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
262  wxASSERT( (PLUGIN*) row->plugin );
263  row->plugin->FootprintEnumerate( aFootprintNames, row->GetFullURI( true ),
264  row->GetProperties() );
265 }
266 
267 
268 void FP_LIB_TABLE::PrefetchLib( const wxString& aNickname )
269 {
270  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
271  wxASSERT( (PLUGIN*) row->plugin );
272  row->plugin->PrefetchLib( row->GetFullURI( true ), row->GetProperties() );
273 }
274 
275 
276 const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname )
277 {
278  FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( findRow( aNickname ) );
279 
280  if( !row )
281  {
282  wxString msg = wxString::Format(
283  _( "fp-lib-table files contain no library with nickname \"%s\"" ),
284  GetChars( aNickname ) );
285 
286  THROW_IO_ERROR( msg );
287  }
288 
289  // We've been 'lazy' up until now, but it cannot be deferred any longer,
290  // instantiate a PLUGIN of the proper kind if it is not already in this
291  // FP_LIB_TABLE_ROW.
292  if( !row->plugin )
293  row->setPlugin( IO_MGR::PluginFind( row->type ) );
294 
295  return row;
296 }
297 
298 
299 static void setLibNickname( MODULE* aModule,
300  const wxString& aNickname, const wxString& aFootprintName )
301 {
302  // The library cannot know its own name, because it might have been renamed or moved.
303  // Therefore footprints cannot know their own library nickname when residing in
304  // a footprint library.
305  // Only at this API layer can we tell the footprint about its actual library nickname.
306  if( aModule )
307  {
308  // remove "const"-ness, I really do want to set nickname without
309  // having to copy the LIB_ID and its two strings, twice each.
310  LIB_ID& fpid = (LIB_ID&) aModule->GetFPID();
311 
312  // Catch any misbehaving plugin, which should be setting internal footprint name properly:
313  wxASSERT( aFootprintName == fpid.GetLibItemName().wx_str() );
314 
315  // and clearing nickname
316  wxASSERT( !fpid.GetLibNickname().size() );
317 
318  fpid.SetLibNickname( aNickname );
319  }
320 }
321 
322 
323 MODULE* FP_LIB_TABLE::LoadEnumeratedFootprint( const wxString& aNickname,
324  const wxString& aFootprintName )
325 {
326  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
327  wxASSERT( (PLUGIN*) row->plugin );
328 
329  MODULE* ret = row->plugin->LoadEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
330  row->GetProperties() );
331 
332  setLibNickname( ret, row->GetNickName(), aFootprintName );
333 
334  return ret;
335 }
336 
337 
338 MODULE* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString& aFootprintName )
339 {
340  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
341  wxASSERT( (PLUGIN*) row->plugin );
342 
343  MODULE* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
344  row->GetProperties() );
345 
346  setLibNickname( ret, row->GetNickName(), aFootprintName );
347 
348  return ret;
349 }
350 
351 
353  const MODULE* aFootprint, bool aOverwrite )
354 {
355  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
356  wxASSERT( (PLUGIN*) row->plugin );
357 
358  if( !aOverwrite )
359  {
360  // Try loading the footprint to see if it already exists, caller wants overwrite
361  // protection, which is atypical, not the default.
362 
363  wxString fpname = aFootprint->GetFPID().GetLibItemName();
364 
365  std::unique_ptr<MODULE> footprint( row->plugin->FootprintLoad( row->GetFullURI( true ),
366  fpname, row->GetProperties() ) );
367 
368  if( footprint.get() )
369  return SAVE_SKIPPED;
370  }
371 
372  row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
373 
374  return SAVE_OK;
375 }
376 
377 
378 void FP_LIB_TABLE::FootprintDelete( const wxString& aNickname, const wxString& aFootprintName )
379 {
380  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
381  wxASSERT( (PLUGIN*) row->plugin );
382  return row->plugin->FootprintDelete( row->GetFullURI( true ), aFootprintName,
383  row->GetProperties() );
384 }
385 
386 
387 bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
388 {
389  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
390  wxASSERT( (PLUGIN*) row->plugin );
391  return row->plugin->IsFootprintLibWritable( row->GetFullURI( true ) );
392 }
393 
394 
395 void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
396 {
397  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
398  wxASSERT( (PLUGIN*) row->plugin );
399  row->plugin->FootprintLibDelete( row->GetFullURI( true ), row->GetProperties() );
400 }
401 
402 
403 void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
404 {
405  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
406  wxASSERT( (PLUGIN*) row->plugin );
407  row->plugin->FootprintLibCreate( row->GetFullURI( true ), row->GetProperties() );
408 }
409 
410 
412 {
413  wxString nickname = aFootprintId.GetLibNickname();
414  wxString fpname = aFootprintId.GetLibItemName();
415 
416  if( nickname.size() )
417  {
418  return FootprintLoad( nickname, fpname );
419  }
420 
421  // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
422  else
423  {
424  std::vector<wxString> nicks = GetLogicalLibs();
425 
426  // Search each library going through libraries alphabetically.
427  for( unsigned i = 0; i < nicks.size(); ++i )
428  {
429  // FootprintLoad() returns NULL on not found, does not throw exception
430  // unless there's an IO_ERROR.
431  MODULE* ret = FootprintLoad( nicks[i], fpname );
432 
433  if( ret )
434  return ret;
435  }
436 
437  return NULL;
438  }
439 }
440 
441 
443 {
444  return "KISYSMOD";
445 }
446 
447 
449 {
450  bool tableExists = true;
451  wxFileName fn = GetGlobalTableFileName();
452 
453  if( !fn.FileExists() )
454  {
455  tableExists = false;
456 
457  if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
458  {
459  THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path \"%s\"." ),
460  GetChars( fn.GetPath() ) ) );
461  }
462 
463  // Attempt to copy the default global file table from the KiCad
464  // template folder to the user's home configuration path.
465  wxString fileName = Kiface().KifaceSearch().FindValidPath( global_tbl_name );
466 
467  // The fallback is to create an empty global footprint table for the user to populate.
468  if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
469  {
470  FP_LIB_TABLE emptyTable;
471 
472  emptyTable.Save( fn.GetFullPath() );
473  }
474  }
475 
476  aTable.Load( fn.GetFullPath() );
477 
478  return tableExists;
479 }
480 
481 
483 {
484  wxFileName fn;
485 
486  fn.SetPath( GetKicadConfigPath() );
487  fn.SetName( global_tbl_name );
488 
489  return fn.GetFullPath();
490 }
void setPlugin(PLUGIN *aPlugin)
Definition: fp_lib_table.h:93
static const wxChar global_tbl_name[]
bool IsFootprintLibWritable(const wxString &aNickname)
Function IsFootprintLibWritable.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE...
virtual void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Return a list of footprint names contained within the library at aLibraryPath.
Definition: plugin.cpp:61
virtual long long GetLibraryTimestamp(const wxString &aLibraryPath) const =0
Generate a timestamp representing all the files in the library (including the library directory)...
virtual void PrefetchLib(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Function PrefetchLib If possible, prefetches the specified library (e.g.
Definition: plugin.cpp:69
Class FP_LIB_TABLE_ROW.
Definition: fp_lib_table.h:42
const PROPERTIES * GetProperties() const
Return the constant PROPERTIES for this library (LIB_TABLE_ROW).
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
MODULE * LoadEnumeratedFootprint(const wxString &aNickname, const wxString &aFootprintName)
Function LoadEnumeratedFootprint.
MODULE * FootprintLoad(const wxString &aNickname, const wxString &aFootprintName)
Function FootprintLoad.
virtual void FootprintSave(const wxString &aLibraryPath, const MODULE *aFootprint, const PROPERTIES *aProperties=NULL)
Function FootprintSave will write aModule to an existing library located at aLibraryPath.
Definition: plugin.cpp:94
FP_LIB_TABLE(FP_LIB_TABLE *aFallBackTable=NULL)
Constructor FP_LIB_TABLE.
Class OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a conve...
Definition: richio.h:327
bool operator==(const FP_LIB_TABLE &aFpTable) const
LIB_TABLE_ROWS rows
std::string::size_type size() const
Definition: utf8.h:115
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
void FootprintLibDelete(const wxString &aNickname)
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
PLUGIN::RELEASER plugin
Definition: fp_lib_table.h:98
long long GenerateTimestamp(const wxString *aNickname)
Generate a hashed timestamp representing the last-mod-times of the library indicated by aNickname...
virtual bool IsFootprintLibWritable(const wxString &aLibraryPath)
Function IsFootprintLibWritable returns true iff the library at aLibraryPath is writable.
Definition: plugin.cpp:123
const LIB_ID & GetFPID() const
Definition: class_module.h:191
SEARCH_STACK & KifaceSearch()
Only for DSO specific &#39;non-library&#39; files.
Definition: kiface_i.h:127
wxString wx_str() const
Definition: utf8.cpp:48
static const wxString GlobalPathEnvVariableName()
Function GlobalPathEnvVarVariableName.
virtual void Parse(LIB_TABLE_LEXER *aLexer) override
Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate LIB_TABLE_ROW objec...
virtual MODULE * FootprintLoad(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function FootprintLoad loads a footprint having aFootprintName from the aLibraryPath containing a lib...
Definition: plugin.cpp:85
static bool LoadGlobalTable(FP_LIB_TABLE &aTable)
Function LoadGlobalTable loads the global footprint library table into aTable.
virtual bool FootprintLibDelete(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Function FootprintLibDelete deletes an existing footprint library and returns true, or if library does not exist returns false, or throws an exception if library exists but is read only or cannot be deleted for some other reason.
Definition: plugin.cpp:115
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Function EnumFromStr returns the PCB_FILE_T from the corresponding plugin type name: "kicad"...
Definition: io_mgr.cpp:93
const UTF8 & GetLibItemName() const
Definition: lib_id.h:118
void PrefetchLib(const wxString &aNickname)
Function PrefetchLib If possible, prefetches the specified library (e.g.
bool operator==(const LIB_TABLE_ROW &r) const
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
bool operator==(const FP_LIB_TABLE_ROW &aRow) const
LIB_TABLE_ROW * findRow(const wxString &aNickname) const
Return a LIB_TABLE_ROW if aNickname is found in this table or in any chained fallBack table fragment...
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
wxString GetKicadConfigPath()
Return the user configuration path used to store KiCad&#39;s configuration files.
Definition: common.cpp:211
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indention level of aIndentLevel.
int SetLibNickname(const UTF8 &aNickname)
Override the logical library name portion of the LIB_ID to aNickname.
Definition: lib_id.cpp:219
void FootprintLibCreate(const wxString &aNickname)
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName)
Function FindRow.
SAVE_T
Enum SAVE_T is the set of return values from FootprintSave() below.
Definition: fp_lib_table.h:200
const wxString & GetNickName() const
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
LIB_TABLE_ROWS::const_iterator LIB_TABLE_ROWS_CITER
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
virtual MODULE * LoadEnumeratedFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function LoadEnumeratedFootprint a version of FootprintLoad() for use after FootprintEnumerate() for ...
Definition: plugin.cpp:76
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Function PluginFind returns a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
Class PLUGIN is a base class that BOARD loading and saving plugins should derive from.
Definition: io_mgr.h:266
size_t i
Definition: json11.cpp:597
virtual void FootprintDelete(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function FootprintDelete deletes aFootprintName from the library at aLibraryPath. ...
Definition: plugin.cpp:101
The common library.
virtual void FootprintLibCreate(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Function FootprintLibCreate creates a new empty footprint library at aLibraryPath empty...
Definition: plugin.cpp:108
static void setLibNickname(MODULE *aModule, const wxString &aNickname, const wxString &aFootprintName)
MODULE * FootprintLoadWithOptionalNickname(const LIB_ID &aFootprintId)
Function FootprintLoadWithOptionalNickname loads a footprint having aFootprintId with possibly an emp...
wxString FindValidPath(const wxString &aFileName) const
Definition: search_stack.h:71
Module description (excepted pads)
void SetType(const wxString &aType) override
Function SetType.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:404
void FootprintEnumerate(wxArrayString &aFootprintNames, const wxString &aNickname)
Return a list of footprint names contained within the library given by aNickname. ...
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:101
SAVE_T FootprintSave(const wxString &aNickname, const MODULE *aFootprint, bool aOverwrite=true)
Function FootprintSave.
void FootprintDelete(const wxString &aNickname, const wxString &aFootprintName)
Function FootprintDelete.
PCB_FILE_T
Enum PCB_FILE_T is a set of file types that the IO_MGR knows about, and for which there has been a pl...
Definition: io_mgr.h:52
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
static wxString GetGlobalTableFileName()
Function GetGlobalTableFileName.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE...
S-expression Pcbnew file format.
Definition: io_mgr.h:55
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.