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 hole_aspect_ratio (max 1.0))\n"
1599 " (condition \"A.Via_Type == 'Micro'\"))\n"
1600 "(rule \"HoleRatio\"\n"
1601 " (constraint hole_aspect_ratio (max 8.0)))\n"
1603 " (constraint microvia_stack_depth (max 3)))";
1606 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1609 BOOST_REQUIRE_EQUAL( entries.size(), 3 );
1614 auto scoped = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[0].constraintData );
1615 auto plain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1616 auto depth = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[2].constraintData );
1621 BOOST_CHECK_CLOSE( scoped->GetNumericInputValue(), 1.0, 0.0001 );
1622 BOOST_CHECK_CLOSE( plain->GetNumericInputValue(), 8.0, 0.0001 );
1623 BOOST_CHECK_CLOSE( depth->GetNumericInputValue(), 3.0, 0.0001 );
1625 BOOST_CHECK_EQUAL( scoped->GetRuleCondition(), wxString( wxS(
"A.Via_Type == 'Micro'" ) ) );
1626 BOOST_CHECK( plain->GetRuleCondition().IsEmpty() );
1628 entries[0].wasEdited =
true;
1629 entries[1].wasEdited =
true;
1630 entries[2].wasEdited =
true;
1633 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded =
1636 BOOST_REQUIRE_EQUAL( reloaded.size(), 3 );
1641 auto scopedAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[0].constraintData );
1642 auto plainAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[1].constraintData );
1643 auto depthAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[2].constraintData );
1648 BOOST_CHECK_CLOSE( scopedAgain->GetNumericInputValue(), 1.0, 0.0001 );
1649 BOOST_CHECK_CLOSE( plainAgain->GetNumericInputValue(), 8.0, 0.0001 );
1650 BOOST_CHECK_CLOSE( depthAgain->GetNumericInputValue(), 3.0, 0.0001 );
1653 BOOST_CHECK_EQUAL( scopedAgain->GetRuleCondition(), wxString( wxS(
"A.Via_Type == 'Micro'" ) ) );
1654 BOOST_CHECK( plainAgain->GetRuleCondition().IsEmpty() );
1670 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1671 numericData->SetRuleName(
"TestClearance" );
1672 numericData->SetConstraintCode(
"clearance" );
1673 numericData->SetNumericInputValue( 0.2 );
1677 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1680 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1681 BOOST_CHECK(
result.Contains(
"TestClearance" ) );
1682 BOOST_CHECK(
result.Contains(
"clearance" ) );
1691 entry.
originalRuleText =
"(rule \"Preserved Rule\"\n\t(constraint clearance (min 0.5mm)))";
1694 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1695 numericData->SetRuleName(
"Preserved Rule" );
1696 numericData->SetConstraintCode(
"clearance" );
1697 numericData->SetNumericInputValue( 0.5 );
1701 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1713 entry.
originalRuleText =
"(rule \"EditedRule\"\n\t(constraint clearance (min 0.5mm)))";
1716 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1717 numericData->SetRuleName(
"EditedRule" );
1718 numericData->SetConstraintCode(
"clearance" );
1719 numericData->SetNumericInputValue( 0.3 );
1723 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1727 BOOST_CHECK( !
result.Contains(
"0.5mm" ) );
1728 BOOST_CHECK(
result.Contains(
"EditedRule" ) );
1738 auto viaData = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>();
1739 viaData->SetRuleName(
"ViaTest" );
1740 viaData->SetMinViaDiameter( 0.5 );
1741 viaData->SetMaxViaDiameter( 0.8 );
1742 viaData->SetMinViaHoleSize( 0.2 );
1743 viaData->SetMaxViaHoleSize( 0.4 );
1748 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1751 BOOST_CHECK(
result.Contains(
"ViaTest" ) );
1752 BOOST_CHECK(
result.Contains(
"via_diameter" ) );
1753 BOOST_CHECK(
result.Contains(
"hole_size" ) );
1759 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1764 auto data1 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1765 data1->SetRuleName(
"RuleA" );
1766 data1->SetConstraintCode(
"clearance" );
1767 data1->SetNumericInputValue( 0.2 );
1770 entries.push_back( entry1 );
1775 auto data2 = std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>();
1776 data2->SetRuleName(
"RuleB" );
1777 data2->SetOptWidth( 0.2 );
1778 data2->SetWidthTolerance( 0.1 );
1781 entries.push_back( entry2 );
1787 BOOST_CHECK(
result.Contains(
"RuleA" ) );
1788 BOOST_CHECK(
result.Contains(
"RuleB" ) );
1791 size_t posA =
result.Find(
"RuleA" );
1792 size_t posB =
result.Find(
"RuleB" );
1793 BOOST_CHECK( posA < posB );
1801 entry.
ruleName =
"ConditionalRule";
1802 entry.
condition =
"A.NetClass == 'Power'";
1804 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1805 numericData->SetRuleName(
"ConditionalRule" );
1806 numericData->SetConstraintCode(
"clearance" );
1807 numericData->SetRuleCondition(
"A.NetClass == 'Power'" );
1808 numericData->SetNumericInputValue( 0.3 );
1813 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1816 BOOST_CHECK(
result.Contains(
"ConditionalRule" ) );
1817 BOOST_CHECK(
result.Contains(
"condition" ) );
1818 BOOST_CHECK(
result.Contains(
"Power" ) );
1825 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1828 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1843 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1847 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1848 BOOST_CHECK( !
result.Contains(
"Null Data Rule" ) );
1854 wxString originalText =
1856 "(rule \"RoundTripTest\"\n"
1857 " (constraint clearance (min 0.25mm)))";
1860 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
1862 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1866 entries[0].wasEdited =
true;
1873 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
1875 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
1883 for(
const char*
name : {
"issue16182.kicad_dru",
"issue20480/issue20480.kicad_dru" } )
1889 wxFFile file(
path,
"r" );
1892 file.ReadAll( &content );
1895 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFile(
path );
1909 const wxString originalName = wxS(
"Annular width: LEDs" );
1916 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1917 numericData->SetRuleName( originalName );
1918 numericData->SetConstraintCode(
"annular_width" );
1919 numericData->SetNumericInputValue( 0.085 );
1923 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1927 BOOST_CHECK(
result.Contains( wxS(
"\"Annular width: LEDs\"" ) ) );
1928 BOOST_CHECK( !
result.Contains( wxS(
"Annular_width__LEDs" ) ) );
1934 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1944 entry.
ruleName = wxS(
"My_Bare_Rule-1.0" );
1947 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1948 numericData->SetRuleName( entry.
ruleName );
1949 numericData->SetConstraintCode(
"clearance" );
1950 numericData->SetNumericInputValue( 0.2 );
1954 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1957 BOOST_CHECK(
result.Contains( wxS(
"(rule My_Bare_Rule-1.0\n" ) ) );
1958 BOOST_CHECK( !
result.Contains( wxS(
"\"My_Bare_Rule-1.0\"" ) ) );
1971 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1972 numericData->SetRuleName( entry.
ruleName );
1973 numericData->SetConstraintCode(
"clearance" );
1974 numericData->SetNumericInputValue( 0.2 );
1978 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1981 BOOST_CHECK(
result.Contains( wxS(
"\"3.3\"" ) ) );
1985 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1997 auto dpData = std::make_shared<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>();
1998 dpData->SetRuleName(
"DiffPairTest" );
1999 dpData->SetOptWidth( 0.25 );
2000 dpData->SetWidthTolerance( 0.05 );
2001 dpData->SetOptGap( 0.15 );
2002 dpData->SetGapTolerance( 0.05 );
2003 dpData->SetMaxUncoupledLength( 5.0 );
2008 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2011 BOOST_CHECK(
result.Contains(
"DiffPairTest" ) );
2012 BOOST_CHECK(
result.Contains(
"track_width" ) );
2013 BOOST_CHECK(
result.Contains(
"diff_pair_gap" ) );
2026 "(rule \"PTH to Track Clearance\"\n"
2027 " (constraint hole_clearance (min 1.0mm))\n"
2028 " (condition \"A.Type == 'Pad' && A.Pad_Type == 'Through-hole' && B.Type =='Track'\"))\n"
2029 "(rule \"Max Drill Hole Size Mechanical\"\n"
2030 " (constraint hole (max 2.0mm))\n"
2031 " (condition \"A.Type == 'Pad'\"))";
2034 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2036 BOOST_REQUIRE_GE( entries.size(), 2 );
2041 BOOST_CHECK( !entries[0].condition.IsEmpty() );
2053 "(rule board_edge\n"
2054 " (constraint edge_clearance (min 1mm))\n"
2055 " (condition \"A.memberOf('board_edge')\")\n"
2056 " (severity ignore))";
2059 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2061 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2072 "(rule high_current_netclass\n"
2073 " (constraint connection_width (min 0.16mm))\n"
2074 " (condition \"A.NetClass == 'High_current'\"))\n"
2075 "(rule high_current_area\n"
2076 " (constraint connection_width (min 0.16mm))\n"
2077 " (condition \"A.insideArea('high_current')\"))";
2080 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2082 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
2089 BOOST_CHECK( !entries[0].condition.IsEmpty() );
2090 BOOST_CHECK( !entries[1].condition.IsEmpty() );
2097 wxString originalText =
2099 "(rule ClearanceRule\n"
2100 " (constraint clearance (min 0.2mm))\n"
2101 " (condition \"A.NetClass == 'Power'\"))\n"
2102 "(rule TrackWidthRule\n"
2103 " (constraint track_width (min 0.15mm) (opt 0.2mm) (max 0.3mm)))";
2106 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2108 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
2111 for(
auto& entry : entries )
2112 entry.wasEdited =
true;
2119 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2121 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 2 );
2135 wxString originalText =
2137 "(rule \"Via Style\"\n"
2138 " (constraint via_diameter (min 0.5mm) (opt 0.6mm) (max 0.8mm))\n"
2139 " (constraint hole_size (min 0.2mm) (opt 0.3mm) (max 0.4mm)))";
2142 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2144 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2147 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
2150 double originalMinDia = viaData->GetMinViaDiameter();
2151 double originalMinHole = viaData->GetMinViaHoleSize();
2154 entries[0].wasEdited =
true;
2159 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2161 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
2164 auto reloadedViaData =
2165 std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
2168 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaDiameter(), originalMinDia, 0.0001 );
2169 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaHoleSize(), originalMinHole, 0.0001 );
2177 "(rule \"Rule A\"\n"
2178 " (constraint clearance (min 0.2mm)))\n"
2179 "(rule \"Rule B\"\n"
2180 " (constraint via_diameter (min 0.5mm))\n"
2181 " (constraint hole_size (min 0.2mm))\n"
2182 " (constraint track_width (min 0.15mm)))\n"
2183 "(rule \"Rule C\"\n"
2184 " (constraint edge_clearance (min 0.3mm)))";
2187 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2190 BOOST_REQUIRE_GE( entries.size(), 4 );
2193 int ruleACount = 0, ruleBCount = 0, ruleCCount = 0;
2195 for(
const auto& entry : entries )
2197 if( entry.ruleName ==
"Rule A" )
2199 else if( entry.ruleName ==
"Rule B" )
2201 else if( entry.ruleName ==
"Rule C" )
2206 BOOST_CHECK_GE( ruleBCount, 2 );
2210 int lastAIndex = -1, firstBIndex = entries.size(), lastBIndex = -1, firstCIndex = entries.size();
2212 for(
size_t i = 0; i < entries.size(); i++ )
2214 if( entries[i].ruleName ==
"Rule A" )
2216 else if( entries[i].ruleName ==
"Rule B" )
2218 if( (
int)i < firstBIndex )
2223 else if( entries[i].ruleName ==
"Rule C" )
2225 if( (
int)i < firstCIndex )
2230 BOOST_CHECK( lastAIndex < firstBIndex );
2231 BOOST_CHECK( lastBIndex < firstCIndex );
2242 == KIND::ENCLOSED_BY_AREA );
2253 wxString expr =
"A.NetName == 'VCC'";
2256 BOOST_CHECK( !expr.IsEmpty() );
2257 BOOST_CHECK( expr.Contains(
"NetName" ) );
2258 BOOST_CHECK( expr.Contains(
"VCC" ) );
2264 wxString expr =
"A.NetName == 'VCC' && B.NetClass == 'Power'";
2267 BOOST_CHECK( expr.Contains(
"&&" ) );
2268 BOOST_CHECK( expr.Contains(
"NetName" ) );
2269 BOOST_CHECK( expr.Contains(
"NetClass" ) );
2275 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2278 BOOST_CHECK( expr.Contains(
"||" ) );
2279 BOOST_CHECK( expr.Contains(
"intersectsArea" ) );
2285 wxString expr =
"A.NetClass == 'Power' && !A.intersectsArea('NoRouting')";
2288 BOOST_CHECK( expr.Contains(
"&&" ) );
2289 BOOST_CHECK( expr.Contains(
"!" ) );
2295 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2298 BOOST_CHECK( expr.Contains(
"||" ) );
2299 BOOST_CHECK( expr.Contains(
"underFPGA" ) );
2300 BOOST_CHECK( expr.Contains(
"underDDR" ) );
2306 while( ( pos = expr.find(
"||", pos ) ) != wxString::npos )
2329 for(
KICAD_T type : excludedTypes )
2336 BOOST_CHECK(
true );
2340 BOOST_FAIL(
"Excluded type not handled in filter" );
2345 for(
KICAD_T type : includedTypes )
2352 BOOST_FAIL(
"Included type incorrectly matched by filter" );
2356 BOOST_CHECK(
true );
2369 entry.
condition =
"A.NetClass == 'Power'";
2373 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2374 data->SetRuleName(
"SilkMaskTest" );
2375 data->SetConstraintCode(
"silk_clearance" );
2376 data->SetRuleCondition(
"A.NetClass == 'Power'" );
2377 data->SetNumericInputValue( 0.15 );
2381 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2385 BOOST_CHECK(
result.Contains(
"L == 'F.Mask'" ) );
2386 BOOST_CHECK(
result.Contains(
"Power" ) );
2387 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2392 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2410 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2411 data->SetRuleName(
"SilkMaskSimple" );
2412 data->SetConstraintCode(
"silk_clearance" );
2413 data->SetNumericInputValue( 0.1 );
2417 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2420 BOOST_CHECK(
result.Contains(
"L == 'B.Mask'" ) );
2421 BOOST_CHECK(
result.Contains(
"(condition" ) );
2422 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2434 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2435 data->SetRuleName(
"SilkSilkBoth" );
2436 data->SetConstraintCode(
"silk_clearance" );
2437 data->SetNumericInputValue( 0.2 );
2441 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2444 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS' || L == 'B.SilkS'" ) );
2445 BOOST_CHECK(
result.Contains(
"(condition" ) );
2446 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2458 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2459 data->SetRuleName(
"SilkSilkFront" );
2460 data->SetConstraintCode(
"silk_clearance" );
2461 data->SetNumericInputValue( 0.2 );
2465 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2468 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2469 BOOST_CHECK( !
result.Contains(
"B.SilkS" ) );
2470 BOOST_CHECK(
result.Contains(
"(condition" ) );
2471 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2480 entry.
condition =
"A.NetClass == 'Signal'";
2484 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2485 data->SetRuleName(
"SilkSilkCond" );
2486 data->SetConstraintCode(
"silk_clearance" );
2487 data->SetRuleCondition(
"A.NetClass == 'Signal'" );
2488 data->SetNumericInputValue( 0.2 );
2492 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2495 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2496 BOOST_CHECK(
result.Contains(
"Signal" ) );
2501 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2514 BOOST_CHECK( result1.
isValid );
2515 BOOST_CHECK( result1.
errors.empty() );
2520 BOOST_CHECK( result2.
isValid );
2521 BOOST_CHECK( result2.
errors.empty() );
2529 BOOST_CHECK( !
result.isValid );
2530 BOOST_CHECK( !
result.errors.empty() );
2532 bool foundError =
false;
2533 for(
const auto& error :
result.errors )
2535 if( error.find(
"At least one via type must be selected" ) != std::string::npos )
2538 BOOST_CHECK( foundError );
2550 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2551 BOOST_CHECK( clauses[0].Contains(
"disallow via" ) );
2552 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2557 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2558 BOOST_CHECK( clauses[0].Contains(
"micro_via" ) );
2559 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2560 BOOST_CHECK( !clauses[0].Contains(
"blind_via" ) );
2561 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2566 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2567 BOOST_CHECK( clauses[0].Contains(
"through_via" ) );
2568 BOOST_CHECK( clauses[0].Contains(
"blind_via" ) );
2569 BOOST_CHECK( !clauses[0].Contains(
"micro_via" ) );
2570 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2575 BOOST_CHECK( clauses.empty() );
2581 wxString originalText =
"(version 1)\n"
2582 "(rule \"ViasUnderSmdTest\"\n"
2583 " (constraint disallow micro_via)\n"
2584 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2587 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2589 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2592 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2596 BOOST_CHECK( !viaData->GetDisallowThroughVias() );
2597 BOOST_CHECK( viaData->GetDisallowMicroVias() );
2598 BOOST_CHECK( !viaData->GetDisallowBlindVias() );
2599 BOOST_CHECK( !viaData->GetDisallowBuriedVias() );
2602 entries[0].wasEdited =
true;
2607 BOOST_CHECK( savedText.Contains(
"micro_via" ) );
2608 BOOST_CHECK( !savedText.Contains(
"through_via" ) );
2609 BOOST_CHECK( !savedText.Contains(
"blind_via" ) );
2610 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2613 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2614 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
2617 std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
2620 BOOST_CHECK( !reloadedData->GetDisallowThroughVias() );
2621 BOOST_CHECK( reloadedData->GetDisallowMicroVias() );
2622 BOOST_CHECK( !reloadedData->GetDisallowBlindVias() );
2623 BOOST_CHECK( !reloadedData->GetDisallowBuriedVias() );
2626 wxString blanketText =
"(version 1)\n"
2627 "(rule \"BlanketVia\"\n"
2628 " (constraint disallow via)\n"
2629 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2632 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2634 auto blanketData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2637 BOOST_CHECK( blanketData->GetDisallowThroughVias() );
2638 BOOST_CHECK( blanketData->GetDisallowMicroVias() );
2639 BOOST_CHECK( blanketData->GetDisallowBlindVias() );
2640 BOOST_CHECK( blanketData->GetDisallowBuriedVias() );
2643 wxString multiText =
"(version 1)\n"
2644 "(rule \"TwoVias\"\n"
2645 " (constraint disallow through_via blind_via)\n"
2646 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2649 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2651 auto multiData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2654 BOOST_CHECK( multiData->GetDisallowThroughVias() );
2655 BOOST_CHECK( !multiData->GetDisallowMicroVias() );
2656 BOOST_CHECK( multiData->GetDisallowBlindVias() );
2657 BOOST_CHECK( !multiData->GetDisallowBuriedVias() );
2659 entries[0].wasEdited =
true;
2662 BOOST_CHECK( savedText.Contains(
"through_via" ) );
2663 BOOST_CHECK( savedText.Contains(
"blind_via" ) );
2664 BOOST_CHECK( !savedText.Contains(
"micro_via" ) );
2665 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2671 wxString ruleText =
"(version 1)\n"
2672 "(rule \"Angled\"\n"
2673 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2677 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2679 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2682 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2684 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2685 BOOST_CHECK( !customData->GetRuleText().Contains( wxS(
"Angled" ) ) );
2688 wxString ruleTextUnquoted =
"(version 1)\n"
2690 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2695 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2698 auto customDataUnquoted =
2699 std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2701 BOOST_CHECK( customDataUnquoted->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2702 BOOST_CHECK( !customDataUnquoted->GetRuleText().Contains( wxS(
"Angled" ) ) );
2707 wxString ruleText =
"(version 1)\n"
2708 "(rule \"Standard\"\n"
2709 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg\")\n"
2713 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2715 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2719 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2721 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2722 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2723 BOOST_CHECK( !orientData->GetIsOneEightyDegreesAllowed() );
2724 BOOST_CHECK( !orientData->GetIsAllDegreesAllowed() );
2727 wxString singleLine =
"(version 1) (rule \"SingleLine\" (constraint assertion \"A.Orientation == 0 deg || "
2728 "A.Orientation == 90 deg\"))";
2732 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2735 auto singleLineData =
2736 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2738 BOOST_CHECK( singleLineData->GetIsZeroDegreesAllowed() );
2739 BOOST_CHECK( singleLineData->GetIsNinetyDegreesAllowed() );
2740 BOOST_CHECK( !singleLineData->GetIsOneEightyDegreesAllowed() );
2741 BOOST_CHECK( !singleLineData->GetIsAllDegreesAllowed() );
2746 wxString ruleText =
"(version 1)\n"
2747 "(rule \"AllAngles\"\n"
2748 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg || "
2749 "A.Orientation == 180 deg || A.Orientation == 270 deg\")\n"
2753 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2755 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2759 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2761 BOOST_CHECK( orientData->GetIsAllDegreesAllowed() );
2762 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2763 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2764 BOOST_CHECK( orientData->GetIsOneEightyDegreesAllowed() );
2765 BOOST_CHECK( orientData->GetIsTwoSeventyDegreesAllowed() );
2770 wxString ruleText =
"(version 1)\n"
2771 "(rule \"InnerLayers\"\n"
2772 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'In1.Cu'\")\n"
2776 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2778 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2781 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2783 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"In1.Cu" ) ) );
2788 wxString ruleText =
"(version 1)\n"
2789 "(rule \"StandardLayers\"\n"
2790 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'B.Cu'\")\n"
2794 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2796 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2799 auto layerData = std::dynamic_pointer_cast<DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA>( entries[0].constraintData );
2801 BOOST_CHECK( layerData->GetTopLayerEnabled() );
2802 BOOST_CHECK( layerData->GetBottomLayerEnabled() );
2813 board.
Add( vendorFp );
2817 board.
Add( otherFp );
2819 auto rule = std::make_shared<DRC_RULE>( wxT(
"Custom property" ) );
2820 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.customProperty('Vendor') == 'ACME'" ) );
2824 rule->AddConstraint( constraint );
2830 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2831 BOOST_CHECK( matches.front() == vendorFp );
2842 board.
Add( vendorFp );
2846 board.
Add( otherFp );
2848 auto rule = std::make_shared<DRC_RULE>( wxT(
"Has custom property" ) );
2849 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.hasCustomProperty('Vendor')" ) );
2853 rule->AddConstraint( constraint );
2859 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2860 BOOST_CHECK( matches.front() == vendorFp );
2867 wxString ruleText =
"(version 1)\n"
2868 "(rule \"clk_delay\"\n"
2869 " (constraint length (min 210ps) (max 230ps))\n"
2873 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2875 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2878 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2880 BOOST_CHECK( data->IsTimeDomain() );
2881 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 220.0, 0.0001 );
2882 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2898 BOOST_CHECK( ruleText.Contains( wxS(
"210ps" ) ) );
2899 BOOST_CHECK( ruleText.Contains( wxS(
"220ps" ) ) );
2900 BOOST_CHECK( ruleText.Contains( wxS(
"230ps" ) ) );
2903 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2905 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2907 auto parsed = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2909 BOOST_CHECK( parsed->IsTimeDomain() );
2910 BOOST_CHECK_CLOSE( parsed->GetOptimumLength(), 220.0, 0.0001 );
2911 BOOST_CHECK_CLOSE( parsed->GetTolerance(), 10.0, 0.0001 );
2918 wxString ruleText =
"(version 1)\n"
2919 "(rule \"len_window\"\n"
2920 " (constraint length (min 30mm) (max 50mm))\n"
2924 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2926 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2929 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2931 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 40.0, 0.0001 );
2932 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2935 ctx.
ruleName = entries[0].ruleName;
2938 wxString saved = data->GenerateRule( ctx );
2940 BOOST_CHECK( saved.Contains( wxS(
"30mm" ) ) );
2941 BOOST_CHECK( saved.Contains( wxS(
"40mm" ) ) );
2942 BOOST_CHECK( saved.Contains( wxS(
"50mm" ) ) );
2949 wxString ruleText =
"(rule \"length_DDR_Byte0\"\n"
2951 "\t# (constraint length (min 29.5mm) (max 30.5mm) (opt 30mm))\n"
2952 "(constraint length (min 210ps) (max 230ps) (opt 223ps))\n"
2953 "\t# tightened after bring-up\n"
2954 "\t(condition \"A.NetClass == 'DDR4_BYTE0'\"))";
2958 BOOST_CHECK( body.StartsWith( wxS(
"(constraint length (min 210ps)" ) ) );
2959 BOOST_CHECK( !body.Contains( wxS(
"29.5mm" ) ) );
2960 BOOST_CHECK( !body.Contains( wxS(
"byte lane" ) ) );
2961 BOOST_CHECK( !body.Contains( wxS(
"bring-up" ) ) );
2962 BOOST_CHECK( body.Contains( wxS(
"condition" ) ) );
2966 BOOST_CHECK( comment.Contains( wxS(
"byte lane 0" ) ) );
2967 BOOST_CHECK( comment.Contains( wxS(
"29.5mm" ) ) );
2968 BOOST_CHECK( comment.Contains( wxS(
"bring-up" ) ) );
2975 wxString ruleText =
"(version 1)\n"
2976 "(rule \"pair_ps\"\n"
2977 " (constraint length (min 10mm) (opt 11mm) (max 12mm))\n"
2978 " (constraint skew (max 5ps))\n"
2982 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2984 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2987 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2989 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"5ps" ) ) );
2995 wxString ruleText =
"(version 1)\n"
2996 "(rule \"len_mm\"\n"
2997 " (constraint length (min 30mm) (opt 40mm) (max 50mm))\n"
3001 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
3003 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()
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::optional< SELECTOR_CONDITION > ParseSelectorCondition(const wxString &aExpr)
Match a condition that a net, netclass or area selector can show.
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)