Merge remote-tracking branch 'origin/topic/johanna/bit-1976'

* origin/topic/johanna/bit-1976:
  Allow event/function definitions to be wrapped in directives.

Fixed to work with attributes (e.g. &priority).
This commit is contained in:
Jon Siwek 2018-08-29 18:21:37 -05:00
commit 611c00a605
10 changed files with 126 additions and 37 deletions

13
CHANGES
View file

@ -1,4 +1,17 @@
2.5-924 | 2018-08-29 18:21:37 -0500
* Allow event/function headers to be wrapped in directives. (Johanna Amann)
For example:
@if ( conditions )
event a(...)
@else
event b(...)
@endif
{ ... }
2.5-922 | 2018-08-29 17:22:20 -0500
* Fix unit tests (Jon Siwek, Corelight)

View file

@ -1 +1 @@
2.5-922
2.5-924

View file

@ -11,9 +11,10 @@ static scope_list scopes;
static Scope* top_scope;
Scope::Scope(ID* id)
Scope::Scope(ID* id, attr_list* al)
{
scope_id = id;
attrs = al;
return_type = 0;
local = new PDict(ID)(ORDERED);
@ -42,6 +43,14 @@ Scope::~Scope()
for ( int i = 0; i < local->Length(); ++i )
Unref(local->NthEntry(i));
if ( attrs )
{
loop_over_list(*attrs, i)
Unref((*attrs)[i]);
delete attrs;
}
Unref(scope_id);
Unref(return_type);
delete local;
@ -186,9 +195,9 @@ void push_existing_scope(Scope* scope)
scopes.append(scope);
}
void push_scope(ID* id)
void push_scope(ID* id, attr_list* attrs)
{
top_scope = new Scope(id);
top_scope = new Scope(id, attrs);
scopes.append(top_scope);
}

View file

@ -19,7 +19,7 @@ declare(PDict,ID);
class Scope : public BroObj {
public:
explicit Scope(ID* id);
explicit Scope(ID* id, attr_list* al);
~Scope() override;
ID* Lookup(const char* name) const { return local->Lookup(name); }
@ -31,6 +31,7 @@ public:
}
ID* ScopeID() const { return scope_id; }
attr_list* Attrs() const { return attrs; }
BroType* ReturnType() const { return return_type; }
int Length() const { return local->Length(); }
@ -53,6 +54,7 @@ public:
protected:
ID* scope_id;
attr_list* attrs;
BroType* return_type;
PDict(ID)* local;
id_list* inits;
@ -69,7 +71,7 @@ extern ID* lookup_ID(const char* name, const char* module,
extern ID* install_ID(const char* name, const char* module_name,
bool is_global, bool is_export);
extern void push_scope(ID* id);
extern void push_scope(ID* id, attr_list* attrs);
extern void push_existing_scope(Scope* scope);
// Returns the one popped off; it's not deleted.

View file

@ -328,8 +328,20 @@ static void transfer_arg_defaults(RecordType* args, RecordType* recv)
}
}
static bool has_attr(const attr_list* al, attr_tag tag)
{
if ( ! al )
return false;
for ( int i = 0; i < al->length(); ++i )
if ( (*al)[i]->Tag() == tag )
return true;
return false;
}
void begin_func(ID* id, const char* module_name, function_flavor flavor,
int is_redef, FuncType* t)
int is_redef, FuncType* t, attr_list* attrs)
{
if ( flavor == FUNC_FLAVOR_EVENT )
{
@ -384,7 +396,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
else
id->SetType(t);
push_scope(id);
push_scope(id, attrs);
RecordType* args = t->Args();
int num_args = args->NumFields();
@ -401,6 +413,9 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
arg_id = install_ID(arg_i->id, module_name, false, false);
arg_id->SetType(arg_i->type->Ref());
}
if ( has_attr(attrs, ATTR_DEPRECATED) )
id->MakeDeprecated();
}
class OuterIDBindingFinder : public TraversalCallback {
@ -431,7 +446,7 @@ TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr)
return TC_CONTINUE;
}
void end_func(Stmt* body, attr_list* attrs)
void end_func(Stmt* body)
{
int frame_size = current_scope()->Length();
id_list* inits = current_scope()->GetInits();
@ -440,6 +455,8 @@ void end_func(Stmt* body, attr_list* attrs)
ID* id = scope->ScopeID();
int priority = 0;
auto attrs = scope->Attrs();
if ( attrs )
{
loop_over_list(*attrs, i)

View file

@ -21,8 +21,8 @@ extern Expr* add_and_assign_local(ID* id, Expr* init, Val* val = 0);
extern void add_type(ID* id, BroType* t, attr_list* attr);
extern void begin_func(ID* id, const char* module_name, function_flavor flavor,
int is_redef, FuncType* t);
extern void end_func(Stmt* body, attr_list* attrs = 0);
int is_redef, FuncType* t, attr_list* attrs = nullptr);
extern void end_func(Stmt* body);
extern Val* internal_val(const char* name);
extern Val* internal_const_val(const char* name); // internal error if not const

View file

@ -848,7 +848,7 @@ int main(int argc, char** argv)
add_input_file(argv[optind++]);
}
push_scope(0);
push_scope(nullptr, nullptr);
dns_mgr = new DNS_Mgr(dns_type);

View file

@ -234,18 +234,6 @@ static bool expr_is_table_type_name(const Expr* expr)
return false;
}
static bool has_attr(const attr_list* al, attr_tag tag)
{
if ( ! al )
return false;
for ( int i = 0; i < al->length(); ++i )
if ( (*al)[i]->Tag() == tag )
return true;
return false;
}
%}
%union {
@ -1142,9 +1130,16 @@ decl:
| func_hdr func_body
{ }
| func_hdr conditional_list func_body
{ }
| conditional
;
conditional_list:
conditional
| conditional conditional_list
conditional:
TOK_ATIF '(' expr ')'
{ do_atif($3); }
@ -1159,43 +1154,40 @@ conditional:
;
func_hdr:
TOK_FUNCTION def_global_id func_params
TOK_FUNCTION def_global_id func_params opt_attr
{
begin_func($2, current_module.c_str(),
FUNC_FLAVOR_FUNCTION, 0, $3);
FUNC_FLAVOR_FUNCTION, 0, $3, $4);
$$ = $3;
broxygen_mgr->Identifier($2);
}
| TOK_EVENT event_id func_params
| TOK_EVENT event_id func_params opt_attr
{
begin_func($2, current_module.c_str(),
FUNC_FLAVOR_EVENT, 0, $3);
FUNC_FLAVOR_EVENT, 0, $3, $4);
$$ = $3;
}
| TOK_HOOK def_global_id func_params
| TOK_HOOK def_global_id func_params opt_attr
{
$3->ClearYieldType(FUNC_FLAVOR_HOOK);
$3->SetYieldType(base_type(TYPE_BOOL));
begin_func($2, current_module.c_str(),
FUNC_FLAVOR_HOOK, 0, $3);
FUNC_FLAVOR_HOOK, 0, $3, $4);
$$ = $3;
}
| TOK_REDEF TOK_EVENT event_id func_params
| TOK_REDEF TOK_EVENT event_id func_params opt_attr
{
begin_func($3, current_module.c_str(),
FUNC_FLAVOR_EVENT, 1, $4);
FUNC_FLAVOR_EVENT, 1, $4, $5);
$$ = $4;
}
;
func_body:
opt_attr '{'
'{'
{
saved_in_init.push_back(in_init);
in_init = 0;
if ( has_attr($1, ATTR_DEPRECATED) )
current_scope()->ScopeID()->MakeDeprecated();
}
stmt_list
@ -1206,7 +1198,7 @@ func_body:
'}'
{
end_func($4, $1);
end_func($3);
}
;

View file

@ -0,0 +1,5 @@
0
1
2
3
4

View file

@ -0,0 +1,51 @@
# @TEST-EXEC: bro -b %INPUT >out
# @TEST-EXEC: btest-diff out
# Check if @if can be used to alternative function/event definitions
@if ( 1==1 )
function test_case(msg: string)
@else
lalala
@endif
{
print msg;
}
@if ( 1==1 )
event bro_init()
@else
lalala
@endif
{
print "1";
test_case("2");
}
@if ( 1==0 )
lalala
@else
event bro_init()
@endif
{
print "3";
}
@if ( 1==1 )
@if ( 1==1 )
event bro_init()
@endif
@else
lalala
@endif
{
print "4";
}
@if ( 1==1 )
event bro_init() &priority=10
@else
lalala
@endif
{
print "0";
}