KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pin_map.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <pin_map.h>
21
22#include <json_common.h>
23
24#include <algorithm>
25#include <utility>
26
27
28#if defined( _MSC_VER ) && wxCHECK_VERSION( 3, 3, 0 )
29extern template class WXDLLIMPEXP_BASE std::vector<wxString>;
30#endif
31
32
33PIN_MAP::PIN_MAP( const wxString& aName ) :
34 m_name( aName )
35{
36}
37
38
39std::vector<PIN_MAP_ENTRY>::iterator PIN_MAP::findEntry( const wxString& aPinNumber )
40{
41 return std::find_if( m_entries.begin(), m_entries.end(),
42 [&]( const PIN_MAP_ENTRY& e )
43 {
44 return e.m_PinNumber == aPinNumber;
45 } );
46}
47
48
49std::vector<PIN_MAP_ENTRY>::const_iterator PIN_MAP::findEntry( const wxString& aPinNumber ) const
50{
51 return std::find_if( m_entries.begin(), m_entries.end(),
52 [&]( const PIN_MAP_ENTRY& e )
53 {
54 return e.m_PinNumber == aPinNumber;
55 } );
56}
57
58
59void PIN_MAP::SetEntry( const wxString& aPinNumber, const wxString& aPadNumber )
60{
61 auto it = findEntry( aPinNumber );
62
63 if( it == m_entries.end() )
64 m_entries.push_back( { aPinNumber, aPadNumber } );
65 else
66 it->m_PadNumber = aPadNumber;
67}
68
69
70void PIN_MAP::ClearEntry( const wxString& aPinNumber )
71{
72 auto it = findEntry( aPinNumber );
73
74 if( it != m_entries.end() )
75 m_entries.erase( it );
76}
77
78
79bool PIN_MAP::HasEntry( const wxString& aPinNumber ) const
80{
81 return findEntry( aPinNumber ) != m_entries.end();
82}
83
84
85const wxString& PIN_MAP::GetPadNumber( const wxString& aPinNumber ) const
86{
87 static const wxString empty;
88
89 auto it = findEntry( aPinNumber );
90
91 return it == m_entries.end() ? empty : it->m_PadNumber;
92}
93
94
95bool PIN_MAP::IsIdentity( const std::vector<wxString>& aPinNumbers ) const
96{
97 return std::all_of( aPinNumbers.begin(), aPinNumbers.end(),
98 [&]( const wxString& pin )
99 {
100 auto it = findEntry( pin );
101
102 return it == m_entries.end() || it->m_PadNumber == pin;
103 } );
104}
105
106
107bool PIN_MAP::operator==( const PIN_MAP& aOther ) const
108{
109 return m_name == aOther.m_name && m_entries == aOther.m_entries;
110}
111
112
114{
115 if( PIN_MAP* existing = FindByName( aMap.GetName() ) )
116 *existing = std::move( aMap );
117 else
118 m_maps.push_back( std::move( aMap ) );
119}
120
121
122void PIN_MAP_SET::Remove( const wxString& aName )
123{
124 m_maps.erase( std::remove_if( m_maps.begin(), m_maps.end(),
125 [&]( const PIN_MAP& m )
126 {
127 return m.GetName() == aName;
128 } ),
129 m_maps.end() );
130}
131
132
133const PIN_MAP* PIN_MAP_SET::FindByName( const wxString& aName ) const
134{
135 auto it = std::find_if( m_maps.begin(), m_maps.end(),
136 [&]( const PIN_MAP& m )
137 {
138 return m.GetName() == aName;
139 } );
140
141 return it == m_maps.end() ? nullptr : &*it;
142}
143
144
145PIN_MAP* PIN_MAP_SET::FindByName( const wxString& aName )
146{
147 return const_cast<PIN_MAP*>( std::as_const( *this ).FindByName( aName ) );
148}
149
150
151PIN_MAP MakeLegacyPinMap( const wxString& aName,
152 const std::unordered_map<wxString, std::vector<wxString>>& aAssignments )
153{
154 PIN_MAP map( aName );
155
156 for( const auto& [pinNumber, pads] : aAssignments )
157 {
158 if( pads.empty() )
159 continue;
160
161 if( pads.size() == 1 )
162 {
163 map.SetEntry( pinNumber, pads.front() );
164 }
165 else
166 {
167 wxString stacked = wxS( "[" );
168
169 for( size_t ii = 0; ii < pads.size(); ++ii )
170 {
171 if( ii > 0 )
172 stacked += wxS( "," );
173
174 stacked += pads[ii];
175 }
176
177 stacked += wxS( "]" );
178 map.SetEntry( pinNumber, stacked );
179 }
180 }
181
182 return map;
183}
184
185
186std::unordered_map<wxString, std::vector<wxString>>
187ParseLegacyPinAssignments( const nlohmann::json& aArray )
188{
189 std::unordered_map<wxString, std::vector<wxString>> assignments;
190
191 if( !aArray.is_array() )
192 return assignments;
193
194 for( const auto& entry : aArray )
195 {
196 if( !entry.contains( "sym" ) || !entry.contains( "fp" ) )
197 continue;
198
199 wxString symbolPin = wxString::FromUTF8( entry["sym"].get<std::string>() );
200 std::vector<wxString> pads;
201 const auto& fp = entry["fp"];
202
203 if( fp.is_array() )
204 {
205 for( const auto& pad : fp )
206 pads.push_back( wxString::FromUTF8( pad.get<std::string>() ) );
207 }
208 else if( fp.is_string() )
209 {
210 pads.push_back( wxString::FromUTF8( fp.get<std::string>() ) );
211 }
212
213 if( !symbolPin.empty() && !pads.empty() )
214 assignments[symbolPin] = std::move( pads );
215 }
216
217 return assignments;
218}
219
220
221PIN_MAP_SET ParsePinMapSet( const nlohmann::json& aParent )
222{
223 PIN_MAP_SET set;
224
225 if( !aParent.contains( "pin_maps" ) || !aParent["pin_maps"].is_array() )
226 return set;
227
228 for( const auto& mapJson : aParent["pin_maps"] )
229 {
230 if( !mapJson.contains( "name" ) )
231 continue;
232
233 PIN_MAP map( wxString::FromUTF8( mapJson["name"].get<std::string>() ) );
234
235 if( mapJson.contains( "entries" ) && mapJson["entries"].is_array() )
236 {
237 for( const auto& entryJson : mapJson["entries"] )
238 {
239 if( entryJson.contains( "pin" ) && entryJson.contains( "pad" ) )
240 {
241 map.SetEntry( wxString::FromUTF8( entryJson["pin"].get<std::string>() ),
242 wxString::FromUTF8( entryJson["pad"].get<std::string>() ) );
243 }
244 }
245 }
246
247 set.AddOrReplace( std::move( map ) );
248 }
249
250 return set;
251}
252
253
254std::vector<ASSOCIATED_FOOTPRINT> ParseAssociatedFootprints( const nlohmann::json& aParent )
255{
256 std::vector<ASSOCIATED_FOOTPRINT> associations;
257
258 if( !aParent.contains( "associated_footprints" ) || !aParent["associated_footprints"].is_array() )
259 return associations;
260
261 for( const auto& assocJson : aParent["associated_footprints"] )
262 {
263 if( !assocJson.contains( "footprint" ) )
264 continue;
265
267 assoc.m_FootprintLibId.Parse( wxString::FromUTF8( assocJson["footprint"].get<std::string>() ) );
268
269 if( assocJson.contains( "map" ) )
270 assoc.m_MapName = wxString::FromUTF8( assocJson["map"].get<std::string>() );
271
272 associations.push_back( std::move( assoc ) );
273 }
274
275 return associations;
276}
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
A symbol-owned ordered set of named pin maps.
Definition pin_map.h:123
void AddOrReplace(PIN_MAP aMap)
Insert aMap, replacing any existing entry with the same name.
Definition pin_map.cpp:113
void Remove(const wxString &aName)
Remove the map with the given name.
Definition pin_map.cpp:122
const PIN_MAP * FindByName(const wxString &aName) const
Definition pin_map.cpp:133
std::vector< PIN_MAP > m_maps
Definition pin_map.h:145
A named pin map.
Definition pin_map.h:64
PIN_MAP()=default
const wxString & GetPadNumber(const wxString &aPinNumber) const
Definition pin_map.cpp:85
bool operator==(const PIN_MAP &aOther) const
Definition pin_map.cpp:107
const wxString & GetName() const
Definition pin_map.h:69
bool HasEntry(const wxString &aPinNumber) const
Definition pin_map.cpp:79
wxString m_name
Definition pin_map.h:110
void ClearEntry(const wxString &aPinNumber)
Remove the entry for aPinNumber.
Definition pin_map.cpp:70
std::vector< PIN_MAP_ENTRY > m_entries
Definition pin_map.h:111
bool IsIdentity(const std::vector< wxString > &aPinNumbers) const
Definition pin_map.cpp:95
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
Definition pin_map.cpp:59
std::vector< PIN_MAP_ENTRY >::iterator findEntry(const wxString &aPinNumber)
Definition pin_map.cpp:39
static bool empty(const wxTextEntryBase *aCtrl)
PIN_MAP MakeLegacyPinMap(const wxString &aName, const std::unordered_map< wxString, std::vector< wxString > > &aAssignments)
Build a single named PIN_MAP from a legacy symbol-pin to footprint-pad(s) assignment table (the flat ...
Definition pin_map.cpp:151
std::vector< ASSOCIATED_FOOTPRINT > ParseAssociatedFootprints(const nlohmann::json &aParent)
Parse the spec-form footprint associations from aParent["associated_footprints"] (issue #2282).
Definition pin_map.cpp:254
std::unordered_map< wxString, std::vector< wxString > > ParseLegacyPinAssignments(const nlohmann::json &aArray)
Parse the legacy flat pin-assignment JSON array (MR !2540 form) into a symbol-pin to footprint-pad(s)...
Definition pin_map.cpp:187
PIN_MAP_SET ParsePinMapSet(const nlohmann::json &aParent)
Parse the spec-form named maps from aParent["pin_maps"] into a PIN_MAP_SET (issue #2282).
Definition pin_map.cpp:221
A first-class footprint choice on a LIB_SYMBOL, tied to a named pin map.
Definition pin_map.h:158
LIB_ID m_FootprintLibId
Definition pin_map.h:159
One symbol-pin to footprint-pad mapping inside a PIN_MAP.
Definition pin_map.h:41
KIBIS_PIN * pin