KiCad PCB EDA Suite
drc_rule_condition.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_item.h>
26#include <reporter.h>
28#include <pcb_expr_evaluator.h>
29
30
31DRC_RULE_CONDITION::DRC_RULE_CONDITION( const wxString& aExpression ) :
32 m_expression( aExpression ),
33 m_ucode ( nullptr )
34{
35}
36
37
39{
40}
41
42
43bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM* aItemB,
44 int aConstraint, PCB_LAYER_ID aLayer, REPORTER* aReporter )
45{
46 if( GetExpression().IsEmpty() )
47 return true;
48
49 if( !m_ucode )
50 {
51 if( aReporter )
52 aReporter->Report( _( "ERROR in expression." ) );
53
54 return false;
55 }
56
57 PCB_EXPR_CONTEXT ctx( aConstraint, aLayer );
58
59 if( aReporter )
60 {
62 [&]( const wxString& aMessage, int aOffset )
63 {
64 aReporter->Report( _( "ERROR:" ) + wxS( " " ) + aMessage );
65 } );
66 }
67
68 BOARD_ITEM* a = const_cast<BOARD_ITEM*>( aItemA );
69 BOARD_ITEM* b = const_cast<BOARD_ITEM*>( aItemB );
70
71 ctx.SetItems( a, b );
72
73 if( m_ucode->Run( &ctx )->AsDouble() != 0.0 )
74 {
75 return true;
76 }
77 else if( aItemB ) // Conditions are commutative
78 {
79 ctx.SetItems( b, a );
80
81 if( m_ucode->Run( &ctx )->AsDouble() != 0.0 )
82 return true;
83 }
84
85 return false;
86}
87
88
89bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
90{
91 PCB_EXPR_COMPILER compiler( new PCB_UNIT_RESOLVER() );
92
93 if( aReporter )
94 {
95 compiler.SetErrorCallback(
96 [&]( const wxString& aMessage, int aOffset )
97 {
98 wxString rest;
99 wxString first = aMessage.BeforeFirst( '|', &rest );
100 wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
101 aSourceLine,
102 aSourceOffset + aOffset,
103 first,
104 rest );
105
106 aReporter->Report( msg, RPT_SEVERITY_ERROR );
107 } );
108 }
109
110 m_ucode = std::make_unique<PCB_EXPR_UCODE>();
111
112 PCB_EXPR_CONTEXT preflightContext( 0, F_Cu );
113
114 bool ok = compiler.Compile( GetExpression().ToUTF8().data(), m_ucode.get(), &preflightContext );
115 return ok;
116}
117
118
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
DRC_RULE_CONDITION(const wxString &aExpression="")
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
wxString GetExpression() const
bool EvaluateFor(const BOARD_ITEM *aItemA, const BOARD_ITEM *aItemB, int aConstraint, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
std::unique_ptr< PCB_EXPR_UCODE > m_ucode
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
void SetErrorCallback(std::function< void(const wxString &aMessage, int aOffset)> aCallback)
void SetItems(BOARD_ITEM *a, BOARD_ITEM *b=nullptr)
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ F_Cu
Definition: layer_ids.h:64
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ RPT_SEVERITY_ERROR