Fixed memory leaks in the parser.

Improved Dictionary performance.
This commit is contained in:
Gunnar Beutner 2012-06-06 14:38:28 +02:00
parent 100287dfdb
commit 3e2b5d5269
18 changed files with 494 additions and 249 deletions

View File

@ -87,7 +87,10 @@ public:
template<typename T> template<typename T>
void SetProperty(string key, const T& value) void SetProperty(string key, const T& value)
{ {
m_Data[key] = value; pair<typename map<string, Variant>::iterator, bool> ret;
ret = m_Data.insert(make_pair(key, value));
if (!ret.second)
ret.first->second = value;
} }
/** /**

View File

@ -24,7 +24,7 @@ AX_SET_VERSION_INFO
AC_CONFIG_AUX_DIR([config]) AC_CONFIG_AUX_DIR([config])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE($PACKAGE,$VERSION) AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
#AM_SILENT_RULES([yes]) AM_SILENT_RULES([yes])
AC_PROG_CXX AC_PROG_CXX
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS

View File

@ -9,13 +9,15 @@ BUILT_SOURCES = config_parser.h
AM_YFLAGS = -d AM_YFLAGS = -d
libdyn_la_SOURCES = \ libdyn_la_SOURCES = \
configcontext.cpp \ configcompiler.cpp \
configcontext.h \ configcompiler.h \
configvm.cpp \
configvm.h \
config_lexer.ll \ config_lexer.ll \
config_parser.yy \ config_parser.yy \
i2-dyn.h \ i2-dyn.h \
dconfigobject.cpp \ configitem.cpp \
dconfigobject.h \ configitem.h \
expression.cpp \ expression.cpp \
expression.h \ expression.h \
expressionlist.cpp \ expressionlist.cpp \

View File

@ -529,8 +529,15 @@ static yyconst flex_int32_t yy_rule_can_match_eol[24] =
using namespace icinga; using namespace icinga;
#define YY_EXTRA_TYPE ConfigContext * #define YY_EXTRA_TYPE ConfigCompiler *
#define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_USER_ACTION \
do { \
yylloc->FirstLine = yylineno; \
yylloc->FirstColumn = yycolumn; \
yylloc->LastLine = yylineno; \
yylloc->LastColumn = yycolumn + yyleng - 1; \
yycolumn += yyleng; \
} while (0);
#define YY_INPUT(buf, result, max_size) \ #define YY_INPUT(buf, result, max_size) \
do { \ do { \
@ -538,7 +545,7 @@ do { \
} while (0) } while (0)
#define YY_NO_UNISTD_H 1 #define YY_NO_UNISTD_H 1
#line 542 "config_lexer.cc" #line 549 "config_lexer.cc"
#define INITIAL 0 #define INITIAL 0
#define IN_C_COMMENT 1 #define IN_C_COMMENT 1
@ -785,9 +792,9 @@ YY_DECL
register int yy_act; register int yy_act;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
#line 41 "config_lexer.ll" #line 48 "config_lexer.ll"
#line 791 "config_lexer.cc" #line 798 "config_lexer.cc"
yylval = yylval_param; yylval = yylval_param;
@ -884,127 +891,127 @@ do_action: /* This label is used only to access EOF actions. */
case 1: case 1:
YY_RULE_SETUP YY_RULE_SETUP
#line 42 "config_lexer.ll" #line 49 "config_lexer.ll"
return T_ABSTRACT; return T_ABSTRACT;
YY_BREAK YY_BREAK
case 2: case 2:
YY_RULE_SETUP YY_RULE_SETUP
#line 43 "config_lexer.ll" #line 50 "config_lexer.ll"
return T_LOCAL; return T_LOCAL;
YY_BREAK YY_BREAK
case 3: case 3:
YY_RULE_SETUP YY_RULE_SETUP
#line 44 "config_lexer.ll" #line 51 "config_lexer.ll"
return T_OBJECT; return T_OBJECT;
YY_BREAK YY_BREAK
case 4: case 4:
YY_RULE_SETUP YY_RULE_SETUP
#line 45 "config_lexer.ll" #line 52 "config_lexer.ll"
return T_INCLUDE; return T_INCLUDE;
YY_BREAK YY_BREAK
case 5: case 5:
YY_RULE_SETUP YY_RULE_SETUP
#line 46 "config_lexer.ll" #line 53 "config_lexer.ll"
return T_INHERITS; return T_INHERITS;
YY_BREAK YY_BREAK
case 6: case 6:
YY_RULE_SETUP YY_RULE_SETUP
#line 47 "config_lexer.ll" #line 54 "config_lexer.ll"
return T_NULL; return T_NULL;
YY_BREAK YY_BREAK
case 7: case 7:
YY_RULE_SETUP YY_RULE_SETUP
#line 48 "config_lexer.ll" #line 55 "config_lexer.ll"
{ yylval->text = strdup(yytext); return T_IDENTIFIER; } { yylval->text = strdup(yytext); return T_IDENTIFIER; }
YY_BREAK YY_BREAK
case 8: case 8:
/* rule 8 can match eol */ /* rule 8 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 49 "config_lexer.ll" #line 56 "config_lexer.ll"
{ yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING; } { yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING; }
YY_BREAK YY_BREAK
case 9: case 9:
YY_RULE_SETUP YY_RULE_SETUP
#line 50 "config_lexer.ll" #line 57 "config_lexer.ll"
{ yylval->num = atoi(yytext); return T_NUMBER; } { yylval->num = atoi(yytext); return T_NUMBER; }
YY_BREAK YY_BREAK
case 10: case 10:
YY_RULE_SETUP YY_RULE_SETUP
#line 51 "config_lexer.ll" #line 58 "config_lexer.ll"
{ yylval->op = OperatorSet; return T_EQUAL; } { yylval->op = OperatorSet; return T_EQUAL; }
YY_BREAK YY_BREAK
case 11: case 11:
YY_RULE_SETUP YY_RULE_SETUP
#line 52 "config_lexer.ll" #line 59 "config_lexer.ll"
{ yylval->op = OperatorPlus; return T_PLUS_EQUAL; } { yylval->op = OperatorPlus; return T_PLUS_EQUAL; }
YY_BREAK YY_BREAK
case 12: case 12:
YY_RULE_SETUP YY_RULE_SETUP
#line 53 "config_lexer.ll" #line 60 "config_lexer.ll"
{ yylval->op = OperatorMinus; return T_MINUS_EQUAL; } { yylval->op = OperatorMinus; return T_MINUS_EQUAL; }
YY_BREAK YY_BREAK
case 13: case 13:
YY_RULE_SETUP YY_RULE_SETUP
#line 54 "config_lexer.ll" #line 61 "config_lexer.ll"
{ yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; } { yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; }
YY_BREAK YY_BREAK
case 14: case 14:
YY_RULE_SETUP YY_RULE_SETUP
#line 55 "config_lexer.ll" #line 62 "config_lexer.ll"
{ yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; } { yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; }
YY_BREAK YY_BREAK
case 15: case 15:
YY_RULE_SETUP YY_RULE_SETUP
#line 58 "config_lexer.ll" #line 65 "config_lexer.ll"
BEGIN(IN_C_COMMENT); BEGIN(IN_C_COMMENT);
YY_BREAK YY_BREAK
case 16: case 16:
YY_RULE_SETUP YY_RULE_SETUP
#line 62 "config_lexer.ll" #line 69 "config_lexer.ll"
BEGIN(INITIAL); BEGIN(INITIAL);
YY_BREAK YY_BREAK
case 17: case 17:
/* rule 17 can match eol */ /* rule 17 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 63 "config_lexer.ll" #line 70 "config_lexer.ll"
/* ignore comment */ /* ignore comment */
YY_BREAK YY_BREAK
case 18: case 18:
YY_RULE_SETUP YY_RULE_SETUP
#line 64 "config_lexer.ll" #line 71 "config_lexer.ll"
/* ignore star */ /* ignore star */
YY_BREAK YY_BREAK
case 19: case 19:
YY_RULE_SETUP YY_RULE_SETUP
#line 67 "config_lexer.ll" #line 74 "config_lexer.ll"
/* ignore C++-style comments */ /* ignore C++-style comments */
YY_BREAK YY_BREAK
case 20: case 20:
YY_RULE_SETUP YY_RULE_SETUP
#line 68 "config_lexer.ll" #line 75 "config_lexer.ll"
/* ignore shell-style comments */ /* ignore shell-style comments */
YY_BREAK YY_BREAK
case 21: case 21:
/* rule 21 can match eol */ /* rule 21 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 69 "config_lexer.ll" #line 76 "config_lexer.ll"
/* ignore whitespace */ /* ignore whitespace */
YY_BREAK YY_BREAK
case 22: case 22:
YY_RULE_SETUP YY_RULE_SETUP
#line 71 "config_lexer.ll" #line 78 "config_lexer.ll"
return yytext[0]; return yytext[0];
YY_BREAK YY_BREAK
case 23: case 23:
YY_RULE_SETUP YY_RULE_SETUP
#line 72 "config_lexer.ll" #line 79 "config_lexer.ll"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 1008 "config_lexer.cc" #line 1015 "config_lexer.cc"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(IN_C_COMMENT): case YY_STATE_EOF(IN_C_COMMENT):
yyterminate(); yyterminate();
@ -2192,18 +2199,18 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#line 72 "config_lexer.ll" #line 79 "config_lexer.ll"
void ConfigContext::InitializeScanner(void) void ConfigCompiler::InitializeScanner(void)
{ {
yylex_init(&m_Scanner); yylex_init(&m_Scanner);
yyset_extra(this,m_Scanner); yyset_extra(this,m_Scanner);
} }
void ConfigContext::DestroyScanner(void) void ConfigCompiler::DestroyScanner(void)
{ {
yylex_destroy(m_Scanner); yylex_destroy(m_Scanner);
} }

View File

@ -23,8 +23,15 @@
using namespace icinga; using namespace icinga;
#define YY_EXTRA_TYPE ConfigContext * #define YY_EXTRA_TYPE ConfigCompiler *
#define YY_USER_ACTION yylloc->first_line = yylineno; #define YY_USER_ACTION \
do { \
yylloc->FirstLine = yylineno; \
yylloc->FirstColumn = yycolumn; \
yylloc->LastLine = yylineno; \
yylloc->LastColumn = yycolumn + yyleng - 1; \
yycolumn += yyleng; \
} while (0);
#define YY_INPUT(buf, result, max_size) \ #define YY_INPUT(buf, result, max_size) \
do { \ do { \
@ -72,13 +79,13 @@ null return T_NULL;
%% %%
void ConfigContext::InitializeScanner(void) void ConfigCompiler::InitializeScanner(void)
{ {
yylex_init(&m_Scanner); yylex_init(&m_Scanner);
yyset_extra(this, m_Scanner); yyset_extra(this, m_Scanner);
} }
void ConfigContext::DestroyScanner(void) void ConfigCompiler::DestroyScanner(void)
{ {
yylex_destroy(m_Scanner); yylex_destroy(m_Scanner);
} }

View File

@ -65,7 +65,31 @@
/* Copy the first part of user declarations. */ /* Copy the first part of user declarations. */
/* Line 268 of yacc.c */ /* Line 268 of yacc.c */
#line 71 "config_parser.cc"
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 1
#endif
/* Enabling the token table. */
#ifndef YYTOKEN_TABLE
# define YYTOKEN_TABLE 0
#endif
/* "%code requires" blocks. */
/* Line 288 of yacc.c */
#line 1 "config_parser.yy" #line 1 "config_parser.yy"
/****************************************************************************** /******************************************************************************
@ -91,29 +115,13 @@
using namespace icinga; using namespace icinga;
#define YYLTYPE DebugInfo
/* Line 268 of yacc.c */
#line 98 "config_parser.cc"
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 1
#endif
/* Enabling the token table. */
#ifndef YYTOKEN_TABLE
# define YYTOKEN_TABLE 0
#endif
/* Line 288 of yacc.c */
#line 125 "config_parser.cc"
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
@ -161,7 +169,7 @@ typedef union YYSTYPE
{ {
/* Line 293 of yacc.c */ /* Line 293 of yacc.c */
#line 36 "config_parser.yy" #line 38 "config_parser.yy"
char *text; char *text;
int num; int num;
@ -171,7 +179,7 @@ typedef union YYSTYPE
/* Line 293 of yacc.c */ /* Line 293 of yacc.c */
#line 175 "config_parser.cc" #line 183 "config_parser.cc"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -195,12 +203,12 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */ /* Copy the second part of user declarations. */
/* Line 343 of yacc.c */ /* Line 343 of yacc.c */
#line 64 "config_parser.yy" #line 66 "config_parser.yy"
int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
void yyerror(YYLTYPE *locp, ConfigContext *context, const char *err) void yyerror(YYLTYPE *locp, ConfigCompiler *context, const char *err)
{ {
stringstream message; stringstream message;
@ -212,25 +220,29 @@ void yyerror(YYLTYPE *locp, ConfigContext *context, const char *err)
throw runtime_error(message.str()); throw runtime_error(message.str());
} }
int yyparse(ConfigContext *context); int yyparse(ConfigCompiler *context);
void ConfigContext::Compile(void)
{
yyparse(this);
}
#define scanner (context->GetScanner())
static stack<ExpressionList::Ptr> m_ExpressionLists; static stack<ExpressionList::Ptr> m_ExpressionLists;
static set<DConfigObject::Ptr> m_Objects; static vector<ConfigItem::Ptr> m_Objects;
static DConfigObject::Ptr m_Object; static ConfigItem::Ptr m_Object;
static bool m_Abstract; static bool m_Abstract;
static bool m_Local; static bool m_Local;
static Dictionary::Ptr m_Array; static Dictionary::Ptr m_Array;
void ConfigCompiler::Compile(void)
{
m_Objects.clear();
yyparse(this);
SetResult(m_Objects);
m_Objects.clear();
}
#define scanner (context->GetScanner())
/* Line 343 of yacc.c */ /* Line 343 of yacc.c */
#line 234 "config_parser.cc" #line 246 "config_parser.cc"
#ifdef short #ifdef short
# undef short # undef short
@ -533,11 +545,11 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] = static const yytype_uint16 yyrline[] =
{ {
0, 98, 98, 99, 105, 105, 108, 112, 117, 112, 0, 104, 104, 105, 108, 108, 111, 115, 120, 115,
148, 149, 152, 156, 162, 163, 166, 172, 173, 177, 150, 151, 154, 158, 164, 165, 168, 175, 176, 180,
176, 188, 189, 190, 193, 201, 214, 223, 224, 225, 179, 191, 192, 193, 196, 204, 218, 227, 228, 229,
226, 227, 233, 237, 241, 247, 248, 249, 256, 255, 230, 231, 237, 242, 246, 252, 253, 254, 261, 260,
267, 273, 275, 276 272, 278, 280, 281
}; };
#endif #endif
@ -803,7 +815,7 @@ do { \
#if (defined __STDC__ || defined __C99__FUNC__ \ #if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER) || defined __cplusplus || defined _MSC_VER)
static void static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ConfigContext *context) yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ConfigCompiler *context)
#else #else
static void static void
yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context)
@ -811,7 +823,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context)
int yytype; int yytype;
YYSTYPE const * const yyvaluep; YYSTYPE const * const yyvaluep;
YYLTYPE const * const yylocationp; YYLTYPE const * const yylocationp;
ConfigContext *context; ConfigCompiler *context;
#endif #endif
{ {
if (!yyvaluep) if (!yyvaluep)
@ -839,7 +851,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context)
#if (defined __STDC__ || defined __C99__FUNC__ \ #if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER) || defined __cplusplus || defined _MSC_VER)
static void static void
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ConfigContext *context) yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ConfigCompiler *context)
#else #else
static void static void
yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context)
@ -847,7 +859,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context)
int yytype; int yytype;
YYSTYPE const * const yyvaluep; YYSTYPE const * const yyvaluep;
YYLTYPE const * const yylocationp; YYLTYPE const * const yylocationp;
ConfigContext *context; ConfigCompiler *context;
#endif #endif
{ {
if (yytype < YYNTOKENS) if (yytype < YYNTOKENS)
@ -900,14 +912,14 @@ do { \
#if (defined __STDC__ || defined __C99__FUNC__ \ #if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER) || defined __cplusplus || defined _MSC_VER)
static void static void
yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, ConfigContext *context) yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, ConfigCompiler *context)
#else #else
static void static void
yy_reduce_print (yyvsp, yylsp, yyrule, context) yy_reduce_print (yyvsp, yylsp, yyrule, context)
YYSTYPE *yyvsp; YYSTYPE *yyvsp;
YYLTYPE *yylsp; YYLTYPE *yylsp;
int yyrule; int yyrule;
ConfigContext *context; ConfigCompiler *context;
#endif #endif
{ {
int yynrhs = yyr2[yyrule]; int yynrhs = yyr2[yyrule];
@ -1206,7 +1218,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
#if (defined __STDC__ || defined __C99__FUNC__ \ #if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER) || defined __cplusplus || defined _MSC_VER)
static void static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, ConfigContext *context) yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, ConfigCompiler *context)
#else #else
static void static void
yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) yydestruct (yymsg, yytype, yyvaluep, yylocationp, context)
@ -1214,7 +1226,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, context)
int yytype; int yytype;
YYSTYPE *yyvaluep; YYSTYPE *yyvaluep;
YYLTYPE *yylocationp; YYLTYPE *yylocationp;
ConfigContext *context; ConfigCompiler *context;
#endif #endif
{ {
YYUSE (yyvaluep); YYUSE (yyvaluep);
@ -1243,7 +1255,7 @@ int yyparse ();
#endif #endif
#else /* ! YYPARSE_PARAM */ #else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus #if defined __STDC__ || defined __cplusplus
int yyparse (ConfigContext *context); int yyparse (ConfigCompiler *context);
#else #else
int yyparse (); int yyparse ();
#endif #endif
@ -1268,11 +1280,11 @@ yyparse (YYPARSE_PARAM)
#if (defined __STDC__ || defined __C99__FUNC__ \ #if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER) || defined __cplusplus || defined _MSC_VER)
int int
yyparse (ConfigContext *context) yyparse (ConfigCompiler *context)
#else #else
int int
yyparse (context) yyparse (context)
ConfigContext *context; ConfigCompiler *context;
#endif #endif
#endif #endif
{ {
@ -1551,19 +1563,10 @@ yyreduce:
YY_REDUCE_PRINT (yyn); YY_REDUCE_PRINT (yyn);
switch (yyn) switch (yyn)
{ {
case 3: case 7:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 100 "config_parser.yy" #line 115 "config_parser.yy"
{
context->SetResult(m_Objects);
}
break;
case 7:
/* Line 1806 of yacc.c */
#line 112 "config_parser.yy"
{ {
m_Abstract = false; m_Abstract = false;
m_Local = false; m_Local = false;
@ -1573,9 +1576,9 @@ yyreduce:
case 8: case 8:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 117 "config_parser.yy" #line 120 "config_parser.yy"
{ {
m_Object = make_shared<DConfigObject>((yyvsp[(4) - (5)].text), (yyvsp[(5) - (5)].text), yylloc.first_line); m_Object = make_shared<ConfigItem>((yyvsp[(4) - (5)].text), (yyvsp[(5) - (5)].text), yylloc);
free((yyvsp[(4) - (5)].text)); free((yyvsp[(4) - (5)].text));
free((yyvsp[(5) - (5)].text)); free((yyvsp[(5) - (5)].text));
} }
@ -1584,28 +1587,27 @@ yyreduce:
case 9: case 9:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 123 "config_parser.yy" #line 126 "config_parser.yy"
{ {
Object::Ptr exprl_object = *(yyvsp[(8) - (8)].variant); Object::Ptr exprl_object = *(yyvsp[(8) - (8)].variant);
delete (yyvsp[(8) - (8)].variant); delete (yyvsp[(8) - (8)].variant);
ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object); ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object);
Expression typeexpr("__type", OperatorSet, m_Object->GetType(), yylloc.first_line); Expression typeexpr("__type", OperatorSet, m_Object->GetType(), yylloc);
exprl->AddExpression(typeexpr); exprl->AddExpression(typeexpr);
Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc.first_line); Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc);
exprl->AddExpression(nameexpr); exprl->AddExpression(nameexpr);
Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc.first_line); Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc);
exprl->AddExpression(abstractexpr); exprl->AddExpression(abstractexpr);
Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc.first_line); Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc);
exprl->AddExpression(localexpr); exprl->AddExpression(localexpr);
m_Object->SetExpressionList(exprl); m_Object->SetExpressionList(exprl);
DConfigObject::AddObject(m_Object); m_Objects.push_back(m_Object);
m_Objects.insert(m_Object);
m_Object.reset(); m_Object.reset();
} }
break; break;
@ -1613,7 +1615,7 @@ yyreduce:
case 12: case 12:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 153 "config_parser.yy" #line 155 "config_parser.yy"
{ {
m_Abstract = true; m_Abstract = true;
} }
@ -1622,7 +1624,7 @@ yyreduce:
case 13: case 13:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 157 "config_parser.yy" #line 159 "config_parser.yy"
{ {
m_Local = true; m_Local = true;
} }
@ -1631,16 +1633,17 @@ yyreduce:
case 16: case 16:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 167 "config_parser.yy" #line 169 "config_parser.yy"
{ {
m_Object->AddParent((yyvsp[(1) - (1)].text)); m_Object->AddParent((yyvsp[(1) - (1)].text));
free((yyvsp[(1) - (1)].text));
} }
break; break;
case 19: case 19:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 177 "config_parser.yy" #line 180 "config_parser.yy"
{ {
m_ExpressionLists.push(make_shared<ExpressionList>()); m_ExpressionLists.push(make_shared<ExpressionList>());
} }
@ -1649,7 +1652,7 @@ yyreduce:
case 20: case 20:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 182 "config_parser.yy" #line 185 "config_parser.yy"
{ {
(yyval.variant) = new Variant(m_ExpressionLists.top()); (yyval.variant) = new Variant(m_ExpressionLists.top());
m_ExpressionLists.pop(); m_ExpressionLists.pop();
@ -1659,9 +1662,9 @@ yyreduce:
case 24: case 24:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 194 "config_parser.yy" #line 197 "config_parser.yy"
{ {
Expression expr((yyvsp[(1) - (3)].text), (yyvsp[(2) - (3)].op), *(yyvsp[(3) - (3)].variant), yylloc.first_line); Expression expr((yyvsp[(1) - (3)].text), (yyvsp[(2) - (3)].op), *(yyvsp[(3) - (3)].variant), yylloc);
free((yyvsp[(1) - (3)].text)); free((yyvsp[(1) - (3)].text));
delete (yyvsp[(3) - (3)].variant); delete (yyvsp[(3) - (3)].variant);
@ -1672,16 +1675,17 @@ yyreduce:
case 25: case 25:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 202 "config_parser.yy" #line 205 "config_parser.yy"
{ {
Expression subexpr((yyvsp[(3) - (6)].text), (yyvsp[(5) - (6)].op), *(yyvsp[(6) - (6)].variant), yylloc.first_line); Expression subexpr((yyvsp[(3) - (6)].text), (yyvsp[(5) - (6)].op), *(yyvsp[(6) - (6)].variant), yylloc);
free((yyvsp[(3) - (6)].text)); free((yyvsp[(3) - (6)].text));
delete (yyvsp[(6) - (6)].variant); delete (yyvsp[(6) - (6)].variant);
ExpressionList::Ptr subexprl = make_shared<ExpressionList>(); ExpressionList::Ptr subexprl = make_shared<ExpressionList>();
subexprl->AddExpression(subexpr); subexprl->AddExpression(subexpr);
Expression expr((yyvsp[(1) - (6)].text), OperatorPlus, subexprl, yylloc.first_line); Expression expr((yyvsp[(1) - (6)].text), OperatorPlus, subexprl, yylloc);
free((yyvsp[(1) - (6)].text));
m_ExpressionLists.top()->AddExpression(expr); m_ExpressionLists.top()->AddExpression(expr);
} }
@ -1690,11 +1694,11 @@ yyreduce:
case 26: case 26:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 215 "config_parser.yy" #line 219 "config_parser.yy"
{ {
Expression expr((yyvsp[(1) - (1)].text), OperatorSet, (yyvsp[(1) - (1)].text), yylloc.first_line); Expression expr((yyvsp[(1) - (1)].text), OperatorSet, (yyvsp[(1) - (1)].text), yylloc);
free((yyvsp[(1) - (1)].text)); free((yyvsp[(1) - (1)].text));
m_ExpressionLists.top()->AddExpression(expr); m_ExpressionLists.top()->AddExpression(expr);
} }
break; break;
@ -1702,7 +1706,7 @@ yyreduce:
case 31: case 31:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 228 "config_parser.yy" #line 232 "config_parser.yy"
{ {
(yyval.op) = (yyvsp[(1) - (1)].op); (yyval.op) = (yyvsp[(1) - (1)].op);
} }
@ -1711,16 +1715,17 @@ yyreduce:
case 32: case 32:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 234 "config_parser.yy" #line 238 "config_parser.yy"
{ {
(yyval.variant) = new Variant((yyvsp[(1) - (1)].text)); (yyval.variant) = new Variant((yyvsp[(1) - (1)].text));
free((yyvsp[(1) - (1)].text));
} }
break; break;
case 33: case 33:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 238 "config_parser.yy" #line 243 "config_parser.yy"
{ {
(yyval.variant) = new Variant((yyvsp[(1) - (1)].num)); (yyval.variant) = new Variant((yyvsp[(1) - (1)].num));
} }
@ -1729,7 +1734,7 @@ yyreduce:
case 34: case 34:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 242 "config_parser.yy" #line 247 "config_parser.yy"
{ {
(yyval.variant) = new Variant(); (yyval.variant) = new Variant();
} }
@ -1738,7 +1743,7 @@ yyreduce:
case 37: case 37:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 250 "config_parser.yy" #line 255 "config_parser.yy"
{ {
(yyval.variant) = (yyvsp[(1) - (1)].variant); (yyval.variant) = (yyvsp[(1) - (1)].variant);
} }
@ -1747,7 +1752,7 @@ yyreduce:
case 38: case 38:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 256 "config_parser.yy" #line 261 "config_parser.yy"
{ {
m_Array = make_shared<Dictionary>(); m_Array = make_shared<Dictionary>();
} }
@ -1756,7 +1761,7 @@ yyreduce:
case 39: case 39:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 261 "config_parser.yy" #line 266 "config_parser.yy"
{ {
(yyval.variant) = new Variant(m_Array); (yyval.variant) = new Variant(m_Array);
m_Array.reset(); m_Array.reset();
@ -1766,7 +1771,7 @@ yyreduce:
case 40: case 40:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 268 "config_parser.yy" #line 273 "config_parser.yy"
{ {
m_Array->AddUnnamedProperty(*(yyvsp[(1) - (1)].variant)); m_Array->AddUnnamedProperty(*(yyvsp[(1) - (1)].variant));
delete (yyvsp[(1) - (1)].variant); delete (yyvsp[(1) - (1)].variant);
@ -1776,7 +1781,7 @@ yyreduce:
/* Line 1806 of yacc.c */ /* Line 1806 of yacc.c */
#line 1780 "config_parser.cc" #line 1785 "config_parser.cc"
default: break; default: break;
} }
/* User semantic actions sometimes alter yychar, and that requires /* User semantic actions sometimes alter yychar, and that requires
@ -2014,6 +2019,6 @@ yyreturn:
/* Line 2067 of yacc.c */ /* Line 2067 of yacc.c */
#line 278 "config_parser.yy" #line 283 "config_parser.yy"

View File

@ -30,6 +30,41 @@
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
/* "%code requires" blocks. */
/* Line 2068 of yacc.c */
#line 1 "config_parser.yy"
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "i2-dyn.h"
using namespace icinga;
#define YYLTYPE DebugInfo
/* Line 2068 of yacc.c */
#line 68 "config_parser.h"
/* Tokens. */ /* Tokens. */
#ifndef YYTOKENTYPE #ifndef YYTOKENTYPE
@ -77,7 +112,7 @@ typedef union YYSTYPE
{ {
/* Line 2068 of yacc.c */ /* Line 2068 of yacc.c */
#line 36 "config_parser.yy" #line 38 "config_parser.yy"
char *text; char *text;
int num; int num;
@ -87,7 +122,7 @@ typedef union YYSTYPE
/* Line 2068 of yacc.c */ /* Line 2068 of yacc.c */
#line 91 "config_parser.h" #line 126 "config_parser.h"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@ -1,4 +1,4 @@
%{ %code requires {
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
@ -22,7 +22,9 @@
using namespace icinga; using namespace icinga;
%} #define YYLTYPE DebugInfo
}
%pure-parser %pure-parser
@ -30,7 +32,7 @@ using namespace icinga;
%defines %defines
%error-verbose %error-verbose
%parse-param { ConfigContext *context } %parse-param { ConfigCompiler *context }
%lex-param { void *scanner } %lex-param { void *scanner }
%union { %union {
@ -65,7 +67,7 @@ using namespace icinga;
int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
void yyerror(YYLTYPE *locp, ConfigContext *context, const char *err) void yyerror(YYLTYPE *locp, ConfigCompiler *context, const char *err)
{ {
stringstream message; stringstream message;
@ -77,29 +79,30 @@ void yyerror(YYLTYPE *locp, ConfigContext *context, const char *err)
throw runtime_error(message.str()); throw runtime_error(message.str());
} }
int yyparse(ConfigContext *context); int yyparse(ConfigCompiler *context);
void ConfigContext::Compile(void) static stack<ExpressionList::Ptr> m_ExpressionLists;
static vector<ConfigItem::Ptr> m_Objects;
static ConfigItem::Ptr m_Object;
static bool m_Abstract;
static bool m_Local;
static Dictionary::Ptr m_Array;
void ConfigCompiler::Compile(void)
{ {
m_Objects.clear();
yyparse(this); yyparse(this);
SetResult(m_Objects);
m_Objects.clear();
} }
#define scanner (context->GetScanner()) #define scanner (context->GetScanner())
static stack<ExpressionList::Ptr> m_ExpressionLists;
static set<DConfigObject::Ptr> m_Objects;
static DConfigObject::Ptr m_Object;
static bool m_Abstract;
static bool m_Local;
static Dictionary::Ptr m_Array;
%} %}
%% %%
statements: /* empty */ statements: /* empty */
| statements statement | statements statement
{
context->SetResult(m_Objects);
}
; ;
statement: object | include statement: object | include
@ -115,7 +118,7 @@ object:
} }
attributes T_OBJECT T_IDENTIFIER T_STRING attributes T_OBJECT T_IDENTIFIER T_STRING
{ {
m_Object = make_shared<DConfigObject>($4, $5, yylloc.first_line); m_Object = make_shared<ConfigItem>($4, $5, yylloc);
free($4); free($4);
free($5); free($5);
} }
@ -125,22 +128,21 @@ inherits_specifier expressionlist
delete $8; delete $8;
ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object); ExpressionList::Ptr exprl = dynamic_pointer_cast<ExpressionList>(exprl_object);
Expression typeexpr("__type", OperatorSet, m_Object->GetType(), yylloc.first_line); Expression typeexpr("__type", OperatorSet, m_Object->GetType(), yylloc);
exprl->AddExpression(typeexpr); exprl->AddExpression(typeexpr);
Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc.first_line); Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc);
exprl->AddExpression(nameexpr); exprl->AddExpression(nameexpr);
Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc.first_line); Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc);
exprl->AddExpression(abstractexpr); exprl->AddExpression(abstractexpr);
Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc.first_line); Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc);
exprl->AddExpression(localexpr); exprl->AddExpression(localexpr);
m_Object->SetExpressionList(exprl); m_Object->SetExpressionList(exprl);
DConfigObject::AddObject(m_Object); m_Objects.push_back(m_Object);
m_Objects.insert(m_Object);
m_Object.reset(); m_Object.reset();
} }
; ;
@ -166,6 +168,7 @@ inherits_list: inherits_item
inherits_item: T_STRING inherits_item: T_STRING
{ {
m_Object->AddParent($1); m_Object->AddParent($1);
free($1);
} }
; ;
@ -192,7 +195,7 @@ expressions: /* empty */
expression: T_IDENTIFIER operator value expression: T_IDENTIFIER operator value
{ {
Expression expr($1, $2, *$3, yylloc.first_line); Expression expr($1, $2, *$3, yylloc);
free($1); free($1);
delete $3; delete $3;
@ -200,22 +203,23 @@ expression: T_IDENTIFIER operator value
} }
| T_IDENTIFIER '[' T_STRING ']' operator value | T_IDENTIFIER '[' T_STRING ']' operator value
{ {
Expression subexpr($3, $5, *$6, yylloc.first_line); Expression subexpr($3, $5, *$6, yylloc);
free($3); free($3);
delete $6; delete $6;
ExpressionList::Ptr subexprl = make_shared<ExpressionList>(); ExpressionList::Ptr subexprl = make_shared<ExpressionList>();
subexprl->AddExpression(subexpr); subexprl->AddExpression(subexpr);
Expression expr($1, OperatorPlus, subexprl, yylloc.first_line); Expression expr($1, OperatorPlus, subexprl, yylloc);
free($1);
m_ExpressionLists.top()->AddExpression(expr); m_ExpressionLists.top()->AddExpression(expr);
} }
| T_STRING | T_STRING
{ {
Expression expr($1, OperatorSet, $1, yylloc.first_line); Expression expr($1, OperatorSet, $1, yylloc);
free($1); free($1);
m_ExpressionLists.top()->AddExpression(expr); m_ExpressionLists.top()->AddExpression(expr);
} }
; ;
@ -233,6 +237,7 @@ operator: T_EQUAL
simplevalue: T_STRING simplevalue: T_STRING
{ {
$$ = new Variant($1); $$ = new Variant($1);
free($1);
} }
| T_NUMBER | T_NUMBER
{ {

View File

@ -1,36 +1,74 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "i2-dyn.h" #include "i2-dyn.h"
using namespace icinga; using namespace icinga;
ConfigContext::ConfigContext(istream *input) ConfigCompiler::ConfigCompiler(istream *input)
{ {
m_Input = input; m_Input = input;
InitializeScanner(); InitializeScanner();
} }
ConfigContext::~ConfigContext(void) ConfigCompiler::~ConfigCompiler(void)
{ {
DestroyScanner(); DestroyScanner();
} }
size_t ConfigContext::ReadInput(char *buffer, size_t max_size) size_t ConfigCompiler::ReadInput(char *buffer, size_t max_size)
{ {
m_Input->read(buffer, max_size); m_Input->read(buffer, max_size);
return m_Input->gcount(); return m_Input->gcount();
} }
void *ConfigContext::GetScanner(void) const void *ConfigCompiler::GetScanner(void) const
{ {
return m_Scanner; return m_Scanner;
} }
void ConfigContext::SetResult(set<DConfigObject::Ptr> result) void ConfigCompiler::SetResult(vector<ConfigItem::Ptr> result)
{ {
m_Result = result; m_Result = result;
} }
set<DConfigObject::Ptr> ConfigContext::GetResult(void) const vector<ConfigItem::Ptr> ConfigCompiler::GetResult(void) const
{ {
return m_Result; return m_Result;
} }
vector<ConfigItem::Ptr> ConfigCompiler::CompileStream(istream *stream)
{
ConfigCompiler ctx(stream);
ctx.Compile();
return ctx.GetResult();
}
vector<ConfigItem::Ptr> ConfigCompiler::CompileFile(string filename)
{
ifstream stream;
stream.open(filename, ifstream::in);
return CompileStream(&stream);
}
vector<ConfigItem::Ptr> ConfigCompiler::CompileText(string text)
{
stringstream stream(text);
return CompileStream(&stream);
}

View File

@ -17,22 +17,26 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef CONFIGCONTEXT_H #ifndef CONFIGCOMPILER_H
#define CONFIGCONTEXT_H #define CONFIGCOMPILER_H
namespace icinga namespace icinga
{ {
class I2_DYN_API ConfigContext class I2_DYN_API ConfigCompiler
{ {
public: public:
ConfigContext(istream *input = &cin); ConfigCompiler(istream *input = &cin);
virtual ~ConfigContext(void); virtual ~ConfigCompiler(void);
void Compile(void); void Compile(void);
void SetResult(set<DConfigObject::Ptr> result); static vector<ConfigItem::Ptr> CompileStream(istream *stream);
set<DConfigObject::Ptr> GetResult(void) const; static vector<ConfigItem::Ptr> CompileFile(string filename);
static vector<ConfigItem::Ptr> CompileText(string text);
void SetResult(vector<ConfigItem::Ptr> result);
vector<ConfigItem::Ptr> GetResult(void) const;
size_t ReadInput(char *buffer, size_t max_bytes); size_t ReadInput(char *buffer, size_t max_bytes);
void *GetScanner(void) const; void *GetScanner(void) const;
@ -40,7 +44,7 @@ public:
private: private:
istream *m_Input; istream *m_Input;
void *m_Scanner; void *m_Scanner;
set<DConfigObject::Ptr> m_Result; vector<ConfigItem::Ptr> m_Result;
void InitializeScanner(void); void InitializeScanner(void);
void DestroyScanner(void); void DestroyScanner(void);
@ -48,4 +52,4 @@ private:
} }
#endif /* CONFIGCONTEXT_H */ #endif /* CONFIGCOMPILER_H */

View File

@ -1,53 +1,72 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "i2-dyn.h" #include "i2-dyn.h"
using namespace icinga; using namespace icinga;
DConfigObject::DConfigObject(string type, string name, long debuginfo) ConfigItem::ConfigItem(string type, string name, DebugInfo debuginfo)
: m_Type(type), m_Name(name), m_DebugInfo(debuginfo) : m_Type(type), m_Name(name), m_DebugInfo(debuginfo)
{ {
} }
string DConfigObject::GetType(void) const string ConfigItem::GetType(void) const
{ {
return m_Type; return m_Type;
} }
string DConfigObject::GetName(void) const string ConfigItem::GetName(void) const
{ {
return m_Name; return m_Name;
} }
ExpressionList::Ptr DConfigObject::GetExpressionList(void) const ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
{ {
return m_ExpressionList; return m_ExpressionList;
} }
void DConfigObject::SetExpressionList(const ExpressionList::Ptr& exprl) void ConfigItem::SetExpressionList(const ExpressionList::Ptr& exprl)
{ {
m_ExpressionList = exprl; m_ExpressionList = exprl;
} }
vector<string> DConfigObject::GetParents(void) const vector<string> ConfigItem::GetParents(void) const
{ {
return m_Parents; return m_Parents;
} }
void DConfigObject::AddParent(string parent) void ConfigItem::AddParent(string parent)
{ {
m_Parents.push_back(parent); m_Parents.push_back(parent);
} }
Dictionary::Ptr DConfigObject::CalculateProperties(void) const Dictionary::Ptr ConfigItem::CalculateProperties(void) const
{ {
Dictionary::Ptr result = make_shared<Dictionary>(); Dictionary::Ptr result = make_shared<Dictionary>();
vector<string>::const_iterator it; vector<string>::const_iterator it;
for (it = m_Parents.begin(); it != m_Parents.end(); it++) { for (it = m_Parents.begin(); it != m_Parents.end(); it++) {
DConfigObject::Ptr parent = DConfigObject::GetObject(GetType(), *it); ConfigItem::Ptr parent = ConfigItem::GetObject(GetType(), *it);
if (!parent) { if (!parent) {
stringstream message; stringstream message;
message << "Parent object '" << *it << "' does not exist (in line " << m_DebugInfo << ")"; message << "Parent object '" << *it << "' does not exist (" << m_DebugInfo << ")";
throw domain_error(message.str()); throw domain_error(message.str());
} }
@ -59,56 +78,79 @@ Dictionary::Ptr DConfigObject::CalculateProperties(void) const
return result; return result;
} }
ObjectSet<DConfigObject::Ptr>::Ptr DConfigObject::GetAllObjects(void) ObjectSet<ConfigItem::Ptr>::Ptr ConfigItem::GetAllObjects(void)
{ {
static ObjectSet<DConfigObject::Ptr>::Ptr allObjects; static ObjectSet<ConfigItem::Ptr>::Ptr allObjects;
if (!allObjects) { if (!allObjects) {
allObjects = make_shared<ObjectSet<DConfigObject::Ptr> >(); allObjects = make_shared<ObjectSet<ConfigItem::Ptr> >();
allObjects->Start(); allObjects->Start();
} }
return allObjects; return allObjects;
} }
bool DConfigObject::GetTypeAndName(const DConfigObject::Ptr& object, pair<string, string> *key) bool ConfigItem::GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *key)
{ {
*key = make_pair(object->GetType(), object->GetName()); *key = make_pair(object->GetType(), object->GetName());
return true; return true;
} }
ObjectMap<pair<string, string>, DConfigObject::Ptr>::Ptr DConfigObject::GetObjectsByTypeAndName(void) ConfigItem::TNMap::Ptr ConfigItem::GetObjectsByTypeAndName(void)
{ {
static ObjectMap<pair<string, string>, DConfigObject::Ptr>::Ptr tnmap; static ConfigItem::TNMap::Ptr tnmap;
if (!tnmap) { if (!tnmap) {
tnmap = make_shared<ObjectMap<pair<string, string>, DConfigObject::Ptr> >(GetAllObjects(), &DConfigObject::GetTypeAndName); tnmap = make_shared<ConfigItem::TNMap>(GetAllObjects(), &ConfigItem::GetTypeAndName);
tnmap->Start(); tnmap->Start();
} }
return tnmap; return tnmap;
} }
void DConfigObject::AddObject(DConfigObject::Ptr object) void ConfigItem::Commit(void)
{ {
GetAllObjects()->AddObject(object); DynamicObject::Ptr dobj = m_DynamicObject.lock();
if (!dobj) {
dobj = DynamicObject::GetObject(GetType(), GetName());
if (!dobj)
dobj = make_shared<DynamicObject>();
m_DynamicObject = dobj;
}
dobj->SetConfig(CalculateProperties());
dobj->Commit();
ConfigItem::Ptr ci = GetObject(GetType(), GetName());
ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this());
if (ci && ci != self) {
ci->m_DynamicObject.reset();
GetAllObjects()->RemoveObject(ci);
}
GetAllObjects()->CheckObject(self);
} }
void DConfigObject::RemoveObject(DConfigObject::Ptr object) void ConfigItem::Unregister(void)
{ {
throw logic_error("not implemented."); // TODO: unregister associated DynamicObject
ConfigItem::Ptr self = static_pointer_cast<ConfigItem>(shared_from_this());
GetAllObjects()->RemoveObject(self);
} }
DConfigObject::Ptr DConfigObject::GetObject(string type, string name) ConfigItem::Ptr ConfigItem::GetObject(string type, string name)
{ {
ObjectMap<pair<string, string>, DConfigObject::Ptr>::Range range; ConfigItem::TNMap::Range range;
range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name)); range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name));
assert(distance(range.first, range.second) <= 1); assert(distance(range.first, range.second) <= 1);
if (range.first == range.second) if (range.first == range.second)
return DConfigObject::Ptr(); return ConfigItem::Ptr();
else else
return range.first->second; return range.first->second;
} }

