KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_rule_parser.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020-2022 KiCad Developers, see change_log.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25#include <board.h>
26#include <zones.h>
27#include <drc/drc_rule_parser.h>
29#include <drc_rules_lexer.h>
30#include <pcbexpr_evaluator.h>
31#include <reporter.h>
32
33using namespace DRCRULE_T;
34
35
36DRC_RULES_PARSER::DRC_RULES_PARSER( const wxString& aSource, const wxString& aSourceDescr ) :
37 DRC_RULES_LEXER( aSource.ToStdString(), aSourceDescr ),
38 m_requiredVersion( 0 ),
39 m_tooRecent( false ),
40 m_reporter( nullptr )
41{
42}
43
44
45DRC_RULES_PARSER::DRC_RULES_PARSER( FILE* aFile, const wxString& aFilename ) :
46 DRC_RULES_LEXER( aFile, aFilename ),
47 m_requiredVersion( 0 ),
48 m_tooRecent( false ),
49 m_reporter( nullptr )
50{
51}
52
53
54void DRC_RULES_PARSER::reportError( const wxString& aMessage )
55{
56 wxString rest;
57 wxString first = aMessage.BeforeFirst( '|', &rest );
58
59 if( m_reporter )
60 {
61 wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ), CurLineNumber(),
62 CurOffset(), first, rest );
63
65 }
66 else
67 {
68 wxString msg = wxString::Format( _( "ERROR: %s%s" ), first, rest );
69
70 THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
71 }
72}
73
74
75void DRC_RULES_PARSER::reportDeprecation( const wxString& oldToken, const wxString newToken )
76{
77 if( m_reporter )
78 {
79 wxString msg = wxString::Format( _( "The '%s' keyword has been deprecated. "
80 "Please use '%s' instead." ),
81 oldToken,
82 newToken);
83
85 }
86}
87
88
90{
91 int depth = 1;
92
93 for( T token = NextTok(); token != T_EOF; token = NextTok() )
94 {
95 if( token == T_LEFT )
96 depth++;
97
98 if( token == T_RIGHT )
99 {
100 if( --depth == 0 )
101 break;
102 }
103 }
104}
105
106
107void DRC_RULES_PARSER::Parse( std::vector<std::shared_ptr<DRC_RULE>>& aRules, REPORTER* aReporter )
108{
109 bool haveVersion = false;
110 wxString msg;
111
112 m_reporter = aReporter;
113
114 for( T token = NextTok(); token != T_EOF; token = NextTok() )
115 {
116 if( token != T_LEFT )
117 reportError( _( "Missing '('." ) );
118
119 token = NextTok();
120
121 if( !haveVersion && token != T_version )
122 {
123 reportError( _( "Missing version statement." ) );
124 haveVersion = true; // don't keep on reporting it
125 }
126
127 switch( token )
128 {
129 case T_version:
130 haveVersion = true;
131 token = NextTok();
132
133 if( (int) token == DSN_RIGHT )
134 {
135 reportError( _( "Missing version number." ) );
136 break;
137 }
138
139 if( (int) token == DSN_NUMBER )
140 {
141 m_requiredVersion = (int)strtol( CurText(), nullptr, 10 );
143 token = NextTok();
144 }
145 else
146 {
147 msg.Printf( _( "Unrecognized item '%s'.| Expected version number." ),
148 FromUTF8() );
149 reportError( msg );
150 }
151
152 if( (int) token != DSN_RIGHT )
153 {
154 msg.Printf( _( "Unrecognized item '%s'." ),
155 FromUTF8() );
156 reportError( msg );
157 parseUnknown();
158 }
159
160 break;
161
162 case T_rule:
163 aRules.emplace_back( parseDRC_RULE() );
164 break;
165
166 case T_EOF:
167 reportError( _( "Incomplete statement." ) );
168 break;
169
170 default:
171 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
172 wxT( "rule or version" ) );
173 reportError( msg );
174 parseUnknown();
175 }
176 }
177
178 if( m_reporter && !m_reporter->HasMessage() )
179 m_reporter->Report( _( "No errors found." ), RPT_SEVERITY_INFO );
180
181 m_reporter = nullptr;
182}
183
184
185std::shared_ptr<DRC_RULE> DRC_RULES_PARSER::parseDRC_RULE()
186{
187 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
188
189 T token = NextTok();
190 wxString msg;
191
192 if( !IsSymbol( token ) )
193 reportError( _( "Missing rule name." ) );
194
195 rule->m_Name = FromUTF8();
196
197 for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
198 {
199 if( token != T_LEFT )
200 reportError( _( "Missing '('." ) );
201
202 token = NextTok();
203
204 switch( token )
205 {
206 case T_constraint:
207 parseConstraint( rule.get() );
208 break;
209
210 case T_condition:
211 token = NextTok();
212
213 if( (int) token == DSN_RIGHT )
214 {
215 reportError( _( "Missing condition expression." ) );
216 break;
217 }
218
219 if( IsSymbol( token ) )
220 {
221 rule->m_Condition = new DRC_RULE_CONDITION( FromUTF8() );
222 rule->m_Condition->Compile( m_reporter, CurLineNumber(), CurOffset() );
223 }
224 else
225 {
226 msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ),
227 FromUTF8() );
228 reportError( msg );
229 }
230
231 if( (int) NextTok() != DSN_RIGHT )
232 {
233 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
234 parseUnknown();
235 }
236
237 break;
238
239 case T_layer:
240 if( rule->m_LayerCondition != LSET::AllLayersMask() )
241 reportError( _( "'layer' keyword already present." ) );
242 rule->m_LayerSource = FromUTF8();
243 rule->m_LayerCondition = parseLayer();
244 break;
245
246 case T_severity:
247 rule->m_Severity = parseSeverity();
248 break;
249
250 case T_EOF:
251 reportError( _( "Incomplete statement." ) );
252 return rule;
253
254 default:
255 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
256 wxT( "constraint, condition, or disallow" ) );
257 reportError( msg );
258 parseUnknown();
259 }
260 }
261
262 if( (int) CurTok() != DSN_RIGHT )
263 reportError( _( "Missing ')'." ) );
264
265 return rule;
266}
267
268
270{
272 int value;
273 wxString msg;
274
275 T token = NextTok();
276
277 if( token == T_mechanical_clearance )
278 {
279 reportDeprecation( wxT( "mechanical_clearance" ), wxT( "physical_clearance" ) );
280 token = T_physical_clearance;
281 }
282 else if( token == T_mechanical_hole_clearance )
283 {
284 reportDeprecation( wxT( "mechanical_hole_clearance" ), wxT( "physical_hole_clearance" ) );
285 token = T_physical_hole_clearance;
286 }
287 else if( token == T_hole )
288 {
289 reportDeprecation( wxT( "hole" ), wxT( "hole_size" ) );
290 token = T_hole_size;
291 }
292 else if( (int) token == DSN_RIGHT || token == T_EOF )
293 {
294 msg.Printf( _( "Missing constraint type.| Expected %s." ),
295 wxT( "assertion, clearance, hole_clearance, edge_clearance, "
296 "physical_clearance, physical_hole_clearance, courtyard_clearance, "
297 "silk_clearance, hole_size, hole_to_hole, track_width, annular_width, "
298 "via_diameter, disallow, zone_connection, thermal_relief_gap, "
299 "thermal_spoke_width, min_resolved_spokes, length, skew, via_count, "
300 "diff_pair_gap or diff_pair_uncoupled" ) );
301 reportError( msg );
302 return;
303 }
304
305 switch( token )
306 {
307 case T_assertion: c.m_Type = ASSERTION_CONSTRAINT; break;
308 case T_clearance: c.m_Type = CLEARANCE_CONSTRAINT; break;
309 case T_creepage: c.m_Type = CREEPAGE_CONSTRAINT; break;
310 case T_hole_clearance: c.m_Type = HOLE_CLEARANCE_CONSTRAINT; break;
311 case T_edge_clearance: c.m_Type = EDGE_CLEARANCE_CONSTRAINT; break;
312 case T_hole_size: c.m_Type = HOLE_SIZE_CONSTRAINT; break;
313 case T_hole_to_hole: c.m_Type = HOLE_TO_HOLE_CONSTRAINT; break;
314 case T_courtyard_clearance: c.m_Type = COURTYARD_CLEARANCE_CONSTRAINT; break;
315 case T_silk_clearance: c.m_Type = SILK_CLEARANCE_CONSTRAINT; break;
316 case T_text_height: c.m_Type = TEXT_HEIGHT_CONSTRAINT; break;
317 case T_text_thickness: c.m_Type = TEXT_THICKNESS_CONSTRAINT; break;
318 case T_track_width: c.m_Type = TRACK_WIDTH_CONSTRAINT; break;
319 case T_track_angle: c.m_Type = TRACK_ANGLE_CONSTRAINT; break;
320 case T_track_segment_length: c.m_Type = TRACK_SEGMENT_LENGTH_CONSTRAINT; break;
321 case T_connection_width: c.m_Type = CONNECTION_WIDTH_CONSTRAINT; break;
322 case T_annular_width: c.m_Type = ANNULAR_WIDTH_CONSTRAINT; break;
323 case T_via_diameter: c.m_Type = VIA_DIAMETER_CONSTRAINT; break;
324 case T_zone_connection: c.m_Type = ZONE_CONNECTION_CONSTRAINT; break;
325 case T_thermal_relief_gap: c.m_Type = THERMAL_RELIEF_GAP_CONSTRAINT; break;
326 case T_thermal_spoke_width: c.m_Type = THERMAL_SPOKE_WIDTH_CONSTRAINT; break;
327 case T_min_resolved_spokes: c.m_Type = MIN_RESOLVED_SPOKES_CONSTRAINT; break;
328 case T_disallow: c.m_Type = DISALLOW_CONSTRAINT; break;
329 case T_length: c.m_Type = LENGTH_CONSTRAINT; break;
330 case T_skew: c.m_Type = SKEW_CONSTRAINT; break;
331 case T_via_count: c.m_Type = VIA_COUNT_CONSTRAINT; break;
332 case T_diff_pair_gap: c.m_Type = DIFF_PAIR_GAP_CONSTRAINT; break;
333 case T_diff_pair_uncoupled: c.m_Type = MAX_UNCOUPLED_CONSTRAINT; break;
334 case T_physical_clearance: c.m_Type = PHYSICAL_CLEARANCE_CONSTRAINT; break;
335 case T_physical_hole_clearance: c.m_Type = PHYSICAL_HOLE_CLEARANCE_CONSTRAINT; break;
336 default:
337 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
338 wxT( "assertion, clearance, hole_clearance, edge_clearance, "
339 "physical_clearance, physical_hole_clearance, courtyard_clearance, "
340 "silk_clearance, hole_size, hole_to_hole, track_width, track_angle, track_segment_length, annular_width, "
341 "disallow, zone_connection, thermal_relief_gap, thermal_spoke_width, "
342 "min_resolved_spokes, length, skew, via_count, via_diameter, "
343 "diff_pair_gap or diff_pair_uncoupled" ) );
344 reportError( msg );
345 }
346
347 if( aRule->FindConstraint( c.m_Type ) )
348 {
349 msg.Printf( _( "Rule already has a '%s' constraint." ), FromUTF8() );
350 reportError( msg );
351 }
352
353 bool unitless = c.m_Type == VIA_COUNT_CONSTRAINT
356
357 if( c.m_Type == DISALLOW_CONSTRAINT )
358 {
359 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
360 {
361 if( (int) token == DSN_STRING )
362 token = GetCurStrAsToken();
363
364 switch( token )
365 {
366 case T_track: c.m_DisallowFlags |= DRC_DISALLOW_TRACKS; break;
367 case T_via: c.m_DisallowFlags |= DRC_DISALLOW_VIAS; break;
368 case T_micro_via: c.m_DisallowFlags |= DRC_DISALLOW_MICRO_VIAS; break;
369 case T_buried_via: c.m_DisallowFlags |= DRC_DISALLOW_BB_VIAS; break;
370 case T_pad: c.m_DisallowFlags |= DRC_DISALLOW_PADS; break;
371 case T_zone: c.m_DisallowFlags |= DRC_DISALLOW_ZONES; break;
372 case T_text: c.m_DisallowFlags |= DRC_DISALLOW_TEXTS; break;
373 case T_graphic: c.m_DisallowFlags |= DRC_DISALLOW_GRAPHICS; break;
374 case T_hole: c.m_DisallowFlags |= DRC_DISALLOW_HOLES; break;
375 case T_footprint: c.m_DisallowFlags |= DRC_DISALLOW_FOOTPRINTS; break;
376
377 case T_EOF:
378 reportError( _( "Missing ')'." ) );
379 return;
380
381 default:
382 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
383 wxT( "track, via, micro_via, buried_via, pad, zone, text, graphic, "
384 "hole, or footprint." ) );
385 reportError( msg );
386 break;
387 }
388 }
389
390 if( (int) CurTok() != DSN_RIGHT )
391 reportError( _( "Missing ')'." ) );
392
393 aRule->AddConstraint( c );
394 return;
395 }
396 else if( c.m_Type == ZONE_CONNECTION_CONSTRAINT )
397 {
398 token = NextTok();
399
400 if( (int) token == DSN_STRING )
401 token = GetCurStrAsToken();
402
403 switch( token )
404 {
405 case T_solid: c.m_ZoneConnection = ZONE_CONNECTION::FULL; break;
406 case T_thermal_reliefs: c.m_ZoneConnection = ZONE_CONNECTION::THERMAL; break;
407 case T_none: c.m_ZoneConnection = ZONE_CONNECTION::NONE; break;
408
409 case T_EOF:
410 reportError( _( "Missing ')'." ) );
411 return;
412
413 default:
414 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ), FromUTF8(),
415 "solid, thermal_reliefs or none." );
416 reportError( msg );
417 break;
418 }
419
420 if( (int) NextTok() != DSN_RIGHT )
421 reportError( _( "Missing ')'." ) );
422
423 aRule->AddConstraint( c );
424 return;
425 }
427 {
428 // We don't use a min/max/opt structure here because it would give a strong implication
429 // that you could specify the optimal number of spokes. We don't want to open that door
430 // because the spoke generator is highly optimized around being able to "cheat" off of a
431 // cartesian coordinate system.
432
433 token = NextTok();
434
435 if( (int) token == DSN_NUMBER )
436 {
437 value = (int) strtol( CurText(), nullptr, 10 );
438 c.m_Value.SetMin( value );
439 }
440 else
441 {
442 reportError( _( "Expecting number." ) );
443 parseUnknown();
444 }
445
446 if( (int) NextTok() != DSN_RIGHT )
447 reportError( _( "Missing ')'." ) );
448
449 aRule->AddConstraint( c );
450 return;
451 }
452 else if( c.m_Type == ASSERTION_CONSTRAINT )
453 {
454 token = NextTok();
455
456 if( (int) token == DSN_RIGHT )
457 reportError( _( "Missing assertion expression." ) );
458
459 if( IsSymbol( token ) )
460 {
461 c.m_Test = new DRC_RULE_CONDITION( FromUTF8() );
462 c.m_Test->Compile( m_reporter, CurLineNumber(), CurOffset() );
463 }
464 else
465 {
466 msg.Printf( _( "Unrecognized item '%s'.| Expected quoted expression." ), FromUTF8() );
467 reportError( msg );
468 }
469
470 if( (int) NextTok() != DSN_RIGHT )
471 {
472 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
473 parseUnknown();
474 }
475
476 aRule->AddConstraint( c );
477 return;
478 }
479
480 for( token = NextTok(); token != T_RIGHT && token != T_EOF; token = NextTok() )
481 {
482 if( token != T_LEFT )
483 reportError( _( "Missing '('." ) );
484
485 token = NextTok();
486
487 switch( token )
488 {
489 case T_within_diff_pairs:
490 if( c.m_Type != SKEW_CONSTRAINT )
491 {
492 reportError( _( "within_diff_pairs option invalid for constraint type." ) );
493 break;
494 }
495
497
498 if( (int) NextTok() != DSN_RIGHT )
499 {
500 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
501 parseUnknown();
502 }
503
504 break;
505 case T_min:
506 token = NextTok();
507
508 if( (int) token == DSN_RIGHT )
509 {
510 reportError( _( "Missing min value." ) );
511 break;
512 }
513
514 parseValueWithUnits( FromUTF8(), value, unitless );
515 c.m_Value.SetMin( value );
516
517 if( (int) NextTok() != DSN_RIGHT )
518 {
519 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
520 parseUnknown();
521 }
522
523 break;
524
525 case T_max:
526 token = NextTok();
527
528 if( (int) token == DSN_RIGHT )
529 {
530 reportError( _( "Missing max value." ) );
531 break;
532 }
533
534 parseValueWithUnits( FromUTF8(), value, unitless );
535
536 c.m_Value.SetMax( value );
537
538 if( (int) NextTok() != DSN_RIGHT )
539 {
540 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
541 parseUnknown();
542 }
543
544 break;
545
546 case T_opt:
547 token = NextTok();
548
549 if( (int) token == DSN_RIGHT )
550 {
551 reportError( _( "Missing opt value." ) );
552 break;
553 }
554
555 parseValueWithUnits( FromUTF8(), value, unitless );
556 c.m_Value.SetOpt( value );
557
558 if( (int) NextTok() != DSN_RIGHT )
559 {
560 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
561 parseUnknown();
562 }
563
564 break;
565
566 case T_EOF:
567 reportError( _( "Incomplete statement." ) );
568 return;
569
570 default:
571 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
572 FromUTF8(),
573 wxT( "min, max, or opt" ) );
574 reportError( msg );
575 parseUnknown();
576 }
577 }
578
579 if( (int) CurTok() != DSN_RIGHT )
580 reportError( _( "Missing ')'." ) );
581
582 aRule->AddConstraint( c );
583}
584
585
586void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult, bool aUnitless )
587{
588 auto errorHandler = [&]( const wxString& aMessage, int aOffset )
589 {
590 wxString rest;
591 wxString first = aMessage.BeforeFirst( '|', &rest );
592
593 if( m_reporter )
594 {
595 wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
596 CurLineNumber(), CurOffset() + aOffset, first, rest );
597
599 }
600 else
601 {
602 wxString msg = wxString::Format( _( "ERROR: %s%s" ), first, rest );
603
604 THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(),
605 CurOffset() + aOffset );
606 }
607 };
608
611 evaluator.SetErrorCallback( errorHandler );
612
613 evaluator.Evaluate( aExpr );
614 aResult = evaluator.Result();
615}
616
617
619{
620 LSET retVal;
621 int token = NextTok();
622
623 if( (int) token == DSN_RIGHT )
624 {
625 reportError( _( "Missing layer name or type." ) );
626 return LSET::AllCuMask();
627 }
628 else if( token == T_outer )
629 {
630 retVal = LSET::ExternalCuMask();
631 }
632 else if( token == T_inner )
633 {
634 retVal = LSET::InternalCuMask();
635 }
636 else
637 {
638 wxString layerName = FromUTF8();
639 wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
640
641 for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
642 {
643 wxPGChoiceEntry& entry = layerMap[ii];
644
645 if( entry.GetText().Matches( layerName ) )
646 retVal.set( ToLAYER_ID( entry.GetValue() ) );
647 }
648
649 if( !retVal.any() )
650 {
651 reportError( wxString::Format( _( "Unrecognized layer '%s'." ), layerName ) );
652 retVal.set( Rescue );
653 }
654 }
655
656 if( (int) NextTok() != DSN_RIGHT )
657 {
658 reportError( wxString::Format( _( "Unrecognized item '%s'." ), FromUTF8() ) );
659 parseUnknown();
660 }
661
662 return retVal;
663}
664
665
667{
669 wxString msg;
670
671 T token = NextTok();
672
673 if( (int) token == DSN_RIGHT || token == T_EOF )
674 {
675 reportError( _( "Missing severity name." ) );
677 }
678
679 switch( token )
680 {
681 case T_ignore: retVal = RPT_SEVERITY_IGNORE; break;
682 case T_warning: retVal = RPT_SEVERITY_WARNING; break;
683 case T_error: retVal = RPT_SEVERITY_ERROR; break;
684 case T_exclusion: retVal = RPT_SEVERITY_EXCLUSION; break;
685
686 default:
687 msg.Printf( _( "Unrecognized item '%s'.| Expected %s." ),
688 FromUTF8(),
689 wxT( "ignore, warning, error, or exclusion" ) );
690 reportError( msg );
691 parseUnknown();
692 }
693
694 if( (int) NextTok() != DSN_RIGHT )
695 reportError( _( "Missing ')'." ) );
696
697 return retVal;
698}
BASE_SET & set(size_t pos)
Definition: base_set.h:115
DRC_RULE_CONDITION * m_Test
Definition: drc_rule.h:193
int m_DisallowFlags
Definition: drc_rule.h:191
void SetOption(OPTIONS option)
Definition: drc_rule.h:181
ZONE_CONNECTION m_ZoneConnection
Definition: drc_rule.h:192
MINOPTMAX< int > m_Value
Definition: drc_rule.h:190
DRC_CONSTRAINT_T m_Type
Definition: drc_rule.h:189
SEVERITY parseSeverity()
void parseValueWithUnits(const wxString &aExpr, int &aResult, bool aUnitless=false)
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
REPORTER * m_reporter
std::shared_ptr< DRC_RULE > parseDRC_RULE()
void parseConstraint(DRC_RULE *aRule)
void reportError(const wxString &aMessage)
DRC_RULES_PARSER(const wxString &aSource, const wxString &aSourceDescr)
void reportDeprecation(const wxString &oldToken, const wxString newToken)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
void AddConstraint(DRC_CONSTRAINT &aConstraint)
Definition: drc_rule.cpp:60
std::optional< DRC_CONSTRAINT > FindConstraint(DRC_CONSTRAINT_T aType)
Definition: drc_rule.cpp:67
static ENUM_MAP< T > & Instance()
Definition: property.h:663
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
static LSET ExternalCuMask()
Return a mask holding the Front and Bottom layers.
Definition: lset.cpp:694
static LSET AllLayersMask()
Definition: lset.cpp:701
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:665
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
void SetMin(T v)
Definition: minoptmax.h:41
void SetOpt(T v)
Definition: minoptmax.h:43
void SetMax(T v)
Definition: minoptmax.h:42
bool Evaluate(const wxString &aExpr)
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:72
virtual bool HasMessage() const =0
Returns true if the reporter client is non-empty.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
@ DRC_DISALLOW_PADS
Definition: drc_rule.h:88
@ DRC_DISALLOW_VIAS
Definition: drc_rule.h:84
@ DRC_DISALLOW_TEXTS
Definition: drc_rule.h:90
@ DRC_DISALLOW_ZONES
Definition: drc_rule.h:89
@ DRC_DISALLOW_HOLES
Definition: drc_rule.h:92
@ DRC_DISALLOW_GRAPHICS
Definition: drc_rule.h:91
@ DRC_DISALLOW_FOOTPRINTS
Definition: drc_rule.h:93
@ DRC_DISALLOW_TRACKS
Definition: drc_rule.h:87
@ DRC_DISALLOW_MICRO_VIAS
Definition: drc_rule.h:85
@ DRC_DISALLOW_BB_VIAS
Definition: drc_rule.h:86
@ ANNULAR_WIDTH_CONSTRAINT
Definition: drc_rule.h:61
@ COURTYARD_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:55
@ VIA_DIAMETER_CONSTRAINT
Definition: drc_rule.h:67
@ ZONE_CONNECTION_CONSTRAINT
Definition: drc_rule.h:62
@ DIFF_PAIR_GAP_CONSTRAINT
Definition: drc_rule.h:70
@ DISALLOW_CONSTRAINT
Definition: drc_rule.h:66
@ TRACK_WIDTH_CONSTRAINT
Definition: drc_rule.h:59
@ SILK_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:56
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:53
@ MIN_RESOLVED_SPOKES_CONSTRAINT
Definition: drc_rule.h:65
@ TRACK_SEGMENT_LENGTH_CONSTRAINT
Definition: drc_rule.h:60
@ TEXT_THICKNESS_CONSTRAINT
Definition: drc_rule.h:58
@ LENGTH_CONSTRAINT
Definition: drc_rule.h:68
@ VIA_COUNT_CONSTRAINT
Definition: drc_rule.h:73
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:75
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:49
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
Definition: drc_rule.h:64
@ CONNECTION_WIDTH_CONSTRAINT
Definition: drc_rule.h:77
@ THERMAL_RELIEF_GAP_CONSTRAINT
Definition: drc_rule.h:63
@ MAX_UNCOUPLED_CONSTRAINT
Definition: drc_rule.h:71
@ ASSERTION_CONSTRAINT
Definition: drc_rule.h:76
@ SKEW_CONSTRAINT
Definition: drc_rule.h:69
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:51
@ TRACK_ANGLE_CONSTRAINT
Definition: drc_rule.h:78
@ HOLE_SIZE_CONSTRAINT
Definition: drc_rule.h:54
@ TEXT_HEIGHT_CONSTRAINT
Definition: drc_rule.h:57
@ CREEPAGE_CONSTRAINT
Definition: drc_rule.h:50
@ PHYSICAL_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:74
@ HOLE_TO_HOLE_CONSTRAINT
Definition: drc_rule.h:52
#define DRC_RULE_FILE_VERSION
@ DSN_RIGHT
Definition: dsnlexer.h:68
@ DSN_NUMBER
Definition: dsnlexer.h:67
@ DSN_STRING
Definition: dsnlexer.h:70
#define _(s)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
Definition: ki_exception.h:165
@ Rescue
Definition: layer_ids.h:121
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
@ RPT_SEVERITY_INFO