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>
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_HEADERS([config.h])
AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
#AM_SILENT_RULES([yes])
AM_SILENT_RULES([yes])
AC_PROG_CXX
AC_LANG_CPLUSPLUS

View File

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

View File

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

View File

@ -23,8 +23,15 @@
using namespace icinga;
#define YY_EXTRA_TYPE ConfigContext *
#define YY_USER_ACTION yylloc->first_line = yylineno;
#define YY_EXTRA_TYPE ConfigCompiler *
#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) \
do { \
@ -72,13 +79,13 @@ null return T_NULL;
%%
void ConfigContext::InitializeScanner(void)
void ConfigCompiler::InitializeScanner(void)
{
yylex_init(&m_Scanner);
yyset_extra(this, m_Scanner);
}
void ConfigContext::DestroyScanner(void)
void ConfigCompiler::DestroyScanner(void)
{
yylex_destroy(m_Scanner);
}

View File

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

View File

@ -1,4 +1,4 @@
%{
%code requires {
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
@ -22,7 +22,9 @@
using namespace icinga;
%}
#define YYLTYPE DebugInfo
}
%pure-parser
@ -30,7 +32,7 @@ using namespace icinga;
%defines
%error-verbose
%parse-param { ConfigContext *context }
%parse-param { ConfigCompiler *context }
%lex-param { void *scanner }
%union {
@ -65,7 +67,7 @@ using namespace icinga;
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;
@ -77,29 +79,30 @@ void yyerror(YYLTYPE *locp, ConfigContext *context, const char *err)
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);
SetResult(m_Objects);
m_Objects.clear();
}
#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 statement
{
context->SetResult(m_Objects);
}
;
statement: object | include
@ -115,7 +118,7 @@ object:
}
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($5);
}
@ -125,22 +128,21 @@ inherits_specifier expressionlist
delete $8;
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);
Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc.first_line);
Expression nameexpr("__name", OperatorSet, m_Object->GetName(), yylloc);
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);
Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc.first_line);
Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc);
exprl->AddExpression(localexpr);
m_Object->SetExpressionList(exprl);
DConfigObject::AddObject(m_Object);
m_Objects.insert(m_Object);
m_Objects.push_back(m_Object);
m_Object.reset();
}
;
@ -166,6 +168,7 @@ inherits_list: inherits_item
inherits_item: T_STRING
{
m_Object->AddParent($1);
free($1);
}
;
@ -192,7 +195,7 @@ expressions: /* empty */
expression: T_IDENTIFIER operator value
{
Expression expr($1, $2, *$3, yylloc.first_line);
Expression expr($1, $2, *$3, yylloc);
free($1);
delete $3;
@ -200,22 +203,23 @@ expression: T_IDENTIFIER operator value
}
| T_IDENTIFIER '[' T_STRING ']' operator value
{
Expression subexpr($3, $5, *$6, yylloc.first_line);
Expression subexpr($3, $5, *$6, yylloc);
free($3);
delete $6;
ExpressionList::Ptr subexprl = make_shared<ExpressionList>();
subexprl->AddExpression(subexpr);
Expression expr($1, OperatorPlus, subexprl, yylloc.first_line);
Expression expr($1, OperatorPlus, subexprl, yylloc);
free($1);
m_ExpressionLists.top()->AddExpression(expr);
}
| T_STRING
{
Expression expr($1, OperatorSet, $1, yylloc.first_line);
Expression expr($1, OperatorSet, $1, yylloc);
free($1);
m_ExpressionLists.top()->AddExpression(expr);
}
;
@ -233,6 +237,7 @@ operator: T_EQUAL
simplevalue: T_STRING
{
$$ = new Variant($1);
free($1);
}
| 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"
using namespace icinga;
ConfigContext::ConfigContext(istream *input)
ConfigCompiler::ConfigCompiler(istream *input)
{
m_Input = input;
InitializeScanner();
}
ConfigContext::~ConfigContext(void)
ConfigCompiler::~ConfigCompiler(void)
{
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);
return m_Input->gcount();
}
void *ConfigContext::GetScanner(void) const
void *ConfigCompiler::GetScanner(void) const
{
return m_Scanner;
}
void ConfigContext::SetResult(set<DConfigObject::Ptr> result)
void ConfigCompiler::SetResult(vector<ConfigItem::Ptr> 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. *
******************************************************************************/
#ifndef CONFIGCONTEXT_H
#define CONFIGCONTEXT_H
#ifndef CONFIGCOMPILER_H
#define CONFIGCOMPILER_H
namespace icinga
{
class I2_DYN_API ConfigContext
class I2_DYN_API ConfigCompiler
{
public:
ConfigContext(istream *input = &cin);
virtual ~ConfigContext(void);
ConfigCompiler(istream *input = &cin);
virtual ~ConfigCompiler(void);
void Compile(void);
void SetResult(set<DConfigObject::Ptr> result);
set<DConfigObject::Ptr> GetResult(void) const;
static vector<ConfigItem::Ptr> CompileStream(istream *stream);
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);
void *GetScanner(void) const;
@ -40,7 +44,7 @@ public:
private:
istream *m_Input;
void *m_Scanner;
set<DConfigObject::Ptr> m_Result;
vector<ConfigItem::Ptr> m_Result;
void InitializeScanner(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"
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)
{
}
string DConfigObject::GetType(void) const
string ConfigItem::GetType(void) const
{
return m_Type;
}
string DConfigObject::GetName(void) const
string ConfigItem::GetName(void) const
{
return m_Name;
}
ExpressionList::Ptr DConfigObject::GetExpressionList(void) const
ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
{
return m_ExpressionList;
}
void DConfigObject::SetExpressionList(const ExpressionList::Ptr& exprl)
void ConfigItem::SetExpressionList(const ExpressionList::Ptr& exprl)
{
m_ExpressionList = exprl;
}
vector<string> DConfigObject::GetParents(void) const
vector<string> ConfigItem::GetParents(void) const
{
return m_Parents;
}
void DConfigObject::AddParent(string parent)
void ConfigItem::AddParent(string parent)
{
m_Parents.push_back(parent);
}
Dictionary::Ptr DConfigObject::CalculateProperties(void) const
Dictionary::Ptr ConfigItem::CalculateProperties(void) const
{
Dictionary::Ptr result = make_shared<Dictionary>();
vector<string>::const_iterator 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) {
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());
}
@ -59,56 +78,79 @@ Dictionary::Ptr DConfigObject::CalculateProperties(void) const
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) {
allObjects = make_shared<ObjectSet<DConfigObject::Ptr> >();
allObjects = make_shared<ObjectSet<ConfigItem::Ptr> >();
allObjects->Start();
}
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());
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) {
tnmap = make_shared<ObjectMap<pair<string, string>, DConfigObject::Ptr> >(GetAllObjects(), &DConfigObject::GetTypeAndName);
tnmap = make_shared<ConfigItem::TNMap>(GetAllObjects(), &ConfigItem::GetTypeAndName);
tnmap->Start();
}
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));
assert(distance(range.first, range.second) <= 1);
if (range.first == range.second)
return DConfigObject::Ptr();
return ConfigItem::Ptr();
else
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
{
class DConfigObject : public Object {
class ConfigItem : public Object {
public:
typedef shared_ptr<DConfigObject> Ptr;
typedef weak_ptr<DConfigObject> WeakPtr;
typedef shared_ptr<ConfigItem> Ptr;
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 GetName(void) const;
@ -22,23 +43,26 @@ public:
Dictionary::Ptr CalculateProperties(void) const;
static ObjectSet<DConfigObject::Ptr>::Ptr GetAllObjects(void);
static ObjectMap<pair<string, string>, DConfigObject::Ptr>::Ptr GetObjectsByTypeAndName(void);
static void AddObject(DConfigObject::Ptr object);
static void RemoveObject(DConfigObject::Ptr object);
static DConfigObject::Ptr GetObject(string type, string name);
void Commit(void);
void Unregister(void);
static ObjectSet<ConfigItem::Ptr>::Ptr GetAllObjects(void);
static TNMap::Ptr GetObjectsByTypeAndName(void);
static ConfigItem::Ptr GetObject(string type, string name);
private:
string m_Type;
string m_Name;
long m_DebugInfo;
DebugInfo m_DebugInfo;
vector<string> m_Parents;
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
{
return m_Config;
@ -36,16 +41,32 @@ Dictionary::Ptr DynamicObject::GetTags(void) const
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)
{
DynamicObject::Ptr dobj = GetObject(GetType(), GetName());
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)
{
DynamicObject::Ptr self = static_pointer_cast<DynamicObject>(shared_from_this());
DynamicObject::GetAllObjects()->RemoveObject(self);
GetAllObjects()->RemoveObject(self);
}
ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void)
@ -59,3 +80,36 @@ ObjectSet<DynamicObject::Ptr>::Ptr DynamicObject::GetAllObjects(void)
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 weak_ptr<DynamicObject> WeakPtr;
typedef ObjectMap<pair<string, string>, DynamicObject::Ptr> TNMap;
DynamicObject(void);
void SetConfig(Dictionary::Ptr config);
Dictionary::Ptr GetConfig(void) const;
Dictionary::Ptr GetTags(void) const;
string GetType(void) const;
string GetName(void) const;
void Commit(void);
void Unregister(void);
static ObjectSet<DynamicObject::Ptr>::Ptr GetAllObjects(void);
static TNMap::Ptr GetObjectsByTypeAndName(void);
static DynamicObject::Ptr GetObject(string type, string name);
private:
Dictionary::Ptr m_Config;
Dictionary::Ptr m_Tags;
static bool GetTypeAndName(const DynamicObject::Ptr& object, pair<string, string> *key);
};
}

View File

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

View File

@ -34,14 +34,16 @@ enum ExpressionOperator
struct I2_DYN_API Expression
{
string Key;
ExpressionOperator Operator;
Variant Value;
long DebugInfo;
Expression(string key, ExpressionOperator op, Variant value, long debuginfo);
public:
Expression(string key, ExpressionOperator op, const Variant& value, const DebugInfo& debuginfo);
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 <stack>
#include <fstream>
#ifdef I2_DYN_BUILD
# define I2_DYN_API I2_EXPORT
@ -37,12 +38,14 @@
# define I2_DYN_API I2_IMPORT
#endif /* I2_DYN_BUILD */
#include "debuginfo.h"
#include "expression.h"
#include "expressionlist.h"
#include "objectset.h"
#include "objectmap.h"
#include "dynamicobject.h"
#include "dconfigobject.h"
#include "configcontext.h"
#include "configitem.h"
#include "configcompiler.h"
#include "configvm.h"
#endif /* I2DYN_H */

View File

@ -5,20 +5,23 @@ using namespace icinga;
int main(int argc, char **argv)
{
ConfigContext ctx;
ctx.Compile();
set<DConfigObject::Ptr> objects = ctx.GetResult();
if (argc < 2) {
cout << "Syntax: " << argv[0] << " <filename>" << endl;
return 1;
}
for (auto it = objects.begin(); it != objects.end(); it++) {
DConfigObject::Ptr obj = *it;
for (int i = 0; i < 10; i++) {
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 << "\t" << obj->GetParents().size() << " parents" << endl;
cout << "\t" << obj->GetExpressionList()->GetLength() << " top-level exprs" << endl;
Dictionary::Ptr props = obj->CalculateProperties();
cout << "\t" << props->GetLength() << " top-level properties" << endl;
MessagePart mp(props);
MessagePart mp(obj->GetConfig());
cout << mp.ToJsonString() << endl;
}