25#include <wx/filename.h>
35 if( !wxGetEnv( wxT(
"KICAD_DRC_BENCH_CORPUS" ), &root ) || root.IsEmpty() )
38 return wxFileName::DirExists( root );
46 if( !wxGetEnv( wxT(
"KICAD_DRC_BENCH_CORPUS" ), &root ) )
56 if( aRelative.IsEmpty() )
59 wxFileName fn( aRelative );
62 return fn.GetFullPath();
64 wxFileName resolved( aRoot, wxEmptyString );
65 resolved.SetFullName( wxEmptyString );
67 wxFileName joined( aRoot + wxFileName::GetPathSeparator() + aRelative );
68 joined.MakeAbsolute();
70 return joined.GetFullPath();
74bool CORPUS::Load( std::vector<CORPUS_ENTRY>& aEntries, wxString& aError )
82 wxString root =
Root();
83 wxFileName manifest( root, wxT(
"corpus.json" ) );
85 if( !manifest.Exists() )
87 aError = wxString::Format( wxT(
"corpus.json not found in %s" ), root );
91 std::ifstream in( manifest.GetFullPath().fn_str() );
95 aError = wxString::Format( wxT(
"cannot open %s" ), manifest.GetFullPath() );
99 std::stringstream buffer;
100 buffer << in.rdbuf();
106 doc = nlohmann::json::parse( buffer.str() );
108 catch(
const std::exception& e )
110 aError = wxString::Format( wxT(
"corpus.json parse error: %s" ), e.what() );
114 if( !doc.is_array() )
116 aError = wxT(
"corpus.json must be a JSON array of entries" );
120 for(
const nlohmann::json& node : doc )
122 if( !node.is_object() || !node.contains(
"board" ) )
127 auto getString = [&](
const char* aKey ) -> wxString
129 if( node.contains( aKey ) && node[aKey].is_string() )
130 return wxString::FromUTF8( node[aKey].get<std::string>().c_str() );
132 return wxEmptyString;
137 entry.
tier = getString(
"tier" );
138 entry.
source = getString(
"source" );
139 entry.
notes = getString(
"notes" );
141 if( node.contains(
"quick" ) && node[
"quick"].is_boolean() )
142 entry.
quick = node[
"quick"].get<
bool>();
144 aEntries.push_back( entry );
256 static const std::vector<wxString> names = { wxT(
"intersectsCourtyard" ),
257 wxT(
"intersectsFrontCourtyard" ),
258 wxT(
"intersectsBackCourtyard" ),
259 wxT(
"insideCourtyard" ),
260 wxT(
"insideFrontCourtyard" ),
261 wxT(
"insideBackCourtyard" ),
262 wxT(
"intersectsArea" ),
263 wxT(
"intersectsKeepout" ),
264 wxT(
"enclosedByArea" ),
267 wxT(
"hasNetclass" ),
268 wxT(
"hasExactNetclass" ),
269 wxT(
"hasComponentClass" ),
271 wxT(
"memberOfSheet" ),
272 wxT(
"memberOfSheetOrChildren" ),
273 wxT(
"memberOfFootprint" ),
274 wxT(
"memberOfGroup" ),
277 wxT(
"isCoupledDiffPair" ),
279 wxT(
"inNetChainClass" ),
280 wxT(
"hasNetChain" ),
281 wxT(
"existsOnLayer" ),
285 wxT(
"isBuriedVia" ),
286 wxT(
"isBlindBuriedVia" ),
287 wxT(
"isStackedVia" ) };
295 std::vector<wxString> found;
301 size_t searchFrom = 0;
305 size_t pos = aRulesText.find(
name, searchFrom );
307 if( pos == wxString::npos )
310 size_t after = pos +
name.length();
312 while( after < aRulesText.length() && wxIsspace( aRulesText[after] ) )
315 if( after < aRulesText.length() && aRulesText[after] ==
'(' )
317 found.push_back(
name );
321 searchFrom = pos + 1;
static bool Load(std::vector< CORPUS_ENTRY > &aEntries, wxString &aError)
Parse <root>/corpus.json into resolved entries.
static bool IsConfigured()
True when KICAD_DRC_BENCH_CORPUS is set and names an existing directory.
static wxString Root()
The resolved corpus root, or an empty string when unconfigured.
const char * ConstraintTypeName(DRC_CONSTRAINT_T aType)
Human-readable token for a DRC_CONSTRAINT_T, matching the .kicad_dru keyword where one exists.
std::vector< wxString > ScanPredicatesInRules(const wxString &aRulesText)
Scan raw .kicad_dru text for occurrences of each registered predicate name.
const std::vector< wxString > & AllPredicateNames()
Every pcbexpr predicate registered in pcbexpr_functions.cpp, used for textual coverage scans.
static wxString resolveAgainstRoot(const wxString &aRoot, const wxString &aRelative)
Resolve a manifest-relative path against the corpus root and return an absolute path.
const std::vector< DRC_CONSTRAINT_T > & AllConstraintTypes()
Every DRC_CONSTRAINT_T the engine can carry rules for, in enum order, excluding NULL_CONSTRAINT.
@ ANNULAR_WIDTH_CONSTRAINT
@ BRIDGED_MASK_CONSTRAINT
@ COURTYARD_CLEARANCE_CONSTRAINT
@ VIA_DIAMETER_CONSTRAINT
@ ZONE_CONNECTION_CONSTRAINT
@ DIFF_PAIR_GAP_CONSTRAINT
@ NET_CHAIN_LENGTH_CONSTRAINT
@ VIA_DANGLING_CONSTRAINT
@ SOLDER_MASK_SLIVER_CONSTRAINT
@ NET_CHAIN_STUB_LENGTH_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ TRACK_SEGMENT_LENGTH_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ NET_CHAIN_RETURN_PATH_CONSTRAINT
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
@ MICROVIA_ASPECT_RATIO_CONSTRAINT
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
@ CONNECTION_WIDTH_CONSTRAINT
@ THERMAL_RELIEF_GAP_CONSTRAINT
@ MAX_UNCOUPLED_CONSTRAINT
@ MICROVIA_STACK_DEPTH_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_ABS_MARGIN_CONSTRAINT
@ SOLDER_MASK_EXPANSION_CONSTRAINT
@ DIFF_PAIR_INTRA_SKEW_CONSTRAINT
@ PHYSICAL_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_REL_MARGIN_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
One board+rules pairing from the out-of-tree corpus manifest.
wxString tier
Free-form tier tag from the manifest (A/B/C).
wxString board
Absolute path to the .kicad_pcb.
wxString rules
Absolute path to the .kicad_dru, or empty for none.
wxString source
Provenance string for traceability.
wxString notes
Free-form annotation.
bool quick
Part of the fast iteration set selected by –quick.