[core] Fix value statements in config parser (now using stack for operator)
This commit is contained in:
parent
f3713267db
commit
9989cd62ce
|
@ -28,7 +28,6 @@ struct liConfigParserContext {
|
|||
gboolean condition_negated;
|
||||
|
||||
liCompOperator op;
|
||||
gchar value_op;
|
||||
|
||||
liCastType cast;
|
||||
|
||||
|
@ -38,6 +37,7 @@ struct liConfigParserContext {
|
|||
GQueue *action_list_stack; /* first entry is current action list */
|
||||
GQueue *option_stack; /* stack of liValue* */
|
||||
GQueue *condition_stack; /* stack of condition* */
|
||||
GQueue *value_op_stack; /* stack of gchar* */
|
||||
|
||||
/* information about currenty parsed file */
|
||||
gchar *filename;
|
||||
|
|
|
@ -317,7 +317,7 @@
|
|||
}
|
||||
|
||||
action value_statement_op {
|
||||
ctx->value_op = *ctx->mark;
|
||||
g_queue_push_head(ctx->value_op_stack, ctx->mark);
|
||||
}
|
||||
|
||||
action value_statement {
|
||||
|
@ -325,6 +325,7 @@
|
|||
/* compute new value out of the two */
|
||||
liValue *l, *r, *o;
|
||||
gboolean free_l, free_r;
|
||||
gchar op;
|
||||
|
||||
free_l = free_r = TRUE;
|
||||
|
||||
|
@ -332,8 +333,9 @@
|
|||
l = g_queue_pop_head(ctx->option_stack);
|
||||
o = NULL;
|
||||
|
||||
op = *(gchar*)g_queue_pop_head(ctx->value_op_stack);
|
||||
|
||||
if (ctx->value_op == '=') {
|
||||
if (op == '=') {
|
||||
/* value => value */
|
||||
free_l = FALSE;
|
||||
free_r = FALSE;
|
||||
|
@ -342,7 +344,7 @@
|
|||
g_array_append_val(o->data.list, r);
|
||||
}
|
||||
else if (l->type == LI_VALUE_NUMBER && r->type == LI_VALUE_NUMBER) {
|
||||
switch (ctx->value_op) {
|
||||
switch (op) {
|
||||
case '+': o = li_value_new_number(l->data.number + r->data.number); break;
|
||||
case '-': o = li_value_new_number(l->data.number - r->data.number); break;
|
||||
case '*': o = li_value_new_number(l->data.number * r->data.number); break;
|
||||
|
@ -353,15 +355,15 @@
|
|||
o = l;
|
||||
free_l = FALSE;
|
||||
|
||||
if (r->type == LI_VALUE_STRING && ctx->value_op == '+') {
|
||||
if (r->type == LI_VALUE_STRING && op == '+') {
|
||||
/* str + str */
|
||||
o->data.string = g_string_append_len(o->data.string, GSTR_LEN(r->data.string));
|
||||
}
|
||||
else if (r->type == LI_VALUE_NUMBER && ctx->value_op == '+') {
|
||||
else if (r->type == LI_VALUE_NUMBER && op == '+') {
|
||||
/* str + int */
|
||||
g_string_append_printf(o->data.string, "%" G_GINT64_FORMAT, r->data.number);
|
||||
}
|
||||
else if (r->type == LI_VALUE_NUMBER && ctx->value_op == '*') {
|
||||
else if (r->type == LI_VALUE_NUMBER && op == '*') {
|
||||
/* str * int */
|
||||
if (r->data.number < 0) {
|
||||
ERROR(srv, "string multiplication with negative number (%" G_GINT64_FORMAT ")?", r->data.number);
|
||||
|
@ -382,7 +384,7 @@
|
|||
o = NULL;
|
||||
}
|
||||
else if (l->type == LI_VALUE_LIST) {
|
||||
if (ctx->value_op == '+') {
|
||||
if (op == '+') {
|
||||
/* append r to the end of l */
|
||||
free_l = FALSE; /* use l as the new o */
|
||||
free_r = FALSE; /* r gets appended to o */
|
||||
|
@ -390,7 +392,7 @@
|
|||
|
||||
g_array_append_val(l->data.list, r);
|
||||
}
|
||||
else if (ctx->value_op == '*') {
|
||||
else if (op == '*') {
|
||||
/* merge l and r */
|
||||
if (r->type == LI_VALUE_LIST) {
|
||||
/* merge lists */
|
||||
|
@ -401,7 +403,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (l->type == LI_VALUE_HASH && r->type == LI_VALUE_HASH && ctx->value_op == '+') {
|
||||
else if (l->type == LI_VALUE_HASH && r->type == LI_VALUE_HASH && op == '+') {
|
||||
/* merge hashtables */
|
||||
GHashTableIter iter;
|
||||
gpointer key, val;
|
||||
|
@ -417,15 +419,15 @@
|
|||
|
||||
if (o == NULL) {
|
||||
WARNING(srv, "erronous value statement: %s %c %s in line %zd\n",
|
||||
li_value_type_string(l->type), ctx->value_op,
|
||||
li_value_type_string(l->type), op,
|
||||
li_value_type_string(r->type), ctx->line);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_printf("value statement: %s %c%s %s => %s in line %zd\n",
|
||||
li_value_type_string(l->type),
|
||||
ctx->value_op,
|
||||
ctx->value_op == '=' ? ">" : "",
|
||||
op,
|
||||
op == '=' ? ">" : "",
|
||||
li_value_type_string(r->type),
|
||||
li_value_type_string(o->type),
|
||||
ctx->line);
|
||||
|
@ -1193,6 +1195,7 @@ static liConfigParserContext *config_parser_context_new(liServer *srv, GList *ct
|
|||
ctx->action_list_stack = ((liConfigParserContext*) ctx_stack->data)->action_list_stack;
|
||||
ctx->option_stack = ((liConfigParserContext*) ctx_stack->data)->option_stack;
|
||||
ctx->condition_stack = ((liConfigParserContext*) ctx_stack->data)->condition_stack;
|
||||
ctx->value_op_stack = ((liConfigParserContext*) ctx_stack->data)->value_op_stack;
|
||||
|
||||
ctx->action_blocks = ((liConfigParserContext*) ctx_stack->data)->action_blocks;
|
||||
ctx->uservars = ((liConfigParserContext*) ctx_stack->data)->uservars;
|
||||
|
@ -1223,6 +1226,7 @@ static liConfigParserContext *config_parser_context_new(liServer *srv, GList *ct
|
|||
ctx->action_list_stack = g_queue_new();
|
||||
ctx->option_stack = g_queue_new();
|
||||
ctx->condition_stack = g_queue_new();
|
||||
ctx->value_op_stack = g_queue_new();
|
||||
}
|
||||
|
||||
return ctx;
|
||||
|
@ -1247,6 +1251,7 @@ static void config_parser_context_free(liServer *srv, liConfigParserContext *ctx
|
|||
g_queue_free(ctx->action_list_stack);
|
||||
g_queue_free(ctx->option_stack);
|
||||
g_queue_free(ctx->condition_stack);
|
||||
g_queue_free(ctx->value_op_stack);
|
||||
}
|
||||
|
||||
g_slice_free(liConfigParserContext, ctx);
|
||||
|
|
Loading…
Reference in New Issue