mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
factoring to make checking of &default attributes externally accessible
This commit is contained in:
parent
18fe9d84f6
commit
ffdcc36bd5
2 changed files with 125 additions and 109 deletions
223
src/Attr.cc
223
src/Attr.cc
|
@ -344,116 +344,12 @@ void Attributes::CheckAttr(Attr* a)
|
||||||
|
|
||||||
case ATTR_DEFAULT:
|
case ATTR_DEFAULT:
|
||||||
{
|
{
|
||||||
// &default is allowed for global tables, since it's used in initialization
|
std::string err_msg;
|
||||||
// of table fields. it's not allowed otherwise.
|
if ( ! check_default_attr(a, type, global_var, in_record, err_msg) &&
|
||||||
if ( global_var && ! type->IsTable() )
|
! err_msg.empty() )
|
||||||
{
|
Error(err_msg.c_str());
|
||||||
Error("&default is not valid for global variables except for tables");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& atype = a->GetExpr()->GetType();
|
|
||||||
|
|
||||||
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
|
|
||||||
{
|
|
||||||
if ( same_type(atype, type) )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Record defaults may be promotable.
|
|
||||||
if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
|
||||||
record_promotion_compatible(atype->AsRecordType(), type->AsRecordType())) )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto e = check_and_promote_expr(a->GetExpr(), type);
|
|
||||||
|
|
||||||
if ( e )
|
|
||||||
{
|
|
||||||
a->SetAttrExpr(std::move(e));
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
a->GetExpr()->Error("&default value has inconsistent type", type.get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TableType* tt = type->AsTableType();
|
|
||||||
const auto& ytype = tt->Yield();
|
|
||||||
|
|
||||||
if ( ! in_record )
|
|
||||||
{
|
|
||||||
// &default applies to the type itself.
|
|
||||||
if ( ! same_type(atype, ytype) )
|
|
||||||
{
|
|
||||||
// It can still be a default function.
|
|
||||||
if ( atype->Tag() == TYPE_FUNC )
|
|
||||||
{
|
|
||||||
FuncType* f = atype->AsFuncType();
|
|
||||||
if ( ! f->CheckArgs(tt->GetIndexTypes()) || ! same_type(f->Yield(), ytype) )
|
|
||||||
Error("&default function type clash");
|
|
||||||
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table defaults may be promotable.
|
|
||||||
if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
|
||||||
record_promotion_compatible(atype->AsRecordType(),
|
|
||||||
ytype->AsRecordType())) )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto e = check_and_promote_expr(a->GetExpr(), ytype);
|
|
||||||
|
|
||||||
if ( e )
|
|
||||||
{
|
|
||||||
a->SetAttrExpr(std::move(e));
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error("&default value has inconsistent type 2");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// &default applies to record field.
|
|
||||||
|
|
||||||
if ( same_type(atype, type) )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
|
|
||||||
{
|
|
||||||
auto e = check_and_promote_expr(a->GetExpr(), type);
|
|
||||||
|
|
||||||
if ( e )
|
|
||||||
{
|
|
||||||
a->SetAttrExpr(std::move(e));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table defaults may be promotable.
|
|
||||||
if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
|
||||||
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
|
|
||||||
// Ok.
|
|
||||||
break;
|
|
||||||
|
|
||||||
Error("&default value has inconsistent type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ATTR_EXPIRE_READ:
|
case ATTR_EXPIRE_READ:
|
||||||
{
|
{
|
||||||
|
@ -751,4 +647,113 @@ bool Attributes::operator==(const Attributes& other) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool in_record,
|
||||||
|
std::string& err_msg)
|
||||||
|
{
|
||||||
|
// &default is allowed for global tables, since it's used in
|
||||||
|
// initialization of table fields. It's not allowed otherwise.
|
||||||
|
if ( global_var && ! type->IsTable() )
|
||||||
|
{
|
||||||
|
err_msg = "&default is not valid for global variables except for tables";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& atype = a->GetExpr()->GetType();
|
||||||
|
|
||||||
|
if ( type->Tag() != TYPE_TABLE || (type->IsSet() && ! in_record) )
|
||||||
|
{
|
||||||
|
if ( same_type(atype, type) )
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Record defaults may be promotable.
|
||||||
|
if ( (type->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
||||||
|
record_promotion_compatible(atype->AsRecordType(), type->AsRecordType())) )
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( type->Tag() == TYPE_TABLE && type->AsTableType()->IsUnspecifiedTable() )
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto e = check_and_promote_expr(a->GetExpr(), type);
|
||||||
|
|
||||||
|
if ( e )
|
||||||
|
{
|
||||||
|
a->SetAttrExpr(std::move(e));
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->GetExpr()->Error("&default value has inconsistent type", type.get());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TableType* tt = type->AsTableType();
|
||||||
|
const auto& ytype = tt->Yield();
|
||||||
|
|
||||||
|
if ( ! in_record )
|
||||||
|
{ // &default applies to the type itself.
|
||||||
|
if ( same_type(atype, ytype) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// It can still be a default function.
|
||||||
|
if ( atype->Tag() == TYPE_FUNC )
|
||||||
|
{
|
||||||
|
FuncType* f = atype->AsFuncType();
|
||||||
|
if ( ! f->CheckArgs(tt->GetIndexTypes()) || ! same_type(f->Yield(), ytype) )
|
||||||
|
{
|
||||||
|
err_msg = "&default function type clash";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table defaults may be promotable.
|
||||||
|
if ( (ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
||||||
|
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType())) )
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto e = check_and_promote_expr(a->GetExpr(), ytype);
|
||||||
|
|
||||||
|
if ( e )
|
||||||
|
{
|
||||||
|
a->SetAttrExpr(std::move(e));
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_msg = "&default value has inconsistent type";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// &default applies to record field.
|
||||||
|
|
||||||
|
if ( same_type(atype, type) )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( (atype->Tag() == TYPE_TABLE && atype->AsTableType()->IsUnspecifiedTable()) )
|
||||||
|
{
|
||||||
|
auto e = check_and_promote_expr(a->GetExpr(), type);
|
||||||
|
|
||||||
|
if ( e )
|
||||||
|
{
|
||||||
|
a->SetAttrExpr(std::move(e));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table defaults may be promotable.
|
||||||
|
if ( ytype && ytype->Tag() == TYPE_RECORD && atype->Tag() == TYPE_RECORD &&
|
||||||
|
record_promotion_compatible(atype->AsRecordType(), ytype->AsRecordType()) )
|
||||||
|
// Ok.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
err_msg = "&default value has inconsistent type";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
11
src/Attr.h
11
src/Attr.h
|
@ -139,5 +139,16 @@ protected:
|
||||||
bool global_var;
|
bool global_var;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Checks whether default attribute "a" is compatible with the given type.
|
||||||
|
// "global_var" specifies whether the attribute is being associated with
|
||||||
|
// a global variable, and "in_record" whether it's occurring inside of
|
||||||
|
// a record declaration.
|
||||||
|
//
|
||||||
|
// Returns true on compatibility (which might include modifying "a"), false
|
||||||
|
// on an error. If an error message hasn't been directly generated, then
|
||||||
|
// it will be returned in err_msg.
|
||||||
|
extern bool check_default_attr(Attr* a, const TypePtr& type, bool global_var, bool in_record,
|
||||||
|
std::string& err_msg);
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace zeek
|
} // namespace zeek
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue