fr_token_t op;
char const *p, *value, *end;
size_t slen;
+ bool assignment;
a = talloc_zero(cc->tmp_ctx, fr_value_box_t);
b = talloc_zero(cc->tmp_ctx, fr_value_box_t);
- out = talloc_zero(cc->tmp_ctx, fr_value_box_t);
p = in;
end = in + inlen;
op = fr_table_value_by_longest_prefix(&match_len, fr_tokens_table, p, end - p, T_INVALID);
if (op != T_INVALID) {
p += match_len;
+ assignment = fr_assignment_op[op];
+
} else {
op = token2op[(uint8_t) p[0]];
if (op == T_INVALID) {
RETURN_PARSE_ERROR(0);
}
p++;
+
+ assignment = false;
}
fr_skip_whitespace(p);
p += match_len;
fr_skip_whitespace(p);
- /*
- * If there's no output data type, then the code tries to
- * figure one out automatically.
- */
- if (!*p) {
- type = FR_TYPE_NULL;
+ if (assignment) {
+ if (fr_value_calc_assignment_op(cc->tmp_ctx, a, op, b) < 0) {
+ RETURN_OK_WITH_ERROR();
+ }
+ out = a;
+
} else {
- if (strncmp(p, "->", 2) != 0) RETURN_PARSE_ERROR(0);
- p += 2;
- fr_skip_whitespace(p);
+ out = talloc_zero(cc->tmp_ctx, fr_value_box_t);
- type = fr_table_value_by_longest_prefix(&match_len, fr_value_box_type_table, p, end - p, FR_TYPE_MAX);
- if (type == FR_TYPE_MAX) RETURN_PARSE_ERROR(0);
- fr_value_box_init(out, type, NULL, false);
- }
+ /*
+ * If there's no output data type, then the code tries to
+ * figure one out automatically.
+ */
+ if (!*p) {
+ type = FR_TYPE_NULL;
+ } else {
+ if (strncmp(p, "->", 2) != 0) RETURN_PARSE_ERROR(0);
+ p += 2;
+ fr_skip_whitespace(p);
- if (fr_value_calc_binary_op(cc->tmp_ctx, out, type, a, op, b) < 0) {
- RETURN_OK_WITH_ERROR();
+ type = fr_table_value_by_longest_prefix(&match_len, fr_value_box_type_table, p, end - p, FR_TYPE_MAX);
+ if (type == FR_TYPE_MAX) RETURN_PARSE_ERROR(0);
+ fr_value_box_init(out, type, NULL, false);
+ }
+
+ if (fr_value_calc_binary_op(cc->tmp_ctx, out, type, a, op, b) < 0) {
+ RETURN_OK_WITH_ERROR();
+ }
}
slen = fr_value_box_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), out, NULL);
{
int rcode = -1;
- if (!fr_type_is_leaf(dst->type)) return -1;
+ if (!fr_type_is_leaf(dst->type)) {
+ fr_strerror_printf("Cannot perform any operations for destination type %s",
+ fr_table_str_by_value(fr_value_box_type_table, dst->type, "<INVALID>"));
+ return -1;
+ }
if (!fr_assignment_op[op]) goto invalid;
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
*/
+ case T_OP_ADD_EQ:
+ rcode = fr_value_calc_binary_op(ctx, dst, dst->type, dst, T_ADD, src);
+ break;
+
+ case T_OP_SUB_EQ:
+ rcode = fr_value_calc_binary_op(ctx, dst, dst->type, dst, T_SUB, src);
+ break;
+
+ case T_OP_PREPEND:
rcode = fr_value_calc_binary_op(ctx, dst, dst->type, dst, op, src);
break;
fr_table_str_by_value(fr_value_box_type_table, dst->type, "<INVALID>"));
} else if (rcode == ERR_INVALID) {
- fr_strerror_printf("Invalid operator %s for destination type %s",
+ fr_strerror_printf("Invalid assignment operator %s for destination type %s",
fr_tokens[op],
fr_table_str_by_value(fr_value_box_type_table, dst->type, "<INVALID>"));
}