mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
"if ( ... ) &analyze" language feature
This commit is contained in:
parent
052cda9df0
commit
9f4da24644
6 changed files with 207 additions and 62 deletions
|
@ -3187,7 +3187,7 @@ HasFieldExpr::HasFieldExpr(ExprPtr arg_op, const char* arg_field_name)
|
|||
|
||||
HasFieldExpr::~HasFieldExpr()
|
||||
{
|
||||
delete field_name;
|
||||
delete[] field_name;
|
||||
}
|
||||
|
||||
ValPtr HasFieldExpr::Fold(Val* v) const
|
||||
|
|
66
src/Var.cc
66
src/Var.cc
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "zeek/ActivationManager.h"
|
||||
#include "zeek/Desc.h"
|
||||
#include "zeek/EventRegistry.h"
|
||||
#include "zeek/Expr.h"
|
||||
|
@ -234,7 +235,7 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
|||
{
|
||||
if ( IsFunc(id->GetType()->Tag()) )
|
||||
add_prototype(id, t.get(), attr.get(), init);
|
||||
else
|
||||
else if ( activation_mgr->IsActivated() )
|
||||
id->Error("already defined", init.get());
|
||||
|
||||
return;
|
||||
|
@ -405,7 +406,18 @@ static void make_var(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
|||
void add_global(const IDPtr& id, TypePtr t, InitClass c, ExprPtr init,
|
||||
std::unique_ptr<std::vector<AttrPtr>> attr, DeclType dt)
|
||||
{
|
||||
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, true);
|
||||
bool do_init = activation_mgr->IsActivated();
|
||||
|
||||
if ( dt == VAR_REDEF )
|
||||
{
|
||||
activation_mgr->AddingRedef(id, c, init, attr);
|
||||
|
||||
if ( ! do_init )
|
||||
// Don't actually change the attributes.
|
||||
attr = nullptr;
|
||||
}
|
||||
|
||||
make_var(id, std::move(t), c, std::move(init), std::move(attr), dt, do_init);
|
||||
}
|
||||
|
||||
StmtPtr add_local(IDPtr id, TypePtr t, InitClass c, ExprPtr init,
|
||||
|
@ -711,6 +723,8 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
else if ( is_redef )
|
||||
id->Error("redef of not-previously-declared value");
|
||||
|
||||
bool is_activated = activation_mgr->IsActivated();
|
||||
|
||||
if ( id->HasVal() )
|
||||
{
|
||||
FunctionFlavor id_flavor = id->GetVal()->AsFunc()->Flavor();
|
||||
|
@ -724,12 +738,17 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
case FUNC_FLAVOR_EVENT:
|
||||
case FUNC_FLAVOR_HOOK:
|
||||
if ( is_redef )
|
||||
// Clear out value so it will be replaced.
|
||||
id->SetVal(nullptr);
|
||||
{
|
||||
activation_mgr->RedefingHandler(id);
|
||||
|
||||
if ( ! is_activated )
|
||||
// Clear out value so it will be replaced.
|
||||
id->SetVal(nullptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FUNC_FLAVOR_FUNCTION:
|
||||
if ( ! id->IsRedefinable() )
|
||||
if ( ! id->IsRedefinable() && is_activated )
|
||||
id->Error("already defined", t.get());
|
||||
break;
|
||||
|
||||
|
@ -753,12 +772,15 @@ void begin_func(IDPtr id, const char* module_name, FunctionFlavor flavor, bool i
|
|||
if ( ! check_params(i, prototype, args, canon_args, module_name) )
|
||||
break;
|
||||
|
||||
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
||||
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
||||
if ( is_activated )
|
||||
{
|
||||
if ( Attr* depr_attr = find_attr(current_scope()->Attrs().get(), ATTR_DEPRECATED) )
|
||||
current_scope()->GetID()->MakeDeprecated(depr_attr->GetExpr());
|
||||
|
||||
// Reset the AST node statistics to track afresh for this function.
|
||||
Stmt::ResetNumStmts();
|
||||
Expr::ResetNumExprs();
|
||||
// Reset the AST node statistics to track afresh for this function.
|
||||
Stmt::ResetNumStmts();
|
||||
Expr::ResetNumExprs();
|
||||
}
|
||||
}
|
||||
|
||||
class OuterIDBindingFinder : public TraversalCallback
|
||||
|
@ -846,7 +868,7 @@ void end_func(StmtPtr body, const char* module_name, bool free_of_conditionals)
|
|||
oi->num_stmts = Stmt::GetNumStmts();
|
||||
oi->num_exprs = Expr::GetNumExprs();
|
||||
|
||||
auto ingredients = std::make_unique<FunctionIngredients>(pop_scope(), std::move(body),
|
||||
auto ingredients = std::make_shared<FunctionIngredients>(pop_scope(), std::move(body),
|
||||
module_name);
|
||||
auto id = ingredients->GetID();
|
||||
if ( ! id->HasVal() )
|
||||
|
@ -854,27 +876,27 @@ void end_func(StmtPtr body, const char* module_name, bool free_of_conditionals)
|
|||
auto f = make_intrusive<ScriptFunc>(id);
|
||||
id->SetVal(make_intrusive<FuncVal>(std::move(f)));
|
||||
id->SetConst();
|
||||
activation_mgr->AddingGlobalVal(id);
|
||||
}
|
||||
|
||||
id->GetVal()->AsFunc()->AddBody(ingredients->Body(), ingredients->Inits(),
|
||||
ingredients->FrameSize(), ingredients->Priority(),
|
||||
ingredients->Groups());
|
||||
|
||||
script_coverage_mgr.AddFunction(id, ingredients->Body());
|
||||
|
||||
auto func_ptr = cast_intrusive<FuncVal>(id->GetVal())->AsFuncPtr();
|
||||
auto func = cast_intrusive<ScriptFunc>(func_ptr);
|
||||
func->SetScope(ingredients->Scope());
|
||||
|
||||
for ( const auto& group : ingredients->Groups() )
|
||||
group->AddFunc(func);
|
||||
activation_mgr->AddingBody(id, ingredients);
|
||||
|
||||
analyze_func(std::move(func));
|
||||
if ( activation_mgr->IsActivated() )
|
||||
{
|
||||
func->AddBody(ingredients->Body(), ingredients->Inits(), ingredients->FrameSize(),
|
||||
ingredients->Priority(), ingredients->Groups());
|
||||
|
||||
// Note: ideally, something would take ownership of this memory until the
|
||||
// end of script execution, but that's essentially the same as the
|
||||
// lifetime of the process at the moment, so ok to "leak" it.
|
||||
ingredients.release();
|
||||
for ( const auto& group : ingredients->Groups() )
|
||||
group->AddFunc(func);
|
||||
|
||||
analyze_func(std::move(func));
|
||||
}
|
||||
}
|
||||
|
||||
IDPList gather_outer_ids(ScopePtr scope, StmtPtr body)
|
||||
|
|
|
@ -23,7 +23,7 @@ extern void add_to_name_list(char* s, char delim, zeek::name_list& nl);
|
|||
|
||||
extern void begin_RE();
|
||||
|
||||
extern void do_atif(zeek::detail::Expr* expr);
|
||||
extern void do_atif(zeek::detail::Expr* expr, bool is_activate);
|
||||
extern void do_atifdef(const char* id);
|
||||
extern void do_atifndef(const char* id);
|
||||
extern void do_atelse();
|
||||
|
|
111
src/parse.y
111
src/parse.y
|
@ -5,10 +5,10 @@
|
|||
// Switching parser table type fixes ambiguity problems.
|
||||
%define lr.type ielr
|
||||
|
||||
%expect 211
|
||||
%expect 212
|
||||
|
||||
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
|
||||
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
|
||||
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATACTIVATEIF TOK_ATIFDEF TOK_ATIFNDEF
|
||||
%token TOK_BOOL TOK_BREAK TOK_CASE TOK_OPTION TOK_CONST
|
||||
%token TOK_CONSTANT TOK_COPY TOK_COUNT TOK_DEFAULT TOK_DELETE
|
||||
%token TOK_DOUBLE TOK_ELSE TOK_ENUM TOK_EVENT TOK_EXPORT TOK_FALLTHROUGH
|
||||
|
@ -31,6 +31,18 @@
|
|||
%token TOK_ATTR_TYPE_COLUMN TOK_ATTR_DEPRECATED
|
||||
%token TOK_ATTR_IS_ASSIGNED TOK_ATTR_IS_USED TOK_ATTR_ORDERED
|
||||
|
||||
// Heads-up, this one is a weirdo. It combines both the attribute and
|
||||
// a leading ')' before it (the two can be separated by spaces/tabs, but
|
||||
// no newlines). This is necessary because if we use the more natural
|
||||
//
|
||||
// TOK_ATIF '(' expr ')' TOK_ATTR_ANALYZE
|
||||
//
|
||||
// then the parser needs to look ahead past the ')' to see if the attribute
|
||||
// is there. If it *isn't*, then the scanner will return the first token
|
||||
// of the conditional block for the look-ahead ... which will break the parse
|
||||
// if that block should in fact have been skipped.
|
||||
%token TOK_ATTR_ANALYZE
|
||||
|
||||
%token TOK_DEBUG
|
||||
|
||||
%token TOK_NO_TEST
|
||||
|
@ -98,6 +110,7 @@
|
|||
#include "zeek/RE.h"
|
||||
#include "zeek/Scope.h"
|
||||
#include "zeek/Reporter.h"
|
||||
#include "zeek/ActivationManager.h"
|
||||
#include "zeek/ScriptCoverageManager.h"
|
||||
#include "zeek/ScriptValidation.h"
|
||||
#include "zeek/zeekygen/Manager.h"
|
||||
|
@ -139,16 +152,19 @@ extern const char* g_curr_debug_error;
|
|||
extern int in_when_cond;
|
||||
|
||||
static int in_hook = 0;
|
||||
int in_init = 0;
|
||||
int in_record = 0;
|
||||
static int in_init = 0;
|
||||
static int in_body = 0;
|
||||
static int in_global_stmts = 0;
|
||||
static int in_record = 0;
|
||||
static int in_record_redef = 0;
|
||||
static int in_enum_redef = 0;
|
||||
bool resolving_global_ID = false;
|
||||
bool defining_global_ID = false;
|
||||
std::vector<int> saved_in_init;
|
||||
static bool resolving_global_ID = false;
|
||||
static bool defining_global_ID = false;
|
||||
static bool is_activated = true;
|
||||
static std::vector<int> saved_in_init;
|
||||
static int expr_list_has_opt_comma = 0;
|
||||
|
||||
std::vector<std::set<const ID*>> locals_at_this_scope;
|
||||
static std::vector<std::set<const ID*>> locals_at_this_scope;
|
||||
static std::unordered_set<const ID*> out_of_scope_locals;
|
||||
|
||||
static Location func_hdr_location;
|
||||
|
@ -321,6 +337,9 @@ static void build_global(ID* id, Type* t, InitClass ic, Expr* e,
|
|||
|
||||
add_global(id_ptr, std::move(t_ptr), ic, e_ptr, std::move(attrs_ptr), dt);
|
||||
|
||||
if ( ! activation_mgr->IsActivated() )
|
||||
return;
|
||||
|
||||
if ( dt == VAR_REDEF )
|
||||
zeekygen_mgr->Redef(id, ::filename, ic, std::move(e_ptr));
|
||||
else
|
||||
|
@ -392,9 +411,13 @@ zeek:
|
|||
auto loc = zeek::detail::GetCurrentLocation();
|
||||
if ( loc.filename )
|
||||
set_location(loc);
|
||||
|
||||
++in_global_stmts;
|
||||
}
|
||||
stmt_list
|
||||
{
|
||||
--in_global_stmts;
|
||||
|
||||
if ( stmts )
|
||||
stmts->AsStmtList()->Stmts().push_back($3);
|
||||
else
|
||||
|
@ -1400,29 +1423,49 @@ decl:
|
|||
}
|
||||
|
||||
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{'
|
||||
{ ++in_enum_redef; parse_redef_enum($3); zeekygen_mgr->Redef($3, ::filename); }
|
||||
{
|
||||
++in_enum_redef;
|
||||
parse_redef_enum($3);
|
||||
zeekygen_mgr->Redef($3, ::filename);
|
||||
}
|
||||
enum_body '}' ';'
|
||||
{
|
||||
if ( activation_mgr->InsideConditional() )
|
||||
reporter->Error("enum redef cannot appear inside @if &analyze");
|
||||
--in_enum_redef;
|
||||
// Zeekygen already grabbed new enum IDs as the type created them.
|
||||
}
|
||||
|
||||
| TOK_REDEF TOK_RECORD global_id '$' TOK_ID
|
||||
{ cur_decl_type_id = $3; zeekygen_mgr->Redef($3, ::filename, INIT_EXTRA); }
|
||||
{
|
||||
cur_decl_type_id = $3;
|
||||
zeekygen_mgr->Redef($3, ::filename, INIT_EXTRA);
|
||||
}
|
||||
TOK_ADD_TO '{' attr_list '}' ';'
|
||||
{
|
||||
if ( activation_mgr->InsideConditional() )
|
||||
reporter->Error("record redef cannot appear inside @if &analyze");
|
||||
cur_decl_type_id = 0;
|
||||
parse_redef_record_field($3, $5, INIT_EXTRA, std::unique_ptr<std::vector<AttrPtr>>($9));
|
||||
}
|
||||
|
||||
| TOK_REDEF TOK_RECORD global_id '$' TOK_ID
|
||||
{ cur_decl_type_id = $3; zeekygen_mgr->Redef($3, ::filename, INIT_REMOVE); }
|
||||
{
|
||||
cur_decl_type_id = $3;
|
||||
zeekygen_mgr->Redef($3, ::filename, INIT_REMOVE);
|
||||
}
|
||||
TOK_REMOVE_FROM '{' attr_list '}' ';'
|
||||
{
|
||||
if ( activation_mgr->InsideConditional() )
|
||||
reporter->Error("record redef cannot appear inside @if &analyze");
|
||||
cur_decl_type_id = 0;
|
||||
parse_redef_record_field($3, $5, INIT_REMOVE, std::unique_ptr<std::vector<AttrPtr>>($9));
|
||||
}
|
||||
| TOK_REDEF TOK_RECORD global_id
|
||||
{ cur_decl_type_id = $3; zeekygen_mgr->Redef($3, ::filename); }
|
||||
{
|
||||
cur_decl_type_id = $3;
|
||||
zeekygen_mgr->Redef($3, ::filename);
|
||||
}
|
||||
TOK_ADD_TO '{'
|
||||
{ ++in_record; ++in_record_redef; }
|
||||
type_decl_list
|
||||
|
@ -1433,6 +1476,8 @@ decl:
|
|||
|
||||
if ( ! $3->GetType() )
|
||||
$3->Error("unknown identifier");
|
||||
else if ( activation_mgr->InsideConditional() )
|
||||
reporter->Error("record redef cannot appear inside @if &analyze");
|
||||
else
|
||||
extend_record($3, std::unique_ptr<type_decl_list>($8),
|
||||
std::unique_ptr<std::vector<AttrPtr>>($11));
|
||||
|
@ -1465,7 +1510,19 @@ conditional_list:
|
|||
|
||||
conditional:
|
||||
TOK_ATIF '(' expr ')'
|
||||
{ do_atif($3); }
|
||||
{ do_atif($3, false); }
|
||||
| TOK_ATIF '(' expr TOK_ATTR_ANALYZE
|
||||
{
|
||||
if ( in_body )
|
||||
reporter->Error("@if &analyze cannot appear inside a function body");
|
||||
do_atif($3, true);
|
||||
}
|
||||
| TOK_ATACTIVATEIF '(' expr ')'
|
||||
{
|
||||
if ( in_body )
|
||||
reporter->Error("@if &analyze cannot appear inside a function body");
|
||||
do_atif($3, true);
|
||||
}
|
||||
| TOK_ATIFDEF '(' TOK_ID ')'
|
||||
{ do_atifdef($3); }
|
||||
| TOK_ATIFNDEF '(' TOK_ID ')'
|
||||
|
@ -1516,6 +1573,7 @@ func_body:
|
|||
{
|
||||
saved_in_init.push_back(in_init);
|
||||
in_init = 0;
|
||||
++in_body;
|
||||
|
||||
locals_at_this_scope.clear();
|
||||
out_of_scope_locals.clear();
|
||||
|
@ -1525,6 +1583,7 @@ func_body:
|
|||
{
|
||||
in_init = saved_in_init.back();
|
||||
saved_in_init.pop_back();
|
||||
--in_body;
|
||||
}
|
||||
|
||||
'}'
|
||||
|
@ -1545,12 +1604,14 @@ lambda_body:
|
|||
{
|
||||
saved_in_init.push_back(in_init);
|
||||
in_init = 0;
|
||||
++in_body;
|
||||
}
|
||||
|
||||
stmt_list
|
||||
{
|
||||
in_init = saved_in_init.back();
|
||||
saved_in_init.pop_back();
|
||||
--in_body;
|
||||
}
|
||||
|
||||
'}'
|
||||
|
@ -1963,11 +2024,21 @@ stmt:
|
|||
;
|
||||
|
||||
stmt_list:
|
||||
stmt_list stmt
|
||||
stmt_list { is_activated = activation_mgr->IsActivated(); } stmt
|
||||
{
|
||||
set_location(@1, @2);
|
||||
$1->AsStmtList()->Stmts().push_back($2);
|
||||
$1->UpdateLocationEndInfo(@2);
|
||||
set_location(@1, @3);
|
||||
|
||||
// We can't simply test activation_mgr->IsActivated()
|
||||
// here because the parser can wind up looking ahead
|
||||
// to the @endif token and restoring activation that
|
||||
// in fact was off for the statement. So we capture
|
||||
// the activation state prior to parsing the statement
|
||||
// in "is_activated" and test that instead.
|
||||
if ( ! in_global_stmts || is_activated )
|
||||
{
|
||||
$1->AsStmtList()->Stmts().push_back($3);
|
||||
$1->UpdateLocationEndInfo(@3);
|
||||
}
|
||||
}
|
||||
|
|
||||
{ $$ = new StmtList(); }
|
||||
|
@ -2207,8 +2278,10 @@ global_or_event_id:
|
|||
resolving_global_ID ?
|
||||
current_module.c_str() : 0;
|
||||
|
||||
$$ = install_ID($1, module_name,
|
||||
true, is_export).release();
|
||||
auto gid = install_ID($1, module_name,
|
||||
true, is_export);
|
||||
activation_mgr->CreatingGlobalID(gid);
|
||||
$$ = gid.release();
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
84
src/scan.l
84
src/scan.l
|
@ -29,8 +29,6 @@
|
|||
#include "zeek/DNS_Mgr.h"
|
||||
#include "zeek/Expr.h"
|
||||
#include "zeek/Func.h"
|
||||
#include "zeek/Stmt.h"
|
||||
#include "zeek/IntrusivePtr.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/Var.h"
|
||||
#include "zeek/Debug.h"
|
||||
|
@ -41,6 +39,7 @@
|
|||
#include "zeek/Traverse.h"
|
||||
#include "zeek/module_util.h"
|
||||
#include "zeek/ScannedFile.h"
|
||||
#include "zeek/ActivationManager.h"
|
||||
|
||||
#include "zeek/analyzer/Analyzer.h"
|
||||
#include "zeek/zeekygen/Manager.h"
|
||||
|
@ -55,9 +54,10 @@ extern YYLTYPE yylloc; // holds start line and column of token
|
|||
extern zeek::EnumType* cur_enum_type;
|
||||
|
||||
// Track the @if... depth.
|
||||
static std::intptr_t conditional_depth = 0;
|
||||
static int conditional_depth = 0;
|
||||
|
||||
zeek::detail::int_list entry_cond_depth; // @if depth upon starting file
|
||||
zeek::detail::int_list entry_act_depth; // @if &analyze depth upon starting file
|
||||
zeek::detail::int_list entry_pragma_stack_depth; // @pragma push depth upon starting file
|
||||
static std::vector<std::string> pragma_stack; // stack of @pragma pushes
|
||||
|
||||
|
@ -127,6 +127,9 @@ static std::string find_relative_script_file(const std::string& filename)
|
|||
|
||||
static void start_conditional()
|
||||
{
|
||||
if ( activation_mgr->InsideConditional() )
|
||||
zeek::reporter->Warning("@conditional inside @if &analyze");
|
||||
|
||||
++conditional_depth;
|
||||
++conditional_epoch;
|
||||
|
||||
|
@ -155,17 +158,18 @@ static void do_pragma(const std::string& pragma)
|
|||
|
||||
if ( parts[0] == "push" )
|
||||
{
|
||||
if ( parts.size() < 2 )
|
||||
{
|
||||
zeek::reporter->FatalError("@pragma push without value");
|
||||
return;
|
||||
}
|
||||
if ( parts.size() < 2 )
|
||||
{
|
||||
zeek::reporter->FatalError("@pragma push without value");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( known_stack_pragmas.count(parts[1]) == 0 )
|
||||
zeek::reporter->Warning("pushing unknown @pragma value '%s'", parts[1].c_str());
|
||||
if ( known_stack_pragmas.count(parts[1]) == 0 )
|
||||
zeek::reporter->Warning("pushing unknown @pragma value '%s'", parts[1].c_str());
|
||||
|
||||
pragma_stack.push_back(parts[1]);
|
||||
pragma_stack.push_back(parts[1]);
|
||||
}
|
||||
|
||||
else if ( parts[0] == "pop" )
|
||||
{
|
||||
if ( pragma_stack.empty() || pragma_stack.size() == entry_pragma_stack_depth.back() )
|
||||
|
@ -176,10 +180,11 @@ static void do_pragma(const std::string& pragma)
|
|||
|
||||
// Popping with a value: Verify it's popping the right thing. Not providing
|
||||
// a pop value itself is valid. Don't return, probably blows up below anyway.
|
||||
if ( parts.size() > 1 && pragma_stack.back() != parts[1] ) {
|
||||
if ( parts.size() > 1 && pragma_stack.back() != parts[1] )
|
||||
{
|
||||
zeek::reporter->Error("@pragma pop with unexpected '%s', expected '%s'",
|
||||
parts[1].c_str(), pragma_stack.back().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Just pop anything
|
||||
pragma_stack.pop_back();
|
||||
|
@ -397,6 +402,8 @@ when return TOK_WHEN;
|
|||
&backend return TOK_ATTR_BACKEND;
|
||||
&ordered return TOK_ATTR_ORDERED;
|
||||
|
||||
")"{OWS}&analyze return TOK_ATTR_ANALYZE; // see parse.y for discussion of weirdness
|
||||
|
||||
@deprecated.* {
|
||||
auto num_files = file_stack.length();
|
||||
auto comment = zeek::util::skip_whitespace(yytext + 11);
|
||||
|
@ -534,11 +541,12 @@ when return TOK_WHEN;
|
|||
@endif do_atendif();
|
||||
|
||||
<IGNORE>@if start_conditional();
|
||||
<IGNORE>&analyze zeek::reporter->Warning("@if &analyze inside regular @if");
|
||||
<IGNORE>@ifdef start_conditional();
|
||||
<IGNORE>@ifndef start_conditional();
|
||||
<IGNORE>@else return TOK_ATELSE;
|
||||
<IGNORE>@endif return TOK_ATENDIF;
|
||||
<IGNORE>[^@\r\n]+ /* eat */
|
||||
<IGNORE>[^@&\r\n]+ /* eat */
|
||||
<IGNORE>. /* eat */
|
||||
|
||||
T RET_CONST(zeek::val_mgr->True()->Ref())
|
||||
|
@ -802,6 +810,7 @@ static int load_files(const char* orig_file)
|
|||
current_file_has_conditionals = files_with_conditionals.count(filename) > 0;
|
||||
|
||||
entry_cond_depth.push_back(conditional_depth);
|
||||
entry_act_depth.push_back(activation_mgr->ActivationDepth());
|
||||
entry_pragma_stack_depth.push_back(pragma_stack.size());
|
||||
|
||||
return 1;
|
||||
|
@ -846,10 +855,8 @@ static void resume_processing()
|
|||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
void do_atif(zeek::detail::Expr* expr)
|
||||
void do_atif(zeek::detail::Expr* expr, bool is_activate)
|
||||
{
|
||||
start_conditional();
|
||||
|
||||
LocalNameFinder cb;
|
||||
expr->Traverse(&cb);
|
||||
zeek::ValPtr val;
|
||||
|
@ -865,11 +872,28 @@ void do_atif(zeek::detail::Expr* expr)
|
|||
if ( ! val )
|
||||
{
|
||||
expr->Error("invalid expression in @if");
|
||||
|
||||
if ( ! is_activate )
|
||||
start_conditional();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! val->AsBool() )
|
||||
begin_ignoring();
|
||||
bool is_true = val->AsBool();
|
||||
|
||||
if ( is_activate )
|
||||
{
|
||||
if ( conditional_depth > 0 )
|
||||
zeek::reporter->Warning("@if &analyze inside conditional");
|
||||
activation_mgr->Start({zeek::NewRef{}, expr}, is_true, conditional_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
start_conditional();
|
||||
|
||||
if ( ! is_true )
|
||||
begin_ignoring();
|
||||
}
|
||||
}
|
||||
|
||||
void do_atifdef(const char* id)
|
||||
|
@ -904,6 +928,12 @@ void do_atifndef(const char *id)
|
|||
|
||||
void do_atelse()
|
||||
{
|
||||
if ( activation_mgr->InsideConditional(conditional_depth) )
|
||||
{ // This is the @else corresponding to an @if &analyze.
|
||||
activation_mgr->SwitchToElse();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( conditional_depth == 0 )
|
||||
zeek::reporter->Error("@else without @if...");
|
||||
|
||||
|
@ -918,6 +948,15 @@ void do_atelse()
|
|||
|
||||
void do_atendif()
|
||||
{
|
||||
if ( activation_mgr->InsideConditional(conditional_depth) )
|
||||
{ // We're ending an @if &analyze.
|
||||
if ( activation_mgr->ActivationDepth() <= entry_act_depth.back() )
|
||||
zeek::reporter->Error("unbalanced @if &analyze... @endif");
|
||||
else
|
||||
activation_mgr->End();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( conditional_depth <= entry_cond_depth.back() )
|
||||
zeek::reporter->Error("unbalanced @if... @endif");
|
||||
|
||||
|
@ -1000,6 +1039,13 @@ int yywrap()
|
|||
entry_cond_depth.pop_back();
|
||||
}
|
||||
|
||||
if ( entry_act_depth.size() > 0 )
|
||||
{
|
||||
if ( activation_mgr->ActivationDepth() > entry_act_depth.back() )
|
||||
zeek::reporter->FatalError("unbalanced @if &analyze... @endif");
|
||||
entry_act_depth.pop_back();
|
||||
}
|
||||
|
||||
if ( entry_pragma_stack_depth.size() > 0 )
|
||||
{
|
||||
if ( pragma_stack.size() > entry_pragma_stack_depth.back() )
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define DOCTEST_CONFIG_IMPLEMENT
|
||||
|
||||
#include "zeek/3rdparty/doctest.h"
|
||||
#include "zeek/ActivationManager.h"
|
||||
#include "zeek/Anon.h"
|
||||
#include "zeek/DFA.h"
|
||||
#include "zeek/DNS_Mgr.h"
|
||||
|
@ -183,6 +184,7 @@ zeek::plugin::Manager* zeek::plugin_mgr = nullptr;
|
|||
zeek::detail::RuleMatcher* zeek::detail::rule_matcher = nullptr;
|
||||
zeek::detail::DNS_Mgr* zeek::detail::dns_mgr = nullptr;
|
||||
zeek::detail::TimerMgr* zeek::detail::timer_mgr = nullptr;
|
||||
zeek::detail::ActivationManager* zeek::detail::activation_mgr;
|
||||
|
||||
zeek::logging::Manager* zeek::log_mgr = nullptr;
|
||||
zeek::threading::Manager* zeek::thread_mgr = nullptr;
|
||||
|
@ -443,6 +445,7 @@ static void terminate_zeek()
|
|||
delete session_mgr;
|
||||
delete fragment_mgr;
|
||||
delete telemetry_mgr;
|
||||
delete activation_mgr;
|
||||
#ifdef HAVE_SPICY
|
||||
delete spicy_mgr;
|
||||
#endif
|
||||
|
@ -673,6 +676,7 @@ SetupResult setup(int argc, char** argv, Options* zopts)
|
|||
|
||||
auto zeekygen_cfg = options.zeekygen_config_file.value_or("");
|
||||
zeekygen_mgr = new zeekygen::detail::Manager(zeekygen_cfg, zeek_argv[0]);
|
||||
activation_mgr = new ActivationManager();
|
||||
|
||||
add_essential_input_file("base/init-bare.zeek");
|
||||
add_essential_input_file("builtin-plugins/__preload__.zeek");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue