mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
193 lines
4.9 KiB
C++
193 lines
4.9 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include "zeek/Obj.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "zeek/Desc.h"
|
|
#include "zeek/File.h"
|
|
#include "zeek/Func.h"
|
|
#include "zeek/plugin/Manager.h"
|
|
|
|
namespace zeek {
|
|
namespace detail {
|
|
|
|
Location start_location("<start uninitialized>", 0, 0);
|
|
Location end_location("<end uninitialized>", 0, 0);
|
|
|
|
void Location::Describe(ODesc* d) const {
|
|
if ( FileName() ) {
|
|
d->Add(FileName());
|
|
|
|
if ( FirstLine() == 0 )
|
|
return;
|
|
|
|
d->AddSP(",");
|
|
}
|
|
|
|
if ( LastLine() != FirstLine() ) {
|
|
if ( LastLine() < FirstLine() )
|
|
reporter->InternalError("Location::Describe: %s inconsistent: last_line %d < first_line %d", FileName(),
|
|
LastLine(), FirstLine());
|
|
|
|
d->Add("lines ");
|
|
d->Add(FirstLine());
|
|
d->Add("-");
|
|
d->Add(LastLine());
|
|
}
|
|
else {
|
|
d->Add("line ");
|
|
d->Add(FirstLine());
|
|
}
|
|
}
|
|
|
|
bool Location::operator==(const Location& l) const {
|
|
if ( FileName() == l.FileName() || (FileName() && l.FileName() && util::streq(FileName(), l.FileName())) )
|
|
return FirstLine() == l.FirstLine() && LastLine() == l.LastLine();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
} // namespace detail
|
|
|
|
int Obj::suppress_errors = 0;
|
|
|
|
Obj::~Obj() {
|
|
if ( notify_plugins )
|
|
PLUGIN_HOOK_VOID(HOOK_OBJ_DTOR, HookObjDtor(this));
|
|
|
|
delete location;
|
|
}
|
|
|
|
void Obj::Warn(const char* msg, const Obj* obj2, bool pinpoint_only, const detail::Location* expr_location) const {
|
|
ODesc d;
|
|
DoMsg(&d, msg, obj2, pinpoint_only, expr_location);
|
|
reporter->Warning("%s", d.Description());
|
|
reporter->PopLocation();
|
|
}
|
|
|
|
void Obj::Error(const char* msg, const Obj* obj2, bool pinpoint_only, const detail::Location* expr_location) const {
|
|
if ( suppress_errors )
|
|
return;
|
|
|
|
ODesc d;
|
|
DoMsg(&d, msg, obj2, pinpoint_only, expr_location);
|
|
reporter->Error("%s", d.Description());
|
|
reporter->PopLocation();
|
|
}
|
|
|
|
void Obj::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->FatalErrorWithCore("%s", d.Description());
|
|
reporter->PopLocation();
|
|
}
|
|
|
|
void Obj::Internal(const char* msg) const {
|
|
ODesc d;
|
|
DoMsg(&d, msg);
|
|
auto rcs = render_call_stack();
|
|
|
|
if ( rcs.empty() )
|
|
reporter->InternalError("%s", d.Description());
|
|
else
|
|
reporter->InternalError("%s, call stack: %s", d.Description(), rcs.data());
|
|
|
|
reporter->PopLocation();
|
|
}
|
|
|
|
void Obj::InternalWarning(const char* msg) const {
|
|
ODesc d;
|
|
DoMsg(&d, msg);
|
|
reporter->InternalWarning("%s", d.Description());
|
|
reporter->PopLocation();
|
|
}
|
|
|
|
void Obj::AddLocation(ODesc* d) const {
|
|
if ( ! location ) {
|
|
d->Add("<no location>");
|
|
return;
|
|
}
|
|
|
|
location->Describe(d);
|
|
}
|
|
|
|
bool Obj::SetLocationInfo(const detail::Location* start, const detail::Location* end) {
|
|
if ( ! start || ! end )
|
|
return false;
|
|
|
|
if ( end->FileName() && ! util::streq(start->FileName(), end->FileName()) )
|
|
return false;
|
|
|
|
if ( location && (start == &detail::no_location || end == &detail::no_location) )
|
|
// We already have a better location, so don't use this one.
|
|
return true;
|
|
|
|
auto new_location = new detail::Location(start->FileName(), start->FirstLine(), end->LastLine());
|
|
|
|
// Don't delete this until we've constructed the new location, in case
|
|
// "start" or "end" are our own location.
|
|
delete location;
|
|
location = new_location;
|
|
|
|
return true;
|
|
}
|
|
|
|
void Obj::UpdateLocationEndInfo(const detail::Location& end) {
|
|
if ( ! location )
|
|
SetLocationInfo(&end, &end);
|
|
|
|
location->SetLastLine(end.LastLine());
|
|
}
|
|
|
|
void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, bool pinpoint_only,
|
|
const detail::Location* expr_location) const {
|
|
d->SetShort();
|
|
|
|
d->Add(s1);
|
|
PinPoint(d, obj2, pinpoint_only);
|
|
|
|
const detail::Location* loc2 = nullptr;
|
|
if ( obj2 && obj2->GetLocationInfo() != &detail::no_location && *obj2->GetLocationInfo() != *GetLocationInfo() )
|
|
loc2 = obj2->GetLocationInfo();
|
|
else if ( expr_location )
|
|
loc2 = expr_location;
|
|
|
|
reporter->PushLocation(GetLocationInfo(), loc2);
|
|
}
|
|
|
|
void Obj::PinPoint(ODesc* d, const Obj* obj2, bool pinpoint_only) const {
|
|
d->Add(" (");
|
|
Describe(d);
|
|
if ( obj2 && ! pinpoint_only ) {
|
|
d->Add(" and ");
|
|
obj2->Describe(d);
|
|
}
|
|
|
|
d->Add(")");
|
|
}
|
|
|
|
void Obj::Print() const {
|
|
static File fstderr(stderr);
|
|
ODesc d(DESC_READABLE, &fstderr);
|
|
Describe(&d);
|
|
d.Add("\n");
|
|
}
|
|
|
|
void bad_ref(int type) {
|
|
reporter->InternalError("bad reference count [%d]", type);
|
|
abort();
|
|
}
|
|
|
|
void obj_delete_func(void* v) { Unref((Obj*)v); }
|
|
|
|
} // namespace zeek
|