View File

@ -1,15 +1,36 @@
#ifndef DCONFIGOBJECT_H /******************************************************************************
#define DCONFIGOBJECT_H * Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CONFIGITEM_H
#define CONFIGITEM_H
namespace icinga namespace icinga
{ {
class DConfigObject : public Object { class ConfigItem : public Object {
public: public:
typedef shared_ptr<DConfigObject> Ptr; typedef shared_ptr<ConfigItem> Ptr;
typedef weak_ptr<DConfigObject> WeakPtr; typedef weak_ptr<ConfigItem> WeakPtr;
DConfigObject(string type, string name, long debuginfo); typedef ObjectMap<pair<string, string>, ConfigItem::Ptr> TNMap;
ConfigItem(string type, string name, DebugInfo debuginfo);
string GetType(void) const; string GetType(void) const;
string GetName(void) const; string GetName(void) const;
@ -22,23 +43,26 @@ public:
Dictionary::Ptr CalculateProperties(void) const; Dictionary::Ptr CalculateProperties(void) const;
static ObjectSet<DConfigObject::Ptr>::Ptr GetAllObjects(void); void Commit(void);
static ObjectMap<pair<string, string>, DConfigObject::Ptr>::Ptr GetObjectsByTypeAndName(void); void Unregister(void);
static void AddObject(DConfigObject::Ptr object);
static void RemoveObject(DConfigObject::Ptr object); static ObjectSet<ConfigItem::Ptr>::Ptr GetAllObjects(void);
static DConfigObject::Ptr GetObject(string type, string name); static TNMap::Ptr GetObjectsByTypeAndName(void);
static ConfigItem::Ptr GetObject(string type, string name);
private: private:
string m_Type; string m_Type;
string m_Name; string m_Name;
long m_DebugInfo; DebugInfo m_DebugInfo;
vector<string> m_Parents; vector<string> m_Parents;
ExpressionList::Ptr m_ExpressionList; ExpressionList::Ptr m_ExpressionList;
static bool GetTypeAndName(const DConfigObject::Ptr& object, pair<string, string> *key); DynamicObject::WeakPtr m_DynamicObject;
static bool GetTypeAndName(const ConfigItem::Ptr& object, pair<string, string> *key);
}; };
} }
#endif /* DCONFIGOBJECT_H */ #endif /* CONFIGITEM_H */

