* - #XLAT_ACTION_DONE if we're done processing this node.
*
*/
-static xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, char letter)
+static inline CC_HINT(always_inline)
+xlat_action_t xlat_eval_one_letter(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, char letter)
{
char buffer[64];
return XLAT_ACTION_FAIL;
}
- fr_dcursor_append(out, value);
- fr_dcursor_next(out); /* Advance to our first value */
+ fr_dlist_insert_tail(out, value);
return XLAT_ACTION_DONE;
}
* - #XLAT_ACTION_FAIL on memory allocation errors.
* - #XLAT_ACTION_DONE if we're done processing this node.
*/
-static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt)
+static xlat_action_t xlat_eval_pair_virtual(TALLOC_CTX *ctx, fr_value_box_list_t *out,
+ request_t *request, tmpl_t const *vpt)
{
fr_radius_packet_t *packet = NULL;
fr_value_box_t *value;
}
done:
- fr_dcursor_append(out, value);
- fr_dcursor_next(out); /* Advance to our first value */
+ fr_dlist_insert_tail(out, value);
return XLAT_ACTION_DONE;
}
* - #XLAT_ACTION_FAIL we failed getting a value for the attribute.
* - #XLAT_ACTION_DONE we successfully evaluated the xlat.
*/
-static xlat_action_t xlat_eval_pair_real(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, tmpl_t const *vpt)
+static inline CC_HINT(always_inline) xlat_action_t
+xlat_eval_pair_real(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *request, tmpl_t const *vpt)
{
fr_pair_t *vp = NULL;
fr_value_box_t *value;
goto done;
}
value->datum.int32 = 0;
- fr_dcursor_append(out, value);
- fr_dcursor_next(out); /* Advance to our first value */
+ fr_dlist_insert_tail(out, value);
} /* Fall through to being done */
goto done;
value = fr_value_box_alloc(ctx, FR_TYPE_UINT32, NULL, false);
value->datum.uint32 = count;
- fr_dcursor_append(out, value);
- fr_dcursor_next(out); /* Advance to our first value */
+ fr_dlist_insert_tail(out, value);
break;
}
vp = fr_dcursor_next(&cursor)) {
value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted);
fr_value_box_copy(value, value, &vp->data);
- fr_dcursor_append(out, value);
+ fr_dlist_insert_tail(out, value);
}
- fr_dcursor_next(out); /* Advance to our first value */
break;
default:
if (!value) goto oom;
fr_value_box_copy(value, value, &vp->data); /* Also dups taint */
- fr_dcursor_append(out, value);
- fr_dcursor_next(out); /* Advance to our first value */
+ fr_dlist_insert_tail(out, value);
break;
}
fr_dlist_talloc_free(&result_copy);
return xa;
}
- VALUE_BOX_TALLOC_LIST_VERIFY(result);
+ VALUE_BOX_TALLOC_LIST_VERIFY(result);
xa = node->call.func->func(ctx, out,
- XLAT_CTX(node->call.inst->data, t->data, t->mctx, NULL),
- request, result);
+ XLAT_CTX(node->call.inst->data, t->data, t->mctx, NULL),
+ request, result);
VALUE_BOX_TALLOC_LIST_VERIFY(result);
if (RDEBUG_ENABLED2) xlat_debug_log_expansion(request, *in, &result_copy);
return xa;
case XLAT_ACTION_PUSH_UNLANG:
- RDEBUG3(" -- UNLANG");
+ RDEBUG3(" -- UNLANG");
return xa;
case XLAT_ACTION_YIELD:
{
xlat_exp_t const *node = *in;
xlat_action_t xa = XLAT_ACTION_DONE;
+ fr_value_box_list_t result; /* tmp list so debug works correctly */
+
+ fr_value_box_list_init(&result);
+
fr_value_box_t *value;
*child = NULL;
fr_dcursor_tail(out); /* Needed for debugging */
VALUE_BOX_TALLOC_LIST_VERIFY(out->dlist);
+ fr_assert(fr_dlist_num_elements(&result) == 0); /* Should all have been moved */
+
switch (node->type) {
case XLAT_BOX:
XLAT_DEBUG("** [%i] %s(value_box) - %s", unlang_interpret_stack_depth(request), __FUNCTION__, node->fmt);
node->fmt);
xlat_debug_log_expansion(request, node, NULL);
- if (xlat_eval_one_letter(ctx, out, request, node->fmt[0]) == XLAT_ACTION_FAIL) {
+ if (xlat_eval_one_letter(ctx, &result, request, node->fmt[0]) == XLAT_ACTION_FAIL) {
fail:
- fr_dcursor_free_list(out); /* Only frees what we've added during this call */
+ fr_dlist_talloc_free(&result);
xa = XLAT_ACTION_FAIL;
goto finish;
}
- xlat_debug_log_result(request, fr_dcursor_current(out));
+ xlat_debug_log_list_result(request, &result);
+ fr_dlist_move(out->dlist, &result);
continue;
case XLAT_ATTRIBUTE:
node->fmt);
xlat_debug_log_expansion(request, node, NULL);
- if (xlat_eval_pair_real(ctx, out, request, node->attr) == XLAT_ACTION_FAIL) goto fail;
- xlat_debug_log_result(request, fr_dcursor_current(out));
+ if (xlat_eval_pair_real(ctx, &result, request, node->attr) == XLAT_ACTION_FAIL) goto fail;
+
+ xlat_debug_log_list_result(request, &result);
+ fr_dlist_move(out->dlist, &result);
continue;
case XLAT_VIRTUAL:
continue;
case XLAT_FUNC:
- {
- fr_value_box_list_t result;
- fr_value_box_list_init(&result);
-
XLAT_DEBUG("** [%i] %s(func) - %%{%s:...}", unlang_interpret_stack_depth(request), __FUNCTION__,
node->fmt);
*/
xa = xlat_frame_eval_repeat(ctx, out, child, NULL, request, in, &result);
if (xa != XLAT_ACTION_DONE || (!*in)) goto finish;
- }
continue;
#ifdef HAVE_REGEX
XLAT_DEBUG("** [%i] %s(regex) - %%{%s}", unlang_interpret_stack_depth(request), __FUNCTION__,
node->fmt);
+
+ xlat_debug_log_expansion(request, node, NULL);
MEM(value = fr_value_box_alloc_null(ctx));
if (regex_request_to_sub(ctx, &str, request, node->regex_index) < 0) {
talloc_free(value);
continue;
}
fr_value_box_bstrdup_buffer_shallow(NULL, value, NULL, str, false);
+
+ xlat_debug_log_result(request, value);
fr_dcursor_append(out, value);
}
continue;
if (!vb->tainted) continue;
- len = talloc_array_length(str) * 3;
+ if (fr_value_box_cast_in_place(pool, vb, FR_TYPE_STRING, NULL) < 0) {
+ RPEDEBUG("Failed casting result to string");
+ error:
+ talloc_free(pool);
+ return -1;
+ }
+ len = vb->vb_length * 3;
escaped = talloc_array(pool, char, len);
- real_len = escape(request, escaped, len, str, UNCONST(void *, escape_ctx));
+ real_len = escape(request, escaped, len, vb->vb_strvalue, UNCONST(void *, escape_ctx));
entry = vb->entry;
fr_value_box_clear_value(vb);
}
}
- str = fr_value_box_list_aprint(ctx, &result, NULL, &fr_value_escape_double);
+ str = fr_value_box_list_aprint(ctx, &result, NULL, NULL);
if (!str) {
RPEDEBUG("Failed concatenating xlat result string");
talloc_free(pool);
- return -1;
+ goto error;
}
} else {
str = talloc_strdup(ctx, "");
*out = str;
- return strlen(str);
+ return talloc_array_length(str) - 1;
}
/** Replace %whatever in a string.
return slen;
}
- slen = strlen(buff);
-
/*
* If out doesn't point to an existing buffer
* copy the pointer to our buffer over.