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-2018 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 ) ) + wxHashTable::MakeKey( *aNickname );
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 ) ) + wxHashTable::MakeKey( nickname );
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  // Do not optimize this code. Is done this way specifically to fix a runtime
279  // error with clang 4.0.1.
280  LIB_TABLE_ROW* ltrow = findRow( aNickname );
281  FP_LIB_TABLE_ROW* row = dynamic_cast< FP_LIB_TABLE_ROW* >( ltrow );
282 
283  if( !row )
284  {
285  wxString msg = wxString::Format(
286  _( "fp-lib-table files contain no library with nickname \"%s\"" ),
287  GetChars( aNickname ) );
288 
289  THROW_IO_ERROR( msg );
290  }
291 
292  // We've been 'lazy' up until now, but it cannot be deferred any longer,
293  // instantiate a PLUGIN of the proper kind if it is not already in this
294  // FP_LIB_TABLE_ROW.
295  if( !row->plugin )
296  row->setPlugin( IO_MGR::PluginFind( row->type ) );
297 
298  return row;
299 }
300 
301 
302 static void setLibNickname( MODULE* aModule,
303  const wxString& aNickname, const wxString& aFootprintName )
304 {
305  // The library cannot know its own name, because it might have been renamed or moved.
306  // Therefore footprints cannot know their own library nickname when residing in
307  // a footprint library.
308  // Only at this API layer can we tell the footprint about its actual library nickname.
309  if( aModule )
310  {
311  // remove "const"-ness, I really do want to set nickname without
312  // having to copy the LIB_ID and its two strings, twice each.
313  LIB_ID& fpid = (LIB_ID&) aModule->GetFPID();
314 
315  // Catch any misbehaving plugin, which should be setting internal footprint name properly:
316  wxASSERT( aFootprintName == fpid.GetLibItemName().wx_str() );
317 
318  // and clearing nickname
319  wxASSERT( !fpid.GetLibNickname().size() );
320 
321  fpid.SetLibNickname( aNickname );
322  }
323 }
324 
325 
326 const MODULE* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname,
327  const wxString& aFootprintName )
328 {
329  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
330  wxASSERT( (PLUGIN*) row->plugin );
331 
332  return row->plugin->GetEnumeratedFootprint( row->GetFullURI( true ), aFootprintName,
333  row->GetProperties() );
334 }
335 
336 
337 bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName )
338 {
339  try
340  {
341  std::unique_ptr<MODULE> m( FootprintLoad( aNickname, aFootprintName ) );
342  return m.get() != nullptr;
343  }
344  catch( ... )
345  {
346  return false;
347  }
348 }
349 
350 
351 MODULE* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString& aFootprintName )
352 {
353  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
354  wxASSERT( (PLUGIN*) row->plugin );
355 
356  MODULE* ret = row->plugin->FootprintLoad( row->GetFullURI( true ), aFootprintName,
357  row->GetProperties() );
358 
359  setLibNickname( ret, row->GetNickName(), aFootprintName );
360 
361  return ret;
362 }
363 
364 
366  const MODULE* aFootprint, bool aOverwrite )
367 {
368  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
369  wxASSERT( (PLUGIN*) row->plugin );
370 
371  if( !aOverwrite )
372  {
373  // Try loading the footprint to see if it already exists, caller wants overwrite
374  // protection, which is atypical, not the default.
375 
376  wxString fpname = aFootprint->GetFPID().GetLibItemName();
377 
378  std::unique_ptr<MODULE> footprint( row->plugin->FootprintLoad( row->GetFullURI( true ),
379  fpname, row->GetProperties() ) );
380 
381  if( footprint.get() )
382  return SAVE_SKIPPED;
383  }
384 
385  row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
386 
387  return SAVE_OK;
388 }
389 
390 
391 void FP_LIB_TABLE::FootprintDelete( const wxString& aNickname, const wxString& aFootprintName )
392 {
393  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
394  wxASSERT( (PLUGIN*) row->plugin );
395  return row->plugin->FootprintDelete( row->GetFullURI( true ), aFootprintName,
396  row->GetProperties() );
397 }
398 
399 
400 bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
401 {
402  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
403  wxASSERT( (PLUGIN*) row->plugin );
404  return row->plugin->IsFootprintLibWritable( row->GetFullURI( true ) );
405 }
406 
407 
408 void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
409 {
410  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
411  wxASSERT( (PLUGIN*) row->plugin );
412  row->plugin->FootprintLibDelete( row->GetFullURI( true ), row->GetProperties() );
413 }
414 
415 
416 void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
417 {
418  const FP_LIB_TABLE_ROW* row = FindRow( aNickname );
419  wxASSERT( (PLUGIN*) row->plugin );
420  row->plugin->FootprintLibCreate( row->GetFullURI( true ), row->GetProperties() );
421 }
422 
423 
425 {
426  wxString nickname = aFootprintId.GetLibNickname();
427  wxString fpname = aFootprintId.GetLibItemName();
428 
429  if( nickname.size() )
430  {
431  return FootprintLoad( nickname, fpname );
432  }
433 
434  // nickname is empty, sequentially search (alphabetically) all libs/nicks for first match:
435  else
436  {
437  std::vector<wxString> nicks = GetLogicalLibs();
438 
439  // Search each library going through libraries alphabetically.
440  for( unsigned i = 0; i < nicks.size(); ++i )
441  {
442  // FootprintLoad() returns NULL on not found, does not throw exception
443  // unless there's an IO_ERROR.
444  MODULE* ret = FootprintLoad( nicks[i], fpname );
445 
446  if( ret )
447  return ret;
448  }
449 
450  return NULL;
451  }
452 }
453 
454 
456 {
457  return "KISYSMOD";
458 }
459 
460 
462 {
463  bool tableExists = true;
464  wxFileName fn = GetGlobalTableFileName();
465 
466  if( !fn.FileExists() )
467  {
468  tableExists = false;
469 
470  if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
471  {
472  THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path \"%s\"." ),
473  GetChars( fn.GetPath() ) ) );
474  }
475 
476  // Attempt to copy the default global file table from the KiCad
477  // template folder to the user's home configuration path.
478  wxString fileName = Kiface().KifaceSearch().FindValidPath( global_tbl_name );
479 
480  // The fallback is to create an empty global footprint table for the user to populate.
481  if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
482  {
483  FP_LIB_TABLE emptyTable;
484 
485  emptyTable.Save( fn.GetFullPath() );
486  }
487  }
488 
489  aTable.Load( fn.GetFullPath() );
490 
491  return tableExists;
492 }
493 
494 
496 {
497  wxFileName fn;
498 
499  fn.SetPath( GetKicadConfigPath() );
500  fn.SetName( global_tbl_name );
501 
502  return fn.GetFullPath();
503 }
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:60
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:68
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 * 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:93
FP_LIB_TABLE(FP_LIB_TABLE *aFallBackTable=NULL)
Constructor FP_LIB_TABLE.
virtual const MODULE * GetEnumeratedFootprint(const wxString &aLibraryPath, const wxString &aFootprintName, const PROPERTIES *aProperties=NULL)
Function GetEnumeratedFootprint a version of FootprintLoad() for use after FootprintEnumerate() for m...
Definition: plugin.cpp:75
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:124
const LIB_ID & GetFPID() const
Definition: class_module.h:193
SEARCH_STACK & KifaceSearch()
Only for DSO specific &#39;non-library&#39; files.
Definition: kiface_i.h:127
wxString wx_str() const
Definition: utf8.cpp:51
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:84
static bool LoadGlobalTable(FP_LIB_TABLE &aTable)
Function LoadGlobalTable loads the global footprint library table into aTable.
const MODULE * GetEnumeratedFootprint(const wxString &aNickname, const wxString &aFootprintName)
Function GetEnumeratedFootprint.
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:116
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:114
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.
#define THROW_IO_ERROR(msg)
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:263
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:193
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:210
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
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:109
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:73
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:97
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
bool FootprintExists(const wxString &aNickname, const wxString &aFootprintName)
Function FootprintExists.
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.