Expr: Implement string in table[pattern] of X

Not sure how useful this is (and the implementation isn't optimized in
any way), but seems reasonable for consistency.

Vern suggested that set[pattern] can already be achieved via
set_to_regex(), so left out any set[pattern] variants.
This commit is contained in:
Arne Welzel 2023-11-01 17:27:47 +01:00
parent 9ae99cdc44
commit c72d4a4427
5 changed files with 42 additions and 3 deletions

View file

@ -3815,6 +3815,18 @@ InExpr::InExpr(ExprPtr arg_op1, ExprPtr arg_op2) : BinaryExpr(EXPR_IN, std::move
} }
} }
// Support <string> in table[pattern] of X
if ( op1->GetType()->Tag() == TYPE_STRING ) {
if ( op2->GetType()->Tag() == TYPE_TABLE ) {
const auto& table_type = op2->GetType()->AsTableType();
if ( table_type->IsPatternIndex() && table_type->Yield() ) {
SetType(base_type(TYPE_BOOL));
return;
}
}
}
if ( op1->Tag() != EXPR_LIST ) if ( op1->Tag() != EXPR_LIST )
op1 = make_intrusive<ListExpr>(std::move(op1)); op1 = make_intrusive<ListExpr>(std::move(op1));
@ -3853,8 +3865,14 @@ ValPtr InExpr::Fold(Val* v1, Val* v2) const {
auto ind = v1->AsListVal()->Idx(0)->CoerceToUnsigned(); auto ind = v1->AsListVal()->Idx(0)->CoerceToUnsigned();
res = ind < vv2->Size() && vv2->ValAt(ind); res = ind < vv2->Size() && vv2->ValAt(ind);
} }
else {
const auto& table_val = v2->AsTableVal();
const auto& table_type = table_val->GetType<zeek::TableType>();
if ( table_type->IsPatternIndex() && table_type->Yield() && v1->GetType()->Tag() == TYPE_STRING )
res = table_val->LookupPattern({NewRef{}, v1->AsStringVal()})->Size() > 0;
else else
res = (bool)v2->AsTableVal()->Find({NewRef{}, v1}); res = (bool)v2->AsTableVal()->Find({NewRef{}, v1});
}
return val_mgr->Bool(res); return val_mgr->Bool(res);
} }

View file

@ -4,3 +4,5 @@ populate_a()
gotcha a, [42] gotcha a, [42]
populate_b() populate_b()
gotcha b, [4242] gotcha b, [4242]
populate_c()
gotcha c, [4711]

View file

@ -2,9 +2,13 @@
indexing empty, 0 indexing empty, 0
single insert, match, [1] single insert, match, [1]
single insert, non-match, [] single insert, non-match, []
single insert, in, T
single insert, not-in, F
multiple inserts, non-match, [] multiple inserts, non-match, []
multiple inserts, single match, [3] multiple inserts, single match, [3]
multiple inserts, double match, [1, 3] multiple inserts, double match, [1, 3]
multiple insert, in, T
multiple insert, not-in, F
triple match, [1, 3, 4] triple match, [1, 3, 4]
embedded newline, /s operator, [6] embedded newline, /s operator, [6]
no embedded newline, /s vs. no /s operator, [5, 6, 7] no embedded newline, /s vs. no /s operator, [5, 6, 7]

View file

@ -6,11 +6,18 @@ global pt: table[pattern] of count;
redef exit_only_after_terminate = T; redef exit_only_after_terminate = T;
event populate_c()
{
print "populate_c()";
pt[/c/] = 4711;
terminate();
}
event populate_b() event populate_b()
{ {
print "populate_b()"; print "populate_b()";
pt[/b/] = 4242; pt[/b/] = 4242;
terminate(); schedule 1msec { populate_c() };
} }
event populate_a() event populate_a()
@ -38,6 +45,10 @@ event zeek_init()
print "gotcha b", pt["b"]; print "gotcha b", pt["b"];
} }
when ( "c" in pt ) {
print "gotcha c", pt["c"];
}
print "schedule populate"; print "schedule populate";
schedule 1msec { populate_a() }; schedule 1msec { populate_a() };
} }

View file

@ -13,6 +13,8 @@ event zeek_init()
print "single insert, match", pt["foo"]; print "single insert, match", pt["foo"];
print "single insert, non-match", pt["foox"]; print "single insert, non-match", pt["foox"];
print "single insert, in", "foo" in pt;
print "single insert, not-in", "foox" in pt;
pt[/bar/] = 2; pt[/bar/] = 2;
pt[/(foo|bletch)/] = 3; pt[/(foo|bletch)/] = 3;
@ -20,6 +22,8 @@ event zeek_init()
print "multiple inserts, non-match", pt["x"]; print "multiple inserts, non-match", pt["x"];
print "multiple inserts, single match", pt["bletch"]; print "multiple inserts, single match", pt["bletch"];
print "multiple inserts, double match", sort(pt["foo"]); print "multiple inserts, double match", sort(pt["foo"]);
print "multiple insert, in", "foo" in pt;
print "multiple insert, not-in", "x" in pt;
pt[/(foo|bletch|xyz)/] = 4; pt[/(foo|bletch|xyz)/] = 4;
print "triple match", sort(pt["foo"]); print "triple match", sort(pt["foo"]);