A number of smaller API extensions to provide plugins with access to

information.
This commit is contained in:
Robin Sommer 2014-05-29 12:48:36 -07:00
parent 79531a4538
commit d88b333353
13 changed files with 127 additions and 35 deletions

View file

@ -71,6 +71,23 @@ EventRegistry::string_list* EventRegistry::UsedHandlers()
return names;
}
EventRegistry::string_list* EventRegistry::AllHandlers()
{
string_list* names = new string_list;
IterCookie* c = handlers.InitForIteration();
HashKey* k;
EventHandler* v;
while ( (v = handlers.NextEntry(k, c)) )
{
names->append(v->Name());
delete k;
}
return names;
}
void EventRegistry::PrintDebug()
{
IterCookie* c = handlers.InitForIteration();

View file

@ -33,6 +33,8 @@ public:
string_list* UnusedHandlers();
string_list* UsedHandlers();
string_list* AllHandlers();
void PrintDebug();
private:

View file

@ -608,6 +608,10 @@ public:
CondExpr(Expr* op1, Expr* op2, Expr* op3);
~CondExpr();
const Expr* Op1() const { return op1; }
const Expr* Op2() const { return op2; }
const Expr* Op3() const { return op3; }
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
int IsPure() const;
@ -706,6 +710,7 @@ public:
~FieldExpr();
int Field() const { return field; }
const char* FieldName() const { return field_name; }
int CanDel() const;
@ -737,6 +742,8 @@ public:
HasFieldExpr(Expr* op, const char* field_name);
~HasFieldExpr();
const char* FieldName() const { return field_name; }
protected:
friend class Expr;
HasFieldExpr() { field_name = 0; }

View file

@ -52,6 +52,7 @@ public:
Kind GetKind() const { return kind; }
const char* Name() const { return name.c_str(); }
void SetName(const char* arg_name) { name = arg_name; }
virtual void Describe(ODesc* d) const = 0;
virtual void DescribeDebug(ODesc* d, const val_list* args) const;

View file

@ -1403,6 +1403,23 @@ bool OpaqueType::DoUnserialize(UnserialInfo* info)
return true;
}
EnumType::EnumType(const string& name)
: BroType(TYPE_ENUM)
{
counter = 0;
SetName(name);
}
EnumType::EnumType(EnumType* e)
: BroType(TYPE_ENUM)
{
counter = e->counter;
SetName(e->GetName());
for ( NameMap::iterator it = e->names.begin(); it != e->names.end(); ++it )
names[copy_string(it->first)] = it->second;
}
EnumType::~EnumType()
{
for ( NameMap::iterator iter = names.begin(); iter != names.end(); ++iter )
@ -1769,7 +1786,7 @@ static int is_init_compat(const BroType* t1, const BroType* t2)
return 0;
}
int same_type(const BroType* t1, const BroType* t2, int is_init)
int same_type(const BroType* t1, const BroType* t2, int is_init, bool match_record_field_names)
{
if ( t1 == t2 ||
t1->Tag() == TYPE_ANY ||
@ -1825,7 +1842,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
if ( tl1 || tl2 )
{
if ( ! tl1 || ! tl2 || ! same_type(tl1, tl2, is_init) )
if ( ! tl1 || ! tl2 || ! same_type(tl1, tl2, is_init, match_record_field_names) )
return 0;
}
@ -1834,7 +1851,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
if ( y1 || y2 )
{
if ( ! y1 || ! y2 || ! same_type(y1, y2, is_init) )
if ( ! y1 || ! y2 || ! same_type(y1, y2, is_init, match_record_field_names) )
return 0;
}
@ -1852,7 +1869,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
if ( t1->YieldType() || t2->YieldType() )
{
if ( ! t1->YieldType() || ! t2->YieldType() ||
! same_type(t1->YieldType(), t2->YieldType(), is_init) )
! same_type(t1->YieldType(), t2->YieldType(), is_init, match_record_field_names) )
return 0;
}
@ -1872,8 +1889,8 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
const TypeDecl* td1 = rt1->FieldDecl(i);
const TypeDecl* td2 = rt2->FieldDecl(i);
if ( ! streq(td1->id, td2->id) ||
! same_type(td1->type, td2->type, is_init) )
if ( (match_record_field_names && ! streq(td1->id, td2->id)) ||
! same_type(td1->type, td2->type, is_init, match_record_field_names) )
return 0;
}
@ -1889,7 +1906,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
return 0;
loop_over_list(*tl1, i)
if ( ! same_type((*tl1)[i], (*tl2)[i], is_init) )
if ( ! same_type((*tl1)[i], (*tl2)[i], is_init, match_record_field_names) )
return 0;
return 1;
@ -1897,7 +1914,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
case TYPE_VECTOR:
case TYPE_FILE:
return same_type(t1->YieldType(), t2->YieldType(), is_init);
return same_type(t1->YieldType(), t2->YieldType(), is_init, match_record_field_names);
case TYPE_OPAQUE:
{
@ -1907,7 +1924,7 @@ int same_type(const BroType* t1, const BroType* t2, int is_init)
}
case TYPE_TYPE:
return same_type(t1, t2, is_init);
return same_type(t1, t2, is_init, match_record_field_names);
case TYPE_UNION:
reporter->Error("union type in same_type()");

View file