View File

@ -26,6 +26,11 @@ DynamicObject::DynamicObject(void)
{ {
} }
void DynamicObject::SetConfig(Dictionary::Ptr config)
{
m_Config = config;
}
Dictionary::Ptr DynamicObject::GetConfig(void) const Dictionary::Ptr DynamicObject::GetConfig(void) const
{ {
return m_Config; return m_Config;
@ -36,16 +41,32 @@ Dictionary::Ptr DynamicObject::GetTags(void) const
return m_Tags; return m_Tags;
} }
string DynamicObject::GetType(void) const
{
string type;
GetConfig()->GetProperty("__type", &type);
return type;
}
string DynamicObject::GetName(void) const
{
string name;
GetConfig()->GetProperty("__name", &name);
return name;
}
void DynamicObject::Commit(void) void DynamicObject::Commit(void)
{ {
DynamicObject::Ptr dobj = GetObject(GetType(), GetName());
DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this()); DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this());
DynamicObject::GetAllObjects()->CheckObject(self); assert(!dobj || dobj == self);
GetAllObjects()->CheckObject(self);
} }
void DynamicObject::Unregister(void) void DynamicObject::Unregister(void)
{ {
DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this()); DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this());
DynamicObject::GetAllObjects()->RemoveObject(self); GetAllObjects()->RemoveObject(self);
} }
ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void) ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void)
@ -59,3 +80,36 @@ ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void)
return allObjects; return allObjects;
} }
DynamicObject::TNMap::Ptr DynamicObject::GetObjectsByTypeAndName(void)
{
static DynamicObject::TNMap::Ptr tnmap;
if (!tnmap) {
tnmap = make_shared<DynamicObject::TNMap>(GetAllObjects(), &DynamicObject::GetTypeAndName);
tnmap->Start();
}
return tnmap;
}
DynamicObject::Ptr DynamicObject::GetObject(string type, string name)
{
DynamicObject::TNMap::Range range;
range = GetObjectsByTypeAndName()->GetRange(make_pair(type, name));
assert(distance(range.first, range.second) <= 1);
if (range.first == range.second)
return DynamicObject::Ptr();
else
return range.first->second;
}
bool DynamicObject::GetTypeAndName(const DynamicObject::Ptr& object, pair<string, string> *key)
{
*key = make_pair(object->GetType(), object->GetName());
return true;
}

