20#include <boost/test/unit_test.hpp>
65 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
66 auto parsed = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( parsedRules[0] );
71 BOOST_CHECK_CLOSE( parsed->GetMinViaDiameter(), original.
GetMinViaDiameter(), 0.0001 );
72 BOOST_CHECK_CLOSE( parsed->GetMaxViaDiameter(), original.
GetMaxViaDiameter(), 0.0001 );
73 BOOST_CHECK_CLOSE( parsed->GetMinViaHoleSize(), original.
GetMinViaHoleSize(), 0.0001 );
74 BOOST_CHECK_CLOSE( parsed->GetMaxViaHoleSize(), original.
GetMaxViaHoleSize(), 0.0001 );
84 board.
Add( footprint );
86 auto rule = std::make_shared<DRC_RULE>( wxT(
"String literal" ) );
91 rule->AddConstraint( constraint );
96 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
116 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
117 auto parsed = std::dynamic_pointer_cast<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( parsedRules[0] );
122 BOOST_CHECK_CLOSE( parsed->GetOptWidth(), original.
GetOptWidth(), 0.0001 );
123 BOOST_CHECK_CLOSE( parsed->GetWidthTolerance(), original.
GetWidthTolerance(), 0.0001 );
128 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
130 auto rule1 = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( 0, 0,
"ViaRule", 0.5, 0.8, 0.2, 0.4 );
131 rule1->SetConstraintCode(
"via_style" );
132 rule1->SetRuleCondition(
"A.NetClass == 'Power'" );
133 rules.push_back( rule1 );
135 auto rule2 = std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( 0, 0,
"TrackRule", 0.3, 0.1 );
136 rule2->SetConstraintCode(
"track_width" );
137 rule2->SetRuleCondition(
"A.NetClass == 'Signal'" );
138 rules.push_back( rule2 );
140 wxString filename =
"test_rules.dru";
146 wxFFile file( filename );
149 file.ReadAll( &content );
152 BOOST_CHECK( content.Contains(
"(version 2)" ) );
153 BOOST_CHECK( content.Contains(
"(rule ViaRule" ) );
154 BOOST_CHECK( content.Contains(
"(constraint via_diameter" ) );
155 BOOST_CHECK( content.Contains(
"(constraint hole_size" ) );
156 BOOST_CHECK( content.Contains(
"(rule TrackRule" ) );
157 BOOST_CHECK( content.Contains(
"(constraint track_width" ) );
160 wxRemoveFile( filename );
166 std::vector<RULE_TREE_NODE> ruleTreeNodeDatas;
174 auto data = std::make_shared<DRC_RE_BASE_CONSTRAINT_DATA>( 1, 0,
"TestRule" );
175 data->SetConstraintCode(
"clearance" );
178 ruleTreeNodeDatas.push_back( node );
181 std::vector<std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>> rules;
185 if( n.m_nodeType !=
RULE )
188 auto d = std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( n.m_nodeData );
191 rules.push_back( d );
199 auto rule = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 0.2,
"ClearanceRule" );
200 rule->SetConstraintCode(
"clearance" );
206 wxString ruleText = rule->GenerateRule( ctx );
208 BOOST_CHECK( ruleText.Contains(
"(constraint clearance (min 0.2mm))" ) );
211 auto rule2 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 10,
"ViaCountRule" );
212 rule2->SetConstraintCode(
"via_count" );
213 ctx.
ruleName = rule2->GetRuleName();
216 ruleText = rule2->GenerateRule( ctx );
217 BOOST_CHECK( ruleText.Contains(
"(constraint via_count (max 10))" ) );
220 auto rule3 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( 0, 0, 45,
"AngleRule" );
221 rule3->SetConstraintCode(
"track_angle" );
222 ctx.
ruleName = rule3->GetRuleName();
225 ruleText = rule3->GenerateRule( ctx );
226 BOOST_CHECK( ruleText.Contains(
"(constraint track_angle (min 45deg))" ) );
231 auto rule = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
true,
"DisallowTestRule" );
232 rule->SetConstraintCode(
"disallow" );
238 wxString ruleText = rule->GenerateRule( ctx );
240 BOOST_CHECK( ruleText.Contains(
"(constraint disallow)" ) );
243 auto rule2 = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( 0, 0,
false,
"NoDisallowTestRule" );
244 rule2->SetConstraintCode(
"disallow" );
245 ctx.
ruleName = rule2->GetRuleName();
248 ruleText = rule2->GenerateRule( ctx );
249 BOOST_CHECK( ruleText.IsEmpty() );
256 "(rule \"Clearance Rule\"\n"
257 "\t(constraint clearance (min 0.2mm))\n"
258 "\t(condition \"A.NetClass == 'Power'\"))\n"
259 "(rule \"Via Style Rule\"\n"
260 "\t(constraint via_diameter (min 0.5mm))\n"
261 "\t(constraint hole_size (min 0.3mm))\n"
262 "\t(condition \"A.NetClass == 'Power'\"))\n";
266 BOOST_REQUIRE_EQUAL( parsedRules.size(), 2 );
269 auto clearanceRule = parsedRules[0];
274 auto numericData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( clearanceRule );
276 BOOST_CHECK_CLOSE( numericData->GetNumericInputValue(), 0.2, 0.0001 );
279 auto viaStyleRule = parsedRules[1];
283 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( viaStyleRule );
285 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.5, 0.0001 );
286 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.3, 0.0001 );
292 bool parserCalled =
false;
294 [&](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA>
299 auto data = std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name );
300 data->SetConstraintCode(
"custom_clearance" );
306 wxString ruleText =
"(version 1) (rule \"Test Rule\" (constraint clearance (min 1.0mm)) (condition \"A.Type == 'Pad'\"))";
309 BOOST_CHECK( parserCalled );
310 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
320 BOOST_CHECK(
result.isValid );
321 BOOST_CHECK(
result.errors.empty() );
331 BOOST_CHECK( !
result.isValid );
332 BOOST_CHECK( !
result.errors.empty() );
335 bool foundMinMaxError =
false;
336 for(
const auto& error :
result.errors )
338 if( error.find(
"Minimum Via Diameter cannot be greater than Maximum Via Diameter" ) != std::string::npos )
339 foundMinMaxError =
true;
341 BOOST_CHECK( foundMinMaxError );
351 BOOST_CHECK( !
result.isValid );
352 BOOST_CHECK( !
result.errors.empty() );
355 bool foundNegativeError =
false;
356 for(
const auto& error :
result.errors )
358 if( error.find(
"must be greater than 0" ) != std::string::npos )
359 foundNegativeError =
true;
361 BOOST_CHECK( foundNegativeError );
368 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> {
369 if( aRule->m_Name ==
"Test" )
370 return std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name +
"_1" );
376 [](
const std::shared_ptr<DRC_RULE>& aRule ) -> std::shared_ptr<DRC_RE_BASE_CONSTRAINT_DATA> {
377 if( aRule->m_Name ==
"Test" )
378 return std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( 0, 0, aRule->m_Name +
"_2" );
382 wxString ruleText =
"(version 1) (rule \"Test\" (constraint clearance (min 1.0mm)))";
385 BOOST_REQUIRE_EQUAL( parsedRules.size(), 1 );
396 BOOST_CHECK(
result.isValid );
397 BOOST_CHECK(
result.errors.empty() );
407 BOOST_CHECK( !result1.
isValid );
408 BOOST_CHECK( !result1.
errors.empty() );
410 bool foundToleranceError =
false;
412 for(
const auto& error : result1.
errors )
414 if( error.find(
"Tolerance is too large" ) != std::string::npos )
415 foundToleranceError =
true;
418 BOOST_CHECK( foundToleranceError );
425 BOOST_CHECK( !result2.
isValid );
427 bool foundNegativeError =
false;
429 for(
const auto& error : result2.
errors )
431 if( error.find(
"Tolerance must be greater than or equal to 0" ) != std::string::npos )
432 foundNegativeError =
true;
435 BOOST_CHECK( foundNegativeError );
446 BOOST_CHECK(
result.isValid );
447 BOOST_CHECK(
result.errors.empty() );
457 BOOST_CHECK( !result1.
isValid );
458 BOOST_CHECK( !result1.
errors.empty() );
460 bool foundWidthError =
false;
461 for(
const auto& error : result1.
errors )
463 if( error.find(
"Width Tolerance must be less than Optimum Width" ) != std::string::npos )
464 foundWidthError =
true;
466 BOOST_CHECK( foundWidthError );
473 BOOST_CHECK( !result2.
isValid );
475 bool foundNegativeError =
false;
476 for(
const auto& error : result2.
errors )
478 if( error.find(
"must be greater than or equal to 0" ) != std::string::npos )
479 foundNegativeError =
true;
481 BOOST_CHECK( foundNegativeError );
491 BOOST_CHECK( result1.
isValid );
492 BOOST_CHECK( result1.
errors.empty() );
499 BOOST_CHECK( result2.
isValid );
500 BOOST_CHECK( result2.
errors.empty() );
507 BOOST_CHECK( result3.
isValid );
508 BOOST_CHECK( result3.
errors.empty() );
518 BOOST_CHECK( !
result.isValid );
519 BOOST_CHECK( !
result.errors.empty() );
521 bool foundLayerError =
false;
522 for(
const auto& error :
result.errors )
524 if( error.find(
"At least one layer must be selected" ) != std::string::npos )
525 foundLayerError =
true;
527 BOOST_CHECK( foundLayerError );
536 BOOST_CHECK(
result.isValid );
537 BOOST_CHECK(
result.errors.empty() );
546 BOOST_CHECK( !
result.isValid );
547 BOOST_CHECK( !
result.errors.empty() );
550 bool foundError =
false;
551 for(
const auto& error :
result.errors )
553 if( error.find(
"must be greater than 0" ) != std::string::npos )
556 BOOST_CHECK( foundError );
565 BOOST_CHECK(
result.isValid );
566 BOOST_CHECK(
result.errors.empty() );
576 BOOST_CHECK( !
result.isValid );
577 BOOST_CHECK( !
result.errors.empty() );
579 bool foundError =
false;
580 for(
const auto& error :
result.errors )
582 if( error.find(
"Width Tolerance must be less than Optimum Width" ) != std::string::npos )
585 BOOST_CHECK( foundError );
595 BOOST_CHECK( result1.
isValid );
596 BOOST_CHECK( result1.
errors.empty() );
603 BOOST_CHECK( result2.
isValid );
604 BOOST_CHECK( result2.
errors.empty() );
611 BOOST_CHECK( result3.
isValid );
612 BOOST_CHECK( result3.
errors.empty() );
619 BOOST_CHECK( result4.
isValid );
620 BOOST_CHECK( result4.
errors.empty() );
630 BOOST_CHECK( !
result.isValid );
631 BOOST_CHECK( !
result.errors.empty() );
633 bool foundOrientationError =
false;
634 for(
const auto& error :
result.errors )
636 if( error.find(
"At least one orientation must be selected" ) != std::string::npos )
637 foundOrientationError =
true;
639 BOOST_CHECK( foundOrientationError );
649 BOOST_CHECK( resultTrue.
isValid );
650 BOOST_CHECK( resultTrue.
errors.empty() );
657 BOOST_CHECK( resultFalse.
isValid );
658 BOOST_CHECK( resultFalse.
errors.empty() );
668 BOOST_CHECK(
result.isValid );
669 BOOST_CHECK(
result.errors.empty() );
679 BOOST_CHECK( !result1.
isValid );
680 BOOST_CHECK( !result1.
errors.empty() );
682 bool foundHeightError =
false;
683 for(
const auto& error : result1.
errors )
685 if( error.find(
"Minimum Text Height must be greater than 0" ) != std::string::npos )
686 foundHeightError =
true;
688 BOOST_CHECK( foundHeightError );
695 BOOST_CHECK( !result2.
isValid );
697 bool foundThicknessError =
false;
698 for(
const auto& error : result2.
errors )
700 if( error.find(
"Minimum Text Thickness must be greater than 0" ) != std::string::npos )
701 foundThicknessError =
true;
703 BOOST_CHECK( foundThicknessError );
710 BOOST_CHECK( !result3.
isValid );
717 data.
SetRuleText(
"(constraint clearance (min 0.2mm))" );
721 BOOST_CHECK(
result.isValid );
722 BOOST_CHECK(
result.errors.empty() );
732 BOOST_CHECK( !
result.isValid );
733 BOOST_CHECK( !
result.errors.empty() );
736 bool foundEmptyError =
false;
737 for(
const auto& error :
result.errors )
739 if( error.find(
"Rule text cannot be empty" ) != std::string::npos )
740 foundEmptyError =
true;
742 BOOST_CHECK( foundEmptyError );
768 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
770 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
780 DRC_RULE rule(
"ViaDiameterOnlyRule" );
787 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
789 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
813 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
815 BOOST_REQUIRE_EQUAL( matches.size(), 2 );
845 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
847 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
856 DRC_RULE rule(
"DiffPairWithUncoupledRule" );
871 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
873 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
884 DRC_RULE rule(
"TrackWidthOnlyRule" );
893 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
895 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
914 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
916 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
933 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
935 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
943 DRC_RULE rule(
"MatchedLengthRule" );
956 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
958 BOOST_REQUIRE_EQUAL( matches.size(), 1 );
961 BOOST_CHECK( matches[0].claimedConstraints.count(
SKEW_CONSTRAINT ) > 0 );
970 std::vector<DRC_PANEL_MATCH> matches = matcher.
MatchRule( rule );
1015 "(rule \"Via Test\"\n"
1016 " (constraint via_diameter (min 0.5mm) (opt 0.6mm) (max 0.8mm))\n"
1017 " (constraint hole_size (min 0.2mm) (opt 0.3mm) (max 0.4mm)))";
1020 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1022 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1026 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
1029 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.5, 0.0001 );
1030 BOOST_CHECK_CLOSE( viaData->GetMaxViaDiameter(), 0.8, 0.0001 );
1031 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.2, 0.0001 );
1032 BOOST_CHECK_CLOSE( viaData->GetMaxViaHoleSize(), 0.4, 0.0001 );
1040 "(rule \"Track Test\"\n"
1041 " (constraint track_width (min 0.2mm) (opt 0.25mm) (max 0.3mm)))";
1044 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1046 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1050 auto trackData = std::dynamic_pointer_cast<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( entries[0].constraintData );
1053 BOOST_CHECK_CLOSE( trackData->GetOptWidth(), 0.25, 0.0001 );
1054 BOOST_CHECK_CLOSE( trackData->GetWidthTolerance(), 0.05, 0.0001 );
1062 "(rule \"Diff Pair Test\"\n"
1063 " (constraint track_width (min 0.2mm) (opt 0.25mm) (max 0.3mm))\n"
1064 " (constraint diff_pair_gap (min 0.1mm) (opt 0.15mm) (max 0.2mm))\n"
1065 " (constraint diff_pair_uncoupled (max 5mm)))";
1068 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1070 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1073 auto dpData = std::dynamic_pointer_cast<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1076 BOOST_CHECK_CLOSE( dpData->GetOptWidth(), 0.25, 0.0001 );
1077 BOOST_CHECK_CLOSE( dpData->GetWidthTolerance(), 0.05, 0.0001 );
1078 BOOST_CHECK_CLOSE( dpData->GetOptGap(), 0.15, 0.0001 );
1079 BOOST_CHECK_CLOSE( dpData->GetGapTolerance(), 0.05, 0.0001 );
1080 BOOST_CHECK_CLOSE( dpData->GetMaxUncoupledLength(), 5.0, 0.0001 );
1088 "(rule \"Split Test\"\n"
1089 " (constraint via_diameter (min 0.5mm))\n"
1090 " (constraint hole_size (min 0.2mm))\n"
1091 " (constraint clearance (min 0.15mm)))";
1094 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1096 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1106 auto numericData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1108 BOOST_CHECK_CLOSE( numericData->GetNumericInputValue(), 0.15, 0.0001 );
1118 "(rule \"clearance_under_fpga\"\n"
1119 " (constraint clearance (min 0.1mm))\n"
1120 " (constraint hole_size (min 0.2mm))\n"
1121 " (constraint via_diameter (min 0.4mm))\n"
1122 " (condition \"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')\"))";
1125 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1128 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1133 BOOST_CHECK_EQUAL( entries[0].condition,
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')" );
1138 BOOST_CHECK_EQUAL( entries[1].condition,
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')" );
1141 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
1143 BOOST_CHECK_CLOSE( viaData->GetMinViaDiameter(), 0.4, 0.0001 );
1144 BOOST_CHECK_CLOSE( viaData->GetMinViaHoleSize(), 0.2, 0.0001 );
1147 auto clearanceData = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1149 BOOST_CHECK_CLOSE( clearanceData->GetNumericInputValue(), 0.1, 0.0001 );
1157 "(rule \"Text Test\"\n"
1158 " (constraint text_height (min 1mm))\n"
1159 " (constraint text_thickness (min 0.15mm)))";
1162 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1164 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1167 auto textData = std::dynamic_pointer_cast<DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA>( entries[0].constraintData );
1170 BOOST_CHECK_CLOSE( textData->GetMinTextHeight(), 1.0, 0.0001 );
1171 BOOST_CHECK_CLOSE( textData->GetMinTextThickness(), 0.15, 0.0001 );
1179 "(rule \"Length Test\"\n"
1180 " (constraint length (min 10mm) (opt 30mm) (max 50mm)))";
1183 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1185 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1189 auto lengthData = dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
1191 BOOST_CHECK_CLOSE( lengthData->GetMinimumLength(), 10.0, 0.0001 );
1192 BOOST_CHECK_CLOSE( lengthData->GetOptimumLength(), 30.0, 0.0001 );
1193 BOOST_CHECK_CLOSE( lengthData->GetMaximumLength(), 50.0, 0.0001 );
1201 "(rule \"DP Length Match\"\n"
1202 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1203 " (constraint skew (max 1mm)))";
1206 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1208 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1213 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1216 BOOST_CHECK_CLOSE( matchedData->GetMinimumLength(), 10.0, 0.0001 );
1217 BOOST_CHECK_CLOSE( matchedData->GetOptimumLength(), 30.0, 0.0001 );
1218 BOOST_CHECK_CLOSE( matchedData->GetMaximumLength(), 50.0, 0.0001 );
1219 BOOST_CHECK_CLOSE( matchedData->GetMaxSkew(), 1.0, 0.0001 );
1227 "(rule \"DP Match RT\"\n"
1228 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1229 " (constraint skew (max 2.5mm)))";
1232 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1234 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1235 entries[0].wasEdited =
true;
1240 BOOST_CHECK( savedText.Contains(
"length" ) );
1241 BOOST_CHECK( savedText.Contains(
"skew" ) );
1242 BOOST_CHECK( savedText.Contains(
"2.5mm" ) );
1244 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded = loader.
LoadFromString( savedText );
1246 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1250 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( reloaded[0].constraintData );
1253 BOOST_CHECK_CLOSE( reloadedData->GetMaxSkew(), 2.5, 0.0001 );
1254 BOOST_CHECK_CLOSE( reloadedData->GetMinimumLength(), 10.0, 0.0001 );
1255 BOOST_CHECK_CLOSE( reloadedData->GetOptimumLength(), 30.0, 0.0001 );
1256 BOOST_CHECK_CLOSE( reloadedData->GetMaximumLength(), 50.0, 0.0001 );
1262 wxString ruleText =
"(version 1)\n"
1263 "(rule \"DP Skew Within\"\n"
1264 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1265 " (constraint skew (max 1mm) (within_diff_pairs)))";
1268 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1270 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1274 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1277 BOOST_CHECK_CLOSE( matchedData->GetMaxSkew(), 1.0, 0.0001 );
1278 BOOST_CHECK( matchedData->GetWithinDiffPairs() );
1281 entries[0].wasEdited =
true;
1286 BOOST_CHECK( savedText.Contains(
"within_diff_pairs" ) );
1288 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded = loader.
LoadFromString( savedText );
1290 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1293 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( reloaded[0].constraintData );
1296 BOOST_CHECK_CLOSE( reloadedData->GetMaxSkew(), 1.0, 0.0001 );
1297 BOOST_CHECK( reloadedData->GetWithinDiffPairs() );
1303 wxString ruleText =
"(version 1)\n"
1304 "(rule \"DP Skew Bus\"\n"
1305 " (constraint length (min 10mm) (opt 30mm) (max 50mm))\n"
1306 " (constraint skew (max 2mm)))";
1309 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1311 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1314 std::dynamic_pointer_cast<DRC_RE_MATCHED_LENGTH_DIFF_PAIR_CONSTRAINT_DATA>( entries[0].constraintData );
1317 BOOST_CHECK( !matchedData->GetWithinDiffPairs() );
1320 entries[0].wasEdited =
true;
1325 BOOST_CHECK( !savedText.Contains(
"within_diff_pairs" ) );
1333 "(rule \"Conditional Test\"\n"
1334 " (condition \"A.NetClass == 'Power'\")\n"
1335 " (constraint clearance (min 0.3mm)))";
1338 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1340 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1343 BOOST_CHECK_EQUAL( entries[0].constraintData->GetRuleCondition(),
"A.NetClass == 'Power'" );
1351 "(rule \"Rule A\"\n"
1352 " (constraint clearance (min 0.2mm)))\n"
1353 "(rule \"Rule B\"\n"
1354 " (constraint track_width (min 0.15mm)))\n"
1355 "(rule \"Rule C\"\n"
1356 " (constraint via_diameter (min 0.5mm))\n"
1357 " (constraint hole_size (min 0.3mm)))";
1360 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1362 BOOST_REQUIRE_EQUAL( entries.size(), 3 );
1379 "(rule \"Empty Rule\")";
1382 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1384 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1392 wxString ruleText =
"not valid rule text at all";
1395 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1405 "(rule \"Edge Clearance\"\n"
1406 " (constraint edge_clearance (min 0.5mm)))\n"
1407 "(rule \"Hole Clearance\"\n"
1408 " (constraint hole_clearance (min 0.3mm)))\n"
1409 "(rule \"Courtyard\"\n"
1410 " (constraint courtyard_clearance (min 0.25mm)))";
1413 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1415 BOOST_REQUIRE_EQUAL( entries.size(), 3 );
1427 wxString ruleText =
"(version 1)\n"
1429 " (constraint microvia_aspect_ratio (max 1.0)))\n"
1431 " (constraint microvia_stack_depth (max 3)))";
1434 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1436 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1440 auto ratio = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[0].constraintData );
1441 auto depth = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( entries[1].constraintData );
1445 BOOST_CHECK_CLOSE( ratio->GetNumericInputValue(), 1.0, 0.0001 );
1446 BOOST_CHECK_CLOSE( depth->GetNumericInputValue(), 3.0, 0.0001 );
1448 entries[0].wasEdited =
true;
1449 entries[1].wasEdited =
true;
1452 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloaded =
1455 BOOST_REQUIRE_EQUAL( reloaded.size(), 2 );
1457 auto ratioAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[0].constraintData );
1458 auto depthAgain = std::dynamic_pointer_cast<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( reloaded[1].constraintData );
1462 BOOST_CHECK_CLOSE( ratioAgain->GetNumericInputValue(), 1.0, 0.0001 );
1463 BOOST_CHECK_CLOSE( depthAgain->GetNumericInputValue(), 3.0, 0.0001 );
1479 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1480 numericData->SetRuleName(
"TestClearance" );
1481 numericData->SetConstraintCode(
"clearance" );
1482 numericData->SetNumericInputValue( 0.2 );
1486 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1489 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1490 BOOST_CHECK(
result.Contains(
"TestClearance" ) );
1491 BOOST_CHECK(
result.Contains(
"clearance" ) );
1500 entry.
originalRuleText =
"(rule \"Preserved Rule\"\n\t(constraint clearance (min 0.5mm)))";
1503 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1504 numericData->SetRuleName(
"Preserved Rule" );
1505 numericData->SetConstraintCode(
"clearance" );
1506 numericData->SetNumericInputValue( 0.5 );
1510 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1522 entry.
originalRuleText =
"(rule \"EditedRule\"\n\t(constraint clearance (min 0.5mm)))";
1525 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1526 numericData->SetRuleName(
"EditedRule" );
1527 numericData->SetConstraintCode(
"clearance" );
1528 numericData->SetNumericInputValue( 0.3 );
1532 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1536 BOOST_CHECK( !
result.Contains(
"0.5mm" ) );
1537 BOOST_CHECK(
result.Contains(
"EditedRule" ) );
1547 auto viaData = std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>();
1548 viaData->SetRuleName(
"ViaTest" );
1549 viaData->SetMinViaDiameter( 0.5 );
1550 viaData->SetMaxViaDiameter( 0.8 );
1551 viaData->SetMinViaHoleSize( 0.2 );
1552 viaData->SetMaxViaHoleSize( 0.4 );
1557 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1560 BOOST_CHECK(
result.Contains(
"ViaTest" ) );
1561 BOOST_CHECK(
result.Contains(
"via_diameter" ) );
1562 BOOST_CHECK(
result.Contains(
"hole_size" ) );
1568 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1573 auto data1 = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1574 data1->SetRuleName(
"RuleA" );
1575 data1->SetConstraintCode(
"clearance" );
1576 data1->SetNumericInputValue( 0.2 );
1579 entries.push_back( entry1 );
1584 auto data2 = std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>();
1585 data2->SetRuleName(
"RuleB" );
1586 data2->SetOptWidth( 0.2 );
1587 data2->SetWidthTolerance( 0.1 );
1590 entries.push_back( entry2 );
1596 BOOST_CHECK(
result.Contains(
"RuleA" ) );
1597 BOOST_CHECK(
result.Contains(
"RuleB" ) );
1600 size_t posA =
result.Find(
"RuleA" );
1601 size_t posB =
result.Find(
"RuleB" );
1602 BOOST_CHECK( posA < posB );
1610 entry.
ruleName =
"ConditionalRule";
1611 entry.
condition =
"A.NetClass == 'Power'";
1613 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1614 numericData->SetRuleName(
"ConditionalRule" );
1615 numericData->SetConstraintCode(
"clearance" );
1616 numericData->SetRuleCondition(
"A.NetClass == 'Power'" );
1617 numericData->SetNumericInputValue( 0.3 );
1622 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1625 BOOST_CHECK(
result.Contains(
"ConditionalRule" ) );
1626 BOOST_CHECK(
result.Contains(
"condition" ) );
1627 BOOST_CHECK(
result.Contains(
"Power" ) );
1634 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1637 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1652 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1656 BOOST_CHECK(
result.Contains(
"(version 2)" ) );
1657 BOOST_CHECK( !
result.Contains(
"Null Data Rule" ) );
1663 wxString originalText =
1665 "(rule \"RoundTripTest\"\n"
1666 " (constraint clearance (min 0.25mm)))";
1669 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
1671 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1675 entries[0].wasEdited =
true;
1682 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
1684 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
1694 const wxString originalName = wxS(
"Annular width: LEDs" );
1701 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1702 numericData->SetRuleName( originalName );
1703 numericData->SetConstraintCode(
"annular_width" );
1704 numericData->SetNumericInputValue( 0.085 );
1708 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1712 BOOST_CHECK(
result.Contains( wxS(
"\"Annular width: LEDs\"" ) ) );
1713 BOOST_CHECK( !
result.Contains( wxS(
"Annular_width__LEDs" ) ) );
1719 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1729 entry.
ruleName = wxS(
"My_Bare_Rule-1.0" );
1732 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1733 numericData->SetRuleName( entry.
ruleName );
1734 numericData->SetConstraintCode(
"clearance" );
1735 numericData->SetNumericInputValue( 0.2 );
1739 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1742 BOOST_CHECK(
result.Contains( wxS(
"(rule My_Bare_Rule-1.0\n" ) ) );
1743 BOOST_CHECK( !
result.Contains( wxS(
"\"My_Bare_Rule-1.0\"" ) ) );
1753 entry.
ruleName = wxS(
"3.3V_Power" );
1756 auto numericData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>();
1757 numericData->SetRuleName( entry.
ruleName );
1758 numericData->SetConstraintCode(
"clearance" );
1759 numericData->SetNumericInputValue( 0.2 );
1763 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1766 BOOST_CHECK(
result.Contains( wxS(
"\"3.3V_Power\"" ) ) );
1770 BOOST_REQUIRE_EQUAL( reloaded.size(), 1 );
1782 auto dpData = std::make_shared<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>();
1783 dpData->SetRuleName(
"DiffPairTest" );
1784 dpData->SetOptWidth( 0.25 );
1785 dpData->SetWidthTolerance( 0.05 );
1786 dpData->SetOptGap( 0.15 );
1787 dpData->SetGapTolerance( 0.05 );
1788 dpData->SetMaxUncoupledLength( 5.0 );
1793 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
1796 BOOST_CHECK(
result.Contains(
"DiffPairTest" ) );
1797 BOOST_CHECK(
result.Contains(
"track_width" ) );
1798 BOOST_CHECK(
result.Contains(
"diff_pair_gap" ) );
1811 "(rule \"PTH to Track Clearance\"\n"
1812 " (constraint hole_clearance (min 1.0mm))\n"
1813 " (condition \"A.Type == 'Pad' && A.Pad_Type == 'Through-hole' && B.Type =='Track'\"))\n"
1814 "(rule \"Max Drill Hole Size Mechanical\"\n"
1815 " (constraint hole (max 2.0mm))\n"
1816 " (condition \"A.Type == 'Pad'\"))";
1819 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1821 BOOST_REQUIRE_GE( entries.size(), 2 );
1826 BOOST_CHECK( !entries[0].condition.IsEmpty() );
1838 "(rule board_edge\n"
1839 " (constraint edge_clearance (min 1mm))\n"
1840 " (condition \"A.memberOf('board_edge')\")\n"
1841 " (severity ignore))";
1844 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1846 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1857 "(rule high_current_netclass\n"
1858 " (constraint connection_width (min 0.16mm))\n"
1859 " (condition \"A.NetClass == 'High_current'\"))\n"
1860 "(rule high_current_area\n"
1861 " (constraint connection_width (min 0.16mm))\n"
1862 " (condition \"A.insideArea('high_current')\"))";
1865 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1867 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1874 BOOST_CHECK( !entries[0].condition.IsEmpty() );
1875 BOOST_CHECK( !entries[1].condition.IsEmpty() );
1882 wxString originalText =
1884 "(rule ClearanceRule\n"
1885 " (constraint clearance (min 0.2mm))\n"
1886 " (condition \"A.NetClass == 'Power'\"))\n"
1887 "(rule TrackWidthRule\n"
1888 " (constraint track_width (min 0.15mm) (opt 0.2mm) (max 0.3mm)))";
1891 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
1893 BOOST_REQUIRE_EQUAL( entries.size(), 2 );
1896 for(
auto& entry : entries )
1897 entry.wasEdited =
true;
1904 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
1906 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 2 );
1920 wxString originalText =
1922 "(rule \"Via Style\"\n"
1923 " (constraint via_diameter (min 0.5mm) (opt 0.6mm) (max 0.8mm))\n"
1924 " (constraint hole_size (min 0.2mm) (opt 0.3mm) (max 0.4mm)))";
1927 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
1929 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
1932 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( entries[0].constraintData );
1935 double originalMinDia = viaData->GetMinViaDiameter();
1936 double originalMinHole = viaData->GetMinViaHoleSize();
1939 entries[0].wasEdited =
true;
1944 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
1946 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
1949 auto reloadedViaData =
1950 std::dynamic_pointer_cast<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
1953 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaDiameter(), originalMinDia, 0.0001 );
1954 BOOST_CHECK_CLOSE( reloadedViaData->GetMinViaHoleSize(), originalMinHole, 0.0001 );
1962 "(rule \"Rule A\"\n"
1963 " (constraint clearance (min 0.2mm)))\n"
1964 "(rule \"Rule B\"\n"
1965 " (constraint via_diameter (min 0.5mm))\n"
1966 " (constraint hole_size (min 0.2mm))\n"
1967 " (constraint track_width (min 0.15mm)))\n"
1968 "(rule \"Rule C\"\n"
1969 " (constraint edge_clearance (min 0.3mm)))";
1972 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
1975 BOOST_REQUIRE_GE( entries.size(), 4 );
1978 int ruleACount = 0, ruleBCount = 0, ruleCCount = 0;
1980 for(
const auto& entry : entries )
1982 if( entry.ruleName ==
"Rule A" )
1984 else if( entry.ruleName ==
"Rule B" )
1986 else if( entry.ruleName ==
"Rule C" )
1991 BOOST_CHECK_GE( ruleBCount, 2 );
1995 int lastAIndex = -1, firstBIndex = entries.size(), lastBIndex = -1, firstCIndex = entries.size();
1997 for(
size_t i = 0; i < entries.size(); i++ )
1999 if( entries[i].ruleName ==
"Rule A" )
2001 else if( entries[i].ruleName ==
"Rule B" )
2003 if( (
int)i < firstBIndex )
2008 else if( entries[i].ruleName ==
"Rule C" )
2010 if( (
int)i < firstCIndex )
2015 BOOST_CHECK( lastAIndex < firstBIndex );
2016 BOOST_CHECK( lastBIndex < firstCIndex );
2028 wxString expr =
"A.NetName == 'VCC'";
2031 BOOST_CHECK( !expr.IsEmpty() );
2032 BOOST_CHECK( expr.Contains(
"NetName" ) );
2033 BOOST_CHECK( expr.Contains(
"VCC" ) );
2039 wxString expr =
"A.NetName == 'VCC' && B.NetClass == 'Power'";
2042 BOOST_CHECK( expr.Contains(
"&&" ) );
2043 BOOST_CHECK( expr.Contains(
"NetName" ) );
2044 BOOST_CHECK( expr.Contains(
"NetClass" ) );
2050 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2053 BOOST_CHECK( expr.Contains(
"||" ) );
2054 BOOST_CHECK( expr.Contains(
"intersectsArea" ) );
2060 wxString expr =
"A.NetClass == 'Power' && !A.intersectsArea('NoRouting')";
2063 BOOST_CHECK( expr.Contains(
"&&" ) );
2064 BOOST_CHECK( expr.Contains(
"!" ) );
2070 wxString expr =
"A.intersectsArea('underFPGA') || A.intersectsArea('underDDR')";
2073 BOOST_CHECK( expr.Contains(
"||" ) );
2074 BOOST_CHECK( expr.Contains(
"underFPGA" ) );
2075 BOOST_CHECK( expr.Contains(
"underDDR" ) );
2081 while( ( pos = expr.find(
"||", pos ) ) != wxString::npos )
2104 for(
KICAD_T type : excludedTypes )
2111 BOOST_CHECK(
true );
2115 BOOST_FAIL(
"Excluded type not handled in filter" );
2120 for(
KICAD_T type : includedTypes )
2127 BOOST_FAIL(
"Included type incorrectly matched by filter" );
2131 BOOST_CHECK(
true );
2144 entry.
condition =
"A.NetClass == 'Power'";
2148 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2149 data->SetRuleName(
"SilkMaskTest" );
2150 data->SetConstraintCode(
"silk_clearance" );
2151 data->SetRuleCondition(
"A.NetClass == 'Power'" );
2152 data->SetNumericInputValue( 0.15 );
2156 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2160 BOOST_CHECK(
result.Contains(
"L == 'F.Mask'" ) );
2161 BOOST_CHECK(
result.Contains(
"Power" ) );
2162 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2167 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2185 auto data = std::make_shared<DRC_RE_SILK_TO_SOLDERMASK_CLEARANCE_CONSTRAINT_DATA>();
2186 data->SetRuleName(
"SilkMaskSimple" );
2187 data->SetConstraintCode(
"silk_clearance" );
2188 data->SetNumericInputValue( 0.1 );
2192 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2195 BOOST_CHECK(
result.Contains(
"L == 'B.Mask'" ) );
2196 BOOST_CHECK(
result.Contains(
"(condition" ) );
2197 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2209 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2210 data->SetRuleName(
"SilkSilkBoth" );
2211 data->SetConstraintCode(
"silk_clearance" );
2212 data->SetNumericInputValue( 0.2 );
2216 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2219 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS' || L == 'B.SilkS'" ) );
2220 BOOST_CHECK(
result.Contains(
"(condition" ) );
2221 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2233 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2234 data->SetRuleName(
"SilkSilkFront" );
2235 data->SetConstraintCode(
"silk_clearance" );
2236 data->SetNumericInputValue( 0.2 );
2240 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2243 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2244 BOOST_CHECK( !
result.Contains(
"B.SilkS" ) );
2245 BOOST_CHECK(
result.Contains(
"(condition" ) );
2246 BOOST_CHECK( !
result.Contains(
"(layer" ) );
2255 entry.
condition =
"A.NetClass == 'Signal'";
2259 auto data = std::make_shared<DRC_RE_SILK_TO_SILK_CLEARANCE_CONSTRAINT_DATA>();
2260 data->SetRuleName(
"SilkSilkCond" );
2261 data->SetConstraintCode(
"silk_clearance" );
2262 data->SetRuleCondition(
"A.NetClass == 'Signal'" );
2263 data->SetNumericInputValue( 0.2 );
2267 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = { entry };
2270 BOOST_CHECK(
result.Contains(
"L == 'F.SilkS'" ) );
2271 BOOST_CHECK(
result.Contains(
"Signal" ) );
2276 while( ( pos =
result.find(
"(condition", pos ) ) != wxString::npos )
2289 BOOST_CHECK( result1.
isValid );
2290 BOOST_CHECK( result1.
errors.empty() );
2295 BOOST_CHECK( result2.
isValid );
2296 BOOST_CHECK( result2.
errors.empty() );
2304 BOOST_CHECK( !
result.isValid );
2305 BOOST_CHECK( !
result.errors.empty() );
2307 bool foundError =
false;
2308 for(
const auto& error :
result.errors )
2310 if( error.find(
"At least one via type must be selected" ) != std::string::npos )
2313 BOOST_CHECK( foundError );
2325 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2326 BOOST_CHECK( clauses[0].Contains(
"disallow via" ) );
2327 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2332 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2333 BOOST_CHECK( clauses[0].Contains(
"micro_via" ) );
2334 BOOST_CHECK( !clauses[0].Contains(
"through_via" ) );
2335 BOOST_CHECK( !clauses[0].Contains(
"blind_via" ) );
2336 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2341 BOOST_REQUIRE_EQUAL( clauses.size(), 1 );
2342 BOOST_CHECK( clauses[0].Contains(
"through_via" ) );
2343 BOOST_CHECK( clauses[0].Contains(
"blind_via" ) );
2344 BOOST_CHECK( !clauses[0].Contains(
"micro_via" ) );
2345 BOOST_CHECK( !clauses[0].Contains(
"buried_via" ) );
2350 BOOST_CHECK( clauses.empty() );
2356 wxString originalText =
"(version 1)\n"
2357 "(rule \"ViasUnderSmdTest\"\n"
2358 " (constraint disallow micro_via)\n"
2359 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2362 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( originalText );
2364 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2367 auto viaData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2371 BOOST_CHECK( !viaData->GetDisallowThroughVias() );
2372 BOOST_CHECK( viaData->GetDisallowMicroVias() );
2373 BOOST_CHECK( !viaData->GetDisallowBlindVias() );
2374 BOOST_CHECK( !viaData->GetDisallowBuriedVias() );
2377 entries[0].wasEdited =
true;
2382 BOOST_CHECK( savedText.Contains(
"micro_via" ) );
2383 BOOST_CHECK( !savedText.Contains(
"through_via" ) );
2384 BOOST_CHECK( !savedText.Contains(
"blind_via" ) );
2385 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2388 std::vector<DRC_RE_LOADED_PANEL_ENTRY> reloadedEntries = loader.
LoadFromString( savedText );
2389 BOOST_REQUIRE_EQUAL( reloadedEntries.size(), 1 );
2392 std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( reloadedEntries[0].constraintData );
2395 BOOST_CHECK( !reloadedData->GetDisallowThroughVias() );
2396 BOOST_CHECK( reloadedData->GetDisallowMicroVias() );
2397 BOOST_CHECK( !reloadedData->GetDisallowBlindVias() );
2398 BOOST_CHECK( !reloadedData->GetDisallowBuriedVias() );
2401 wxString blanketText =
"(version 1)\n"
2402 "(rule \"BlanketVia\"\n"
2403 " (constraint disallow via)\n"
2404 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2407 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2409 auto blanketData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2412 BOOST_CHECK( blanketData->GetDisallowThroughVias() );
2413 BOOST_CHECK( blanketData->GetDisallowMicroVias() );
2414 BOOST_CHECK( blanketData->GetDisallowBlindVias() );
2415 BOOST_CHECK( blanketData->GetDisallowBuriedVias() );
2418 wxString multiText =
"(version 1)\n"
2419 "(rule \"TwoVias\"\n"
2420 " (constraint disallow through_via blind_via)\n"
2421 " (condition \"A.Pad_Type == 'SMD' && A.insideArea('BGA*')\"))";
2424 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2426 auto multiData = std::dynamic_pointer_cast<DRC_RE_VIAS_UNDER_SMD_CONSTRAINT_DATA>( entries[0].constraintData );
2429 BOOST_CHECK( multiData->GetDisallowThroughVias() );
2430 BOOST_CHECK( !multiData->GetDisallowMicroVias() );
2431 BOOST_CHECK( multiData->GetDisallowBlindVias() );
2432 BOOST_CHECK( !multiData->GetDisallowBuriedVias() );
2434 entries[0].wasEdited =
true;
2437 BOOST_CHECK( savedText.Contains(
"through_via" ) );
2438 BOOST_CHECK( savedText.Contains(
"blind_via" ) );
2439 BOOST_CHECK( !savedText.Contains(
"micro_via" ) );
2440 BOOST_CHECK( !savedText.Contains(
"buried_via" ) );
2446 wxString ruleText =
"(version 1)\n"
2447 "(rule \"Angled\"\n"
2448 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2452 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2454 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2457 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2459 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2460 BOOST_CHECK( !customData->GetRuleText().Contains( wxS(
"Angled" ) ) );
2463 wxString ruleTextUnquoted =
"(version 1)\n"
2465 " (constraint assertion \"A.Orientation == 46 deg\")\n"
2470 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2473 auto customDataUnquoted =
2474 std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2476 BOOST_CHECK( customDataUnquoted->GetRuleText().Contains( wxS(
"46 deg" ) ) );
2477 BOOST_CHECK( !customDataUnquoted->GetRuleText().Contains( wxS(
"Angled" ) ) );
2482 wxString ruleText =
"(version 1)\n"
2483 "(rule \"Standard\"\n"
2484 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg\")\n"
2488 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2490 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2494 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2496 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2497 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2498 BOOST_CHECK( !orientData->GetIsOneEightyDegreesAllowed() );
2499 BOOST_CHECK( !orientData->GetIsAllDegreesAllowed() );
2502 wxString singleLine =
"(version 1) (rule \"SingleLine\" (constraint assertion \"A.Orientation == 0 deg || "
2503 "A.Orientation == 90 deg\"))";
2507 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2510 auto singleLineData =
2511 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2513 BOOST_CHECK( singleLineData->GetIsZeroDegreesAllowed() );
2514 BOOST_CHECK( singleLineData->GetIsNinetyDegreesAllowed() );
2515 BOOST_CHECK( !singleLineData->GetIsOneEightyDegreesAllowed() );
2516 BOOST_CHECK( !singleLineData->GetIsAllDegreesAllowed() );
2521 wxString ruleText =
"(version 1)\n"
2522 "(rule \"AllAngles\"\n"
2523 " (constraint assertion \"A.Orientation == 0 deg || A.Orientation == 90 deg || "
2524 "A.Orientation == 180 deg || A.Orientation == 270 deg\")\n"
2528 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2530 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2534 std::dynamic_pointer_cast<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( entries[0].constraintData );
2536 BOOST_CHECK( orientData->GetIsAllDegreesAllowed() );
2537 BOOST_CHECK( orientData->GetIsZeroDegreesAllowed() );
2538 BOOST_CHECK( orientData->GetIsNinetyDegreesAllowed() );
2539 BOOST_CHECK( orientData->GetIsOneEightyDegreesAllowed() );
2540 BOOST_CHECK( orientData->GetIsTwoSeventyDegreesAllowed() );
2545 wxString ruleText =
"(version 1)\n"
2546 "(rule \"InnerLayers\"\n"
2547 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'In1.Cu'\")\n"
2551 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2553 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2556 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2558 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"In1.Cu" ) ) );
2563 wxString ruleText =
"(version 1)\n"
2564 "(rule \"StandardLayers\"\n"
2565 " (constraint assertion \"A.Layer == 'F.Cu' || A.Layer == 'B.Cu'\")\n"
2569 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2571 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2574 auto layerData = std::dynamic_pointer_cast<DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA>( entries[0].constraintData );
2576 BOOST_CHECK( layerData->GetTopLayerEnabled() );
2577 BOOST_CHECK( layerData->GetBottomLayerEnabled() );
2588 board.
Add( vendorFp );
2592 board.
Add( otherFp );
2594 auto rule = std::make_shared<DRC_RULE>( wxT(
"Custom property" ) );
2595 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.customProperty('Vendor') == 'ACME'" ) );
2599 rule->AddConstraint( constraint );
2605 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2606 BOOST_CHECK( matches.front() == vendorFp );
2617 board.
Add( vendorFp );
2621 board.
Add( otherFp );
2623 auto rule = std::make_shared<DRC_RULE>( wxT(
"Has custom property" ) );
2624 rule->m_Condition =
new DRC_RULE_CONDITION( wxT(
"A.hasCustomProperty('Vendor')" ) );
2628 rule->AddConstraint( constraint );
2634 BOOST_REQUIRE_EQUAL( matches.size(), 1u );
2635 BOOST_CHECK( matches.front() == vendorFp );
2642 wxString ruleText =
"(version 1)\n"
2643 "(rule \"clk_delay\"\n"
2644 " (constraint length (min 210ps) (max 230ps))\n"
2648 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2650 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2653 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2655 BOOST_CHECK( data->IsTimeDomain() );
2656 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 220.0, 0.0001 );
2657 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2673 BOOST_CHECK( ruleText.Contains( wxS(
"210ps" ) ) );
2674 BOOST_CHECK( ruleText.Contains( wxS(
"220ps" ) ) );
2675 BOOST_CHECK( ruleText.Contains( wxS(
"230ps" ) ) );
2678 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2680 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2682 auto parsed = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2684 BOOST_CHECK( parsed->IsTimeDomain() );
2685 BOOST_CHECK_CLOSE( parsed->GetOptimumLength(), 220.0, 0.0001 );
2686 BOOST_CHECK_CLOSE( parsed->GetTolerance(), 10.0, 0.0001 );
2693 wxString ruleText =
"(version 1)\n"
2694 "(rule \"len_window\"\n"
2695 " (constraint length (min 30mm) (max 50mm))\n"
2699 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2701 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2704 auto data = std::dynamic_pointer_cast<DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA>( entries[0].constraintData );
2706 BOOST_CHECK_CLOSE( data->GetOptimumLength(), 40.0, 0.0001 );
2707 BOOST_CHECK_CLOSE( data->GetTolerance(), 10.0, 0.0001 );
2710 ctx.
ruleName = entries[0].ruleName;
2713 wxString saved = data->GenerateRule( ctx );
2715 BOOST_CHECK( saved.Contains( wxS(
"30mm" ) ) );
2716 BOOST_CHECK( saved.Contains( wxS(
"40mm" ) ) );
2717 BOOST_CHECK( saved.Contains( wxS(
"50mm" ) ) );
2724 wxString ruleText =
"(rule \"length_DDR_Byte0\"\n"
2726 "\t# (constraint length (min 29.5mm) (max 30.5mm) (opt 30mm))\n"
2727 "(constraint length (min 210ps) (max 230ps) (opt 223ps))\n"
2728 "\t# tightened after bring-up\n"
2729 "\t(condition \"A.NetClass == 'DDR4_BYTE0'\"))";
2733 BOOST_CHECK( body.StartsWith( wxS(
"(constraint length (min 210ps)" ) ) );
2734 BOOST_CHECK( !body.Contains( wxS(
"29.5mm" ) ) );
2735 BOOST_CHECK( !body.Contains( wxS(
"byte lane" ) ) );
2736 BOOST_CHECK( !body.Contains( wxS(
"bring-up" ) ) );
2737 BOOST_CHECK( body.Contains( wxS(
"condition" ) ) );
2741 BOOST_CHECK( comment.Contains( wxS(
"byte lane 0" ) ) );
2742 BOOST_CHECK( comment.Contains( wxS(
"29.5mm" ) ) );
2743 BOOST_CHECK( comment.Contains( wxS(
"bring-up" ) ) );
2750 wxString ruleText =
"(version 1)\n"
2751 "(rule \"pair_ps\"\n"
2752 " (constraint length (min 10mm) (opt 11mm) (max 12mm))\n"
2753 " (constraint skew (max 5ps))\n"
2757 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2759 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
2762 auto customData = std::dynamic_pointer_cast<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( entries[0].constraintData );
2764 BOOST_CHECK( customData->GetRuleText().Contains( wxS(
"5ps" ) ) );
2770 wxString ruleText =
"(version 1)\n"
2771 "(rule \"len_mm\"\n"
2772 " (constraint length (min 30mm) (opt 40mm) (max 50mm))\n"
2776 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFromString( ruleText );
2778 BOOST_REQUIRE_EQUAL( entries.size(), 1 );
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
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.
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.
Saves DRC panel entries back to .kicad_dru files.
wxString GenerateRulesText(const std::vector< DRC_RE_LOADED_PANEL_ENTRY > &aEntries, const BOARD *aBoard=nullptr)
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.
wxString GetRuleName()
Get the name of the rule.
@ 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
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()
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)