Add !~ operator to filter grammar

This commit is contained in:
Pavel Tvrdik 2016-09-20 15:13:01 +02:00 committed by Ondrej Zajicek (work)
parent 75ac3d199d
commit 768d5e1058
5 changed files with 32 additions and 20 deletions

View file

@ -246,6 +246,7 @@ else: {
<CCOMM>. <CCOMM>.
\!\= return NEQ; \!\= return NEQ;
\!\~ return NMA;
\<\= return LEQ; \<\= return LEQ;
\>\= return GEQ; \>\= return GEQ;
\&\& return AND; \&\& return AND;

View file

@ -82,7 +82,7 @@ CF_DECLS
%nonassoc PREFIX_DUMMY %nonassoc PREFIX_DUMMY
%left AND OR %left AND OR
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ PO PC %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
%left '+' '-' %left '+' '-'
%left '*' '/' '%' %left '*' '/' '%'
%left '!' %left '!'

View file

@ -1016,9 +1016,9 @@ foot).
of type <cf/string/, print such variables, use standard string of type <cf/string/, print such variables, use standard string
comparison operations (e.g. <cf/=, !=, &lt;, &gt;, &lt;=, &gt;=/), but comparison operations (e.g. <cf/=, !=, &lt;, &gt;, &lt;=, &gt;=/), but
you can't concatenate two strings. String literals are written as you can't concatenate two strings. String literals are written as
<cf/"This is a string constant"/. Additionally matching <cf/&tilde;/ <cf/"This is a string constant"/. Additionally matching (<cf/&tilde;,
operator could be used to match a string value against a shell pattern !&tilde;/) operators could be used to match a string value against
(represented also as a string). a shell pattern (represented also as a string).
<tag/ip/ <tag/ip/
This type can hold a single IP address. Depending on the compile-time This type can hold a single IP address. Depending on the compile-time
@ -1202,9 +1202,9 @@ foot).
<tag/eclist/ <tag/eclist/
Eclist is a data type used for BGP extended community lists. Eclists Eclist is a data type used for BGP extended community lists. Eclists
are very similar to clists, but they are sets of ECs instead of pairs. are very similar to clists, but they are sets of ECs instead of pairs.
The same operations (like <cf/add/, <cf/delete/, or <cf/&tilde;/ The same operations (like <cf/add/, <cf/delete/ or <cf/&tilde;/ and
membership operator) can be used to modify or test eclists, with ECs <cf/!&tilde;/ membership operators) can be used to modify or test
instead of pairs as arguments. eclists, with ECs instead of pairs as arguments.
</descrip> </descrip>
@ -1213,19 +1213,19 @@ foot).
<p>The filter language supports common integer operators <cf>(+,-,*,/)</cf>, <p>The filter language supports common integer operators <cf>(+,-,*,/)</cf>,
parentheses <cf/(a*(b+c))/, comparison <cf/(a=b, a!=b, a&lt;b, a&gt;=b)/. parentheses <cf/(a*(b+c))/, comparison <cf/(a=b, a!=b, a&lt;b, a&gt;=b)/.
Logical operations include unary not (<cf/!/), and (<cf/&amp;&amp;/) and or Logical operations include unary not (<cf/!/), and (<cf/&amp;&amp;/) and or
(<cf/&verbar;&verbar;/). Special operators include <cf/&tilde;/ for "is element (<cf/&verbar;&verbar;/). Special operators include (<cf/&tilde;/,
of a set" operation - it can be used on element and set of elements of the same <cf/!&tilde;/) for "is (not) element of a set" operation - it can be used on
type (returning true if element is contained in the given set), or on two element and set of elements of the same type (returning true if element is
strings (returning true if first string matches a shell-like pattern stored in contained in the given set), or on two strings (returning true if first string
second string) or on IP and prefix (returning true if IP is within the range matches a shell-like pattern stored in second string) or on IP and prefix
defined by that prefix), or on prefix and prefix (returning true if first prefix (returning true if IP is within the range defined by that prefix), or on prefix
is more specific than second one) or on bgppath and bgpmask (returning true if and prefix (returning true if first prefix is more specific than second one) or
the path matches the mask) or on number and bgppath (returning true if the on bgppath and bgpmask (returning true if the path matches the mask) or on
number is in the path) or on bgppath and int (number) set (returning true if any number and bgppath (returning true if the number is in the path) or on bgppath
ASN from the path is in the set) or on pair/quad and clist (returning true if and int (number) set (returning true if any ASN from the path is in the set) or
the pair/quad is element of the clist) or on clist and pair/quad set (returning on pair/quad and clist (returning true if the pair/quad is element of the
true if there is an element of the clist that is also a member of the pair/quad clist) or on clist and pair/quad set (returning true if there is an element of
set). the clist that is also a member of the pair/quad set).
<p>There is one operator related to ROA infrastructure - <cf/roa_check()/. It <p>There is one operator related to ROA infrastructure - <cf/roa_check()/. It
examines a ROA table and does RFC 6483 route origin validation for a given examines a ROA table and does RFC 6483 route origin validation for a given

View file

@ -735,6 +735,7 @@ term:
| term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; } | term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; }
| term GEQ term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $3; $$->a2.p = $1; } | term GEQ term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $3; $$->a2.p = $1; }
| term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; } | term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; }
| term NMA term { $$ = f_new_inst(); $$->code = P('!','~'); $$->a1.p = $1; $$->a2.p = $3; }
| '!' term { $$ = f_new_inst(); $$->code = '!'; $$->a1.p = $2; } | '!' term { $$ = f_new_inst(); $$->code = '!'; $$->a1.p = $2; }
| DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e'); $$->a1.p = $3; } | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e'); $$->a1.p = $3; }

View file

@ -716,6 +716,16 @@ interpret(struct f_inst *what)
runtime( "~ applied on unknown type pair" ); runtime( "~ applied on unknown type pair" );
res.val.i = !!res.val.i; res.val.i = !!res.val.i;
break; break;
case P('!','~'):
TWOARGS;
res.type = T_BOOL;
res.val.i = val_in_range(v1, v2);
if (res.val.i == CMP_ERROR)
runtime( "!~ applied on unknown type pair" );
res.val.i = !res.val.i;
break;
case P('d','e'): case P('d','e'):
ONEARG; ONEARG;
res.type = T_BOOL; res.type = T_BOOL;