20#include <boost/test/unit_test.hpp>
70 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
71 auto parsed = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( parsedRules[0] );
76 BOOST_CHECK_CLOSE( parsed->GetMinViaDiameter(), original.
GetMinViaDiameter(), 0.0001 );
77 BOOST_CHECK_CLOSE( parsed->GetMaxViaDiameter(), original.
GetMaxViaDiameter(), 0.0001 );
78 BOOST_CHECK_CLOSE( parsed->GetMinViaHoleSize(), original.
GetMinViaHoleSize(), 0.0001 );
79 BOOST_CHECK_CLOSE( parsed->GetMaxViaHoleSize(), original.
GetMaxViaHoleSize(), 0.0001 );
89 board.
Add( footprint );
91 auto rule = std::make_shared<DRC_RULE>( wxT(
"String literal" ) );
96 rule->AddConstraint( constraint );
101 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
121 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
122 auto parsed = std::dynamic_pointer_cast<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( parsedRules[0] );
127 BOOST_CHECK_CLOSE( parsed->GetOptWidth(), original.
GetOptWidth(), 0.0001 );
128 BOOST_CHECK_CLOSE( parsed->GetWidthTolerance(), original.
GetWidthTolerance(), 0.0001 );
133 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
135 auto rule1 = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( 0, 0,
"ViaRule", 0.5, 0.8, 0.2, 0.4 );
136 rule1->SetConstraintCode(
"via_style" );
137 rule1->SetRuleCondition(
"A.NetClass == 'Power'" );
138 rules.push_back( rule1 );
140 auto rule2 = std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( 0, 0,
"TrackRule", 0.3, 0.1 );
141 rule2->SetConstraintCode(
"track_width" );
142 rule2->SetRuleCondition(
"A.NetClass == 'Signal'" );
143 rules.push_back( rule2 );
145 wxString filename =
"test_rules.dru";
151 wxFFile file( filename );
154 file.ReadAll( &content );
157 BOOST_CHECK( content.Contains(
"(version 2)" ) );
158 BOOST_CHECK( content.Contains(
"(rule ViaRule" ) );
159 BOOST_CHECK( content.Contains(
"(constraint via_diameter" ) );
160 BOOST_CHECK( content.Contains(
"(constraint hole_size" ) );
161 BOOST_CHECK( content.Contains(
"(rule TrackRule" ) );
162 BOOST_CHECK( content.Contains(
"(constraint track_width" ) );
165 wxRemoveFile( filename );
171 std::vector<RULE_TREE_NODE> ruleTreeNodeDatas;
179 auto data = std::make_shared<DRC_RE_BASE_CONSTRAINT_DATA>( 1, 0,
"TestRule" );
180 data->SetConstraintCode(
"clearance" );
183 ruleTreeNodeDatas.push_back( node );
186 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
190 if( n.m_nodeType !=
RULE )
193 auto d = std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( n.m_nodeData );
196 rules.push_back( d );
204 auto rule = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 0.2,
"ClearanceRule" );
205 rule->SetConstraintCode(
"clearance" );
211 wxString ruleText = rule->GenerateRule( ctx );
213 BOOST_CHECK( ruleText.Contains(
"(constraint clearance (min 0.2mm))" ) );
216 auto rule2 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 10,
"ViaCountRule" );
217 rule2->SetConstraintCode(
"via_count" );
218 ctx.
ruleName = rule2->GetRuleName();
221 ruleText = rule2->GenerateRule( ctx );
222 BOOST_CHECK( ruleText.Contains(
"(constraint via_count (max 10))" ) );
225 auto rule3 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 45,
"AngleRule" );
226 rule3->SetConstraintCode(
"track_angle" );
227 ctx.
ruleName = rule3->GetRuleName();
230 ruleText = rule3->GenerateRule( ctx );
231 BOOST_CHECK( ruleText.Contains(
"(constraint track_angle (min 45deg))" ) );
236 auto rule = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
true,
"DisallowTestRule" );
237 rule->SetConstraintCode(
"disallow" );
243 wxString ruleText = rule->GenerateRule( ctx );
245 BOOST_CHECK( ruleText.Contains(
"(constraint disallow)" ) );
248 auto rule2 = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
false,
"NoDisallowTestRule" );
249 rule2->SetConstraintCode(
"disallow" );
250 ctx.
ruleName = rule2->GetRuleName();
253 ruleText = rule2->GenerateRule( ctx );
254 BOOST_CHECK( ruleText.IsEmpty() );
261 "(rule \"Clearance Rule\"\n"
262 "\t(constraint clearance (min 0.2mm))\n"
263 "\t(condition \"A.NetClass == 'Power'\"))\n"
264 "(rule \"Via Style Rule\"\n"
265 "\t(constraint via_diameter (min 0.5mm))\n"
266 "\t(constraint hole_size (min 0.3mm))\n"
267 "\t(condition \"A.NetClass == 'Power'\"))\n";
271 BOOST_REQUIRE_EQUAL( parsedRules.size(), 2 );
274 auto clearanceRule = parsedRules[0];
279 auto numericData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( clearanceRule );
281 BOOST_CHECK_CLOSE( numericData->GetNumericInputValue(), 0.2, 0.0001 );
284 auto viaStyleRule = parsedRules[1];
288 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( viaStyleRule );
290 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.5, 0.0001 );
291 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.3, 0.0001 );
297 bool parserCalled =
false;
299 [&](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
304 auto data = std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name );
305 data->SetConstraintCode(
"custom_clearance" );
311 wxString ruleText =
"(version 1) (rule \"Test Rule\" (constraint clearance (min 1.0mm)) (condition \"A.Type == 'Pad'\"))";
314 BOOST_CHECK( parserCalled );
315 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
325 BOOST_CHECK(
result.isValid );
326 BOOST_CHECK(
result.errors.empty() );
336 BOOST_CHECK( !
result.isValid );
337 BOOST_CHECK( !
result.errors.empty() );
340 bool foundMinMaxError =
false;
341 for(
const auto& error :
result.errors )
343 if( error.find(
"Minimum Via Diameter cannot be greater than Maximum Via Diameter" ) != std::string::npos )
344 foundMinMaxError =
true;
346 BOOST_CHECK( foundMinMaxError );
356 BOOST_CHECK( !
result.isValid );
357 BOOST_CHECK( !
result.errors.empty() );
360 bool foundNegativeError =
false;
361 for(
const auto& error :
result.errors )
363 if( error.find(
"must be greater than 0" ) != std::string::npos )
364 foundNegativeError =
true;
366 BOOST_CHECK( foundNegativeError );
372 wxString rules = wxS(
"(version 1)\n"
374 " (condition \"A.NetClass == 'HV'\")\n"
375 " (constraint clearance (min 0.5mm))\n"
376 " (constraint track_width (opt 0.3mm)))\n" );
380 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( rules );
382 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
385 auto deleted = std::find_if( entries.begin(), entries.end(),
388 return aEntry.originalRuleText.IsEmpty();
392 entries.erase( deleted );
399 for(
size_t pos = saved.find( wxS(
"(constraint" ) ); pos != wxString::npos;
400 pos = saved.find( wxS(
"(constraint" ), pos + 1 ) )
415 std::unique_ptr<BOARD> board = plugin.
LoadBoard(
path +
".kicad_pcb" );
421 [](
const wxString& aText )
425 std::vector<std::shared_ptr<DRC_RULE>> rules;
430 reporter.GetMessages().ToStdString() << aText.ToStdString() );
432 std::map<wxString, LSET> layers;
434 for(
const std::shared_ptr<DRC_RULE>& rule : rules )
435 layers[rule->m_Name] = rule->m_LayerCondition;
441 wxFFile file(
path +
".kicad_dru",
"r" );
446 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFile(
path +
".kicad_dru" );
451 entry.wasEdited =
true;
455 BOOST_CHECK( layersByRule( saver.
GenerateRulesText( entries, board.get() ) ) == layersByRule( original ) );
459 entries[0].layerCondition =
LSET( {
F_Cu } );
461 std::map<wxString, LSET> single = layersByRule( saver.
GenerateRulesText( entries, board.get() ) );
463 BOOST_CHECK( single[entries[0].ruleName] ==
LSET( {
F_Cu } ) );
488 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> {
489 if( aRule->m_Name ==
"Test" )
490 return std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name +
"_1" );
496 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> {
497 if( aRule->m_Name ==
"Test" )
498 return std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name +
"_2" );
502 wxString ruleText =
"(version 1) (rule \"Test\" (constraint clearance (min 1.0mm)))";
505 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
512 wxString rules = wxS(
"(version 1)\n"
514 " (constraint via_diameter (min 0.4mm) (opt 0.8mm) (max 1.2mm))\n"
515 " (constraint hole_size (min 0.2mm) (opt 0.4mm) (max 0.6mm)))\n" );
519 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( rules );
521 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
523 entries[0].wasEdited =
true;
528 BOOST_CHECK_MESSAGE( saved.find( wxS(
"(opt 0.8mm)" ) ) != wxString::npos,
529 "the via diameter optimum was dropped: " << saved.ToStdString() );
530 BOOST_CHECK_MESSAGE( saved.find( wxS(
"(opt 0.4mm)" ) ) != wxString::npos,
531 "the hole size optimum was dropped: " << saved.ToStdString() );
533 auto data = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
536 data->SetMinViaDiameter( 0.9 );
538 BOOST_CHECK( data->Validate().isValid );
542 BOOST_CHECK_MESSAGE( saved.find( wxS(
"(constraint via_diameter (min 0.9mm) (max 1.2mm))" ) ) != wxString::npos,
543 "the voided optimum was not dropped from the clause: " << saved.ToStdString() );
544 BOOST_CHECK_MESSAGE( saved.find( wxS(
"(opt 0.4mm)" ) ) != wxString::npos,
545 "the untouched hole size optimum must survive: " << saved.ToStdString() );
565 BOOST_CHECK(
result.isValid );
566 BOOST_CHECK(
result.errors.empty() );
576 BOOST_CHECK( !result1.
isValid );
577 BOOST_CHECK( !result1.
errors.empty() );
579 bool foundToleranceError =
false;
581 for(
const auto& error : result1.
errors )
583 if( error.find(
"Tolerance is too large" ) != std::string::npos )
584 foundToleranceError =
true;
587 BOOST_CHECK( foundToleranceError );
594 BOOST_CHECK( !result2.
isValid );
596 bool foundNegativeError =
false;
598 for(
const auto& error : result2.
errors )
600 if( error.find(
"Tolerance must be greater than or equal to 0" ) != std::string::npos )
601 foundNegativeError =
true;
604 BOOST_CHECK( foundNegativeError );
615 BOOST_CHECK(
result.isValid );
616 BOOST_CHECK(
result.errors.empty() );
626 BOOST_CHECK( !result1.
isValid );
627 BOOST_CHECK( !result1.
errors.empty() );
629 bool foundWidthError =
false;
630 for(
const auto& error : result1.
errors )
632 if( error.find(
"Width Tolerance must be less than Optimum Width" ) != std::string::npos )
633 foundWidthError =
true;
635 BOOST_CHECK( foundWidthError );
642 BOOST_CHECK( !result2.
isValid );
644 bool foundNegativeError =
false;
645 for(
const auto& error : result2.
errors )
647 if( error.find(
"must be greater than or equal to 0" ) != std::string::npos )
648 foundNegativeError =
true;
650 BOOST_CHECK( foundNegativeError );
660 BOOST_CHECK( result1.
isValid );
661 BOOST_CHECK( result1.
errors.empty() );
668 BOOST_CHECK( result2.
isValid );
669 BOOST_CHECK( result2.
errors.empty() );
676 BOOST_CHECK( result3.
isValid );
677 BOOST_CHECK( result3.
errors.empty() );
687 BOOST_CHECK( !
result.isValid );
688 BOOST_CHECK( !
result.errors.empty() );
690 bool foundLayerError =
false;
691 for(
const auto& error :
result.errors )
693 if( error.find(
"At least one layer must be selected" ) != std::string::npos )
694 foundLayerError =
true;
696 BOOST_CHECK( foundLayerError );
705 BOOST_CHECK(
result.isValid );
706 BOOST_CHECK(
result.errors.empty() );
715 BOOST_CHECK( !
result.isValid );
716 BOOST_CHECK( !
result.errors.empty() );
719 bool foundError =
false;
720 for(
const auto& error :
result.errors )
722 if( error.find(
"must be greater than 0" ) != std::string::npos )
725 BOOST_CHECK( foundError );
734 BOOST_CHECK(
result.isValid );
735 BOOST_CHECK(
result.errors.empty() );
745 BOOST_CHECK( !
result.isValid );
746 BOOST_CHECK( !
result.errors.empty() );
748 bool foundError =
false;
749 for(
const auto& error :
result.errors )
751 if( error.find(
"Width Tolerance must be less than Optimum Width" ) != std::string::npos )
754 BOOST_CHECK( foundError );
764 BOOST_CHECK( result1.
isValid );
765 BOOST_CHECK( result1.
errors.empty() );
772 BOOST_CHECK( result2.
isValid );
773 BOOST_CHECK( result2.
errors.empty() );
780 BOOST_CHECK( result3.
isValid );
781 BOOST_CHECK( result3.
errors.empty() );
788 BOOST_CHECK( result4.
isValid );
789 BOOST_CHECK( result4.
errors.empty() );
799 BOOST_CHECK( !
result.isValid );
800 BOOST_CHECK( !
result.errors.empty() );
802 bool foundOrientationError =
false;
803 for(
const auto& error :
result.errors )
805 if( error.find(
"At least one orientation must be selected" ) != std::string::npos )
806 foundOrientationError =
true;
808 BOOST_CHECK( foundOrientationError );
818 BOOST_CHECK( resultTrue.
isValid );
819 BOOST_CHECK( resultTrue.
errors.empty() );
826 BOOST_CHECK( resultFalse.
isValid );
827 BOOST_CHECK( resultFalse.
errors.empty() );
837 BOOST_CHECK(
result.isValid );
838 BOOST_CHECK(
result.errors.empty() );
848 BOOST_CHECK( !result1.
isValid );
849 BOOST_CHECK( !result1.
errors.empty() );
851 bool foundHeightError =
false;
852 for(
const auto& error : result1.
errors )
854 if( error.find(
"Minimum Text Height must be greater than 0" ) != std::string::npos )
855 foundHeightError =
true;
857 BOOST_CHECK( foundHeightError );
864 BOOST_CHECK( !result2.
isValid );
866 bool foundThicknessError =
false;
867 for(
const auto& error : result2.
errors )
869 if( error.find(
"Minimum Text Thickness must be greater than 0" ) != std::string::npos )
870 foundThicknessError =
true;
872 BOOST_CHECK( foundThicknessError );
879 BOOST_CHECK( !result3.
isValid );
886 data.
SetRuleText(
"(constraint clearance (min 0.2mm))" );
890 BOOST_CHECK(
result.isValid );
891 BOOST_CHECK(
result.errors.empty() );
901 BOOST_CHECK( !
result.isValid );
902 BOOST_CHECK( !
result.errors.empty() );
905 bool foundEmptyError =
false;
906 for(
const auto& error :
result.errors )
908 if( error.find(
"Rule text cannot be empty" ) != std::string::npos )
909 foundEmptyError =
true;
911 BOOST_CHECK( foundEmptyError );
937 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
939 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
949 DRC_RULE rule(
"ViaDiameterOnlyRule" );
956 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
958 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
982 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
984 BOOST_REQUIRE_EQUAL( matches.size(), 2 );
1014 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1016 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1025 DRC_RULE rule(
"DiffPairWithUncoupledRule" );
1040 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1042 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1053 DRC_RULE rule(
"TrackWidthOnlyRule" );
1062 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1064 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1083 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1085 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1102 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1104 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1112 DRC_RULE rule(
"MatchedLengthRule" );
1125 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1127 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
1130 BOOST_CHECK( matches[0].claimedConstraints.count(
SKEW_CONSTRAINT ) > 0 );
1139 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1184 "(rule \"Via Test\"\n"
1185 " (constraint via_diameter (min 0.5mm) (opt 0.6mm) (max 0.8mm))\n"
1186 " (constraint hole_size (min 0.2mm) (opt 0.3mm) (max 0.4mm)))";
1189 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1191 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1195 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
1198 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.5, 0.0001 );
1199 BOOST_CHECK_CLOSE( viaData->GetMaxViaDiameter(), 0.8, 0.0001 );
1200 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.2, 0.0001 );
1201 BOOST_CHECK_CLOSE( viaData->GetMaxViaHoleSize(), 0.4, 0.0001 );
1209 "(rule \"Track Test\"\n"
1210 " (constraint track_width (min 0.2mm) (opt 0.25mm) (max 0.3mm)))";
1213 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1215 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1219 auto trackData = std::dynamic_pointer_cast<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( entries[0].constraintData );
1222 BOOST_CHECK_CLOSE( trackData->GetOptWidth(), 0.25, 0.0001 );
1223 BOOST_CHECK_CLOSE( trackData->GetWidthTolerance(), 0.05, 0.0001 );
1231 "(rule \"Diff Pair Test\"\n"
1232 " (constraint track_width (min 0.2mm) (opt 0.25mm) (max 0.3mm))\n"
1233 " (constraint diff_pair_gap (min 0.1mm) (opt 0.15mm) (max 0.2mm))\n"
1234 " (constraint diff_pair_uncoupled (max 5mm)))";
1237 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1239 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1242 auto dpData = std::dynamic_pointer_cast<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1245 BOOST_CHECK_CLOSE( dpData->GetOptWidth(), 0.25, 0.0001 );
1246 BOOST_CHECK_CLOSE( dpData->GetWidthTolerance(), 0.05, 0.0001 );
1247 BOOST_CHECK_CLOSE( dpData->GetOptGap(), 0.15, 0.0001 );
1248 BOOST_CHECK_CLOSE( dpData->GetGapTolerance(), 0.05, 0.0001 );
1249 BOOST_CHECK_CLOSE( dpData->GetMaxUncoupledLength(), 5.0, 0.0001 );
1257 "(rule \"Split Test\"\n"
1258 " (constraint via_diameter (min 0.5mm))\n"
1259 " (constraint hole_size (min 0.2mm))\n"
1260 " (constraint clearance (min 0.15mm)))";
1263 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1265 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1275 auto numericData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1277 BOOST_CHECK_CLOSE( numericData->GetNumericInputValue(), 0.15, 0.0001 );
1287 "(rule \"clearance_under_fpga\"\n"
1288 " (constraint clearance (min 0.1mm))\n"
1289 " (constraint hole_size (min 0.2mm))\n"
1290 " (constraint via_diameter (min 0.4mm))\n"
1291 " (condition \"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')\"))";
1294 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1297 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1302 BOOST_CHECK_EQUAL( entries[0].condition,
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')" );
1307 BOOST_CHECK_EQUAL( entries[1].condition,
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')" );
1310 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
1312 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.4, 0.0001 );
1313 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.2, 0.0001 );
1316 auto clearanceData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1318 BOOST_CHECK_CLOSE( clearanceData->GetNumericInputValue(), 0.1, 0.0001 );
1326 "(rule \"Text Test\"\n"
1327 " (constraint text_height (min 1mm))\n"
1328 " (constraint text_thickness (min 0.15mm)))";
1331 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1333 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1336 auto textData = std::dynamic_pointer_cast<DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA>( entries[0].constraintData );
1339 BOOST_CHECK_CLOSE( textData->GetMinTextHeight(), 1.0, 0.0001 );
1340 BOOST_CHECK_CLOSE( textData->GetMinTextThickness(), 0.15, 0.0001 );
1348 "(rule \"Length Test\"\n"
1349 " (constraint length (min 10mm) (opt 30mm) (max 50mm)))";
1352 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1354 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1358 auto lengthData = dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
1360 BOOST_CHECK_CLOSE( lengthData->GetMinimumLength(), 10.0, 0.0001 );
1361 BOOST_CHECK_CLOSE( lengthData->GetOptimumLength(), 30.0, 0.0001 );
1362 BOOST_CHECK_CLOSE( lengthData->GetMaximumLength(), 50.0, 0.0001 );
1370 "(rule \"DP Length Match\"\n"
1371 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1372 " (constraint skew (max 1mm)))";
1375 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1377 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1382 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1385 BOOST_CHECK_CLOSE( matchedData->GetMinimumLength(), 10.0, 0.0001 );
1386 BOOST_CHECK_CLOSE( matchedData->GetOptimumLength(), 30.0, 0.0001 );
1387 BOOST_CHECK_CLOSE( matchedData->GetMaximumLength(), 50.0, 0.0001 );
1388 BOOST_CHECK_CLOSE( matchedData->GetMaxSkew(), 1.0, 0.0001 );
1396 "(rule \"DP Match RT\"\n"
1397 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1398 " (constraint skew (max 2.5mm)))";
1401 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1403 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1404 entries[0].wasEdited =
true;
1409 BOOST_CHECK( savedText.Contains(
"length" ) );
1410 BOOST_CHECK( savedText.Contains(
"skew" ) );
1411 BOOST_CHECK( savedText.Contains(
"2.5mm" ) );
1413 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded = loader.
LoadFromString( savedText );
1415 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1419 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( reloaded[0].constraintData );
1422 BOOST_CHECK_CLOSE( reloadedData->GetMaxSkew(), 2.5, 0.0001 );
1423 BOOST_CHECK_CLOSE( reloadedData->GetMinimumLength(), 10.0, 0.0001 );
1424 BOOST_CHECK_CLOSE( reloadedData->GetOptimumLength(), 30.0, 0.0001 );
1425 BOOST_CHECK_CLOSE( reloadedData->GetMaximumLength(), 50.0, 0.0001 );
1431 wxString ruleText =
"(version 1)\n"
1432 "(rule \"DP Skew Within\"\n"
1433 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1434 " (constraint skew (max 1mm) (within_diff_pairs)))";
1437 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1439 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1443 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1446 BOOST_CHECK_CLOSE( matchedData->GetMaxSkew(), 1.0, 0.0001 );
1447 BOOST_CHECK( matchedData->GetWithinDiffPairs() );
1450 entries[0].wasEdited =
true;
1455 BOOST_CHECK( savedText.Contains(
"within_diff_pairs" ) );
1457 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded = loader.
LoadFromString( savedText );
1459 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1462 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( reloaded[0].constraintData );
1465 BOOST_CHECK_CLOSE( reloadedData->GetMaxSkew(), 1.0, 0.0001 );
1466 BOOST_CHECK( reloadedData->GetWithinDiffPairs() );
1472 wxString ruleText =
"(version 1)\n"
1473 "(rule \"DP Skew Bus\"\n"
1474 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1475 " (constraint skew (max 2mm)))";
1478 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1480 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1483 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1486 BOOST_CHECK( !matchedData->GetWithinDiffPairs() );
1489 entries[0].wasEdited =
true;
1494 BOOST_CHECK( !savedText.Contains(
"within_diff_pairs" ) );
1502 "(rule \"Conditional Test\"\n"
1503 " (condition \"A.NetClass == 'Power'\")\n"
1504 " (constraint clearance (min 0.3mm)))";
1507 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1509 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1512 BOOST_CHECK_EQUAL( entries[0].constraintData->GetRuleCondition(),
"A.NetClass == 'Power'" );
1520 "(rule \"Rule A\"\n"
1521 " (constraint clearance (min 0.2mm)))\n"
1522 "(rule \"Rule B\"\n"
1523 " (constraint track_width (min 0.15mm)))\n"
1524 "(rule \"Rule C\"\n"
1525 " (constraint via_diameter (min 0.5mm))\n"
1526 " (constraint hole_size (min 0.3mm)))";
1529 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1531 BOOST_REQUIRE_EQUAL( entries.size(), 3 );
1548 "(rule \"Empty Rule\")";
1551 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1553 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1561 wxString ruleText =
"not valid rule text at all";
1564 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1574 "(rule \"Edge Clearance\"\n"
1575 " (constraint edge_clearance (min 0.5mm)))\n"
1576 "(rule \"Hole Clearance\"\n"
1577 " (constraint hole_clearance (min 0.3mm)))\n"
1578 "(rule \"Courtyard\"\n"
1579 " (constraint courtyard_clearance (min 0.25mm)))";
1582 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1584 BOOST_REQUIRE_EQUAL( entries.size(), 3 );
1596 wxString ruleText =
"(version 1)\n"
1598 " (constraint microvia_aspect_ratio (max 1.0)))\n"
1600 " (constraint microvia_stack_depth (max 3)))";
1603 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1605 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1609 auto ratio = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[0].constraintData );
1610 auto depth = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1614 BOOST_CHECK_CLOSE( ratio->GetNumericInputValue(), 1.0, 0.0001 );
1615 BOOST_CHECK_CLOSE( depth->GetNumericInputValue(), 3.0, 0.0001 );
1617 entries[0].wasEdited =
true;
1618 entries[1].wasEdited =
true;
1621 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded =
1624 BOOST_REQUIRE_EQUAL( reloaded.size(), 2 );
1626 auto ratioAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[0].constraintData );
1627 auto depthAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[1].constraintData );
1631 BOOST_CHECK_CLOSE( ratioAgain->GetNumericInputValue(), 1.0, 0.0001 );
1632 BOOST_CHECK_CLOSE( depthAgain->GetNumericInputValue(), 3.0, 0.0001 );
1648 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1649 numericData->SetRuleName(
"TestClearance" );
1650 numericData->SetConstraintCode(
"clearance" );
1651 numericData->SetNumericInputValue( 0.2 );
1655 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1658 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1659 BOOST_CHECK(
result.Contains(
"TestClearance" ) );
1660 BOOST_CHECK(
result.Contains(
"clearance" ) );
1669 entry.
originalRuleText =
"(rule \"Preserved Rule\"\n\t(constraint clearance (min 0.5mm)))";
1672 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1673 numericData->SetRuleName(
"Preserved Rule" );
1674 numericData->SetConstraintCode(
"clearance" );
1675 numericData->SetNumericInputValue( 0.5 );
1679 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1691 entry.
originalRuleText =
"(rule \"EditedRule\"\n\t(constraint clearance (min 0.5mm)))";
1694 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1695 numericData->SetRuleName(
"EditedRule" );
1696 numericData->SetConstraintCode(
"clearance" );
1697 numericData->SetNumericInputValue( 0.3 );
1701 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1705 BOOST_CHECK( !
result.Contains(
"0.5mm" ) );
1706 BOOST_CHECK(
result.Contains(
"EditedRule" ) );
1716 auto viaData = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>();
1717 viaData->SetRuleName(
"ViaTest" );
1718 viaData->SetMinViaDiameter( 0.5 );
1719 viaData->SetMaxViaDiameter( 0.8 );
1720 viaData->SetMinViaHoleSize( 0.2 );
1721 viaData->SetMaxViaHoleSize( 0.4 );
1726 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1729 BOOST_CHECK(
result.Contains(
"ViaTest" ) );
1730 BOOST_CHECK(
result.Contains(
"via_diameter" ) );
1731 BOOST_CHECK(
result.Contains(
"hole_size" ) );
1737 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1742 auto data1 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1743 data1->SetRuleName(
"RuleA" );
1744 data1->SetConstraintCode(
"clearance" );
1745 data1->SetNumericInputValue( 0.2 );
1748 entries.push_back( entry1 );
1753 auto data2 = std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>();
1754 data2->SetRuleName(
"RuleB" );
1755 data2->SetOptWidth( 0.2 );
1756 data2->SetWidthTolerance( 0.1 );
1759 entries.push_back( entry2 );
1765 BOOST_CHECK(
result.Contains(
"RuleA" ) );
1766 BOOST_CHECK(
result.Contains(
"RuleB" ) );
1769 size_t posA =
result.Find(
"RuleA" );
1770 size_t posB =
result.Find(
"RuleB" );
1771 BOOST_CHECK( posA < posB );
1779 entry.
ruleName =
"ConditionalRule";
1780 entry.
condition =
"A.NetClass == 'Power'";
1782 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1783 numericData->SetRuleName(
"ConditionalRule" );
1784 numericData->SetConstraintCode(
"clearance" );
1785 numericData->SetRuleCondition(
"A.NetClass == 'Power'" );
1786 numericData->SetNumericInputValue( 0.3 );
1791 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1794 BOOST_CHECK(
result.Contains(
"ConditionalRule" ) );
1795 BOOST_CHECK(
result.Contains(
"condition" ) );
1796 BOOST_CHECK(
result.Contains(
"Power" ) );
1803 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1806 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1821 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1825 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1826 BOOST_CHECK( !
result.Contains(
"Null Data Rule" ) );
1832 wxString originalText =
1834 "(rule \"RoundTripTest\"\n"
1835 " (constraint clearance (min 0.25mm)))";
1838 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
1840 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1844 entries[0].wasEdited =
true;
1851 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
1853 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
1861 for(
const char*
name : {
"issue16182.kicad_dru",
"issue20480/issue20480.kicad_dru" } )
1867 wxFFile file(
path,
"r" );
1870 file.ReadAll( &content );
1873 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFile(
path );
1887 const wxString originalName = wxS(
"Annular width: LEDs" );
1894 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1895 numericData->SetRuleName( originalName );
1896 numericData->SetConstraintCode(
"annular_width" );
1897 numericData->SetNumericInputValue( 0.085 );
1901 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1905 BOOST_CHECK(
result.Contains( wxS(
"\"Annular width: LEDs\"" ) ) );
1906 BOOST_CHECK( !
result.Contains( wxS(
"Annular_width__LEDs" ) ) );
1912 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1922 entry.
ruleName = wxS(
"My_Bare_Rule-1.0" );
1925 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1926 numericData->SetRuleName( entry.
ruleName );
1927 numericData->SetConstraintCode(
"clearance" );
1928 numericData->SetNumericInputValue( 0.2 );
1932 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1935 BOOST_CHECK(
result.Contains( wxS(
"(rule My_Bare_Rule-1.0\n" ) ) );
1936 BOOST_CHECK( !
result.Contains( wxS(
"\"My_Bare_Rule-1.0\"" ) ) );
1946 entry.
ruleName = wxS(
"3.3V_Power" );
1949 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1950 numericData->SetRuleName( entry.
ruleName );
1951 numericData->SetConstraintCode(
"clearance" );
1952 numericData->SetNumericInputValue( 0.2 );
1956 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1959 BOOST_CHECK(
result.Contains( wxS(
"\"3.3V_Power\"" ) ) );
1963 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1975 auto dpData = std::make_shared<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>();
1976 dpData->SetRuleName(
"DiffPairTest" );
1977 dpData->SetOptWidth( 0.25 );
1978 dpData->SetWidthTolerance( 0.05 );
1979 dpData->SetOptGap( 0.15 );
1980 dpData->SetGapTolerance( 0.05 );
1981 dpData->SetMaxUncoupledLength( 5.0 );
1986 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1989 BOOST_CHECK(
result.Contains(
"DiffPairTest" ) );
1990 BOOST_CHECK(
result.Contains(
"track_width" ) );
1991 BOOST_CHECK(
result.Contains(
"diff_pair_gap" ) );
2004 "(rule \"PTH to Track Clearance\"\n"
2005 " (constraint hole_clearance (min 1.0mm))\n"
2006 " (condition \"A.Type == 'Pad' && A.Pad_Type == 'Through-hole' && B.Type =='Track'\"))\n"
2007 "(rule \"Max Drill Hole Size Mechanical\"\n"
2008 " (constraint hole (max 2.0mm))\n"
2009 " (condition \"A.Type == 'Pad'\"))";
2012 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2014 BOOST_REQUIRE_GE( entries.size(), 2 );
2019 BOOST_CHECK( !entries[0].condition.IsEmpty() );
2031 "(rule board_edge\n"
2032 " (constraint edge_clearance (min 1mm))\n"
2033 " (condition \"A.memberOf('board_edge')\")\n"
2034 " (severity ignore))";
2037 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2039 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2050 "(rule high_current_netclass\n"
2051 " (constraint connection_width (min 0.16mm))\n"
2052 " (condition \"A.NetClass == 'High_current'\"))\n"
2053 "(rule high_current_area\n"
2054 " (constraint connection_width (min 0.16mm))\n"
2055 " (condition \"A.insideArea('high_current')\"))";
2058 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2060 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
2067 BOOST_CHECK( !entries[0].condition.IsEmpty() );
2068 BOOST_CHECK( !entries[1].condition.IsEmpty() );
2075 wxString originalText =
2077 "(rule ClearanceRule\n"
2078 " (constraint clearance (min 0.2mm))\n"
2079 " (condition \"A.NetClass == 'Power'\"))\n"
2080 "(rule TrackWidthRule\n"
2081 " (constraint track_width (min 0.15mm) (opt 0.2mm) (max 0.3mm)))";
2084 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2086 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
2089 for(
auto& entry : entries )
2090 entry.wasEdited =
true;
2097 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2099 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 2 );
2113 wxString originalText =
2115 "(rule \"Via Style\"\n"
2116 " (constraint via_diameter (min 0.5mm) (opt 0.6mm) (max 0.8mm))\n"
2117 " (constraint hole_size (min 0.2mm) (opt 0.3mm) (max 0.4mm)))";
2120 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2122 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2125 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
2128 double originalMinDia = viaData->GetMinViaDiameter();
2129 double originalMinHole = viaData->GetMinViaHoleSize();
2132 entries[0].wasEdited =
true;
2137 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2139 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
2142 auto reloadedViaData =
2143 std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
2146 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaDiameter(), originalMinDia, 0.0001 );
2147 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaHoleSize(), originalMinHole, 0.0001 );
2155 "(rule \"Rule A\"\n"
2156 " (constraint clearance (min 0.2mm)))\n"
2157 "(rule \"Rule B\"\n"
2158 " (constraint via_diameter (min 0.5mm))\n"
2159 " (constraint hole_size (min 0.2mm))\n"
2160 " (constraint track_width (min 0.15mm)))\n"
2161 "(rule \"Rule C\"\n"
2162 " (constraint edge_clearance (min 0.3mm)))";
2165 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2168 BOOST_REQUIRE_GE( entries.size(), 4 );
2171 int ruleACount = 0, ruleBCount = 0, ruleCCount = 0;
2173 for(
const auto& entry : entries )
2175 if( entry.ruleName ==
"Rule A" )
2177 else if( entry.ruleName ==
"Rule B" )
2179 else if( entry.ruleName ==
"Rule C" )
2184 BOOST_CHECK_GE( ruleBCount, 2 );
2188 int lastAIndex = -1, firstBIndex = entries.size(), lastBIndex = -1, firstCIndex = entries.size();
2190 for(
size_t i = 0; i < entries.size(); i++ )
2192 if( entries[i].ruleName ==
"Rule A" )
2194 else if( entries[i].ruleName ==
"Rule B" )
2196 if( (
int)i < firstBIndex )
2201 else if( entries[i].ruleName ==
"Rule C" )
2203 if( (
int)i < firstCIndex )
2208 BOOST_CHECK( lastAIndex < firstBIndex );
2209 BOOST_CHECK( lastBIndex < firstCIndex );
2221 wxString expr =
"A.NetName == 'VCC'";
2224 BOOST_CHECK( !expr.IsEmpty() );
2225 BOOST_CHECK( expr.Contains(
"NetName" ) );
2226 BOOST_CHECK( expr.Contains(
"VCC" ) );
2232 wxString expr =
"A.NetName == 'VCC' && B.NetClass == 'Power'";
2235 BOOST_CHECK( expr.Contains(
"&&" ) );
2236 BOOST_CHECK( expr.Contains(
"NetName" ) );
2237 BOOST_CHECK( expr.Contains(
"NetClass" ) );
2243 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2246 BOOST_CHECK( expr.Contains(
"||" ) );
2247 BOOST_CHECK( expr.Contains(
"intersectsArea" ) );
2253 wxString expr =
"A.NetClass == 'Power' && !A.intersectsArea('NoRouting')";
2256 BOOST_CHECK( expr.Contains(
"&&" ) );
2257 BOOST_CHECK( expr.Contains(
"!" ) );
2263 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2266 BOOST_CHECK( expr.Contains(
"||" ) );
2267 BOOST_CHECK( expr.Contains(
"underFPGA" ) );
2268 BOOST_CHECK( expr.Contains(
"underDDR" ) );
2274 while( ( pos = expr.find(
"||", pos ) ) != wxString::npos )
2297 for(
KICAD_T type : excludedTypes )
2304 BOOST_CHECK(
true );
2308 BOOST_FAIL(
"Excluded type not handled in filter" );
2313 for(
KICAD_T type : includedTypes )
2320 BOOST_FAIL(
"Included type incorrectly matched by filter" );
2324 BOOST_CHECK(
true );
2337 entry.
condition =
"A.NetClass == 'Power'";
2341 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2342 data->SetRuleName(
"SilkMaskTest" );
2343 data->SetConstraintCode(
"silk_clearance" );
2344 data->SetRuleCondition(
"A.NetClass == 'Power'" );
2345 data->SetNumericInputValue( 0.15 );
2349 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2353 BOOST_CHECK(
result.Contains(
"L == 'F.Mask'" ) );
2354 BOOST_CHECK(
result.Contains(
"Power" ) );
2355 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2360 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2378 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2379 data->SetRuleName(
"SilkMaskSimple" );
2380 data->SetConstraintCode(
"silk_clearance" );
2381 data->SetNumericInputValue( 0.1 );
2385 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2388 BOOST_CHECK(
result.Contains(
"L == 'B.Mask'" ) );
2389 BOOST_CHECK(
result.Contains(
"(condition" ) );
2390 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2402 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2403 data->SetRuleName(
"SilkSilkBoth" );
2404 data->SetConstraintCode(
"silk_clearance" );
2405 data->SetNumericInputValue( 0.2 );
2409 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2412 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS' || L == 'B.SilkS'" ) );
2413 BOOST_CHECK(
result.Contains(
"(condition" ) );
2414 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2426 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2427 data->SetRuleName(
"SilkSilkFront" );
2428 data->SetConstraintCode(
"silk_clearance" );
2429 data->SetNumericInputValue( 0.2 );
2433 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2436 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2437 BOOST_CHECK( !
result.Contains(
"B.SilkS" ) );
2438 BOOST_CHECK(
result.Contains(
"(condition" ) );
2439 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2448 entry.
condition =
"A.NetClass == 'Signal'";
2452 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2453 data->SetRuleName(
"SilkSilkCond" );
2454 data->SetConstraintCode(
"silk_clearance" );
2455 data->SetRuleCondition(
"A.NetClass == 'Signal'" );
2456 data->SetNumericInputValue( 0.2 );
2460 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2463 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2464 BOOST_CHECK(
result.Contains(
"Signal" ) );
2469 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2482 BOOST_CHECK( result1.
isValid );
2483 BOOST_CHECK( result1.
errors.empty() );
2488 BOOST_CHECK( result2.
isValid );
2489 BOOST_CHECK( result2.
errors.empty() );
2497 BOOST_CHECK( !
result.isValid );
2498 BOOST_CHECK( !
result.errors.empty() );
2500 bool foundError =
false;
2501 for(
const auto& error :
result.errors )
2503 if( error.find(
"At least one via type must be selected" ) != std::string::npos )
2506 BOOST_CHECK( foundError );
2518 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2519 BOOST_CHECK( clauses[0].Contains(
"disallow via" ) );
2520 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2525 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2526 BOOST_CHECK( clauses[0].Contains(
"micro_via" ) );
2527 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2528 BOOST_CHECK( !clauses[0].Contains(
"blind_via" ) );
2529 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2534 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2535 BOOST_CHECK( clauses[0].Contains(
"through_via" ) );
2536 BOOST_CHECK( clauses[0].Contains(
"blind_via" ) );
2537 BOOST_CHECK( !clauses[0].Contains(
"micro_via" ) );
2538 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2543 BOOST_CHECK( clauses.empty() );
2549 wxString originalText =
"(version 1)\n"
2550 "(rule \"ViasUnderSmdTest\"\n"
2551 " (constraint disallow micro_via)\n"
2552 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2555 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2557 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2560 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2564 BOOST_CHECK( !viaData->GetDisallowThroughVias() );
2565 BOOST_CHECK( viaData->GetDisallowMicroVias() );
2566 BOOST_CHECK( !viaData->GetDisallowBlindVias() );
2567 BOOST_CHECK( !viaData->GetDisallowBuriedVias() );
2570 entries[0].wasEdited =
true;
2575 BOOST_CHECK( savedText.Contains(
"micro_via" ) );
2576 BOOST_CHECK( !savedText.Contains(
"through_via" ) );
2577 BOOST_CHECK( !savedText.Contains(
"blind_via" ) );
2578 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2581 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2582 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
2585 std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
2588 BOOST_CHECK( !reloadedData->GetDisallowThroughVias() );
2589 BOOST_CHECK( reloadedData->GetDisallowMicroVias() );
2590 BOOST_CHECK( !reloadedData->GetDisallowBlindVias() );
2591 BOOST_CHECK( !reloadedData->GetDisallowBuriedVias() );
2594 wxString blanketText =
"(version 1)\n"
2595 "(rule \"BlanketVia\"\n"
2596 " (constraint disallow via)\n"
2597 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2600 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2602 auto blanketData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2605 BOOST_CHECK( blanketData->GetDisallowThroughVias() );
2606 BOOST_CHECK( blanketData->GetDisallowMicroVias() );
2607 BOOST_CHECK( blanketData->GetDisallowBlindVias() );
2608 BOOST_CHECK( blanketData->GetDisallowBuriedVias() );
2611 wxString multiText =
"(version 1)\n"
2612 "(rule \"TwoVias\"\n"
2613 " (constraint disallow through_via blind_via)\n"
2614 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2617 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2619 auto multiData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2622 BOOST_CHECK( multiData->GetDisallowThroughVias() );
2623 BOOST_CHECK( !multiData->GetDisallowMicroVias() );
2624 BOOST_CHECK( multiData->GetDisallowBlindVias() );
2625 BOOST_CHECK( !multiData->GetDisallowBuriedVias() );
2627 entries[0].wasEdited =
true;
2630 BOOST_CHECK( savedText.Contains(
"through_via" ) );
2631 BOOST_CHECK( savedText.Contains(
"blind_via" ) );
2632 BOOST_CHECK( !savedText.Contains(
"micro_via" ) );
2633 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2639 wxString ruleText =
"(version 1)\n"
2640 "(rule \"Angled\"\n"
2641 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2645 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2647 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2650 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2652 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2653 BOOST_CHECK( !customData->GetRuleText().Contains( wxS(
"Angled" ) ) );
2656 wxString ruleTextUnquoted =
"(version 1)\n"
2658 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2663 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2666 auto customDataUnquoted =
2667 std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2669 BOOST_CHECK( customDataUnquoted->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2670 BOOST_CHECK( !customDataUnquoted->GetRuleText().Contains( wxS(
"Angled" ) ) );
2675 wxString ruleText =
"(version 1)\n"
2676 "(rule \"Standard\"\n"
2677 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg\")\n"
2681 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2683 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2687 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2689 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2690 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2691 BOOST_CHECK( !orientData->GetIsOneEightyDegreesAllowed() );
2692 BOOST_CHECK( !orientData->GetIsAllDegreesAllowed() );
2695 wxString singleLine =
"(version 1) (rule \"SingleLine\" (constraint assertion \"A.Orientation == 0 deg || "
2696 "A.Orientation == 90 deg\"))";
2700 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2703 auto singleLineData =
2704 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2706 BOOST_CHECK( singleLineData->GetIsZeroDegreesAllowed() );
2707 BOOST_CHECK( singleLineData->GetIsNinetyDegreesAllowed() );
2708 BOOST_CHECK( !singleLineData->GetIsOneEightyDegreesAllowed() );
2709 BOOST_CHECK( !singleLineData->GetIsAllDegreesAllowed() );
2714 wxString ruleText =
"(version 1)\n"
2715 "(rule \"AllAngles\"\n"
2716 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg || "
2717 "A.Orientation == 180 deg || A.Orientation == 270 deg\")\n"
2721 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2723 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2727 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2729 BOOST_CHECK( orientData->GetIsAllDegreesAllowed() );
2730 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2731 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2732 BOOST_CHECK( orientData->GetIsOneEightyDegreesAllowed() );
2733 BOOST_CHECK( orientData->GetIsTwoSeventyDegreesAllowed() );
2738 wxString ruleText =
"(version 1)\n"
2739 "(rule \"InnerLayers\"\n"
2740 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'In1.Cu'\")\n"
2744 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2746 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2749 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2751 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"In1.Cu" ) ) );
2756 wxString ruleText =
"(version 1)\n"
2757 "(rule \"StandardLayers\"\n"
2758 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'B.Cu'\")\n"
2762 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2764 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2767 auto layerData = std::dynamic_pointer_cast<DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA>( entries[0].constraintData );
2769 BOOST_CHECK( layerData->GetTopLayerEnabled() );
2770 BOOST_CHECK( layerData->GetBottomLayerEnabled() );
2781 board.
Add( vendorFp );
2785 board.
Add( otherFp );
2787 auto rule = std::make_shared<DRC_RULE>( wxT(
"Custom property" ) );
2788 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.customProperty('Vendor') == 'ACME'" ) );
2792 rule->AddConstraint( constraint );
2798 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2799 BOOST_CHECK( matches.front() == vendorFp );
2810 board.
Add( vendorFp );
2814 board.
Add( otherFp );
2816 auto rule = std::make_shared<DRC_RULE>( wxT(
"Has custom property" ) );
2817 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.hasCustomProperty('Vendor')" ) );
2821 rule->AddConstraint( constraint );
2827 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2828 BOOST_CHECK( matches.front() == vendorFp );
2835 wxString ruleText =
"(version 1)\n"
2836 "(rule \"clk_delay\"\n"
2837 " (constraint length (min 210ps) (max 230ps))\n"
2841 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2843 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2846 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2848 BOOST_CHECK( data->IsTimeDomain() );
2849 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 220.0, 0.0001 );
2850 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2866 BOOST_CHECK( ruleText.Contains( wxS(
"210ps" ) ) );
2867 BOOST_CHECK( ruleText.Contains( wxS(
"220ps" ) ) );
2868 BOOST_CHECK( ruleText.Contains( wxS(
"230ps" ) ) );
2871 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2873 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2875 auto parsed = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2877 BOOST_CHECK( parsed->IsTimeDomain() );
2878 BOOST_CHECK_CLOSE( parsed->GetOptimumLength(), 220.0, 0.0001 );
2879 BOOST_CHECK_CLOSE( parsed->GetTolerance(), 10.0, 0.0001 );
2886 wxString ruleText =
"(version 1)\n"
2887 "(rule \"len_window\"\n"
2888 " (constraint length (min 30mm) (max 50mm))\n"
2892 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2894 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2897 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2899 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 40.0, 0.0001 );
2900 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2903 ctx.
ruleName = entries[0].ruleName;
2906 wxString saved = data->GenerateRule( ctx );
2908 BOOST_CHECK( saved.Contains( wxS(
"30mm" ) ) );
2909 BOOST_CHECK( saved.Contains( wxS(
"40mm" ) ) );
2910 BOOST_CHECK( saved.Contains( wxS(
"50mm" ) ) );
2917 wxString ruleText =
"(rule \"length_DDR_Byte0\"\n"
2919 "\t# (constraint length (min 29.5mm) (max 30.5mm) (opt 30mm))\n"
2920 "(constraint length (min 210ps) (max 230ps) (opt 223ps))\n"
2921 "\t# tightened after bring-up\n"
2922 "\t(condition \"A.NetClass == 'DDR4_BYTE0'\"))";
2926 BOOST_CHECK( body.StartsWith( wxS(
"(constraint length (min 210ps)" ) ) );
2927 BOOST_CHECK( !body.Contains( wxS(
"29.5mm" ) ) );
2928 BOOST_CHECK( !body.Contains( wxS(
"byte lane" ) ) );
2929 BOOST_CHECK( !body.Contains( wxS(
"bring-up" ) ) );
2930 BOOST_CHECK( body.Contains( wxS(
"condition" ) ) );
2934 BOOST_CHECK( comment.Contains( wxS(
"byte lane 0" ) ) );
2935 BOOST_CHECK( comment.Contains( wxS(
"29.5mm" ) ) );
2936 BOOST_CHECK( comment.Contains( wxS(
"bring-up" ) ) );
2943 wxString ruleText =
"(version 1)\n"
2944 "(rule \"pair_ps\"\n"
2945 " (constraint length (min 10mm) (opt 11mm) (max 12mm))\n"
2946 " (constraint skew (max 5ps))\n"
2950 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2952 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2955 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2957 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"5ps" ) ) );
2963 wxString ruleText =
"(version 1)\n"
2964 "(rule \"len_mm\"\n"
2965 " (constraint length (min 30mm) (opt 40mm) (max 50mm))\n"
2969 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2971 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
General utilities for PCB file IO for QA programs.
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
MINOPTMAX< int > & Value()
Design Rule Checker object that performs all the DRC tests.
std::vector< BOARD_ITEM * > GetItemsMatchingRule(const std::shared_ptr< DRC_RULE > &aRule, REPORTER *aReporter=nullptr)
Maps DRC rule constraints to appropriate editor panels.
DRC_RULE_EDITOR_CONSTRAINT_NAME GetPanelForConstraint(DRC_CONSTRAINT_T aConstraintType)
Get the panel type for a single constraint.
bool CanPanelLoad(DRC_RULE_EDITOR_CONSTRAINT_NAME aPanel, const std::set< DRC_CONSTRAINT_T > &aConstraints)
Check if a specific panel type can load a set of constraints.
std::vector< DRC_PANEL_MATCH > MatchRule(const DRC_RULE &aRule)
Match a DRC rule to one or more panel types.
VALIDATION_RESULT Validate() const override
Validates the constraint data.
void SetTimeDomain(bool aTimeDomain)
wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext) override
VALIDATION_RESULT Validate() const override
Validates the constraint data.
wxString GetConstraintCode() const
void SetConstraintCode(const wxString &aCode)
wxString GetRuleCondition()
void SetRuleCondition(const wxString &aRuleCondition)
Simple constraint data object used by custom rules.
void SetRuleText(const wxString &aText)
VALIDATION_RESULT Validate() const override
Validates the constraint data.
VALIDATION_RESULT Validate() const override
Validates the constraint data.
VALIDATION_RESULT Validate() const override
Validates the constraint data.
VALIDATION_RESULT Validate() const override
Validates the constraint data.
double GetWidthTolerance()
wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext) override
VALIDATION_RESULT Validate() const override
Validates the constraint data.
VALIDATION_RESULT Validate() const override
Validates the constraint data.
std::vector< wxString > GetConstraintClauses(const RULE_GENERATION_CONTEXT &aContext) const override
Returns just the constraint clauses without the rule wrapper.
double GetMaxViaDiameter()
double GetMinViaHoleSize()
double GetMinViaDiameter()
double GetMaxViaHoleSize()
VALIDATION_RESULT Validate() const override
Validates the constraint data.
wxString GenerateRule(const RULE_GENERATION_CONTEXT &aContext) override
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
static bool SaveRules(const wxString &aFilename, const std::vector< std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > > &aRules, const BOARD *aBoard)
static void RegisterRuleConverter(RuleConverter aConverter)
static std::vector< std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > > ParseRules(const wxString &aRules)
Loads DRC rules from .kicad_dru files and converts them to panel entries.
const DRC_RE_FILE_TRIVIA & GetFileTrivia() const
std::vector< DRC_RE_LOADED_PANEL_ENTRY > LoadFromString(const wxString &aRulesText)
Load rules from a text string.
static wxString ExtractRuleComment(const wxString &aOriginalText)
Extract comment lines from a rule.
static wxString ExtractRuleBody(const wxString &aOriginalText)
Extract the body of a rule from its original text, stripping the (rule "name" ...) wrapper.
std::vector< DRC_RE_LOADED_PANEL_ENTRY > LoadFile(const wxString &aPath)
Load all rules from a .kicad_dru file.
Saves DRC panel entries back to .kicad_dru files.
wxString GenerateRulesText(const std::vector< DRC_RE_LOADED_PANEL_ENTRY > &aEntries, const BOARD *aBoard=nullptr, const DRC_RE_FILE_TRIVIA &aTrivia={})
Generate rule text from panel entries.
void AddConstraint(DRC_CONSTRAINT &aConstraint)
void SetCustomProperty(const wxString &aKey, const wxString &aValue)
LSET is a set of PCB_LAYER_IDs.
A PCB_IO derivation for saving and loading Pcbnew s-expression formatted files.
std::unique_ptr< BOARD > LoadBoard(const wxString &aFileName, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into new BOA...
wxString GetRuleName()
Get the name of the rule.
A wrapper for reporting to a wxString object.
@ COURTYARD_CLEARANCE_CONSTRAINT
@ VIA_DIAMETER_CONSTRAINT
@ DIFF_PAIR_GAP_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ MAX_UNCOUPLED_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
@ SILK_TO_SOLDERMASK_CLEARANCE
@ MINIMUM_CONNECTION_WIDTH
@ MINIMUM_TEXT_HEIGHT_AND_THICKNESS
@ COPPER_TO_HOLE_CLEARANCE
@ MATCHED_LENGTH_DIFF_PAIR
@ COPPER_TO_EDGE_CLEARANCE
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
Represents a rule loaded from a .kicad_dru file and mapped to a panel.
wxString originalRuleText
std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > constraintData
DRC_RULE_EDITOR_CONSTRAINT_NAME panelType
wxString conditionExpression
Structure representing a node in a rule tree, collection of this used for building the rule tree.
std::shared_ptr< RULE_EDITOR_DATA_BASE > m_nodeData
Result of a validation operation.
std::vector< wxString > errors
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(RoundTripViaStyle)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
IbisParser parser & reporter
BOOST_TEST_CONTEXT("Test Clearance")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)