Implements C.len operator for clist and eclist types.

Thanks to Sergey Popovich for the original patch.
This commit is contained in:
Ondrej Zajicek 2013-10-02 14:57:29 +02:00
parent 28a10f84cb
commit 7ccb36d330
4 changed files with 11 additions and 3 deletions

View file

@ -1077,6 +1077,8 @@ incompatible with each other (that is to prevent you from shooting in the foot).
no literals of this type. There are three special operators on no literals of this type. There are three special operators on
clists: clists:
<cf><m/C/.len</cf> returns the length of clist <m/C/.
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist <cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist
<m/C/ and returns the result. If item <m/P/ is already in <m/C/ and returns the result. If item <m/P/ is already in
clist <m/C/, it does nothing. <m/P/ may also be a clist, clist <m/C/, it does nothing. <m/P/ may also be a clist,

View file

@ -1067,7 +1067,9 @@ interpret(struct f_inst *what)
switch(v1.type) { switch(v1.type) {
case T_PREFIX: res.val.i = v1.val.px.len; break; case T_PREFIX: res.val.i = v1.val.px.len; break;
case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break; case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break;
default: runtime( "Prefix or path expected" ); case T_CLIST: res.val.i = int_set_get_size(v1.val.ad); break;
case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
default: runtime( "Prefix, path, clist or eclist expected" );
} }
break; break;
case P('c','p'): /* Convert prefix to ... */ case P('c','p'): /* Convert prefix to ... */

View file

@ -142,10 +142,10 @@ eclist el2;
l = add( l, (3,5) ); l = add( l, (3,5) );
l2 = filter( l, [(3,*)] ); l2 = filter( l, [(3,*)] );
l = delete( l, [(3,2..4)] ); l = delete( l, [(3,2..4)] );
print "Community list (1,2) (3,1) (3,5) ", l; print "Community list (1,2) (3,1) (3,5) ", l, " len: ", l.len;
l = add( l, (3,2) ); l = add( l, (3,2) );
l = add( l, (4,5) ); l = add( l, (4,5) );
print "Community list (1,2) (3,1) (3,2) (3,5) (4,5) ", l; print "Community list (1,2) (3,1) (3,2) (3,5) (4,5) ", l, " len: ", l.len;
print "Should be true: ", l ~ [(*,2)], " ", l ~ [(*,5)], " ", l ~ [(*, one)]; print "Should be true: ", l ~ [(*,2)], " ", l ~ [(*,5)], " ", l ~ [(*, one)];
print "Should be false: ", l ~ [(*,3)], " ", l ~ [(*,(one+6))], " ", l ~ [(*, (one+one+one))]; print "Should be false: ", l ~ [(*,3)], " ", l ~ [(*,(one+6))], " ", l ~ [(*, (one+one+one))];
l = delete( l, [(*,(one+onef(3)))] ); l = delete( l, [(*,(one+onef(3)))] );
@ -168,6 +168,7 @@ eclist el2;
el = add(el, (ro, 11.21.31.41.mask(16), 200)); el = add(el, (ro, 11.21.31.41.mask(16), 200));
print "EC list (rt, 10, 20) (ro, 10.20.30.40, 100) (ro, 11.21.0.0, 200):"; print "EC list (rt, 10, 20) (ro, 10.20.30.40, 100) (ro, 11.21.0.0, 200):";
print el; print el;
print "EC len: ", el.len;
el = delete(el, (rt, 10, 20)); el = delete(el, (rt, 10, 20));
el = delete(el, (rt, 10, 30)); el = delete(el, (rt, 10, 30));
el = add(el, (unknown 2, ten, 1)); el = add(el, (unknown 2, ten, 1));

View file

@ -69,6 +69,9 @@ int as_path_match(struct adata *path, struct f_path_mask *mask);
static inline int int_set_get_size(struct adata *list) static inline int int_set_get_size(struct adata *list)
{ return list->length / 4; } { return list->length / 4; }
static inline int ec_set_get_size(struct adata *list)
{ return list->length / 8; }
static inline u32 *int_set_get_data(struct adata *list) static inline u32 *int_set_get_data(struct adata *list)
{ return (u32 *) list->data; } { return (u32 *) list->data; }