Implement boolean not processing in expression language.

Also adds some more error catching to be more robust in the face
of malformed customer rules.

Fixes https://gitlab.com/kicad/code/kicad/issues/5694
This commit is contained in:
Jeff Young 2020-09-19 00:09:53 +01:00
parent 23f7ba6ee4
commit 0763a8962c
4 changed files with 41 additions and 4 deletions

View File

@ -128,6 +128,12 @@ nt(A) ::= nt(B) G_BOOL_OR nt(C).
A->leaf[1] = C;
}
nt(A) ::= G_BOOL_NOT nt(B).
{
A = newNode( pEval, TR_OP_BOOL_NOT );
A->leaf[0] = B;
}
nt(A) ::= nt(B) G_PLUS nt(C).
{
A = newNode( pEval, TR_OP_ADD );

View File

@ -1031,7 +1031,24 @@ void UOP::Exec( CONTEXT* ctx )
}
else if( m_op & TR_OP_UNARY_MASK )
{
// fixme : not operator
LIBEVAL::VALUE* arg1 = ctx->Pop();
double arg1Value = arg1 ? arg1->AsDouble() : 0.0;
double result;
switch( m_op )
{
case TR_OP_BOOL_NOT:
result = arg1Value != 0.0 ? 0 : 1;
break;
default:
result = 0.0;
break;
}
auto rp = ctx->AllocValue();
rp->Set( result );
ctx->Push( rp );
return;
}
}
@ -1040,8 +1057,16 @@ VALUE* UCODE::Run( CONTEXT* ctx )
{
static VALUE g_false( 0 );
for( UOP* op : m_ucode )
op->Exec( ctx );
try
{
for( UOP* op : m_ucode )
op->Exec( ctx );
}
catch(...)
{
// rules which fail outright should not be fired
return &g_false;
}
// non-well-formed rules should not be fired
if( ctx->SP() != 1 )

View File

@ -276,6 +276,12 @@ public:
VALUE* Pop()
{
if( m_stack.size() == 0 )
{
ReportError( _( "Malformed expression" ) );
return AllocValue();
}
VALUE* value = m_stack.top();
m_stack.pop();
return value;

View File

@ -44,7 +44,7 @@ pad hole graphic text zone
(rule HV_unshielded
(constraint clearance (min 2mm))
(condition "A.NetClass == 'HV' && not A.insideArea('Shield*')))
(condition "A.NetClass == 'HV' && !A.insideArea('Shield*')))
# ---- Notes