View File

@ -29,19 +29,30 @@ public:
typedef shared_ptr<DynamicObject> Ptr; typedef shared_ptr<DynamicObject> Ptr;
typedef weak_ptr<DynamicObject> WeakPtr; typedef weak_ptr<DynamicObject> WeakPtr;
typedef ObjectMap<pair<string, string>, DynamicObject::Ptr> TNMap;
DynamicObject(void); DynamicObject(void);
void SetConfig(Dictionary::Ptr config);
Dictionary::Ptr GetConfig(void) const; Dictionary::Ptr GetConfig(void) const;
Dictionary::Ptr GetTags(void) const; Dictionary::Ptr GetTags(void) const;
string GetType(void) const;
string GetName(void) const;
void Commit(void); void Commit(void);
void Unregister(void); void Unregister(void);
static ObjectSet<DynamicObject::Ptr>::Ptr GetAllObjects(void); static ObjectSet<DynamicObject::Ptr>::Ptr GetAllObjects(void);
static TNMap::Ptr GetObjectsByTypeAndName(void);
static DynamicObject::Ptr GetObject(string type, string name);
private: private:
Dictionary::Ptr m_Config; Dictionary::Ptr m_Config;
Dictionary::Ptr m_Tags; Dictionary::Ptr m_Tags;
static bool GetTypeAndName(const DynamicObject::Ptr& object, pair<string, string> *key);
}; };
} }

View File

@ -21,23 +21,23 @@
using namespace icinga; using namespace icinga;
Expression::Expression(string key, ExpressionOperator op, Variant value, long debuginfo) Expression::Expression(string key, ExpressionOperator op, const Variant& value, const DebugInfo& debuginfo)
: Key(key), Operator(op), Value(value), DebugInfo(debuginfo) : m_Key(key), m_Operator(op), m_Value(value), m_DebugInfo(debuginfo)
{ {
} }
void Expression::Execute(const Dictionary::Ptr& dictionary) const void Expression::Execute(const Dictionary::Ptr& dictionary) const
{ {
Variant oldValue, newValue; Variant oldValue, newValue;
dictionary->GetProperty(Key, &oldValue); dictionary->GetProperty(m_Key, &oldValue);
ExpressionList::Ptr exprl; ExpressionList::Ptr exprl;
if (Value.GetType() == VariantObject) if (m_Value.GetType() == VariantObject)
exprl = dynamic_pointer_cast<ExpressionList>(Value.GetObject()); exprl = dynamic_pointer_cast<ExpressionList>(m_Value.GetObject());
newValue = Value; newValue = m_Value;
switch (Operator) { switch (m_Operator) {
case OperatorSet: case OperatorSet:
if (exprl) { if (exprl) {
Dictionary::Ptr dict = make_shared<Dictionary>(); Dictionary::Ptr dict = make_shared<Dictionary>();
@ -56,7 +56,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
if (!dict) { if (!dict) {
if (!oldValue.IsEmpty()) { if (!oldValue.IsEmpty()) {
stringstream message; stringstream message;
message << "Wrong argument types for += (non-dictionary and dictionary) (in line " << DebugInfo << ")"; message << "Wrong argument types for += (non-dictionary and dictionary) (" << m_DebugInfo << ")";
throw domain_error(message.str()); throw domain_error(message.str());
} }
@ -67,7 +67,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
newValue = dict; newValue = dict;
} else { } else {
stringstream message; stringstream message;
message << "+= only works for dictionaries (in line " << DebugInfo << ")"; message << "+= only works for dictionaries (" << m_DebugInfo << ")";
throw domain_error(message.str()); throw domain_error(message.str());
} }
@ -79,5 +79,5 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
break; break;
} }
dictionary->SetProperty(Key, newValue); dictionary->SetProperty(m_Key, newValue);
} }

View File

@ -34,14 +34,16 @@ enum ExpressionOperator
struct I2_DYN_API Expression struct I2_DYN_API Expression
{ {
string Key; public:
ExpressionOperator Operator; Expression(string key, ExpressionOperator op, const Variant& value, const DebugInfo& debuginfo);
Variant Value;
long DebugInfo;
Expression(string key, ExpressionOperator op, Variant value, long debuginfo);
void Execute(const Dictionary::Ptr& dictionary) const; void Execute(const Dictionary::Ptr& dictionary) const;
private:
string m_Key;
ExpressionOperator m_Operator;
Variant m_Value;
DebugInfo m_DebugInfo;
}; };
} }

View File

@ -30,6 +30,7 @@
#include <i2-base.h> #include <i2-base.h>
#include <stack> #include <stack>
#include <fstream>
#ifdef I2_DYN_BUILD #ifdef I2_DYN_BUILD
# define I2_DYN_API I2_EXPORT # define I2_DYN_API I2_EXPORT
@ -37,12 +38,14 @@
# define I2_DYN_API I2_IMPORT # define I2_DYN_API I2_IMPORT
#endif /* I2_DYN_BUILD */ #endif /* I2_DYN_BUILD */
#include "debuginfo.h"
#include "expression.h" #include "expression.h"
#include "expressionlist.h" #include "expressionlist.h"
#include "objectset.h" #include "objectset.h"
#include "objectmap.h" #include "objectmap.h"
#include "dynamicobject.h" #include "dynamicobject.h"
#include "dconfigobject.h" #include "configitem.h"
#include "configcontext.h" #include "configcompiler.h"
#include "configvm.h"
#endif /* I2DYN_H */ #endif /* I2DYN_H */

View File

@ -5,20 +5,23 @@ using namespace icinga;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
ConfigContext ctx; if (argc < 2) {
ctx.Compile(); cout << "Syntax: " << argv[0] << " <filename>" << endl;
set<DConfigObject::Ptr> objects = ctx.GetResult(); return 1;
}
for (auto it = objects.begin(); it != objects.end(); it++) { for (int i = 0; i < 10; i++) {
DConfigObject::Ptr obj = *it; vector<ConfigItem::Ptr> objects = ConfigCompiler::CompileFile(string(argv[1]));
ConfigVM::ExecuteItems(objects);
}
ObjectSet<DynamicObject::Ptr>::Iterator it;
for (it = DynamicObject::GetAllObjects()->Begin(); it != DynamicObject::GetAllObjects()->End(); it++) {
DynamicObject::Ptr obj = *it;
cout << "Object, name: " << obj->GetName() << ", type: " << obj->GetType() << endl; cout << "Object, name: " << obj->GetName() << ", type: " << obj->GetType() << endl;
cout << "\t" << obj->GetParents().size() << " parents" << endl;
cout << "\t" << obj->GetExpressionList()->GetLength() << " top-level exprs" << endl;
Dictionary::Ptr props = obj->CalculateProperties(); MessagePart mp(obj->GetConfig());
cout << "\t" << props->GetLength() << " top-level properties" << endl;
MessagePart mp(props);
cout << mp.ToJsonString() << endl; cout << mp.ToJsonString() << endl;
} }