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 2.5-922 | 2018-08-29 17:22:20 -0500
* Fix unit tests (Jon Siwek, Corelight) * 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; static Scope* top_scope;
Scope::Scope(ID* id) Scope::Scope(ID* id, attr_list* al)
{ {
scope_id = id; scope_id = id;
attrs = al;
return_type = 0; return_type = 0;
local = new PDict(ID)(ORDERED); local = new PDict(ID)(ORDERED);
@ -42,6 +43,14 @@ Scope::~Scope()
for ( int i = 0; i < local->Length(); ++i ) for ( int i = 0; i < local->Length(); ++i )
Unref(local->NthEntry(i)); Unref(local->NthEntry(i));
if ( attrs )
{
loop_over_list(*attrs, i)
Unref((*attrs)[i]);
delete attrs;
}
Unref(scope_id); Unref(scope_id);
Unref(return_type); Unref(return_type);
delete local; delete local;
@ -186,9 +195,9 @@ void push_existing_scope(Scope* scope)
scopes.append(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); scopes.append(top_scope);
} }

View file

@ -19,7 +19,7 @@ declare(PDict,ID);
class Scope : public BroObj { class Scope : public BroObj {
public: public:
explicit Scope(ID* id); explicit Scope(ID* id, attr_list* al);
~Scope() override; ~Scope() override;
ID* Lookup(const char* name) const { return local->Lookup(name); } ID* Lookup(const char* name) const { return local->Lookup(name); }
@ -31,6 +31,7 @@ public:
} }
ID* ScopeID() const { return scope_id; } ID* ScopeID() const { return scope_id; }
attr_list* Attrs() const { return attrs; }
BroType* ReturnType() const { return return_type; } BroType* ReturnType() const { return return_type; }
int Length() const { return local->Length(); } int Length() const { return local->Length(); }
@ -53,6 +54,7 @@ public:
protected: protected:
ID* scope_id; ID* scope_id;
attr_list* attrs;
BroType* return_type; BroType* return_type;
PDict(ID)* local; PDict(ID)* local;
id_list* inits; 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, extern ID* install_ID(const char* name, const char* module_name,
bool is_global, bool is_export); 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); extern void push_existing_scope(Scope* scope);
// Returns the one popped off; it's not deleted. // 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, 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 ) if ( flavor == FUNC_FLAVOR_EVENT )
{ {
@ -384,7 +396,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
else else
id->SetType(t); id->SetType(t);
push_scope(id); push_scope(id, attrs);
RecordType* args = t->Args(); RecordType* args = t->Args();
int num_args = args->NumFields(); 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 = install_ID(arg_i->id, module_name, false, false);
arg_id->SetType(arg_i->type->Ref()); arg_id->SetType(arg_i->type->Ref());
} }
if ( has_attr(attrs, ATTR_DEPRECATED) )
id->MakeDeprecated();
} }
class OuterIDBindingFinder : public TraversalCallback { class OuterIDBindingFinder : public TraversalCallback {
@ -431,7 +446,7 @@ TraversalCode OuterIDBindingFinder::PreExpr(const Expr* expr)
return TC_CONTINUE; return TC_CONTINUE;
} }
void end_func(Stmt* body, attr_list* attrs) void end_func(Stmt* body)
{ {
int frame_size = current_scope()->Length(); int frame_size = current_scope()->Length();
id_list* inits = current_scope()->GetInits(); id_list* inits = current_scope()->GetInits();
@ -440,6 +455,8 @@ void end_func(Stmt* body, attr_list* attrs)
ID* id = scope->ScopeID(); ID* id = scope->ScopeID();
int priority = 0; int priority = 0;
auto attrs = scope->Attrs();
if ( attrs ) if ( attrs )
{ {
loop_over_list(*attrs, i) 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 add_type(ID* id, BroType* t, attr_list* attr);
extern void begin_func(ID* id, const char* module_name, function_flavor flavor, extern 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 = nullptr);
extern void end_func(Stmt* body, attr_list* attrs = 0); extern void end_func(Stmt* body);
extern Val* internal_val(const char* name); extern Val* internal_val(const char* name);
extern Val* internal_const_val(const char* name); // internal error if not const 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++]); add_input_file(argv[optind++]);
} }
push_scope(0); push_scope(nullptr, nullptr);
dns_mgr = new DNS_Mgr(dns_type); 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; 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 { %union {
@ -1142,9 +1130,16 @@ decl:
| func_hdr func_body | func_hdr func_body
{ } { }
| func_hdr conditional_list func_body
{ }
| conditional | conditional
; ;
conditional_list:
conditional
| conditional conditional_list
conditional: conditional:
TOK_ATIF '(' expr ')' TOK_ATIF '(' expr ')'
{ do_atif($3); } { do_atif($3); }
@ -1159,43 +1154,40 @@ conditional:
; ;
func_hdr: 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(), begin_func($2, current_module.c_str(),
FUNC_FLAVOR_FUNCTION, 0, $3); FUNC_FLAVOR_FUNCTION, 0, $3, $4);
$$ = $3; $$ = $3;
broxygen_mgr->Identifier($2); 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(), begin_func($2, current_module.c_str(),
FUNC_FLAVOR_EVENT, 0, $3); FUNC_FLAVOR_EVENT, 0, $3, $4);
$$ = $3; $$ = $3;
} }
| TOK_HOOK def_global_id func_params | TOK_HOOK def_global_id func_params opt_attr
{ {
$3->ClearYieldType(FUNC_FLAVOR_HOOK); $3->ClearYieldType(FUNC_FLAVOR_HOOK);
$3->SetYieldType(base_type(TYPE_BOOL)); $3->SetYieldType(base_type(TYPE_BOOL));
begin_func($2, current_module.c_str(), begin_func($2, current_module.c_str(),
FUNC_FLAVOR_HOOK, 0, $3); FUNC_FLAVOR_HOOK, 0, $3, $4);
$$ = $3; $$ = $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(), begin_func($3, current_module.c_str(),
FUNC_FLAVOR_EVENT, 1, $4); FUNC_FLAVOR_EVENT, 1, $4, $5);
$$ = $4; $$ = $4;
} }
; ;
func_body: func_body:
opt_attr '{' '{'
{ {
saved_in_init.push_back(in_init); saved_in_init.push_back(in_init);
in_init = 0; in_init = 0;
if ( has_attr($1, ATTR_DEPRECATED) )
current_scope()->ScopeID()->MakeDeprecated();
} }
stmt_list 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";
}