KiCad PCB EDA Suite
netlist_exporter_spice.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) 1992-2013 jp.charras at wanadoo.fr
5 * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 1992-2022 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#include <sim/kibis/kibis.h>
30#include <sim/spice_grammar.h>
31#include <common.h>
32#include <confirm.h>
33#include <pgm_base.h>
34#include <env_paths.h>
35#include <sim/sim_library.h>
37#include <sim/sim_model_kibis.h>
38#include <sim/sim_model.h>
39#include <sch_screen.h>
40#include <sch_text.h>
41#include <sch_textbox.h>
42#include <string_utils.h>
43
45#include <boost/algorithm/string/replace.hpp>
46#include <fmt/core.h>
47#include <paths.h>
48#include <pegtl.hpp>
49#include <pegtl/contrib/parse_tree.hpp>
50#include <wx/dir.h>
51#include <locale_io.h>
52
54{
55 using namespace SPICE_GRAMMAR;
56
57 struct textGrammar : must<spiceSourceNothrow> {};
58
59 template <typename Rule> struct textSelector : std::false_type {};
60 template <> struct textSelector<modelUnit> : std::true_type {};
61
62 template <> struct textSelector<dotControl> : std::true_type {};
63
64 template <> struct textSelector<dotTitle> : std::true_type {};
65 template <> struct textSelector<dotTitleTitle> : std::true_type {};
66
67 template <> struct textSelector<dotInclude> : std::true_type {};
68 template <> struct textSelector<dotIncludePathWithoutQuotes> : std::true_type {};
69 template <> struct textSelector<dotIncludePathWithoutApostrophes> : std::true_type {};
70 template <> struct textSelector<dotIncludePath> : std::true_type {};
71
72 template <> struct textSelector<kLine> : std::true_type {};
73
74 template <> struct textSelector<dotLine> : std::true_type {};
75}
76
77
78std::string NAME_GENERATOR::Generate( const std::string& aProposedName )
79{
80 if( !m_names.count( aProposedName ) )
81 return aProposedName;
82
83 for( uint64_t i = 1; i < UINT64_MAX; ++i )
84 {
85 std::string name = fmt::format( "{}#{}", aProposedName, i );
86
87 if( !m_names.count( name ) )
88 return name;
89 }
90
91 // Should never happen.
92 THROW_IO_ERROR( wxString::Format( _( "Failed to generate a name for '%s': exceeded UINT64_MAX" ),
93 aProposedName ) );
94}
95
96
98 NETLIST_EXPORTER_BASE( aSchematic ),
99 m_libMgr( aSchematic->Prj() )
100{
101}
102
103
104bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions,
105 REPORTER& aReporter )
106{
107 FILE_OUTPUTFORMATTER formatter( aOutFileName, wxT( "wt" ), '\'' );
108 return DoWriteNetlist( formatter, aNetlistOptions, aReporter );
109}
110
111
112bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
113 REPORTER& aReporter )
114{
116
117 // Cleanup list to avoid duplicate if the netlist exporter is run more than once.
118 m_rawIncludes.clear();
119
120 // Default title.
121 m_title = "KiCad schematic";
122
123 if( !ReadSchematicAndLibraries( aNetlistOptions, aReporter ) )
124 return false;
125
126 WriteHead( aFormatter, aNetlistOptions );
127
128 writeIncludes( aFormatter, aNetlistOptions );
129 writeModels( aFormatter );
130
131 // Skip this if there is no netlist to avoid an ngspice segfault
132 if( !m_items.empty() )
133 WriteDirectives( aFormatter, aNetlistOptions );
134
135 writeItems( aFormatter );
136
137 WriteTail( aFormatter, aNetlistOptions );
138
139 return true;
140}
141
142
143void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
144{
145 aFormatter.Print( 0, ".title %s\n", m_title.c_str() );
146}
147
148
149void NETLIST_EXPORTER_SPICE::WriteTail( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
150{
151 aFormatter.Print( 0, ".end\n" );
152}
153
154
156 REPORTER& aReporter )
157{
158 wxString msg;
159 std::set<std::string> refNames; // Set of reference names to check for duplication.
160 int ncCounter = 1;
161
162 ReadDirectives( aNetlistOptions, aReporter );
163
164 m_nets.clear();
165 m_items.clear();
166 m_libParts.clear();
167
168 wxFileName cacheDir;
169 cacheDir.AssignDir( PATHS::GetUserCachePath() );
170 cacheDir.AppendDir( wxT( "ibis" ) );
171
172 if( !cacheDir.DirExists() )
173 {
174 cacheDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
175
176 if( !cacheDir.DirExists() )
177 {
178 wxLogTrace( wxT( "IBIS_CACHE:" ),
179 wxT( "%s:%s:%d\n * failed to create ibis cache directory '%s'" ),
180 __FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
181
182 return false;
183 }
184 }
185
186 wxDir dir;
187 wxString dirName = cacheDir.GetFullPath();
188
189 if( !dir.Open( dirName ) )
190 return false;
191
192 wxFileName thisFile;
193 wxArrayString fileList;
194 wxString fileSpec = wxT( "*.cache" );
195
196 thisFile.SetPath( dirName ); // Set the base path to the cache folder
197
198 int numFilesFound = dir.GetAllFiles( dirName, &fileList, fileSpec );
199
200 for( int i = 0; i < numFilesFound; i++ )
201 {
202 // Completes path to specific file so we can get its "last access" date
203 thisFile.SetFullName( fileList[i] );
204 wxRemoveFile( thisFile.GetFullPath() );
205 }
206
207 for( SCH_SHEET_PATH& sheet : GetSheets( aNetlistOptions ) )
208 {
209 for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
210 {
211 SCH_SYMBOL* symbol = findNextSymbol( item, &sheet );
212
213 if( !symbol || symbol->GetFieldText( SIM_MODEL::ENABLE_FIELD ) == wxT( "0" ) )
214 continue;
215
216 CreatePinList( symbol, &sheet, true );
217
218 SPICE_ITEM spiceItem;
219
220 // This is a little bit dangerous as any value fetched from the fields will not
221 // be instance-data aware, and will just fetch the value of some random sheet
222 // (whatever sheet the user happens to be looking at). However, we currently only
223 // use it to fetch "Sim_*" fields, which have no instance data.
224 spiceItem.fields = &symbol->GetFields();
225
226 try
227 {
228 if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
229 return false;
230
231 readModel( sheet, *symbol, spiceItem );
232
233 readPinNumbers( *symbol, spiceItem );
234 readPinNetNames( *symbol, spiceItem, ncCounter );
235
236 // TODO: transmission line handling?
237
238 m_items.push_back( std::move( spiceItem ) );
239 }
240 catch( const IO_ERROR& e )
241 {
242 msg.Printf( _( "Error reading simulation model from symbol '%s':\n%s" ),
243 symbol->GetRef( &sheet ),
244 e.What() );
245 aReporter.Report( msg, RPT_SEVERITY_ERROR );
246 }
247 }
248 }
249
250 return !aReporter.HasMessage();
251}
252
253
255{
256 boost::replace_all( aNetName, "(", "_" );
257 boost::replace_all( aNetName, ")", "_" );
258 boost::replace_all( aNetName, " ", "_" );
259}
260
261
262std::string NETLIST_EXPORTER_SPICE::GetItemName( const std::string& aRefName ) const
263{
264 const SPICE_ITEM* item = FindItem( aRefName );
265
266 if( !item )
267 return "";
268
269 return item->model->SpiceGenerator().ItemName( *item );
270}
271
272
273const SPICE_ITEM* NETLIST_EXPORTER_SPICE::FindItem( const std::string& aRefName ) const
274{
275 const std::list<SPICE_ITEM>& spiceItems = GetItems();
276
277 auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
278 [aRefName]( const SPICE_ITEM& item )
279 {
280 return item.refName == aRefName;
281 } );
282
283 if( it != spiceItems.end() )
284 return &*it;
285
286 return nullptr;
287}
288
289
290void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions, REPORTER& aReporter )
291{
292 wxString msg;
293 wxString text;
294
295 m_directives.clear();
296
297 for( const SCH_SHEET_PATH& sheet : GetSheets( aNetlistOptions ) )
298 {
299 for( SCH_ITEM* item : sheet.LastScreen()->Items() )
300 {
301 if( item->Type() == SCH_TEXT_T )
302 text = static_cast<SCH_TEXT*>( item )->GetShownText();
303 else if( item->Type() == SCH_TEXTBOX_T )
304 text = static_cast<SCH_TEXTBOX*>( item )->GetShownText();
305 else
306 continue;
307
308 tao::pegtl::string_input<> in( text.ToUTF8(), "from_content" );
309 std::unique_ptr<tao::pegtl::parse_tree::node> root;
310
311 try
312 {
315 tao::pegtl::nothing,
317 ( in );
318 }
319 catch( const tao::pegtl::parse_error& )
320 {
321 continue;
322 }
323
324 wxASSERT( root );
325
326 for( const auto& node : root->children )
327 {
328 if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotTitle>() )
329 {
330 m_title = node->children.at( 0 )->string();
331 }
332 else if( node->is_type<NETLIST_EXPORTER_SPICE_PARSER::dotInclude>() )
333 {
334 std::string path = node->children.at( 0 )->string();
335
336 try
337 {
339 }
340 catch( const IO_ERROR& e )
341 {
342 msg.Printf( _( "Error reading simulation model library '%s':\n%s" ),
343 path,
344 e.What() );
345 aReporter.Report( msg, RPT_SEVERITY_ERROR );
346 }
347 }
348 else
349 {
350 m_directives.emplace_back( node->string() );
351 }
352 }
353 }
354 }
355}
356
357
359 SPICE_ITEM& aItem,
360 std::set<std::string>& aRefNames )
361{
362 aItem.refName = aSymbol.GetRef( &aSheet );
363
364 if( !aRefNames.insert( aItem.refName ).second )
365 wxASSERT( wxT( "Duplicate refdes encountered; what happened to ReadyToNetlist()?" ) );
366
367 return true;
368}
369
370
372 SPICE_ITEM& aItem )
373{
374 SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( aSymbol );
375
376 aItem.baseModelName = libModel.name;
377 aItem.model = &libModel.model;
378
379 std::string modelName = aItem.model->SpiceGenerator().ModelName( aItem );
380 // Resolve model name collisions.
382
383 // FIXME: Don't have special cases for raw Spice models and KIBIS.
384 if( auto rawSpiceModel = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model ) )
385 {
386 int libParamIndex = static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
387 std::string path = rawSpiceModel->GetParam( libParamIndex ).value->ToString();
388
389 if( path != "" )
390 m_rawIncludes.insert( path );
391 }
392 else if( auto kibisModel = dynamic_cast<const SIM_MODEL_KIBIS*>( aItem.model ) )
393 {
394 wxFileName cacheDir;
395 cacheDir.AssignDir( PATHS::GetUserCachePath() );
396 cacheDir.AppendDir( wxT( "ibis" ) );
397
398 std::string libraryPath = fmt::format( "{}/{}.cache",
399 std::string( cacheDir.GetPath() ),
400 std::string( aSymbol.GetRef( &aSheet ) ) );
401 wxFile cacheFile( libraryPath, wxFile::write );
402
403 if( !cacheFile.IsOpened() )
404 {
405 DisplayErrorMessage( nullptr,
406 wxString::Format( _( "Could not open file '%s' to write IBIS model" ),
407 libraryPath ) );
408 }
409
410 auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
411 std::string modelData = spiceGenerator.IbisDevice(
412 aItem, std::string( m_schematic->Prj().GetProjectPath().c_str() ),
413 std::string( cacheDir.GetPath( wxPATH_GET_SEPARATOR ) ).c_str() );
414
415 cacheFile.Write( wxString( modelData ) );
416 m_rawIncludes.insert( libraryPath );
417 }
418}
419
420
422{
423 for( const PIN_INFO& pin : m_sortedSymbolPinList )
424 aItem.pinNumbers.emplace_back( std::string( pin.num.ToUTF8() ) );
425}
426
427
429 int& aNcCounter )
430{
431 for( const PIN_INFO& pinInfo : m_sortedSymbolPinList )
432 {
433 std::string netName = GenerateItemPinNetName( std::string( pinInfo.netName.ToUTF8() ),
434 aNcCounter );
435
436 aItem.pinNetNames.push_back( netName );
437 m_nets.insert( netName );
438 }
439}
440
441
442void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
443 const std::string& aPath )
444{
445 // First, expand env vars, if any.
446 wxString expandedPath = ExpandEnvVarSubstitutions( aPath, &m_schematic->Prj() );
447 wxString fullPath;
448
449 if( aNetlistOptions & OPTION_ADJUST_INCLUDE_PATHS )
450 {
451 // Look for the library in known search locations.
452 fullPath = ResolveFile( expandedPath, &Pgm().GetLocalEnvVariables(),
453 &m_schematic->Prj() );
454
455 if( fullPath.IsEmpty() )
456 {
457 DisplayErrorMessage( nullptr,
458 wxString::Format( _( "Could not find library file '%s'" ),
459 expandedPath ) );
460 fullPath = expandedPath;
461 }
462 }
463 else
464 {
465 fullPath = expandedPath;
466 }
467
468 aFormatter.Print( 0, ".include \"%s\"\n", TO_UTF8( fullPath ) );
469}
470
471
472void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
473{
474 for( auto&& [path, library] : m_libMgr.GetLibraries() )
475 {
476 if( dynamic_cast<const SIM_LIBRARY_SPICE*>( &library.get() ) )
477 writeInclude( aFormatter, aNetlistOptions, path );
478 }
479
480 for( const std::string& path : m_rawIncludes )
481 writeInclude( aFormatter, aNetlistOptions, path );
482}
483
484
486{
487 for( const SPICE_ITEM& item : m_items )
488 {
489 if( !item.model->IsEnabled() )
490 continue;
491
492 aFormatter.Print( 0, "%s", item.model->SpiceGenerator().ModelLine( item ).c_str() );
493 }
494}
495
496
498{
499 for( const SPICE_ITEM& item : m_items )
500 {
501 if( !item.model->IsEnabled() )
502 continue;
503
504 aFormatter.Print( 0, "%s", item.model->SpiceGenerator().ItemLine( item ).c_str() );
505 }
506}
507
508
510 unsigned aNetlistOptions ) const
511{
512 if( aNetlistOptions & OPTION_SAVE_ALL_VOLTAGES )
513 aFormatter.Print( 0, ".save all\n" );
514
515 if( aNetlistOptions & OPTION_SAVE_ALL_CURRENTS )
516 aFormatter.Print( 0, ".probe alli\n" );
517
518 for( const std::string& directive : m_directives )
519 aFormatter.Print( 0, "%s\n", directive.c_str() );
520}
521
522
523std::string NETLIST_EXPORTER_SPICE::GenerateItemPinNetName( const std::string& aNetName,
524 int& aNcCounter ) const
525{
526 std::string netName = aNetName;
527
528 ReplaceForbiddenChars( netName );
529 netName = std::string( UnescapeString( netName ).ToUTF8() );
530
531 if( netName == "" )
532 netName = fmt::format( "NC-{}", aNcCounter++ );
533
534 return netName;
535}
536
537
538SCH_SHEET_LIST NETLIST_EXPORTER_SPICE::GetSheets( unsigned aNetlistOptions ) const
539{
540 if( aNetlistOptions & OPTION_CUR_SHEET_AS_ROOT )
541 return SCH_SHEET_LIST( m_schematic->CurrentSheet().at( 0 ) );
542 else
543 return m_schematic->GetSheets();
544}
545
const char * name
Definition: DXF_plotter.cpp:56
Used for text file output.
Definition: richio.h:457
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
std::unordered_set< std::string > m_names
std::string Generate(const std::string &aProposedName)
An abstract class used for the netlist exporters that Eeschema supports.
void CreatePinList(SCH_SYMBOL *aSymbol, SCH_SHEET_PATH *aSheetPath, bool aKeepUnconnectedPins)
Find a symbol from the DrawList and builds its pin list in m_sortedSymbolPinList.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
SCH_SYMBOL * findNextSymbol(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Check if the given symbol should be processed for netlisting.
SCHEMATIC_IFACE * m_schematic
The schematic we're generating a netlist for.
std::vector< PIN_INFO > m_sortedSymbolPinList
Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic...
bool DoWriteNetlist(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions, REPORTER &aReporter)
Write the netlist in aFormatter.
void writeModels(OUTPUTFORMATTER &aFormatter)
void writeIncludes(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions)
std::list< SPICE_ITEM > m_items
Items representing schematic symbols in Spice world.
static void ReplaceForbiddenChars(std::string &aNetName)
Replace illegal spice net name characters with underscores.
virtual void WriteDirectives(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions) const
std::string GetItemName(const std::string &aRefName) const
Return name of Spice device corresponding to a schematic symbol.
std::string m_title
Spice simulation title found in the schematic sheet.
void writeInclude(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions, const std::string &aPath)
SCH_SHEET_LIST GetSheets(unsigned aNetlistOptions=0) const
Return the paths of exported sheets (either all or the current one).
std::vector< std::string > m_directives
Spice directives found in the schematic sheet.
void ReadDirectives(unsigned aNetlistOptions, REPORTER &aReporter)
void writeItems(OUTPUTFORMATTER &aFormatter)
virtual void WriteHead(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions)
Write the netlist head (title and so on).
virtual std::string GenerateItemPinNetName(const std::string &aNetName, int &aNcCounter) const
const SPICE_ITEM * FindItem(const std::string &aRefName) const
Find and return the item corresponding to aRefName.
SIM_LIB_MGR m_libMgr
Holds libraries and models.
std::set< std::string > m_rawIncludes
include directives found in symbols
void readPinNumbers(SCH_SYMBOL &aSymbol, SPICE_ITEM &aItem)
virtual bool ReadSchematicAndLibraries(unsigned aNetlistOptions, REPORTER &aReporter)
Process the schematic and Spice libraries to create net mapping and a list of SPICE_ITEMs.
void readPinNetNames(SCH_SYMBOL &aSymbol, SPICE_ITEM &aItem, int &aNcCounter)
std::set< std::string > m_nets
const std::list< SPICE_ITEM > & GetItems() const
Return the list of items representing schematic symbols in the Spice world.
bool readRefName(SCH_SHEET_PATH &aSheet, SCH_SYMBOL &aSymbol, SPICE_ITEM &aItem, std::set< std::string > &aRefNames)
virtual void WriteTail(OUTPUTFORMATTER &aFormatter, unsigned aNetlistOptions)
Write the tail (.end).
NAME_GENERATOR m_modelNameGenerator
Generates unique model names.
NETLIST_EXPORTER_SPICE(SCHEMATIC_IFACE *aSchematic)
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write to specified output file.
void readModel(SCH_SHEET_PATH &aSheet, SCH_SYMBOL &aSymbol, SPICE_ITEM &aItem)
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:310
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:431
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:321
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:126
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual bool HasMessage() const =0
Returns true if the reporter client is non-empty.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
virtual SCH_SHEET_LIST GetSheets() const =0
virtual SCH_SHEET_PATH & CurrentSheet() const =0
virtual PROJECT & Prj() const =0
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * at(size_t aIndex) const
Forwarded method from std::vector.
Schematic symbol object.
Definition: sch_symbol.h:80
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:624
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:824
wxString GetFieldText(const wxString &aFieldName) const
Search for a field named aFieldName and returns text associated with this field.
Definition: sch_symbol.cpp:812
wxString GetShownText(int aDepth=0, bool aAllowExtraText=true) const override
Return the string actually shown after processing of the base text.
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, int aSymbolPinCount)
Definition: sim_lib_mgr.cpp:70
std::map< std::string, std::reference_wrapper< const SIM_LIBRARY > > GetLibraries() const
SIM_LIBRARY & CreateLibrary(const std::string &aLibraryPath, REPORTER *aReporter=nullptr)
Definition: sim_lib_mgr.cpp:47
static constexpr auto ENABLE_FIELD
Definition: sim_model.h:61
const SPICE_GENERATOR & SpiceGenerator() const
Definition: sim_model.h:417
std::string IbisDevice(const SPICE_ITEM &aItem, const std::string aCwd, const std::string aCacheDir) const
virtual std::string ItemName(const SPICE_ITEM &aItem) const
virtual std::string ModelName(const SPICE_ITEM &aItem) const
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:267
The common library.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299
This file is part of the common library.
#define _(s)
wxString ResolveFile(const wxString &aFileName, const ENV_VAR_MAP *aEnvVars, const PROJECT *aProject)
Search the default paths trying to find one with the requested file.
Definition: env_paths.cpp:164
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
PROJECT & Prj()
Definition: kicad.cpp:556
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
must_if< error >::control< Rule > control
bool parse(std::istream &aStream, bool aVerbose)
Parse a PCB or footprint file from the given input stream.
see class PGM_BASE
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ RPT_SEVERITY_ERROR
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:74
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
wxString UnescapeString(const wxString &aSource)
SIM_MODEL & model
Definition: sim_library.h:41
std::string name
Definition: sim_library.h:40
std::string refName
std::string modelName
const SIM_MODEL * model
const std::vector< SCH_FIELD > * fields
std::vector< std::string > pinNetNames
std::string baseModelName
std::vector< std::string > pinNumbers
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ SCH_TEXT_T
Definition: typeinfo.h:150
@ SCH_TEXTBOX_T
Definition: typeinfo.h:149