mirror of https://github.com/Icinga/icinga2.git
parent
b61f803d60
commit
ab63fca3d5
|
@ -69,6 +69,8 @@ void ThreadPool::Stop(void)
|
|||
}
|
||||
|
||||
m_ThreadGroup.join_all();
|
||||
|
||||
m_Stopped = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -201,6 +201,8 @@ static void SigHupHandler(int)
|
|||
static bool Daemonize(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
Application::GetTP().Stop();
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
return false;
|
||||
|
@ -231,6 +233,8 @@ static bool Daemonize(void)
|
|||
|
||||
Application::Exit(0);
|
||||
}
|
||||
|
||||
Application::GetTP().Start();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return true;
|
||||
|
|
|
@ -60,54 +60,6 @@ do { \
|
|||
do { \
|
||||
result = yyextra->ReadInput(buf, max_size); \
|
||||
} while (0)
|
||||
|
||||
extern int ignore_newlines;
|
||||
|
||||
struct lex_buf {
|
||||
char *buf;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static void lb_init(lex_buf *lb)
|
||||
{
|
||||
lb->buf = NULL;
|
||||
lb->size = 0;
|
||||
}
|
||||
|
||||
/*static void lb_cleanup(lex_buf *lb)
|
||||
{
|
||||
free(lb->buf);
|
||||
}*/
|
||||
|
||||
static void lb_append_char(lex_buf *lb, char new_char)
|
||||
{
|
||||
const size_t block_size = 64;
|
||||
|
||||
size_t old_blocks = (lb->size + (block_size - 1)) / block_size;
|
||||
size_t new_blocks = ((lb->size + 1) + (block_size - 1)) / block_size;
|
||||
|
||||
if (old_blocks != new_blocks) {
|
||||
char *new_buf = (char *)realloc(lb->buf, new_blocks * block_size);
|
||||
|
||||
if (new_buf == NULL && new_blocks > 0)
|
||||
throw std::bad_alloc();
|
||||
|
||||
lb->buf = new_buf;
|
||||
}
|
||||
|
||||
lb->size++;
|
||||
lb->buf[lb->size - 1] = new_char;
|
||||
}
|
||||
|
||||
static char *lb_steal(lex_buf *lb)
|
||||
{
|
||||
lb_append_char(lb, '\0');
|
||||
|
||||
char *buf = lb->buf;
|
||||
lb->buf = NULL;
|
||||
lb->size = 0;
|
||||
return buf;
|
||||
}
|
||||
%}
|
||||
|
||||
%option reentrant noyywrap yylineno
|
||||
|
@ -120,25 +72,19 @@ static char *lb_steal(lex_buf *lb)
|
|||
%x HEREDOC
|
||||
|
||||
%%
|
||||
lex_buf string_buf;
|
||||
|
||||
\" { lb_init(&string_buf); BEGIN(STRING); }
|
||||
\" { yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(STRING); }
|
||||
|
||||
<STRING>\" {
|
||||
BEGIN(INITIAL);
|
||||
|
||||
lb_append_char(&string_buf, '\0');
|
||||
|
||||
yylval->text = lb_steal(&string_buf);
|
||||
std::string str = yyextra->m_LexBuffer.str();
|
||||
yylval->text = strdup(str.c_str());
|
||||
|
||||
return T_STRING;
|
||||
}
|
||||
|
||||
<STRING>\n {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Unterminated string found: " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
BEGIN(INITIAL);
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Unterminated string literal") << errinfo_debuginfo(*yylloc));
|
||||
}
|
||||
|
||||
<STRING>\\[0-7]{1,3} {
|
||||
|
@ -149,50 +95,45 @@ static char *lb_steal(lex_buf *lb)
|
|||
|
||||
if (result > 0xff) {
|
||||
/* error, constant is out-of-bounds */
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Constant is out-of-bounds: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Constant is out of bounds: " + String(yytext)) << errinfo_debuginfo(*yylloc));
|
||||
}
|
||||
|
||||
lb_append_char(&string_buf, result);
|
||||
yyextra->m_LexBuffer << static_cast<char>(result);
|
||||
}
|
||||
|
||||
<STRING>\\[0-9]+ {
|
||||
/* generate error - bad escape sequence; something
|
||||
* like '\48' or '\0777777'
|
||||
*/
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Bad escape sequence found: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
BOOST_THROW_EXCEPTION(ConfigError("Bad escape sequence found: " + String(yytext)) << errinfo_debuginfo(*yylloc));
|
||||
}
|
||||
|
||||
<STRING>\\n { lb_append_char(&string_buf, '\n'); }
|
||||
<STRING>\\t { lb_append_char(&string_buf, '\t'); }
|
||||
<STRING>\\r { lb_append_char(&string_buf, '\r'); }
|
||||
<STRING>\\b { lb_append_char(&string_buf, '\b'); }
|
||||
<STRING>\\f { lb_append_char(&string_buf, '\f'); }
|
||||
<STRING>\\(.|\n) { lb_append_char(&string_buf, yytext[1]); }
|
||||
<STRING>\\n { yyextra->m_LexBuffer << "\n"; }
|
||||
<STRING>\\t { yyextra->m_LexBuffer << "\t"; }
|
||||
<STRING>\\r { yyextra->m_LexBuffer << "\r"; }
|
||||
<STRING>\\b { yyextra->m_LexBuffer << "\b"; }
|
||||
<STRING>\\f { yyextra->m_LexBuffer << "\f"; }
|
||||
<STRING>\\(.|\n) { yyextra->m_LexBuffer << yytext[1]; }
|
||||
|
||||
<STRING>[^\\\n\"]+ {
|
||||
char *yptr = yytext;
|
||||
|
||||
while (*yptr)
|
||||
lb_append_char(&string_buf, *yptr++);
|
||||
yyextra->m_LexBuffer << *yptr++;
|
||||
}
|
||||
|
||||
\{\{\{ { lb_init(&string_buf); BEGIN(HEREDOC); }
|
||||
\{\{\{ { yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(HEREDOC); }
|
||||
|
||||
<HEREDOC>\}\}\} {
|
||||
BEGIN(INITIAL);
|
||||
|
||||
lb_append_char(&string_buf, '\0');
|
||||
|
||||
yylval->text = lb_steal(&string_buf);
|
||||
std::string str = yyextra->m_LexBuffer.str();
|
||||
yylval->text = strdup(str.c_str());
|
||||
|
||||
return T_STRING;
|
||||
}
|
||||
|
||||
<HEREDOC>(.|\n) { lb_append_char(&string_buf, yytext[0]); }
|
||||
<HEREDOC>(.|\n) { yyextra->m_LexBuffer << yytext[0]; }
|
||||
|
||||
<INITIAL>{
|
||||
"/*" BEGIN(C_COMMENT);
|
||||
|
@ -205,10 +146,7 @@ static char *lb_steal(lex_buf *lb)
|
|||
}
|
||||
|
||||
<C_COMMENT><<EOF>> {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "End-of-file while in comment: " << yytext << " " << *yylloc;
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
|
||||
yyterminate();
|
||||
BOOST_THROW_EXCEPTION(ConfigError("End-of-file while in comment") << errinfo_debuginfo(*yylloc));
|
||||
}
|
||||
|
||||
|
||||
|
@ -294,7 +232,7 @@ in return T_IN;
|
|||
\> return T_GREATER_THAN;
|
||||
}
|
||||
|
||||
[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!ignore_newlines) return T_NEWLINE; }
|
||||
[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) return T_NEWLINE; }
|
||||
<<EOF>> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } }
|
||||
. return yytext[0];
|
||||
|
||||
|
|
|
@ -69,8 +69,6 @@ do { \
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
int ignore_newlines = 0;
|
||||
|
||||
template<typename T>
|
||||
static void MakeRBinaryOp(Expression** result, Expression *left, Expression *right, DebugInfo& diLeft, DebugInfo& diRight)
|
||||
{
|
||||
|
@ -230,32 +228,21 @@ int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
|
|||
|
||||
void yyerror(YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << *locp << ": " << err;
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message.str(), *locp);
|
||||
BOOST_THROW_EXCEPTION(ConfigError(err) << errinfo_debuginfo(*locp));
|
||||
}
|
||||
|
||||
int yyparse(std::vector<Expression *> *elist, ConfigCompiler *context);
|
||||
|
||||
Expression *ConfigCompiler::Compile(void)
|
||||
{
|
||||
try {
|
||||
std::vector<Expression *> elist;
|
||||
std::vector<Expression *> elist;
|
||||
|
||||
if (yyparse(&elist, this) != 0)
|
||||
return NULL;
|
||||
if (yyparse(&elist, this) != 0)
|
||||
return NULL;
|
||||
|
||||
DictExpression *expr = new DictExpression(elist);
|
||||
expr->MakeInline();
|
||||
return expr;
|
||||
} catch (const ConfigError& ex) {
|
||||
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
|
||||
} catch (const std::exception& ex) {
|
||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
DictExpression *expr = new DictExpression(elist);
|
||||
expr->MakeInline();
|
||||
return expr;
|
||||
}
|
||||
|
||||
#define scanner (context->GetScanner())
|
||||
|
@ -788,11 +775,11 @@ rterm_without_indexer: T_STRING
|
|||
}
|
||||
| '('
|
||||
{
|
||||
ignore_newlines++;
|
||||
context->m_IgnoreNewlines++;
|
||||
}
|
||||
rterm ')'
|
||||
{
|
||||
ignore_newlines--;
|
||||
context->m_IgnoreNewlines--;
|
||||
$$ = $3;
|
||||
}
|
||||
| rterm T_LOGICAL_OR rterm { MakeRBinaryOp<LogicalOrExpression>(&$$, $1, $3, @1, @3); }
|
||||
|
|
|
@ -41,7 +41,7 @@ std::vector<String> ConfigCompiler::m_IncludeSearchDirs;
|
|||
* @param zone The zone.
|
||||
*/
|
||||
ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
|
||||
: m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false)
|
||||
: m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_IgnoreNewlines(0)
|
||||
{
|
||||
InitializeScanner();
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const St
|
|||
ConfigCompiler::~ConfigCompiler(void)
|
||||
{
|
||||
DestroyScanner();
|
||||
delete m_Input;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,6 +174,17 @@ void ConfigCompiler::HandleLibrary(const String& library)
|
|||
(void) Utility::LoadExtensionLibrary(library);
|
||||
}
|
||||
|
||||
void ConfigCompiler::CompileHelper(void)
|
||||
{
|
||||
try {
|
||||
m_Promise.set_value(boost::shared_ptr<Expression>(Compile()));
|
||||
} catch (...) {
|
||||
m_Promise.set_exception(boost::current_exception());
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a stream.
|
||||
*
|
||||
|
@ -186,8 +198,12 @@ Expression *ConfigCompiler::CompileStream(const String& path, std::istream *stre
|
|||
|
||||
stream->exceptions(std::istream::badbit);
|
||||
|
||||
ConfigCompiler ctx(path, stream, zone);
|
||||
return ctx.Compile();
|
||||
ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone);
|
||||
|
||||
boost::shared_future<boost::shared_ptr<Expression> > ftr = boost::shared_future<boost::shared_ptr<Expression> >(ctx->m_Promise.get_future());
|
||||
|
||||
Utility::QueueAsyncCallback(boost::bind(&ConfigCompiler::CompileHelper, ctx));
|
||||
return new FutureExpression(ftr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,10 +216,10 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
|
|||
{
|
||||
CONTEXT("Compiling configuration file '" + path + "'");
|
||||
|
||||
std::ifstream stream;
|
||||
stream.open(path.CStr(), std::ifstream::in);
|
||||
std::ifstream *stream = new std::ifstream();
|
||||
stream->open(path.CStr(), std::ifstream::in);
|
||||
|
||||
if (!stream)
|
||||
if (!*stream)
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("std::ifstream::open")
|
||||
<< boost::errinfo_errno(errno)
|
||||
|
@ -212,7 +228,7 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
|
|||
Log(LogInformation, "ConfigCompiler")
|
||||
<< "Compiling config file: " << path;
|
||||
|
||||
return CompileStream(path, &stream, zone);
|
||||
return CompileStream(path, stream, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,8 +240,8 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
|
|||
*/
|
||||
Expression *ConfigCompiler::CompileText(const String& path, const String& text, const String& zone)
|
||||
{
|
||||
std::stringstream stream(text);
|
||||
return CompileStream(path, &stream, zone);
|
||||
std::stringstream *stream = new std::stringstream(text);
|
||||
return CompileStream(path, stream, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
void *GetScanner(void) const;
|
||||
|
||||
private:
|
||||
boost::promise<boost::shared_ptr<Expression> > m_Promise;
|
||||
|
||||
String m_Path;
|
||||
std::istream *m_Input;
|
||||
String m_Zone;
|
||||
|
@ -88,6 +90,9 @@ private:
|
|||
void *m_Scanner;
|
||||
bool m_Eof;
|
||||
|
||||
int m_IgnoreNewlines;
|
||||
std::ostringstream m_LexBuffer;
|
||||
|
||||
std::stack<TypeRuleList::Ptr> m_RuleLists;
|
||||
ConfigType::Ptr m_Type;
|
||||
|
||||
|
@ -105,6 +110,8 @@ private:
|
|||
void InitializeScanner(void);
|
||||
void DestroyScanner(void);
|
||||
|
||||
void CompileHelper(void);
|
||||
|
||||
friend int ::yylex(YYSTYPE *context, icinga::DebugInfo *di, yyscan_t scanner);
|
||||
friend int ::yyparse(std::vector<icinga::Expression *> *elist, ConfigCompiler *context);
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "base/configerror.hpp"
|
||||
#include "base/convert.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace icinga
|
||||
|
@ -164,6 +165,28 @@ private:
|
|||
boost::shared_ptr<Expression> m_Expression;
|
||||
};
|
||||
|
||||
class I2_CONFIG_API FutureExpression : public Expression
|
||||
{
|
||||
public:
|
||||
FutureExpression(const boost::shared_future<boost::shared_ptr<Expression> >& future)
|
||||
: m_Future(future)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
return m_Future.get()->DoEvaluate(frame, dhint);
|
||||
}
|
||||
|
||||
virtual const DebugInfo& GetDebugInfo(void) const
|
||||
{
|
||||
return m_Future.get()->GetDebugInfo();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable boost::shared_future<boost::shared_ptr<Expression> > m_Future;
|
||||
};
|
||||
|
||||
class I2_CONFIG_API LiteralExpression : public Expression
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue