From: Alan T. DeKok Date: Sat, 20 Nov 2021 14:13:15 +0000 (-0500) Subject: add function to manage assignment operations X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=783d75ab6f170a9fd75cc0dcbe46085723905183;p=thirdparty%2Ffreeradius-server.git add function to manage assignment operations --- diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index 58db2af2a0b..4188b7f36bb 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -1113,3 +1113,52 @@ done: return rcode; } + +int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src) +{ + int rcode = -1; + + if (!fr_type_is_leaf(dst->type)) return -1; + + if (!fr_assignment_op[op]) goto invalid; + + switch (op) { + case T_OP_EQ: + case T_OP_SET: + fr_value_box_clear(dst); + fr_value_box_copy(ctx, dst, src); + rcode = 0; + break; + + case T_OP_ADD_EQ: + case T_OP_SUB_EQ: + case T_OP_PREPEND: + /* + * Just call the binary op function. It already + * ensures that (a) the inputs are "const", and + * (b) the output is over-written only as the + * final step + */ + rcode = fr_value_calc_binary_op(ctx, dst, dst->type, dst, op, src); + break; + + default: + invalid: + rcode = ERR_INVALID; + break; + } + + if (rcode == ERR_OVERFLOW) { + fr_strerror_printf("Value overflows/underflows when calculating answer for %s", + fr_table_str_by_value(fr_value_box_type_table, dst->type, "")); + + } else if (rcode == ERR_INVALID) { + fr_strerror_printf("Invalid operator %s for destination type %s", + fr_tokens[op], + fr_table_str_by_value(fr_value_box_type_table, dst->type, "")); + } + + if (rcode == 0) dst->tainted |= src->tainted; + + return rcode; +} diff --git a/src/lib/util/calc.h b/src/lib/util/calc.h index b672901e648..cfa90d21452 100644 --- a/src/lib/util/calc.h +++ b/src/lib/util/calc.h @@ -31,7 +31,9 @@ RCSIDH(calc_h, "$Id$") extern "C" { #endif -int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b); +int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b) CC_HINT(nonnull(2,4,6)); + +int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src) CC_HINT(nonnull(2,4)); #ifdef __cplusplus }