mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 19:18:19 +00:00
Add key-value for loop
This commit is contained in:
parent
a36ac12e88
commit
1f7924754e
7 changed files with 145 additions and 6 deletions
44
src/Stmt.cc
44
src/Stmt.cc
|
@ -1421,12 +1421,48 @@ ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr)
|
|||
e->Error("target to iterate over must be a table, set, vector, or string");
|
||||
}
|
||||
|
||||
ForStmt::ForStmt(id_list* arg_loop_vars, Expr* loop_expr, ID* val_var)
|
||||
: ForStmt(arg_loop_vars, loop_expr)
|
||||
{
|
||||
value_var = val_var;
|
||||
// Valdate that key-value for loop is being used on a table
|
||||
if ( e->Type()->Tag() == TYPE_TABLE )
|
||||
{
|
||||
// Type of values table holds
|
||||
BroType* yield_type = e->Type()->AsTableType()->YieldType();
|
||||
|
||||
// Verify value_vars type if its already been defined
|
||||
if ( value_var->Type() )
|
||||
{
|
||||
if ( ! same_type(value_var->Type(), yield_type) )
|
||||
{
|
||||
value_var->Type()->Error("type clash in iteration", yield_type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete add_local(value_var,
|
||||
yield_type->Ref(), INIT_NONE,
|
||||
0, 0, VAR_REGULAR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e->Error("key value for loops only support iteration over tables");
|
||||
}
|
||||
}
|
||||
|
||||
ForStmt::~ForStmt()
|
||||
{
|
||||
loop_over_list(*loop_vars, i)
|
||||
Unref((*loop_vars)[i]);
|
||||
delete loop_vars;
|
||||
|
||||
if (value_var)
|
||||
{
|
||||
Unref(value_var);
|
||||
}
|
||||
|
||||
Unref(body);
|
||||
}
|
||||
|
||||
|
@ -1443,12 +1479,18 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
|||
return 0;
|
||||
|
||||
HashKey* k;
|
||||
TableEntryVal* current_tev;
|
||||
IterCookie* c = loop_vals->InitForIteration();
|
||||
while ( loop_vals->NextEntry(k, c) )
|
||||
while ( (current_tev = loop_vals->NextEntry(k, c)) )
|
||||
{
|
||||
ListVal* ind_lv = tv->RecoverIndex(k);
|
||||
delete k;
|
||||
|
||||
if (value_var)
|
||||
{
|
||||
f->SetElement(value_var->Offset(), current_tev->Value()->Ref());
|
||||
}
|
||||
|
||||
for ( int i = 0; i < ind_lv->Length(); i++ )
|
||||
f->SetElement((*loop_vars)[i]->Offset(), ind_lv->Index(i)->Ref());
|
||||
Unref(ind_lv);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue