20#include <boost/test/unit_test.hpp>
53#include <wx/filename.h>
89 const std::map<int, int>
expected = { { 9, 1 }, { 10, 2 }, { 2, 3 }, { 13, 4 }, { 24, 5 },
90 { 66, 1 }, { 16, 2 }, { 12, 3 }, { 64, 4 } };
92 for(
const auto& [type, depth] :
expected )
95 BOOST_REQUIRE_MESSAGE(
actual,
"type " << type );
120 "Sch 2: PCI Connector" );
148 constexpr uint32_t legacyModified = 0x56A2631C;
149 constexpr uint32_t currentModified = 0x652CEBA8;
160 BOOST_CHECK_GT( reverseDiagonal.size(), 40u );
161 BOOST_CHECK_LT( reverseDiagonal.size(), 48u );
162 BOOST_CHECK( std::all_of( reverseDiagonal.begin(), reverseDiagonal.end(),
163 [](
const SEG& aLine )
165 return static_cast<int64_t>( aLine.B.x - aLine.A.x )
166 * ( aLine.B.y - aLine.A.y )
171 BOOST_CHECK_GT( diagonalCross.size(), 80u );
172 BOOST_CHECK_LT( diagonalCross.size(), 96u );
175 BOOST_CHECK_GT( orthogonalCross.size(), 40u );
176 BOOST_CHECK_LT( orthogonalCross.size(), 48u );
177 BOOST_CHECK( std::any_of( orthogonalCross.begin(), orthogonalCross.end(),
178 [](
const SEG& aLine ) { return aLine.A.x == aLine.B.x; } ) );
179 BOOST_CHECK( std::any_of( orthogonalCross.begin(), orthogonalCross.end(),
180 [](
const SEG& aLine ) { return aLine.A.y == aLine.B.y; } ) );
183 BOOST_CHECK_GT( currentCross.size(), 20u );
184 BOOST_CHECK_LT( currentCross.size(), 40u );
190 wxString dashed = wxS(
"03 - CAN" );
191 wxString dotted = wxS(
"02.uC" );
192 wxString colon = wxS(
"13:IMU" );
193 wxString folder = wxS(
"Sch 7: CAN Drivers" );
194 wxString pager = wxS(
"PAGER 8" );
195 wxString underscored = wxS(
"PAGE_03_HSMC CONNECTOR" );
196 wxString compact = wxS(
"PAGE01 OVERALL BLOCK DIAGRAM" );
197 wxString plain = wxS(
"Overview" );
236 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
238 if( !corpusEnv || !*corpusEnv )
240 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping multi-preview OLE check." );
244 std::filesystem::path dsn;
246 for(
const std::filesystem::directory_entry& entry : std::filesystem::recursive_directory_iterator( corpusEnv ) )
248 if( entry.is_regular_file() && entry.path().filename() ==
"reServer industrial J401 Carrier Board v11.DSN" )
257 BOOST_TEST_MESSAGE(
"reServer industrial J401 design not present; skipping multi-preview OLE check." );
261 std::ifstream stream( dsn, std::ios::binary );
262 std::vector<uint8_t> bytes( std::istreambuf_iterator<char>( stream ), {} );
263 const std::array<std::array<uint8_t, 8>, 2> markers = {
264 std::array<uint8_t, 8>{ 0x6A, 0x31, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00 },
265 std::array<uint8_t, 8>{ 0x16, 0x94, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00 }
268 for(
size_t markerIndex = 0; markerIndex < markers.size(); ++markerIndex )
270 const auto& marker = markers[markerIndex];
271 auto markerPos = std::search( bytes.begin(), bytes.end(), marker.begin(), marker.end() );
274 size_t offset =
static_cast<size_t>( std::distance( bytes.begin(), markerPos ) );
275 size_t size =
static_cast<size_t>( bytes[offset] ) | (
static_cast<size_t>( bytes[offset + 1] ) << 8 )
276 | (
static_cast<size_t>( bytes[offset + 2] ) << 16 )
277 | (
static_cast<size_t>( bytes[offset + 3] ) << 24 );
278 BOOST_REQUIRE_LE( offset + size + 4, bytes.size() );
283 BOOST_CHECK_GT( preview.
data.size(), 200000u );
287 "marker " << markerIndex <<
", preview bytes " << preview.
data.size() <<
", "
289 BOOST_CHECK_GT(
image.GetWidth(), 1000 );
290 BOOST_CHECK_GT(
image.GetHeight(), 500 );
295static std::string
terminalToken(
const std::string& aRef,
const std::string& aPin );
297 std::vector<std::set<std::string>>* aInconsistent =
nullptr );
306 if( symbol->
GetRef( &aPath,
false ) == aReference )
314static std::filesystem::path
findCorpusDesign(
const std::filesystem::path& aRoot,
const std::string& aFileName );
319 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
321 if( !corpusEnv || !*corpusEnv )
329 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
332 schematic->SetProject( &manager.
Prj() );
333 schematic->CurrentSheet().clear();
334 schematic->CurrentSheet().push_back( &schematic->Root() );
339 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
340 schematic->ConnectionGraph()->Recalculate( sheets,
true );
343 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
347 for(
SCH_ITEM* item : subgraph->GetItems() )
355 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"C1" )
356 &&
pin->GetNumber() == wxS(
"1" ) )
358 c1Pin1Net = key.Name;
370 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
372 if( !corpusEnv || !*corpusEnv )
380 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
383 schematic->SetProject( &manager.
Prj() );
384 schematic->CurrentSheet().clear();
385 schematic->CurrentSheet().push_back( &schematic->Root() );
390 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
391 schematic->ConnectionGraph()->Recalculate( sheets,
true );
394 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
398 if( !subgraph->GetSheet().LastScreen()->GetFileName().Contains( wxS(
"_PSU" ) ) )
401 for(
SCH_ITEM* item : subgraph->GetItems() )
410 pinNets[{ symbol->
GetRef( &subgraph->GetSheet(),
false ),
pin->GetNumber() }] = subgraph;
415 BOOST_REQUIRE( pinNets.count( { wxS(
"C126" ), wxS(
"1" ) } ) );
416 BOOST_REQUIRE( pinNets.count( { wxS(
"U15" ), wxS(
"3" ) } ) );
417 BOOST_REQUIRE( pinNets.count( { wxS(
"U15" ), wxS(
"8" ) } ) );
419 pinNets.at( { wxS(
"U15" ), wxS(
"3" ) } ) );
421 pinNets.at( { wxS(
"U15" ), wxS(
"3" ) } ) );
427 wxFileName missing( wxFileName::GetTempDir(), wxS(
"qa_orcad_does_not_exist.dsn" ) );
430 BOOST_CHECK( !m_plugin.CanReadSchematicFile( missing.GetFullPath() ) );
438 auto notSpace = [](
unsigned char c )
440 return !std::isspace( c );
442 aText.erase( aText.begin(), std::find_if( aText.begin(), aText.end(), notSpace ) );
443 aText.erase( std::find_if( aText.rbegin(), aText.rend(), notSpace ).base(), aText.end() );
445 if( aText.size() >= 2 && aText.front() ==
'"' && aText.back() ==
'"' )
446 aText = aText.substr( 1, aText.size() - 2 );
452static std::vector<std::string>
splitRefs(
const std::string& aCell )
454 std::vector<std::string> refs;
457 for(
char c : aCell )
485 std::set<std::string> refs;
486 std::ifstream in( aPath );
490 while( std::getline( in, line ) )
492 if( !line.empty() && line.back() ==
'\r' )
495 std::vector<std::string> cols;
502 cols.push_back( cell );
511 cols.push_back( cell );
516 for(
size_t i = 0; i < cols.size(); ++i )
518 if(
trimCell( cols[i] ) ==
"Reference" )
520 refCol =
static_cast<int>( i );
528 if( refCol <
static_cast<int>( cols.size() ) )
541 std::set<std::string> refs;
542 std::ifstream in( aPath );
545 while( std::getline( in, line ) )
547 if( line.rfind(
".ADD_COM", 0 ) != 0 )
551 std::string rest =
trimCell( line.substr( 8 ) );
556 if( std::isspace(
static_cast<unsigned char>( c ) ) )
574 std::set<std::string> refs;
587 wxString ref = symbol->
GetRef( &
path,
false );
590 if( ref.IsEmpty() || ref.StartsWith( wxS(
"#" ) ) || ref.EndsWith( wxS(
"?" ) ) )
593 refs.insert( std::string( ref.ToUTF8() ) );
601static std::string
terminalToken(
const std::string& aRef,
const std::string& aPin )
611 std::vector<std::set<std::string>> nets;
612 std::set<std::string> current;
613 std::ifstream in( aPath );
618 if( current.size() >= 2 )
619 nets.push_back( current );
624 while( std::getline( in, line ) )
626 if( !line.empty() && line.back() ==
'\r' )
629 bool addTer = line.rfind(
".ADD_TER", 0 ) == 0;
630 bool ter = line.rfind(
".TER", 0 ) == 0;
631 bool cont = !line.empty() && std::isspace(
static_cast<unsigned char>( line[0] ) );
633 if( line.rfind(
".END", 0 ) == 0 )
639 if( addTer || ter || cont )
641 std::istringstream ss( addTer ? line.substr( 8 ) : ter ? line.substr( 4 ) : line );
642 std::string ref,
pin;
644 if( ss >> ref >>
pin )
657 std::vector<std::set<std::string>>* aInconsistent )
662 std::map<std::string, int> pinNet;
669 for(
SCH_ITEM* item : subgraph->GetItems() )
680 wxString ref = symbol->
GetRef( &subgraph->GetSheet(),
false );
682 if( ref.IsEmpty() || ref.StartsWith( wxS(
"#" ) ) || ref.EndsWith( wxS(
"?" ) ) )
685 pinNet[
terminalToken( std::string( ref.ToUTF8() ), std::string(
pin->GetNumber().ToUTF8() ) )] = netId;
694 const std::set<std::string>* terminals;
698 std::vector<CHECKED_NET> checkedNets;
699 std::map<int, int> sourceNetsPerImportedNet;
701 for(
const std::set<std::string>& net : aNets )
706 for(
const std::string& term : net )
708 auto it = pinNet.find( term );
710 if( it != pinNet.end() )
712 ids.insert( it->second );
719 if( ids.size() == 1 )
720 sourceNetsPerImportedNet[*ids.begin()]++;
722 checkedNets.push_back( { &net, std::move( ids ) } );
728 for(
const CHECKED_NET& net : checkedNets )
730 bool exact = net.ids.size() == 1 && sourceNetsPerImportedNet[*net.ids.begin()] == 1;
734 else if( aInconsistent )
735 aInconsistent->push_back( *net.terminals );
738 return { consistent,
static_cast<int>( checkedNets.size() ) };
751 for(
SCH_ITEM* item : subgraph->GetItems() )
759 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == aReference
760 &&
pin->GetNumber() == aPinNumber )
773static std::set<std::string>
expectedRefsFor(
const std::filesystem::path& aDsn, std::string& aSource )
775 for(
const char* ext : {
".NET",
".net",
".BOM",
".bom" } )
777 std::filesystem::path candidate = aDsn;
778 candidate.replace_extension( ext );
780 if( std::filesystem::exists( candidate ) )
782 aSource = candidate.filename().string();
784 bool isNet = std::string( ext ) ==
".NET" || std::string( ext ) ==
".net";
796 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
798 if( !corpusEnv || !*corpusEnv )
800 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD corpus validation." );
804 namespace fs = std::filesystem;
805 fs::path root( corpusEnv );
807 BOOST_REQUIRE_MESSAGE( fs::exists( root ),
"KICAD_ORCAD_CORPUS path does not exist." );
809 std::vector<fs::path> designs;
811 for(
auto it = fs::recursive_directory_iterator( root, fs::directory_options::skip_permission_denied );
812 it != fs::recursive_directory_iterator(); ++it )
814 if( !it->is_regular_file() )
817 std::string ext = it->path().extension().string();
818 std::transform( ext.begin(), ext.end(), ext.begin(),
819 [](
unsigned char c )
821 return std::tolower( c );
825 designs.push_back( it->path() );
828 std::sort( designs.begin(), designs.end() );
830 BOOST_TEST_MESSAGE(
"OrCAD corpus: " << designs.size() <<
" .DSN files under " << root );
832 int imported = 0, crashed = 0, unsupported = 0, rejected = 0, checked = 0;
833 unsigned int totalExpected = 0, totalMatched = 0, totalMissing = 0, totalExtra = 0;
834 int netConsistent = 0, netCheckable = 0, netTotal = 0;
835 uint64_t importedPages = 0, importedComponents = 0, importedPowerSymbols = 0;
836 uint64_t importedPins = 0, importedWires = 0, importedBuses = 0;
837 uint64_t importedLabels = 0, importedShapes = 0, importedTexts = 0, importedBitmaps = 0;
839 const char* debugEnv = std::getenv(
"KICAD_ORCAD_DEBUG" );
840 std::string debugFilter = debugEnv ? debugEnv :
"";
841 const char* filterEnv = std::getenv(
"KICAD_ORCAD_FILTER" );
842 std::string designFilter = filterEnv ? filterEnv :
"";
844 for(
const fs::path& dsn : designs )
846 std::string rel = fs::relative( dsn, root ).string();
848 if( !designFilter.empty() && rel.find( designFilter ) == std::string::npos )
851 BOOST_TEST_INFO_SCOPE(
"OrCAD source: " << rel );
854 uint64_t perDesignPages = 0, perDesignComponents = 0, perDesignPowerSymbols = 0;
855 uint64_t perDesignPins = 0, perDesignWires = 0, perDesignBuses = 0;
856 uint64_t perDesignLabels = 0, perDesignShapes = 0, perDesignTexts = 0;
857 uint64_t perDesignBitmaps = 0;
858 uint64_t perDesignRedWires = 0;
859 uint64_t perDesignVddmPowerSymbols = 0;
861 bool debug = !debugFilter.empty() && rel.find( debugFilter ) != std::string::npos;
870 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
872 schematic->SetProject( &manager.
Prj() );
873 schematic->CurrentSheet().clear();
874 schematic->CurrentSheet().push_back( &schematic->Root() );
882 schematic->CurrentSheet().UpdateAllScreenReferences();
884 catch(
const std::exception& e )
887 if( std::string( e.what() ).find(
"pre-2003" ) != std::string::npos )
910 switch( item->Type() )
915 wxString ref = symbol->
GetRef( &
path,
false );
917 if( ref.StartsWith( wxS(
"#" ) ) )
919 ++importedPowerSymbols;
920 ++perDesignPowerSymbols;
923 ++perDesignVddmPowerSymbols;
927 ++importedComponents;
928 ++perDesignComponents;
932 importedPins += pinCount;
933 perDesignPins += pinCount;
985 BOOST_TEST_MESSAGE(
" AUDIT " << rel <<
"|pages=" << perDesignPages <<
"|components=" << perDesignComponents
986 <<
"|power=" << perDesignPowerSymbols <<
"|pins=" << perDesignPins
987 <<
"|wires=" << perDesignWires <<
"|buses=" << perDesignBuses
988 <<
"|labels=" << perDesignLabels <<
"|shapes=" << perDesignShapes
989 <<
"|texts=" << perDesignTexts <<
"|bitmaps=" << perDesignBitmaps );
991 if( rel ==
"allegro/beagleboard-xm/SCH/BeagleBoard-xM_ORCAD.DSN" )
999 ==
"allegro/OpenCellular-LED/Rev-C/schematic/"
1000 "OpenCellular_Connect-1_LED_Life-3_Schematic.DSN" )
1006 ==
"orcad/OpenCellular-GBC-Elgon_ARM/Rev-A/schematics/"
1007 "CN81XX_GBCV2_sch_0530.DSN" )
1014 << std::string(
reporter.GetMessages().ToUTF8() ) );
1026 std::set<std::string> missing, extra;
1027 std::set_difference(
expected.begin(),
expected.end(), got.begin(), got.end(),
1028 std::inserter( missing, missing.begin() ) );
1029 std::set_difference( got.begin(), got.end(),
expected.begin(),
expected.end(),
1030 std::inserter( extra, extra.begin() ) );
1032 unsigned int matched =
static_cast<unsigned int>(
expected.size() - missing.size() );
1036 totalMatched += matched;
1037 totalMissing += missing.size();
1038 totalExtra += extra.size();
1041 <<
int( 100.0 * matched /
expected.size() ) <<
"%), extra " << extra.size()
1042 <<
" [" <<
source <<
"]" );
1046 for(
const std::string& ref : missing )
1049 for(
const std::string& ref : extra )
1054 std::filesystem::path net = dsn;
1055 net.replace_extension(
source.size() >= 4 &&
source.substr(
source.size() - 4 ) ==
".net" ?
".net" :
".NET" );
1057 if( std::filesystem::exists( net ) )
1063 std::vector<std::set<std::string>> inconsistent;
1064 auto [consistent, checkableNets] =
checkConnectivity( *schematic, nets, &inconsistent );
1065 netConsistent += consistent;
1066 netCheckable += checkableNets;
1067 netTotal +=
static_cast<int>( nets.size() );
1070 <<
" nets consistent" );
1074 for(
const std::set<std::string>& terminals : inconsistent )
1078 for(
const std::string& terminal : terminals )
1080 if( !joined.empty() )
1094 BOOST_TEST_MESSAGE(
" designs: " << designs.size() <<
" imported: " << imported <<
" crashed: " << crashed
1095 <<
" unsupported: " << unsupported <<
" rejected: " << rejected );
1097 << importedPages <<
" components " << importedComponents <<
" power " << importedPowerSymbols
1098 <<
" pins " << importedPins <<
" wires " << importedWires <<
" buses " << importedBuses
1099 <<
" labels " << importedLabels <<
" shapes " << importedShapes <<
" texts " << importedTexts
1100 <<
" bitmaps " << importedBitmaps );
1104 BOOST_TEST_MESSAGE(
" refdes coverage: " << totalMatched <<
"/" << totalExpected <<
" ("
1105 <<
int( 100.0 * totalMatched / totalExpected )
1106 <<
"%) missing: " << totalMissing <<
" extra: " << totalExtra );
1111 BOOST_TEST_MESSAGE(
" net connectivity: " << netConsistent <<
"/" << netCheckable <<
" ("
1112 <<
int( 100.0 * netConsistent / netCheckable ) <<
"%)" );
1116 BOOST_CHECK_MESSAGE( crashed == 0, crashed <<
" design(s) crashed during import." );
1118 const char* snapshotEnv = std::getenv(
"KICAD_ORCAD_CORPUS_SNAPSHOT" );
1121 if( designFilter.empty() )
1122 BOOST_REQUIRE_MESSAGE( checked > 0,
"No ground-truth .BOM/.NET companions were validated." );
1124 if( designFilter.empty() && snapshotEnv && *snapshotEnv )
1134 BOOST_CHECK_GE( 100.0 * totalMatched / totalExpected, 95.0 );
1140 BOOST_CHECK_GE( 100.0 * netCheckable / netTotal, 80.0 );
1146static std::filesystem::path
findCorpusDesign(
const std::filesystem::path& aRoot,
const std::string& aFileName )
1148 for(
const std::filesystem::directory_entry& entry : std::filesystem::recursive_directory_iterator( aRoot ) )
1150 if( entry.is_regular_file() && entry.path().filename() == aFileName )
1151 return entry.path();
1160 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1162 if( !corpusEnv || !*corpusEnv )
1165 std::filesystem::path dsn =
1166 std::filesystem::path( corpusEnv ) /
"PADS" /
"skyworks-eval" /
"SI34061FB12V4KIT"
1167 /
"si34061-evb-ext_1.7.1.20220111" /
"schematic" /
"SI34061-EVB-EXT.DSN";
1169 if( !std::filesystem::exists( dsn ) )
1171 BOOST_TEST_MESSAGE(
"SI34061-EVB-EXT 12 V design not present; skipping CIS variant check." );
1175 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1178 schematic->SetProject( &manager.
Prj() );
1179 schematic->CurrentSheet().clear();
1180 schematic->CurrentSheet().push_back( &schematic->Root() );
1185 std::map<wxString, std::pair<SCH_SYMBOL*, SCH_SHEET_PATH>> symbols;
1192 symbols.emplace( symbol->
GetRef( &
path,
false ), std::make_pair( symbol,
path ) );
1197 BOOST_CHECK( schematic->GetVariantNames() == std::set<wxString>( { wxS(
"12V" ), wxS(
"5V" ) } ) );
1200 auto fieldText = [&](
const wxString& aRef,
const wxString& aField,
const wxString& aVariant )
1203 auto& [symbol,
path] = symbols.at( aRef );
1204 return symbol->GetFieldText( aField, &
path, aVariant );
1207 BOOST_CHECK_EQUAL( fieldText( wxS(
"U1" ), wxS(
"Value" ), wxS(
"12V" ) ), wxS(
"NVMFS5C680NLT1G" ) );
1208 BOOST_CHECK_EQUAL( fieldText( wxS(
"D13" ), wxS(
"Value" ), wxS(
"12V" ) ), wxS(
"PDS5100" ) );
1209 BOOST_CHECK_EQUAL( fieldText( wxS(
"T2" ), wxS(
"Value" ), wxS(
"12V" ) ), wxS(
"LDT1026-50R" ) );
1211 wxS(
"LABEL-Si34061-EVB-EXT-BOM-R1.7-12V" ) );
1213 wxS(
"LABEL-Si34061-EVB-EXT-BOM R1.7" ) );
1214 BOOST_CHECK_EQUAL( fieldText( wxS(
"U1" ), wxS(
"Voltage" ), wxS(
"12V" ) ), wxS(
"60V" ) );
1218 BOOST_CHECK( !symbols.at( wxS(
"C19" ) ).first->FindFieldCaseInsensitive( wxS(
"Part type" ) ) );
1219 BOOST_CHECK( !symbols.at( wxS(
"C19" ) ).first->FindFieldCaseInsensitive( wxS(
"Power Pins Visible" ) ) );
1223 auto& [c16, c16Path] = symbols.at( wxS(
"C16" ) );
1224 BOOST_CHECK( c16->GetDNP( &c16Path, wxS(
"12V" ) ) );
1225 BOOST_CHECK( !c16->GetDNP( &c16Path, wxS(
"5V" ) ) );
1226 BOOST_CHECK( !c16->GetDNP( &c16Path ) );
1228 for(
const wxString& ref : { wxS(
"D15" ), wxS(
"R35" ), wxS(
"TP1" ) } )
1231 BOOST_CHECK( symbols.at( ref ).first->GetDNP() );
1238 bool variantNameFound =
false;
1243 BOOST_CHECK_NE(
text, wxS(
"<Core Design>" ) );
1244 variantNameFound |=
text == wxS(
"12V" );
1247 BOOST_CHECK( variantNameFound );
1248 BOOST_CHECK_EQUAL(
path.LastScreen()->GetTitleBlock().GetComment( 1 ), wxS(
"Variant Name: ${VARIANT}" ) );
1255 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1257 if( !corpusEnv || !*corpusEnv )
1260 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"PROJET INDUS.DSN" );
1265 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1268 schematic->SetProject( &manager.
Prj() );
1269 schematic->CurrentSheet().clear();
1270 schematic->CurrentSheet().push_back( &schematic->Root() );
1275 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
1276 size_t excluded = 0;
1277 size_t excludedSymbols = 0;
1281 excluded +=
path.GetExcludedFromBoard();
1283 if( !
path.GetExcludedFromBoard() )
1289 BOOST_CHECK(
static_cast<SCH_SYMBOL*
>( item )->GetExcludedFromBoard() );
1295 BOOST_CHECK_GT( excludedSymbols, 0u );
1301 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1303 if( !corpusEnv || !*corpusEnv )
1306 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC1987A-2.DSN" );
1311 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1314 schematic->SetProject( &manager.
Prj() );
1315 schematic->CurrentSheet().clear();
1316 schematic->CurrentSheet().push_back( &schematic->Root() );
1321 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
1322 BOOST_REQUIRE_EQUAL( sheets.size(), 1u );
1328 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1330 if( !corpusEnv || !*corpusEnv )
1338 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1341 schematic->SetProject( &manager.
Prj() );
1342 schematic->CurrentSheet().clear();
1343 schematic->CurrentSheet().push_back( &schematic->Root() );
1364 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1366 if( !corpusEnv || !*corpusEnv )
1374 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1377 schematic->SetProject( &manager.
Prj() );
1378 schematic->CurrentSheet().clear();
1379 schematic->CurrentSheet().push_back( &schematic->Root() );
1384 auto [consistent, checkable] =
1394 std::map<std::string, std::vector<std::string>> uuids;
1398 std::ostringstream identity;
1401 identity << item.
Type() <<
':' << item.
GetLayer() <<
':' << position.
x <<
',' << position.
y
1402 <<
':' << bounds.
GetX() <<
',' << bounds.
GetY() <<
',' << bounds.
GetWidth() <<
','
1405 auto text = [&](
const wxString& value )
1407 const std::string utf8 = value.ToStdString( wxConvUTF8 );
1408 identity <<
':' << utf8.size() <<
':' << utf8;
1411 if(
const auto* line =
dynamic_cast<const SCH_LINE*
>( &item ) )
1413 identity <<
':' << line->GetEndPoint().x <<
',' << line->GetEndPoint().y;
1416 if(
const auto* label =
dynamic_cast<const EDA_TEXT*
>( &item ) )
1418 text( label->GetText() );
1419 identity <<
':' << label->GetTextAngleDegrees() <<
':' << label->GetTextWidth() <<
','
1420 << label->GetTextHeight();
1423 if(
const auto* shape =
dynamic_cast<const SCH_SHAPE*
>( &item ) )
1425 identity << ':' << static_cast<int>( shape->GetShape() ) <<
':' << shape->GetStart().x
1426 <<
',' << shape->GetStart().y <<
':' << shape->GetEnd().x <<
',' << shape->GetEnd().y;
1429 identity <<
':' << shape->GetPolyShape().Format();
1431 identity <<
':' << shape->GetArcMid().x <<
',' << shape->GetArcMid().y;
1433 identity <<
':' << shape->GetBezierC1().x <<
',' << shape->GetBezierC1().y <<
':'
1434 << shape->GetBezierC2().x <<
',' << shape->GetBezierC2().y;
1437 if(
const auto* symbol =
dynamic_cast<const SCH_SYMBOL*
>( &item ) )
1440 text( symbol->GetLibId().Format() );
1441 identity <<
':' << symbol->GetUnitSelection( &
path ) <<
':' << symbol->GetOrientation();
1444 if(
const auto*
pin =
dynamic_cast<const SCH_PIN*
>( &item ) )
1448 identity <<
':' <<
pin->GetUnit() <<
':' <<
pin->GetBodyStyle() <<
':'
1449 <<
static_cast<int>(
pin->GetOrientation() ) <<
':' <<
pin->GetLength();
1452 if(
const auto* sheet =
dynamic_cast<const SCH_SHEET*
>( &item ) )
1454 text( sheet->GetName() );
1455 text( sheet->GetFileName() );
1458 return identity.str();
1468 const std::string
name = sheet->
GetName().ToStdString( wxConvUTF8 );
1469 scope += std::to_string(
name.size() ) +
':' +
name +
'/';
1480 const std::string identity = scope + itemIdentity( *item,
path );
1483 if(
auto* symbol =
dynamic_cast<SCH_SYMBOL*
>( item ) )
1485 for(
const std::unique_ptr<SCH_PIN>&
pin : symbol->GetRawPins() )
1486 uuids[identity +
"/pin/" + itemIdentity( *
pin,
path )].push_back(
pin->m_Uuid.AsStdString() );
1488 else if(
const auto* child =
dynamic_cast<const SCH_SHEET*
>( item ) )
1491 uuids[identity +
"/pin/" + itemIdentity( *
pin,
path )].push_back(
pin->m_Uuid.AsStdString() );
1497 for(
auto& [identity, values] : uuids )
1498 std::sort( values.begin(), values.end() );
1505 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1507 if( !corpusEnv || !*corpusEnv )
1509 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD determinism check." );
1517 BOOST_TEST_MESSAGE(
"mc33163.dsn not present in corpus; skipping OrCAD determinism check." );
1521 auto importUuids = [&](
const std::filesystem::path& aDsn )
1523 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1526 schematic->SetProject( &manager.
Prj() );
1527 schematic->CurrentSheet().clear();
1528 schematic->CurrentSheet().push_back( &schematic->Root() );
1535 const auto first = importUuids( dsn );
1536 const auto second = importUuids( dsn );
1539 BOOST_REQUIRE_EQUAL( first.size(), second.size() );
1541 for(
const auto& [identity, values] : first )
1545 const auto found = second.find( identity );
1555 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1557 if( !corpusEnv || !*corpusEnv )
1559 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD sheet-load UUID check." );
1567 BOOST_TEST_MESSAGE(
"mc33163.dsn not present in corpus; skipping OrCAD sheet-load UUID check." );
1572 std::unique_ptr<SCHEMATIC> schematic;
1573 KI_TEST::LoadSchematic( settings, wxS(
"netlists/complex_hierarchy_shared/complex_hierarchy" ), schematic );
1575 auto existingUuids = [&]()
1577 std::vector<std::string> uuids;
1582 uuids.push_back( item->m_Uuid.AsStdString() );
1585 std::sort( uuids.begin(), uuids.end() );
1589 const std::vector<std::string> before = existingUuids();
1595 m_plugin.LoadSchematicFile( dsn.string(), schematic.get(), &sheet );
1599 const std::vector<std::string> after = existingUuids();
1606 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1608 if( !corpusEnv || !*corpusEnv )
1610 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD hierarchical sheet refusal check." );
1618 BOOST_TEST_MESSAGE(
"mc33163.dsn not present in corpus; skipping OrCAD hierarchical sheet refusal check." );
1623 std::unique_ptr<SCHEMATIC> schematic;
1624 KI_TEST::LoadSchematic( settings, wxS(
"netlists/complex_hierarchy_shared/complex_hierarchy" ), schematic );
1626 const std::vector<SCH_SHEET*> topLevel = schematic->GetTopLevelSheets();
1629 std::map<std::string, UTF8> props = { {
"hierarchical_sheet_load",
"1" } };
1631 BOOST_CHECK_THROW( m_plugin.LoadSchematicFile( dsn.string(), schematic.get(),
nullptr, &props ),
IO_ERROR );
1632 BOOST_CHECK( schematic->GetTopLevelSheets() == topLevel );
1638 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1640 if( !corpusEnv || !*corpusEnv )
1642 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD graphic variant pin check." );
1646 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"OC_CONNECT1_SDR_REV_C_V1P1.DSN" );
1650 BOOST_TEST_MESSAGE(
"OC_CONNECT1_SDR_REV_C_V1P1.DSN not present in corpus; skipping variant pin check." );
1654 m_plugin.LoadSchematicFile( dsn.string(), m_schematic.get() );
1658 bool attached =
false;
1662 if( !
path.LastScreen()->GetFileName().Contains( wxS(
"FPGA_1" ) ) )
1673 attached |=
pin->GetPosition() == stubEnd;
1677 BOOST_CHECK( attached );
1683 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1685 if( !corpusEnv || !*corpusEnv )
1687 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping generated net-name check." );
1691 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CutiePi_V2.3-20210409.DSN" );
1695 BOOST_TEST_MESSAGE(
"CutiePi_V2.3-20210409.DSN not present in corpus; skipping generated "
1696 "net-name check." );
1700 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1703 schematic->SetProject( &manager.
Prj() );
1704 schematic->CurrentSheet().clear();
1705 schematic->CurrentSheet().push_back( &schematic->Root() );
1713 for(
const auto& [sourceName, reference, number] :
1714 { std::tuple{ wxString(
"N12720539" ), wxString(
"D10" ), wxString(
"A" ) },
1715 std::tuple{ wxString(
"N132252170" ), wxString(
"D23" ), wxString(
"1" ) } } )
1718 BOOST_CHECK_NE( netName, sourceName );
1727 BOOST_CHECK( !entry.
terminals.empty() );
1732 BOOST_CHECK( found );
1734 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
1736 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
1740 BOOST_CHECK_NE( label->GetText(), sourceName );
1742 || label->GetTextColor().a > 0 );
1752 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
1754 if( !corpusEnv || !*corpusEnv )
1756 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping Capture net/unit regression check." );
1760 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"BEAGLEBONEBLK_C3.DSN" );
1764 BOOST_TEST_MESSAGE(
"BEAGLEBONEBLK_C3.DSN not present in corpus; skipping Capture net/unit "
1765 "regression check." );
1769 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
1772 schematic->SetProject( &manager.
Prj() );
1773 schematic->CurrentSheet().clear();
1774 schematic->CurrentSheet().push_back( &schematic->Root() );
1779 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
1780 schematic->ConnectionGraph()->Recalculate( sheets,
true );
1782 std::map<std::tuple<std::string, std::string, std::string>,
int> terminalNets;
1785 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
1789 std::string page = subgraph->GetSheet().LastScreen()->GetFileName().ToStdString();
1791 for(
SCH_ITEM* item : subgraph->GetItems() )
1801 terminalNets[{ page, symbol->
GetRef( &subgraph->GetSheet(),
false ).ToStdString(),
1802 pin->GetNumber().ToStdString() }] = netId;
1810 auto findNet = [&](
const std::string& aPage,
const std::string& aRef,
const std::string& aPin )
1812 for(
const auto& [terminal,
id] : terminalNets )
1814 if( std::get<0>( terminal ).
find( aPage ) != std::string::npos && std::get<1>( terminal ) == aRef
1815 && std::get<2>( terminal ) == aPin )
1824 int ground = findNet(
"AM335x 2_3, USB",
"J1",
"1" );
1825 int rx = findNet(
"AM335x 2_3, USB",
"J1",
"4" );
1826 int tx = findNet(
"AM335x 2_3, USB",
"J1",
"5" );
1828 BOOST_REQUIRE_NE( ground, -1 );
1829 BOOST_REQUIRE_NE( rx, -1 );
1830 BOOST_REQUIRE_NE( tx, -1 );
1831 BOOST_CHECK_NE( ground, rx );
1832 BOOST_CHECK_NE( ground, tx );
1833 BOOST_CHECK_NE( rx, tx );
1835 BOOST_CHECK_EQUAL( findNet(
"LED, Config",
"D3",
"1" ), findNet(
"LED, Config",
"Q1",
"3" ) );
1836 BOOST_CHECK_EQUAL( findNet(
"LED, Config",
"R77",
"1" ), findNet(
"LED, Config",
"Q1",
"5" ) );
1838 std::set<int> q1Units;
1839 std::set<wxString> q1ShownReferences;
1843 if(
path.LastScreen()->GetFileName().Find( wxS(
"LED, Config" ) ) == wxNOT_FOUND )
1850 if( symbol->
GetRef( &
path,
false ) == wxS(
"Q1" ) )
1852 q1Units.insert( symbol->
GetUnit() );
1853 q1ShownReferences.insert( symbol->
GetRef( &
path,
true ) );
1858 const std::set<int> expectedUnits = { 1, 2 };
1861 const std::set<wxString> expectedShownReferences = { wxS(
"Q1" ) };
1863 expectedShownReferences.begin(), expectedShownReferences.end() );
1869 const char* corpus = std::getenv(
"KICAD_ORCAD_CORPUS" );
1871 if( !corpus || !*corpus )
1887 bool memberFound =
false;
1888 bool bundleFound =
false;
1889 wxString actualName =
terminalNetName( schematic, wxS(
"J10" ), wxS(
"25" ) );
1894 if( entry.
view != wxS(
"Hierarchical Interconnects" ) )
1902 BOOST_CHECK( !entry.
terminals.empty() );
1911 BOOST_CHECK( !entry.
itemUuids.empty() );
1912 std::set<std::string> mappedTerminals;
1919 mappedTerminals.insert(
terminalToken( symbol->GetRef( &
path,
false ).ToStdString(),
1923 const std::set<std::string>
expected = {
"J10.25",
"R77.2",
"RP16.7",
"U10.R8" };
1924 BOOST_CHECK( mappedTerminals ==
expected );
1927 BOOST_CHECK( memberFound );
1928 BOOST_CHECK( bundleFound );
1934 const char* corpus = std::getenv(
"KICAD_ORCAD_CORPUS" );
1936 if( !corpus || !*corpus )
1963 BOOST_CHECK( found );
1965 for(
const wxString& reference : { wxString(
"U1" ), wxString(
"U2" ), wxString(
"U4" ) } )
1972 const char* corpus = std::getenv(
"KICAD_ORCAD_CORPUS" );
1974 if( !corpus || !*corpus )
1977 std::filesystem::path dsn =
findCorpusDesign( corpus,
"meta_carrier_sch_rev1.dsn" );
1995 || entry.
occurrence != std::vector<wxString>( {
"TOP",
"9136400",
"TILE_AD9523" } ) )
2013 BOOST_CHECK( found );
2019 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2021 if( !corpusEnv || !*corpusEnv )
2023 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping named wireless-pin check." );
2027 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CURRENT_SENSOR.DSN" );
2031 BOOST_TEST_MESSAGE(
"CURRENT_SENSOR.DSN not present in corpus; skipping named wireless-pin check." );
2035 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2038 schematic->SetProject( &manager.
Prj() );
2039 schematic->CurrentSheet().clear();
2040 schematic->CurrentSheet().push_back( &schematic->Root() );
2045 wxString netName =
terminalNetName( *schematic, wxS(
"U1" ), wxS(
"7" ) );
2049 bool mapped =
false;
2057 BOOST_CHECK( !entry.
terminals.empty() );
2062 BOOST_CHECK( mapped );
2068 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2070 if( !corpusEnv || !*corpusEnv )
2073 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"reComputer J202_V1.0.DSN" );
2078 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2081 schematic->SetProject( &manager.
Prj() );
2082 schematic->CurrentSheet().clear();
2083 schematic->CurrentSheet().push_back( &schematic->Root() );
2095 if( symbol->
GetRef( &
path,
false ) == wxS(
"R48" ) )
2107 size_t datasheetFields = std::count_if(
2109 [](
const SCH_FIELD& field ) { return field.GetName() == wxS(
"Datasheet" ); } );
2113 wxS(
"Y:\\01_Cadence_Library\\05_Datasheet\\301010000_YAGEO_RC0402JR-070RL_Datasheet.pdf" ) );
2119 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2121 if( !corpusEnv || !*corpusEnv )
2124 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY4532 Power Board Schematic.DSN" );
2129 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2132 schematic->SetProject( &manager.
Prj() );
2133 schematic->CurrentSheet().clear();
2134 schematic->CurrentSheet().push_back( &schematic->Root() );
2146 if( symbol->
GetRef( &
path,
false ) == wxS(
"C45" ) )
2158 size_t footprintFields = std::count_if(
2160 [](
const SCH_FIELD& field ) { return field.GetName() == wxS(
"Footprint" ); } );
2172 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2174 if( !corpusEnv || !*corpusEnv )
2177 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY4532 Power Board Schematic.DSN" );
2182 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2185 schematic->SetProject( &manager.
Prj() );
2186 schematic->CurrentSheet().clear();
2187 schematic->CurrentSheet().push_back( &schematic->Root() );
2200 wxString reference = symbol->
GetRef( &
path,
false );
2202 if( reference == wxS(
"C104" ) )
2204 else if( reference == wxS(
"R58" ) )
2206 else if( reference == wxS(
"TP8" ) )
2226 BOOST_CHECK( description->
IsVisible() );
2236 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2238 if( !corpusEnv || !*corpusEnv )
2241 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC1859A-2.DSN" );
2246 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2249 schematic->SetProject( &manager.
Prj() );
2250 schematic->CurrentSheet().clear();
2251 schematic->CurrentSheet().push_back( &schematic->Root() );
2263 if( symbol->
GetRef( &
path,
false ) == wxS(
"C2" ) )
2284 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2286 if( !corpusEnv || !*corpusEnv )
2289 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-48278.DSN" );
2294 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2297 schematic->SetProject( &manager.
Prj() );
2298 schematic->CurrentSheet().clear();
2299 schematic->CurrentSheet().push_back( &schematic->Root() );
2304 bool renderedJumper =
false;
2312 if( symbol->
GetRef( &
path,
false ) == wxS(
"J2" ) )
2314 jumper = symbol->
GetField( wxS(
"JUMPER(DEFAULT)" ) );
2322 renderedJumper = renderedJumper
2323 ||
text->GetText() == wxS(
"JUMPER(DEFAULT) = OFF:POLARITY_SEL_L" );
2332 BOOST_CHECK( renderedJumper );
2338 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2340 if( !corpusEnv || !*corpusEnv )
2342 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping wireless peer-net check." );
2346 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY3280_MBR3 EVK Schematic.DSN" );
2350 BOOST_TEST_MESSAGE(
"CY3280_MBR3 EVK Schematic.DSN not present; skipping wireless peer-net check." );
2354 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2357 schematic->SetProject( &manager.
Prj() );
2358 schematic->CurrentSheet().clear();
2359 schematic->CurrentSheet().push_back( &schematic->Root() );
2364 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2365 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2368 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2372 for(
SCH_ITEM* item : subgraph->GetItems() )
2381 pinNets[{ symbol->
GetRef( &subgraph->GetSheet(),
false ),
pin->GetNumber() }] = subgraph;
2386 BOOST_REQUIRE_EQUAL( pinNets.count( { wxS(
"R51" ), wxS(
"1" ) } ), 1u );
2387 BOOST_REQUIRE_EQUAL( pinNets.count( { wxS(
"R51" ), wxS(
"2" ) } ), 1u );
2388 BOOST_REQUIRE_EQUAL( pinNets.count( { wxS(
"R52" ), wxS(
"1" ) } ), 1u );
2389 BOOST_REQUIRE_EQUAL( pinNets.count( { wxS(
"R52" ), wxS(
"2" ) } ), 1u );
2395 BOOST_CHECK_NE( r51Pin1, r51Pin2 );
2396 BOOST_CHECK_NE( r52Pin1, r52Pin2 );
2402 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2404 if( !corpusEnv || !*corpusEnv )
2410 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"BeagleBoard-xM_ORCAD.DSN" );
2414 BOOST_TEST_MESSAGE(
"BeagleBoard-xM_ORCAD.DSN not present in corpus; skipping global-net case check." );
2418 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2421 schematic->SetProject( &manager.
Prj() );
2422 schematic->CurrentSheet().clear();
2423 schematic->CurrentSheet().push_back( &schematic->Root() );
2428 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2429 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2431 std::map<std::tuple<std::string, std::string, std::string>,
int> terminalNets;
2434 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2438 std::string page = subgraph->GetSheet().LastScreen()->GetFileName().ToStdString();
2440 for(
SCH_ITEM* item : subgraph->GetItems() )
2450 terminalNets[{ page, symbol->
GetRef( &subgraph->GetSheet(),
false ).ToStdString(),
2451 pin->GetNumber().ToStdString() }] = netId;
2459 auto findNet = [&](
const std::string& aPage,
const std::string& aRef,
const std::string& aPin )
2461 for(
const auto& [terminal,
id] : terminalNets )
2463 if( std::get<0>( terminal ).
find( aPage ) != std::string::npos && std::get<1>( terminal ) == aRef
2464 && std::get<2>( terminal ) == aPin )
2473 int processor = findNet(
"PROCESSOR_C",
"C75",
"1" );
2474 int power = findNet(
"PMIC _POWER",
"C122",
"1" );
2476 BOOST_REQUIRE_NE( processor, -1 );
2477 BOOST_REQUIRE_NE( power, -1 );
2484 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2486 if( !corpusEnv || !*corpusEnv )
2488 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping bus-range syntax check." );
2492 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"parallella_e16_z7020_schematic.dsn" );
2496 BOOST_TEST_MESSAGE(
"parallella_e16_z7020_schematic.dsn not present in corpus; skipping bus-range check." );
2500 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2503 schematic->SetProject( &manager.
Prj() );
2504 schematic->CurrentSheet().clear();
2505 schematic->CurrentSheet().push_back( &schematic->Root() );
2517 BOOST_CHECK_NE(
text, wxS(
"DDR_DQ[31:0]" ) );
2518 found |=
text == wxS(
"DDR_DQ[31..0]" );
2522 BOOST_CHECK( found );
2528 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2530 if( !corpusEnv || !*corpusEnv )
2533 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"parallella_e16_z7020_schematic.dsn" );
2538 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2541 schematic->SetProject( &manager.
Prj() );
2542 schematic->CurrentSheet().clear();
2543 schematic->CurrentSheet().push_back( &schematic->Root() );
2555 if( symbol->
GetRef( &
path,
false ) == wxS(
"PTH1" ) )
2557 platedHole = symbol;
2567 size_t valueFields = std::count_if(
2569 [](
const SCH_FIELD& aField ) { return aField.GetName().CmpNoCase( wxS(
"Value" ) ) == 0; } );
2577 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2579 if( !corpusEnv || !*corpusEnv )
2582 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"parallella_e16_z7020_schematic.dsn" );
2587 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2590 schematic->SetProject( &manager.
Prj() );
2591 schematic->CurrentSheet().clear();
2592 schematic->CurrentSheet().push_back( &schematic->Root() );
2597 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2598 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2600 std::map<std::string, int> terminalNets;
2603 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2607 for(
SCH_ITEM* item : subgraph->GetItems() )
2618 pin->GetNumber().ToStdString() )] = netId;
2636 BOOST_CHECK_NE( terminalNets[
"R41.2"], terminalNets[
"R56.2"] );
2642 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2644 if( !corpusEnv || !*corpusEnv )
2647 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"parallella_gen0.dsn" );
2652 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2655 schematic->SetProject( &manager.
Prj() );
2656 schematic->CurrentSheet().clear();
2657 schematic->CurrentSheet().push_back( &schematic->Root() );
2673 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2675 if( !corpusEnv || !*corpusEnv )
2678 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-20380.DSN" );
2683 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2686 schematic->SetProject( &manager.
Prj() );
2687 schematic->CurrentSheet().clear();
2688 schematic->CurrentSheet().push_back( &schematic->Root() );
2707 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2709 if( !corpusEnv || !*corpusEnv )
2712 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-38863_CX1.DSN" );
2717 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2720 schematic->SetProject( &manager.
Prj() );
2721 schematic->CurrentSheet().clear();
2722 schematic->CurrentSheet().push_back( &schematic->Root() );
2729 std::set<wxString> netNames;
2731 for(
const auto& [reference, peer, sourceName] :
2732 { std::tuple{ wxString(
"J16" ), wxString(
"C520" ), wxString(
"GNDISOHU" ) },
2733 std::tuple{ wxString(
"J17" ), wxString(
"C590" ), wxString(
"GNDISOHV" ) },
2734 std::tuple{ wxString(
"J18" ), wxString(
"C661" ), wxString(
"GNDISOHW" ) } } )
2736 wxString netName =
terminalNetName( *schematic, reference, wxS(
"1" ) );
2739 netNames.insert( netName );
2740 bool mapped =
false;
2752 BOOST_CHECK( mapped );
2761 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2763 if( !corpusEnv || !*corpusEnv )
2765 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping duplicate page-net check." );
2773 BOOST_TEST_MESSAGE(
"MTB4.DSN not present in corpus; skipping duplicate page-net check." );
2777 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2780 schematic->SetProject( &manager.
Prj() );
2781 schematic->CurrentSheet().clear();
2782 schematic->CurrentSheet().push_back( &schematic->Root() );
2787 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2788 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2790 std::map<std::string, wxString> pinNets;
2792 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2796 if( subgraph->GetSheet().LastScreen()->GetFileName().Find( wxS(
"PAGE 2 - MCU" ) ) == wxNOT_FOUND )
2799 for(
SCH_ITEM* item : subgraph->GetItems() )
2807 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"U1" ) )
2808 pinNets[
pin->GetNumber().ToStdString()] = key.Name;
2813 BOOST_REQUIRE_EQUAL( pinNets.count(
"F3" ), 1u );
2814 BOOST_REQUIRE_EQUAL( pinNets.count(
"F8" ), 1u );
2815 BOOST_REQUIRE_EQUAL( pinNets.count(
"G3" ), 1u );
2816 BOOST_REQUIRE_EQUAL( pinNets.count(
"G7" ), 1u );
2817 BOOST_CHECK( pinNets[
"F3"].EndsWith( wxS(
"I2C2_SDA" ) ) );
2818 BOOST_CHECK( pinNets[
"F8"].EndsWith( wxS(
"I2C2_SDA" ) ) );
2819 BOOST_CHECK( pinNets[
"G3"].EndsWith( wxS(
"I2C2_SCL" ) ) );
2820 BOOST_CHECK( pinNets[
"G7"].EndsWith( wxS(
"I2C2_SCL" ) ) );
2826 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2828 if( !corpusEnv || !*corpusEnv )
2830 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping duplicate page-net isolation check." );
2834 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2125A-2.DSN" );
2838 BOOST_TEST_MESSAGE(
"DC2125A-2.DSN not present; skipping duplicate page-net isolation check." );
2842 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2845 schematic->SetProject( &manager.
Prj() );
2846 schematic->CurrentSheet().clear();
2847 schematic->CurrentSheet().push_back( &schematic->Root() );
2852 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2853 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2856 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2860 for(
SCH_ITEM* item : subgraph->GetItems() )
2869 pinNets[{ symbol->
GetRef( &subgraph->GetSheet(),
false ),
pin->GetNumber() }] = subgraph;
2876 BOOST_CHECK_NE( earth, vportn );
2882 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2884 if( !corpusEnv || !*corpusEnv )
2886 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping alias-at-crossing isolation check." );
2890 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"OC_CONNECT1_FRONTEND_REV_C_V1P1.DSN" );
2894 BOOST_TEST_MESSAGE(
"OC_CONNECT1_FRONTEND_REV_C_V1P1.DSN not present; skipping alias-at-crossing check." );
2898 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2901 schematic->SetProject( &manager.
Prj() );
2902 schematic->CurrentSheet().clear();
2903 schematic->CurrentSheet().push_back( &schematic->Root() );
2908 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2909 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2912 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2916 for(
SCH_ITEM* item : subgraph->GetItems() )
2925 pinNets[{ symbol->
GetRef( &subgraph->GetSheet(),
false ),
pin->GetNumber() }] = subgraph;
2938 BOOST_CHECK_NE( a0, a2 );
2939 BOOST_CHECK_NE( a0, io1 );
2940 BOOST_CHECK_NE( a2, io1 );
2946 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
2948 if( !corpusEnv || !*corpusEnv )
2950 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping wireless page-net check." );
2954 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"Si828X-BW-GDB.DSN" );
2958 BOOST_TEST_MESSAGE(
"Si828X-BW-GDB.DSN not present; skipping wireless page-net check." );
2962 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
2965 schematic->SetProject( &manager.
Prj() );
2966 schematic->CurrentSheet().clear();
2967 schematic->CurrentSheet().push_back( &schematic->Root() );
2972 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
2973 schematic->ConnectionGraph()->Recalculate( sheets,
true );
2974 std::map<std::pair<wxString, wxString>, wxString> pinNames;
2976 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
2980 for(
SCH_ITEM* item : subgraph->GetItems() )
2989 pinNames[{ symbol->
GetRef( &subgraph->GetSheet(),
false ),
pin->GetNumber() }] = key.Name;
3001 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3003 if( !corpusEnv || !*corpusEnv )
3005 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping ambiguous wireless-net check." );
3009 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2047A-3-A.DSN" );
3013 BOOST_TEST_MESSAGE(
"DC2047A-3-A.DSN not present; skipping ambiguous wireless-net check." );
3017 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3020 schematic->SetProject( &manager.
Prj() );
3021 schematic->CurrentSheet().clear();
3022 schematic->CurrentSheet().push_back( &schematic->Root() );
3027 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
3028 schematic->ConnectionGraph()->Recalculate( sheets,
true );
3031 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
3035 for(
SCH_ITEM* item : subgraph->GetItems() )
3043 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"D15" )
3044 &&
pin->GetNumber() == wxS(
"2" ) )
3058 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3060 if( !corpusEnv || !*corpusEnv )
3063 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2084A-3.DSN" );
3068 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3071 schematic->SetProject( &manager.
Prj() );
3072 schematic->CurrentSheet().clear();
3073 schematic->CurrentSheet().push_back( &schematic->Root() );
3078 std::map<wxString, std::set<wxString>> pinNumbers;
3080 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3086 wxString reference = symbol->
GetRef( &sheet,
false );
3088 if( reference != wxS(
"C31" ) && reference != wxS(
"C42" ) )
3091 for(
const std::unique_ptr<SCH_PIN>&
pin : symbol->
GetRawPins() )
3092 pinNumbers[reference].insert(
pin->GetNumber() );
3096 BOOST_CHECK( pinNumbers[wxS(
"C31" )] == std::set<wxString>( { wxS(
"1" ), wxS(
"2" ) } ) );
3097 BOOST_CHECK( pinNumbers[wxS(
"C42" )] == std::set<wxString>( { wxS(
"1" ), wxS(
"2" ) } ) );
3103 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3105 if( !corpusEnv || !*corpusEnv )
3108 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2091A-3.DSN" );
3113 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3116 schematic->SetProject( &manager.
Prj() );
3117 schematic->CurrentSheet().clear();
3118 schematic->CurrentSheet().push_back( &schematic->Root() );
3123 std::map<wxString, std::set<wxString>> pinNumbers;
3125 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3130 wxString reference = symbol->
GetRef( &sheet,
false );
3132 if( reference != wxS(
"C1" ) && reference != wxS(
"C2" ) )
3135 for(
const std::unique_ptr<SCH_PIN>&
pin : symbol->
GetRawPins() )
3136 pinNumbers[reference].insert(
pin->GetNumber() );
3140 const std::set<wxString>
expected = { wxS(
"1" ), wxS(
"2" ) };
3141 BOOST_CHECK( pinNumbers[wxS(
"C1" )] ==
expected );
3142 BOOST_CHECK( pinNumbers[wxS(
"C2" )] ==
expected );
3148 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3150 if( !corpusEnv || !*corpusEnv )
3153 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2228A-3.DSN" );
3158 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3161 schematic->SetProject( &manager.
Prj() );
3162 schematic->CurrentSheet().clear();
3163 schematic->CurrentSheet().push_back( &schematic->Root() );
3177 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3179 if( !corpusEnv || !*corpusEnv )
3182 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2228A-3.DSN" );
3187 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3190 schematic->SetProject( &manager.
Prj() );
3191 schematic->CurrentSheet().clear();
3192 schematic->CurrentSheet().push_back( &schematic->Root() );
3197 std::map<int, size_t> pinCounts;
3199 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3205 if( symbol->
GetRef( &sheet,
false ) == wxS(
"U9" ) )
3210 const std::map<int, size_t>
expected = {
3211 { 1, 2 }, { 2, 21 }, { 3, 14 }, { 4, 9 }, { 5, 11 }, { 6, 8 }, { 7, 13 },
3212 { 8, 8 }, { 9, 9 }, { 10, 7 }, { 11, 5 }, { 12, 7 }, { 13, 15 }, { 14, 17 },
3213 { 15, 16 }, { 16, 12 }, { 17, 32 }, { 18, 6 }, { 19, 22 }, { 20, 22 },
3215 BOOST_CHECK( pinCounts ==
expected );
3221 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3223 if( !corpusEnv || !*corpusEnv )
3226 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI82AX-CX_NB8_EVB.DSN" );
3231 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3234 schematic->SetProject( &manager.
Prj() );
3235 schematic->CurrentSheet().clear();
3236 schematic->CurrentSheet().push_back( &schematic->Root() );
3241 bool foundR2 =
false;
3242 bool foundR17 =
false;
3243 wxString refsAtR2Position;
3244 wxString refsAtR17Position;
3246 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3251 wxString reference = symbol->
GetRef( &sheet,
false );
3255 refsAtR2Position += reference + wxS(
" " );
3256 foundR2 = foundR2 || reference == wxS(
"R2" );
3261 refsAtR17Position += reference + wxS(
" " );
3262 foundR17 = foundR17 || reference == wxS(
"R17" );
3267 BOOST_CHECK_MESSAGE( foundR2,
"references at R2 position: " << refsAtR2Position );
3268 BOOST_CHECK_MESSAGE( foundR17,
"references at R17 position: " << refsAtR17Position );
3274 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3276 if( !corpusEnv || !*corpusEnv )
3279 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"Low EMI demo board.DSN" );
3284 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3287 schematic->SetProject( &manager.
Prj() );
3288 schematic->CurrentSheet().clear();
3289 schematic->CurrentSheet().push_back( &schematic->Root() );
3296 BOOST_CHECK( refs.count(
"C1" ) );
3297 BOOST_CHECK( refs.count(
"U1" ) );
3298 BOOST_CHECK( !refs.count(
"C71" ) );
3299 BOOST_CHECK( !refs.count(
"U12" ) );
3305 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3307 if( !corpusEnv || !*corpusEnv )
3310 std::filesystem::path dsn;
3312 for(
const std::filesystem::directory_entry& entry :
3313 std::filesystem::recursive_directory_iterator( corpusEnv ) )
3315 if( entry.is_regular_file() && entry.path().filename() ==
"BDC.DSN"
3316 && entry.path().string().find(
"backpack-bdc" ) != std::string::npos )
3326 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3329 schematic->SetProject( &manager.
Prj() );
3330 schematic->CurrentSheet().clear();
3331 schematic->CurrentSheet().push_back( &schematic->Root() );
3338 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3345 reference = symbol->
GetRef( &sheet,
false );
3355 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3357 if( !corpusEnv || !*corpusEnv )
3360 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SuperSpeed Explorer Kit Schematic.DSN" );
3365 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3368 schematic->SetProject( &manager.
Prj() );
3369 schematic->CurrentSheet().clear();
3370 schematic->CurrentSheet().push_back( &schematic->Root() );
3375 std::map<wxString, SCH_SYMBOL*> switches;
3377 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3382 wxString reference = symbol->
GetRef( &sheet,
false );
3384 if( reference == wxS(
"SW1" ) || reference == wxS(
"SW2" ) )
3385 switches[reference] = symbol;
3389 BOOST_REQUIRE_EQUAL( switches.size(), 2u );
3391 for(
const wxString& reference : { wxS(
"SW1" ), wxS(
"SW2" ) } )
3393 SCH_SYMBOL* symbol = switches.at( reference );
3397 wxS(
"Wurth Electronics Inc" ) );
3406 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3408 if( !corpusEnv || !*corpusEnv )
3411 auto checkFieldCleared = [&](
const wxString& aFileName,
const wxString& aReference,
3412 const wxString& aFieldName )
3414 std::filesystem::path dsn =
findCorpusDesign( corpusEnv, aFileName.ToStdString() );
3417 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3420 schematic->SetProject( &manager.
Prj() );
3421 schematic->CurrentSheet().clear();
3422 schematic->CurrentSheet().push_back( &schematic->Root() );
3429 for(
const SCH_SHEET_PATH& sheet : schematic->BuildSheetListSortedByPageNumbers() )
3435 if( symbol->
GetRef( &sheet,
false ) == aReference )
3436 field = symbol->
GetField( aFieldName );
3440 BOOST_CHECK( !field || field->
GetText().IsEmpty() );
3443 checkFieldCleared( wxS(
"DC2596A-3.DSN" ), wxS(
"L2" ), wxS(
"4th Part Field" ) );
3444 checkFieldCleared( wxS(
"CY4532 Power Board Schematic.DSN" ), wxS(
"J2" ), wxS(
"PART_NUMBER" ) );
3450 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3452 if( !corpusEnv || !*corpusEnv )
3455 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2641A3-SCH.DSN" );
3460 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3463 schematic->SetProject( &manager.
Prj() );
3464 schematic->CurrentSheet().clear();
3465 schematic->CurrentSheet().push_back( &schematic->Root() );
3474 size_t nativePowerPins = 0;
3483 wxString ref = symbol->
GetRef( &
path,
false );
3485 if( ref != wxS(
"L1" ) && ref != wxS(
"L4" ) )
3490 if(
pin->GetNumber() != wxS(
"3" ) )
3494 BOOST_CHECK( !
pin->IsVisible() );
3495 BOOST_CHECK(
pin->IsGlobalPower() );
3502 BOOST_CHECK_NE( label->GetText(), wxString(
"$$$1" ) );
3514 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3516 if( !corpusEnv || !*corpusEnv )
3519 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-54852_A5.DSN" );
3524 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3527 schematic->SetProject( &manager.
Prj() );
3528 schematic->CurrentSheet().clear();
3529 schematic->CurrentSheet().push_back( &schematic->Root() );
3543 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3545 if( !corpusEnv || !*corpusEnv )
3548 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-31399_C4.DSN" );
3553 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3556 schematic->SetProject( &manager.
Prj() );
3557 schematic->CurrentSheet().clear();
3558 schematic->CurrentSheet().push_back( &schematic->Root() );
3573 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3575 if( !corpusEnv || !*corpusEnv )
3583 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3586 schematic->SetProject( &manager.
Prj() );
3587 schematic->CurrentSheet().clear();
3588 schematic->CurrentSheet().push_back( &schematic->Root() );
3605 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3607 if( !corpusEnv || !*corpusEnv )
3610 std::filesystem::path dsn =
3611 findCorpusDesign( corpusEnv,
"630-60651-01_04_CYW9BTM2BASE3_20829_BaseBoard_Schematics.DSN" );
3616 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3619 schematic->SetProject( &manager.
Prj() );
3620 schematic->CurrentSheet().clear();
3621 schematic->CurrentSheet().push_back( &schematic->Root() );
3636 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3638 if( !corpusEnv || !*corpusEnv )
3641 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"parallella_gen0.dsn" );
3646 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3649 schematic->SetProject( &manager.
Prj() );
3650 schematic->CurrentSheet().clear();
3651 schematic->CurrentSheet().push_back( &schematic->Root() );
3667 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3669 if( !corpusEnv || !*corpusEnv )
3672 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI347X-DC-EB.DSN" );
3677 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3680 schematic->SetProject( &manager.
Prj() );
3681 schematic->CurrentSheet().clear();
3682 schematic->CurrentSheet().push_back( &schematic->Root() );
3687 std::vector<std::set<std::string>>
expected;
3689 for(
int channel = 1; channel <= 8; ++channel )
3691 std::string q =
"Q" + std::to_string( channel );
3692 std::string r =
"R" + std::to_string( channel );
3693 std::string gatePin = std::to_string( std::array{ 1, 7, 8, 14, 29, 35, 36, 42 }[channel - 1] );
3694 std::string sourcePin = std::to_string( std::array{ 2, 6, 9, 13, 30, 34, 37, 41 }[channel - 1] );
3708 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3710 if( !corpusEnv || !*corpusEnv )
3713 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"Si828X-BW-GDB.DSN" );
3718 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3721 schematic->SetProject( &manager.
Prj() );
3722 schematic->CurrentSheet().clear();
3723 schematic->CurrentSheet().push_back( &schematic->Root() );
3728 std::vector<std::set<std::string>>
expected = {
3744 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3746 if( !corpusEnv || !*corpusEnv )
3749 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI8284v2-EVB.DSN" );
3754 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3757 schematic->SetProject( &manager.
Prj() );
3758 schematic->CurrentSheet().clear();
3759 schematic->CurrentSheet().push_back( &schematic->Root() );
3766 BOOST_CHECK( refs.count(
"Q1-1" ) );
3767 BOOST_CHECK( refs.count(
"Q1-2" ) );
3768 BOOST_CHECK( refs.count(
"Q8-1" ) );
3769 BOOST_CHECK( refs.count(
"Q8-2" ) );
3775 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3777 if( !corpusEnv || !*corpusEnv )
3780 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI8284v2-EVB.DSN" );
3785 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3788 schematic->SetProject( &manager.
Prj() );
3789 schematic->CurrentSheet().clear();
3790 schematic->CurrentSheet().push_back( &schematic->Root() );
3796 wxString( wxS(
"s3" ) ) );
3802 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3804 if( !corpusEnv || !*corpusEnv )
3807 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI8284v2-EVB.DSN" );
3812 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3815 schematic->SetProject( &manager.
Prj() );
3816 schematic->CurrentSheet().clear();
3817 schematic->CurrentSheet().push_back( &schematic->Root() );
3822 wxString boostNet =
terminalNetName( *schematic, wxS(
"C36" ), wxS(
"1" ) );
3823 wxString supplyNet =
terminalNetName( *schematic, wxS(
"C12" ), wxS(
"1" ) );
3827 BOOST_CHECK_NE( boostNet, supplyNet );
3831 auto mapped = std::find_if( map->
entries.begin(), map->
entries.end(),
3834 return entry.sourceNetId == 16939716
3835 && entry.originalName == wxS(
"N16864826" );
3845 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3847 if( !corpusEnv || !*corpusEnv )
3850 for(
const char* filename : {
"Si828X-BW-GDB.DSN",
"SI828X-AW-GDB.DSN" } )
3855 BOOST_REQUIRE_MESSAGE( !dsn.empty(), filename <<
" not present in corpus." );
3862 wxString netName =
terminalNetName( schematic, wxS(
"C306" ), wxS(
"1" ) );
3865 for(
const auto& [reference,
pin] :
3866 { std::pair{ wxString(
"U2" ), wxString(
"16" ) },
3867 std::pair{ wxString(
"C307" ), wxString(
"2" ) },
3868 std::pair{ wxString(
"C309" ), wxString(
"1" ) },
3869 std::pair{ wxString(
"C310" ), wxString(
"1" ) },
3870 std::pair{ wxString(
"R333" ), wxString(
"1" ) },
3871 std::pair{ wxString(
"UB8" ), wxString(
"3" ) },
3872 std::pair{ wxString(
"UT6" ), wxString(
"5" ) } } )
3877 std::set<wxString> powerNames;
3893 BOOST_REQUIRE_EQUAL( powerNames.size(), 1u );
3902 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3904 if( !corpusEnv || !*corpusEnv )
3907 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CN81XX_GBCV2_sch_0530.DSN" );
3912 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3915 schematic->SetProject( &manager.
Prj() );
3916 schematic->CurrentSheet().clear();
3917 schematic->CurrentSheet().push_back( &schematic->Root() );
3922 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
3923 schematic->ConnectionGraph()->Recalculate( sheets,
true );
3924 wxString r13Pin1Net;
3926 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
3930 for(
SCH_ITEM* item : subgraph->GetItems() )
3938 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"R13" )
3939 &&
pin->GetNumber() == wxS(
"1" ) )
3941 r13Pin1Net = key.Name;
3953 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3955 if( !corpusEnv || !*corpusEnv )
3963 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3966 schematic->SetProject( &manager.
Prj() );
3967 schematic->CurrentSheet().clear();
3968 schematic->CurrentSheet().push_back( &schematic->Root() );
3985 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
3987 if( !corpusEnv || !*corpusEnv )
3995 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
3998 schematic->SetProject( &manager.
Prj() );
3999 schematic->CurrentSheet().clear();
4000 schematic->CurrentSheet().push_back( &schematic->Root() );
4019 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4021 if( !corpusEnv || !*corpusEnv )
4024 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2283A-2.DSN" );
4029 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4032 schematic->SetProject( &manager.
Prj() );
4033 schematic->CurrentSheet().clear();
4034 schematic->CurrentSheet().push_back( &schematic->Root() );
4049 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4051 if( !corpusEnv || !*corpusEnv )
4059 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4062 schematic->SetProject( &manager.
Prj() );
4063 schematic->CurrentSheet().clear();
4064 schematic->CurrentSheet().push_back( &schematic->Root() );
4080 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4082 if( !corpusEnv || !*corpusEnv )
4085 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2793A-3.DSN" );
4090 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4093 schematic->SetProject( &manager.
Prj() );
4094 schematic->CurrentSheet().clear();
4095 schematic->CurrentSheet().push_back( &schematic->Root() );
4110 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4112 if( !corpusEnv || !*corpusEnv )
4115 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY4532 Power Board Schematic.DSN" );
4120 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4123 schematic->SetProject( &manager.
Prj() );
4124 schematic->CurrentSheet().clear();
4125 schematic->CurrentSheet().push_back( &schematic->Root() );
4139 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4141 if( !corpusEnv || !*corpusEnv )
4144 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2047A-3-A.DSN" );
4149 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4152 schematic->SetProject( &manager.
Prj() );
4153 schematic->CurrentSheet().clear();
4154 schematic->CurrentSheet().push_back( &schematic->Root() );
4168 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4170 if( !corpusEnv || !*corpusEnv )
4173 std::filesystem::path dsn =
4174 findCorpusDesign( corpusEnv,
"630-60651-01_04_CYW9BTM2BASE3_20829_BaseBoard_Schematics.DSN" );
4179 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4182 schematic->SetProject( &manager.
Prj() );
4183 schematic->CurrentSheet().clear();
4184 schematic->CurrentSheet().push_back( &schematic->Root() );
4201 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4203 if( !corpusEnv || !*corpusEnv )
4206 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY4532 Power Board Schematic.DSN" );
4211 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4214 schematic->SetProject( &manager.
Prj() );
4215 schematic->CurrentSheet().clear();
4216 schematic->CurrentSheet().push_back( &schematic->Root() );
4231 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4233 if( !corpusEnv || !*corpusEnv )
4236 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI347XY_MB_EVB.DSN" );
4255 if( label->
GetText() !=
"VDD" )
4282 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4284 if( !corpusEnv || !*corpusEnv )
4287 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2659A-4.DSN" );
4302 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
4310 if( label->
GetText() !=
"VOUT2"
4312 > int64_t( 15000 ) * 15000 )
4320 for(
SCH_ITEM* other : sheet.LastScreen()->Items() )
4332 BOOST_CHECK_LE( incident, 1 );
4342 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4344 if( !corpusEnv || !*corpusEnv )
4346 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping off-page display-name check." );
4350 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2509A-1.DSN" );
4354 BOOST_TEST_MESSAGE(
"DC2509A-1.DSN not present in corpus; skipping off-page display-name check." );
4358 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4361 schematic->SetProject( &manager.
Prj() );
4362 schematic->CurrentSheet().clear();
4363 schematic->CurrentSheet().push_back( &schematic->Root() );
4368 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
4369 schematic->ConnectionGraph()->Recalculate( sheets,
true );
4371 std::map<std::string, CONNECTION_SUBGRAPH*> pinNets;
4373 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
4377 for(
SCH_ITEM* item : subgraph->GetItems() )
4385 if( !symbol ||
pin->GetNumber() != wxS(
"1" ) )
4388 wxString ref = symbol->
GetRef( &subgraph->GetSheet(),
false );
4390 if( ref == wxS(
"U3" ) || ref == wxS(
"U4" ) )
4391 pinNets[ref.ToStdString()] = subgraph;
4396 BOOST_REQUIRE_EQUAL( pinNets.count(
"U3" ), 1u );
4397 BOOST_REQUIRE_EQUAL( pinNets.count(
"U4" ), 1u );
4404 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4406 if( !corpusEnv || !*corpusEnv )
4408 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping single leaf occurrence check." );
4412 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-28988.DSN" );
4416 BOOST_TEST_MESSAGE(
"SCH-28988.DSN not present in corpus; skipping single leaf occurrence check." );
4420 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4423 schematic->SetProject( &manager.
Prj() );
4424 schematic->CurrentSheet().clear();
4425 schematic->CurrentSheet().push_back( &schematic->Root() );
4430 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
4431 schematic->ConnectionGraph()->Recalculate( sheets,
true );
4434 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
4438 for(
SCH_ITEM* item : subgraph->GetItems() )
4446 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"C3" )
4447 &&
pin->GetNumber() == wxS(
"1" ) )
4462 auto mapped = std::find_if( map->
entries.begin(), map->
entries.end(),
4465 return entry.sourceNetId == 16645429
4466 && entry.originalName == wxS(
"ANALOG5V" );
4478 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4480 if( !corpusEnv || !*corpusEnv )
4486 auto load = [&](
const char* aName )
4489 BOOST_REQUIRE_MESSAGE( !dsn.empty(), aName <<
" not present in corpus." );
4491 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4494 schematic->SetProject( &manager->
Prj() );
4495 schematic->CurrentSheet().clear();
4496 schematic->CurrentSheet().push_back( &schematic->Root() );
4500 return std::pair( std::move( schematic ), std::unique_ptr<SETTINGS_MANAGER>( manager ) );
4503 auto [breakout, breakoutManager] = load(
"OC_CONNECT_1_BRKOUT_BRD.DSN" );
4504 std::map<wxString, std::set<wxString>> switchPins;
4511 wxString ref = symbol->
GetRef( &
path,
false );
4513 if( ref != wxS(
"S1" ) && ref != wxS(
"S3" ) )
4517 switchPins[ref].insert(
pin->GetNumber() );
4521 const std::set<wxString> expectedS1 = { wxS(
"1" ), wxS(
"2" ), wxS(
"3" ), wxS(
"4" ) };
4522 const std::set<wxString> expectedS3 = { wxS(
"1" ), wxS(
"2" ), wxS(
"3" ) };
4528 auto [j401, j401Manager] = load(
"reServer industrial J401 Carrier Board v11.DSN" );
4529 std::set<wxString> j10Pins;
4537 if( symbol->
GetRef( &
path,
false ) != wxS(
"J10" ) )
4541 j10Pins.insert(
pin->GetNumber() );
4553 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4555 if( !corpusEnv || !*corpusEnv )
4557 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping legacy package-map check." );
4565 BOOST_TEST_MESSAGE(
"EXAMPLE.DSN not present in corpus; skipping legacy package-map check." );
4569 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4572 schematic->SetProject( &manager.
Prj() );
4573 schematic->CurrentSheet().clear();
4574 schematic->CurrentSheet().push_back( &schematic->Root() );
4579 std::set<wxString> pins;
4587 if( symbol->
GetRef( &
path,
false ) != wxS(
"U4" ) )
4591 pins.insert(
pin->GetNumber() );
4595 const std::set<wxString>
expected = { wxS(
"2" ), wxS(
"3" ), wxS(
"4" ), wxS(
"5" ), wxS(
"12" ) };
4602 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4604 if( !corpusEnv || !*corpusEnv )
4606 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping S-593487 connector check." );
4610 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"S-593487-REV-B.DSN" );
4611 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"S-593487-REV-B.DSN not present in corpus." );
4613 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4616 schematic->SetProject( &manager.
Prj() );
4617 schematic->CurrentSheet().clear();
4618 schematic->CurrentSheet().push_back( &schematic->Root() );
4623 auto [consistent, checkable] =
4635 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4637 if( !corpusEnv || !*corpusEnv )
4639 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping M5275 visible-power-pin check." );
4644 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"M5275EVB.DSN not present in corpus." );
4646 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4649 schematic->SetProject( &manager.
Prj() );
4650 schematic->CurrentSheet().clear();
4651 schematic->CurrentSheet().push_back( &schematic->Root() );
4656 std::map<wxString, bool> visible;
4664 if( symbol->
GetRef( &
path,
false ) != wxS(
"U21" ) )
4668 visible[
pin->GetNumber()] =
pin->IsVisible();
4672 BOOST_REQUIRE_EQUAL( visible.size(), 6u );
4673 BOOST_CHECK( visible[wxS(
"2" )] );
4674 BOOST_CHECK( visible[wxS(
"5" )] );
4680 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4682 if( !corpusEnv || !*corpusEnv )
4684 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping SI34062 stacked-pin check." );
4688 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI34062-ISO-FB-EVB.DSN" );
4689 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"SI34062-ISO-FB-EVB.DSN not present in corpus." );
4691 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4694 schematic->SetProject( &manager.
Prj() );
4695 schematic->CurrentSheet().clear();
4696 schematic->CurrentSheet().push_back( &schematic->Root() );
4710 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4712 if( !corpusEnv || !*corpusEnv )
4714 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping duplicate power-alias check." );
4718 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI8284v2-EVB.DSN" );
4719 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"SI8284v2-EVB.DSN not present in corpus." );
4721 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4724 schematic->SetProject( &manager.
Prj() );
4725 schematic->CurrentSheet().clear();
4726 schematic->CurrentSheet().push_back( &schematic->Root() );
4731 auto [consistent, checkable] =
4741 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4743 if( !corpusEnv || !*corpusEnv )
4745 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping logical power-pin check." );
4749 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY8CKIT-041-41XX Schematic.DSN" );
4750 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"CY8CKIT-041-41XX Schematic.DSN not present in corpus." );
4752 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4755 schematic->SetProject( &manager.
Prj() );
4756 schematic->CurrentSheet().clear();
4757 schematic->CurrentSheet().push_back( &schematic->Root() );
4762 bool checkedHeaderPin =
false;
4770 if( symbol->
GetRef( &
path,
false ) != wxS(
"J8" )
4771 || !
path.Last()->GetName().Contains( wxS(
"PSoC 5LP Programmer" ) ) )
4778 if(
pin->GetNumber() == wxS(
"3" ) )
4781 checkedHeaderPin =
true;
4789 auto [consistent, checkable] =
4809 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4811 if( !corpusEnv || !*corpusEnv )
4814 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY4605_Schematic.dsn" );
4819 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4822 schematic->SetProject( &manager.
Prj() );
4823 schematic->CurrentSheet().clear();
4824 schematic->CurrentSheet().push_back( &schematic->Root() );
4839 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4841 if( !corpusEnv || !*corpusEnv )
4844 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CYW920706WCDEVAL Evaluation Kit Schematics.DSN" );
4849 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4852 schematic->SetProject( &manager.
Prj() );
4853 schematic->CurrentSheet().clear();
4854 schematic->CurrentSheet().push_back( &schematic->Root() );
4869 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4871 if( !corpusEnv || !*corpusEnv )
4874 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2263A-2.DSN" );
4879 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4882 schematic->SetProject( &manager.
Prj() );
4883 schematic->CurrentSheet().clear();
4884 schematic->CurrentSheet().push_back( &schematic->Root() );
4899 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4901 if( !corpusEnv || !*corpusEnv )
4904 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"OC_CONNECT-1_BB_BOARD_20072023_01.DSN" );
4909 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4912 schematic->SetProject( &manager.
Prj() );
4913 schematic->CurrentSheet().clear();
4914 schematic->CurrentSheet().push_back( &schematic->Root() );
4929 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4931 if( !corpusEnv || !*corpusEnv )
4934 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"710-DC2693A_REV02_PCA_SCHEMATIC.DSN" );
4939 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4942 schematic->SetProject( &manager.
Prj() );
4943 schematic->CurrentSheet().clear();
4944 schematic->CurrentSheet().push_back( &schematic->Root() );
4960 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4962 if( !corpusEnv || !*corpusEnv )
4965 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"OpenCellular_Connect-1_GBC_Life-3_Schematic_v1.2.DSN" );
4970 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
4973 schematic->SetProject( &manager.
Prj() );
4974 schematic->CurrentSheet().clear();
4975 schematic->CurrentSheet().push_back( &schematic->Root() );
4990 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
4992 if( !corpusEnv || !*corpusEnv )
5000 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5003 schematic->SetProject( &manager.
Prj() );
5004 schematic->CurrentSheet().clear();
5005 schematic->CurrentSheet().push_back( &schematic->Root() );
5019 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5021 if( !corpusEnv || !*corpusEnv )
5024 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"710-DC2222A_REV07_PCA_SCHEMATIC.DSN" );
5029 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5032 schematic->SetProject( &manager.
Prj() );
5033 schematic->CurrentSheet().clear();
5034 schematic->CurrentSheet().push_back( &schematic->Root() );
5051 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5053 if( !corpusEnv || !*corpusEnv )
5056 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2382A-1.DSN" );
5061 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5064 schematic->SetProject( &manager.
Prj() );
5065 schematic->CurrentSheet().clear();
5066 schematic->CurrentSheet().push_back( &schematic->Root() );
5071 std::set<wxString> pinNumbers;
5079 if( symbol->
GetRef( &
path,
false ) != wxS(
"J3" ) )
5083 pinNumbers.insert(
pin->GetNumber() );
5090 expected.insert( wxString::Format( wxS(
"%d" ),
pin ) );
5107 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5109 if( !corpusEnv || !*corpusEnv )
5112 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"DC2382A-1.DSN" );
5117 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5120 schematic->SetProject( &manager.
Prj() );
5121 schematic->CurrentSheet().clear();
5122 schematic->CurrentSheet().push_back( &schematic->Root() );
5135 if( symbol->
GetRef( &
path,
false ) == wxS(
"JP4" ) )
5143 int bodyRectangles = 0;
5157 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5159 if( !corpusEnv || !*corpusEnv )
5162 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"X375D_VER72.DSN" );
5167 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5170 schematic->SetProject( &manager.
Prj() );
5171 schematic->CurrentSheet().clear();
5172 schematic->CurrentSheet().push_back( &schematic->Root() );
5185 if( symbol->
GetRef( &
path,
false ) != wxS(
"CLKOUT0" ) )
5199 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5201 if( !corpusEnv || !*corpusEnv )
5204 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SI8281V2-EVB.DSN" );
5209 m_plugin.LoadSchematicFile( dsn.string(), m_schematic.get() );
5210 std::map<wxString, SCH_SCREEN*> screensByFile;
5211 size_t connectorPins = 0;
5216 auto [entry, inserted] = screensByFile.emplace( screen->
GetFileName().Lower(), screen );
5217 BOOST_CHECK_MESSAGE( inserted || entry->second == screen,
5218 "Distinct sheets share output file " << screen->
GetFileName() );
5224 if( symbol->
GetRef( &
path,
false ) == wxS(
"J24" ) )
5235 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5237 if( !corpusEnv || !*corpusEnv )
5245 m_plugin.LoadSchematicFile( dsn.string(), m_schematic.get() );
5255 "Hidden hierarchical port " << label->
GetText() );
5260 BOOST_CHECK_GT( ports, 0 );
5266 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5268 if( !corpusEnv || !*corpusEnv )
5270 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping legacy hierarchy check." );
5274 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-20380.DSN" );
5278 BOOST_TEST_MESSAGE(
"SCH-20380.DSN not present in corpus; skipping legacy hierarchy check." );
5282 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5285 schematic->SetProject( &manager.
Prj() );
5286 schematic->CurrentSheet().clear();
5287 schematic->CurrentSheet().push_back( &schematic->Root() );
5291 schematic->CurrentSheet().UpdateAllScreenReferences();
5294 size_t components = 0;
5319 *schematic, { {
"J7.54",
"RP17.3",
"U10.C13" },
5320 {
"J10.35",
"J12.9",
"RP15.7",
"U10.N10" } } );
5328 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5330 if( !corpusEnv || !*corpusEnv )
5333 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-20380.DSN" );
5338 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5341 schematic->SetProject( &manager.
Prj() );
5342 schematic->CurrentSheet().clear();
5343 schematic->CurrentSheet().push_back( &schematic->Root() );
5348 const std::vector<std::set<std::string>>
expected = {
5360 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5362 if( !corpusEnv || !*corpusEnv )
5365 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-20380.DSN" );
5370 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5373 schematic->SetProject( &manager.
Prj() );
5374 schematic->CurrentSheet().clear();
5375 schematic->CurrentSheet().push_back( &schematic->Root() );
5380 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
5381 schematic->ConnectionGraph()->Recalculate( sheets,
true );
5384 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
5388 for(
SCH_ITEM* item : subgraph->GetItems() )
5396 if( symbol && symbol->
GetRef( &subgraph->GetSheet(),
false ) == wxS(
"J1" )
5397 &&
pin->GetNumber() == wxS(
"7" ) )
5399 j1Pin7Net = key.Name;
5405 BOOST_CHECK( !j1Pin7Net.IsEmpty() );
5411 auto mapped = std::find_if( map->
entries.begin(), map->
entries.end(),
5414 return entry.sourceNetId == 3221698
5415 && entry.originalName == wxS(
"BDM_/RSTIN" );
5421 bool sourcePort =
false;
5426 sourcePort |=
static_cast<SCH_HIERLABEL*
>( item )->GetText() == wxS(
"BDM_/RSTIN" );
5429 BOOST_CHECK( sourcePort );
5435 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5437 if( !corpusEnv || !*corpusEnv )
5440 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SCH-21095.DSN" );
5445 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5448 schematic->SetProject( &manager.
Prj() );
5449 schematic->CurrentSheet().clear();
5450 schematic->CurrentSheet().push_back( &schematic->Root() );
5454 schematic->CurrentSheet().UpdateAllScreenReferences();
5463 if(
path.LastScreen()->GetFileName().Upper().Contains( wxS(
"MRAM" ) ) )
5465 else if(
path.LastScreen()->GetFileName().Upper().Contains( wxS(
"RESET" ) ) )
5478 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5480 if( !corpusEnv || !*corpusEnv )
5482 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping legacy flat-page check." );
5486 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"X375D_VER72.DSN" );
5490 BOOST_TEST_MESSAGE(
"X375D_VER72.DSN not present in corpus; skipping legacy flat-page check." );
5494 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5497 schematic->SetProject( &manager.
Prj() );
5498 schematic->CurrentSheet().clear();
5499 schematic->CurrentSheet().push_back( &schematic->Root() );
5509 catch(
const std::exception& e )
5511 BOOST_FAIL( e.what() <<
"\n" <<
reporter.GetMessages() );
5516 size_t components = 0;
5545 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5547 if( !corpusEnv || !*corpusEnv )
5549 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping legacy power-table check." );
5557 BOOST_TEST_MESSAGE(
"DC1414B.DSN not present in corpus; skipping legacy power-table check." );
5561 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5564 schematic->SetProject( &manager.
Prj() );
5565 schematic->CurrentSheet().clear();
5566 schematic->CurrentSheet().push_back( &schematic->Root() );
5570 schematic->CurrentSheet().UpdateAllScreenReferences();
5573 size_t components = 0;
5602 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5604 if( !corpusEnv || !*corpusEnv )
5618 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5621 schematic->SetProject( &manager.
Prj() );
5622 schematic->CurrentSheet().clear();
5623 schematic->CurrentSheet().push_back( &schematic->Root() );
5628 std::vector<SCH_SHEET*> topSheets = schematic->GetTopLevelSheets();
5629 BOOST_REQUIRE_EQUAL( topSheets.size(), 1u );
5631 SCH_SCREEN* rootScreen = topSheets.front()->GetScreen();
5633 size_t sheetPins = 0;
5639 sheetPins += sheet->
GetPins().size();
5642 const std::vector<wxString> expectedNames = { wxS(
"PAG_2" ), wxS(
"PAG_3" ), wxS(
"PAG_4" ), wxS(
"PAG_5" ),
5643 wxS(
"PAG_6" ), wxS(
"PAG_7" ), wxS(
"PAG_8" ), wxS(
"PAG_9" ) };
5644 const std::vector<size_t> expectedPinCounts = { 31, 24, 39, 47, 40, 33, 26, 10 };
5645 SCH_SHEET_LIST hierarchy = schematic->BuildSheetListSortedByPageNumbers();
5646 std::vector<wxString> sheetNames;
5647 std::vector<size_t> pinCounts;
5649 for(
auto it = std::next( hierarchy.begin() ); it != hierarchy.end(); ++it )
5652 std::set<wxString> sheetPinNames;
5653 std::set<wxString> hierarchicalLabelNames;
5656 pinCounts.push_back( sheet->
GetPins().size() );
5659 sheetPinNames.insert(
pin->GetText() );
5662 hierarchicalLabelNames.insert(
static_cast<SCH_HIERLABEL*
>( item )->GetText() );
5665 hierarchicalLabelNames.end() );
5668 schematic->ConnectionGraph()->Recalculate( hierarchy,
true );
5675 expectedPinCounts.end() );
5681 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5683 if( !corpusEnv || !*corpusEnv )
5689 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"SE_NGFOC-L_01.DSN" );
5693 BOOST_TEST_MESSAGE(
"SE_NGFOC-L_01.DSN not present in corpus; skipping issue 25009." );
5697 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5700 schematic->SetProject( &manager.
Prj() );
5701 schematic->CurrentSheet().clear();
5702 schematic->CurrentSheet().push_back( &schematic->Root() );
5707 const std::vector<wxString> expectedNames = { wxS(
"01.REV.HISTORY" ), wxS(
"02.uC" ), wxS(
"03.CAN" ),
5708 wxS(
"04. Ethercat" ), wxS(
"05.EtherSynch" ), wxS(
"06.RS-485" ),
5709 wxS(
"11.GPIO" ), wxS(
"12.Analog" ), wxS(
"13:IMU" ),
5710 wxS(
"14.Bridge" ), wxS(
"15.Encoder" ), wxS(
"29.uCPower" ),
5711 wxS(
"30.PowerSupply" ), wxS(
"31.Expansion" ) };
5713 std::vector<SCH_SHEET*> sheets = schematic->GetTopLevelSheets();
5714 BOOST_REQUIRE_EQUAL( sheets.size(), expectedNames.size() );
5721 for(
size_t i = 0; i < sheets.size(); ++i )
5725 for(
SCH_ITEM* item : sheets[i]->GetScreen()->Items() )
5764 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5766 if( !corpusEnv || !*corpusEnv )
5768 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD OLB library import." );
5772 namespace fs = std::filesystem;
5773 std::vector<fs::path> libs;
5775 for(
auto it = fs::recursive_directory_iterator( fs::path( corpusEnv ),
5776 fs::directory_options::skip_permission_denied );
5777 it != fs::recursive_directory_iterator(); ++it )
5779 if( !it->is_regular_file() )
5782 std::string ext = it->path().extension().string();
5783 std::transform( ext.begin(), ext.end(), ext.begin(),
5784 [](
unsigned char c )
5786 return std::tolower( c );
5790 libs.push_back( it->path() );
5793 std::sort( libs.begin(), libs.end() );
5796 int totalSymbols = 0, emptySymbols = 0, checkedLibs = 0, rejectedLibs = 0, crashedLibs = 0;
5798 for(
const fs::path& lib : libs )
5801 std::vector<LIB_SYMBOL*> symbols;
5814 catch(
const std::exception& e )
5822 int withGeometry = 0;
5829 if( symbol->GetPinCount() > 0 || !symbol->GetDrawItems().empty() )
5835 BOOST_TEST_MESSAGE(
" " << lib.filename().string() <<
" : " << symbols.size() <<
" symbols, " << withGeometry
5836 <<
" with pins/graphics" );
5839 BOOST_TEST_MESSAGE(
"OLB summary: " << checkedLibs <<
" libs, " << rejectedLibs <<
" rejected, " << crashedLibs
5840 <<
" crashed, " << totalSymbols <<
" symbols, " << emptySymbols <<
" empty" );
5844 BOOST_CHECK_GT( totalSymbols, 0 );
5847 BOOST_CHECK_LT( emptySymbols, totalSymbols / 2 );
5854 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5856 if( !corpusEnv || !*corpusEnv )
5859 std::filesystem::path olb =
findCorpusDesign( corpusEnv,
"LT8550-UKG.OLB" );
5862 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"BeagleBoard-xM_ORCAD.DSN" );
5864 if( olb.empty() || dsn.empty() )
5873 std::set<wxString> numbers;
5876 BOOST_CHECK_MESSAGE( numbers.insert(
pin->GetNumber() ).second,
"duplicate pin " <<
pin->GetNumber() );
5889 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5891 if( !corpusEnv || !*corpusEnv )
5893 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD multi-page import." );
5897 namespace fs = std::filesystem;
5898 fs::path dsn = fs::path( corpusEnv ) /
"cutiepi-board" /
"CutiePi_V2.3-20210409.DSN";
5900 if( !fs::exists( dsn ) )
5906 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5909 schematic->SetProject( &manager.
Prj() );
5910 schematic->CurrentSheet().clear();
5911 schematic->CurrentSheet().push_back( &schematic->Root() );
5920 std::vector<SCH_SHEET*> tops = schematic->GetTopLevelSheets();
5921 BOOST_REQUIRE_EQUAL( tops.size(), 3u );
5927 std::set<wxString> globalLabels;
5932 globalLabels.insert(
static_cast<SCH_LABEL_BASE*
>( item )->GetText() );
5936 BOOST_CHECK( globalLabels.count( wxS(
"CAM0_IO1" ) ) );
5937 BOOST_CHECK( globalLabels.count( wxS(
"AMP_SHUTDOWN" ) ) );
5940 bool checkedField =
false;
5948 if( sym->
GetRef( &
path,
false ) == wxS(
"R3197" ) )
5951 checkedField =
true;
5956 BOOST_CHECK( checkedField );
5962 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
5964 if( !corpusEnv || !*corpusEnv )
5966 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping flat-page instance-path check." );
5970 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"OCTOPAES_10.DSN" );
5974 BOOST_TEST_MESSAGE(
"OCTOPAES_10.DSN not present in corpus; skipping instance-path check." );
5978 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
5981 schematic->SetProject( &manager.
Prj() );
5982 schematic->CurrentSheet().clear();
5983 schematic->CurrentSheet().push_back( &schematic->Root() );
5992 if( !
path.LastScreen()->GetFileName().Contains( wxS(
"CPLD Power" ) ) )
5999 if( symbol->
GetRef( &
path,
false ) != wxS(
"P?" ) )
6005 return aInstance.m_Path == path.Path();
6010 stored += instance.m_Path.AsString().ToStdString() +
" ";
6012 BOOST_CHECK_MESSAGE( canonical,
"expected=" <<
path.Path().AsString() <<
" stored=" << stored );
6023 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6025 if( !corpusEnv || !*corpusEnv )
6027 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping multi-page hierarchy check." );
6031 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"HB1A-AAFM.DSN" );
6035 BOOST_TEST_MESSAGE(
"HB1A-AAFM.DSN not present in corpus; skipping multi-page hierarchy check." );
6039 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6042 schematic->SetProject( &manager.
Prj() );
6043 schematic->CurrentSheet().clear();
6044 schematic->CurrentSheet().push_back( &schematic->Root() );
6049 SCH_SHEET_LIST sheets = schematic->BuildSheetListSortedByPageNumbers();
6050 schematic->ConnectionGraph()->Recalculate( sheets,
true );
6052 std::map<std::tuple<std::string, std::string, std::string>,
int> terminalNets;
6055 for(
const auto& [key, subgraphs] : schematic->ConnectionGraph()->GetNetMap() )
6059 std::string page = subgraph->GetSheet().LastScreen()->GetFileName().ToStdString();
6061 for(
SCH_ITEM* item : subgraph->GetItems() )
6071 terminalNets[{ page, symbol->
GetRef( &subgraph->GetSheet(),
false ).ToStdString(),
6072 pin->GetNumber().ToStdString() }] = netId;
6080 auto findNet = [&](
const std::string& aPage,
const std::string& aRef,
const std::string& aPin )
6082 for(
const auto& [terminal,
id] : terminalNets )
6084 if( std::get<0>( terminal ).
find( aPage ) != std::string::npos && std::get<1>( terminal ) == aRef
6085 && std::get<2>( terminal ) == aPin )
6094 int clockNet = findNet(
"Clock Generator",
"J1",
"1" );
6095 int fmcNet = findNet(
"FMC Connector",
"P1",
"H38" );
6096 BOOST_REQUIRE_NE( clockNet, -1 );
6097 BOOST_REQUIRE_NE( fmcNet, -1 );
6100 BOOST_CHECK_EQUAL( findNet(
"Clock Generator",
"J1",
"2" ), findNet(
"FMC Connector",
"P1",
"G37" ) );
6101 BOOST_CHECK_EQUAL( findNet(
"Clock Generator",
"U12",
"7" ), findNet(
"MAX II CPLD",
"U9",
"73" ) );
6102 BOOST_CHECK_EQUAL( findNet(
"Current Sense",
"U2",
"2" ), findNet(
"PROM & Misc",
"U6",
"4" ) );
6104 int mvddUr = findNet(
"Power & Control",
"TP13",
"1" );
6105 int mvddUl = findNet(
"Power & Control",
"TP30",
"1" );
6106 int mvddLr = findNet(
"Power & Control",
"TP14",
"1" );
6107 int mvddLl = findNet(
"Power & Control",
"TP31",
"1" );
6108 BOOST_REQUIRE_NE( mvddUr, -1 );
6109 BOOST_REQUIRE_NE( mvddUl, -1 );
6110 BOOST_REQUIRE_NE( mvddLr, -1 );
6111 BOOST_REQUIRE_NE( mvddLl, -1 );
6112 BOOST_CHECK_NE( mvddUr, mvddUl );
6113 BOOST_CHECK_NE( mvddUr, mvddLr );
6114 BOOST_CHECK_NE( mvddUr, mvddLl );
6115 BOOST_CHECK_NE( mvddUl, mvddLr );
6116 BOOST_CHECK_NE( mvddUl, mvddLl );
6117 BOOST_CHECK_NE( mvddLr, mvddLl );
6119 int urLclk = findNet(
"Link Ports NORTH_SOUTH",
"U4",
"V6" );
6120 int lrLclk = findNet(
"Link Ports NORTH_SOUTH",
"U8",
"A13" );
6121 BOOST_REQUIRE_NE( urLclk, -1 );
6122 BOOST_REQUIRE_NE( lrLclk, -1 );
6124 BOOST_CHECK_NE( urLclk, findNet(
"Link Ports NORTH_SOUTH",
"U4",
"V7" ) );
6126 int p1c35 = findNet(
"FMC Connector",
"P1",
"C35" );
6127 int p1c37 = findNet(
"FMC Connector",
"P1",
"C37" );
6128 BOOST_REQUIRE_NE( p1c35, -1 );
6129 BOOST_REQUIRE_NE( p1c37, -1 );
6132 wxString( wxS(
"ll_ul_ns_data_p_0" ) ) );
6138 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6140 if( !corpusEnv || !*corpusEnv )
6142 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping power-symbol connectivity check." );
6146 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"POWER_SOURCE_BOARD_20180717.DSN" );
6150 BOOST_TEST_MESSAGE(
"POWER_SOURCE_BOARD_20180717.DSN not present; skipping power-symbol connectivity check." );
6154 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6157 schematic->SetProject( &manager.
Prj() );
6158 schematic->CurrentSheet().clear();
6159 schematic->CurrentSheet().push_back( &schematic->Root() );
6164 std::vector<std::set<std::string>>
expected = {
6175 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6177 if( !corpusEnv || !*corpusEnv )
6180 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"meta_carrier_sch_rev1.dsn" );
6184 BOOST_TEST_MESSAGE(
"meta_carrier_sch_rev1.dsn not present in corpus; skipping repeated bus check." );
6188 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6191 schematic->SetProject( &manager.
Prj() );
6192 schematic->CurrentSheet().clear();
6193 schematic->CurrentSheet().push_back( &schematic->Root() );
6198 std::vector<std::set<std::string>>
expected = {
6199 {
"J1.1",
"J11.1" },
6200 {
"J12.239",
"J5.239" },
6201 {
"J15.239",
"J3.239" },
6208 wxString netName =
terminalNetName( *schematic, wxS(
"C103" ), wxS(
"1" ) );
6213 std::set<wxString> occurrenceNames;
6224 BOOST_CHECK( occurrenceNames.contains( netName ) );
6231 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6233 if( !corpusEnv || !*corpusEnv )
6236 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"meta_module_sch_rev1.dsn" );
6240 BOOST_TEST_MESSAGE(
"meta_module_sch_rev1.dsn not present in corpus; skipping nested bus check." );
6244 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6247 schematic->SetProject( &manager.
Prj() );
6248 schematic->CurrentSheet().clear();
6249 schematic->CurrentSheet().push_back( &schematic->Root() );
6254 std::vector<std::set<std::string>>
expected = {
6262 wxString netName =
terminalNetName( *schematic, wxS(
"R138" ), wxS(
"1" ) );
6267 std::set<wxString> occurrenceNames;
6278 BOOST_CHECK( occurrenceNames.contains( netName ) );
6285 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6287 if( !corpusEnv || !*corpusEnv )
6290 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"HB1A-AAFM.DSN" );
6294 BOOST_TEST_MESSAGE(
"HB1A-AAFM.DSN not present in corpus; skipping renamed bus check." );
6298 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6301 schematic->SetProject( &manager.
Prj() );
6302 schematic->CurrentSheet().clear();
6303 schematic->CurrentSheet().push_back( &schematic->Root() );
6308 std::vector<std::set<std::string>>
expected = {
6321 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6323 if( !corpusEnv || !*corpusEnv )
6326 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"HB1A-AAFM.DSN" );
6331 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6334 schematic->SetProject( &manager.
Prj() );
6335 schematic->CurrentSheet().clear();
6336 schematic->CurrentSheet().push_back( &schematic->Root() );
6341 auto [consistent, checkable] =
6353 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6355 if( !corpusEnv || !*corpusEnv )
6358 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"buddy_sch_rev1.dsn" );
6362 BOOST_TEST_MESSAGE(
"buddy_sch_rev1.dsn not present in corpus; skipping block-pin geometry check." );
6366 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6369 schematic->SetProject( &manager.
Prj() );
6370 schematic->CurrentSheet().clear();
6371 schematic->CurrentSheet().push_back( &schematic->Root() );
6376 std::vector<std::set<std::string>>
expected = {
6377 {
"J1.C10",
"U1.J19" }, {
"J1.C11",
"U1.K19" }, {
"J3.C10",
"U1.W33" },
6378 {
"J3.F28",
"U1.J35" }, {
"J1.E33",
"U1.B38" }, {
"J3.E33",
"U1.AV40" },
6384 wxString netName =
terminalNetName( *schematic, wxS(
"J6" ), wxS(
"F35" ) );
6385 BOOST_CHECK( !netName.IsEmpty() );
6388 auto mapped = std::find_if( map->
entries.begin(), map->
entries.end(),
6391 return entry.sourceNetId == 9578237
6392 && entry.originalName == wxS(
"CTRL_N3" )
6393 && entry.nameAtImport == netName;
6397 BOOST_REQUIRE_EQUAL( mapped->occurrence.size(), 3u );
6404 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6406 if( !corpusEnv || !*corpusEnv )
6412 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"MC2_REV1_16_2.DSN" );
6420 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6423 schematic->SetProject( &manager.
Prj() );
6424 schematic->CurrentSheet().clear();
6425 schematic->CurrentSheet().push_back( &schematic->Root() );
6440 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6442 if( !corpusEnv || !*corpusEnv )
6445 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"710-DC2693A_REV02_PCA_SCHEMATIC.DSN" );
6451 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6453 schematic->SetProject( &manager.
Prj() );
6454 schematic->CurrentSheet().clear();
6455 schematic->CurrentSheet().push_back( &schematic->Root() );
6473 std::vector<wxString> displayedNumbers;
6478 displayedNumbers.push_back(
pin->GetNumber() );
6481 BOOST_REQUIRE_EQUAL( displayedNumbers.size(), 1u );
6488 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6490 if( !corpusEnv || !*corpusEnv )
6494 corpusEnv,
"CY8CPROTO-040T_PSoC_4000T_CapSense_Prototyping_Board_Schematic.DSN" );
6500 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6502 schematic->SetProject( &manager.
Prj() );
6503 schematic->CurrentSheet().clear();
6504 schematic->CurrentSheet().push_back( &schematic->Root() );
6509 auto displayedPinNumbers =
6512 std::set<wxString> numbers;
6514 if( aSymbol.GetShowPinNumbers() )
6518 if(
pin->IsVisible() &&
pin->GetNumberTextSize() > 0 )
6519 numbers.insert(
pin->GetNumber() );
6550 std::set<wxString> j1PinText;
6554 BOOST_CHECK( !
pin->GetName().IsEmpty() );
6555 BOOST_CHECK( !
pin->GetNumber().IsEmpty() );
6556 BOOST_CHECK_GT(
pin->GetNameTextSize(), 0 );
6557 BOOST_CHECK_GT(
pin->GetNumberTextSize(), 0 );
6558 j1PinText.insert(
pin->GetName() );
6559 j1PinText.insert(
pin->GetNumber() );
6565 BOOST_CHECK( !j1PinText.contains(
static_cast<const SCH_TEXT&
>( item ).
GetText() ) );
6570 BOOST_CHECK( displayedPinNumbers( *u1 ).contains( wxS(
"23" ) ) );
6571 BOOST_CHECK( displayedPinNumbers( *u1 ).contains( wxS(
"H" ) ) );
6572 BOOST_CHECK( displayedPinNumbers( *j11 ).contains( wxS(
"1" ) ) );
6573 BOOST_CHECK( displayedPinNumbers( *j11 ).contains( wxS(
"10" ) ) );
6579 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6581 if( !corpusEnv || !*corpusEnv )
6584 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"CY8CKIT-149 Schematic.DSN" );
6590 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6592 schematic->SetProject( &manager.
Prj() );
6593 schematic->CurrentSheet().clear();
6594 schematic->CurrentSheet().push_back( &schematic->Root() );
6599 const wxImage* blockDiagram =
nullptr;
6600 size_t redShapesOnBlockDiagram = 0;
6601 size_t elephantNotes = 0;
6605 if(
path.Last()->GetName().Contains( wxS(
"Block Diagram" ) ) )
6612 ++redShapesOnBlockDiagram;
6620 if(
text.GetText() == wxS(
"*All Test Points are No Load" ) )
6624 int sourceBottom =
path.Last()->GetName().Contains( wxS(
"PSoC 4100S" ) ) ? 623 : 613;
6626 ink.
Offset(
text.GetSchematicTextOffset(
nullptr ) +
text.GetOffsetToMatchSCH_FIELD(
nullptr ) );
6635 const wxImage*
image =
static_cast<SCH_BITMAP*
>( item )->GetReferenceImage().GetImage().GetImageData();
6640 > blockDiagram->GetWidth() * blockDiagram->GetHeight() ) )
6642 blockDiagram =
image;
6647 BOOST_REQUIRE_MESSAGE( blockDiagram,
"CY8CKIT-149 block diagram was not rendered at full size" );
6650 BOOST_CHECK( schematic->GetEmbeddedFiles()->HasFile( wxS(
"KiCadOrCADElephant-Black.ttf" ) ) );
6651 BOOST_CHECK( schematic->GetAreFontsEmbedded() );
6653 std::array<size_t, 3> blueColumns{};
6654 std::array<size_t, 3> blueRows{};
6655 const int width = blockDiagram->GetWidth();
6656 const int height = blockDiagram->GetHeight();
6658 for(
int y = 0; y < height; ++y )
6660 for(
int x = 0; x < width; ++x )
6662 int red = blockDiagram->GetRed( x, y );
6663 int green = blockDiagram->GetGreen( x, y );
6664 int blue = blockDiagram->GetBlue( x, y );
6668 ++blueColumns[std::min( 2, x * 3 / width )];
6669 ++blueRows[std::min( 2, y * 3 / height )];
6674 const size_t minimumBluePixels =
static_cast<size_t>( width ) * height / 500;
6676 BOOST_TEST_MESSAGE(
"block diagram size=" << width <<
'x' << height <<
" columns=" << blueColumns[0] <<
','
6677 << blueColumns[1] <<
',' << blueColumns[2] <<
" rows="
6678 << blueRows[0] <<
',' << blueRows[1] <<
',' << blueRows[2] );
6680 for(
size_t count : blueColumns )
6681 BOOST_CHECK_GE( count, minimumBluePixels );
6683 for(
size_t count : blueRows )
6684 BOOST_CHECK_GE( count, minimumBluePixels );
6692 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6694 if( !corpusEnv || !*corpusEnv )
6696 BOOST_TEST_MESSAGE(
"KICAD_ORCAD_CORPUS not set; skipping OrCAD component detail." );
6700 namespace fs = std::filesystem;
6701 fs::path dsn = fs::path( corpusEnv ) /
"cutiepi-board" /
"CutiePi_V2.3-20210409.DSN";
6703 if( !fs::exists( dsn ) )
6709 std::unique_ptr<SCHEMATIC> schematic(
new SCHEMATIC(
nullptr ) );
6712 schematic->SetProject( &manager.
Prj() );
6713 schematic->CurrentSheet().clear();
6714 schematic->CurrentSheet().push_back( &schematic->Root() );
6719 std::map<wxString, SCH_SYMBOL*> symbols;
6720 std::multimap<wxString, int> labelSpins;
6749 BOOST_CHECK( symbols[wxS(
"U3" )]->GetShowPinNumbers() );
6750 BOOST_CHECK( symbols[wxS(
"U3" )]->GetShowPinNames() );
6752 BOOST_CHECK( !symbols[wxS(
"R3174" )]->GetShowPinNumbers() );
6753 BOOST_CHECK( !symbols[wxS(
"R3174" )]->GetShowPinNames() );
6757 BOOST_CHECK( !symbols[wxS(
"FB8" )]->GetField(
FIELD_T::VALUE )->IsVisible() );
6763 BOOST_CHECK_GT( fb8Ref->
GetPosition().
x, symbols[wxS(
"FB8" )]->GetPosition().x );
6770 for(
const wxString& ref : { wxS(
"R3186" ), wxS(
"C2517" ), wxS(
"R3189" ), wxS(
"FB13" ), wxS(
"FB9" ) } )
6772 BOOST_REQUIRE_MESSAGE( symbols.count( ref ), ref );
6781 bool checkedPower =
false;
6790 if( val == wxS(
"REG1V8" ) || val == wxS(
"REG3V3" ) )
6793 checkedPower =
true;
6798 BOOST_CHECK( checkedPower );
6801 BOOST_CHECK_GE( noConnects, 17 );
6806 auto range = labelSpins.equal_range( aText );
6808 for(
auto it = range.first; it != range.second; ++it )
6810 if( it->second == (
int) aSpin )
6824 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6826 if( !corpusEnv || !*corpusEnv )
6829 std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"buddy_sch_rev1.dsn" );
6830 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"buddy_sch_rev1.dsn not present in corpus." );
6838 std::set<SCH_SCREEN*> visited;
6844 if( !visited.insert( screen ).second )
6847 std::vector<SCH_ITEM*> hidden;
6857 hidden.push_back( item );
6864 auto [consistent, checkable] =
6865 checkConnectivity( schematic, { {
"U1.BB5",
"J6.J30" }, {
"U1.BA5",
"J6.K31" } } );
6873 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6875 if( !corpusEnv || !*corpusEnv )
6879 BOOST_REQUIRE_MESSAGE( !dsn.empty(),
"M5275EVB.DSN not present in corpus." );
6887 std::set<SCH_SCREEN*> visited;
6893 if( !visited.insert( screen ).second )
6896 std::vector<SCH_LABEL_BASE*> hidden;
6903 hidden.push_back( label );
6908 screen->
Append(
new SCH_LABEL( label->GetPosition(), label->GetText() ) );
6913 const std::vector<std::set<std::string>>
expected = {
6914 {
"J3.38",
"RP49.7",
"U6.D10" },
6915 {
"J3.40",
"RP49.5",
"U6.D11" },
6916 {
"J3.42",
"RP49.3",
"U6.D12" },
6917 {
"J3.44",
"RP49.1",
"U6.D13" },
6918 {
"J4.43",
"RP16.4",
"RP45.5",
"RP9.8",
"TP33.1",
"U1.40",
"U7.47" },
6919 {
"J4.45",
"RP16.8",
"RP45.3",
"RP9.6",
"TP35.1",
"U1.39",
"U7.20" },
6920 {
"J4.47",
"RP9.4" },
6921 {
"J4.49",
"RP15.2",
"RP9.2",
"TP31.1",
"U7.24" },
6922 {
"J5.21",
"R37.2",
"RP50.1",
"U6.G13" },
6923 {
"J5.22",
"RP47.3",
"U6.E13" },
6924 {
"J5.23",
"RP50.3",
"U6.H16" },
6925 {
"J5.24",
"RP47.1",
"U2.6",
"U6.F13" },
6926 {
"J5.25",
"RP50.5",
"U6.H15" },
6927 {
"J5.27",
"RP50.7",
"U6.H14" },
6928 {
"J5.29",
"J9.11",
"RP48.3",
"U6.J14" },
6929 {
"J5.31",
"RP48.5",
"U6.J13",
"U8.25" },
6930 {
"J5.33",
"RP48.7",
"U6.K13",
"U9.25" },
6931 {
"J6.15",
"RP47.7",
"TP4.1",
"U11.12",
"U12.A8",
"U2.1",
"U6.R6" },
6932 {
"J6.21",
"RP47.5",
"U1.6",
"U2.3",
"U6.N7" },
6943 const char* corpusEnv = std::getenv(
"KICAD_ORCAD_CORPUS" );
6945 if( !corpusEnv || !*corpusEnv )
6948 const std::filesystem::path dsn =
findCorpusDesign( corpusEnv,
"HB1A-AAFM.DSN" );
6952 BOOST_TEST_MESSAGE(
"HB1A-AAFM.DSN not present in corpus; skipping sheet-pin repair check." );
6962 std::set<std::set<std::string>> partitions;
6966 std::set<std::string> terminals;
6970 for(
SCH_ITEM* item : subgraph->GetItems() )
6977 wxString reference = symbol->
GetRef( &subgraph->GetSheet(),
false );
6979 if( !reference.IsEmpty() && !reference.StartsWith( wxS(
"#" ) ) )
6981 terminals.insert(
terminalToken( reference.ToStdString( wxConvUTF8 ),
6982 pin->GetNumber().ToStdString( wxConvUTF8 ) ) );
6987 partitions.insert( std::move( terminals ) );
6991 const std::map<std::string, std::set<std::string>>
expected = {
7002 BOOST_CHECK( partitions.count( terminals ) == 1 );
7010 const char* corpus = std::getenv(
"KICAD_ORCAD_CORPUS" );
7012 if( !corpus || !*corpus )
7036 if(
pin->GetNumber() != wxS(
"3" ) )
7040 bool labelled =
false;
7041 bool junction =
false;
7046 BOOST_CHECK( !wire->GetSeg().Contains(
pin->GetPosition() ) );
7048 if( item->GetPosition() !=
pin->GetPosition() )
7053 if(
auto* label =
dynamic_cast<SCH_LABEL*
>( item ) )
7055 labelled |= label->GetText() == wxS(
"Agnd" );
7057 || label->GetTextColor().a > 0 );
7061 BOOST_CHECK( junction );
7062 BOOST_CHECK( labelled );
7066 BOOST_CHECK( found );
7068 for(
const wxString& reference : { wxString(
"COUT1" ), wxString(
"COUT2" ), wxString(
"COUT3" ) } )
constexpr EDA_IU_SCALE schIUScale
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr size_type GetHeight() const
constexpr void Offset(coord_type dx, coord_type dy)
constexpr coord_type GetBottom() const
const NET_MAP & GetNetMap() const
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
A subgraph is a set of items that are electrically connected on a single sheet.
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
KICAD_T Type() const
Returns the type of object.
virtual void SetEnd(const VECTOR2I &aEnd)
FILL_T GetFillMode() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual VECTOR2I GetTextSize() const
COLOR4D GetTextColor() const
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual bool IsVisible() const
GR_TEXT_H_ALIGN_T GetHorizJustify() const
EE_TYPE OfType(KICAD_T aType) const
virtual void SetReporter(REPORTER *aReporter)
Set an optional reporter for warnings/errors.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
std::string AsStdString() const
const UTF8 & GetLibItemName() const
Define a library symbol object.
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
bool HasDeMorganBodyStyles() const override
bool IsGlobalPower() const override
int GetUnitCount() const override
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const override
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
Holds all the data relating to one schematic.
SCH_SHEET_LIST BuildSheetListSortedByPageNumbers() const
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
const IMPORT_NET_MAP * GetImportNetMap() const
void SetProject(PROJECT *aPrj)
CONNECTION_GRAPH * ConnectionGraph() const
Object to handle a bitmap image that can be inserted in a schematic.
VECTOR2I GetPosition() const override
EDA_ANGLE GetDrawRotation() const override
Adjusters to allow EDA_TEXT to draw/print/etc.
virtual const wxString & GetText() const override
Return the string associated with the text object.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
A SCH_IO derivation for loading OrCAD Capture schematic designs (.dsn).
bool CanReadSchematicFile(const wxString &aFileName) const override
The .dsn extension also identifies SPECCTRA files.
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
LIB_SYMBOL * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load a LIB_SYMBOL object having aPartName from the aLibraryPath containing a library format that this...
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
Base class for any item which can be embedded within the SCHEMATIC container class,...
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
SPIN_STYLE GetSpinStyle() const
Segment description base class to describe items which have 2 end points (track, wire,...
SEG GetSeg() const
Get the geometric aspect of the wire as a SEG.
KIGFX::COLOR4D GetLineColor() const
Return COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
const KIID & GetUuid() const
void DeleteItem(SCH_ITEM *aItem)
Remove aItem from the linked list and deletes the object.
void SetPosition(const VECTOR2I &aPos) override
STROKE_PARAMS GetStroke() const override
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...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
SCH_SCREEN * GetScreen() const
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
std::vector< SCH_SHEET_PIN * > & GetPins()
bool GetShowPinNumbers() const override
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
bool GetShowPinNames() const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
const LIB_ID & GetLibId() const override
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit, int aBodyStyle) const override
const wxString GetValue(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString) const override
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
bool IsPower() const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
VECTOR2I GetPosition() const override
bool Contains(const SEG &aSeg) const
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
KIGFX::COLOR4D GetColor() const
A wrapper for reporting to a wxString object.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
@ FILLED_SHAPE
Fill with object color.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ BUS
the source net is carried by a bus
@ RESOLVED
exactly one physical net carries the source net
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
VECTOR2I OleWmfRenderSize(int aNaturalWidth, int aNaturalHeight, int aMaxWidth, int aMaxHeight, double aTargetAspect)
bool OleRenderWmf(const std::vector< uint8_t > &aWmf, int aMaxWidth, int aMaxHeight, wxImage &aImage, double aTargetAspect)
OLE_IMAGE_PAYLOAD ExtractOleImageFromPayload(const std::vector< uint8_t > &aPayload)
Read the picture out of an OLE object payload that carries the 26-byte prologue.
wxString OleDescribeImagePayload(const std::vector< uint8_t > &aPayload)
Include leading bytes when the payload format is unknown.
VECTOR2I OrcadDbuToIu(int aX, int aY)
FILL_T OrcadFillType(int aFillStyle, int aHatchStyle)
int OrcadLineWidthIu(int aWidth)
std::pair< double, double > OrcadDashRatios(int aFormatVersionMajor)
int OrcadTextBaselineOffset(int aTextSize)
std::vector< SEG > OrcadHatchLines(const EDA_SHAPE &aShape, int aHatchStyle, int aPitch)
int OrcadPageOrder(wxString &aName)
Return a numeric page prefix (or -1); strip only the "N - title" convention.
int OrcadHatchPitchIu(uint32_t aModifyTimestamp)
int OrcadHatchLineWidthIu(uint32_t aModifyTimestamp)
KIGFX::COLOR4D OrcadColor(int aColorIndex)
wxString OrcadPinNameMarkup(const wxString &aName)
LINE_STYLE OrcadLineStyle(int aStyle)
int OrcadPageGraphicLineWidthIu(int aWidth)
VECTOR2I OrcadStretchedImageSize(int aWidth, int aHeight, int aBoxWidth, int aBoxHeight)
std::optional< size_t > OrcadLongPrefixCount(int aTypeId)
Registered number of long prefixes for a modern framed structure type.
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
std::string OrcadNormalizeCfbName(const std::string &aName)
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::vector< wxString > occurrence
std::vector< KIID > itemUuids
std::vector< IMPORT_NET_TERMINAL > terminals
Import provenance, held only for the lifetime of the importing SCHEMATIC.
std::vector< IMPORT_NET_MAP_ENTRY > entries
std::vector< uint8_t > data
ORCAD_SCH_IMPORT_FIXTURE()
std::unique_ptr< SCHEMATIC > m_schematic
SETTINGS_MANAGER m_manager
~ORCAD_SCH_IMPORT_FIXTURE()
A simple container for schematic symbol instance information.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_CHECK_EQUAL_COLLECTIONS(mixed.begin(), mixed.end(), expMixed.begin(), expMixed.end())
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
IbisParser parser & reporter
KIBIS top(path, &reporter)
VECTOR3I expected(15, 30, 45)
static std::vector< std::string > splitRefs(const std::string &aCell)
static std::filesystem::path findCorpusDesign(const std::filesystem::path &aRoot, const std::string &aFileName)
static std::set< std::string > parseBomRefs(const std::string &aPath)
static std::vector< std::set< std::string > > parseNetTerminals(const std::string &aPath)
Net terminal sets from .NET.
static std::set< std::string > expectedRefsFor(const std::filesystem::path &aDsn, std::string &aSource)
Ground-truth companion beside .DSN, .NET preferred over .BOM.
static std::string trimCell(std::string aText)
static SCH_SYMBOL * findConvertedSymbol(SCH_SCREEN &aScreen, const SCH_SHEET_PATH &aPath, const wxString &aReference)
static std::pair< int, int > checkConnectivity(SCHEMATIC &aSchematic, const std::vector< std::set< std::string > > &aNets, std::vector< std::set< std::string > > *aInconsistent=nullptr)
Count ground-truth nets whose resolvable terminals all land on one KiCad net after connectivity rebui...
BOOST_AUTO_TEST_CASE(StructurePrefixDepthIsTypeOwned)
static std::set< std::string > parseNetComs(const std::string &aPath)
static std::string terminalToken(const std::string &aRef, const std::string &aPin)
static std::set< std::string > collectImportedRefs(SCHEMATIC &aSchematic)
Unique refdes of real (non-power) parts.
static wxString terminalNetName(SCHEMATIC &aSchematic, const wxString &aReference, const wxString &aPinNumber)
static std::map< std::string, std::vector< std::string > > collectImportedUuids(const SCHEMATIC &aSchematic)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I