zeek/src/Obj.cc

264 lines
5.2 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#include "config.h"
#include <stdlib.h>
#include "Obj.h"
#include "Serializer.h"
#include "File.h"
#include "plugin/Manager.h"
Location no_location("<no location>", 0, 0, 0, 0);
Location start_location("<start uninitialized>", 0, 0, 0, 0);
Location end_location("<end uninitialized>", 0, 0, 0, 0);
bool Location::Serialize(SerialInfo* info) const
{
return SerialObj::Serialize(info);
}
Location* Location::Unserialize(UnserialInfo* info)
{
return (Location*) SerialObj::Unserialize(info, SER_LOCATION);
}
IMPLEMENT_SERIAL(Location, SER_LOCATION);
bool Location::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_LOCATION, SerialObj);
info->s->WriteOpenTag("Location");
if ( ! (SERIALIZE(filename) &&
SERIALIZE(first_line) &&
SERIALIZE(last_line) &&
SERIALIZE(first_column) &&
SERIALIZE(last_column)) )
return false;
info->s->WriteCloseTag("Location");
return true;
}
bool Location::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(SerialObj);
delete_data = true;
return UNSERIALIZE_STR(&filename, 0)
&& UNSERIALIZE(&first_line)
&& UNSERIALIZE(&last_line)
&& UNSERIALIZE(&first_column)
&& UNSERIALIZE(&last_column);
}
void Location::Describe(ODesc* d) const
{
if ( filename )
{
d->Add(filename);
if ( first_line == 0 )
return;
d->AddSP(",");
}
if ( last_line != first_line )
{
d->Add("lines ");
d->Add(first_line);
d->Add("-");
d->Add(last_line);
}
else
{
d->Add("line ");
d->Add(first_line);
}
}
bool Location::operator==(const Location& l) const
{
if ( filename == l.filename ||
(filename && l.filename && streq(filename, l.filename)) )
return first_line == l.first_line && last_line == l.last_line;
else
return false;
}
int BroObj::suppress_errors = 0;
BroObj::~BroObj()
{
if ( notify_plugins )
PLUGIN_HOOK_VOID(HOOK_BRO_OBJ_DTOR, HookBroObjDtor(this));
delete location;
}
void BroObj::Warn(const char* msg, const BroObj* obj2, int pinpoint_only) const
{
ODesc d;
DoMsg(&d, msg, obj2, pinpoint_only);
reporter->Warning("%s", d.Description());
reporter->PopLocation();
}
void BroObj::Error(const char* msg, const BroObj* obj2, int pinpoint_only) const
{
if ( suppress_errors )
return;
ODesc d;
DoMsg(&d, msg, obj2, pinpoint_only);
reporter->Error("%s", d.Description());
reporter->PopLocation();
}
void BroObj::BadTag(const char* msg, const char* t1, const char* t2) const
{
char out[512];
if ( t2 )
snprintf(out, sizeof(out), "%s (%s/%s)", msg, t1, t2);
else if ( t1 )
snprintf(out, sizeof(out), "%s (%s)", msg, t1);
else
snprintf(out, sizeof(out), "%s", msg);
ODesc d;
DoMsg(&d, out);
reporter->FatalError("%s", d.Description());
reporter->PopLocation();
}
void BroObj::Internal(const char* msg) const
{
ODesc d;
DoMsg(&d, msg);
reporter->InternalError("%s", d.Description());
reporter->PopLocation();
}
void BroObj::InternalWarning(const char* msg) const
{
ODesc d;
DoMsg(&d, msg);
reporter->InternalWarning("%s", d.Description());
reporter->PopLocation();
}
void BroObj::AddLocation(ODesc* d) const
{
if ( ! location )
{
d->Add("<no location>");
return;
}
location->Describe(d);
}
bool BroObj::SetLocationInfo(const Location* start, const Location* end)
{
if ( ! start || ! end )
return false;
if ( end->filename && ! streq(start->filename, end->filename) )
return false;
if ( location && (start == &no_location || end == &no_location) )
// We already have a better location, so don't use this one.
return true;
delete location;
location = new Location(start->filename,
start->first_line, end->last_line,
start->first_column, end->last_column);
return true;
}
void BroObj::UpdateLocationEndInfo(const Location& end)
{
if ( ! location )
SetLocationInfo(&end, &end);
location->last_line = end.last_line;
location->last_column = end.last_column;
}
void BroObj::DoMsg(ODesc* d, const char s1[], const BroObj* obj2,
int pinpoint_only) const
{
d->SetShort();
d->Add(s1);
PinPoint(d, obj2, pinpoint_only);
const Location* loc2 = 0;
if ( obj2 && obj2->GetLocationInfo() != &no_location &&
*obj2->GetLocationInfo() != *GetLocationInfo() )
loc2 = obj2->GetLocationInfo();
reporter->PushLocation(GetLocationInfo(), loc2);
}
void BroObj::PinPoint(ODesc* d, const BroObj* obj2, int pinpoint_only) const
{
d->Add(" (");
Describe(d);
if ( obj2 && ! pinpoint_only )
{
d->Add(" and ");
obj2->Describe(d);
}
d->Add(")");
}
bool BroObj::DoSerialize(SerialInfo* info) const
{
DO_SERIALIZE(SER_BRO_OBJ, SerialObj);
info->s->WriteOpenTag("Object");
Location* loc = info->include_locations ? location : 0;
SERIALIZE_OPTIONAL(loc);
info->s->WriteCloseTag("Object");
return true;
}
bool BroObj::DoUnserialize(UnserialInfo* info)
{
DO_UNSERIALIZE(SerialObj);
delete location;
UNSERIALIZE_OPTIONAL(location, Location::Unserialize(info));
return true;
}
void print(const BroObj* obj)
{
static BroFile fstderr(stderr);
ODesc d(DESC_READABLE, &fstderr);
obj->Describe(&d);
d.Add("\n");
}
void bad_ref(int type)
{
reporter->InternalError("bad reference count [%d]", type);
abort();
}
void bro_obj_delete_func(void* v)
{
Unref((BroObj*) v);
}