char *p;
ssize_t slen;
xlat_exp_head_t *head = NULL;
- xlat_exp_head_t const **argv;
+ xlat_exp_head_t **argv;
size_t len;
size_t input_len = strlen(in);
char buff[1024];
RETURN_OK_WITH_ERROR();
}
- argc = xlat_flatten_compiled_argv(cc->tmp_ctx, &argv, head);
+ argc = xlat_flatten_compiled_argv(cc->tmp_ctx, &argv, &head);
if (argc <= 0) {
fr_strerror_printf_push("ERROR in argument %d", (int) -argc);
RETURN_OK_WITH_ERROR();
int xlat_aeval_compiled_argv(TALLOC_CTX *ctx, char ***argv, request_t *request,
xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx);
-int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t const ***argv, xlat_exp_head_t const *head);
+int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t ***argv, xlat_exp_head_t **head);
bool xlat_async_required(xlat_exp_head_t const *xlat);
return count;
}
-/** Turn xlat_tokenize_argv() into an argv[] array
+/** Turn xlat_tokenize_argv() into an argv[] array, and nuke the input list.
*
* This is mostly for async use.
*/
-int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t const ***argv, xlat_exp_head_t const *head)
+int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t ***argv, xlat_exp_head_t **head)
{
int i;
- xlat_exp_head_t const **my_argv;
+ xlat_exp_head_t **my_argv;
size_t count;
count = 0;
- xlat_exp_foreach(head, node) {
+ xlat_exp_foreach(*head, node) {
count++;
}
- MEM(my_argv = talloc_zero_array(ctx, xlat_exp_head_t const *, count + 1));
+ MEM(my_argv = talloc_zero_array(ctx, xlat_exp_head_t *, count + 1));
*argv = my_argv;
fr_assert(done_init);
i = 0;
- xlat_exp_foreach(head, node) {
- my_argv[i++] = node->group;
+ xlat_exp_foreach(*head, node) {
+ fr_assert(node->type == XLAT_GROUP);
+ my_argv[i++] = talloc_steal(my_argv, node->group);
}
+ talloc_free(*head);
+ *head = NULL;
+
return count;
}
static int xlat_logical_instantiate(xlat_inst_ctx_t const *xctx)
{
xlat_logical_inst_t *inst = talloc_get_type_abort(xctx->inst, xlat_logical_inst_t);
- int i;
- xlat_exp_foreach(xctx->ex->call.args, arg) {
- inst->argc++;
- }
-
- inst->argv = talloc_array(inst, xlat_exp_head_t *, inst->argc);
-
- i = 0;
- xlat_exp_foreach(xctx->ex->call.args, arg) {
- MEM(inst->argv[i] = xlat_exp_head_alloc(inst->argv));
- inst->argv[i++]->next = talloc_steal(inst->argv[i], arg);
- fr_assert(arg->type == XLAT_GROUP);
- }
-
- /*
- * The arguments are in a linked list, so unlink them,
- */
- for (i = 0; i < inst->argc; i++) {
- inst->argv[i]->next->next = NULL;
- }
-
- xctx->ex->call.args->next = NULL;
- TALLOC_FREE(xctx->ex->call.args);
+ inst->argc = xlat_flatten_compiled_argv(inst, &inst->argv, &xctx->ex->call.args);
inst->sense = (xctx->ex->call.func->token == T_LOR);
return 0;
switch (node->type) {
case XLAT_TMPL:
fr_assert(tmpl_is_list(node->vpt) || tmpl_is_attr(node->vpt));
+ fr_assert(talloc_parent(node->vpt) == node);
slen = tmpl_attr_print(out, node->vpt, TMPL_ATTR_REF_PREFIX_NO);
if (slen < 0) {
error: