#include "foreach_priv.h"
#include "return_priv.h"
#include "unlang_priv.h"
+#include "xlat_priv.h"
static char const * const xlat_foreach_names[] = {"Foreach-Variable-0",
"Foreach-Variable-1",
#endif
} unlang_frame_state_foreach_t;
-static ssize_t unlang_foreach_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
- void const *mod_inst, UNUSED void const *xlat_inst,
- request_t *request, UNUSED char const *fmt);
+static xlat_action_t unlang_foreach_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+ UNUSED void const *xlat_inst, void *xlat_thread_inst,
+ UNUSED fr_value_box_list_t *in);
#define FOREACH_REQUEST_DATA (void *)unlang_foreach_xlat
*
* @ingroup xlat_functions
*/
-static ssize_t unlang_foreach_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
- void const *mod_inst, UNUSED void const *xlat_inst,
- request_t *request, UNUSED char const *fmt)
+static xlat_action_t unlang_foreach_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+ void const *xlat_inst, UNUSED void *xlat_thread_inst,
+ UNUSED fr_value_box_list_t *in)
{
- fr_pair_t **pvp;
+ fr_pair_t **pvp;
+ int const *inst = xlat_inst;
+ fr_value_box_t *vb;
- pvp = (fr_pair_t **) request_data_reference(request, FOREACH_REQUEST_DATA, *(int const *) mod_inst);
- if (!pvp || !*pvp) return 0;
+ pvp = (fr_pair_t **) request_data_reference(request, FOREACH_REQUEST_DATA, *inst);
+ if (!pvp || !*pvp) return XLAT_ACTION_FAIL;
- return fr_value_box_aprint(ctx, out, &(*pvp)->data, NULL);
+ MEM(vb = fr_value_box_alloc_null(ctx));
+ fr_value_box_copy(ctx, vb, &(*pvp)->data);
+ fr_dcursor_append(out, vb);
+ return XLAT_ACTION_DONE;
}
void unlang_foreach_init(void)
for (i = 0; i < NUM_ELEMENTS(xlat_foreach_names); i++) {
xlat_t *x;
- x = xlat_register_legacy(&xlat_foreach_inst[i], xlat_foreach_names[i],
- unlang_foreach_xlat, NULL, NULL, 0, 0);
+ x = xlat_register(NULL, xlat_foreach_names[i],
+ unlang_foreach_xlat, true);
+ x->uctx = &xlat_foreach_inst[i];
fr_assert(x);
xlat_internal(x);
}
node->fmt);
xlat_debug_log_expansion(request, node, NULL);
- MEM(value = fr_value_box_alloc_null(ctx));
- slen = node->call.func->func.sync(value, &str, node->call.func->buf_len, node->call.func->mod_inst,
+ if (node->call.func->type == XLAT_FUNC_NORMAL) {
+ node->call.func->func.async(ctx, out, request, node->call.func->uctx, NULL, NULL);
+ } else {
+ MEM(value = fr_value_box_alloc_null(ctx));
+ slen = node->call.func->func.sync(value, &str, node->call.func->buf_len, node->call.func->mod_inst,
NULL, request, NULL);
- if (slen < 0) {
- talloc_free(value);
- goto fail;
- }
- if (slen == 0) continue;
+ if (slen < 0) {
+ talloc_free(value);
+ goto fail;
+ }
+ if (slen == 0) continue;
- fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
- fr_dcursor_append(out, value);
+ fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
+ fr_dcursor_append(out, value);
+ }
fr_dcursor_next(out);
xlat_debug_log_result(request, fr_dcursor_current(out));
case XLAT_VIRTUAL:
XLAT_DEBUG("xlat_sync_eval VIRTUAL");
+ /*
+ * Temporary hack to use the new API
+ */
+ if (node->call.func->type == XLAT_FUNC_NORMAL) {
+ fr_value_box_list_t result;
+ xlat_action_t action;
+ fr_dcursor_t out;
+ TALLOC_CTX *pool = talloc_new(NULL);
+
+ fr_value_box_list_init (&result);
+ fr_dcursor_init(&out, &result);
+
+ action = node->call.func->func.async(pool, &out, request, node->call.func->uctx, NULL, NULL);
+ if (action == XLAT_ACTION_FAIL) {
+ talloc_free(pool);
+ return NULL;
+ }
+ if (!fr_dlist_empty(&result)) {
+ str = fr_value_box_list_aprint(ctx, &result, NULL, &fr_value_escape_double);
+ if (!str) {
+ RPEDEBUG("Failed concatenating xlat result string");
+ talloc_free(pool);
+ return NULL;
+ }
+ } else {
+ str = talloc_strdup(ctx, "");
+ }
+ talloc_free(pool); /* Memory should be in new ctx */
+ break;
+ }
+
if (node->call.func->buf_len > 0) {
str = talloc_array(ctx, char, node->call.func->buf_len);
str[0] = '\0'; /* Be sure the string is \0 terminated */