@ -547,7 +547,8 @@ class EnumType : public BroType {
public:
typedef std::list<std::pair<string, bro_int_t> > enum_name_list;
EnumType() : BroType(TYPE_ENUM) { counter = 0; }
EnumType(EnumType* e);
EnumType(const string& arg_name);
~EnumType();
// The value of this name is next internal counter value, starting
@ -570,6 +571,8 @@ public:
void DescribeReST(ODesc* d, bool roles_only = false) const;
protected:
EnumType() { counter = 0; }
DECLARE_SERIAL(EnumType)
void AddNameInternal(const string& module_name,
@ -628,9 +631,10 @@ extern BroType* base_type(TypeTag tag);
// Returns the BRO basic error type.
inline BroType* error_type() { return base_type(TYPE_ERROR); }
// True if the two types are equivalent. If is_init is true then the
// test is done in the context of an initialization.
extern int same_type(const BroType* t1, const BroType* t2, int is_init=0);
// True if the two types are equivalent. If is_init is true then the test is
// done in the context of an initialization. If match_record_field_names is
// true then for record types the field names have to match, too.
extern int same_type(const BroType* t1, const BroType* t2, int is_init=0, bool match_record_field_names=true);
// True if the two attribute lists are equivalent.
extern int same_attrs(const Attributes* a1, const Attributes* a2);

View file

@ -127,7 +127,7 @@ static void parser_new_enum (void)
{
/* Starting a new enum definition. */
assert(cur_enum_type == NULL);
cur_enum_type = new EnumType();
cur_enum_type = new EnumType(cur_decl_type_id->Name());
}
static void parser_redef_enum (ID *id)

View file

@ -129,7 +129,7 @@ template <class T, class C>
ComponentManager<T, C>::ComponentManager(const string& arg_module)
: module(arg_module)
{
tag_enum_type = new EnumType();
tag_enum_type = new EnumType(module + "::Tag");
::ID* id = install_ID("Tag", module.c_str(), true, true);
add_type(id, tag_enum_type, 0);
broxygen_mgr->Identifier(id);

View file

@ -416,8 +416,17 @@ void Manager::EnableHook(HookType hook, Plugin* plugin, int prio)
if ( ! hooks[hook] )
hooks[hook] = new hook_list;
hooks[hook]->push_back(std::make_pair(prio, plugin));
hooks[hook]->sort(hook_cmp);
hook_list* l = hooks[hook];
for ( hook_list::iterator i = l->begin(); i != l->end(); i++ )
{
// Already enabled for this plugin.
if ( (*i).second == plugin )
return;
}
l->push_back(std::make_pair(prio, plugin));
l->sort(hook_cmp);
}
void Manager::DisableHook(HookType hook, Plugin* plugin)
@ -445,8 +454,9 @@ void Manager::DisableHook(HookType hook, Plugin* plugin)
void Manager::RequestEvent(EventHandlerPtr handler, Plugin* plugin)
{
DBG_LOG(DBG_PLUGINS, "Plugin %s requested event %s", Name(), handler->Name());
handler->GenerateAlways();
DBG_LOG(DBG_PLUGINS, "Plugin %s requested event %s",
plugin->Name().c_str(), handler->Name());
handler->SetGenerateAlways();
}
void Manager::RequestBroObjDtor(BroObj* obj, Plugin* plugin)
@ -465,13 +475,27 @@ int Manager::HookLoadFile(const string& file)
hook_list* l = hooks[HOOK_LOAD_FILE];
size_t i = file.find_last_of("./");
string ext;
string normalized_file = file;
if ( i != string::npos && file[i] == '.' )
ext = file.substr(i + 1);
else
{
// Add .bro as default extension.
normalized_file = file + ".bro";
ext = "bro";
}
int rc = -1;
for ( hook_list::iterator i = l->begin(); l && i != l->end(); i++ )
{
Plugin* p = (*i).second;
int rc = p->HookLoadFile(file);
rc = p->HookLoadFile(normalized_file, ext);
if ( rc >= 0 )
break;

View file

@ -79,7 +79,7 @@ void HookArgument::Describe(ODesc* d) const
break;
case EVENT:
if ( arg.event )
if ( arg.event )
{
d->Add(arg.event->Handler()->Name());
d->Add("(");
@ -106,7 +106,7 @@ void HookArgument::Describe(ODesc* d) const
break;
case VAL:
if ( arg.val )
if ( arg.val )
arg.val->Describe(d);
else
@ -284,7 +284,7 @@ void Plugin::RequestBroObjDtor(BroObj* obj)
plugin_mgr->RequestBroObjDtor(obj, this);
}
int Plugin::HookLoadFile(const std::string& file)
int Plugin::HookLoadFile(const std::string& file, const std::string& ext)
{
return -1;
}
@ -410,7 +410,7 @@ void Plugin::Describe(ODesc* d) const
d->Add(hook_name(hook));
d->Add(" (priority ");
d->Add(prio);
d->Add("]\n");
d->Add(")\n");
}
}

View file

@ -440,6 +440,11 @@ protected:
* is about to load, either given on the command line or via @load
* script directives. The hook can take over the file, in which case
* Bro not further process it otherwise.
*
* @param file The filename to be loaded.
*
* @param ext The extension of the filename. This is provided separately
* just for convenience. The dot is excluded.
*
* @return 1 if the plugin took over the file and loaded it
* successfully; 0 if the plugin took over the file but had trouble
@ -447,7 +452,7 @@ protected:
* printed an error message); and -1 if the plugin wasn't interested
* in the file at all.
*/
virtual int HookLoadFile(const std::string& file);
virtual int HookLoadFile(const std::string& file, const std::string& ext);
/**
* Hook into executing a script-level function/event/hook. Whenever