diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluate.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 61ebcbfc..2182d8f1 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1690,6 +1690,14 @@ static int interval_set_eval(struct eval_ctx *ctx, struct set *set, return ret; } +static void expr_evaluate_set_ref(struct eval_ctx *ctx, struct expr *expr) +{ + struct set *set = expr->set; + + expr_set_context(&ctx->ectx, set->key->dtype, set->key->len); + ctx->ectx.key = set->key; +} + static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) { struct expr *set = *expr, *i, *next; @@ -2557,6 +2565,7 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr) case EXPR_VARIABLE: return expr_evaluate_variable(ctx, expr); case EXPR_SET_REF: + expr_evaluate_set_ref(ctx, *expr); return 0; case EXPR_VALUE: return expr_evaluate_value(ctx, expr); @@ -2719,6 +2728,25 @@ static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt, return __stmt_evaluate_arg(ctx, stmt, dtype, len, byteorder, expr); } +/* like stmt_evaluate_arg, but keep existing context created + * by previous expr_evaluate(). + * + * This is needed for add/update statements: + * ctx->ectx.key has the set key, which may be needed for 'typeof' + * sets: the 'add/update' expression might contain integer data types. + * + * Without the key we cannot derive the element size. + */ +static int stmt_evaluate_key(struct eval_ctx *ctx, struct stmt *stmt, + const struct datatype *dtype, unsigned int len, + enum byteorder byteorder, struct expr **expr) +{ + if (expr_evaluate(ctx, expr) < 0) + return -1; + + return __stmt_evaluate_arg(ctx, stmt, dtype, len, byteorder, expr); +} + static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt) { if (stmt_evaluate_arg(ctx, stmt, &verdict_type, 0, 0, &stmt->expr) < 0) @@ -3952,7 +3980,7 @@ static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt) return expr_error(ctx->msgs, stmt->set.set, "Expression does not refer to a set"); - if (stmt_evaluate_arg(ctx, stmt, + if (stmt_evaluate_key(ctx, stmt, stmt->set.set->set->key->dtype, stmt->set.set->set->key->len, stmt->set.set->set->key->byteorder, @@ -3995,7 +4023,7 @@ static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt) return expr_error(ctx->msgs, stmt->map.set, "Expression does not refer to a set"); - if (stmt_evaluate_arg(ctx, stmt, + if (stmt_evaluate_key(ctx, stmt, stmt->map.set->set->key->dtype, stmt->map.set->set->key->len, stmt->map.set->set->key->byteorder, |