Two small infrastructure extensions for passing information into the

logging framework.

- To enable passing a type into a bif, there's now a new
  BroType-derived class TypeType and a corresponding TYPE_TYPE tag.
  With that, a Val can now have a type as its value.

  This is experimental for now.

- RecordVal's get a new method CoerceTo() to coerce their value into a
  another record type with the usual semantics. Most of the code in
  there was previously in RecordContructorExpr::InitVal(), which is
  now calling the new CoerceTo() method.
This commit is contained in:
Robin Sommer 2011-02-18 13:01:34 -08:00
parent ffa494e428
commit 9d407d882c
5 changed files with 119 additions and 40 deletions

View file

@ -2892,6 +2892,62 @@ Val* RecordVal::Lookup(int field) const
return (*AsRecord())[field];
}
RecordVal* RecordVal::CoerceTo(const RecordType* t, Val* aggr) const
{
if ( ! record_promotion_compatible(t->AsRecordType(), Type()->AsRecordType()) )
return 0;
if ( ! aggr )
aggr = new RecordVal(const_cast<RecordType*>(t->AsRecordType()));
RecordVal* ar = aggr->AsRecordVal();
RecordType* ar_t = aggr->Type()->AsRecordType();
const RecordType* rv_t = Type()->AsRecordType();
int i;
for ( i = 0; i < rv_t->NumFields(); ++i )
{
int t_i = ar_t->FieldOffset(rv_t->FieldName(i));
if ( t_i < 0 )
{
char buf[512];
safe_snprintf(buf, sizeof(buf),
"orphan field \"%s\" in initialization",
rv_t->FieldName(i));
Error(buf);
break;
}
else
ar->Assign(t_i, Lookup(i)->Ref());
}
for ( i = 0; i < ar_t->NumFields(); ++i )
if ( ! ar->Lookup(i) &&
! ar_t->FieldDecl(i)->FindAttr(ATTR_OPTIONAL) )
{
char buf[512];
safe_snprintf(buf, sizeof(buf),
"non-optional field \"%s\" missing in initialization", ar_t->FieldName(i));
Error(buf);
}
return ar;
}
RecordVal* RecordVal::CoerceTo(RecordType* t)
{
if ( same_type(Type(), t) )
{
this->Ref();
return this;
}
return CoerceTo(t, 0);
}
void RecordVal::Describe(ODesc* d) const
{
const val_list* vl = AsRecord();