mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-30 00:54:30 +02:00
parent
75eed9f30e
commit
7621870278
@ -193,9 +193,9 @@ int Main(void)
|
|||||||
("app,a", po::value<std::string>(), "application library name (default: icinga)")
|
("app,a", po::value<std::string>(), "application library name (default: icinga)")
|
||||||
("library,l", po::value<std::vector<std::string> >(), "load a library")
|
("library,l", po::value<std::vector<std::string> >(), "load a library")
|
||||||
("include,I", po::value<std::vector<std::string> >(), "add include search directory")
|
("include,I", po::value<std::vector<std::string> >(), "add include search directory")
|
||||||
("log-level,x", po::value<std::string>()
|
("log-level,x", po::value<std::string>(), "specify the log level for the console log.\n"
|
||||||
, "specify the log level for the console log.\n"
|
"The valid value is either debug, notice, information (default), warning, or critical")
|
||||||
"The valid value is either debug, notice, information (default), warning, or critical");
|
("script-debugger,X", "whether to enable the script debugger");
|
||||||
|
|
||||||
po::options_description hiddenDesc("Hidden options");
|
po::options_description hiddenDesc("Hidden options");
|
||||||
|
|
||||||
@ -264,6 +264,9 @@ int Main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count("script-debugger"))
|
||||||
|
Application::SetScriptDebuggerEnabled(true);
|
||||||
|
|
||||||
Application::DeclareStatePath(Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state");
|
Application::DeclareStatePath(Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state");
|
||||||
Application::DeclareModAttrPath(Application::GetLocalStateDir() + "/lib/icinga2/modified-attributes.conf");
|
Application::DeclareModAttrPath(Application::GetLocalStateDir() + "/lib/icinga2/modified-attributes.conf");
|
||||||
Application::DeclareObjectsPath(Application::GetLocalStateDir() + "/cache/icinga2/icinga2.debug");
|
Application::DeclareObjectsPath(Application::GetLocalStateDir() + "/cache/icinga2/icinga2.debug");
|
||||||
|
@ -63,6 +63,7 @@ static bool l_InExceptionHandler = false;
|
|||||||
int Application::m_ArgC;
|
int Application::m_ArgC;
|
||||||
char **Application::m_ArgV;
|
char **Application::m_ArgV;
|
||||||
double Application::m_StartTime;
|
double Application::m_StartTime;
|
||||||
|
bool Application::m_ScriptDebuggerEnabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for the Application class.
|
* Constructor for the Application class.
|
||||||
@ -1450,6 +1451,16 @@ void Application::SetStartTime(double ts)
|
|||||||
m_StartTime = ts;
|
m_StartTime = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::GetScriptDebuggerEnabled(void)
|
||||||
|
{
|
||||||
|
return m_ScriptDebuggerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::SetScriptDebuggerEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_ScriptDebuggerEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::ValidateName(const String& value, const ValidationUtils& utils)
|
void Application::ValidateName(const String& value, const ValidationUtils& utils)
|
||||||
{
|
{
|
||||||
ObjectImpl<Application>::ValidateName(value, utils);
|
ObjectImpl<Application>::ValidateName(value, utils);
|
||||||
|
@ -134,6 +134,9 @@ public:
|
|||||||
static double GetStartTime(void);
|
static double GetStartTime(void);
|
||||||
static void SetStartTime(double ts);
|
static void SetStartTime(double ts);
|
||||||
|
|
||||||
|
static bool GetScriptDebuggerEnabled(void);
|
||||||
|
static void SetScriptDebuggerEnabled(bool enabled);
|
||||||
|
|
||||||
static void DisplayInfoMessage(std::ostream& os, bool skipVersion = false);
|
static void DisplayInfoMessage(std::ostream& os, bool skipVersion = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -164,6 +167,7 @@ private:
|
|||||||
static bool m_Debugging; /**< Whether debugging is enabled. */
|
static bool m_Debugging; /**< Whether debugging is enabled. */
|
||||||
static LogSeverity m_DebuggingSeverity; /**< Whether debugging severity is set. */
|
static LogSeverity m_DebuggingSeverity; /**< Whether debugging severity is set. */
|
||||||
static double m_StartTime;
|
static double m_StartTime;
|
||||||
|
static bool m_ScriptDebuggerEnabled;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static void SigIntTermHandler(int signum);
|
static void SigIntTermHandler(int signum);
|
||||||
|
@ -254,7 +254,7 @@ ScriptError::ScriptError(const String& message)
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
ScriptError::ScriptError(const String& message, const DebugInfo& di, bool incompleteExpr)
|
ScriptError::ScriptError(const String& message, const DebugInfo& di, bool incompleteExpr)
|
||||||
: m_Message(message), m_DebugInfo(di), m_IncompleteExpr(incompleteExpr)
|
: m_Message(message), m_DebugInfo(di), m_IncompleteExpr(incompleteExpr), m_HandledByDebugger(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
ScriptError::~ScriptError(void) throw()
|
ScriptError::~ScriptError(void) throw()
|
||||||
@ -275,6 +275,16 @@ bool ScriptError::IsIncompleteExpression(void) const
|
|||||||
return m_IncompleteExpr;;
|
return m_IncompleteExpr;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptError::IsHandledByDebugger(void) const
|
||||||
|
{
|
||||||
|
return m_HandledByDebugger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptError::SetHandledByDebugger(bool handled)
|
||||||
|
{
|
||||||
|
m_HandledByDebugger = handled;
|
||||||
|
}
|
||||||
|
|
||||||
posix_error::posix_error(void)
|
posix_error::posix_error(void)
|
||||||
: m_Message(NULL)
|
: m_Message(NULL)
|
||||||
{ }
|
{ }
|
||||||
|
@ -60,10 +60,14 @@ public:
|
|||||||
DebugInfo GetDebugInfo(void) const;
|
DebugInfo GetDebugInfo(void) const;
|
||||||
bool IsIncompleteExpression(void) const;
|
bool IsIncompleteExpression(void) const;
|
||||||
|
|
||||||
|
bool IsHandledByDebugger(void) const;
|
||||||
|
void SetHandledByDebugger(bool handled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_Message;
|
String m_Message;
|
||||||
DebugInfo m_DebugInfo;
|
DebugInfo m_DebugInfo;
|
||||||
bool m_IncompleteExpr;
|
bool m_IncompleteExpr;
|
||||||
|
bool m_HandledByDebugger;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,6 +46,36 @@ static String l_Session;
|
|||||||
|
|
||||||
REGISTER_CLICOMMAND("console", ConsoleCommand);
|
REGISTER_CLICOMMAND("console", ConsoleCommand);
|
||||||
|
|
||||||
|
INITIALIZE_ONCE(&ConsoleCommand::StaticInitialize);
|
||||||
|
|
||||||
|
void ConsoleCommand::BreakpointHandler(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di)
|
||||||
|
{
|
||||||
|
static boost::mutex mutex;
|
||||||
|
boost::mutex::scoped_lock lock(mutex);
|
||||||
|
|
||||||
|
if (!Application::GetScriptDebuggerEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ex && ex->IsHandledByDebugger())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::cout << "Breakpoint encountered in '" << di.Path << "' at " << di << "\n";
|
||||||
|
|
||||||
|
if (ex) {
|
||||||
|
std::cout << "Exception: " << DiagnosticInformation(*ex);
|
||||||
|
ex->SetHandledByDebugger(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "You can leave the debugger and continue the program with \"$quit\".\n";
|
||||||
|
|
||||||
|
ConsoleCommand::RunScriptConsole(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleCommand::StaticInitialize(void)
|
||||||
|
{
|
||||||
|
Expression::OnBreakpoint.connect(&ConsoleCommand::BreakpointHandler);
|
||||||
|
}
|
||||||
|
|
||||||
String ConsoleCommand::GetDescription(void) const
|
String ConsoleCommand::GetDescription(void) const
|
||||||
{
|
{
|
||||||
return "Interprets Icinga script expressions.";
|
return "Interprets Icinga script expressions.";
|
||||||
@ -118,19 +148,15 @@ char *ConsoleCommand::ConsoleCompleteHelper(const char *word, int state)
|
|||||||
*/
|
*/
|
||||||
int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::string>& ap) const
|
int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::string>& ap) const
|
||||||
{
|
{
|
||||||
std::map<String, String> lines;
|
|
||||||
int next_line = 1;
|
|
||||||
|
|
||||||
#ifdef HAVE_EDITLINE
|
#ifdef HAVE_EDITLINE
|
||||||
rl_completion_entry_function = ConsoleCommand::ConsoleCompleteHelper;
|
rl_completion_entry_function = ConsoleCommand::ConsoleCompleteHelper;
|
||||||
rl_completion_append_character = '\0';
|
rl_completion_append_character = '\0';
|
||||||
#endif /* HAVE_EDITLINE */
|
#endif /* HAVE_EDITLINE */
|
||||||
|
|
||||||
String addr;
|
String addr, session;
|
||||||
ScriptFrame scriptFrame;
|
ScriptFrame scriptFrame;
|
||||||
|
|
||||||
l_ScriptFrame = &scriptFrame;
|
session = Utility::NewUniqueID();
|
||||||
l_Session = Utility::NewUniqueID();
|
|
||||||
|
|
||||||
if (vm.count("sandbox"))
|
if (vm.count("sandbox"))
|
||||||
scriptFrame.Sandboxed = true;
|
scriptFrame.Sandboxed = true;
|
||||||
@ -144,9 +170,24 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
|
|||||||
if (addrEnv)
|
if (addrEnv)
|
||||||
addr = addrEnv;
|
addr = addrEnv;
|
||||||
|
|
||||||
if (vm.count("connect")) {
|
if (vm.count("connect"))
|
||||||
addr = vm["connect"].as<std::string>();
|
addr = vm["connect"].as<std::string>();
|
||||||
}
|
|
||||||
|
String command;
|
||||||
|
|
||||||
|
if (vm.count("eval"))
|
||||||
|
command = vm["eval"].as<std::string>();
|
||||||
|
|
||||||
|
return RunScriptConsole(scriptFrame, addr, session, command);;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsoleCommand::RunScriptConsole(ScriptFrame& scriptFrame, const String& addr, const String& session, const String& commandOnce)
|
||||||
|
{
|
||||||
|
std::map<String, String> lines;
|
||||||
|
int next_line = 1;
|
||||||
|
|
||||||
|
l_ScriptFrame = &scriptFrame;
|
||||||
|
l_Session = session;
|
||||||
|
|
||||||
if (!addr.IsEmpty()) {
|
if (!addr.IsEmpty()) {
|
||||||
Url::Ptr url;
|
Url::Ptr url;
|
||||||
@ -182,7 +223,7 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
|
|||||||
incomplete:
|
incomplete:
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
if (!vm.count("eval")) {
|
if (commandOnce.IsEmpty()) {
|
||||||
#ifdef HAVE_EDITLINE
|
#ifdef HAVE_EDITLINE
|
||||||
std::ostringstream promptbuf;
|
std::ostringstream promptbuf;
|
||||||
std::ostream& os = promptbuf;
|
std::ostream& os = promptbuf;
|
||||||
@ -215,7 +256,14 @@ incomplete:
|
|||||||
std::getline(std::cin, line);
|
std::getline(std::cin, line);
|
||||||
#endif /* HAVE_EDITLINE */
|
#endif /* HAVE_EDITLINE */
|
||||||
} else
|
} else
|
||||||
line = vm["eval"].as<std::string>();
|
line = commandOnce;
|
||||||
|
|
||||||
|
if (!line.empty() && line[0] == '$') {
|
||||||
|
if (line == "$quit")
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::cout << "Unknown debugger command: " << line;
|
||||||
|
}
|
||||||
|
|
||||||
if (!command.empty())
|
if (!command.empty())
|
||||||
command += "\n";
|
command += "\n";
|
||||||
@ -254,7 +302,7 @@ incomplete:
|
|||||||
boost::rethrow_exception(eptr);
|
boost::rethrow_exception(eptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vm.count("eval")) {
|
if (commandOnce.IsEmpty()) {
|
||||||
std::cout << ConsoleColorTag(Console_ForegroundCyan);
|
std::cout << ConsoleColorTag(Console_ForegroundCyan);
|
||||||
ConfigWriter::EmitValue(std::cout, 1, result);
|
ConfigWriter::EmitValue(std::cout, 1, result);
|
||||||
std::cout << ConsoleColorTag(Console_Normal) << "\n";
|
std::cout << ConsoleColorTag(Console_Normal) << "\n";
|
||||||
@ -308,12 +356,12 @@ incomplete:
|
|||||||
|
|
||||||
std::cout << ex.what() << "\n";
|
std::cout << ex.what() << "\n";
|
||||||
|
|
||||||
if (vm.count("eval"))
|
if (!commandOnce.IsEmpty())
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
std::cout << "Error: " << DiagnosticInformation(ex) << "\n";
|
std::cout << "Error: " << DiagnosticInformation(ex) << "\n";
|
||||||
|
|
||||||
if (vm.count("eval"))
|
if (!commandOnce.IsEmpty())
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "cli/clicommand.hpp"
|
#include "cli/clicommand.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
|
#include "base/scriptframe.hpp"
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
@ -36,6 +37,8 @@ class ConsoleCommand : public CLICommand
|
|||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(ConsoleCommand);
|
DECLARE_PTR_TYPEDEFS(ConsoleCommand);
|
||||||
|
|
||||||
|
static void StaticInitialize(void);
|
||||||
|
|
||||||
virtual String GetDescription(void) const override;
|
virtual String GetDescription(void) const override;
|
||||||
virtual String GetShortDescription(void) const override;
|
virtual String GetShortDescription(void) const override;
|
||||||
virtual ImpersonationLevel GetImpersonationLevel(void) const override;
|
virtual ImpersonationLevel GetImpersonationLevel(void) const override;
|
||||||
@ -43,6 +46,9 @@ public:
|
|||||||
boost::program_options::options_description& hiddenDesc) const override;
|
boost::program_options::options_description& hiddenDesc) const override;
|
||||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
|
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
|
||||||
|
|
||||||
|
static int RunScriptConsole(ScriptFrame& scriptFrame, const String& addr = String(),
|
||||||
|
const String& session = String(), const String& commandOnce = String());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable boost::mutex m_Mutex;
|
mutable boost::mutex m_Mutex;
|
||||||
mutable boost::condition_variable m_CV;
|
mutable boost::condition_variable m_CV;
|
||||||
@ -58,6 +64,8 @@ private:
|
|||||||
static char *ConsoleCompleteHelper(const char *word, int state);
|
static char *ConsoleCompleteHelper(const char *word, int state);
|
||||||
#endif /* HAVE_EDITLINE */
|
#endif /* HAVE_EDITLINE */
|
||||||
|
|
||||||
|
static void BreakpointHandler(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,7 @@ throw return T_THROW;
|
|||||||
ignore_on_error return T_IGNORE_ON_ERROR;
|
ignore_on_error return T_IGNORE_ON_ERROR;
|
||||||
current_filename return T_CURRENT_FILENAME;
|
current_filename return T_CURRENT_FILENAME;
|
||||||
current_line return T_CURRENT_LINE;
|
current_line return T_CURRENT_LINE;
|
||||||
|
debugger return T_DEBUGGER;
|
||||||
=\> return T_FOLLOWS;
|
=\> return T_FOLLOWS;
|
||||||
\<\< return T_SHIFT_LEFT;
|
\<\< return T_SHIFT_LEFT;
|
||||||
\>\> return T_SHIFT_RIGHT;
|
\>\> return T_SHIFT_RIGHT;
|
||||||
|
@ -146,6 +146,7 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig
|
|||||||
%token T_IGNORE_ON_ERROR "ignore_on_error (T_IGNORE_ON_ERROR)"
|
%token T_IGNORE_ON_ERROR "ignore_on_error (T_IGNORE_ON_ERROR)"
|
||||||
%token T_CURRENT_FILENAME "current_filename (T_CURRENT_FILENAME)"
|
%token T_CURRENT_FILENAME "current_filename (T_CURRENT_FILENAME)"
|
||||||
%token T_CURRENT_LINE "current_line (T_CURRENT_LINE)"
|
%token T_CURRENT_LINE "current_line (T_CURRENT_LINE)"
|
||||||
|
%token T_DEBUGGER "debugger (T_DEBUGGER)"
|
||||||
%token T_USE "use (T_USE)"
|
%token T_USE "use (T_USE)"
|
||||||
%token T_OBJECT "object (T_OBJECT)"
|
%token T_OBJECT "object (T_OBJECT)"
|
||||||
%token T_TEMPLATE "template (T_TEMPLATE)"
|
%token T_TEMPLATE "template (T_TEMPLATE)"
|
||||||
@ -514,6 +515,10 @@ lterm: T_LIBRARY rterm
|
|||||||
{
|
{
|
||||||
$$ = new ContinueExpression(@$);
|
$$ = new ContinueExpression(@$);
|
||||||
}
|
}
|
||||||
|
| T_DEBUGGER
|
||||||
|
{
|
||||||
|
$$ = new BreakpointExpression(@$);
|
||||||
|
}
|
||||||
| apply
|
| apply
|
||||||
| object
|
| object
|
||||||
| T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope_require_side_effect
|
| T_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')' rterm_scope_require_side_effect
|
||||||
|
@ -34,9 +34,23 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
boost::signals2::signal<void (ScriptFrame&, ScriptError *ex, const DebugInfo&)> Expression::OnBreakpoint;
|
||||||
|
boost::thread_specific_ptr<bool> l_InBreakpointHandler;
|
||||||
|
|
||||||
Expression::~Expression(void)
|
Expression::~Expression(void)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void Expression::ScriptBreakpoint(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di)
|
||||||
|
{
|
||||||
|
bool *inHandler = l_InBreakpointHandler.get();
|
||||||
|
if (!inHandler || !*inHandler) {
|
||||||
|
inHandler = new bool(true);
|
||||||
|
l_InBreakpointHandler.reset(inHandler);
|
||||||
|
OnBreakpoint(frame, ex, di);
|
||||||
|
*inHandler = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionResult Expression::Evaluate(ScriptFrame& frame, DebugHint *dhint) const
|
ExpressionResult Expression::Evaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -48,7 +62,8 @@ ExpressionResult Expression::Evaluate(ScriptFrame& frame, DebugHint *dhint) cons
|
|||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
|
|
||||||
return DoEvaluate(frame, dhint);
|
return DoEvaluate(frame, dhint);
|
||||||
} catch (const ScriptError& ex) {
|
} catch (ScriptError& ex) {
|
||||||
|
ScriptBreakpoint(frame, &ex, GetDebugInfo());
|
||||||
throw;
|
throw;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
BOOST_THROW_EXCEPTION(ScriptError("Error while evaluating expression: " + String(ex.what()), GetDebugInfo())
|
BOOST_THROW_EXCEPTION(ScriptError("Error while evaluating expression: " + String(ex.what()), GetDebugInfo())
|
||||||
@ -859,3 +874,11 @@ ExpressionResult IncludeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpressionResult BreakpointExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||||
|
{
|
||||||
|
ScriptBreakpoint(frame, NULL, GetDebugInfo());
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -198,6 +198,10 @@ public:
|
|||||||
virtual const DebugInfo& GetDebugInfo(void) const;
|
virtual const DebugInfo& GetDebugInfo(void) const;
|
||||||
|
|
||||||
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const = 0;
|
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const = 0;
|
||||||
|
|
||||||
|
static boost::signals2::signal<void (ScriptFrame& frame, ScriptError *ex, const DebugInfo& di)> OnBreakpoint;
|
||||||
|
|
||||||
|
static void ScriptBreakpoint(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di);
|
||||||
};
|
};
|
||||||
|
|
||||||
I2_CONFIG_API Expression *MakeIndexer(ScopeSpecifier scopeSpec, const String& index);
|
I2_CONFIG_API Expression *MakeIndexer(ScopeSpecifier scopeSpec, const String& index);
|
||||||
@ -937,6 +941,17 @@ private:
|
|||||||
String m_Package;
|
String m_Package;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class I2_CONFIG_API BreakpointExpression : public DebuggableExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BreakpointExpression(const DebugInfo& debugInfo = DebugInfo())
|
||||||
|
: DebuggableExpression(debugInfo)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EXPRESSION_H */
|
#endif /* EXPRESSION_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user