KiCad PCB EDA Suite
Loading...
Searching...
No Matches
net_settings.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) 2020 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Jon Evans <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <algorithm>
23#include <limits>
24
25#include <json_common.h>
26
28#include <settings/parameters.h>
30#include <string_utils.h>
31#include <base_units.h>
32#include <unordered_set>
33
34
35// const int netSettingsSchemaVersion = 0;
36// const int netSettingsSchemaVersion = 1; // new overbar syntax
37// const int netSettingsSchemaVersion = 2; // exclude buses from netclass members
38// const int netSettingsSchemaVersion = 3; // netclass assignment patterns
39// const int netSettingsSchemaVersion = 4; // netclass ordering
40const int netSettingsSchemaVersion = 5; // Tuning profile names
41
42
43static std::optional<int> getInPcbUnits( const nlohmann::json& aObj, const std::string& aKey,
44 std::optional<int> aDefault = std::optional<int>() )
45{
46 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
47 return pcbIUScale.mmToIU( aObj[aKey].get<double>() );
48 else
49 return aDefault;
50};
51
52
53static std::optional<int> getInSchUnits( const nlohmann::json& aObj, const std::string& aKey,
54 std::optional<int> aDefault = std::optional<int>() )
55{
56 if( aObj.contains( aKey ) && aObj[aKey].is_number() )
57 return schIUScale.MilsToIU( aObj[aKey].get<double>() );
58 else
59 return aDefault;
60};
61
62
63NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
64 NESTED_SETTINGS( "net_settings", netSettingsSchemaVersion, aParent, aPath, false )
65{
66 m_defaultNetClass = std::make_shared<NETCLASS>( NETCLASS::Default, true );
67 m_defaultNetClass->SetDescription( _( "This is the default net class." ) );
68 m_defaultNetClass->SetPriority( std::numeric_limits<int>::max() );
69
70 auto saveNetclass =
71 []( nlohmann::json& json_array, const std::shared_ptr<NETCLASS>& nc )
72 {
73 // Note: we're in common/, but we do happen to know which of these
74 // fields are used in which units system.
75 nlohmann::json nc_json = { { "name", nc->GetName().ToUTF8() },
76 { "priority", nc->GetPriority() },
77 { "schematic_color", nc->GetSchematicColor( true ) },
78 { "pcb_color", nc->GetPcbColor( true ) },
79 { "tuning_profile", nc->GetDelayProfile() } };
80
81 auto saveInPcbUnits =
82 []( nlohmann::json& json, const std::string& aKey, int aValue )
83 {
84 json.push_back( { aKey, pcbIUScale.IUTomm( aValue ) } );
85 };
86
87 if( nc->HasWireWidth() )
88 nc_json.push_back(
89 { "wire_width", schIUScale.IUToMils( nc->GetWireWidth() ) } );
90
91 if( nc->HasBusWidth() )
92 nc_json.push_back( { "bus_width", schIUScale.IUToMils( nc->GetBusWidth() ) } );
93
94 if( nc->HasLineStyle() )
95 nc_json.push_back( { "line_style", nc->GetLineStyle() } );
96
97 if( nc->HasClearance() )
98 saveInPcbUnits( nc_json, "clearance", nc->GetClearance() );
99
100 if( nc->HasTrackWidth() )
101 saveInPcbUnits( nc_json, "track_width", nc->GetTrackWidth() );
102
103 if( nc->HasViaDiameter() )
104 saveInPcbUnits( nc_json, "via_diameter", nc->GetViaDiameter() );
105
106 if( nc->HasViaDrill() )
107 saveInPcbUnits( nc_json, "via_drill", nc->GetViaDrill() );
108
109 if( nc->HasuViaDiameter() )
110 saveInPcbUnits( nc_json, "microvia_diameter", nc->GetuViaDiameter() );
111
112 if( nc->HasuViaDrill() )
113 saveInPcbUnits( nc_json, "microvia_drill", nc->GetuViaDrill() );
114
115 if( nc->HasDiffPairWidth() )
116 saveInPcbUnits( nc_json, "diff_pair_width", nc->GetDiffPairWidth() );
117
118 if( nc->HasDiffPairGap() )
119 saveInPcbUnits( nc_json, "diff_pair_gap", nc->GetDiffPairGap() );
120
121 if( nc->HasDiffPairViaGap() )
122 saveInPcbUnits( nc_json, "diff_pair_via_gap", nc->GetDiffPairViaGap() );
123
124 json_array.push_back( nc_json );
125 };
126
127 auto readNetClass =
128 []( const nlohmann::json& entry )
129 {
130 wxString name = entry["name"];
131
132 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( name, false );
133
134 int priority = entry["priority"];
135 nc->SetPriority( priority );
136
137 nc->SetDelayProfile( entry["tuning_profile"] );
138
139 if( auto value = getInPcbUnits( entry, "clearance" ) )
140 nc->SetClearance( *value );
141
142 if( auto value = getInPcbUnits( entry, "track_width" ) )
143 nc->SetTrackWidth( *value );
144
145 if( auto value = getInPcbUnits( entry, "via_diameter" ) )
146 nc->SetViaDiameter( *value );
147
148 if( auto value = getInPcbUnits( entry, "via_drill" ) )
149 nc->SetViaDrill( *value );
150
151 if( auto value = getInPcbUnits( entry, "microvia_diameter" ) )
152 nc->SetuViaDiameter( *value );
153
154 if( auto value = getInPcbUnits( entry, "microvia_drill" ) )
155 nc->SetuViaDrill( *value );
156
157 if( auto value = getInPcbUnits( entry, "diff_pair_width" ) )
158 nc->SetDiffPairWidth( *value );
159
160 if( auto value = getInPcbUnits( entry, "diff_pair_gap" ) )
161 nc->SetDiffPairGap( *value );
162
163 if( auto value = getInPcbUnits( entry, "diff_pair_via_gap" ) )
164 nc->SetDiffPairViaGap( *value );
165
166 if( auto value = getInSchUnits( entry, "wire_width" ) )
167 nc->SetWireWidth( *value );
168
169 if( auto value = getInSchUnits( entry, "bus_width" ) )
170 nc->SetBusWidth( *value );
171
172 if( entry.contains( "line_style" ) && entry["line_style"].is_number() )
173 nc->SetLineStyle( entry["line_style"].get<int>() );
174
175 if( entry.contains( "pcb_color" ) && entry["pcb_color"].is_string() )
176 nc->SetPcbColor( entry["pcb_color"].get<KIGFX::COLOR4D>() );
177
178 if( entry.contains( "schematic_color" )
179 && entry["schematic_color"].is_string() )
180 {
181 nc->SetSchematicColor( entry["schematic_color"].get<KIGFX::COLOR4D>() );
182 }
183
184 return nc;
185 };
186
187 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "classes",
188 [&]() -> nlohmann::json
189 {
190 nlohmann::json ret = nlohmann::json::array();
191
192 if( m_defaultNetClass )
193 saveNetclass( ret, m_defaultNetClass );
194
195 for( const auto& [name, netclass] : m_netClasses )
196 saveNetclass( ret, netclass );
197
198 return ret;
199 },
200 [&]( const nlohmann::json& aJson )
201 {
202 if( !aJson.is_array() )
203 return;
204
205 m_netClasses.clear();
206
207 for( const nlohmann::json& entry : aJson )
208 {
209 if( !entry.is_object() || !entry.contains( "name" ) )
210 continue;
211
212 std::shared_ptr<NETCLASS> nc = readNetClass( entry );
213
214 if( nc->IsDefault() )
215 m_defaultNetClass = nc;
216 else
217 m_netClasses[nc->GetName()] = nc;
218 }
219 },
220 {} ) );
221
222 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "net_colors",
223 [&]() -> nlohmann::json
224 {
225 nlohmann::json ret = {};
226
227 for( const auto& [netname, color] : m_netColorAssignments )
228 {
229 std::string key( netname.ToUTF8() );
230 ret[ std::move( key ) ] = color;
231 }
232
233 return ret;
234 },
235 [&]( const nlohmann::json& aJson )
236 {
237 if( !aJson.is_object() )
238 return;
239
240 m_netColorAssignments.clear();
241
242 for( const auto& pair : aJson.items() )
243 {
244 wxString key( pair.key().c_str(), wxConvUTF8 );
245 m_netColorAssignments[std::move( key )] = pair.value().get<KIGFX::COLOR4D>();
246 }
247 },
248 {} ) );
249
250 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "netclass_assignments",
251 [&]() -> nlohmann::json
252 {
253 nlohmann::json ret = {};
254
255 for( const auto& [netname, netclassNames] : m_netClassLabelAssignments )
256 {
257 nlohmann::json netclassesJson = nlohmann::json::array();
258
259 for( const auto& netclass : netclassNames )
260 {
261 std::string netclassStr( netclass.ToUTF8() );
262 netclassesJson.push_back( std::move( netclassStr ) );
263 }
264
265 std::string key( netname.ToUTF8() );
266 ret[std::move( key )] = netclassesJson;
267 }
268
269 return ret;
270 },
271 [&]( const nlohmann::json& aJson )
272 {
273 if( !aJson.is_object() )
274 return;
275
276 m_netClassLabelAssignments.clear();
277
278 for( const auto& pair : aJson.items() )
279 {
280 wxString key( pair.key().c_str(), wxConvUTF8 );
281
282 for( const auto& netclassName : pair.value() )
283 m_netClassLabelAssignments[key].insert( netclassName.get<wxString>() );
284 }
285 },
286 {} ) );
287
288 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "netclass_patterns",
289 [&]() -> nlohmann::json
290 {
291 nlohmann::json ret = nlohmann::json::array();
292
293 for( const auto& [matcher, netclassName] : m_netClassPatternAssignments )
294 {
295 nlohmann::json pattern_json = {
296 { "pattern", matcher->GetPattern().ToUTF8() },
297 { "netclass", netclassName.ToUTF8() }
298 };
299
300 ret.push_back( std::move( pattern_json ) );
301 }
302
303 return ret;
304 },
305 [&]( const nlohmann::json& aJson )
306 {
307 if( !aJson.is_array() )
308 return;
309
310 m_netClassPatternAssignments.clear();
311
312 for( const nlohmann::json& entry : aJson )
313 {
314 if( !entry.is_object() )
315 continue;
316
317 if( entry.contains( "pattern" ) && entry["pattern"].is_string()
318 && entry.contains( "netclass" ) && entry["netclass"].is_string() )
319 {
320 wxString pattern = entry["pattern"].get<wxString>();
321 wxString netclass = entry["netclass"].get<wxString>();
322
323 m_netClassPatternAssignments.push_back(
324 { std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ),
325 netclass } );
326 }
327 }
328 },
329 {} ) );
330
331 registerMigration( 0, 1, std::bind( &NET_SETTINGS::migrateSchema0to1, this ) );
332 registerMigration( 1, 2, std::bind( &NET_SETTINGS::migrateSchema1to2, this ) );
333 registerMigration( 2, 3, std::bind( &NET_SETTINGS::migrateSchema2to3, this ) );
334 registerMigration( 3, 4, std::bind( &NET_SETTINGS::migrateSchema3to4, this ) );
335 registerMigration( 4, 5, std::bind( &NET_SETTINGS::migrateSchema4to5, this ) );
336}
337
338
340{
341 // Release early before destroying members
342 if( m_parent )
343 {
345 m_parent = nullptr;
346 }
347}
348
349
350bool NET_SETTINGS::operator==( const NET_SETTINGS& aOther ) const
351{
352 if( !std::equal( std::begin( m_netClasses ), std::end( m_netClasses ),
353 std::begin( aOther.m_netClasses ) ) )
354 return false;
355
356 if( !std::equal( std::begin( m_netClassPatternAssignments ),
358 std::begin( aOther.m_netClassPatternAssignments ) ) )
359 return false;
360
361 if( !std::equal( std::begin( m_netClassLabelAssignments ),
362 std::end( m_netClassLabelAssignments ),
363 std::begin( aOther.m_netClassLabelAssignments ) ) )
364 return false;
365
366
367 if( !std::equal( std::begin( m_netColorAssignments ), std::end( m_netColorAssignments ),
368 std::begin( aOther.m_netColorAssignments ) ) )
369 return false;
370
371 return true;
372}
373
374
376{
377 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
378 {
379 for( auto& netClass : m_internals->At( "classes" ).items() )
380 {
381 if( netClass.value().contains( "nets" ) && netClass.value()["nets"].is_array() )
382 {
383 nlohmann::json migrated = nlohmann::json::array();
384
385 for( auto& net : netClass.value()["nets"].items() )
386 migrated.push_back( ConvertToNewOverbarNotation( net.value().get<wxString>() ) );
387
388 netClass.value()["nets"] = migrated;
389 }
390 }
391 }
392
393 return true;
394}
395
396
398{
399 return true;
400}
401
402
404{
405 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
406 {
407 nlohmann::json patterns = nlohmann::json::array();
408
409 for( auto& netClass : m_internals->At( "classes" ).items() )
410 {
411 if( netClass.value().contains( "name" )
412 && netClass.value().contains( "nets" )
413 && netClass.value()["nets"].is_array() )
414 {
415 wxString netClassName = netClass.value()["name"].get<wxString>();
416
417 for( auto& net : netClass.value()["nets"].items() )
418 {
419 nlohmann::json pattern_json = {
420 { "pattern", net.value().get<wxString>() },
421 { "netclass", netClassName }
422 };
423
424 patterns.push_back( pattern_json );
425 }
426 }
427 }
428
429 m_internals->SetFromString( "netclass_patterns", patterns );
430 }
431
432 return true;
433}
434
435
437{
438 // Add priority field to netclasses
439 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
440 {
441 int priority = 0;
442
443 for( auto& netClass : m_internals->At( "classes" ).items() )
444 {
445 if( netClass.value()["name"].get<wxString>() == NETCLASS::Default )
446 netClass.value()["priority"] = std::numeric_limits<int>::max();
447 else
448 netClass.value()["priority"] = priority++;
449 }
450 }
451
452 // Move netclass assignments to a list
453 if( m_internals->contains( "netclass_assignments" )
454 && m_internals->At( "netclass_assignments" ).is_object() )
455 {
456 nlohmann::json migrated = {};
457
458 for( const auto& pair : m_internals->At( "netclass_assignments" ).items() )
459 {
460 nlohmann::json netclassesJson = nlohmann::json::array();
461
462 if( pair.value().get<wxString>() != wxEmptyString )
463 netclassesJson.push_back( pair.value() );
464
465 migrated[pair.key()] = netclassesJson;
466 }
467
468 m_internals->SetFromString( "netclass_assignments", migrated );
469 }
470
471 return true;
472}
473
474
476{
477 // Add tuning profile name field to netclasses
478 if( m_internals->contains( "classes" ) && m_internals->At( "classes" ).is_array() )
479 {
480 const wxString emptyStr = "";
481
482 for( auto& netClass : m_internals->At( "classes" ).items() )
483 netClass.value()["tuning_profile"] = emptyStr.ToUTF8();
484 }
485
486 return true;
487}
488
489
490void NET_SETTINGS::SetDefaultNetclass( std::shared_ptr<NETCLASS> netclass )
491{
492 m_defaultNetClass = netclass;
493}
494
495
496std::shared_ptr<NETCLASS> NET_SETTINGS::GetDefaultNetclass()
497{
498 return m_defaultNetClass;
499}
500
501
502bool NET_SETTINGS::HasNetclass( const wxString& netclassName ) const
503{
504 return m_netClasses.find( netclassName ) != m_netClasses.end();
505}
506
507
508void NET_SETTINGS::SetNetclass( const wxString& netclassName, std::shared_ptr<NETCLASS>& netclass )
509{
510 m_netClasses[netclassName] = netclass;
511}
512
513
514void NET_SETTINGS::SetNetclasses( const std::map<wxString, std::shared_ptr<NETCLASS>>& netclasses )
515{
516 m_netClasses = netclasses;
518}
519
520
521const std::map<wxString, std::shared_ptr<NETCLASS>>& NET_SETTINGS::GetNetclasses() const
522{
523 return m_netClasses;
524}
525
526
527const std::map<wxString, std::shared_ptr<NETCLASS>>& NET_SETTINGS::GetCompositeNetclasses() const
528{
530}
531
532
534{
535 m_netClasses.clear();
536 m_impicitNetClasses.clear();
538}
539
540
541const std::map<wxString, std::set<wxString>>& NET_SETTINGS::GetNetclassLabelAssignments() const
542{
544}
545
546
548{
550}
551
552
553void NET_SETTINGS::ClearNetclassLabelAssignment( const wxString& netName )
554{
555 m_netClassLabelAssignments.erase( netName );
556}
557
558
559void NET_SETTINGS::SetNetclassLabelAssignment( const wxString& netName,
560 const std::set<wxString>& netclasses )
561{
562 m_netClassLabelAssignments[netName] = netclasses;
563}
564
565
567 const std::set<wxString>& netclasses )
568{
569 m_netClassLabelAssignments[netName].insert( netclasses.begin(), netclasses.end() );
570}
571
572
573bool NET_SETTINGS::HasNetclassLabelAssignment( const wxString& netName ) const
574{
575 return m_netClassLabelAssignments.find( netName ) != m_netClassLabelAssignments.end();
576}
577
578
579void NET_SETTINGS::SetNetclassPatternAssignment( const wxString& pattern, const wxString& netclass )
580{
581 // Replace existing assignment if we have one
582 for( auto& assignment : m_netClassPatternAssignments )
583 {
584 if( assignment.first->GetPattern() == pattern )
585 {
586 assignment.second = netclass;
588 return;
589 }
590 }
591
592 // No assignment, add a new one
594 { std::make_unique<EDA_COMBINED_MATCHER>( pattern, CTX_NETCLASS ), netclass } );
595
597}
598
599
601 std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&& netclassPatterns )
602{
603 m_netClassPatternAssignments = std::move( netclassPatterns );
605}
606
607
608std::vector<std::pair<std::unique_ptr<EDA_COMBINED_MATCHER>, wxString>>&
610{
612}
613
614
616{
618}
619
620
621void NET_SETTINGS::ClearCacheForNet( const wxString& netName )
622{
623 if( m_effectiveNetclassCache.count( netName ) )
624 {
625 wxString compositeNetclassName = m_effectiveNetclassCache[netName]->GetName();
626 m_compositeNetClasses.erase( compositeNetclassName );
627 m_effectiveNetclassCache.erase( netName );
628 }
629}
630
631
633{
635 m_compositeNetClasses.clear();
636}
637
638
639void NET_SETTINGS::SetNetColorAssignment( const wxString& netName, const KIGFX::COLOR4D& color )
640{
641 m_netColorAssignments[netName] = color;
642}
643
644
645const std::map<wxString, KIGFX::COLOR4D>& NET_SETTINGS::GetNetColorAssignments() const
646{
648}
649
650
652{
653 m_netColorAssignments.clear();
654}
655
656
657bool NET_SETTINGS::HasEffectiveNetClass( const wxString& aNetName ) const
658{
659 return m_effectiveNetclassCache.count( aNetName ) > 0;
660}
661
662
663std::shared_ptr<NETCLASS> NET_SETTINGS::GetCachedEffectiveNetClass( const wxString& aNetName ) const
664{
665 return m_effectiveNetclassCache.at( aNetName );
666}
667
668
669std::shared_ptr<NETCLASS> NET_SETTINGS::GetEffectiveNetClass( const wxString& aNetName )
670{
671 // Lambda to fetch an explicit netclass. Returns a nullptr if not found
672 auto getExplicitNetclass = [this]( const wxString& netclass ) -> std::shared_ptr<NETCLASS>
673 {
674 if( netclass == NETCLASS::Default )
675 return m_defaultNetClass;
676
677 auto ii = m_netClasses.find( netclass );
678
679 if( ii == m_netClasses.end() )
680 return {};
681 else
682 return ii->second;
683 };
684
685 // Lambda to fetch or create an implicit netclass (defined with a label, but not configured)
686 // These are needed as while they do not provide any netclass parameters, they do now appear in
687 // DRC matching strings as an assigned netclass.
688 auto getOrAddImplicitNetcless = [this]( const wxString& netclass ) -> std::shared_ptr<NETCLASS>
689 {
690 auto ii = m_impicitNetClasses.find( netclass );
691
692 if( ii == m_impicitNetClasses.end() )
693 {
694 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( netclass, false );
695 nc->SetPriority( std::numeric_limits<int>::max() - 1 ); // Priority > default netclass
696 m_impicitNetClasses[netclass] = nc;
697 return nc;
698 }
699 else
700 {
701 return ii->second;
702 }
703 };
704
705 // <no net> is forced to be part of the default netclass.
706 if( aNetName.IsEmpty() )
707 return m_defaultNetClass;
708
709 // First check if we have a cached resolved netclass
710 auto cacheItr = m_effectiveNetclassCache.find( aNetName );
711
712 if( cacheItr != m_effectiveNetclassCache.end() )
713 return cacheItr->second;
714
715 // No cache found - build a vector of all netclasses assigned to or matching this net
716 std::unordered_set<std::shared_ptr<NETCLASS>> resolvedNetclasses;
717
718 // First find explicit netclass assignments
719 auto it = m_netClassLabelAssignments.find( aNetName );
720
721 if( it != m_netClassLabelAssignments.end() && it->second.size() > 0 )
722 {
723 for( const wxString& netclassName : it->second )
724 {
725 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
726
727 if( netclass )
728 {
729 resolvedNetclasses.insert( std::move( netclass ) );
730 }
731 else
732 {
733 resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
734 }
735 }
736 }
737
738 // Now find any pattern-matched netclass assignments
739 for( const auto& [matcher, netclassName] : m_netClassPatternAssignments )
740 {
741 if( matcher->StartsWith( aNetName ) )
742 {
743 std::shared_ptr<NETCLASS> netclass = getExplicitNetclass( netclassName );
744
745 if( netclass )
746 {
747 resolvedNetclasses.insert( std::move( netclass ) );
748 }
749 else
750 {
751 resolvedNetclasses.insert( getOrAddImplicitNetcless( netclassName ) );
752 }
753 }
754 }
755
756 // Handle zero resolved netclasses
757 if( resolvedNetclasses.size() == 0 )
758 {
760
761 return m_defaultNetClass;
762 }
763
764 // Make and cache the effective netclass. Note that makeEffectiveNetclass will add the default
765 // netclass to resolvedNetclasses if it is needed to complete the netclass paramters set. It
766 // will also sort resolvedNetclasses by priority order.
767 std::vector<NETCLASS*> netclassPtrs;
768
769 for( const std::shared_ptr<NETCLASS>& nc : resolvedNetclasses )
770 netclassPtrs.push_back( nc.get() );
771
772 wxString name;
773 name.Printf( "Effective for net: %s", aNetName );
774 std::shared_ptr<NETCLASS> effectiveNetclass = std::make_shared<NETCLASS>( name, false );
775 makeEffectiveNetclass( effectiveNetclass, netclassPtrs );
776
777 if( netclassPtrs.size() == 1 )
778 {
779 // No defaults were added - just return the primary netclass
780 m_effectiveNetclassCache[aNetName] = *resolvedNetclasses.begin();
781 return *resolvedNetclasses.begin();
782 }
783 else
784 {
785 effectiveNetclass->SetConstituentNetclasses( std::move( netclassPtrs ) );
786
787 m_compositeNetClasses[effectiveNetclass->GetName()] = effectiveNetclass;
788 m_effectiveNetclassCache[aNetName] = effectiveNetclass;
789
790 return effectiveNetclass;
791 }
792}
793
794
796{
797 for( auto& [ncName, nc] : m_compositeNetClasses )
798 {
799 // Note this needs to be a copy in case we now need to add the default netclass
800 std::vector<NETCLASS*> constituents = nc->GetConstituentNetclasses();
801
802 wxASSERT( constituents.size() > 0 );
803
804 // If the last netclass is Default, remove it (it will be re-added if still needed)
805 if( ( *constituents.rbegin() )->GetName() == NETCLASS::Default )
806 {
807 constituents.pop_back();
808 }
809
810 // Remake the netclass from original constituents
811 nc->ResetParameters();
812 makeEffectiveNetclass( nc, constituents );
813 nc->SetConstituentNetclasses( std::move( constituents ) );
814 }
815}
816
817
818void NET_SETTINGS::makeEffectiveNetclass( std::shared_ptr<NETCLASS>& effectiveNetclass,
819 std::vector<NETCLASS*>& constituentNetclasses ) const
820{
821 // Sort the resolved netclasses by priority (highest first), with same-priority netclasses
822 // ordered alphabetically
823 std::sort( constituentNetclasses.begin(), constituentNetclasses.end(),
824 []( NETCLASS* nc1, NETCLASS* nc2 )
825 {
826 int p1 = nc1->GetPriority();
827 int p2 = nc2->GetPriority();
828
829 if( p1 < p2 )
830 return true;
831
832 if (p1 == p2)
833 return nc1->GetName().Cmp( nc2->GetName() ) < 0;
834
835 return false;
836 } );
837
838 // Iterate from lowest priority netclass and fill effective netclass parameters
839 for( auto itr = constituentNetclasses.rbegin(); itr != constituentNetclasses.rend(); ++itr )
840 {
841 NETCLASS* nc = *itr;
842
843 if( nc->HasClearance() )
844 {
845 effectiveNetclass->SetClearance( nc->GetClearance() );
846 effectiveNetclass->SetClearanceParent( nc );
847 }
848
849 if( nc->HasTrackWidth() )
850 {
851 effectiveNetclass->SetTrackWidth( nc->GetTrackWidth() );
852 effectiveNetclass->SetTrackWidthParent( nc );
853 }
854
855 if( nc->HasViaDiameter() )
856 {
857 effectiveNetclass->SetViaDiameter( nc->GetViaDiameter() );
858 effectiveNetclass->SetViaDiameterParent( nc );
859 }
860
861 if( nc->HasViaDrill() )
862 {
863 effectiveNetclass->SetViaDrill( nc->GetViaDrill() );
864 effectiveNetclass->SetViaDrillParent( nc );
865 }
866
867 if( nc->HasuViaDiameter() )
868 {
869 effectiveNetclass->SetuViaDiameter( nc->GetuViaDiameter() );
870 effectiveNetclass->SetuViaDiameterParent( nc );
871 }
872
873 if( nc->HasuViaDrill() )
874 {
875 effectiveNetclass->SetuViaDrill( nc->GetuViaDrill() );
876 effectiveNetclass->SetuViaDrillParent( nc );
877 }
878
879 if( nc->HasDiffPairWidth() )
880 {
881 effectiveNetclass->SetDiffPairWidth( nc->GetDiffPairWidth() );
882 effectiveNetclass->SetDiffPairWidthParent( nc );
883 }
884
885 if( nc->HasDiffPairGap() )
886 {
887 effectiveNetclass->SetDiffPairGap( nc->GetDiffPairGap() );
888 effectiveNetclass->SetDiffPairGapParent( nc );
889 }
890
891 if( nc->HasDiffPairViaGap() )
892 {
893 effectiveNetclass->SetDiffPairViaGap( nc->GetDiffPairViaGap() );
894 effectiveNetclass->SetDiffPairViaGapParent( nc );
895 }
896
897 if( nc->HasWireWidth() )
898 {
899 effectiveNetclass->SetWireWidth( nc->GetWireWidth() );
900 effectiveNetclass->SetWireWidthParent( nc );
901 }
902
903 if( nc->HasBusWidth() )
904 {
905 effectiveNetclass->SetBusWidth( nc->GetBusWidth() );
906 effectiveNetclass->SetBusWidthParent( nc );
907 }
908
909 if( nc->HasLineStyle() )
910 {
911 effectiveNetclass->SetLineStyle( nc->GetLineStyle() );
912 effectiveNetclass->SetLineStyleParent( nc );
913 }
914
915 COLOR4D pcbColor = nc->GetPcbColor();
916
917 if( pcbColor != COLOR4D::UNSPECIFIED )
918 {
919 effectiveNetclass->SetPcbColor( pcbColor );
920 effectiveNetclass->SetPcbColorParent( nc );
921 }
922
923 COLOR4D schColor = nc->GetSchematicColor();
924
925 if( schColor != COLOR4D::UNSPECIFIED )
926 {
927 effectiveNetclass->SetSchematicColor( schColor );
928 effectiveNetclass->SetSchematicColorParent( nc );
929 }
930
931 if( nc->HasDelayProfile() )
932 {
933 effectiveNetclass->SetDelayProfile( nc->GetDelayProfile() );
934 effectiveNetclass->SetDelayProfileParent( nc );
935 }
936 }
937
938 // Fill in any required defaults
939 if( addMissingDefaults( effectiveNetclass.get() ) )
940 constituentNetclasses.push_back( m_defaultNetClass.get() );
941}
942
943
945{
946 bool addedDefault = false;
947
948 if( !nc->HasClearance() )
949 {
950 addedDefault = true;
951 nc->SetClearance( m_defaultNetClass->GetClearance() );
953 }
954
955 if( !nc->HasTrackWidth() )
956 {
957 addedDefault = true;
958 nc->SetTrackWidth( m_defaultNetClass->GetTrackWidth() );
960 }
961
962 if( !nc->HasViaDiameter() )
963 {
964 addedDefault = true;
965 nc->SetViaDiameter( m_defaultNetClass->GetViaDiameter() );
967 }
968
969 if( !nc->HasViaDrill() )
970 {
971 addedDefault = true;
972 nc->SetViaDrill( m_defaultNetClass->GetViaDrill() );
974 }
975
976 if( !nc->HasuViaDiameter() )
977 {
978 addedDefault = true;
979 nc->SetuViaDiameter( m_defaultNetClass->GetuViaDiameter() );
981 }
982
983 if( !nc->HasuViaDrill() )
984 {
985 addedDefault = true;
986 nc->SetuViaDrill( m_defaultNetClass->GetuViaDrill() );
988 }
989
990 if( !nc->HasDiffPairWidth() )
991 {
992 addedDefault = true;
993 nc->SetDiffPairWidth( m_defaultNetClass->GetDiffPairWidth() );
995 }
996
997 if( !nc->HasDiffPairGap() )
998 {
999 addedDefault = true;
1000 nc->SetDiffPairGap( m_defaultNetClass->GetDiffPairGap() );
1002 }
1003
1004 // Currently this is only on the default netclass, and not editable in the setup panel
1005 // if( !nc->HasDiffPairViaGap() )
1006 // {
1007 // addedDefault = true;
1008 // nc->SetDiffPairViaGap( m_defaultNetClass->GetDiffPairViaGap() );
1009 // nc->SetDiffPairViaGapParent( m_defaultNetClass.get() );
1010 // }
1011
1012 if( !nc->HasWireWidth() )
1013 {
1014 addedDefault = true;
1015 nc->SetWireWidth( m_defaultNetClass->GetWireWidth() );
1017 }
1018
1019 if( !nc->HasBusWidth() )
1020 {
1021 addedDefault = true;
1022 nc->SetBusWidth( m_defaultNetClass->GetBusWidth() );
1024 }
1025
1026 // The tuning profile can be empty - only fill if a default tuning profile is set
1027 if( !nc->HasDelayProfile() && m_defaultNetClass->HasDelayProfile() )
1028 {
1029 addedDefault = true;
1030 nc->SetDelayProfile( m_defaultNetClass->GetDelayProfile() );
1032 }
1033
1034 return addedDefault;
1035}
1036
1037
1038std::shared_ptr<NETCLASS> NET_SETTINGS::GetNetClassByName( const wxString& aNetClassName ) const
1039{
1040 auto ii = m_netClasses.find( aNetClassName );
1041
1042 if( ii == m_netClasses.end() )
1043 return m_defaultNetClass;
1044 else
1045 return ii->second;
1046}
1047
1048
1049static bool isSuperSubOverbar( wxChar c )
1050{
1051 return c == '_' || c == '^' || c == '~';
1052}
1053
1054
1055bool NET_SETTINGS::ParseBusVector( const wxString& aBus, wxString* aName,
1056 std::vector<wxString>* aMemberList )
1057{
1058 auto isDigit = []( wxChar c )
1059 {
1060 static wxString digits( wxT( "0123456789" ) );
1061 return digits.Contains( c );
1062 };
1063
1064 size_t busLen = aBus.length();
1065 size_t i = 0;
1066 wxString prefix;
1067 wxString suffix;
1068 wxString tmp;
1069 long begin = 0;
1070 long end = 0;
1071 int braceNesting = 0;
1072
1073 prefix.reserve( busLen );
1074
1075 // Parse prefix
1076 //
1077 for( ; i < busLen; ++i )
1078 {
1079 if( aBus[i] == '{' )
1080 {
1081 if( i > 0 && isSuperSubOverbar( aBus[i-1] ) )
1082 braceNesting++;
1083 else
1084 return false;
1085 }
1086 else if( aBus[i] == '}' )
1087 {
1088 braceNesting--;
1089 }
1090
1091 if( aBus[i] == ' ' || aBus[i] == ']' )
1092 return false;
1093
1094 if( aBus[i] == '[' )
1095 break;
1096
1097 prefix += aBus[i];
1098 }
1099
1100 // Parse start number
1101 //
1102 i++; // '[' character
1103
1104 if( i >= busLen )
1105 return false;
1106
1107 for( ; i < busLen; ++i )
1108 {
1109 if( aBus[i] == '.' && i + 1 < busLen && aBus[i+1] == '.' )
1110 {
1111 tmp.ToLong( &begin );
1112 i += 2;
1113 break;
1114 }
1115
1116 if( !isDigit( aBus[i] ) )
1117 return false;
1118
1119 tmp += aBus[i];
1120 }
1121
1122 // Parse end number
1123 //
1124 tmp = wxEmptyString;
1125
1126 if( i >= busLen )
1127 return false;
1128
1129 for( ; i < busLen; ++i )
1130 {
1131 if( aBus[i] == ']' )
1132 {
1133 tmp.ToLong( &end );
1134 ++i;
1135 break;
1136 }
1137
1138 if( !isDigit( aBus[i] ) )
1139 return false;
1140
1141 tmp += aBus[i];
1142 }
1143
1144 // Parse suffix
1145 //
1146 for( ; i < busLen; ++i )
1147 {
1148 if( aBus[i] == '}' )
1149 {
1150 braceNesting--;
1151 suffix += aBus[i];
1152 }
1153 else
1154 {
1155 return false;
1156 }
1157 }
1158
1159 if( braceNesting != 0 )
1160 return false;
1161
1162 if( begin == end )
1163 return false;
1164 else if( begin > end )
1165 std::swap( begin, end );
1166
1167 if( aName )
1168 *aName = prefix;
1169
1170 if( aMemberList )
1171 {
1172 for( long idx = begin; idx <= end; ++idx )
1173 {
1174 wxString str = prefix;
1175 str << idx;
1176 str << suffix;
1177
1178 aMemberList->emplace_back( str );
1179 }
1180 }
1181
1182 return true;
1183}
1184
1185
1186bool NET_SETTINGS::ParseBusGroup( const wxString& aGroup, wxString* aName,
1187 std::vector<wxString>* aMemberList )
1188{
1189 size_t groupLen = aGroup.length();
1190 size_t i = 0;
1191 wxString prefix;
1192 wxString tmp;
1193 int braceNesting = 0;
1194
1195 prefix.reserve( groupLen );
1196
1197 // Parse prefix
1198 //
1199 for( ; i < groupLen; ++i )
1200 {
1201 if( aGroup[i] == '{' )
1202 {
1203 if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) )
1204 braceNesting++;
1205 else
1206 break;
1207 }
1208 else if( aGroup[i] == '}' )
1209 {
1210 braceNesting--;
1211 }
1212
1213 if( aGroup[i] == ' ' || aGroup[i] == '[' || aGroup[i] == ']' )
1214 return false;
1215
1216 prefix += aGroup[i];
1217 }
1218
1219 if( braceNesting != 0 )
1220 return false;
1221
1222 if( aName )
1223 *aName = prefix;
1224
1225 // Parse members
1226 //
1227 i++; // '{' character
1228
1229 if( i >= groupLen )
1230 return false;
1231
1232 for( ; i < groupLen; ++i )
1233 {
1234 if( aGroup[i] == '{' )
1235 {
1236 if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) )
1237 braceNesting++;
1238 else
1239 return false;
1240 }
1241 else if( aGroup[i] == '}' )
1242 {
1243 if( braceNesting )
1244 {
1245 braceNesting--;
1246 }
1247 else
1248 {
1249 if( aMemberList && !tmp.IsEmpty() )
1250 aMemberList->push_back( EscapeString( tmp, CTX_NETNAME ) );
1251
1252 return true;
1253 }
1254 }
1255
1256 // Commas aren't strictly legal, but we can be pretty sure what the author had in mind.
1257 if( aGroup[i] == ' ' || aGroup[i] == ',' )
1258 {
1259 if( aMemberList && !tmp.IsEmpty() )
1260 aMemberList->push_back( EscapeString( tmp, CTX_NETNAME ) );
1261
1262 tmp.Clear();
1263 continue;
1264 }
1265
1266 tmp += aGroup[i];
1267 }
1268
1269 return false;
1270}
int color
Definition: DXF_plotter.cpp:63
const char * name
Definition: DXF_plotter.cpp:62
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:114
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:45
void SetViaDiameter(int aDia)
Definition: netclass.h:132
void SetViaDrill(int aSize)
Definition: netclass.h:140
bool HasLineStyle() const
Definition: netclass.h:230
void SetDelayProfileParent(NETCLASS *aParent)
Definition: netclass.h:244
int GetViaDiameter() const
Definition: netclass.h:130
int GetViaDrill() const
Definition: netclass.h:138
void SetWireWidthParent(NETCLASS *parent)
Definition: netclass.h:205
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:47
void SetuViaDrillParent(NETCLASS *parent)
Definition: netclass.h:158
bool HasDelayProfile() const
Definition: netclass.h:241
bool HasBusWidth() const
Definition: netclass.h:208
bool HasuViaDrill() const
Definition: netclass.h:153
void SetDiffPairWidthParent(NETCLASS *parent)
Definition: netclass.h:166
void SetuViaDiameter(int aSize)
Definition: netclass.h:148
void SetDiffPairWidth(int aSize)
Definition: netclass.h:164
int HasViaDrill() const
Definition: netclass.h:137
int GetDiffPairViaGap() const
Definition: netclass.h:178
void SetViaDrillParent(NETCLASS *parent)
Definition: netclass.h:142
void SetDiffPairGapParent(NETCLASS *parent)
Definition: netclass.h:174
int GetDiffPairGap() const
Definition: netclass.h:170
int GetuViaDrill() const
Definition: netclass.h:154
bool HasViaDiameter() const
Definition: netclass.h:129
int GetLineStyle() const
Definition: netclass.h:231
bool HasDiffPairWidth() const
Definition: netclass.h:161
bool HasuViaDiameter() const
Definition: netclass.h:145
void SetTrackWidthParent(NETCLASS *parent)
Definition: netclass.h:126
int GetuViaDiameter() const
Definition: netclass.h:146
bool HasTrackWidth() const
Definition: netclass.h:121
void SetViaDiameterParent(NETCLASS *parent)
Definition: netclass.h:134
int GetDiffPairWidth() const
Definition: netclass.h:162
void SetuViaDrill(int aSize)
Definition: netclass.h:156
void SetDelayProfile(const wxString &aDelayProfile)
Definition: netclass.h:242
int GetWireWidth() const
Definition: netclass.h:201
void SetDiffPairGap(int aSize)
Definition: netclass.h:172
void SetBusWidthParent(NETCLASS *parent)
Definition: netclass.h:213
void SetClearance(int aClearance)
Definition: netclass.h:116
COLOR4D GetPcbColor(bool aIsForSave=false) const
Definition: netclass.h:186
bool HasDiffPairGap() const
Definition: netclass.h:169
COLOR4D GetSchematicColor(bool aIsForSave=false) const
Definition: netclass.h:216
void SetBusWidth(int aWidth)
Definition: netclass.h:211
wxString GetDelayProfile() const
Definition: netclass.h:243
void SetClearanceParent(NETCLASS *parent)
Definition: netclass.h:118
int GetTrackWidth() const
Definition: netclass.h:122
void SetWireWidth(int aWidth)
Definition: netclass.h:203
bool HasWireWidth() const
Definition: netclass.h:200
int GetClearance() const
Definition: netclass.h:114
void SetuViaDiameterParent(NETCLASS *parent)
Definition: netclass.h:150
void SetTrackWidth(int aWidth)
Definition: netclass.h:124
bool HasDiffPairViaGap() const
Definition: netclass.h:177
int GetBusWidth() const
Definition: netclass.h:209
bool HasClearance() const
Definition: netclass.h:113
NET_SETTINGS stores various net-related settings in a project context.
Definition: net_settings.h:39
void ClearAllCaches()
Clears the effective netclass cache for all nets.
std::map< wxString, std::shared_ptr< NETCLASS > > m_compositeNetClasses
Map of netclass names to netclass definitions for.
Definition: net_settings.h:223
bool addMissingDefaults(NETCLASS *nc) const
Adds any missing fields to the given netclass from the default netclass.
void ClearNetColorAssignments()
Clears all net name to color assignments Calling user is responsible for resetting the effective netc...
bool operator==(const NET_SETTINGS &aOther) const
void ClearCacheForNet(const wxString &netName)
Clears effective netclass cache for the given net.
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const wxString &aNetName)
Fetches the effective (may be aggregate) netclass for the given net name.
bool HasEffectiveNetClass(const wxString &aNetName) const
Determines if an effective netclass for the given net name has been cached.
void ClearNetclassLabelAssignments()
Clears all net name to netclasses assignments Calling user is responsible for resetting the effective...
void ClearNetclassLabelAssignment(const wxString &netName)
Clears a specific net name to netclass assignment Calling user is responsible for resetting the effec...
void ClearNetclassPatternAssignments()
Clears all netclass pattern assignments.
std::map< wxString, KIGFX::COLOR4D > m_netColorAssignments
A map of fully-qualified net names to colors used in the board context.
Definition: net_settings.h:242
void SetNetclasses(const std::map< wxString, std::shared_ptr< NETCLASS > > &netclasses)
Sets all netclass Calling this method will reset the effective netclass calculation caches.
bool HasNetclassLabelAssignment(const wxString &netName) const
Determines if a given net name has netclasses assigned.
void SetNetclassLabelAssignment(const wxString &netName, const std::set< wxString > &netclasses)
Sets a net name to netclasses assignment Calling user is responsible for resetting the effective netc...
std::shared_ptr< NETCLASS > m_defaultNetClass
The default netclass.
Definition: net_settings.h:209
virtual ~NET_SETTINGS()
static bool ParseBusGroup(const wxString &aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parse a bus group label into the name and a list of components.
void ClearNetclasses()
Clears all netclasses Calling this method will reset the effective netclass calculation caches.
std::map< wxString, std::shared_ptr< NETCLASS > > m_impicitNetClasses
Map of netclass names to netclass definitions for implicit netclasses.
Definition: net_settings.h:231
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetCompositeNetclasses() const
Gets all composite (multiple assignment / missing defaults) netclasses.
std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > m_netClassPatternAssignments
List of net class pattern assignments.
Definition: net_settings.h:219
bool migrateSchema3to4()
bool migrateSchema0to1()
std::map< wxString, std::shared_ptr< NETCLASS > > m_effectiveNetclassCache
Cache of nets to pattern-matched netclasses.
Definition: net_settings.h:234
void SetNetclassPatternAssignments(std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > &&netclassPatterns)
Sets all netclass pattern assignments Calling user is responsible for resetting the effective netclas...
void SetNetclassPatternAssignment(const wxString &pattern, const wxString &netclass)
Sets a netclass pattern assignment Calling this method will reset the effective netclass calculation ...
bool migrateSchema2to3()
std::map< wxString, std::shared_ptr< NETCLASS > > m_netClasses
Map of netclass names to netclass definitions.
Definition: net_settings.h:212
const std::map< wxString, std::set< wxString > > & GetNetclassLabelAssignments() const
Gets all current net name to netclasses assignments.
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetNetclasses() const
Gets all netclasses.
std::shared_ptr< NETCLASS > GetDefaultNetclass()
Gets the default netclass for the project.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
const std::map< wxString, KIGFX::COLOR4D > & GetNetColorAssignments() const
Gets all net name to color assignments.
bool migrateSchema1to2()
std::vector< std::pair< std::unique_ptr< EDA_COMBINED_MATCHER >, wxString > > & GetNetclassPatternAssignments()
Gets the netclass pattern assignments.
void RecomputeEffectiveNetclasses()
Recomputes the internal values of all aggregate effective netclasses Called when a value of a user-de...
std::shared_ptr< NETCLASS > GetCachedEffectiveNetClass(const wxString &aNetName) const
Returns an already cached effective netclass for the given net name.
bool migrateSchema4to5()
std::map< wxString, std::set< wxString > > m_netClassLabelAssignments
Map of net names to resolved netclasses.
Definition: net_settings.h:215
void SetNetclass(const wxString &netclassName, std::shared_ptr< NETCLASS > &netclass)
Sets the given netclass Calling user is responsible for resetting the effective netclass calculation ...
void makeEffectiveNetclass(std::shared_ptr< NETCLASS > &effectiveNetclass, std::vector< NETCLASS * > &netclasses) const
Creates an effective aggregate netclass from the given constituent netclasses.
void AppendNetclassLabelAssignment(const wxString &netName, const std::set< wxString > &netclasses)
Apppends to a net name to netclasses assignment Calling user is responsible for resetting the effecti...
void SetDefaultNetclass(std::shared_ptr< NETCLASS > netclass)
Sets the default netclass for the project Calling user is responsible for resetting the effective net...
std::shared_ptr< NETCLASS > GetNetClassByName(const wxString &aNetName) const
Get a NETCLASS object from a given Netclass name string.
void SetNetColorAssignment(const wxString &netName, const KIGFX::COLOR4D &color)
Sets a net to color assignment Calling user is responsible for resetting the effective netclass calcu...
NET_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
bool HasNetclass(const wxString &netclassName) const
Determines if the given netclass exists.
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:295
bool isDigit(char cc)
Definition: dsnlexer.cpp:468
#define _(s)
@ CTX_NETCLASS
nlohmann::json json
Definition: gerbview.cpp:50
static bool isSuperSubOverbar(wxChar c)
const int netSettingsSchemaVersion
static std::optional< int > getInSchUnits(const nlohmann::json &aObj, const std::string &aKey, std::optional< int > aDefault=std::optional< int >())
static std::optional< int > getInPcbUnits(const nlohmann::json &aObj, const std::string &aKey, std::optional< int > aDefault=std::optional< int >())
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NETNAME
Definition: string_utils.h:53
constexpr double IUTomm(int iu) const
Definition: base_units.h:90
constexpr int IUToMils(int iu) const
Definition: base_units.h:103
constexpr int MilsToIU(int mils) const
Definition: base_units.h:97
constexpr int mmToIU(double mm) const
Definition: base_units.h:92
VECTOR2I end