KiCad PCB EDA Suite
netlist_exporter_cadstar.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-2018 jp.charras at wanadoo.fr
5  * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2020 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 <fctsys.h>
27 #include <build_version.h>
28 #include <confirm.h>
29 
30 #include <connection_graph.h>
31 #include <sch_edit_frame.h>
32 #include <sch_reference_list.h>
33 
35 
36 /* Generate CADSTAR net list. */
37 static wxString StartLine( wxT( "." ) );
38 
39 bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
40 {
41  (void)aNetlistOptions; //unused
42  int ret = 0;
43  FILE* f = NULL;
44 
45  if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
46  {
47  wxString msg;
48  msg.Printf( _( "Failed to create file \"%s\"" ),
49  GetChars( aOutFileName ) );
50  DisplayError( NULL, msg );
51  return false;
52  }
53 
54  wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
55  wxString msg;
56  wxString footprint;
57  SCH_COMPONENT* component;
58  wxString title = wxT( "Eeschema " ) + GetBuildVersion();
59 
60  ret |= fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) );
61  ret |= fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) );
62  ret |= fprintf( f, "%sAPP ", TO_UTF8( StartLine ) );
63  ret |= fprintf( f, "\"%s\"\n", TO_UTF8( title ) );
64  ret |= fprintf( f, ".TYP FULL\n\n" );
65 
66  // Create netlist module section
68 
69  SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
70 
71  for( unsigned i = 0; i < sheetList.size(); i++ )
72  {
73  std::vector<SCH_COMPONENT*> cmps;
74 
75  for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
76  {
77  component = findNextComponent( item, &sheetList[i] );
78 
79  if( !component )
80  continue;
81 
82  if( !component->GetField( FOOTPRINT )->IsVoid() )
83  footprint = component->GetField( FOOTPRINT )->GetText();
84  else
85  footprint = "$noname";
86 
87  msg = component->GetRef( &sheetList[i] );
88  ret |= fprintf( f, "%s ", TO_UTF8( StartCmpDesc ) );
89  ret |= fprintf( f, "%s", TO_UTF8( msg ) );
90 
91  msg = component->GetField( VALUE )->GetText();
92  msg.Replace( wxT( " " ), wxT( "_" ) );
93  ret |= fprintf( f, " \"%s\"", TO_UTF8( msg ) );
94  ret |= fprintf( f, " \"%s\"", TO_UTF8( footprint ) );
95  ret |= fprintf( f, "\n" );
96  }
97  }
98 
99  ret |= fprintf( f, "\n" );
100 
101  if( ! writeListOfNets( f ) )
102  ret = -1; // set error
103 
104  ret |= fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) );
105 
106  fclose( f );
107 
108  return ret >= 0;
109 }
110 
111 
113 {
114  int ret = 0;
115  int print_ter = 0;
116 
117  wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
118  wxString StartNetDesc = StartLine + wxT( "TER" );
119  wxString InitNetDescLine;
120  wxString netName;
121 
122  for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
123  {
124  auto subgraphs = it.second;
125 
126  netName.Printf( wxT( "\"%s\"" ), it.first.first );
127 
128  std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
129 
130  for( auto subgraph : subgraphs )
131  {
132  auto sheet = subgraph->m_sheet;
133 
134  for( auto item : subgraph->m_items )
135  if( item->Type() == SCH_PIN_T )
136  sorted_items.emplace_back(
137  std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
138  }
139 
140  // Netlist ordering: Net name, then ref des, then pin name
141  std::sort( sorted_items.begin(), sorted_items.end(),
142  []( auto a, auto b )
143  {
144  wxString ref_a = a.first->GetParentComponent()->GetRef( &a.second );
145  wxString ref_b = b.first->GetParentComponent()->GetRef( &b.second );
146 
147  if( ref_a == ref_b )
148  return a.first->GetNumber() < b.first->GetNumber();
149 
150  return ref_a < ref_b;
151  } );
152 
153  // Some duplicates can exist, for example on multi-unit parts with duplicated
154  // pins across units. If the user connects the pins on each unit, they will
155  // appear on separate subgraphs. Remove those here:
156  sorted_items.erase( std::unique( sorted_items.begin(), sorted_items.end(),
157  []( auto a, auto b )
158  {
159  auto ref_a = a.first->GetParentComponent()->GetRef( &a.second );
160  auto ref_b = b.first->GetParentComponent()->GetRef( &b.second );
161 
162  return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
163  } ),
164  sorted_items.end() );
165 
166  for( const auto& pair : sorted_items )
167  {
168  SCH_PIN* pin = pair.first;
169  SCH_SHEET_PATH sheet = pair.second;
170 
171  wxString refText = pin->GetParentComponent()->GetRef( &sheet );
172  wxString pinText = pin->GetNumber();
173 
174  // Skip power symbols and virtual components
175  if( refText[0] == wxChar( '#' ) )
176  continue;
177 
178  switch( print_ter )
179  {
180  case 0:
181  {
182  InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
183  GetChars( InitNetDesc ),
184  GetChars( refText ),
185  GetChars( pinText ),
186  GetChars( netName ) );
187  }
188  print_ter++;
189  break;
190 
191  case 1:
192  ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
193  ret |= fprintf( f, "%s %s %.4s\n",
194  TO_UTF8( StartNetDesc ),
195  TO_UTF8( refText ),
196  TO_UTF8( pinText ) );
197  print_ter++;
198  break;
199 
200  default:
201  ret |= fprintf( f, " %s %.4s\n",
202  TO_UTF8( refText ),
203  TO_UTF8( pinText ) );
204  break;
205  }
206  }
207  }
208 
209  return ret >= 0;
210 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
SCH_SHEET_LIST.
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:99
UNIQUE_STRINGS m_ReferencesAlreadyFound
Used for "multi parts per package" components, avoids processing a lib component more than once.
SCHEMATIC * m_schematic
The schematic we're generating a netlist for.
CONNECTION_GRAPH * ConnectionGraph() const
Definition: schematic.h:139
This file is part of the common library.
void Clear()
Function Clear erases the record.
SCH_COMPONENT * findNextComponent(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Checks if the given component should be processed for netlisting.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions) override
Function WriteList writes to specified output file.
Field Name Module PCB, i.e. "16DIP300".
bool IsVoid() const
Function IsVoid returns true if the field is either empty or holds "~".
Definition: sch_field.cpp:293
const wxString & GetNumber() const
Definition: sch_pin.h:104
#define VALUE
#define NULL
wxString GetBuildVersion()
Get the full KiCad version string.
const NET_MAP & GetNetMap() const
SCH_SHEET_PATH.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
static wxString StartLine(wxT("."))
SCH_FIELD * GetField(int aFieldNdx)
Returns a field in this symbol.
bool writeListOfNets(FILE *f)
Function writeListOfNetsCADSTAR writes a net list (ranked by Netcode), and pins connected to it.
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:153
#define _(s)
Definition: 3d_actions.cpp:33
Schematic symbol object.
Definition: sch_component.h:88
#define TO_UTF8(wxstring)
SCH_COMPONENT * GetParentComponent() const
Definition: sch_pin.cpp:64
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:126
wxString DateAndTime()
Definition: string.cpp:379