50 m_exportPath = wxFileName( aOutFileName ).GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR )
51 + wxString(
"devices" );
56 wxString msg = wxString::Format(
_(
"Failed to create directory 'devices' ." ) );
63 if( (
m_f = wxFopen( aOutFileName, wxT(
"wt" ) ) ) ==
nullptr )
65 wxString msg = wxString::Format(
_(
"Failed to create file '%s'." ), aOutFileName );
103 wxString refText1 = aItem1.first->GetRef( &aItem1.second );
104 wxString refText2 = aItem2.first->GetRef( &aItem2.second );
106 if( refText1 == refText2 )
108 return aItem1.second.PathHumanReadable() < aItem2.second.PathHumanReadable();
116 const wxString& aRefText2 )
123 return aRefText1 < aRefText2;
141 for(
unsigned ii = 0; ii < sheetList.size(); ii++ )
149 b->GetRef( &sheet,
false ),
true ) < 0 );
152 std::set<
SCH_SYMBOL*,
decltype( cmp )> ordered_symbols( cmp );
153 std::multiset<
SCH_SYMBOL*,
decltype( cmp )> extra_units( cmp );
158 auto test = ordered_symbols.insert( symbol );
162 if( ( *(
test.first ) )->m_Uuid > symbol->
m_Uuid )
164 extra_units.insert( *(
test.first ) );
165 ordered_symbols.erase(
test.first );
166 ordered_symbols.insert( symbol );
170 extra_units.insert( symbol );
175 for(
EDA_ITEM* item : ordered_symbols )
188 if( !pinList.size() )
195 symbol->
GetRef( &sheet ) ) );
207 NET_RECORD(
const wxString& aName ) :
212 std::vector<NET_NODE> m_Nodes;
215 std::vector<NET_RECORD*> nets;
219 wxString net_name = it.first.Name;
220 const std::vector<CONNECTION_SUBGRAPH*>& subgraphs = it.second;
221 NET_RECORD* net_record =
nullptr;
223 if( subgraphs.empty() )
226 nets.emplace_back(
new NET_RECORD( net_name ) );
227 net_record = nets.back();
231 bool nc = subgraph->GetNoConnect() &&
235 for(
SCH_ITEM* item : subgraph->GetItems() )
247 net_record->m_Nodes.emplace_back(
pin, sheet, nc );
254 std::sort( nets.begin(), nets.end(),
255 [](
const NET_RECORD* a,
const NET_RECORD*b )
257 return StrNumCmp( a->m_Name, b->m_Name ) < 0;
260 for(
int i = 0; i < (int) nets.size(); ++i )
262 NET_RECORD* net_record = nets[i];
265 std::sort( net_record->m_Nodes.begin(), net_record->m_Nodes.end(),
268 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
269 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
272 return a.m_Pin->GetShownNumber() < b.m_Pin->GetShownNumber();
283 wxString refA = a.m_Pin->GetParentSymbol()->GetRef( &a.m_Sheet );
284 wxString refB = b.m_Pin->GetParentSymbol()->GetRef( &b.m_Sheet );
286 return refA == refB && a.m_Pin->GetShownNumber() == b.m_Pin->GetShownNumber();
289 for(
const NET_NODE& netNode : net_record->m_Nodes )
295 if( refText[0] == wxChar(
'#' ) )
300 m_netNameNodes.insert( std::pair<wxString, NET_NODE>( net_record->m_Name, netNode ) );
304 for( NET_RECORD* record : nets )
313 wxString deviceFileCreatingError = wxString(
"" );
326 if( it->first->GetValueFieldText(
false, &it->second,
false )
327 != first_ele.first->GetValueFieldText(
false, &first_ele.second,
false ) )
332 if( it->first->GetFootprintFieldText(
false, &it->second,
false )
333 != first_ele.first->GetFootprintFieldText(
false, &first_ele.second,
false ) )
338 wxString ref1 = it->first->GetRef( &it->second );
339 wxString ref2 = first_ele.first->GetRef( &first_ele.second );
356 ret |= fprintf(
m_f,
"%s\n",
"$PACKAGES" );
358 struct COMP_PACKAGE_STRUCT
361 wxString m_tolerance;
362 std::vector<std::pair<SCH_SYMBOL*, SCH_SHEET_PATH>> m_symbolSheetpaths;
365 COMP_PACKAGE_STRUCT compPackageStruct;
366 std::map<wxString, COMP_PACKAGE_STRUCT> compPackageMap;
368 for(
int groupIndex = 1; groupIndex < groupCount; groupIndex++ )
371 auto beginIter = pairIter.first;
372 auto endIter = pairIter.second;
374 SCH_SYMBOL* sym = ( beginIter->second ).first;
379 wxString deviceType = valueText + wxString(
"_") + footprintText;
381 while( deviceType.GetChar(deviceType.Length()-1) ==
'_' )
383 deviceType.RemoveLast();
388 wxArrayString fieldArray;
389 fieldArray.Add(
"Spice_Model" );
390 fieldArray.Add(
"VALUE" );
395 fieldArray.Add(
"TOLERANCE" );
396 fieldArray.Add(
"TOL" );
399 std::vector<std::pair<SCH_SYMBOL*, SCH_SHEET_PATH>> symbolSheetpaths;
401 for(
auto iter = beginIter; iter != endIter; iter++ )
403 symbolSheetpaths.push_back( std::pair<
SCH_SYMBOL*,
405 iter->second.second ) );
408 std::stable_sort( symbolSheetpaths.begin(), symbolSheetpaths.end(),
411 compPackageStruct.m_value = value;
412 compPackageStruct.m_tolerance = tol;
413 compPackageStruct.m_symbolSheetpaths = symbolSheetpaths;
414 compPackageMap.insert( std::pair( deviceType, compPackageStruct ) );
418 wxString deviceFileName = wxFileName(
m_exportPath, deviceType,
419 wxString(
"txt" ) ).GetFullPath();
421 if( ( d = wxFopen( deviceFileName, wxT(
"wt" ) ) ) ==
nullptr )
424 msg.Printf(
_(
"Failed to create file '%s'.\n" ), deviceFileName );
425 deviceFileCreatingError += msg;
429 footprintText = footprintText.AfterLast(
':' );
431 wxArrayString footprintAlt;
434 for(
const wxString& fp : footprintArray )
436 if( ( fp.Find(
'*' ) != wxNOT_FOUND ) || ( fp.Find(
'?' ) != wxNOT_FOUND ) )
441 footprintAlt.Add( fp.AfterLast(
':' ) );
444 if( footprintText.IsEmpty() )
446 if( !footprintAlt.IsEmpty() )
448 footprintText = footprintAlt[0];
449 footprintAlt.RemoveAt( 0 );
453 footprintText = deviceType;
458 fprintf( d,
"CLASS IC\n" );
473 for(
int ii = 0; ii < (int) pinList.size() - 1; ii++ )
475 if( pinList[ii]->GetNumber() == pinList[ii + 1]->GetNumber() )
478 pinList.erase( pinList.begin() + ii + 1 );
483 unsigned int pinCount = pinList.size();
484 fprintf( d,
"PINCOUNT %u\n", pinCount );
491 if( !value.IsEmpty() )
493 fprintf( d,
"PACKAGEPROP VALUE %s\n",
TO_UTF8( value ) );
498 fprintf( d,
"PACKAGEPROP TOL %s\n",
TO_UTF8( tol ) );
501 if( !footprintAlt.IsEmpty() )
503 fprintf( d,
"PACKAGEPROP ALT_SYMBOLS '(" );
505 wxString footprintAltSymbolsText;
507 for(
const wxString& fp : footprintAlt )
509 footprintAltSymbolsText += fp + wxString(
"," );
512 footprintAltSymbolsText.Truncate( footprintAltSymbolsText.Length() - 1 );
513 fprintf( d,
"%s)'\n",
TO_UTF8( footprintAltSymbolsText ) );
516 wxArrayString propArray;
517 propArray.Add(
"PART_NUMBER" );
518 propArray.Add(
"mpn" );
519 propArray.Add(
"mfr_pn" );
524 fprintf( d,
"PACKAGEPROP %s %s\n",
TO_UTF8( propArray[0] ),
TO_UTF8( data ) );
528 propArray.Add(
"HEIGHT" );
533 fprintf( d,
"PACKAGEPROP %s %s\n",
TO_UTF8( propArray[0] ),
TO_UTF8( data ) );
536 fprintf( d,
"END\n" );
541 for(
auto iter = compPackageMap.begin(); iter != compPackageMap.end(); iter++ )
543 wxString deviceType = iter->first;
544 wxString value = iter->second.m_value;
545 wxString tolerance = iter->second.m_tolerance;
547 if( value.IsEmpty() && tolerance.IsEmpty() )
549 ret |= fprintf(
m_f,
"!%s;",
TO_UTF8( deviceType ) );
551 else if( tolerance.IsEmpty() )
561 std::vector<std::pair<SCH_SYMBOL*, SCH_SHEET_PATH>> symbolSheetpaths =
562 iter->second.m_symbolSheetpaths;
564 for(
auto it = symbolSheetpaths.begin(); it != symbolSheetpaths.end(); it++ )
568 wxString refText = sym->
GetRef( &sheetPath );
569 ret |= fprintf(
m_f,
",\n\t%s",
TO_UTF8( refText ) );
572 ret |= fprintf(
m_f,
"\n" );
575 if( !deviceFileCreatingError.IsEmpty() )
584 if( aString.IsEmpty() )
586 return wxString(
"" );
589 aString.Replace(
"\u03BC",
"u" );
591 std::regex reg(
"[!']|[^ -~]" );
592 wxString processedString = wxString( std::regex_replace( std::string( aString ), reg,
"?" ) );
594 std::regex search_reg(
"[^a-zA-Z0-9_/]" );
596 if( std::regex_search( std::string( processedString ), search_reg ) )
598 return wxString(
"'" ) + processedString + wxString(
"'" );
601 return processedString;
607 wxString pinName4Telesis = aPin.
GetName() + wxString(
"__" ) + aPin.
GetNumber();
608 std::regex reg(
"[^A-Za-z0-9_+?/-]" );
609 return wxString( std::regex_replace( std::string( pinName4Telesis ), reg,
"?" ) );
616 std::list<wxString> pinNameList;
620 for(
auto pin : aPinList )
625 wxString out_str =
"";
628 out_str.Printf( wxT(
"PINORDER %s " ),
TO_UTF8( aName ) );
630 for(
const wxString& pinName : pinNameList )
632 str.Printf(
",\n\t%s",
TO_UTF8( pinName ) );
635 out_str += wxString(
"\n" );
637 str.Printf( wxT(
"FUNCTION %s %s " ),
TO_UTF8( aName ),
TO_UTF8( aName ) );
640 for(
auto pin : aPinList )
642 str.Printf(
",\n\t%s",
TO_UTF8(
pin->GetNumber() ) );
645 out_str += wxString(
"\n" );
656 for(
auto iter = pairIter.first; iter != pairIter.second; ++iter )
661 for(
const wxString& field : aFieldArray )
667 wxString fieldText = fld->
GetShownText( &sheetPath,
true );
669 if( !fieldText.IsEmpty() )
684 for(
auto iter = pairIter.first; iter != pairIter.second; ++iter )
688 for(
const wxString& field : aFieldArray )
696 if( !fieldText.IsEmpty() )
711 return wxString(
"" );
718 std::regex reg(
"[^a-z0-9_-]" );
719 return wxString( std::regex_replace( std::string( aString ), reg,
"_" ) );
727 ret |= fprintf(
m_f,
"%s\n",
"$PACKAGES" );
728 ret |= fprintf(
m_f,
"%s\n",
"$A_PROPERTIES" );
733 wxString sheetPathText = iter->first;
737 std::vector<wxString> refTexts;
741 for( iter = pairIter.first; iter != pairIter.second; ++iter )
743 wxString refText = iter->second;
744 refTexts.push_back( refText );
749 std::stable_sort( refTexts.begin(), refTexts.end(),
752 for(
auto it = refTexts.begin(); it != refTexts.end(); it++ )
754 ret |= fprintf(
m_f,
",\n\t%s",
TO_UTF8( *it ) );
757 ret |= fprintf(
m_f,
"\n" );
766 ret |= fprintf(
m_f,
"%s\n",
"$NETS" );
770 std::multimap<wxString, NET_NODE>::iterator iter =
m_netNameNodes.begin();
771 std::vector<NET_NODE> netNodes;
773 wxString netName = iter->first;
779 for( iter = pairIter.first; iter != pairIter.second; ++iter )
782 netNodes.push_back( netNode );
787 std::stable_sort( netNodes.begin(), netNodes.end() );
789 for(
auto it = netNodes.begin(); it != netNodes.end(); it++ )
797 ret |= fprintf(
m_f,
"\n" );
804 while( ( aString.GetChar( aString.Length() - 1 ) >=
'0' )
805 && ( aString.GetChar( aString.Length() - 1 ) <=
'9' ) )
807 aString.RemoveLast();
818 while( ( aString.GetChar( aString.Length() - 1 ) >=
'0' )
819 && ( aString.GetChar( aString.Length() - 1 ) <=
'9' ) )
821 numString.insert( 0, aString.GetChar( aString.Length() - 1 ) );
822 aString.RemoveLast();
828 numString.ToULong( &val );
829 return (
unsigned int) val;
const NET_MAP & GetNetMap() const
A subgraph is a set of items that are electrically connected on a single sheet.
A base class for most all the KiCad significant classes used in schematics and boards.
EE_TYPE OfType(KICAD_T aType) const
Field object used in symbol libraries.
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
wxString GetShownNumber() const
const wxString & GetNumber() const
const wxString & GetName() const
wxString formatFunction(wxString aName, LIB_PINS aPinList)
Generate the definition of a function in Telesis format, which consists of multiple declarations (PIN...
wxString formatDevice(wxString aString)
Convert a string into one safe for a Telesis device name.
wxString m_exportPath
Directory to store device files.
static unsigned int extractTailNumber(wxString aString)
Extract the str's tailing number.
FILE * m_f
File pointer for netlist file writing operation.
static wxString removeTailDigits(wxString aString)
Remove the str's tailing digits.
void toAllegroPackageProperties()
Write $A_PROPERTIES section.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions, REPORTER &aReporter) override
Write netlist to aOutFileName.
std::list< std::pair< SCH_SYMBOL *, SCH_SHEET_PATH > > m_orderedSymbolsSheetpath
Store the ordered symbols with sheetpath.
static bool CompareSymbolSheetpath(const std::pair< SCH_SYMBOL *, SCH_SHEET_PATH > &aItem1, const std::pair< SCH_SYMBOL *, SCH_SHEET_PATH > &aItem2)
Compare two std::pair<SCH_SYMBOL*, SCH_SHEET_PATH> variables.
wxString formatText(wxString aString)
Convert a string into Telesis-safe format.
std::multimap< wxString, wxString > m_packageProperties
static bool CompareLibPin(const LIB_PIN *aPin1, const LIB_PIN *aPin2)
Compare two LIB_PIN* variables.
static bool CompareSymbolRef(const wxString &aRefText1, const wxString &aRefText2)
Compare two wxString variables.
void extractComponentsInfo()
wxString getGroupField(int aGroupIndex, const wxArrayString &aFieldArray, bool aSanitize=true)
Look up a field for a component group, which may have mismatched case, or the component group may not...
void toAllegroPackages()
Write the $PACKAGES section.
std::multimap< wxString, NET_NODE > m_netNameNodes
Store the NET_NODE with the net name.
std::multimap< int, std::pair< SCH_SYMBOL *, SCH_SHEET_PATH > > m_componentGroups
Store the component group.
wxString formatPin(const LIB_PIN &aPin)
Generate a Telesis-compatible pin name from a pin node.
void toAllegroNets()
Write the $NETS section.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
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.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
virtual void SetCurrentSheet(const SCH_SHEET_PATH &aPath)=0
virtual wxString GetFileName() const =0
virtual CONNECTION_GRAPH * ConnectionGraph() const =0
virtual SCH_SHEET_LIST GetSheets() const =0
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
Base class for any item which can be embedded within the SCHEMATIC container class,...
wxString GetShownNumber() const
SCH_SYMBOL * GetParentSymbol() const
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
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...
const SCH_SHEET * GetSheet(unsigned aIndex) const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
SCH_SCREEN * LastScreen()
void GetLibPins(std::vector< LIB_PIN * > &aPinsList) const
Populate a vector with all the pins from the library object.
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true, bool aCaseInsensitive=false)
Search for a SCH_FIELD with aFieldName.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
const wxString GetFootprintFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
const wxString GetValueFieldText(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const
bool GetExcludedFromBoard() const
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
void Clear()
Erase the record.
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
This file is part of the common library.
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
Collection of utility functions for component reference designators (refdes)
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
wxString GetISO8601CurrentDateTime()
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition for symbol library class.