mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
Fixing attributes to allow &default in tables/sets to be associated
with the field. This works now: type X: record { a: table[string] of bool &default=table( ["foo"] = T ); b: table[string] of bool &default=table(); c: set[string] &default=set("A", "B", "C"); d: set[string] &default=set(); }; I think previously the intend was to associate &default with the table/set (i.e., define the default value for non-existing indices). However, that was already not working: the error checking was reporting type mismatches. So, this shouldn't break anything and make things more consistent.
This commit is contained in:
parent
68a30a0b5a
commit
0a97a9e82a
10 changed files with 72 additions and 24 deletions
17
src/Attr.cc
17
src/Attr.cc
|
@ -57,10 +57,11 @@ void Attr::AddTag(ODesc* d) const
|
|||
d->Add(attr_name(Tag()));
|
||||
}
|
||||
|
||||
Attributes::Attributes(attr_list* a, BroType* t)
|
||||
Attributes::Attributes(attr_list* a, BroType* t, bool arg_in_record)
|
||||
{
|
||||
attrs = new attr_list(a->length());
|
||||
type = t->Ref();
|
||||
in_record = arg_in_record;
|
||||
|
||||
SetLocationInfo(&start_location, &end_location);
|
||||
|
||||
|
@ -199,7 +200,7 @@ void Attributes::CheckAttr(Attr* a)
|
|||
{
|
||||
BroType* atype = a->AttrExpr()->Type();
|
||||
|
||||
if ( type->Tag() != TYPE_TABLE || type->IsSet() )
|
||||
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
|
||||
{
|
||||
if ( ! same_type(atype, type) )
|
||||
a->AttrExpr()->Error("&default value has inconsistent type", type);
|
||||
|
@ -208,6 +209,9 @@ void Attributes::CheckAttr(Attr* a)
|
|||
|
||||
TableType* tt = type->AsTableType();
|
||||
|
||||
if ( ! in_record )
|
||||
{
|
||||
// &default applies to the type itself.
|
||||
if ( ! same_type(atype, tt->YieldType()) )
|
||||
{
|
||||
// It can still be a default function.
|
||||
|
@ -222,6 +226,15 @@ void Attributes::CheckAttr(Attr* a)
|
|||
Error("&default value has inconsistent type");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// &default applies to record field.
|
||||
if ( ! same_type(atype, type) &&
|
||||
! (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
|
||||
Error("&default value has inconsistent type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_ROTATE_INTERVAL:
|
||||
|
|
|
@ -62,7 +62,7 @@ protected:
|
|||
// Manages a collection of attributes.
|
||||
class Attributes : public BroObj {
|
||||
public:
|
||||
Attributes(attr_list* a, BroType* t);
|
||||
Attributes(attr_list* a, BroType* t, bool in_record);
|
||||
~Attributes();
|
||||
|
||||
void AddAttr(Attr* a);
|
||||
|
@ -87,6 +87,7 @@ protected:
|
|||
|
||||
BroType* type;
|
||||
attr_list* attrs;
|
||||
bool in_record;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3400,7 +3400,7 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
|||
SetError("values in table(...) constructor do not specify a table");
|
||||
}
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type) : 0;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
}
|
||||
|
||||
Val* TableConstructorExpr::Eval(Frame* f) const
|
||||
|
@ -3466,7 +3466,7 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
|||
else if ( type->Tag() != TYPE_TABLE || ! type->AsTableType()->IsSet() )
|
||||
SetError("values in set(...) constructor do not specify a set");
|
||||
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type) : 0;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||
}
|
||||
|
||||
Val* SetConstructorExpr::Eval(Frame* f) const
|
||||
|
|
|
@ -935,7 +935,7 @@ void NotifierRegistry::Register(ID* id, NotifierRegistry::Notifier* notifier)
|
|||
attr_list* a = new attr_list;
|
||||
Attr* attr = new Attr(ATTR_TRACKED);
|
||||
a->append(attr);
|
||||
id->SetAttrs(new Attributes(a, id->Type()));
|
||||
id->SetAttrs(new Attributes(a, id->Type(), false));
|
||||
Unref(attr);
|
||||
}
|
||||
|
||||
|
|
|
@ -680,10 +680,10 @@ bool FuncType::DoUnserialize(UnserialInfo* info)
|
|||
return UNSERIALIZE(&is_event);
|
||||
}
|
||||
|
||||
TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs)
|
||||
TypeDecl::TypeDecl(BroType* t, const char* i, attr_list* arg_attrs, bool in_record)
|
||||
{
|
||||
type = t;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, t) : 0;
|
||||
attrs = arg_attrs ? new Attributes(arg_attrs, t, in_record) : 0;
|
||||
id = i;
|
||||
}
|
||||
|
||||
|
|
|
@ -361,7 +361,7 @@ protected:
|
|||
|
||||
class TypeDecl {
|
||||
public:
|
||||
TypeDecl(BroType* t, const char* i, attr_list* attrs = 0);
|
||||
TypeDecl(BroType* t, const char* i, attr_list* attrs = 0, bool in_record = false);
|
||||
~TypeDecl();
|
||||
|
||||
const Attr* FindAttr(attr_tag a) const
|
||||
|
|
|
@ -107,7 +107,7 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
|||
id->SetType(t);
|
||||
|
||||
if ( attr )
|
||||
id->AddAttrs(new Attributes(attr, t));
|
||||
id->AddAttrs(new Attributes(attr, t, false));
|
||||
|
||||
if ( id->FindAttr(ATTR_PERSISTENT) || id->FindAttr(ATTR_SYNCHRONIZED) )
|
||||
{
|
||||
|
@ -221,7 +221,7 @@ void add_type(ID* id, BroType* t, attr_list* attr, int /* is_event */)
|
|||
id->MakeType();
|
||||
|
||||
if ( attr )
|
||||
id->SetAttrs(new Attributes(attr, t));
|
||||
id->SetAttrs(new Attributes(attr, t, false));
|
||||
}
|
||||
|
||||
void begin_func(ID* id, const char* module_name, function_flavor flavor,
|
||||
|
|
|
@ -100,6 +100,7 @@ extern Expr* g_curr_debug_expr;
|
|||
|
||||
Expr* bro_this = 0;
|
||||
int in_init = 0;
|
||||
int in_record = 0;
|
||||
bool in_debug = false;
|
||||
bool resolving_global_ID = false;
|
||||
|
||||
|
@ -704,10 +705,10 @@ type:
|
|||
$$ = new SetType($3, 0);
|
||||
}
|
||||
|
||||
| TOK_RECORD '{' type_decl_list '}'
|
||||
| TOK_RECORD '{' { ++in_record; } type_decl_list { --in_record; } '}'
|
||||
{
|
||||
set_location(@1, @4);
|
||||
$$ = new RecordType($3);
|
||||
set_location(@1, @5);
|
||||
$$ = new RecordType($4);
|
||||
}
|
||||
|
||||
| TOK_UNION '{' type_list '}'
|
||||
|
@ -805,7 +806,7 @@ type_decl:
|
|||
TOK_ID ':' type opt_attr ';'
|
||||
{
|
||||
set_location(@1, @5);
|
||||
$$ = new TypeDecl($3, $1, $4);
|
||||
$$ = new TypeDecl($3, $1, $4, (in_record > 0));
|
||||
}
|
||||
;
|
||||
|
||||
|
|
14
testing/btest/Baseline/language.rec-table-default/output
Normal file
14
testing/btest/Baseline/language.rec-table-default/output
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
[foo] = T
|
||||
}
|
||||
{
|
||||
|
||||
}
|
||||
{
|
||||
A,
|
||||
B,
|
||||
C
|
||||
}
|
||||
{
|
||||
|
||||
}
|
19
testing/btest/language/rec-table-default.bro
Normal file
19
testing/btest/language/rec-table-default.bro
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
# @TEST-EXEC: bro %INPUT >output 2>&1
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
type X: record {
|
||||
a: table[string] of bool &default=table( ["foo"] = T );
|
||||
b: table[string] of bool &default=table();
|
||||
c: set[string] &default=set("A", "B", "C");
|
||||
d: set[string] &default=set();
|
||||
};
|
||||
|
||||
global x: X;
|
||||
global y: table[string] of bool &default=T;
|
||||
|
||||
print x$a;
|
||||
print x$b;
|
||||
print x$c;
|
||||
print x$d;
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue