This helps if the function is processing arguments and yielding between each argument.
/*
* For func and alternate
*/
- fr_value_box_t *result; //!< Of nested expansion.
+ fr_value_box_t *rhead; //!< Of nested expansion.
+ fr_cursor_t result; //!< Result cursor, mainly useful for
+ ///< asynchronous xlat functions.
bool alternate; //!< record which alternate branch we
///< previously took.
} unlang_stack_state_xlat_t;
xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out,
xlat_exp_t const **child, bool *alternate,
REQUEST *request, xlat_exp_t const **in,
- fr_value_box_t *result);
+ fr_cursor_t *result);
xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t const **child,
REQUEST *request, xlat_exp_t const **in);
xlat_action_t xa;
if (frame->repeat) {
+ fr_cursor_init(&xs->result, &xs->rhead);
xa = xlat_frame_eval_repeat(xs->ctx, &xs->values,
&child, &xs->alternate,
request, &xs->exp,
- xs->result);
+ &xs->result);
} else {
xa = xlat_frame_eval(xs->ctx, &xs->values, &child, request, &xs->exp);
}
rad_assert(child);
frame->repeat = true;
- unlang_push_xlat(xs->ctx, &xs->result, request, child, false);
+ unlang_push_xlat(xs->ctx, &xs->rhead, request, child, false);
return UNLANG_ACTION_PUSHED_CHILD;
case XLAT_ACTION_YIELD:
xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_cursor_t *out,
xlat_exp_t const **child, bool *alternate,
REQUEST *request, xlat_exp_t const **in,
- fr_value_box_t *result)
+ fr_cursor_t *result)
{
xlat_exp_t const *node = *in;
char *result_str;
ssize_t slen;
- result_str = fr_value_box_list_asprint(NULL, result, NULL, '\0');
+ result_str = fr_value_box_list_asprint(NULL, fr_cursor_head(result), NULL, '\0');
if (!result_str) return XLAT_ACTION_FAIL;
if (node->xlat->buf_len > 0) {
case XLAT_ALTERNATE:
{
- fr_cursor_t alt_result;
-
rad_assert(alternate);
rad_assert(child);
return XLAT_ACTION_PUSH_CHILD;
}
-
- fr_cursor_init(&alt_result, &result);
- fr_cursor_merge(out, &alt_result);
+ fr_cursor_merge(out, result);
}
break;